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

Commit 2880031e authored by Venkata Prahlad Valluru's avatar Venkata Prahlad Valluru
Browse files

input: touchscreen: synaptics_2.6: Add regulator configuration support



Add bus and power regulator configurations for both active
and suspend mode. Move to low power mode during idle suspend.
Enable configuration options through device tree.

Change-Id: Ic1509ab7e31e7488460a6cc86e5cd434a84fa7a8
Signed-off-by: default avatarVenkata Prahlad Valluru <vvalluru@codeaurora.org>
parent d773196b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ Optional property:
 - vcc_i2c-supply			   : analog voltage power supply needed to power device.
 - synaptics,pwr-reg-name	   : power reg name of digital voltage.
 - synaptics,bus-reg-name	   : bus reg name of analog voltage.
 - synaptics,do-not-disable-regulators	   : If specified, regulators cannot be disabled/enabled during suspend/resume.
 - synaptics,irq-on-state      : status of irq gpio.
 - synaptics,cap-button-codes  : virtual key code mappings to be used.
 - synaptics,vir-button-codes  : virtual key code and the response region on panel.
@@ -26,6 +27,7 @@ Optional property:
 - synaptics,y-flip		       : modify orientation of the y axis.
 - synaptics,reset-delay-ms	   : reset delay for controller (ms), default 100.
 - synaptics,max-y-for-2d	   : maximal y value of the panel.
 - synaptics,bus-lpm-cur-uA	   : I2C bus idle mode current setting.
 - clock-names			: Clock names used for secure touch. They are: "iface_clk", "core_clk"
 - clocks			: Defined if 'clock-names' DT property is defined. These clocks
				  are associated with the underlying I2C bus.
+140 −7
Original line number Diff line number Diff line
@@ -111,6 +111,13 @@
#define F12_WAKEUP_GESTURE_MODE 0x02
#define F12_UDG_DETECT 0x0f

#define PWR_VTG_MIN_UV		2700000
#define PWR_VTG_MAX_UV		3600000
#define PWR_ACTIVE_LOAD_UA	2000
#define I2C_VTG_MIN_UV		1710000
#define I2C_VTG_MAX_UV		2000000
#define I2C_ACTIVE_LOAD_UA	7000

static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
		bool *was_in_bl_mode);
static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data);
@@ -3405,6 +3412,66 @@ err_gpio_irq:
	return retval;
}

static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
{
	return (regulator_count_voltages(reg) > 0) ?
		regulator_set_optimum_mode(reg, load_uA) : 0;
}

static int synaptics_rmi4_configure_reg(struct synaptics_rmi4_data *rmi4_data,
				bool on)
{
	int retval;

	if (on == false)
		goto hw_shutdown;

	if (rmi4_data->pwr_reg) {
		if (regulator_count_voltages(rmi4_data->pwr_reg) > 0) {
			retval = regulator_set_voltage(rmi4_data->pwr_reg,
				PWR_VTG_MIN_UV, PWR_VTG_MAX_UV);
			if (retval) {
				dev_err(rmi4_data->pdev->dev.parent,
					"regulator set_vtg failed retval =%d\n",
					retval);
				goto err_set_vtg_pwr;
			}
		}
	}

	if (rmi4_data->bus_reg) {
		if (regulator_count_voltages(rmi4_data->bus_reg) > 0) {
			retval = regulator_set_voltage(rmi4_data->bus_reg,
				I2C_VTG_MIN_UV, I2C_VTG_MAX_UV);
			if (retval) {
				dev_err(rmi4_data->pdev->dev.parent,
					"regulator set_vtg failed retval =%d\n",
					retval);
				goto err_set_vtg_bus;
			}
		}
	}

	return 0;

err_set_vtg_bus:
	if (rmi4_data->pwr_reg &&
		regulator_count_voltages(rmi4_data->pwr_reg) > 0)
		regulator_set_voltage(rmi4_data->pwr_reg, 0, PWR_VTG_MAX_UV);
err_set_vtg_pwr:
	return retval;

hw_shutdown:
	if (rmi4_data->pwr_reg &&
		regulator_count_voltages(rmi4_data->pwr_reg) > 0)
		regulator_set_voltage(rmi4_data->pwr_reg, 0, PWR_VTG_MAX_UV);
	if (rmi4_data->bus_reg &&
		regulator_count_voltages(rmi4_data->bus_reg) > 0)
		regulator_set_voltage(rmi4_data->bus_reg, 0, I2C_VTG_MAX_UV);

	return 0;
}

