Loading Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt +11 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,14 @@ Required properties: - focaltech,fw-upgrade-id2 : specify the upgrade id2 for firmware upgrade - focaltech,fw-delay-readid-ms : specify the read id delay in ms for firmware upgrade - focaltech,fw-delay-era-flsh-ms : specify the erase flash delay in ms for firmware upgrade - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. 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 properties: Loading @@ -61,6 +69,9 @@ Example: interrupts = <1 0x2>; vdd-supply = <&pm8110_l19>; vcc_i2c-supply = <&pm8110_l14>; pinctrl-names = "pmx_ts_active","pmx_ts_suspend"; pinctrl-0 = <&ts_int_active &ts_reset_active>; pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; focaltech,name = "ft6x06"; focaltech,family-id = <0x06>; focaltech,reset-gpio = <&msmgpio 0 0x00>; Loading drivers/input/touchscreen/ft5x06_ts.c +102 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,9 @@ struct ft5x06_ts_data { #elif defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend; #endif struct pinctrl *ts_pinctrl; struct pinctrl_state *gpio_state_active; struct pinctrl_state *gpio_state_suspend; }; static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf, Loading Loading @@ -496,6 +499,71 @@ pwr_deinit: return 0; } static int ft5x06_ts_pinctrl_init(struct ft5x06_ts_data *ft5x06_data) { int retval; /* Get pinctrl if target uses pinctrl */ ft5x06_data->ts_pinctrl = devm_pinctrl_get(&(ft5x06_data->client->dev)); if (IS_ERR_OR_NULL(ft5x06_data->ts_pinctrl)) { dev_dbg(&ft5x06_data->client->dev, "Target does not use pinctrl\n"); retval = PTR_ERR(ft5x06_data->ts_pinctrl); ft5x06_data->ts_pinctrl = NULL; return retval; } ft5x06_data->gpio_state_active = pinctrl_lookup_state(ft5x06_data->ts_pinctrl, "pmx_ts_active"); if (IS_ERR_OR_NULL(ft5x06_data->gpio_state_active)) { dev_dbg(&ft5x06_data->client->dev, "Can not get ts default pinstate\n"); retval = PTR_ERR(ft5x06_data->gpio_state_active); ft5x06_data->ts_pinctrl = NULL; return retval; } ft5x06_data->gpio_state_suspend = pinctrl_lookup_state(ft5x06_data->ts_pinctrl, "pmx_ts_suspend"); if (IS_ERR_OR_NULL(ft5x06_data->gpio_state_suspend)) { dev_err(&ft5x06_data->client->dev, "Can not get ts sleep pinstate\n"); retval = PTR_ERR(ft5x06_data->gpio_state_suspend); ft5x06_data->ts_pinctrl = NULL; return retval; } return 0; } static int ft5x06_ts_pinctrl_select(struct ft5x06_ts_data *ft5x06_data, bool on) { struct pinctrl_state *pins_state; int ret; pins_state = on ? ft5x06_data->gpio_state_active : ft5x06_data->gpio_state_suspend; if (!IS_ERR_OR_NULL(pins_state)) { ret = pinctrl_select_state(ft5x06_data->ts_pinctrl, pins_state); if (ret) { dev_err(&ft5x06_data->client->dev, "can not set %s pins\n", on ? "pmx_ts_active" : "pmx_ts_suspend"); return ret; } } else { dev_err(&ft5x06_data->client->dev, "not a valid '%s' pinstate\n", on ? "pmx_ts_active" : "pmx_ts_suspend"); } return 0; } #ifdef CONFIG_PM static int ft5x06_ts_suspend(struct device *dev) { Loading @@ -512,6 +580,11 @@ static int ft5x06_ts_suspend(struct device *dev) dev_info(dev, "Already in suspend state\n"); return 0; } if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) dev_err(dev, "Cannot get idle pinctrl state\n"); } disable_irq(data->client->irq); Loading Loading @@ -580,6 +653,11 @@ static int ft5x06_ts_resume(struct device *dev) return err; } } if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, true); if (err < 0) dev_err(dev, "Cannot get default pinctrl state\n"); } if (gpio_is_valid(data->pdata->reset_gpio)) { gpio_set_value_cansleep(data->pdata->reset_gpio, 0); Loading Loading @@ -1524,6 +1602,13 @@ static int ft5x06_ts_probe(struct i2c_client *client, } } err = ft5x06_ts_pinctrl_init(data); if (!err && data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, true); if (err < 0) goto pwr_off; } if (gpio_is_valid(pdata->irq_gpio)) { err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio"); if (err) { Loading Loading @@ -1703,9 +1788,19 @@ irq_free: free_reset_gpio: if (gpio_is_valid(pdata->reset_gpio)) gpio_free(pdata->reset_gpio); if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) pr_err("Cannot get idle pinctrl state\n"); } free_irq_gpio: if (gpio_is_valid(pdata->irq_gpio)) gpio_free(pdata->irq_gpio); if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) pr_err("Cannot get idle pinctrl state\n"); } pwr_off: if (pdata->power_on) pdata->power_on(false); Loading @@ -1727,6 +1822,7 @@ free_inputdev: static int ft5x06_ts_remove(struct i2c_client *client) { struct ft5x06_ts_data *data = i2c_get_clientdata(client); int retval; debugfs_remove_recursive(data->dir); device_remove_file(&client->dev, &dev_attr_force_update_fw); Loading @@ -1747,6 +1843,12 @@ static int ft5x06_ts_remove(struct i2c_client *client) if (gpio_is_valid(data->pdata->irq_gpio)) gpio_free(data->pdata->irq_gpio); if (data->ts_pinctrl) { retval = ft5x06_ts_pinctrl_select(data, false); if (retval < 0) pr_err("Cannot get idle pinctrl state\n"); } if (data->pdata->power_on) data->pdata->power_on(false); else Loading Loading
Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt +11 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,14 @@ Required properties: - focaltech,fw-upgrade-id2 : specify the upgrade id2 for firmware upgrade - focaltech,fw-delay-readid-ms : specify the read id delay in ms for firmware upgrade - focaltech,fw-delay-era-flsh-ms : specify the erase flash delay in ms for firmware upgrade - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. 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 properties: Loading @@ -61,6 +69,9 @@ Example: interrupts = <1 0x2>; vdd-supply = <&pm8110_l19>; vcc_i2c-supply = <&pm8110_l14>; pinctrl-names = "pmx_ts_active","pmx_ts_suspend"; pinctrl-0 = <&ts_int_active &ts_reset_active>; pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; focaltech,name = "ft6x06"; focaltech,family-id = <0x06>; focaltech,reset-gpio = <&msmgpio 0 0x00>; Loading
drivers/input/touchscreen/ft5x06_ts.c +102 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,9 @@ struct ft5x06_ts_data { #elif defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend; #endif struct pinctrl *ts_pinctrl; struct pinctrl_state *gpio_state_active; struct pinctrl_state *gpio_state_suspend; }; static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf, Loading Loading @@ -496,6 +499,71 @@ pwr_deinit: return 0; } static int ft5x06_ts_pinctrl_init(struct ft5x06_ts_data *ft5x06_data) { int retval; /* Get pinctrl if target uses pinctrl */ ft5x06_data->ts_pinctrl = devm_pinctrl_get(&(ft5x06_data->client->dev)); if (IS_ERR_OR_NULL(ft5x06_data->ts_pinctrl)) { dev_dbg(&ft5x06_data->client->dev, "Target does not use pinctrl\n"); retval = PTR_ERR(ft5x06_data->ts_pinctrl); ft5x06_data->ts_pinctrl = NULL; return retval; } ft5x06_data->gpio_state_active = pinctrl_lookup_state(ft5x06_data->ts_pinctrl, "pmx_ts_active"); if (IS_ERR_OR_NULL(ft5x06_data->gpio_state_active)) { dev_dbg(&ft5x06_data->client->dev, "Can not get ts default pinstate\n"); retval = PTR_ERR(ft5x06_data->gpio_state_active); ft5x06_data->ts_pinctrl = NULL; return retval; } ft5x06_data->gpio_state_suspend = pinctrl_lookup_state(ft5x06_data->ts_pinctrl, "pmx_ts_suspend"); if (IS_ERR_OR_NULL(ft5x06_data->gpio_state_suspend)) { dev_err(&ft5x06_data->client->dev, "Can not get ts sleep pinstate\n"); retval = PTR_ERR(ft5x06_data->gpio_state_suspend); ft5x06_data->ts_pinctrl = NULL; return retval; } return 0; } static int ft5x06_ts_pinctrl_select(struct ft5x06_ts_data *ft5x06_data, bool on) { struct pinctrl_state *pins_state; int ret; pins_state = on ? ft5x06_data->gpio_state_active : ft5x06_data->gpio_state_suspend; if (!IS_ERR_OR_NULL(pins_state)) { ret = pinctrl_select_state(ft5x06_data->ts_pinctrl, pins_state); if (ret) { dev_err(&ft5x06_data->client->dev, "can not set %s pins\n", on ? "pmx_ts_active" : "pmx_ts_suspend"); return ret; } } else { dev_err(&ft5x06_data->client->dev, "not a valid '%s' pinstate\n", on ? "pmx_ts_active" : "pmx_ts_suspend"); } return 0; } #ifdef CONFIG_PM static int ft5x06_ts_suspend(struct device *dev) { Loading @@ -512,6 +580,11 @@ static int ft5x06_ts_suspend(struct device *dev) dev_info(dev, "Already in suspend state\n"); return 0; } if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) dev_err(dev, "Cannot get idle pinctrl state\n"); } disable_irq(data->client->irq); Loading Loading @@ -580,6 +653,11 @@ static int ft5x06_ts_resume(struct device *dev) return err; } } if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, true); if (err < 0) dev_err(dev, "Cannot get default pinctrl state\n"); } if (gpio_is_valid(data->pdata->reset_gpio)) { gpio_set_value_cansleep(data->pdata->reset_gpio, 0); Loading Loading @@ -1524,6 +1602,13 @@ static int ft5x06_ts_probe(struct i2c_client *client, } } err = ft5x06_ts_pinctrl_init(data); if (!err && data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, true); if (err < 0) goto pwr_off; } if (gpio_is_valid(pdata->irq_gpio)) { err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio"); if (err) { Loading Loading @@ -1703,9 +1788,19 @@ irq_free: free_reset_gpio: if (gpio_is_valid(pdata->reset_gpio)) gpio_free(pdata->reset_gpio); if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) pr_err("Cannot get idle pinctrl state\n"); } free_irq_gpio: if (gpio_is_valid(pdata->irq_gpio)) gpio_free(pdata->irq_gpio); if (data->ts_pinctrl) { err = ft5x06_ts_pinctrl_select(data, false); if (err < 0) pr_err("Cannot get idle pinctrl state\n"); } pwr_off: if (pdata->power_on) pdata->power_on(false); Loading @@ -1727,6 +1822,7 @@ free_inputdev: static int ft5x06_ts_remove(struct i2c_client *client) { struct ft5x06_ts_data *data = i2c_get_clientdata(client); int retval; debugfs_remove_recursive(data->dir); device_remove_file(&client->dev, &dev_attr_force_update_fw); Loading @@ -1747,6 +1843,12 @@ static int ft5x06_ts_remove(struct i2c_client *client) if (gpio_is_valid(data->pdata->irq_gpio)) gpio_free(data->pdata->irq_gpio); if (data->ts_pinctrl) { retval = ft5x06_ts_pinctrl_select(data, false); if (retval < 0) pr_err("Cannot get idle pinctrl state\n"); } if (data->pdata->power_on) data->pdata->power_on(false); else Loading