Skip to content

Commit

Permalink
Input: atmel_mxt_ts - implement CRC check for configuration data
Browse files Browse the repository at this point in the history
The configuration is stored in NVRAM on the maXTouch chip. When the device
is reset it reports a CRC of the stored configuration values. Therefore it
isn't necessary to send the configuration on each probe - we can check the
CRC matches and avoid a timeconsuming backup/reset cycle.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Nick Dyer authored and Dmitry Torokhov committed May 19, 2014
1 parent 7bed680 commit c3f7804
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
60 changes: 52 additions & 8 deletions drivers/input/touchscreen/atmel_mxt_ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
#define MXT_BACKUP_TIME 50 /* msec */
#define MXT_RESET_TIME 200 /* msec */
#define MXT_RESET_TIMEOUT 3000 /* msec */
#define MXT_CRC_TIMEOUT 1000 /* msec */
#define MXT_FW_RESET_TIME 3000 /* msec */
#define MXT_FW_CHG_TIMEOUT 300 /* msec */

Expand Down Expand Up @@ -259,6 +260,7 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool in_bootloader;
u32 config_crc;

/* Cached parameters from object table */
u8 T6_reportid;
Expand All @@ -272,6 +274,9 @@ struct mxt_data {

/* for reset handling */
struct completion reset_completion;

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

static size_t mxt_obj_size(const struct mxt_object *obj)
Expand Down Expand Up @@ -636,7 +641,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
}
}

static unsigned mxt_extract_T6_csum(const u8 *csum)
static u16 mxt_extract_T6_csum(const u8 *csum)
{
return csum[0] | (csum[1] << 8) | (csum[2] << 16);
}
Expand All @@ -654,6 +659,7 @@ static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
struct device *dev = &data->client->dev;
u8 reportid;
bool update_input = false;
u32 crc;

do {
if (mxt_read_message(data, &message)) {
Expand All @@ -665,9 +671,15 @@ static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)

if (reportid == data->T6_reportid) {
u8 status = payload[0];
unsigned csum = mxt_extract_T6_csum(&payload[1]);

crc = mxt_extract_T6_csum(&payload[1]);
if (crc != data->config_crc) {
data->config_crc = crc;
complete(&data->crc_completion);
}

dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
status, csum);
status, data->config_crc);

if (status & MXT_T6_STATUS_RESET)
complete(&data->reset_completion);
Expand Down Expand Up @@ -757,6 +769,24 @@ static int mxt_soft_reset(struct mxt_data *data)
return 0;
}

static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value)
{
/*
* On failure, CRC is set to 0 and config will always be
* downloaded.
*/
data->config_crc = 0;
reinit_completion(&data->crc_completion);

mxt_t6_command(data, cmd, value, true);

/*
* Wait for crc message. On failure, CRC is set to 0 and config will
* always be downloaded.
*/
mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT);
}

static int mxt_check_reg_init(struct mxt_data *data)
{
const struct mxt_platform_data *pdata = data->pdata;
Expand All @@ -771,6 +801,16 @@ static int mxt_check_reg_init(struct mxt_data *data)
return 0;
}

mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);

if (data->config_crc == pdata->config_crc) {
dev_info(dev, "Config CRC 0x%06X: OK\n", data->config_crc);
return 0;
}

dev_info(dev, "Config CRC 0x%06X: does not match 0x%06X\n",
data->config_crc, pdata->config_crc);

for (i = 0; i < data->info.object_num; i++) {
object = data->object_table + i;

Expand All @@ -790,6 +830,14 @@ static int mxt_check_reg_init(struct mxt_data *data)
index += size;
}

mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);

ret = mxt_soft_reset(data);
if (ret)
return ret;

dev_info(dev, "Config successfully updated\n");

return 0;
}

Expand Down Expand Up @@ -929,11 +977,6 @@ static int mxt_initialize(struct mxt_data *data)
goto err_free_object_table;
}

error = mxt_t6_command(data, MXT_COMMAND_BACKUPNV,
MXT_BACKUP_VALUE, false);
if (!error)
mxt_soft_reset(data);

/* Update matrix size at info struct */
error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
if (error)
Expand Down Expand Up @@ -1263,6 +1306,7 @@ static int mxt_probe(struct i2c_client *client,

init_completion(&data->bl_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);

mxt_calc_resolution(data);

Expand Down
1 change: 1 addition & 0 deletions include/linux/i2c/atmel_mxt_ts.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
struct mxt_platform_data {
const u8 *config;
size_t config_length;
u32 config_crc;

unsigned int x_size;
unsigned int y_size;
Expand Down

0 comments on commit c3f7804

Please sign in to comment.