static int synaptics_rmi4_get_reg(struct synaptics_rmi4_data *rmi4_data,
		bool get)
{
@@ -3470,37 +3537,66 @@ static int synaptics_rmi4_enable_reg(struct synaptics_rmi4_data *rmi4_data,
	}

	if (rmi4_data->bus_reg) {
		retval = reg_set_optimum_mode_check(rmi4_data->bus_reg,
					I2C_ACTIVE_LOAD_UA);
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Regulator set_opt failed rc=%d\n",
					__func__, retval);
			return retval;
		}

		retval = regulator_enable(rmi4_data->bus_reg);
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to enable bus pullup regulator\n",
					__func__);
			goto exit;
			goto err_bus_reg_en;
		}
	}

	if (rmi4_data->pwr_reg) {
		retval = reg_set_optimum_mode_check(rmi4_data->pwr_reg,
					PWR_ACTIVE_LOAD_UA);
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Regulator set_opt failed rc=%d\n",
					__func__, retval);
			goto disable_bus_reg;
		}

		retval = regulator_enable(rmi4_data->pwr_reg);
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to enable power regulator\n",
					__func__);
			goto disable_bus_reg;
			goto err_pwr_reg_en;
		}
		msleep(bdata->power_delay_ms);
	}

	return 0;

err_pwr_reg_en:
	reg_set_optimum_mode_check(rmi4_data->pwr_reg, 0);
	goto disable_bus_reg;
err_bus_reg_en:
	reg_set_optimum_mode_check(rmi4_data->bus_reg, 0);

	return retval;

disable_pwr_reg:
	if (rmi4_data->pwr_reg)
	if (rmi4_data->pwr_reg) {
		reg_set_optimum_mode_check(rmi4_data->pwr_reg, 0);
		regulator_disable(rmi4_data->pwr_reg);
	}

disable_bus_reg:
	if (rmi4_data->bus_reg)
	if (rmi4_data->bus_reg) {
		reg_set_optimum_mode_check(rmi4_data->bus_reg, 0);
		regulator_disable(rmi4_data->bus_reg);
	}

exit:
	return retval;
}

