diff options
| author | dianlujitao <dianlujitao@gmail.com> | 2016-07-01 22:17:42 +0800 |
|---|---|---|
| committer | Michael Bestas <mkbestas@lineageos.org> | 2019-12-23 23:43:38 +0200 |
| commit | 39d21bfc38cb4e2b90ca7422b7526786c0ec9e06 (patch) | |
| tree | edf73d207289801b18748939f0c572f4edd1b618 | |
| parent | 39ba8d7f26a7972f3d6d673460f29377ad4fbcec (diff) | |
msm: qpnp-haptic: set up sysfs interface for common cmhw implementation
* Export vmax_mv as vtg_level
* Add min/max/default voltage sysfs entries
* Make min/max voltage adjustable via DT
Change-Id: Iefa3accdb75fcef9bcb2d4c730ca0a72763994f3
| -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) { |
