From 4c2063bfb3e9378e0e5925ef4118342fa89bf019 Mon Sep 17 00:00:00 2001 From: Shantanu Jain Date: Mon, 10 Aug 2015 23:37:35 +0530 Subject: [PATCH] input: it7258_ts_i2c: add pinctrl support Add pinctrl support for ITE tech touchscreen driver. Change-Id: I3bbea110af189f236bb175670210e086e15d5d2d Signed-off-by: Shantanu Jain --- .../bindings/input/touchscreen/it7258_ts_i2c.txt | 15 +++ drivers/input/touchscreen/it7258_ts_i2c.c | 137 +++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/it7258_ts_i2c.txt b/Documentation/devicetree/bindings/input/touchscreen/it7258_ts_i2c.txt index b06aca1755b9..a43eb3a49feb 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/it7258_ts_i2c.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/it7258_ts_i2c.txt @@ -31,6 +31,16 @@ Optional properties: - ite,display-coords : display min x, min y, max x and max y resolution - ite,num-fingers : number of fingers supported by the touch controller + - 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. + "pmx_ts_release" : Release configuration of pins, this should specify + release config defined in pin groups of interrupt and reset gpio. Required properties palm-detect-en feature: - ite,palm-detect-keycode : The keycode that is required to be sent when @@ -42,6 +52,11 @@ Example: compatible = "ite,it7260_ts"; reg = <0x46>; interrupt-parent = <&msmgpio>; + /* pins used by touchscreen */ + pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + pinctrl-2 = <&ts_release> interrupts = <17 0x2>; avdd-supply = <&pm8226_l19>; vdd-supply = <&pm8226_lvs1>; diff --git a/drivers/input/touchscreen/it7258_ts_i2c.c b/drivers/input/touchscreen/it7258_ts_i2c.c index 66938856ed6b..2a161cdd75ea 100644 --- a/drivers/input/touchscreen/it7258_ts_i2c.c +++ b/drivers/input/touchscreen/it7258_ts_i2c.c @@ -127,6 +127,10 @@ #define IT_I2C_VTG_MIN_UV 2600000 #define IT_I2C_VTG_MAX_UV 3300000 +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" +#define PINCTRL_STATE_RELEASE "pmx_ts_release" + struct FingerData { uint8_t xLo; uint8_t hi; @@ -184,6 +188,10 @@ struct IT7260_ts_data { struct notifier_block fb_notif; #endif struct dentry *dir; + struct pinctrl *ts_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; + struct pinctrl_state *pinctrl_state_release; }; /* Function declarations */ @@ -1269,6 +1277,60 @@ static inline int IT7260_ts_parse_dt(struct device *dev, } #endif +static int IT7260_ts_pinctrl_init(struct IT7260_ts_data *ts_data) +{ + int retval; + + /* Get pinctrl if target uses pinctrl */ + ts_data->ts_pinctrl = devm_pinctrl_get(&(ts_data->client->dev)); + if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) { + retval = PTR_ERR(ts_data->ts_pinctrl); + dev_dbg(&ts_data->client->dev, + "Target does not use pinctrl %d\n", retval); + goto err_pinctrl_get; + } + + ts_data->pinctrl_state_active + = pinctrl_lookup_state(ts_data->ts_pinctrl, + PINCTRL_STATE_ACTIVE); + if (IS_ERR_OR_NULL(ts_data->pinctrl_state_active)) { + retval = PTR_ERR(ts_data->pinctrl_state_active); + dev_err(&ts_data->client->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, retval); + goto err_pinctrl_lookup; + } + + ts_data->pinctrl_state_suspend + = pinctrl_lookup_state(ts_data->ts_pinctrl, + PINCTRL_STATE_SUSPEND); + if (IS_ERR_OR_NULL(ts_data->pinctrl_state_suspend)) { + retval = PTR_ERR(ts_data->pinctrl_state_suspend); + dev_err(&ts_data->client->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, retval); + goto err_pinctrl_lookup; + } + + ts_data->pinctrl_state_release + = pinctrl_lookup_state(ts_data->ts_pinctrl, + PINCTRL_STATE_RELEASE); + if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) { + retval = PTR_ERR(ts_data->pinctrl_state_release); + dev_dbg(&ts_data->client->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_RELEASE, retval); + } + + return 0; + +err_pinctrl_lookup: + devm_pinctrl_put(ts_data->ts_pinctrl); +err_pinctrl_get: + ts_data->ts_pinctrl = NULL; + return retval; +} + static int IT7260_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1358,6 +1420,22 @@ static int IT7260_ts_probe(struct i2c_client *client, } } + ret = IT7260_ts_pinctrl_init(gl_ts); + if (!ret && gl_ts->ts_pinctrl) { + /* + * Pinctrl handle is optional. If pinctrl handle is found + * let pins to be configured in active state. If not + * found continue further without error. + */ + ret = pinctrl_select_state(gl_ts->ts_pinctrl, + gl_ts->pinctrl_state_active); + if (ret < 0) { + dev_err(&gl_ts->client->dev, + "failed to select pin to active state %d", + ret); + } + } + /* reset gpio info */ if (gpio_is_valid(pdata->reset_gpio)) { if (gpio_request(pdata->reset_gpio, "ite_reset_gpio")) { @@ -1511,6 +1589,19 @@ err_identification_fail: if (gpio_is_valid(pdata->irq_gpio)) gpio_free(pdata->irq_gpio); + if (gl_ts->ts_pinctrl) { + if (IS_ERR_OR_NULL(gl_ts->pinctrl_state_release)) { + devm_pinctrl_put(gl_ts->ts_pinctrl); + gl_ts->ts_pinctrl = NULL; + } else { + ret = pinctrl_select_state(gl_ts->ts_pinctrl, + gl_ts->pinctrl_state_release); + if (ret) + dev_err(&gl_ts->client->dev, + "failed to select relase pinctrl state %d\n", + ret); + } + } regulator_disable(gl_ts->vdd); regulator_disable(gl_ts->avdd); regulator_put(gl_ts->vdd); @@ -1521,6 +1612,8 @@ err_identification_fail: static int IT7260_ts_remove(struct i2c_client *client) { + int ret; + debugfs_remove_recursive(gl_ts->dir); #if defined(CONFIG_FB) if (fb_unregister_client(&gl_ts->fb_notif)) @@ -1540,6 +1633,19 @@ static int IT7260_ts_remove(struct i2c_client *client) gpio_free(gl_ts->pdata->reset_gpio); if (gpio_is_valid(gl_ts->pdata->irq_gpio)) gpio_free(gl_ts->pdata->irq_gpio); + if (gl_ts->ts_pinctrl) { + if (IS_ERR_OR_NULL(gl_ts->pinctrl_state_release)) { + devm_pinctrl_put(gl_ts->ts_pinctrl); + gl_ts->ts_pinctrl = NULL; + } else { + ret = pinctrl_select_state(gl_ts->ts_pinctrl, + gl_ts->pinctrl_state_release); + if (ret) + dev_err(&gl_ts->client->dev, + "failed to select relase pinctrl state %d\n", + ret); + } + } regulator_disable(gl_ts->vdd); regulator_disable(gl_ts->avdd); regulator_put(gl_ts->vdd); @@ -1572,6 +1678,8 @@ static int fb_notifier_callback(struct notifier_block *self, #ifdef CONFIG_PM static int IT7260_ts_resume(struct device *dev) { + int retval; + if (device_may_wakeup(dev)) { if (gl_ts->device_needs_wakeup) { gl_ts->device_needs_wakeup = false; @@ -1580,13 +1688,28 @@ static int IT7260_ts_resume(struct device *dev) return 0; } + if (gl_ts->ts_pinctrl) { + retval = pinctrl_select_state(gl_ts->ts_pinctrl, + gl_ts->pinctrl_state_active); + if (retval < 0) { + dev_err(dev, "Cannot get default pinctrl state %d\n", + retval); + goto err_pinctrl_select_suspend; + } + } + enable_irq(gl_ts->client->irq); gl_ts->suspended = false; return 0; + +err_pinctrl_select_suspend: + return retval; } static int IT7260_ts_suspend(struct device *dev) { + int retval; + if (gl_ts->fw_cfg_uploading) { dev_dbg(dev, "Fw/cfg uploading. Can't go to suspend.\n"); return -EBUSY; @@ -1606,9 +1729,23 @@ static int IT7260_ts_suspend(struct device *dev) disable_irq(gl_ts->client->irq); IT7260_ts_release_all(); + + if (gl_ts->ts_pinctrl) { + retval = pinctrl_select_state(gl_ts->ts_pinctrl, + gl_ts->pinctrl_state_suspend); + if (retval < 0) { + dev_err(dev, "Cannot get idle pinctrl state %d\n", + retval); + goto err_pinctrl_select_suspend; + } + } + gl_ts->suspended = true; return 0; + +err_pinctrl_select_suspend: + return retval; } static const struct dev_pm_ops IT7260_ts_dev_pm_ops = { -- 2.11.0