summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/atmel_mxt_ts.c
diff options
context:
space:
mode:
authorXiaohui Tao <xtao@nvidia.com>2012-10-23 12:24:13 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 12:40:38 -0700
commit577e90fc6d0f5ee6b1b613b6264e449020bc5717 (patch)
treea6b3619c770311f9158e50d9aec1efe5a626a118 /drivers/input/touchscreen/atmel_mxt_ts.c
parentf65d0a53d773ca8dd7f9f1cc7c0f16bebd1d5a15 (diff)
input:atmel_mxt - add regulator support
Bug 1063749 Change-Id: I47f9f312fbbda99e0746f5017d30d91a38037e35 Signed-off-by: Xiaohui Tao <xtao@nvidia.com> Reviewed-on: http://git-master/r/147118 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com> Reviewed-by: Robert Collins <rcollins@nvidia.com> Rebase-Id: R928aeb27087120eeefa1b34356125ffbc92ec207
Diffstat (limited to 'drivers/input/touchscreen/atmel_mxt_ts.c')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 9376d5ea3fd3..da419759d537 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -22,6 +22,8 @@
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
#define CREATE_TRACE_POINTS
#include <trace/events/nvevent.h>
@@ -312,6 +314,8 @@ struct mxt_data {
const struct mxt_platform_data *pdata;
enum mxt_device_state state;
struct mxt_object *object_table;
+ struct regulator *regulator_vdd;
+ struct regulator *regulator_avdd;
u16 mem_size;
struct mxt_info info;
unsigned int irq;
@@ -1808,6 +1812,54 @@ static int mxt_read_resolution(struct mxt_data *data)
return 0;
}
+static void mxt_initialize_regulator(struct mxt_data *data)
+{
+ int ret;
+ struct i2c_client *client = data->client;
+
+ /*
+ Vdd and AVdd can be powered up in any order
+ XVdd must not be powered up until after Vdd
+ and must obey the rate-of-rise specification
+ */
+
+ data->regulator_vdd = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR(data->regulator_vdd)) {
+ dev_info(&client->dev,
+ "Atmel regulator_get for vdd failed: %ld\n",
+ PTR_ERR(data->regulator_vdd));
+ goto err_null_regulator;
+ }
+
+ data->regulator_avdd = devm_regulator_get(&client->dev, "avdd");
+ if (IS_ERR(data->regulator_avdd)) {
+ dev_info(&client->dev,
+ "Atmel regulator_get for avdd failed: %ld\n",
+ PTR_ERR(data->regulator_avdd));
+ goto err_put_regulator;
+ }
+
+ dev_info(&client->dev,
+ "Atmel regulator_get for vdd and avdd succeeded\n");
+
+ ret = regulator_enable(data->regulator_vdd);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "Atmel regulator_enable for vdd failed; Error code:%d\n", ret);
+
+ ret = regulator_enable(data->regulator_avdd);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "Atmel regulator_enable for avdd failed; Error code:%d\n", ret);
+ return;
+
+err_put_regulator:
+ devm_regulator_put(data->regulator_vdd);
+err_null_regulator:
+ data->regulator_avdd = NULL;
+ data->regulator_vdd = NULL;
+}
+
static int mxt_initialize(struct mxt_data *data)
{
struct i2c_client *client = data->client;
@@ -2485,10 +2537,12 @@ static int mxt_probe(struct i2c_client *client,
data->pdata = pdata;
data->irq = client->irq;
+ mxt_initialize_regulator(data);
+
/* Initialize i2c device */
error = mxt_initialize(data);
if (error)
- goto err_free_data;
+ goto err_disable_regulator;
error = mxt_initialize_input_device(data);
if (error)
@@ -2533,6 +2587,9 @@ err_free_input_device:
err_free_object:
kfree(data->msg_buf);
kfree(data->object_table);
+err_disable_regulator:
+ regulator_disable(data->regulator_avdd);
+ regulator_disable(data->regulator_vdd);
err_free_data:
kfree(data);
return error;
@@ -2550,6 +2607,8 @@ static int mxt_remove(struct i2c_client *client)
data->msg_buf = NULL;
kfree(data->object_table);
data->object_table = NULL;
+ regulator_disable(data->regulator_avdd);
+ regulator_disable(data->regulator_vdd);
kfree(data);
data = NULL;
@@ -2559,6 +2618,7 @@ static int mxt_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int mxt_suspend(struct device *dev)
{
+ int ret;
struct i2c_client *client = to_i2c_client(dev);
struct mxt_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
@@ -2570,15 +2630,42 @@ static int mxt_suspend(struct device *dev)
mutex_unlock(&input_dev->mutex);
+ if (data->regulator_vdd && data->regulator_avdd) {
+ ret = regulator_disable(data->regulator_avdd);
+ if (ret < 0) {
+ dev_err(dev,
+ "Atmel regulator disable for avdd failed: %d\n", ret);
+ }
+ ret = regulator_disable(data->regulator_vdd);
+ if (ret < 0) {
+ dev_err(dev,
+ "Atmel regulator disable for vdd failed: %d\n", ret);
+ }
+ }
+
return 0;
}
static int mxt_resume(struct device *dev)
{
+ int ret;
struct i2c_client *client = to_i2c_client(dev);
struct mxt_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
+ if (data->regulator_vdd && data->regulator_avdd) {
+ ret = regulator_enable(data->regulator_vdd);
+ if (ret < 0) {
+ dev_err(dev,
+ "Atmel regulator enable for vdd failed: %d\n", ret);
+ }
+ ret = regulator_enable(data->regulator_avdd);
+ if (ret < 0) {
+ dev_err(dev,
+ "Atmel regulator enable for avdd failed: %d\n", ret);
+ }
+ }
+
mutex_lock(&input_dev->mutex);
if (input_dev->users)