diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-qpnp-haptics.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/leds/leds-qpnp-haptics.c b/drivers/leds/leds-qpnp-haptics.c index 9c62ab6521e8..72babedcf009 100644 --- a/drivers/leds/leds-qpnp-haptics.c +++ b/drivers/leds/leds-qpnp-haptics.c @@ -359,8 +359,11 @@ struct hap_chip { bool play_irq_en; bool auto_res_err_recovery_hw; bool vcc_pon_enabled; + int vmax_override; }; +struct hap_chip *gchip; + static int qpnp_haptics_parse_buffer_dt(struct hap_chip *chip); static int qpnp_haptics_parse_pwm_dt(struct hap_chip *chip); @@ -1331,6 +1334,34 @@ static int qpnp_haptics_auto_mode_config(struct hap_chip *chip, int time_ms) return 0; } +void set_vibrate(int val) +{ + int rc; + + if (val > gchip->max_play_time_ms) + return; + + mutex_lock(&gchip->param_lock); + rc = qpnp_haptics_auto_mode_config(gchip, val); + if (rc < 0) { + pr_err("Unable to do auto mode config\n"); + mutex_unlock(&gchip->param_lock); + return; + } + + gchip->play_time_ms = val; + mutex_unlock(&gchip->param_lock); + + hrtimer_cancel(&gchip->stop_timer); + if (is_sw_lra_auto_resonance_control(gchip)) + hrtimer_cancel(&gchip->auto_res_err_poll_timer); + cancel_work_sync(&gchip->haptics_work); + + atomic_set(&gchip->state, 1); + schedule_work(&gchip->haptics_work); + +} + static irqreturn_t qpnp_haptics_play_irq_handler(int irq, void *data) { struct hap_chip *chip = data; @@ -1521,6 +1552,9 @@ static ssize_t qpnp_haptics_store_activate(struct device *dev, if (val != 0 && val != 1) return count; + if (chip->vmax_mv <= HAP_VMAX_MIN_MV && (val != 0)) + return count; + if (val) { hrtimer_cancel(&chip->stop_timer); if (is_sw_lra_auto_resonance_control(chip)) @@ -1761,6 +1795,9 @@ static ssize_t qpnp_haptics_store_vmax(struct device *dev, if (rc < 0) return rc; + if (chip->vmax_override) + return count; + old_vmax_mv = chip->vmax_mv; chip->vmax_mv = data; rc = qpnp_haptics_vmax_config(chip, chip->vmax_mv, false); @@ -1772,6 +1809,65 @@ static ssize_t qpnp_haptics_store_vmax(struct device *dev, return count; } +static ssize_t qpnp_haptics_show_vmax_mv_user(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct hap_chip *chip = container_of(cdev, struct hap_chip, cdev); + + return snprintf(buf, PAGE_SIZE, "%d\n", chip->vmax_mv); +} + +static ssize_t qpnp_haptics_store_vmax_mv_user(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct hap_chip *chip = container_of(cdev, struct hap_chip, cdev); + int data, rc, old_vmax_mv; + + rc = kstrtoint(buf, 10, &data); + if (rc < 0) + return rc; + + old_vmax_mv = chip->vmax_mv; + chip->vmax_mv = data; + rc = qpnp_haptics_vmax_config(chip, chip->vmax_mv, false); + if (rc < 0) { + chip->vmax_mv = old_vmax_mv; + return rc; + } + + return count; +} + +static ssize_t qpnp_haptics_show_vmax_override(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct hap_chip *chip = container_of(cdev, struct hap_chip, cdev); + + return snprintf(buf, PAGE_SIZE, "%d\n", chip->vmax_override); +} + +static ssize_t qpnp_haptics_store_vmax_override(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct hap_chip *chip = container_of(cdev, struct hap_chip, cdev); + int data, rc; + + rc = kstrtoint(buf, 10, &data); + if (rc < 0) + return rc; + + if (data != 0 && data != 1) + return count; + + chip->vmax_override = !!data; + + return count; +} + static ssize_t qpnp_haptics_show_lra_auto_mode(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1814,6 +1910,8 @@ static struct device_attribute qpnp_haptics_attrs[] = { __ATTR(wf_s_rep_count, 0664, qpnp_haptics_show_wf_s_rep_count, qpnp_haptics_store_wf_s_rep_count), __ATTR(vmax_mv, 0664, qpnp_haptics_show_vmax, qpnp_haptics_store_vmax), + __ATTR(vmax_override, 0664, qpnp_haptics_show_vmax_override, qpnp_haptics_store_vmax_override), + __ATTR(vmax_mv_user, 0664, qpnp_haptics_show_vmax_mv_user, qpnp_haptics_store_vmax_mv_user), __ATTR(lra_auto_mode, 0664, qpnp_haptics_show_lra_auto_mode, qpnp_haptics_store_lra_auto_mode), }; @@ -2481,6 +2579,8 @@ static int qpnp_haptics_probe(struct platform_device *pdev) } } + gchip = chip; + return 0; sysfs_fail: |