input: atmel_mxt_ts: put device in LPM from T7 and T9
Signed-off-by: Amy Maloche <amaloche@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
95b98f25a8
commit
33f1771e6d
@@ -234,6 +234,9 @@
|
||||
|
||||
#define MXT_MAX_FINGER 10
|
||||
|
||||
#define MXT_BUFF_SIZE 100
|
||||
#define T7_DATA_SIZE 3
|
||||
|
||||
struct mxt_info {
|
||||
u8 family_id;
|
||||
u8 variant_id;
|
||||
@@ -285,6 +288,8 @@ struct mxt_data {
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
u8 t7_data[T7_DATA_SIZE];
|
||||
u8 t9_ctrl;
|
||||
};
|
||||
|
||||
static bool mxt_object_readable(unsigned int type)
|
||||
@@ -865,7 +870,7 @@ static int mxt_initialize(struct mxt_data *data)
|
||||
{
|
||||
struct i2c_client *client = data->client;
|
||||
struct mxt_info *info = &data->info;
|
||||
int error;
|
||||
int error, i;
|
||||
int timeout_counter = 0;
|
||||
u8 val;
|
||||
u8 command_register;
|
||||
@@ -892,6 +897,23 @@ static int mxt_initialize(struct mxt_data *data)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Store T7 and T9 locally, used in suspend/resume operations */
|
||||
for (i = 0; i < T7_DATA_SIZE; i++) {
|
||||
error = mxt_read_object(data, MXT_GEN_POWER, i,
|
||||
&data->t7_data[i]);
|
||||
if (error < 0) {
|
||||
dev_err(&client->dev,
|
||||
"failed to save current power state\n");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
error = mxt_read_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_CTRL,
|
||||
&data->t9_ctrl);
|
||||
if (error < 0) {
|
||||
dev_err(&client->dev, "failed to save current touch object\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
mxt_handle_pdata(data);
|
||||
|
||||
/* Backup to memory */
|
||||
@@ -1123,25 +1145,63 @@ static const struct attribute_group mxt_attr_group = {
|
||||
.attrs = mxt_attrs,
|
||||
};
|
||||
|
||||
static void mxt_start(struct mxt_data *data)
|
||||
static int mxt_start(struct mxt_data *data)
|
||||
{
|
||||
/* Touch enable */
|
||||
mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
|
||||
int i, error;
|
||||
/* restore the old power state values and reenable touch */
|
||||
for (i = 0; i < T7_DATA_SIZE; i++) {
|
||||
error = mxt_write_object(data, MXT_GEN_POWER, i,
|
||||
data->t7_data[i]);
|
||||
if (error < 0) {
|
||||
dev_err(&data->client->dev,
|
||||
"failed to restore old power state\n");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
error = mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, data->t9_ctrl);
|
||||
if (error < 0) {
|
||||
dev_err(&data->client->dev, "failed to restore touch\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxt_stop(struct mxt_data *data)
|
||||
static int mxt_stop(struct mxt_data *data)
|
||||
{
|
||||
/* Touch disable */
|
||||
mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
|
||||
int i, error;
|
||||
/* configure deep sleep mode and disable touch */
|
||||
for (i = 0; i < T7_DATA_SIZE; i++) {
|
||||
error = mxt_write_object(data, MXT_GEN_POWER, i, 0);
|
||||
if (error < 0) {
|
||||
dev_err(&data->client->dev,
|
||||
"failed to configure deep sleep mode\n");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
error = mxt_write_object(data,
|
||||
MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0);
|
||||
if (error < 0) {
|
||||
dev_err(&data->client->dev,
|
||||
"failed to disable touch\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_input_open(struct input_dev *dev)
|
||||
{
|
||||
struct mxt_data *data = input_get_drvdata(dev);
|
||||
int error;
|
||||
|
||||
mxt_start(data);
|
||||
error = mxt_start(data);
|
||||
if (error < 0) {
|
||||
dev_err(&data->client->dev, "mxt_start failed in input_open\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1149,8 +1209,12 @@ static int mxt_input_open(struct input_dev *dev)
|
||||
static void mxt_input_close(struct input_dev *dev)
|
||||
{
|
||||
struct mxt_data *data = input_get_drvdata(dev);
|
||||
int error;
|
||||
|
||||
error = mxt_stop(data);
|
||||
if (error < 0)
|
||||
dev_err(&data->client->dev, "mxt_stop failed in input_close\n");
|
||||
|
||||
mxt_stop(data);
|
||||
}
|
||||
|
||||
static int mxt_power_on(struct mxt_data *data, bool on)
|
||||
@@ -1288,11 +1352,19 @@ static int mxt_suspend(struct device *dev)
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mxt_data *data = i2c_get_clientdata(client);
|
||||
struct input_dev *input_dev = data->input_dev;
|
||||
int error;
|
||||
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
if (input_dev->users)
|
||||
mxt_stop(data);
|
||||
if (input_dev->users) {
|
||||
error = mxt_stop(data);
|
||||
if (error < 0) {
|
||||
dev_err(&client->dev, "mxt_stop failed in suspend\n");
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
|
||||
@@ -1304,7 +1376,7 @@ static int mxt_resume(struct device *dev)
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mxt_data *data = i2c_get_clientdata(client);
|
||||
struct input_dev *input_dev = data->input_dev;
|
||||
|
||||
int error;
|
||||
/* Soft reset */
|
||||
mxt_write_object(data, MXT_GEN_COMMAND_T6,
|
||||
MXT_COMMAND_RESET, 1);
|
||||
@@ -1313,8 +1385,14 @@ static int mxt_resume(struct device *dev)
|
||||
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
if (input_dev->users)
|
||||
mxt_start(data);
|
||||
if (input_dev->users) {
|
||||
error = mxt_start(data);
|
||||
if (error < 0) {
|
||||
dev_err(&client->dev, "mxt_start failed in resume\n");
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user