summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShantanu Jain <shjain@codeaurora.org>2016-03-02 12:11:38 +0530
committerAbinaya P <abinayap@codeaurora.org>2016-08-05 20:30:50 +0530
commitf8168ee5bf3d7062d418dc6fab26c7ea2c41f065 (patch)
treecd263663d58e8053af4e516f3d1e520bedfd6fdd
parentfdcb967e7ebd5d37e9a2601ae101ce3352d2ee60 (diff)
input: touchscreen: identify ITE tech controller until ready
Identify the ITE tech controller until it is ready to do any i2c transaction. This is needed for dynamic detection and to check if ITE tech controller is connected or not. This is a propagated patch from 3.18 kernel 'commit eb37d1174948 ("input: touchscreen: identify ITE tech controller until ready")' CRs-Fixed: 980427 Change-Id: I9f69eb541e31de6a04db7468ca12a04a837d2b40 Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
-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))) {