diff options
| -rw-r--r-- | drivers/soc/qcom/qpnp-haptic.c | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/drivers/soc/qcom/qpnp-haptic.c b/drivers/soc/qcom/qpnp-haptic.c index 064608fc81cf..c4f311f4afc4 100644 --- a/drivers/soc/qcom/qpnp-haptic.c +++ b/drivers/soc/qcom/qpnp-haptic.c @@ -364,6 +364,9 @@ struct qpnp_hap { u32 timeout_ms; u32 time_required_to_generate_back_emf_us; u32 vmax_mv; + u32 vtg_min; + u32 vtg_max; + u32 vtg_default; u32 ilim_ma; u32 sc_deb_cycles; u32 int_pwm_freq_khz; @@ -889,12 +892,12 @@ static int qpnp_hap_vmax_config(struct qpnp_hap *hap, int vmax_mv, if (hap->pmic_subtype != PM660_SUBTYPE) overdrive = false; - if (vmax_mv < QPNP_HAP_VMAX_MIN_MV) - vmax_mv = QPNP_HAP_VMAX_MIN_MV; - else if (vmax_mv > QPNP_HAP_VMAX_MAX_MV) - vmax_mv = QPNP_HAP_VMAX_MAX_MV; + if (vmax_mv < hap->vtg_min) + vmax_mv = hap->vtg_min; + else if (vmax_mv > hap->vtg_max) + vmax_mv = hap->vtg_max; - val = (vmax_mv / QPNP_HAP_VMAX_MIN_MV) << QPNP_HAP_VMAX_SHIFT; + val = (vmax_mv / hap->vtg_min) << QPNP_HAP_VMAX_SHIFT; if (overdrive) val |= QPNP_HAP_VMAX_OVD_BIT; rc = qpnp_hap_masked_write_reg(hap, QPNP_HAP_VMAX_REG(hap->base), @@ -1788,9 +1791,43 @@ static ssize_t qpnp_hap_vmax_store(struct device *dev, return rc; hap->vmax_mv = data; + rc = qpnp_hap_vmax_config(hap, hap->vmax_mv, true); + if (rc) + return rc; + return count; } +static ssize_t qpnp_hap_min_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_min); +} + +static ssize_t qpnp_hap_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_max); +} + +static ssize_t qpnp_hap_default_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_default); +} + /* sysfs attributes */ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(wf_s0, 0664, qpnp_hap_wf_s0_show, qpnp_hap_wf_s0_store), @@ -1822,6 +1859,10 @@ static struct device_attribute qpnp_hap_attrs[] = { qpnp_hap_override_auto_mode_show, qpnp_hap_override_auto_mode_store), __ATTR(vmax_mv, 0664, qpnp_hap_vmax_show, qpnp_hap_vmax_store), + __ATTR(vtg_level, 0664, qpnp_hap_vmax_show, qpnp_hap_vmax_store), + __ATTR(vtg_min, 0664, qpnp_hap_min_show, NULL), + __ATTR(vtg_max, 0664, qpnp_hap_max_show, NULL), + __ATTR(vtg_default, 0664, qpnp_hap_default_show, NULL), }; static int calculate_lra_code(struct qpnp_hap *hap) @@ -2148,7 +2189,7 @@ static int qpnp_hap_auto_mode_config(struct qpnp_hap *hap, int time_ms) ares_cfg.calibrate_at_eop = -EINVAL; } - vmax_mv = QPNP_HAP_VMAX_MAX_MV; + vmax_mv = hap->vtg_max; rc = qpnp_hap_vmax_config(hap, vmax_mv, true); if (rc < 0) return rc; @@ -2859,7 +2900,25 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap) return rc; } - hap->vmax_mv = QPNP_HAP_VMAX_MAX_MV; + hap->vtg_min = QPNP_HAP_VMAX_MIN_MV; + rc = of_property_read_u32(pdev->dev.of_node, "qcom,vtg-min", &temp); + if (!rc) { + hap->vtg_min = temp; + } else if (rc != -EINVAL) { + pr_err("Unable to read vtg_min\n"); + return rc; + } + + hap->vtg_max = QPNP_HAP_VMAX_MAX_MV; + rc = of_property_read_u32(pdev->dev.of_node, "qcom,vtg-max", &temp); + if (!rc) { + hap->vtg_max = temp; + } else if (rc != -EINVAL) { + pr_err("Unable to read vtg_max\n"); + return rc; + } + + hap->vmax_mv = hap->vtg_max; rc = of_property_read_u32(pdev->dev.of_node, "qcom,vmax-mv", &temp); if (!rc) { hap->vmax_mv = temp; @@ -2868,6 +2927,14 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap) return rc; } + if (hap->vmax_mv < hap->vtg_min) { + hap->vmax_mv = hap->vtg_min; + } else if (hap->vmax_mv > hap->vtg_max) { + hap->vmax_mv = hap->vtg_max; + } + + hap->vtg_default = hap->vmax_mv; + hap->ilim_ma = QPNP_HAP_ILIM_MIN_MV; rc = of_property_read_u32(pdev->dev.of_node, "qcom,ilim-ma", &temp); if (!rc) { |
