Skip to content

Commit

Permalink
Input: atmel_mxt_ts - release touch state during suspend
Browse files Browse the repository at this point in the history
If fingers are down as the MXT chip goes into suspend it does not send a
lift message. In addition, it may not complete its final measurement cycle
immediately, which means touch messages may be received by the interrupt
handler after mxt_stop() has completed.

So:
- disable irq during suspend
- flush any messages created after suspend
- tell app layer that slots were released at suspend

Signed-off-by: Nick Dyer <[email protected]>
Acked-by: Benson Leung <[email protected]>
Acked-by: Yufeng Shen <[email protected]>
  • Loading branch information
ndyer committed Apr 26, 2016
1 parent cb98986 commit 2679443
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions drivers/input/touchscreen/atmel_mxt_ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ struct mxt_data {

/* for config update handling */
struct completion crc_completion;

/* Indicates whether device is in suspend */
bool suspended;
};

static size_t mxt_obj_size(const struct mxt_object *obj)
Expand Down Expand Up @@ -1079,10 +1082,10 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
mxt_proc_t42_messages(data, message);
} else if (report_id == data->T48_reportid) {
mxt_proc_t48_messages(data, message);
} else if (!data->input_dev) {
} else if (!data->input_dev || data->suspended) {
/*
* Do not report events if input device
* is not yet registered.
* Do not report events if input device is not
* yet registered or returning from suspend
*/
mxt_dump_message(data, message);
} else if (report_id >= data->T9_reportid_min &&
Expand Down Expand Up @@ -2605,6 +2608,11 @@ static int mxt_load_fw(struct device *dev, const char *fn)
if (ret)
goto release_firmware;

if (data->suspended) {
enable_irq(data->irq);
data->suspended = false;
}

if (!data->in_bootloader) {
/* Change to the bootloader mode */
data->in_bootloader = true;
Expand Down Expand Up @@ -2720,6 +2728,8 @@ static ssize_t mxt_update_fw_store(struct device *dev,
} else {
dev_info(dev, "The firmware update succeeded\n");

data->suspended = false;

error = mxt_initialize(data);
if (error)
return error;
Expand Down Expand Up @@ -2776,8 +2786,27 @@ static void mxt_sysfs_remove(struct mxt_data *data)
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
}

static void mxt_reset_slots(struct mxt_data *data)
{
struct input_dev *input_dev = data->input_dev;
int id;

if (!input_dev)
return;

for (id = 0; id < data->num_touchids; id++) {
input_mt_slot(input_dev, id);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
}

mxt_input_sync(data);
}

static void mxt_start(struct mxt_data *data)
{
if (!data->suspended || data->in_bootloader)
return;

switch (data->pdata->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
mxt_soft_reset(data);
Expand All @@ -2790,17 +2819,29 @@ static void mxt_start(struct mxt_data *data)

case MXT_SUSPEND_DEEP_SLEEP:
default:
/*
* Discard any touch messages still in message buffer
* from before chip went to sleep
*/
mxt_process_messages_until_invalid(data);

mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);

/* Recalibrate since chip has been in deep sleep */
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);

mxt_acquire_irq(data);
break;
}

data->suspended = false;
}

static void mxt_stop(struct mxt_data *data)
{
if (data->suspended || data->in_bootloader)
return;

switch (data->pdata->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
/* Touch disable */
Expand All @@ -2810,9 +2851,15 @@ static void mxt_stop(struct mxt_data *data)

case MXT_SUSPEND_DEEP_SLEEP:
default:
disable_irq(data->irq);

mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);

mxt_reset_slots(data);
break;
}

data->suspended = true;
}

static int mxt_input_open(struct input_dev *dev)
Expand Down

0 comments on commit 2679443

Please sign in to comment.