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

Commit 51436926 authored by Himanshu Aggarwal's avatar Himanshu Aggarwal Committed by Sudhakar Manapati
Browse files

input: synaptics_i2c_rmi4: add support for pinctrl framework



Migrate the Synaptics driver to use pinctrl framework for GPIO
configuration so that driver is compatible with targets that
use and targets that don't use pinctrl framework.

This patch is propagated from msm-3.10 kernel
(commit: a63ff17c0f7bcbe678d66b5bdeb4a7e41aadb1df
input: synaptics_i2c_rmi4: add support for pinctrl framework)

Change-Id: Ib20fe5a01a1a06c783c69f9da5d1c8379597c542
Signed-off-by: default avatarHimanshu Aggarwal <haggarwa@codeaurora.org>
Signed-off-by: default avatarGuoping Yu <guopingy@codeaurora.org>
parent 174f3bce
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -9,7 +9,14 @@ Required properties:
				of fingers on the panel.
 - synaptics,irq-gpio	: irq gpio
 - synaptics,reset-gpio	: reset gpio

 - pinctrl-names : This should be defined if a target uses pinctrl framework.
			See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt.
			It should specify the names of the configs that pinctrl can install in driver.
			Following are the pinctrl configs that can be installed:
			"pmx_ts_active" : Active configuration of pins, this should specify active
			config defined in pin groups of interrupt and reset gpio.
			"pmx_ts_suspend" : Disabled configuration of pins, this should specify sleep
			config defined in pin groups of interrupt and reset gpio.
Optional property:
 - vdd-supply		: Analog power supply needed to power device
 - vcc_i2c-supply		: Power source required to pull up i2c bus
@@ -49,6 +56,10 @@ Example:
			interrupts = <17 0x2>;
			vdd-supply = <&pm8226_l19>;
			vcc_i2c-supply = <&pm8226_lvs1>;

			pinctrl-names = "pmx_ts_active","pmx_ts_suspend";
			pinctrl-0 = <&ts_int_active &ts_reset_active>;
			pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
			synaptics,reset-gpio = <&msmgpio 16 0x00>;
			synaptics,irq-gpio = <&msmgpio 17 0x00>;
			synaptics,button-map = [8B 66 9E];
+120 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/input/synaptics_dsx.h>
#include <linux/of_gpio.h>
#include "synaptics_i2c_rmi4.h"
@@ -2665,6 +2666,67 @@ power_off:
	return 0;
}

static int synaptics_rmi4_pinctrl_init(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;

	/* Get pinctrl if target uses pinctrl */
	rmi4_data->ts_pinctrl = devm_pinctrl_get(&(rmi4_data->i2c_client->dev));
	if (IS_ERR_OR_NULL(rmi4_data->ts_pinctrl)) {
		dev_dbg(&rmi4_data->i2c_client->dev,
			"Target does not use pinctrl\n");
		retval = PTR_ERR(rmi4_data->ts_pinctrl);
		rmi4_data->ts_pinctrl = NULL;
		return retval;
	}

	rmi4_data->gpio_state_active
		= pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_active");
	if (IS_ERR_OR_NULL(rmi4_data->gpio_state_active)) {
		dev_dbg(&rmi4_data->i2c_client->dev,
			"Can not get ts default pinstate\n");
		retval = PTR_ERR(rmi4_data->gpio_state_active);
		rmi4_data->ts_pinctrl = NULL;
		return retval;
	}

	rmi4_data->gpio_state_suspend
		= pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_suspend");
	if (IS_ERR_OR_NULL(rmi4_data->gpio_state_suspend)) {
		dev_dbg(&rmi4_data->i2c_client->dev,
			"Can not get ts sleep pinstate\n");
		retval = PTR_ERR(rmi4_data->gpio_state_suspend);
		rmi4_data->ts_pinctrl = NULL;
		return retval;
	}

	return 0;
}

static int synpatics_rmi4_pinctrl_select(struct synaptics_rmi4_data *rmi4_data,
						bool on)
{
	struct pinctrl_state *pins_state;
	int ret;

	pins_state = on ? rmi4_data->gpio_state_active
		: rmi4_data->gpio_state_suspend;
	if (!IS_ERR_OR_NULL(pins_state)) {
		ret = pinctrl_select_state(rmi4_data->ts_pinctrl, pins_state);
		if (ret) {
			dev_err(&rmi4_data->i2c_client->dev,
				"can not set %s pins\n",
				on ? "pmx_ts_active" : "pmx_ts_suspend");
			return ret;
		}
	} else
		dev_err(&rmi4_data->i2c_client->dev,
			"not a valid '%s' pinstate\n",
				on ? "pmx_ts_active" : "pmx_ts_suspend");

	return 0;
}

