Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2a95b28 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "leds: qpnp-haptics: Allow duration for buffer mode"

parents 6623e196 6ff7c755
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -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>
@@ -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".
+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
@@ -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
@@ -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;
@@ -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)
@@ -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),
@@ -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:
@@ -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);
@@ -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;
}
@@ -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];

@@ -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;
}