diff options
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/touchscreen/it7258_ts_i2c.c | 121 |
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))) { |