@@ -3974,6 +4070,14 @@ static int synaptics_rmi4_probe(struct platform_device *pdev)
		goto err_get_reg;
	}

	retval = synaptics_rmi4_configure_reg(rmi4_data, true);
	if (retval < 0) {
		dev_err(&pdev->dev,
				"%s: Failed to configure regulators\n",
				__func__);
		goto err_configure_reg;
	}

	retval = synaptics_rmi4_enable_reg(rmi4_data, true);
	if (retval < 0) {
		dev_err(&pdev->dev,
@@ -4200,6 +4304,8 @@ err_set_gpio:
err_enable_reg:
	synaptics_rmi4_get_reg(rmi4_data, false);

err_configure_reg:
	synaptics_rmi4_configure_reg(rmi4_data, false);
err_get_reg:
	kfree(rmi4_data);

@@ -4282,6 +4388,7 @@ static int synaptics_rmi4_remove(struct platform_device *pdev)
	}

	synaptics_rmi4_enable_reg(rmi4_data, false);
	synaptics_rmi4_configure_reg(rmi4_data, false);
	synaptics_rmi4_get_reg(rmi4_data, false);

	kfree(rmi4_data);
@@ -4555,6 +4662,7 @@ static int synaptics_rmi4_suspend(struct device *dev)
	struct synaptics_rmi4_exp_fhandler *exp_fhandler;
	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
	int retval;
	int lpm_uA;

	if (rmi4_data->stay_awake)
		return 0;
@@ -4563,6 +4671,17 @@ static int synaptics_rmi4_suspend(struct device *dev)

	if (rmi4_data->enable_wakeup_gesture) {
		if (!rmi4_data->suspend) {
			/* Set lpm current for bus regulator */
			lpm_uA = rmi4_data->hw_if->board_data->bus_lpm_cur_uA;
			if (lpm_uA) {
				retval = reg_set_optimum_mode_check(
						rmi4_data->bus_reg, lpm_uA);
				if (retval < 0)
					dev_err(dev,
					"Bus Regulator set_opt failed rc=%d\n",
					retval);
			}

			synaptics_rmi4_wakeup_gesture(rmi4_data, true);
			enable_irq_wake(rmi4_data->irq);
		}
@@ -4592,7 +4711,8 @@ exit:
	}
	mutex_unlock(&exp_data.mutex);

	if (!rmi4_data->suspend && !rmi4_data->enable_wakeup_gesture)
	if (!rmi4_data->suspend && !rmi4_data->enable_wakeup_gesture &&
			!rmi4_data->hw_if->board_data->dont_disable_regs)
		synaptics_rmi4_enable_reg(rmi4_data, false);

	rmi4_data->suspend = true;
@@ -4622,6 +4742,18 @@ static int synaptics_rmi4_resume(struct device *dev)

	if (rmi4_data->enable_wakeup_gesture) {
		if (rmi4_data->suspend) {
			/* Set active current for the bus regulator */
			if (rmi4_data->hw_if->board_data->bus_lpm_cur_uA) {
				retval = reg_set_optimum_mode_check(
						rmi4_data->bus_reg,
						I2C_ACTIVE_LOAD_UA);
				if (retval < 0)
					dev_err(dev,
					"Pwr regulator set_opt failed rc=%d\n",
					retval);
			}


			synaptics_rmi4_wakeup_gesture(rmi4_data, false);
			disable_irq_wake(rmi4_data->irq);
		}
@@ -4630,7 +4762,8 @@ static int synaptics_rmi4_resume(struct device *dev)

	rmi4_data->current_page = MASK_8BIT;

	if (rmi4_data->suspend)
	if (rmi4_data->suspend &&
			!rmi4_data->hw_if->board_data->dont_disable_regs)
		synaptics_rmi4_enable_reg(rmi4_data, true);

	synaptics_rmi4_sleep_enable(rmi4_data, false);
+7 −0
Original line number Diff line number Diff line
@@ -84,6 +84,9 @@ static int parse_dt(struct device *dev, struct synaptics_dsx_board_data *bdata)
	bdata->wakeup_gesture_en = of_property_read_bool(np,
			"synaptics,wakeup-gestures-en");

	bdata->dont_disable_regs = of_property_read_bool(np,
			"synaptics,do-not-disable-regulators");

	retval = of_property_read_string(np, "synaptics,pwr-reg-name", &name);
	if (retval < 0)
		bdata->pwr_reg_name = NULL;
@@ -184,6 +187,10 @@ static int parse_dt(struct device *dev, struct synaptics_dsx_board_data *bdata)
		bdata->max_y_for_2d = -1;
	}

	retval = of_property_read_u32(np, "synaptics,bus-lpm-cur-uA",
			&value);
	bdata->bus_lpm_cur_uA = retval < 0 ? 0 : value;

	prop = of_find_property(np, "synaptics,swap-axes", NULL);
	bdata->swap_axes = prop > 0 ? true : false;

+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct synaptics_dsx_button_map {
 * @y_flip: y flip flag
 * @swap_axes: swap axes flag
 * @resume_in_workqueue: defer resume function to workqueue
 * @resume_in_workqueue: do not disable/enable regulators in suspend/resume
 * @irq_gpio: attention interrupt GPIO
 * @irq_on_state: attention interrupt active state
 * @power_gpio: power switch GPIO
@@ -75,6 +76,7 @@ struct synaptics_dsx_button_map {
 * @power_delay_ms: delay time to wait after powering up device
 * @reset_delay_ms: delay time to wait after resetting device
 * @reset_active_ms: reset active time
 * @bus_lpm_cur_uA: low power mode current setting for bus
 * @byte_delay_us: delay time between two bytes of SPI data
 * @block_delay_us: delay time between two SPI transfers
 * @pwr_reg_name: pointer to name of regulator for power control
@@ -89,12 +91,14 @@ struct synaptics_dsx_board_data {
	bool swap_axes;
	bool resume_in_workqueue;
	bool wakeup_gesture_en;
	bool dont_disable_regs;
	int irq_gpio;
	int irq_on_state;
	int power_gpio;
	int power_on_state;
	int reset_gpio;
	int reset_on_state;
	int bus_lpm_cur_uA;
	int max_y_for_2d;
	unsigned long irq_flags;
	unsigned short i2c_addr;