diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index 32395664e879..6f02117ae5d9 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -233,6 +233,11 @@ static void __init goni_radio_init(void) gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "FM_RST"); } +static u8 read_chg(void) +{ + return gpio_get_value(S5PV210_GPJ0(5)); +} + /* TSP */ static struct mxt_platform_data qt602240_platform_data = { .x_line = 17, @@ -244,6 +249,7 @@ static struct mxt_platform_data qt602240_platform_data = { .voltage = 2800000, /* 2.8V */ .orient = MXT_DIAGONAL, .irqflags = IRQF_TRIGGER_FALLING, + .read_chg = &read_chg, }; static struct s3c2410_platform_i2c i2c2_data __initdata = { diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 7f5ba1018146..0c6296f43abd 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -28,6 +28,10 @@ #define MXT_SUSPEND_LEVEL 1 #endif +/* Family ID */ +#define MXT224_ID 0x80 +#define MXT1386_ID 0xA0 + /* Version */ #define MXT_VER_20 20 #define MXT_VER_21 21 @@ -191,7 +195,10 @@ #define MXT_BOOT_VALUE 0xa5 #define MXT_BACKUP_VALUE 0x55 #define MXT_BACKUP_TIME 25 /* msec */ -#define MXT_RESET_TIME 65 /* msec */ +#define MXT224_RESET_TIME 65 /* msec */ +#define MXT1386_RESET_TIME 200 /* msec */ +#define MXT_RESET_TIME 200 /* msec */ +#define MXT_RESET_NOCHGREAD 400 /* msec */ #define MXT_FWRESET_TIME 175 /* msec */ @@ -843,7 +850,9 @@ static int mxt_initialize(struct mxt_data *data) struct i2c_client *client = data->client; struct mxt_info *info = &data->info; int error; + int timeout_counter = 0; u8 val; + u8 command_register; error = mxt_get_info(data); if (error) @@ -874,11 +883,45 @@ static int mxt_initialize(struct mxt_data *data) MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); msleep(MXT_BACKUP_TIME); + do { + error = mxt_read_object(data, MXT_GEN_COMMAND, + MXT_COMMAND_BACKUPNV, + &command_register); + if (error) + return error; + msleep(2); + } while ((command_register != 0) && (timeout_counter++ <= 100)); + if (timeout_counter >= 100) { + dev_err(&client->dev, "No response after backup!\n"); + return -EIO; + } + /* Soft reset */ mxt_write_object(data, MXT_GEN_COMMAND_T6, MXT_COMMAND_RESET, 1); - msleep(MXT_RESET_TIME); + + if (data->pdata->read_chg == NULL) { + msleep(MXT_RESET_NOCHGREAD); + } else { + switch (info->family_id) { + case MXT224_ID: + msleep(MXT224_RESET_TIME); + break; + case MXT1386_ID: + msleep(MXT1386_RESET_TIME); + break; + default: + msleep(MXT_RESET_TIME); + } + timeout_counter = 0; + while ((timeout_counter++ <= 100) && data->pdata->read_chg()) + msleep(2); + if (timeout_counter >= 100) { + dev_err(&client->dev, "No response after reset!\n"); + return -EIO; + } + } /* Update matrix size at info struct */ error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val); diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index b0cb43423584..6a1c918d6537 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h @@ -40,6 +40,7 @@ struct mxt_platform_data { unsigned char orient; unsigned long irqflags; bool i2c_pull_up; + u8(*read_chg) (void); int (*init_hw) (bool); int (*power_on) (bool);