Skip to content

Commit cf2101d

Browse files
ndyerehristev
authored andcommitted
Input: atmel_mxt_ts - implement I2C retries
Some maXTouch chips (eg mXT1386) will not respond on the first I2C request when they are in a sleep state. It must be retried after a delay for the chip to wake up. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Acked-by: Yufeng Shen <miletus@chromium.org>
1 parent d89a0be commit cf2101d

1 file changed

Lines changed: 30 additions & 15 deletions

File tree

drivers/input/touchscreen/atmel_mxt_ts.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ enum t100_type {
197197
#define MXT_CRC_TIMEOUT 1000 /* msec */
198198
#define MXT_FW_RESET_TIME 3000 /* msec */
199199
#define MXT_FW_CHG_TIMEOUT 300 /* msec */
200+
#define MXT_WAKEUP_TIME 25 /* msec */
200201
#define MXT_REGULATOR_DELAY 150 /* msec */
201202
#define MXT_CHG_DELAY 100 /* msec */
202203
#define MXT_POWERON_DELAY 150 /* msec */
@@ -619,6 +620,7 @@ static int __mxt_read_reg(struct i2c_client *client,
619620
struct i2c_msg xfer[2];
620621
u8 buf[2];
621622
int ret;
623+
bool retry = false;
622624

623625
buf[0] = reg & 0xff;
624626
buf[1] = (reg >> 8) & 0xff;
@@ -635,17 +637,22 @@ static int __mxt_read_reg(struct i2c_client *client,
635637
xfer[1].len = len;
636638
xfer[1].buf = val;
637639

638-
ret = i2c_transfer(client->adapter, xfer, 2);
639-
if (ret == 2) {
640-
ret = 0;
641-
} else {
642-
if (ret >= 0)
643-
ret = -EIO;
644-
dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
645-
__func__, ret);
640+
retry_read:
641+
ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
642+
if (ret != ARRAY_SIZE(xfer)) {
643+
if (!retry) {
644+
dev_dbg(&client->dev, "%s: i2c retry\n", __func__);
645+
msleep(MXT_WAKEUP_TIME);
646+
retry = true;
647+
goto retry_read;
648+
} else {
649+
dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
650+
__func__, ret);
651+
return -EIO;
652+
}
646653
}
647654

648-
return ret;
655+
return 0;
649656
}
650657

651658
static int mxt_read_blks(struct mxt_data *data, u16 start, u16 count, u8 *buf)
@@ -675,6 +682,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
675682
u8 *buf;
676683
size_t count;
677684
int ret;
685+
bool retry = false;
678686

679687
count = len + 2;
680688
buf = kmalloc(count, GFP_KERNEL);
@@ -685,14 +693,21 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
685693
buf[1] = (reg >> 8) & 0xff;
686694
memcpy(&buf[2], val, len);
687695

696+
retry_write:
688697
ret = i2c_master_send(client, buf, count);
689-
if (ret == count) {
690-
ret = 0;
691-
} else {
692-
if (ret >= 0)
698+
if (ret != count) {
699+
if (!retry) {
700+
dev_dbg(&client->dev, "%s: i2c retry\n", __func__);
701+
msleep(MXT_WAKEUP_TIME);
702+
retry = true;
703+
goto retry_write;
704+
} else {
705+
dev_err(&client->dev, "%s: i2c send failed (%d)\n",
706+
__func__, ret);
693707
ret = -EIO;
694-
dev_err(&client->dev, "%s: i2c send failed (%d)\n",
695-
__func__, ret);
708+
}
709+
} else {
710+
ret = 0;
696711
}
697712

698713
kfree(buf);

0 commit comments

Comments
 (0)