summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/it7258_ts_i2c.c121
1 files changed, 95 insertions, 26 deletions
diff --git a/drivers/input/touchscreen/it7258_ts_i2c.c b/drivers/input/touchscreen/it7258_ts_i2c.c
index f7b873e56c6d..542f45ba1479 100644
--- a/drivers/input/touchscreen/it7258_ts_i2c.c
+++ b/drivers/input/touchscreen/it7258_ts_i2c.c
@@ -99,19 +99,18 @@
#define FW_WRITE_CHUNK_SIZE 128
#define FW_WRITE_RETRY_COUNT 4
#define CHIP_FLASH_SIZE 0x8000
-#define DEVICE_READY_MAX_WAIT 500
-#define DEVICE_READY_WAIT_10 10
+#define DEVICE_READY_COUNT_MAX 500
+#define DEVICE_READY_COUNT_20 20
+#define IT_I2C_WAIT_10MS 10
/* result of reading with BUF_QUERY bits */
#define CMD_STATUS_BITS 0x07
#define CMD_STATUS_DONE 0x00
#define CMD_STATUS_BUSY 0x01
#define CMD_STATUS_ERROR 0x02
+#define CMD_STATUS_NO_CONN 0x07
#define PT_INFO_BITS 0xF8
-#define BT_INFO_NONE 0x00
#define PT_INFO_YES 0x80
-/* no new data but finder(s) still down */
-#define BT_INFO_NONE_BUT_DOWN 0x08
#define PD_FLAGS_DATA_TYPE_BITS 0xF0
/* other types (like chip-detected gestures) exist but we do not care */
@@ -134,7 +133,6 @@
#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
#define PINCTRL_STATE_RELEASE "pmx_ts_release"
-#define IT_I2C_WAIT 1000
struct FingerData {
uint8_t xLo;
@@ -234,6 +232,7 @@ DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, IT7260_debug_suspend_get,
static bool IT7260_i2cReadNoReadyCheck(uint8_t buf_index, uint8_t *buffer,
uint16_t buf_len)
{
+ int ret;
struct i2c_msg msgs[2] = {
{
.addr = gl_ts->client->addr,
@@ -251,13 +250,20 @@ static bool IT7260_i2cReadNoReadyCheck(uint8_t buf_index, uint8_t *buffer,
memset(buffer, 0xFF, buf_len);
- return i2c_transfer(gl_ts->client->adapter, msgs, 2);
+ ret = i2c_transfer(gl_ts->client->adapter, msgs, 2);
+ if (ret < 0) {
+ dev_err(&gl_ts->client->dev, "i2c read failed %d\n", ret);
+ return false;
+ }
+
+ return (ret == 2) ? true : false;
}
static bool IT7260_i2cWriteNoReadyCheck(uint8_t buf_index,
const uint8_t *buffer, uint16_t buf_len)
{
uint8_t txbuf[257];
+ int ret;
struct i2c_msg msg = {
.addr = gl_ts->client->addr,
.flags = 0,
@@ -274,45 +280,72 @@ static bool IT7260_i2cWriteNoReadyCheck(uint8_t buf_index,
txbuf[0] = buf_index;
memcpy(txbuf + 1, buffer, buf_len);
- return i2c_transfer(gl_ts->client->adapter, &msg, 1);
+ ret = i2c_transfer(gl_ts->client->adapter, &msg, 1);
+ if (ret < 0) {
+ dev_err(&gl_ts->client->dev, "i2c write failed %d\n", ret);
+ return false;
+ }
+
+ return (ret == 1) ? true : false;
}
/*
- * Device is apparently always ready for i2c but not for actual
- * register reads/writes. This function ascertains it is ready
- * for that too. the results of this call often were ignored.
+ * Device is apparently always ready for I2C communication but not for
+ * actual register reads/writes. This function checks if it is ready
+ * for that too. The results of this call often were ignored.
+ * If forever is set to TRUE, then check the device's status until it
+ * becomes ready with 500 retries at max. Otherwise retry 25 times only.
+ * If slowly is set to TRUE, then add sleep of 50 ms in each retry,
+ * otherwise don't sleep.
*/
static bool IT7260_waitDeviceReady(bool forever, bool slowly)
{
uint8_t query;
- uint32_t count = DEVICE_READY_WAIT_10;
+ uint32_t count = DEVICE_READY_COUNT_20;
+ bool ret;
if (gl_ts->fw_cfg_uploading || forever)
- count = DEVICE_READY_MAX_WAIT;
+ count = DEVICE_READY_COUNT_MAX;
do {
- if (!IT7260_i2cReadNoReadyCheck(BUF_QUERY, &query,
- sizeof(query)))
- query = CMD_STATUS_BUSY;
+ ret = IT7260_i2cReadNoReadyCheck(BUF_QUERY, &query,
+ sizeof(query));
+ if (ret == false && ((query & CMD_STATUS_BITS)
+ == CMD_STATUS_NO_CONN))
+ continue;
+ if ((query & CMD_STATUS_BITS) == CMD_STATUS_DONE)
+ break;
+
+ query = CMD_STATUS_BUSY;
if (slowly)
- msleep(IT_I2C_WAIT);
- } while ((query & CMD_STATUS_BUSY) && --count);
+ msleep(IT_I2C_WAIT_10MS);
+ } while (--count);
- return !query;
+ return !(query & CMD_STATUS_BITS);
}
static bool IT7260_i2cRead(uint8_t buf_index, uint8_t *buffer,
uint16_t buf_len)
{
- IT7260_waitDeviceReady(false, false);
+ bool ret;
+
+ ret = IT7260_waitDeviceReady(false, false);
+ if (ret == false)
+ return ret;
+
return IT7260_i2cReadNoReadyCheck(buf_index, buffer, buf_len);
}
static bool IT7260_i2cWrite(uint8_t buf_index, const uint8_t *buffer,
uint16_t buf_len)
{
- IT7260_waitDeviceReady(false, false);
+ bool ret;
+
+ ret = IT7260_waitDeviceReady(false, false);
+ if (ret == false)
+ return ret;
+
return IT7260_i2cWriteNoReadyCheck(buf_index, buffer, buf_len);
}
@@ -448,7 +481,16 @@ static void IT7260_get_chip_versions(struct device *dev)
ret = IT7260_i2cWrite(BUF_COMMAND, cmd_read_fw_ver,
sizeof(cmd_read_fw_ver));
if (ret) {
- ret = IT7260_i2cRead(BUF_RESPONSE, ver_fw, VERSION_LENGTH);
+ /*
+ * Sometimes, the controller may not respond immediately after
+ * writing the command, so wait for device to get ready.
+ */
+ ret = IT7260_waitDeviceReady(true, false);
+ if (ret == false)
+ dev_err(dev, "failed to read from chip\n");
+
+ ret = IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, ver_fw,
+ VERSION_LENGTH);
if (ret)
memcpy(gl_ts->fw_ver, ver_fw + (5 * sizeof(u8)),
VER_BUFFER_SIZE * sizeof(u8));
@@ -459,8 +501,16 @@ static void IT7260_get_chip_versions(struct device *dev)
ret = IT7260_i2cWrite(BUF_COMMAND, cmd_read_cfg_ver,
sizeof(cmd_read_cfg_ver));
if (ret) {
- ret = IT7260_i2cRead(BUF_RESPONSE, ver_cfg, VERSION_LENGTH)
- && ret;
+ /*
+ * Sometimes, the controller may not respond immediately after
+ * writing the command, so wait for device to get ready.
+ */
+ ret = IT7260_waitDeviceReady(true, false);
+ if (ret == false)
+ dev_err(dev, "failed to read from chip\n");
+
+ ret = IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, ver_cfg,
+ VERSION_LENGTH);
if (ret)
memcpy(gl_ts->cfg_ver, ver_cfg + (1 * sizeof(u8)),
VER_BUFFER_SIZE * sizeof(u8));
@@ -1127,7 +1177,16 @@ static int IT7260_chipIdentify(void)
'2', '6', '0'};
uint8_t chip_id[10] = {0,};
- IT7260_waitDeviceReady(false, false);
+ /*
+ * Sometimes, the controller may not respond immediately after
+ * writing the command, so wait for device to get ready.
+ * FALSE means to retry 20 times at max to read the chip status.
+ * TRUE means to add delay in each retry.
+ */
+ if (!IT7260_waitDeviceReady(false, true)) {
+ dev_err(&gl_ts->client->dev, "can't read from the chip\n");
+ return -ENODEV;
+ }
if (!IT7260_i2cWriteNoReadyCheck(BUF_COMMAND, cmd_ident,
sizeof(cmd_ident))) {
@@ -1135,7 +1194,17 @@ static int IT7260_chipIdentify(void)
return -ENODEV;
}
- IT7260_waitDeviceReady(false, false);
+ /*
+ * Sometimes, the controller may not respond immediately after
+ * writing the command, so wait for device to get ready.
+ * TRUE means to retry 500 times at max to read the chip status.
+ * FALSE means to avoid unnecessary delays in each retry.
+ */
+ if (!IT7260_waitDeviceReady(true, false)) {
+ dev_err(&gl_ts->client->dev, "failed to read chip status\n");
+ return -ENODEV;
+ }
+
if (!IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, chip_id,
sizeof(chip_id))) {