diff options
author | Alex Hong <rurumihong@google.com> | 2021-10-15 19:44:12 +0800 |
---|---|---|
committer | Alex Hong <rurumihong@google.com> | 2021-10-15 19:44:19 +0800 |
commit | a92a7113f1728f56bb0598d45683a1c264fce77c (patch) | |
tree | 4cb37f1b381a3e2fcbbba0bb89295a4e221b5cbd | |
parent | a38fc2574a1e25ba7e2cf8fe2febc263c5790ee3 (diff) | |
parent | 6c3428e009eb540d94faf63c4741164bc6f85f40 (diff) | |
download | sec_touch-a92a7113f1728f56bb0598d45683a1c264fce77c.tar.gz |
Merge android12-gs-pixel-5.10-sc-v2 into android13-gs-pixel-5.10
Bug: 199698959
Change-Id: I2f1af7c79c733acd35ec727297b23b7aa1c2180e
Signed-off-by: Alex Hong <rurumihong@google.com>
-rw-r--r-- | sec_ts.c | 222 | ||||
-rw-r--r-- | sec_ts.h | 14 | ||||
-rw-r--r-- | sec_ts_fn.c | 87 |
3 files changed, 295 insertions, 28 deletions
@@ -427,9 +427,22 @@ static int sec_ts_read_internal(struct sec_ts_data *ts, u8 reg, ret = -EIO; - input_err(true, &ts->client->dev, - "%s: retry %d for 0x%02X size(%d) delay(%d)\n", - __func__, retry + 1, reg, len, spi_delay_us); + /* + * For LP idle state from AOD to normal screen-on, + * T-IC needs one SPI cmds to wake-up. + * Therefore, change the log level to warning + * for this intended behavir. + */ + if (!completion_done(&ts->bus_resumed) && + reg == SEC_TS_CMD_CHG_SYSMODE) { + dev_warn(&ts->client->dev, + "%s: wake-up touch(#%d) by 0x%02X cmd delay_us(%d)\n", + __func__, retry + 1, reg, spi_delay_us); + } else { + input_err(true, &ts->client->dev, + "%s: retry %d for 0x%02X size(%d) delay_us(%d)\n", + __func__, retry + 1, reg, len, spi_delay_us); + } ts->comm_err_count++; usleep_range(1 * 1000, 1 * 1000); @@ -1193,6 +1206,130 @@ static int sec_ts_ptflib_reinit(struct sec_ts_data *ts) return 0; } +#define PTFLIB_GRIP_ENABLED_OFFSET_LSB 0x80 +#define PTFLIB_GRIP_ENABLED_OFFSET_MSB 0x00 +static int sec_ts_ptflib_grip_prescreen_enable(struct sec_ts_data *ts, + int grip_prescreen_mode) { + u8 r_data[2] = {0x00, 0x00}; + u8 w_data[3] = {0x00, 0x00, 0x00}; + int result; + + input_info(true, &ts->client->dev, "%s: set mode %d.\n", + __func__, grip_prescreen_mode); + + if (grip_prescreen_mode < GRIP_PRESCREEN_OFF || + grip_prescreen_mode > GRIP_PRESCREEN_MODE_3) { + input_err(true, &ts->client->dev, + "%s: invalid grip_prescreen_mode value %d.\n", + __func__, grip_prescreen_mode); + return -EINVAL; + } + + w_data[0] = PTFLIB_GRIP_ENABLED_OFFSET_LSB; + w_data[1] = PTFLIB_GRIP_ENABLED_OFFSET_MSB; + w_data[2] = grip_prescreen_mode; + result = ts->sec_ts_write(ts, SEC_TS_CMD_CUSTOMLIB_WRITE_PARAM, + w_data, 3); + if (result < 0) { + input_err(true, &ts->client->dev, + "%s: Write grip_prescreen_mode register failed.\n", + __func__); + return -EIO; + } + + r_data[0] = PTFLIB_GRIP_ENABLED_OFFSET_LSB; + r_data[1] = PTFLIB_GRIP_ENABLED_OFFSET_MSB; + result = ts->sec_ts_read_customlib(ts, r_data, 2); + if (result < 0) { + input_err(true, &ts->client->dev, + "%s: Read grip_prescreen_mode register failed.\n", + __func__); + return -EIO; + } + + if (r_data[0] != grip_prescreen_mode) { + input_err(true, &ts->client->dev, + "%s: Configure grip_prescreen_mode register failed %d.\n", + __func__, r_data[0]); + return -EIO; + } + + return 0; +} + +#define PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_LSB 0x9A +#define PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_MSB 0x00 +static int sec_ts_ptflib_grip_prescreen_timeout(struct sec_ts_data *ts, + int grip_prescreen_timeout) { + u8 r_data[2] = {0x00, 0x00}; + u8 w_data[4] = {0x00, 0x00, 0x00, 0x00}; + u16 timeout; + int result; + + input_info(true, &ts->client->dev, "%s: set timeout %d.\n", + __func__, grip_prescreen_timeout); + + if (grip_prescreen_timeout < GRIP_PRESCREEN_TIMEOUT_MIN || + grip_prescreen_timeout > GRIP_PRESCREEN_TIMEOUT_MAX) { + input_err(true, &ts->client->dev, + "%s: invalid grip_prescreen_timeout value %d.\n", + __func__, grip_prescreen_timeout); + return -EINVAL; + } + + w_data[0] = PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_LSB; + w_data[1] = PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_MSB; + w_data[2] = grip_prescreen_timeout & 0xFF; + w_data[3] = (grip_prescreen_timeout >> 8) & 0xFF; + result = ts->sec_ts_write(ts, SEC_TS_CMD_CUSTOMLIB_WRITE_PARAM, + w_data, 4); + if (result < 0) { + input_err(true, &ts->client->dev, + "%s: Write grip_prescreen_timeout register failed.\n", + __func__); + return -EIO; + } + + r_data[0] = PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_LSB; + r_data[1] = PTFLIB_GRIP_PRESCREEN_TIMEOUT_OFFSET_MSB; + result = ts->sec_ts_read_customlib(ts, r_data, 2); + if (result < 0) { + input_err(true, &ts->client->dev, + "%s: Read grip_prescreen_timeout register failed.\n", + __func__); + return -EIO; + } + + timeout = le16_to_cpup((uint16_t *) r_data); + if (timeout != grip_prescreen_timeout) { + input_err(true, &ts->client->dev, + "%s: Configure grip_prescreen_timeout register failed %d.\n", + __func__, timeout); + return -EIO; + } + + return 0; +} + +#define PTFLIB_GRIP_PRESCREEN_FRAMES_OFFSET_LSB 0x9C +#define PTFLIB_GRIP_PRESCREEN_FRAMES_OFFSET_MSB 0x00 +static int sec_ts_ptflib_get_grip_prescreen_frames(struct sec_ts_data *ts) { + u8 r_data[4] = {0x00, 0x00, 0x00, 0x00}; + int result; + + r_data[0] = PTFLIB_GRIP_PRESCREEN_FRAMES_OFFSET_LSB; + r_data[1] = PTFLIB_GRIP_PRESCREEN_FRAMES_OFFSET_MSB; + result = ts->sec_ts_read_customlib(ts, r_data, sizeof(r_data)); + if (result < 0) { + input_err(true, &ts->client->dev, + "%s: Read grip prescreen frames register failed.\n", + __func__); + return -EIO; + } + + return le32_to_cpup((uint32_t *) r_data); +} + static int sec_ts_ptflib_decoder(struct sec_ts_data *ts, const u16 *in_array, const int in_array_size, u16 *out_array, const int out_array_max_size) @@ -2512,6 +2649,7 @@ static void sec_ts_populate_frame(struct sec_ts_data *ts, int sec_ts_enable_grip(struct sec_ts_data *ts, bool enable) { + struct sec_ts_plat_data *pdata = ts->plat_data; u8 value = enable ? 1 : 0; int ret; int final_result = 0; @@ -2535,8 +2673,17 @@ int sec_ts_enable_grip(struct sec_ts_data *ts, bool enable) final_result = ret; } - if (!enable) + if (!enable) { sec_ts_ptflib_reinit(ts); + if (pdata->grip_prescreen_mode == GRIP_PRESCREEN_MODE_2) { + sec_ts_ptflib_grip_prescreen_timeout(ts, + pdata->grip_prescreen_timeout); + } + sec_ts_ptflib_grip_prescreen_enable(ts, + pdata->grip_prescreen_mode); + } else { + sec_ts_ptflib_grip_prescreen_enable(ts, GRIP_PRESCREEN_OFF); + } return final_result; } @@ -3680,6 +3827,8 @@ static int sec_ts_parse_dt(struct spi_device *client) &pdata->encoded_enable) < 0) pdata->encoded_enable = 0; + pdata->grip_prescreen_mode = GRIP_PRESCREEN_MODE_2; + pdata->grip_prescreen_timeout = 120; pdata->is_heatmap_enabled = false; pdata->encoded_frame_counter = 0; pdata->encoded_skip_counter = 0; @@ -5339,6 +5488,10 @@ static void sec_ts_suspend_work(struct work_struct *work) input_info(true, &ts->client->dev, "%s: encoded skipped %d/%d\n", __func__, ts->plat_data->encoded_skip_counter, ts->plat_data->encoded_frame_counter); + if (ts->plat_data->grip_prescreen_mode != GRIP_PRESCREEN_OFF) { + input_info(true, &ts->client->dev, "%s: grip prescreened frames %d.\n", + __func__, sec_ts_ptflib_get_grip_prescreen_frames(ts)); + } mutex_lock(&ts->device_mutex); @@ -5411,44 +5564,57 @@ static void sec_ts_resume_work(struct work_struct *work) ret = ts->sec_ts_read(ts, SEC_TS_CMD_CHG_SYSMODE, touch_mode, sizeof(touch_mode)); if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: read touch mode failed(%d)\n", + __func__, ret); ret = sec_ts_system_reset(ts, RESET_MODE_HW, false, false); if (ret < 0) { input_err(true, &ts->client->dev, "%s: reset failed! ret %d\n", __func__, ret); } } else { - u8 power_mode = 0; + u8 power_mode = TO_TOUCH_MODE; + u8 state_manage_on = { STATE_MANAGE_ON }; - input_info(true, &ts->client->dev, "%s: before resume: mode %#x, state %#x.", - __func__, touch_mode[0], touch_mode[1]); + input_info(true, &ts->client->dev, + "%s: before resume: mode %#x, state %#x.\n", + __func__, touch_mode[0], touch_mode[1]); - if (touch_mode[0] == TOUCH_SYSTEM_MODE_LOWPOWER) { - ret = sec_ts_write(ts, SEC_TS_CMD_SET_POWER_MODE, - &power_mode, sizeof(power_mode)); + /* Enable Normal scan. */ + ret = sec_ts_write(ts, SEC_TS_CMD_SET_POWER_MODE, + &power_mode, sizeof(power_mode)); + if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: set power mode failed(%d)\n", + __func__, ret); + ret = sec_ts_system_reset(ts, RESET_MODE_HW, false, false); if (ret < 0) { input_err(true, &ts->client->dev, - "%s: set power mode failed(%d)\n", - __func__, ret); + "%s: reset failed! ret %d\n", __func__, ret); } + } else { + /* Wait at least 50 ms for mode change. */ sec_ts_delay(50); - ret = ts->sec_ts_read(ts, SEC_TS_CMD_CHG_SYSMODE, touch_mode, - sizeof(touch_mode)); - if (ret < 0) { - input_err(true, &ts->client->dev, - "%s: set read touch mode failed(%d)\n", - __func__, ret); + } - } else { - input_info(true, &ts->client->dev, - "%s: after resume: mode %#x, state %#x", - __func__, touch_mode[0], touch_mode[1]); - } + ret = ts->sec_ts_read(ts, SEC_TS_CMD_CHG_SYSMODE, touch_mode, + sizeof(touch_mode)); + if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: read touch mode failed(%d)\n", + __func__, ret); } else { - ret = sec_ts_system_reset(ts, RESET_MODE_HW, false, false); - if (ret < 0) { - input_err(true, &ts->client->dev, - "%s: reset failed! ret %d\n", __func__, ret); - } + input_info(true, &ts->client->dev, + "%s: after resume: mode %#x, state %#x.\n", + __func__, touch_mode[0], touch_mode[1]); + } + + ret = sec_ts_write(ts, SEC_TS_CMD_STATEMANAGE_ON, &state_manage_on, + sizeof(state_manage_on)); + if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: SEC_TS_CMD_STATEMANAGE_ON failed! ret %d\n", + __func__, ret); } } @@ -659,6 +659,18 @@ enum { }; enum { + GRIP_PRESCREEN_OFF = 0, + GRIP_PRESCREEN_MODE_1 = 1, + GRIP_PRESCREEN_MODE_2 = 2, + GRIP_PRESCREEN_MODE_3 = 3 +}; + +enum { + GRIP_PRESCREEN_TIMEOUT_MIN = 0, + GRIP_PRESCREEN_TIMEOUT_MAX = 480 +}; + +enum { ENCODED_ENABLE_OFF = 0, ENCODED_ENABLE_ON = 1 }; @@ -1155,6 +1167,8 @@ struct sec_ts_plat_data { int bringup; int mis_cal_check; int heatmap_mode; + int grip_prescreen_mode; + int grip_prescreen_timeout; bool is_heatmap_enabled; int encoded_enable; int encoded_frame_counter; diff --git a/sec_ts_fn.c b/sec_ts_fn.c index ff20c34..47200ea 100644 --- a/sec_ts_fn.c +++ b/sec_ts_fn.c @@ -1052,6 +1052,89 @@ static ssize_t heatmap_mode_show(struct device *dev, #endif } +/* sysfs file node to store grip prescreen mode + * "echo cmd > grip_prescreen_mode" to change + * Possible commands: + * 0 = GRIP_PRESCREEN_OFF + * 1 = GRIP_PRESCREEN_MODE_1 + * 2 = GRIP_PRESCREEN_MODE_2 + * 3 = GRIP_PRESCREEN_MODE_3 + */ +static ssize_t grip_prescreen_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct sec_ts_data *ts = container_of(sec, struct sec_ts_data, sec); + struct sec_ts_plat_data *pdata = ts->plat_data; + int result; + int val; + + result = kstrtoint(buf, 10, &val); + if (result < 0 || val < GRIP_PRESCREEN_OFF || + val > GRIP_PRESCREEN_MODE_3) { + input_err(true, &ts->client->dev, + "%s: Invalid input.\n", __func__); + return -EINVAL; + } + + pdata->grip_prescreen_mode = val; + + return count; +} + +static ssize_t grip_prescreen_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct sec_ts_data *ts = container_of(sec, struct sec_ts_data, sec); + const struct sec_ts_plat_data *pdata = ts->plat_data; + + return scnprintf(buf, PAGE_SIZE, "%d\n", + pdata->grip_prescreen_mode); +} + +/* sysfs file node to store grip prescreen timeout + * "echo timeout > grip_prescreen_timeout" to change + * Possible timeout range: + * GRIP_PRESCREEN_TIMEOUT_MIN ~ GRIP_PRESCREEN_TIMEOUT_MAX + */ +static ssize_t grip_prescreen_timeout_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct sec_ts_data *ts = container_of(sec, struct sec_ts_data, sec); + struct sec_ts_plat_data *pdata = ts->plat_data; + int result; + int val; + + result = kstrtoint(buf, 10, &val); + if (result < 0 || val < GRIP_PRESCREEN_TIMEOUT_MIN || + val > GRIP_PRESCREEN_TIMEOUT_MAX) { + input_err(true, &ts->client->dev, + "%s: Invalid input.\n", __func__); + return -EINVAL; + } + + pdata->grip_prescreen_timeout = val; + + return count; +} + +static ssize_t grip_prescreen_timeout_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct sec_ts_data *ts = container_of(sec, struct sec_ts_data, sec); + const struct sec_ts_plat_data *pdata = ts->plat_data; + + return scnprintf(buf, PAGE_SIZE, "%d\n", + pdata->grip_prescreen_timeout); +} + /* sysfs file node to store encoded_enable control * "echo cmd > encoded_enable" to change * Possible commands: @@ -1306,6 +1389,8 @@ static DEVICE_ATTR_RW(pressure_enable); static DEVICE_ATTR_RO(get_lp_dump); static DEVICE_ATTR_RO(force_recal_count); static DEVICE_ATTR_RW(heatmap_mode); +static DEVICE_ATTR_RW(grip_prescreen_mode); +static DEVICE_ATTR_RW(grip_prescreen_timeout); static DEVICE_ATTR_RW(encoded_enable); static DEVICE_ATTR_RW(heatmap_dump); static DEVICE_ATTR_RO(fw_version); @@ -1329,6 +1414,8 @@ static struct attribute *cmd_attributes[] = { &dev_attr_get_lp_dump.attr, &dev_attr_force_recal_count.attr, &dev_attr_heatmap_mode.attr, + &dev_attr_grip_prescreen_mode.attr, + &dev_attr_grip_prescreen_timeout.attr, &dev_attr_encoded_enable.attr, &dev_attr_heatmap_dump.attr, &dev_attr_fw_version.attr, |