static int synaptics_rmi4_gpio_configure(struct synaptics_rmi4_data *rmi4_data,
					bool on)
{
@@ -2881,10 +2943,17 @@ static int synaptics_rmi4_probe(struct i2c_client *client,
		goto err_power_device;
	}

	retval = synaptics_rmi4_pinctrl_init(rmi4_data);
	if (!retval && rmi4_data->ts_pinctrl) {
		retval = synpatics_rmi4_pinctrl_select(rmi4_data, true);
		if (retval < 0)
			goto err_gpio_config;
	}

	retval = synaptics_rmi4_gpio_configure(rmi4_data, true);
	if (retval < 0) {
		dev_err(&client->dev, "Failed to configure gpios\n");
		goto err_gpio_config;
		goto pinctrl_sleep;
	}

	init_waitqueue_head(&rmi4_data->wait);
@@ -3085,6 +3154,12 @@ err_free_gpios:
		gpio_free(rmi4_data->board->reset_gpio);
	if (gpio_is_valid(rmi4_data->board->irq_gpio))
		gpio_free(rmi4_data->board->irq_gpio);
pinctrl_sleep:
	if (rmi4_data->ts_pinctrl) {
		retval = synpatics_rmi4_pinctrl_select(rmi4_data, false);
		if (retval < 0)
			pr_err("Cannot get idle pinctrl state\n");
	}
err_gpio_config:
	synaptics_rmi4_power_on(rmi4_data, false);
err_power_device:
@@ -3115,6 +3190,7 @@ static int synaptics_rmi4_remove(struct i2c_client *client)
	struct synaptics_rmi4_fn *next_fhandler;
	struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
	struct synaptics_rmi4_device_info *rmi;
	int retval;

	rmi = &(rmi4_data->rmi4_mod_info);

@@ -3155,6 +3231,12 @@ static int synaptics_rmi4_remove(struct i2c_client *client)
	if (gpio_is_valid(rmi4_data->board->irq_gpio))
		gpio_free(rmi4_data->board->irq_gpio);

	if (rmi4_data->ts_pinctrl) {
		retval = synpatics_rmi4_pinctrl_select(rmi4_data, false);
		if (retval < 0)
			pr_err("Cannot get idle pinctrl state\n");
	}

	synaptics_rmi4_power_on(rmi4_data, false);
	synaptics_rmi4_regulator_configure(rmi4_data, false);

@@ -3540,6 +3622,13 @@ static int synaptics_rmi4_suspend(struct device *dev)
	}

	if (rmi4_data->board->disable_gpios) {
		if (rmi4_data->ts_pinctrl) {
			retval = synpatics_rmi4_pinctrl_select(rmi4_data,
								 false);
			if (retval < 0)
				dev_err(dev, "Cannot get idle pinctrl state\n");
		}

		retval = synaptics_rmi4_gpio_configure(rmi4_data, false);
		if (retval < 0) {
			dev_err(dev, "failed to put gpios in suspend state\n");
@@ -3551,6 +3640,11 @@ static int synaptics_rmi4_suspend(struct device *dev)
	return 0;

err_gpio_configure:
	if (rmi4_data->ts_pinctrl) {
		retval = synpatics_rmi4_pinctrl_select(rmi4_data, true);
		if (retval < 0)
			dev_err(dev, "Cannot get default pinctrl state\n");
	}
	synaptics_rmi4_regulator_lpm(rmi4_data, false);

err_lpm_regulator:
@@ -3593,6 +3687,12 @@ static int synaptics_rmi4_resume(struct device *dev)
	}

	if (rmi4_data->board->disable_gpios) {
		if (rmi4_data->ts_pinctrl) {
			retval = synpatics_rmi4_pinctrl_select(rmi4_data, true);
			if (retval < 0)
				dev_err(dev, "Cannot get default pinctrl state\n");
		}

		retval = synaptics_rmi4_gpio_configure(rmi4_data, true);
		if (retval < 0) {
			dev_err(dev, "Failed to put gpios in active state\n");
@@ -3618,9 +3718,27 @@ err_check_configuration:
	rmi4_data->touch_stopped = true;
	synaptics_rmi4_sensor_sleep(rmi4_data);

	if (rmi4_data->board->disable_gpios)
	if (rmi4_data->board->disable_gpios) {
		if (rmi4_data->ts_pinctrl) {
			retval = synpatics_rmi4_pinctrl_select(rmi4_data,
								false);
			if (retval < 0)
				dev_err(dev, "Cannot get idle pinctrl state\n");
		}

		synaptics_rmi4_gpio_configure(rmi4_data, false);
	}
	synaptics_rmi4_regulator_lpm(rmi4_data, true);
	wake_up(&rmi4_data->wait);

	return retval;

err_gpio_configure:
	if (rmi4_data->ts_pinctrl) {
		retval = synpatics_rmi4_pinctrl_select(rmi4_data, false);
		if (retval < 0)
			pr_err("Cannot get idle pinctrl state\n");
	}
	synaptics_rmi4_regulator_lpm(rmi4_data, true);
	wake_up(&rmi4_data->wait);

+4 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *
 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2014, 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 as published by
@@ -263,6 +263,9 @@ struct synaptics_rmi4_data {
	struct early_suspend early_suspend;
#endif
#endif
	struct pinctrl *ts_pinctrl;
	struct pinctrl_state *gpio_state_active;
	struct pinctrl_state *gpio_state_suspend;
};

enum exp_fn {