Loading Documentation/devicetree/bindings/leds/leds-qpnp-haptics.txt +17 −1 Original line number Diff line number Diff line Loading @@ -118,6 +118,18 @@ Properties: Following properties are specific only to LRA vibrators. - qcom,lra-auto-mode Usage: optional Value type: <empty> Definition: If specified, a set of pre-configured settings will be applied based on the pattern duration. For example, for a duration of < 20 ms (short duration), one set of settings will be applied and for a duration of >= 20 ms (long duration), another set of settings will be applied. The parameters configured in the driver when this property is specified is based on the LRA tested internally. Those parameters should be fine-tuned or adjusted based on the LRA used on different hardware platforms. - qcom,lra-auto-res-mode Usage: optional Value type: <string> Loading Loading @@ -200,9 +212,13 @@ Following properties are applicable only when "qcom,play-mode" is set to - qcom,wave-samples Usage: optional Value type: <prop-encoded-array> Definition: Wave samples in an array of 8 elements. Each element takes the Definition: Wave samples in an array of 32 elements. Each element takes the following representation, bit 0: unused, bits[5:1] : amplitude, bit 6: overdrive, bit 7: sign. Default sample value is 0x3E. Since the hardware supports configuring upto 8 samples, a set of 8 samples will be configured initially and the next set will be configured upon the play interrupt until all the samples are configured and played. Following properties are applicable only when "qcom,play-mode" is set to "pwm". Loading drivers/leds/leds-qpnp-haptics.c +34 −22 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, 2017-2018, The Linux Foundation. * All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -275,6 +274,7 @@ struct hap_lra_ares_param { * @ last_rate_cfg - Last rate config updated * @ wave_rep_cnt - waveform repeat count * @ wave_s_rep_cnt - waveform sample repeat count * @ wf_samp_len - waveform sample length * @ ext_pwm_freq_khz - external pwm frequency in KHz * @ ext_pwm_dtest_line - DTEST line for external pwm * @ status_flags - status Loading Loading @@ -330,6 +330,7 @@ struct hap_chip { u16 last_rate_cfg; u32 wave_rep_cnt; u32 wave_s_rep_cnt; u32 wf_samp_len; u32 ext_pwm_freq_khz; u8 ext_pwm_dtest_line; u32 status_flags; Loading Loading @@ -445,6 +446,19 @@ static int qpnp_haptics_masked_write_reg(struct hap_chip *chip, u16 addr, return rc; } static inline int get_buffer_mode_duration(struct hap_chip *chip) { int sample_count, sample_duration; sample_count = chip->wave_rep_cnt * chip->wave_s_rep_cnt * chip->wf_samp_len; sample_duration = sample_count * chip->wave_play_rate_us; pr_debug("sample_count: %d sample_duration: %d\n", sample_count, sample_duration); return (sample_duration / 1000); } static bool is_sw_lra_auto_resonance_control(struct hap_chip *chip) { if (chip->act_type != HAP_LRA) Loading Loading @@ -735,7 +749,8 @@ static int qpnp_haptics_play(struct hap_chip *chip, bool enable) goto out; } if (chip->play_mode != HAP_BUFFER) if (chip->play_mode == HAP_BUFFER) time_ms = get_buffer_mode_duration(chip); hrtimer_start(&chip->stop_timer, ktime_set(time_ms / MSEC_PER_SEC, (time_ms % MSEC_PER_SEC) * NSEC_PER_MSEC), Loading Loading @@ -766,6 +781,9 @@ static int qpnp_haptics_play(struct hap_chip *chip, bool enable) if (chip->play_mode == HAP_PWM) pwm_disable(chip->pwm_data.pwm_dev); if (chip->play_mode == HAP_BUFFER) chip->wave_samp_idx = 0; } out: Loading Loading @@ -1182,8 +1200,11 @@ static int qpnp_haptics_auto_mode_config(struct hap_chip *chip, int time_ms) if (time_ms <= 20) { wave_samp[0] = HAP_WF_SAMP_MAX; wave_samp[1] = HAP_WF_SAMP_MAX; if (time_ms > 15) chip->wf_samp_len = 2; if (time_ms > 15) { wave_samp[2] = HAP_WF_SAMP_MAX; chip->wf_samp_len = 3; } /* short pattern */ rc = qpnp_haptics_parse_buffer_dt(chip); Loading Loading @@ -1302,33 +1323,20 @@ static irqreturn_t qpnp_haptics_play_irq_handler(int irq, void *data) chip->wave_samp_idx += HAP_WAVE_SAMP_LEN; if (chip->wave_samp_idx >= ARRAY_SIZE(chip->wave_samp)) { pr_debug("Samples over\n"); /* fall through to stop playing */ } else { pr_debug("moving to next sample set %d\n", chip->wave_samp_idx); /* Moving to next set of wave sample */ rc = qpnp_haptics_buffer_config(chip, NULL, false); if (rc < 0) { pr_err("Error in configuring buffer, rc=%d\n", rc); goto irq_handled; } /* * Moving to next set of wave sample. No need to stop * or change the play control. Just return. */ goto irq_handled; } } rc = qpnp_haptics_play_control(chip, HAP_STOP); if (rc < 0) { pr_err("Error in disabling play, rc=%d\n", rc); goto irq_handled; } chip->wave_samp_idx = 0; irq_handled: return IRQ_HANDLED; } Loading Loading @@ -1638,6 +1646,7 @@ static ssize_t qpnp_haptics_store_wf_samp(struct device *dev, pos += bytes_read; } chip->wf_samp_len = i; for (i = 0; i < ARRAY_SIZE(chip->wave_samp); i++) chip->wave_samp[i] = samp[i]; Loading Loading @@ -1986,7 +1995,10 @@ static int qpnp_haptics_parse_buffer_dt(struct hap_chip *chip) /* Use default values */ for (i = 0; i < HAP_WAVE_SAMP_LEN; i++) chip->wave_samp[i] = HAP_WF_SAMP_MAX; wf_samp_len = HAP_WAVE_SAMP_LEN; } chip->wf_samp_len = wf_samp_len; return 0; } Loading Loading
Documentation/devicetree/bindings/leds/leds-qpnp-haptics.txt +17 −1 Original line number Diff line number Diff line Loading @@ -118,6 +118,18 @@ Properties: Following properties are specific only to LRA vibrators. - qcom,lra-auto-mode Usage: optional Value type: <empty> Definition: If specified, a set of pre-configured settings will be applied based on the pattern duration. For example, for a duration of < 20 ms (short duration), one set of settings will be applied and for a duration of >= 20 ms (long duration), another set of settings will be applied. The parameters configured in the driver when this property is specified is based on the LRA tested internally. Those parameters should be fine-tuned or adjusted based on the LRA used on different hardware platforms. - qcom,lra-auto-res-mode Usage: optional Value type: <string> Loading Loading @@ -200,9 +212,13 @@ Following properties are applicable only when "qcom,play-mode" is set to - qcom,wave-samples Usage: optional Value type: <prop-encoded-array> Definition: Wave samples in an array of 8 elements. Each element takes the Definition: Wave samples in an array of 32 elements. Each element takes the following representation, bit 0: unused, bits[5:1] : amplitude, bit 6: overdrive, bit 7: sign. Default sample value is 0x3E. Since the hardware supports configuring upto 8 samples, a set of 8 samples will be configured initially and the next set will be configured upon the play interrupt until all the samples are configured and played. Following properties are applicable only when "qcom,play-mode" is set to "pwm". Loading
drivers/leds/leds-qpnp-haptics.c +34 −22 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, 2017-2018, The Linux Foundation. * All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -275,6 +274,7 @@ struct hap_lra_ares_param { * @ last_rate_cfg - Last rate config updated * @ wave_rep_cnt - waveform repeat count * @ wave_s_rep_cnt - waveform sample repeat count * @ wf_samp_len - waveform sample length * @ ext_pwm_freq_khz - external pwm frequency in KHz * @ ext_pwm_dtest_line - DTEST line for external pwm * @ status_flags - status Loading Loading @@ -330,6 +330,7 @@ struct hap_chip { u16 last_rate_cfg; u32 wave_rep_cnt; u32 wave_s_rep_cnt; u32 wf_samp_len; u32 ext_pwm_freq_khz; u8 ext_pwm_dtest_line; u32 status_flags; Loading Loading @@ -445,6 +446,19 @@ static int qpnp_haptics_masked_write_reg(struct hap_chip *chip, u16 addr, return rc; } static inline int get_buffer_mode_duration(struct hap_chip *chip) { int sample_count, sample_duration; sample_count = chip->wave_rep_cnt * chip->wave_s_rep_cnt * chip->wf_samp_len; sample_duration = sample_count * chip->wave_play_rate_us; pr_debug("sample_count: %d sample_duration: %d\n", sample_count, sample_duration); return (sample_duration / 1000); } static bool is_sw_lra_auto_resonance_control(struct hap_chip *chip) { if (chip->act_type != HAP_LRA) Loading Loading @@ -735,7 +749,8 @@ static int qpnp_haptics_play(struct hap_chip *chip, bool enable) goto out; } if (chip->play_mode != HAP_BUFFER) if (chip->play_mode == HAP_BUFFER) time_ms = get_buffer_mode_duration(chip); hrtimer_start(&chip->stop_timer, ktime_set(time_ms / MSEC_PER_SEC, (time_ms % MSEC_PER_SEC) * NSEC_PER_MSEC), Loading Loading @@ -766,6 +781,9 @@ static int qpnp_haptics_play(struct hap_chip *chip, bool enable) if (chip->play_mode == HAP_PWM) pwm_disable(chip->pwm_data.pwm_dev); if (chip->play_mode == HAP_BUFFER) chip->wave_samp_idx = 0; } out: Loading Loading @@ -1182,8 +1200,11 @@ static int qpnp_haptics_auto_mode_config(struct hap_chip *chip, int time_ms) if (time_ms <= 20) { wave_samp[0] = HAP_WF_SAMP_MAX; wave_samp[1] = HAP_WF_SAMP_MAX; if (time_ms > 15) chip->wf_samp_len = 2; if (time_ms > 15) { wave_samp[2] = HAP_WF_SAMP_MAX; chip->wf_samp_len = 3; } /* short pattern */ rc = qpnp_haptics_parse_buffer_dt(chip); Loading Loading @@ -1302,33 +1323,20 @@ static irqreturn_t qpnp_haptics_play_irq_handler(int irq, void *data) chip->wave_samp_idx += HAP_WAVE_SAMP_LEN; if (chip->wave_samp_idx >= ARRAY_SIZE(chip->wave_samp)) { pr_debug("Samples over\n"); /* fall through to stop playing */ } else { pr_debug("moving to next sample set %d\n", chip->wave_samp_idx); /* Moving to next set of wave sample */ rc = qpnp_haptics_buffer_config(chip, NULL, false); if (rc < 0) { pr_err("Error in configuring buffer, rc=%d\n", rc); goto irq_handled; } /* * Moving to next set of wave sample. No need to stop * or change the play control. Just return. */ goto irq_handled; } } rc = qpnp_haptics_play_control(chip, HAP_STOP); if (rc < 0) { pr_err("Error in disabling play, rc=%d\n", rc); goto irq_handled; } chip->wave_samp_idx = 0; irq_handled: return IRQ_HANDLED; } Loading Loading @@ -1638,6 +1646,7 @@ static ssize_t qpnp_haptics_store_wf_samp(struct device *dev, pos += bytes_read; } chip->wf_samp_len = i; for (i = 0; i < ARRAY_SIZE(chip->wave_samp); i++) chip->wave_samp[i] = samp[i]; Loading Loading @@ -1986,7 +1995,10 @@ static int qpnp_haptics_parse_buffer_dt(struct hap_chip *chip) /* Use default values */ for (i = 0; i < HAP_WAVE_SAMP_LEN; i++) chip->wave_samp[i] = HAP_WF_SAMP_MAX; wf_samp_len = HAP_WAVE_SAMP_LEN; } chip->wf_samp_len = wf_samp_len; return 0; } Loading