From eeaabccc1c7b5220d8d5674669662e8ca0c07ec0 Mon Sep 17 00:00:00 2001 From: Bingzhe Cai Date: Tue, 6 May 2014 19:26:33 +0800 Subject: input: sensors: pull down 8916SKUH sensor GPIOs for power saving As sensor will power down during suspend, those GPIOs used by sensors also need pull down to minimize leakage. CRs-fixed: 655099 Change-Id: If9463e0cc89675204b9b4bee5eca2dd5a44515a5 Signed-off-by: Bingzhe Cai --- drivers/input/misc/lis3dh_acc.c | 62 +++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/lis3dh_acc.c b/drivers/input/misc/lis3dh_acc.c index d58ec0d5c374..662c27fe64c3 100644 --- a/drivers/input/misc/lis3dh_acc.c +++ b/drivers/input/misc/lis3dh_acc.c @@ -221,6 +221,9 @@ struct lis3dh_acc_data { struct i2c_client *client; struct lis3dh_acc_platform_data *pdata; struct sensors_classdev cdev; + struct pinctrl *pinctrl; + struct pinctrl_state *pin_default; + struct pinctrl_state *pin_sleep; struct mutex lock; struct delayed_work input_work; @@ -513,11 +516,6 @@ static void lis3dh_acc_device_power_off(struct lis3dh_acc_data *acc) if (err < 0) dev_err(&acc->client->dev, "soft power off failed: %d\n", err); - if (gpio_is_valid(acc->pdata->gpio_int1)) - disable_irq_nosync(acc->irq1); - if (gpio_is_valid(acc->pdata->gpio_int2)) - disable_irq_nosync(acc->irq2); - lis3dh_acc_config_regulator(acc, false); if (acc->hw_initialized) { @@ -540,10 +538,6 @@ static int lis3dh_acc_device_power_on(struct lis3dh_acc_data *acc) return err; } - if (gpio_is_valid(acc->pdata->gpio_int1)) - enable_irq(acc->irq1); - if (gpio_is_valid(acc->pdata->gpio_int2)) - enable_irq(acc->irq2); msleep(20); @@ -774,6 +768,10 @@ static int lis3dh_acc_enable(struct lis3dh_acc_data *acc) int err; if (!atomic_cmpxchg(&acc->enabled, 0, 1)) { + if (pinctrl_select_state(acc->pinctrl, acc->pin_default)) + dev_err(&acc->client->dev, + "Can't select pinctrl default state\n"); + err = lis3dh_acc_device_power_on(acc); if (err < 0) { atomic_set(&acc->enabled, 0); @@ -791,6 +789,9 @@ static int lis3dh_acc_disable(struct lis3dh_acc_data *acc) if (atomic_cmpxchg(&acc->enabled, 1, 0)) { cancel_delayed_work_sync(&acc->input_work); lis3dh_acc_device_power_off(acc); + if (pinctrl_select_state(acc->pinctrl, acc->pin_sleep)) + dev_err(&acc->client->dev, + "Can't select pinctrl sleep state\n"); } return 0; @@ -1300,6 +1301,33 @@ static void lis3dh_acc_input_cleanup(struct lis3dh_acc_data *acc) input_free_device(acc->input_dev); } +static int lis3dh_pinctrl_init(struct lis3dh_acc_data *acc) +{ + struct i2c_client *client = acc->client; + + acc->pinctrl = devm_pinctrl_get(&client->dev); + if (IS_ERR_OR_NULL(acc->pinctrl)) { + dev_err(&client->dev, "Failed to get pinctrl\n"); + return PTR_ERR(acc->pinctrl); + } + + acc->pin_default = + pinctrl_lookup_state(acc->pinctrl, "lis3dh_default"); + if (IS_ERR_OR_NULL(acc->pin_default)) { + dev_err(&client->dev, "Failed to look up default state\n"); + return PTR_ERR(acc->pin_default); + } + + acc->pin_sleep = + pinctrl_lookup_state(acc->pinctrl, "lis3dh_sleep"); + if (IS_ERR_OR_NULL(acc->pin_sleep)) { + dev_err(&client->dev, "Failed to look up sleep state\n"); + return PTR_ERR(acc->pin_sleep); + } + + return 0; +} + #ifdef CONFIG_OF static int lis3dh_parse_dt(struct device *dev, struct lis3dh_acc_platform_data *pdata) @@ -1454,6 +1482,18 @@ static int lis3dh_acc_probe(struct i2c_client *client, goto exit_kfree_pdata; } + /* initialize pinctrl */ + err = lis3dh_pinctrl_init(acc); + if (err) { + dev_err(&client->dev, "Can't initialize pinctrl\n"); + goto exit_kfree_pdata; + } + err = pinctrl_select_state(acc->pinctrl, acc->pin_default); + if (err) { + dev_err(&client->dev, + "Can't select pinctrl default state\n"); + goto exit_kfree_pdata; + } if (acc->pdata->init) { err = acc->pdata->init(); @@ -1579,6 +1619,10 @@ static int lis3dh_acc_probe(struct i2c_client *client, disable_irq_nosync(acc->irq2); } + if (pinctrl_select_state(acc->pinctrl, acc->pin_sleep)) + dev_err(&client->dev, + "Can't select pinctrl sleep state\n"); + mutex_unlock(&acc->lock); dev_dbg(&client->dev, "%s: probed\n", LIS3DH_ACC_DEV_NAME); -- cgit v1.2.3