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

Commit a4cadd04 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "input: qti-haptics: Add FF_GAIN capability support"

parents 4f1e2f62 b961c241
Loading
Loading
Loading
Loading
+54 −11
Original line number Diff line number Diff line
@@ -528,7 +528,6 @@ static int qti_haptics_config_brake(struct qti_hap_chip *chip, u8 *brake)
{
	u8 addr, mask, val;
	int i, rc;
	bool en = true;

	addr = REG_HAP_BRAKE;
	for (val = 0, i = 0; i < HAP_BRAKE_PATTERN_MAX; i++)
@@ -540,14 +539,12 @@ static int qti_haptics_config_brake(struct qti_hap_chip *chip, u8 *brake)
		dev_err(chip->dev, "write brake pattern failed, rc=%d\n", rc);
		return rc;
	}

	if (val == 0)
		en = false;

	/* Set BRAKE_EN only if brake pattern is non-zero */
	/*
	 * Set BRAKE_EN regardless of the brake pattern, this helps to stop
	 * playing immediately once the valid values in WF_Sx are played.
	 */
	addr = REG_HAP_EN_CTL2;
	mask = HAP_BRAKE_EN_BIT;
	val = en;
	val = mask = HAP_BRAKE_EN_BIT;
	rc = qti_haptics_masked_write(chip, addr, mask, val);
	if (rc < 0)
		dev_err(chip->dev, "set EN_CTL2 failed, rc=%d\n", rc);
@@ -580,6 +577,9 @@ static int qti_haptics_load_constant_waveform(struct qti_hap_chip *chip)
	if (rc < 0)
		return rc;

	rc = qti_haptics_config_play_rate_us(chip, config->play_rate_us);
	if (rc < 0)
		return rc;
	/*
	 * Using VMAX waveform source if playing length is >= 20ms,
	 * otherwise using buffer waveform source and calculate the
@@ -697,7 +697,6 @@ static irqreturn_t qti_haptics_play_irq_handler(int irq, void *data)
	dev_dbg(chip->dev, "play_irq triggered\n");
	if (play->playing_pos == effect->pattern_length) {
		dev_dbg(chip->dev, "waveform playing done\n");
		qti_haptics_play(chip, false);
		if (chip->play_irq_en) {
			disable_irq_nosync(chip->play_irq);
			chip->play_irq_en = false;
@@ -919,6 +918,10 @@ static int qti_haptics_playback(struct input_dev *dev, int effect_id, int val)
				enable_irq(chip->play_irq);
				chip->play_irq_en = true;
			}
			/* Toggle PLAY when playing pattern */
			rc = qti_haptics_play(chip, false);
			if (rc < 0)
				return rc;
		} else {
			if (chip->play_irq_en) {
				disable_irq_nosync(chip->play_irq);
@@ -967,6 +970,22 @@ static int qti_haptics_erase(struct input_dev *dev, int effect_id)
	return rc;
}

static void qti_haptics_set_gain(struct input_dev *dev, u16 gain)
{
	struct qti_hap_chip *chip = input_get_drvdata(dev);
	struct qti_hap_config *config = &chip->config;
	struct qti_hap_play_info *play = &chip->play;

	if (gain == 0)
		return;

	if (gain > 0x7fff)
		gain = 0x7fff;

	play->vmax_mv = ((u32)(gain * config->vmax_mv)) / 0x7fff;
	qti_haptics_config_vmax(chip, play->vmax_mv);
}

static int qti_haptics_hw_init(struct qti_hap_chip *chip)
{
	struct qti_hap_config *config = &chip->config;
@@ -1093,7 +1112,7 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip)
	struct device_node *child_node;
	struct qti_hap_effect *effect;
	const char *str;
	int rc = 0, tmp, i = 0, j;
	int rc = 0, tmp, i = 0, j, m;
	u8 val;

	rc = of_property_read_u32(node, "reg", &tmp);
@@ -1311,7 +1330,7 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip)
			effect->wf_s_repeat_n = j;
		}

		effect->lra_auto_res_disable = of_property_read_bool(node,
		effect->lra_auto_res_disable = of_property_read_bool(child_node,
				"qcom,lra-auto-resonance-disable");

		tmp = of_property_count_elems_of_size(child_node,
@@ -1347,6 +1366,28 @@ static int qti_haptics_parse_dt(struct qti_hap_chip *chip)
		effect->brake_en = (val != 0);
	}

	for (j = 0; j < i; j++) {
		dev_dbg(chip->dev, "effect: %d\n", chip->predefined[j].id);
		dev_dbg(chip->dev, "        vmax: %d mv\n",
				chip->predefined[j].vmax_mv);
		dev_dbg(chip->dev, "        play_rate: %d us\n",
				chip->predefined[j].play_rate_us);
		for (m = 0; m < chip->predefined[j].pattern_length; m++)
			dev_dbg(chip->dev, "        pattern[%d]: 0x%x\n",
					m, chip->predefined[j].pattern[m]);
		for (m = 0; m < chip->predefined[j].brake_pattern_length; m++)
			dev_dbg(chip->dev, "        brake_pattern[%d]: 0x%x\n",
					m, chip->predefined[j].brake[m]);
		dev_dbg(chip->dev, "    brake_en: %d\n",
				chip->predefined[j].brake_en);
		dev_dbg(chip->dev, "    wf_repeat_n: %d\n",
				chip->predefined[j].wf_repeat_n);
		dev_dbg(chip->dev, "    wf_s_repeat_n: %d\n",
				chip->predefined[j].wf_s_repeat_n);
		dev_dbg(chip->dev, "    lra_auto_res_disable: %d\n",
				chip->predefined[j].lra_auto_res_disable);
	}

	return 0;
}

@@ -1414,6 +1455,7 @@ static int qti_haptics_probe(struct platform_device *pdev)
	chip->input_dev = input_dev;

	input_set_capability(input_dev, EV_FF, FF_CONSTANT);
	input_set_capability(input_dev, EV_FF, FF_GAIN);
	if (chip->effects_count != 0) {
		input_set_capability(input_dev, EV_FF, FF_PERIODIC);
		input_set_capability(input_dev, EV_FF, FF_CUSTOM);
@@ -1434,6 +1476,7 @@ static int qti_haptics_probe(struct platform_device *pdev)
	ff->upload = qti_haptics_upload_effect;
	ff->playback = qti_haptics_playback;
	ff->erase = qti_haptics_erase;
	ff->set_gain = qti_haptics_set_gain;

	rc = input_register_device(input_dev);
	if (rc < 0) {