summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Hong <rurumihong@google.com>2021-10-15 19:44:12 +0800
committerAlex Hong <rurumihong@google.com>2021-10-15 19:44:19 +0800
commita92a7113f1728f56bb0598d45683a1c264fce77c (patch)
tree4cb37f1b381a3e2fcbbba0bb89295a4e221b5cbd
parenta38fc2574a1e25ba7e2cf8fe2febc263c5790ee3 (diff)
parent6c3428e009eb540d94faf63c4741164bc6f85f40 (diff)
downloadsec_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.c222
-rw-r--r--sec_ts.h14
-rw-r--r--sec_ts_fn.c87
3 files changed, 295 insertions, 28 deletions
diff --git a/sec_ts.c b/sec_ts.c
index 9ec8ad0..a417eea 100644
--- a/sec_ts.c
+++ b/sec_ts.c
@@ -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);
}
}
diff --git a/sec_ts.h b/sec_ts.h
index 4d3cba7..fbcdafd 100644
--- a/sec_ts.h
+++ b/sec_ts.h
@@ -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,