diff options
author | Wendly Li <wendlyli@google.com> | 2022-03-25 11:21:45 +0000 |
---|---|---|
committer | Wendly Li <wendlyli@google.com> | 2022-05-06 05:23:32 +0000 |
commit | 50e3b783953806368fc40afd989f1b872733d89f (patch) | |
tree | 4a4fea0733b31c4a6220315f551427dfb8e5a31d | |
parent | e2758577ef0cf2c03f2db83d2adff4a0725dcaf9 (diff) | |
download | goodix_touch-50e3b783953806368fc40afd989f1b872733d89f.tar.gz |
goodix: Import v1.0.5 driver
Bug: 214118944
Test: Be able to wake up device by gestures.
Change-Id: Ie499faa169a9b395c89a7e3e6bd3238a133fd0e0
Signed-off-by: Wendly Li <wendlyli@google.com>
-rw-r--r-- | goodix_brl_hw.c | 50 | ||||
-rw-r--r-- | goodix_ts_core.c | 10 | ||||
-rw-r--r-- | goodix_ts_core.h | 4 | ||||
-rw-r--r-- | goodix_ts_proc.c | 684 |
4 files changed, 558 insertions, 190 deletions
diff --git a/goodix_brl_hw.c b/goodix_brl_hw.c index ceafbe2..34675bf 100644 --- a/goodix_brl_hw.c +++ b/goodix_brl_hw.c @@ -275,13 +275,20 @@ int brl_resume(struct goodix_ts_core *cd) int brl_gesture(struct goodix_ts_core *cd, int gesture_type) { struct goodix_ts_cmd cmd; + u8 val = 0xff; + + if (cd->gesture_type & GESTURE_SINGLE_TAP) + val &= ~(0x01 << 0); + if (cd->gesture_type & GESTURE_FOD_PRESS) + val &= ~(0x01 << 1); if (cd->bus->ic_type == IC_TYPE_BERLIN_A) cmd.cmd = GOODIX_GESTURE_CMD_BA; else cmd.cmd = GOODIX_GESTURE_CMD; - cmd.len = 5; - cmd.data[0] = gesture_type; + cmd.len = 6; + cmd.data[0] = 0xff; + cmd.data[1] = val; if (cd->hw_ops->send_cmd(cd, &cmd)) ts_err("failed send gesture cmd"); @@ -375,7 +382,8 @@ static int brl_send_cmd(struct goodix_ts_core *cd, struct goodix_ts_cmd *cmd) ts_debug("cmd ack data %*ph", (int)sizeof(cmd_ack), cmd_ack.buf); if (cmd_ack.ack == CMD_ACK_OK) { - msleep(40); // wait for cmd response + // msleep(40); // wait for cmd response + usleep_range(6000, 6100); return 0; } if (cmd_ack.ack == CMD_ACK_BUSY || @@ -956,7 +964,7 @@ static int brl_esd_check(struct goodix_ts_core *cd) } #define IRQ_EVENT_HEAD_LEN 8 -#define BYTES_PER_POINT 8 +#define BYTES_PER_POINT 12 #define COOR_DATA_CHECKSUM_SIZE 2 #define GOODIX_TOUCH_EVENT 0x80 @@ -965,18 +973,15 @@ static int brl_esd_check(struct goodix_ts_core *cd) #define GOODIX_FP_EVENT 0x08 #define POINT_TYPE_STYLUS_HOVER 0x01 #define POINT_TYPE_STYLUS 0x03 - +static int point_struct_len; static void goodix_parse_finger( struct goodix_touch_data *touch_data, u8 *buf, int touch_num) { unsigned int id = 0, x = 0, y = 0, w = 0; u8 *coor_data; - u8 *custom_data; int i; coor_data = &buf[IRQ_EVENT_HEAD_LEN]; - custom_data = - &buf[IRQ_EVENT_HEAD_LEN + touch_num * BYTES_PER_POINT + 2]; for (i = 0; i < touch_num; i++) { id = (coor_data[0] >> 4) & 0x0F; if (id >= GOODIX_MAX_TOUCH) { @@ -985,23 +990,23 @@ static void goodix_parse_finger( return; } + touch_data->coords[id].status = TS_TOUCH; x = le16_to_cpup((__le16 *)(coor_data + 2)); y = le16_to_cpup((__le16 *)(coor_data + 4)); w = le16_to_cpup((__le16 *)(coor_data + 6)); - touch_data->coords[id].status = TS_TOUCH; touch_data->coords[id].x = x; touch_data->coords[id].y = y; - if (coor_data[1] & 0x01) { - touch_data->coords[id].major = custom_data[1]; - touch_data->coords[id].minor = custom_data[2]; + touch_data->coords[id].w = w; + + if (point_struct_len == 12) { + touch_data->coords[id].p = coor_data[8]; + touch_data->coords[id].major = coor_data[9]; + touch_data->coords[id].minor = coor_data[10]; touch_data->coords[id].angle = - (signed char)custom_data[3]; - } else { - touch_data->coords[id].major = w; - touch_data->coords[id].minor = w; - touch_data->coords[id].angle = 0; + (signed char)coor_data[11]; } - coor_data += BYTES_PER_POINT; + + coor_data += point_struct_len; } touch_data->touch_num = touch_num; } @@ -1096,13 +1101,14 @@ static int goodix_touch_handler(struct goodix_ts_core *cd, return -EINVAL; } } else { + point_struct_len = misc->point_struct_len; ret = checksum_cmp(&buffer[IRQ_EVENT_HEAD_LEN], - touch_num * BYTES_PER_POINT + 2, + touch_num * point_struct_len + 2, CHECKSUM_MODE_U8_LE); if (ret) { ts_debug("touch data checksum error"); ts_debug("data:%*ph", - touch_num * BYTES_PER_POINT + 2, + touch_num * point_struct_len + 2, &buffer[IRQ_EVENT_HEAD_LEN]); return -EINVAL; } @@ -1149,7 +1155,7 @@ static int brl_event_handler( struct goodix_ts_hw_ops *hw_ops = cd->hw_ops; struct goodix_ic_info_misc *misc = &cd->ic_info.misc; int pre_read_len; - u8 pre_buf[36]; + u8 pre_buf[38]; u8 event_status; int ret; @@ -1438,7 +1444,7 @@ int brl_set_scan_mode(struct goodix_ts_core *cd, int mode) return 0; } -#define GOODIX_CMD_SET_CONTINUOUSLY_REPORT_ENABLED 0xC3 +#define GOODIX_CMD_SET_CONTINUOUSLY_REPORT_ENABLED 0xC6 int brl_set_continuously_report_enabled(struct goodix_ts_core *cd, bool enabled) { struct goodix_ts_cmd cmd; diff --git a/goodix_ts_core.c b/goodix_ts_core.c index 783dc11..7a8bc78 100644 --- a/goodix_ts_core.c +++ b/goodix_ts_core.c @@ -1221,9 +1221,11 @@ static void goodix_ts_report_finger( for (i = 0; i < GOODIX_MAX_TOUCH; i++) { if (touch_data->coords[i].status == TS_TOUCH) { ts_debug( - "report: id[%d], x %d, y %d, major %d, minor %d, angle %d", + "report: id[%d], x %d, y %d, w %d, p %d, major %d, minor %d, angle %d", i, touch_data->coords[i].x, touch_data->coords[i].y, + touch_data->coords[i].w, + touch_data->coords[i].p, touch_data->coords[i].major, touch_data->coords[i].minor, touch_data->coords[i].angle); @@ -1233,6 +1235,10 @@ static void goodix_ts_report_finger( touch_data->coords[i].x); input_report_abs(dev, ABS_MT_POSITION_Y, touch_data->coords[i].y); + input_report_abs(dev, ABS_MT_WIDTH_MAJOR, + touch_data->coords[i].w); + input_report_abs( + dev, ABS_MT_PRESSURE, touch_data->coords[i].p); input_report_abs(dev, ABS_MT_TOUCH_MAJOR, touch_data->coords[i].major); input_report_abs(dev, ABS_MT_TOUCH_MINOR, @@ -1592,6 +1598,8 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data) input_dev, ABS_MT_POSITION_X, 0, ts_bdata->panel_max_x, 0, 0); input_set_abs_params( input_dev, ABS_MT_POSITION_Y, 0, ts_bdata->panel_max_y, 0, 0); + input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); input_set_abs_params( input_dev, ABS_MT_TOUCH_MAJOR, 0, ts_bdata->panel_max_w, 0, 0); input_set_abs_params( diff --git a/goodix_ts_core.h b/goodix_ts_core.h index db366eb..70afaa7 100644 --- a/goodix_ts_core.h +++ b/goodix_ts_core.h @@ -49,7 +49,7 @@ #define GOODIX_CORE_DRIVER_NAME "goodix_ts" #define GOODIX_PEN_DRIVER_NAME "goodix_ts,pen" -#define GOODIX_DRIVER_VERSION "v1.0.4" +#define GOODIX_DRIVER_VERSION "v1.0.5" #define GOODIX_MAX_TOUCH 10 #define GOODIX_PEN_MAX_PRESSURE 4096 #define GOODIX_MAX_PEN_KEY 2 @@ -384,7 +384,7 @@ enum touch_point_status { /* coordinate package */ struct goodix_ts_coords { int status; /* NONE, RELEASE, TOUCH */ - unsigned int x, y, major, minor, p; + unsigned int x, y, major, minor, p, w; signed char angle; }; diff --git a/goodix_ts_proc.c b/goodix_ts_proc.c index afc94ba..5e8f4ae 100644 --- a/goodix_ts_proc.c +++ b/goodix_ts_proc.c @@ -21,6 +21,7 @@ #define CMD_GET_SELF_BASEDATA "get_self_base" #define CMD_SET_DOUBLE_TAP "set_double_tap" #define CMD_SET_SINGLE_TAP "set_single_tap" +#define CMD_SET_LONG_PRESS "set_long_press" #define CMD_SET_CHARGE_MODE "set_charge_mode" #define CMD_SET_IRQ_ENABLE "set_irq_enable" #define CMD_SET_ESD_ENABLE "set_esd_enable" @@ -32,16 +33,25 @@ #define CMD_GET_TX_FREQ "get_tx_freq" #define CMD_RESET "reset" #define CMD_SET_SENSE_ENABLE "set_sense_enable" +#define CMD_GET_CONFIG "get_config" +#define CMD_GET_FW_STATUS "get_fw_status" +#define CMD_SET_HIGHSENSE_MODE "set_highsense_mode" +#define CMD_SET_GRIP_DATA "set_grip_data" +#define CMD_SET_PALM_MODE "set_palm_mode" +#define CMD_SET_NOISE_MODE "set_noise_mode" +#define CMD_SET_WATER_MODE "set_water_mode" char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST, CMD_SELF_OPEN_TEST, CMD_NOISE_TEST, CMD_AUTO_NOISE_TEST, CMD_SHORT_TEST, CMD_GET_PACKAGE_ID, CMD_GET_VERSION, CMD_GET_RAWDATA, CMD_GET_DIFFDATA, CMD_GET_BASEDATA, CMD_GET_SELF_RAWDATA, CMD_GET_SELF_DIFFDATA, CMD_GET_SELF_BASEDATA, CMD_SET_DOUBLE_TAP, CMD_SET_SINGLE_TAP, - CMD_SET_CHARGE_MODE, CMD_SET_IRQ_ENABLE, CMD_SET_ESD_ENABLE, - CMD_SET_DEBUG_LOG, CMD_SET_SCAN_MODE, CMD_GET_SCAN_MODE, - CMD_SET_CONTINUE_MODE, CMD_GET_CHANNEL_NUM, CMD_GET_TX_FREQ, CMD_RESET, - CMD_SET_SENSE_ENABLE, NULL }; + CMD_SET_LONG_PRESS, CMD_SET_CHARGE_MODE, CMD_SET_IRQ_ENABLE, + CMD_SET_ESD_ENABLE, CMD_SET_DEBUG_LOG, CMD_SET_SCAN_MODE, + CMD_GET_SCAN_MODE, CMD_SET_CONTINUE_MODE, CMD_GET_CHANNEL_NUM, + CMD_GET_TX_FREQ, CMD_RESET, CMD_SET_SENSE_ENABLE, CMD_GET_CONFIG, + CMD_GET_FW_STATUS, CMD_SET_HIGHSENSE_MODE, CMD_SET_GRIP_DATA, + CMD_SET_PALM_MODE, CMD_SET_NOISE_MODE, CMD_SET_WATER_MODE, NULL }; /* test limits keyword */ #define CSV_TP_SPECIAL_RAW_MIN "special_raw_min" @@ -54,6 +64,10 @@ char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST, #define CSV_TP_SELFNOISE_LIMIT "noise_selfdata_limit" #define CSV_TP_TEST_CONFIG "test_config" +#define PALM_FUNC 0 +#define NOISE_FUNC 1 +#define WATER_FUNC 2 + #define SHORT_SIZE 100 #define LARGE_SIZE 4096 #define MAX_FRAME_CNT 50 @@ -991,140 +1005,140 @@ static void goodix_save_header(void) index += sprintf(&rbuf[index], "</ItemList>\n"); } -static void goodix_save_limits(void) -{ - int tx = cd->ic_info.parm.drv_num; - int rx = cd->ic_info.parm.sen_num; - int i; - int chn1; - int chn2; - int r; - - index += sprintf(&rbuf[index], "<TestItems>\n"); - - /* save short result */ - if (ts_test->item[GTP_SHORT_TEST]) { - index += sprintf(&rbuf[index], "<Item name=\"Short Test\">\n"); - index += sprintf(&rbuf[index], "<ShortNum>%d</ShortNum>\n", - ts_test->short_res.short_num); - for (i = 0; i < ts_test->short_res.short_num; i++) { - chn1 = ts_test->short_res.short_msg[4 * i]; - chn2 = ts_test->short_res.short_msg[4 * i + 1]; - r = (ts_test->short_res.short_msg[4 * i + 2] << 8) + - ts_test->short_res.short_msg[4 * i + 3]; - if (chn1 == CHN_VDD) - index += sprintf(&rbuf[index], - "<ShortMess Chn1=\"VDD\" "); - else if (chn1 == CHN_GND) - index += sprintf(&rbuf[index], - "<ShortMess Chn1=\"GND\" "); - else if (chn1 & DRV_CHANNEL_FLAG) - index += sprintf(&rbuf[index], - "<ShortMess Chn1=\"Tx%d\" ", - chn1 & 0x7f); - else - index += sprintf(&rbuf[index], - "<ShortMess Chn1=\"Rx%d\" ", - chn1 & 0x7f); - if (chn2 == CHN_VDD) - index += sprintf(&rbuf[index], - "Chn2=\"VDD\" ShortResistor= \"%dKom\"/>\n", - r); - else if (chn2 == CHN_GND) - index += sprintf(&rbuf[index], - "Chn2=\"GND\" ShortResistor= \"%dKom\"/>\n", - r); - else if (chn2 & DRV_CHANNEL_FLAG) - index += sprintf(&rbuf[index], - "Chn2=\"Tx%d\" ShortResistor= \"%dKom\"/>\n", - chn2 & 0x7f, r); - else - index += sprintf(&rbuf[index], - "Chn2=\"Rx%d\" ShortResistor= \"%dKom\"/>\n", - chn2 & 0x7f, r); - } - index += sprintf(&rbuf[index], "</Item>\n"); - } - - /* save open limits */ - if (ts_test->item[GTP_CAP_TEST]) { - index += sprintf( - &rbuf[index], "<Item name=\"Rawdata Test Sets\">\n"); - index += sprintf(&rbuf[index], - "<TotalFrameCnt>%d</TotalFrameCnt>\n", raw_data_cnt); - /* rawdata max limit */ - index += sprintf(&rbuf[index], "<MaxRawLimit>\n"); - for (i = 0; i < tx * rx; i++) { - index += sprintf( - &rbuf[index], "%d,", ts_test->max_limits[i]); - if ((i + 1) % tx == 0) - index += sprintf(&rbuf[index], "\n"); - } - index += sprintf(&rbuf[index], "</MaxRawLimit>\n"); - /* rawdata min limit */ - index += sprintf(&rbuf[index], "<MinRawLimit>\n"); - for (i = 0; i < tx * rx; i++) { - index += sprintf( - &rbuf[index], "%d,", ts_test->min_limits[i]); - if ((i + 1) % tx == 0) - index += sprintf(&rbuf[index], "\n"); - } - index += sprintf(&rbuf[index], "</MinRawLimit>\n"); - /* Max Accord limit */ - index += sprintf(&rbuf[index], "<MaxAccordLimit>\n"); - for (i = 0; i < tx * rx; i++) { - index += sprintf(&rbuf[index], "%d,", - ts_test->deviation_limits[i]); - if ((i + 1) % tx == 0) - index += sprintf(&rbuf[index], "\n"); - } - index += sprintf(&rbuf[index], "</MaxAccordLimit>\n"); - index += sprintf(&rbuf[index], "</Item>\n"); - } - - /* save noise limit */ - if (ts_test->item[GTP_NOISE_TEST]) { - index += sprintf( - &rbuf[index], "<Item name=\"Diffdata Test Sets\">\n"); - index += sprintf(&rbuf[index], - "<TotalFrameCnt>%d</TotalFrameCnt>\n", noise_data_cnt); - index += sprintf(&rbuf[index], - "<MaxJitterLimit>%d</MaxJitterLimit>\n", - ts_test->noise_threshold); - index += sprintf(&rbuf[index], "</Item>\n"); - } - - /* save self rawdata limit */ - if (ts_test->item[GTP_SELFCAP_TEST]) { - index += sprintf(&rbuf[index], - "<Item name=\"Self Rawdata Test Sets\">\n"); - index += sprintf( - &rbuf[index], "<TotalFrameCnt>1</TotalFrameCnt>\n"); - index += sprintf(&rbuf[index], "<MaxRawLimit>\n"); - for (i = 0; i < tx + rx; i++) { - index += sprintf(&rbuf[index], "%d,", - ts_test->self_max_limits[i]); - if ((i + 1) % tx == 0) - index += sprintf(&rbuf[index], "\n"); - } - if ((tx + rx) % tx != 0) - index += sprintf(&rbuf[index], "\n"); - index += sprintf(&rbuf[index], "</MaxRawLimit>\n"); - index += sprintf(&rbuf[index], "<MinRawLimit>\n"); - for (i = 0; i < tx + rx; i++) { - index += sprintf(&rbuf[index], "%d,", - ts_test->self_min_limits[i]); - if ((i + 1) % tx == 0) - index += sprintf(&rbuf[index], "\n"); - } - if ((tx + rx) % tx != 0) - index += sprintf(&rbuf[index], "\n"); - index += sprintf(&rbuf[index], "</MinRawLimit>\n"); - index += sprintf(&rbuf[index], "</Item>\n"); - } - - index += sprintf(&rbuf[index], "</TestItems>\n"); -} +//static void goodix_save_limits(void) +//{ +// int tx = cd->ic_info.parm.drv_num; +// int rx = cd->ic_info.parm.sen_num; +// int i; +// int chn1; +// int chn2; +// int r; +// +// index += sprintf(&rbuf[index], "<TestItems>\n"); +// +// /* save short result */ +// if (ts_test->item[GTP_SHORT_TEST]) { +// index += sprintf(&rbuf[index], "<Item name=\"Short Test\">\n"); +// index += sprintf(&rbuf[index], "<ShortNum>%d</ShortNum>\n", +// ts_test->short_res.short_num); +// for (i = 0; i < ts_test->short_res.short_num; i++) { +// chn1 = ts_test->short_res.short_msg[4 * i]; +// chn2 = ts_test->short_res.short_msg[4 * i + 1]; +// r = (ts_test->short_res.short_msg[4 * i + 2] << 8) + +// ts_test->short_res.short_msg[4 * i + 3]; +// if (chn1 == CHN_VDD) +// index += sprintf(&rbuf[index], +// "<ShortMess Chn1=\"VDD\" "); +// else if (chn1 == CHN_GND) +// index += sprintf(&rbuf[index], +// "<ShortMess Chn1=\"GND\" "); +// else if (chn1 & DRV_CHANNEL_FLAG) +// index += sprintf(&rbuf[index], +// "<ShortMess Chn1=\"Tx%d\" ", +// chn1 & 0x7f); +// else +// index += sprintf(&rbuf[index], +// "<ShortMess Chn1=\"Rx%d\" ", +// chn1 & 0x7f); +// if (chn2 == CHN_VDD) +// index += sprintf(&rbuf[index], +// "Chn2=\"VDD\" ShortResistor= \"%dKom\"/>\n", +// r); +// else if (chn2 == CHN_GND) +// index += sprintf(&rbuf[index], +// "Chn2=\"GND\" ShortResistor= \"%dKom\"/>\n", +// r); +// else if (chn2 & DRV_CHANNEL_FLAG) +// index += sprintf(&rbuf[index], +// "Chn2=\"Tx%d\" ShortResistor= \"%dKom\"/>\n", +// chn2 & 0x7f, r); +// else +// index += sprintf(&rbuf[index], +// "Chn2=\"Rx%d\" ShortResistor= \"%dKom\"/>\n", +// chn2 & 0x7f, r); +// } +// index += sprintf(&rbuf[index], "</Item>\n"); +// } +// +// /* save open limits */ +// if (ts_test->item[GTP_CAP_TEST]) { +// index += sprintf( +// &rbuf[index], "<Item name=\"Rawdata Test Sets\">\n"); +// index += sprintf(&rbuf[index], +// "<TotalFrameCnt>%d</TotalFrameCnt>\n", raw_data_cnt); +// /* rawdata max limit */ +// index += sprintf(&rbuf[index], "<MaxRawLimit>\n"); +// for (i = 0; i < tx * rx; i++) { +// index += sprintf( +// &rbuf[index], "%d,", ts_test->max_limits[i]); +// if ((i + 1) % tx == 0) +// index += sprintf(&rbuf[index], "\n"); +// } +// index += sprintf(&rbuf[index], "</MaxRawLimit>\n"); +// /* rawdata min limit */ +// index += sprintf(&rbuf[index], "<MinRawLimit>\n"); +// for (i = 0; i < tx * rx; i++) { +// index += sprintf( +// &rbuf[index], "%d,", ts_test->min_limits[i]); +// if ((i + 1) % tx == 0) +// index += sprintf(&rbuf[index], "\n"); +// } +// index += sprintf(&rbuf[index], "</MinRawLimit>\n"); +// /* Max Accord limit */ +// index += sprintf(&rbuf[index], "<MaxAccordLimit>\n"); +// for (i = 0; i < tx * rx; i++) { +// index += sprintf(&rbuf[index], "%d,", +// ts_test->deviation_limits[i]); +// if ((i + 1) % tx == 0) +// index += sprintf(&rbuf[index], "\n"); +// } +// index += sprintf(&rbuf[index], "</MaxAccordLimit>\n"); +// index += sprintf(&rbuf[index], "</Item>\n"); +// } +// +// /* save noise limit */ +// if (ts_test->item[GTP_NOISE_TEST]) { +// index += sprintf( +// &rbuf[index], "<Item name=\"Diffdata Test Sets\">\n"); +// index += sprintf(&rbuf[index], +// "<TotalFrameCnt>%d</TotalFrameCnt>\n", noise_data_cnt); +// index += sprintf(&rbuf[index], +// "<MaxJitterLimit>%d</MaxJitterLimit>\n", +// ts_test->noise_threshold); +// index += sprintf(&rbuf[index], "</Item>\n"); +// } +// +// /* save self rawdata limit */ +// if (ts_test->item[GTP_SELFCAP_TEST]) { +// index += sprintf(&rbuf[index], +// "<Item name=\"Self Rawdata Test Sets\">\n"); +// index += sprintf( +// &rbuf[index], "<TotalFrameCnt>1</TotalFrameCnt>\n"); +// index += sprintf(&rbuf[index], "<MaxRawLimit>\n"); +// for (i = 0; i < tx + rx; i++) { +// index += sprintf(&rbuf[index], "%d,", +// ts_test->self_max_limits[i]); +// if ((i + 1) % tx == 0) +// index += sprintf(&rbuf[index], "\n"); +// } +// if ((tx + rx) % tx != 0) +// index += sprintf(&rbuf[index], "\n"); +// index += sprintf(&rbuf[index], "</MaxRawLimit>\n"); +// index += sprintf(&rbuf[index], "<MinRawLimit>\n"); +// for (i = 0; i < tx + rx; i++) { +// index += sprintf(&rbuf[index], "%d,", +// ts_test->self_min_limits[i]); +// if ((i + 1) % tx == 0) +// index += sprintf(&rbuf[index], "\n"); +// } +// if ((tx + rx) % tx != 0) +// index += sprintf(&rbuf[index], "\n"); +// index += sprintf(&rbuf[index], "</MinRawLimit>\n"); +// index += sprintf(&rbuf[index], "</Item>\n"); +// } +// +// index += sprintf(&rbuf[index], "</TestItems>\n"); +//} static void goodix_data_cal(s16 *data, size_t data_size, s16 *stat_result) { @@ -1242,12 +1256,38 @@ static void goodix_save_tail(void) index += sprintf(&rbuf[index], "</TESTLOG>\n"); } -static void goodix_save_test_result(void) +static void goodix_save_test_result(bool is_brief) { - goodix_save_header(); - goodix_save_limits(); - goodix_save_data(); - goodix_save_tail(); + if (is_brief) { + if (ts_test->item[GTP_CAP_TEST]) { + index += sprintf(&rbuf[index], "Open test:\n"); + index += sprintf(&rbuf[index], "%s\n", + ts_test->result[GTP_CAP_TEST] ? "PASS" + : "FAIL"); + } + if (ts_test->item[GTP_SHORT_TEST]) { + index += sprintf(&rbuf[index], "Short test:\n"); + index += sprintf(&rbuf[index], "%s\n", + ts_test->result[GTP_SHORT_TEST] ? "PASS" + : "FAIL"); + } + if (ts_test->item[GTP_NOISE_TEST]) { + index += sprintf(&rbuf[index], "Noise test:\n"); + index += sprintf(&rbuf[index], "%s\n", + ts_test->result[GTP_NOISE_TEST] ? "PASS" + : "FAIL"); + } + if (ts_test->item[GTP_SELFCAP_TEST]) { + index += sprintf(&rbuf[index], "Self test:\n"); + index += sprintf(&rbuf[index], "%s\n", + ts_test->result[GTP_SELFCAP_TEST] ? "PASS" + : "FAIL"); + } + } else { + goodix_save_header(); + goodix_save_data(); + goodix_save_tail(); + } } static void goto_next_line(char **ptr) @@ -1793,7 +1833,7 @@ exit: return ret; } -static int goodix_auto_test(void) +static int goodix_auto_test(bool is_brief) { struct goodix_ts_cmd temp_cmd; int ret; @@ -1839,7 +1879,7 @@ static int goodix_auto_test(void) cd->hw_ops->irq_enable(cd, true); goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); - goodix_save_test_result(); + goodix_save_test_result(is_brief); return 0; } @@ -1854,6 +1894,7 @@ static void goodix_auto_noise_test(u16 cnt, int threshold) int tmp_val; u8 status; int retry = 10; + int err_cnt = 0; int i; raw_addr = cd->ic_info.misc.frame_data_addr + @@ -1885,15 +1926,46 @@ static void goodix_auto_noise_test(u16 cnt, int threshold) } cd->hw_ops->read(cd, raw_addr, (u8 *)tmp_buf, tx * rx * 2); + goodix_rotate_abcd2cbad(tx, rx, tmp_buf); + index += sprintf(&rbuf[index], "max:\n"); for (i = 0; i < tx * rx; i++) { tmp_val = tmp_buf[i]; - tmp_val = ABS(tmp_val); - if (tmp_val > threshold) { - index = sprintf(rbuf, "FAIL\n"); - goto exit; - } + index += sprintf(&rbuf[index], "%3d,", tmp_val); + if ((i + 1) % tx == 0) + index += sprintf(&rbuf[index], "\n"); + if (ABS(tmp_val) > threshold) + err_cnt++; } - index = sprintf(rbuf, "PASS\n"); + + status = 0; + cd->hw_ops->write(cd, sync_addr, &status, 1); + retry = 10; + while (retry--) { + cd->hw_ops->read(cd, sync_addr, &status, 1); + if (status == 0x80) + break; + usleep_range(5000, 5100); + } + if (retry < 0) { + ts_err("noise data not ready, status[%x]", status); + goto exit; + } + cd->hw_ops->read(cd, raw_addr, (u8 *)tmp_buf, tx * rx * 2); + goodix_rotate_abcd2cbad(tx, rx, tmp_buf); + index += sprintf(&rbuf[index], "min:\n"); + for (i = 0; i < tx * rx; i++) { + tmp_val = tmp_buf[i]; + index += sprintf(&rbuf[index], "%3d,", tmp_val); + if ((i + 1) % tx == 0) + index += sprintf(&rbuf[index], "\n"); + if (ABS(tmp_val) > threshold) + err_cnt++; + } + + if (err_cnt > 0) + index += sprintf(&rbuf[index], "Result: FAIL\n"); + else + index += sprintf(&rbuf[index], "Result: PASS\n"); exit: cd->hw_ops->reset(cd, 100); @@ -2053,19 +2125,31 @@ static void goodix_set_scan_mode(u8 val) struct goodix_ts_cmd temp_cmd; if (val == 0) { + temp_cmd.len = 6; + temp_cmd.cmd = 0x25; + temp_cmd.data[0] = 0; + temp_cmd.data[1] = 0; ts_info("set scan mode to default"); index = sprintf(rbuf, "set scan mode to default\n"); } else if (val == 1) { + temp_cmd.len = 5; + temp_cmd.cmd = 0x9F; + temp_cmd.data[0] = 1; ts_info("set scan mode to idle"); index = sprintf(rbuf, "set scan mode to idle\n"); } else { + temp_cmd.len = 5; + temp_cmd.cmd = 0x9F; + temp_cmd.data[0] = 0; + cd->hw_ops->send_cmd(cd, &temp_cmd); + temp_cmd.len = 6; + temp_cmd.cmd = 0x25; + temp_cmd.data[0] = 0xff; + temp_cmd.data[1] = 0xff; ts_info("set scan mode to active"); index = sprintf(rbuf, "set scan mode to active\n"); } - temp_cmd.len = 5; - temp_cmd.cmd = 0x9F; - temp_cmd.data[0] = val; cd->hw_ops->send_cmd(cd, &temp_cmd); } @@ -2119,11 +2203,151 @@ static void goodix_set_continue_mode(u8 val) } temp_cmd.len = 5; - temp_cmd.cmd = 0xC3; + temp_cmd.cmd = 0xC6; temp_cmd.data[0] = val; cd->hw_ops->send_cmd(cd, &temp_cmd); } +static void goodix_read_config(void) +{ + int ret; + int i; + u8 cfg_buf[2500]; + + ret = cd->hw_ops->read_config(cd, cfg_buf, sizeof(cfg_buf)); + if (ret < 0) { + ts_err("read config failed"); + return; + } + + for (i = 0; i < 200; i++) { // only print 200 bytes + index += sprintf(&rbuf[index], "%02x,", cfg_buf[i]); + if ((i + 1) % 20 == 0) + index += sprintf(&rbuf[index], "\n"); + } +} + +static void goodix_get_fw_status(void) +{ + u32 status_addr; + u32 noise_lv_addr; + u32 offset; + u8 val; + + offset = cd->ic_info.misc.frame_data_addr + + cd->ic_info.misc.frame_data_head_len + + cd->ic_info.misc.fw_attr_len; + status_addr = offset + 38; + noise_lv_addr = offset + 65; + + cd->hw_ops->read(cd, status_addr, &val, 1); + ts_info("addr:0x%04x fw_status:0x%02X", status_addr, val); + index += sprintf( + &rbuf[index], "touch[%d] ", (val & (0x01 << 0)) ? 1 : 0); + index += + sprintf(&rbuf[index], "game[%d] ", (val & (0x01 << 1)) ? 1 : 0); + index += + sprintf(&rbuf[index], "palm[%d] ", (val & (0x01 << 2)) ? 1 : 0); + index += sprintf( + &rbuf[index], "water[%d] ", (val & (0x01 << 3)) ? 1 : 0); + index += sprintf( + &rbuf[index], "charge[%d] ", (val & (0x01 << 4)) ? 1 : 0); + index += sprintf( + &rbuf[index], "lowtemp[%d] ", (val & (0x01 << 5)) ? 1 : 0); + + cd->hw_ops->read(cd, noise_lv_addr, &val, 1); + ts_info("noise level addr: 0x%04x", noise_lv_addr); + index += sprintf(&rbuf[index], "noise-lv[%d]\n", val); +} + +static void goodix_set_highsense_mode(u8 val) +{ + struct goodix_ts_cmd temp_cmd; + static bool flag = false; + + if (val == 0 && flag) { + flag = false; + ts_info("exit highsense mode"); + index = sprintf(rbuf, "exit highsense mode\n"); + } else if (val == 1 && !flag) { + flag = true; + ts_info("enter highsense mode"); + index = sprintf(rbuf, "enter highsense mode\n"); + } else { + ts_info("have already %s", val ? "ON" : "OFF"); + return; + } + + temp_cmd.len = 5; + temp_cmd.cmd = 0x72; + temp_cmd.data[0] = val; + cd->hw_ops->send_cmd(cd, &temp_cmd); +} + +static void goodix_set_grip_data(u8 val) +{ + struct goodix_ts_cmd temp_cmd; + + if (val == 0) { + ts_info("portrait mode"); + index = sprintf(rbuf, "portrait mode\n"); + temp_cmd.len = 4; + temp_cmd.cmd = 0x18; + } else if (val == 1) { + ts_info("landscape left"); + index = sprintf(rbuf, "landscape left\n"); + temp_cmd.len = 5; + temp_cmd.cmd = 0x17; + temp_cmd.data[0] = 0; + } else if (val == 2) { + ts_info("landscape right"); + index = sprintf(rbuf, "landscape right\n"); + temp_cmd.len = 5; + temp_cmd.cmd = 0x17; + temp_cmd.data[0] = 1; + } else { + ts_err("invalid grip data, %d", val); + return; + } + + cd->hw_ops->send_cmd(cd, &temp_cmd); +} + +static void goodix_set_custom_mode(u8 type, u8 val) +{ + struct goodix_ts_cmd temp_cmd; + + temp_cmd.len = 6; + temp_cmd.cmd = 0xC7; + temp_cmd.data[0] = type; + + if (type == PALM_FUNC) + index += sprintf(&rbuf[index], "palm "); + else if (type == NOISE_FUNC) + index += sprintf(&rbuf[index], "noise "); + else if (type == WATER_FUNC) + index += sprintf(&rbuf[index], "water "); + else { + ts_err("invalid type, %d", type); + return; + } + + if (val == 1) { + ts_info("restore"); + index += sprintf(&rbuf[index], "restore\n"); + temp_cmd.data[1] = 0; + } else if (val == 0) { + ts_info("disabled"); + index += sprintf(&rbuf[index], "disabled\n"); + temp_cmd.data[1] = 1; + } else { + ts_err("invalid val, %d", val); + return; + } + + cd->hw_ops->send_cmd(cd, &temp_cmd); +} + static ssize_t driver_test_write( struct file *file, const char __user *buf, size_t count, loff_t *pos) { @@ -2155,9 +2379,9 @@ static ssize_t driver_test_write( if (!strncmp(p, CMD_FW_UPDATE, strlen(CMD_FW_UPDATE))) { rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); - ret = goodix_do_fw_update( - NULL, UPDATE_MODE_BLOCK | UPDATE_MODE_FORCE | - UPDATE_MODE_SRC_REQUEST); + ret = goodix_do_fw_update(cd->ic_configs[CONFIG_TYPE_NORMAL], + UPDATE_MODE_BLOCK | UPDATE_MODE_FORCE | + UPDATE_MODE_SRC_REQUEST); if (ret < 0) { index = sprintf(rbuf, "%s: NG\n", CMD_FW_UPDATE); } else { @@ -2287,6 +2511,33 @@ static ssize_t driver_test_write( goto exit; } + if (!strncmp(p, CMD_SET_LONG_PRESS, strlen(CMD_SET_LONG_PRESS))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_LONG_PRESS); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_LONG_PRESS); + goto exit; + } + if (cmd_val == 0) { + cd->gesture_type &= ~GESTURE_FOD_PRESS; + index = sprintf( + rbuf, "%s: disable OK\n", CMD_SET_LONG_PRESS); + ts_info("disable single tap"); + } else { + cd->gesture_type |= GESTURE_FOD_PRESS; + index = sprintf( + rbuf, "%s: enable OK\n", CMD_SET_LONG_PRESS); + ts_info("enable single tap"); + } + goto exit; + } + if (!strncmp(p, CMD_SET_IRQ_ENABLE, strlen(CMD_SET_IRQ_ENABLE))) { rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); token = strsep(&p, ","); @@ -2365,7 +2616,7 @@ static ssize_t driver_test_write( if (!strncmp(p, CMD_AUTO_TEST, strlen(CMD_AUTO_TEST))) { raw_data_cnt = 16; noise_data_cnt = 1; - rbuf = kzalloc(HUGE_SIZE, GFP_KERNEL); + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); ret = malloc_test_resource(); if (ret < 0) { ts_err("malloc test resource failed"); @@ -2375,7 +2626,7 @@ static ssize_t driver_test_write( ts_test->item[GTP_NOISE_TEST] = true; ts_test->item[GTP_SELFCAP_TEST] = true; ts_test->item[GTP_SHORT_TEST] = true; - goodix_auto_test(); + goodix_auto_test(true); goto exit; } @@ -2448,7 +2699,7 @@ static ssize_t driver_test_write( goto exit; } ts_test->item[GTP_NOISE_TEST] = true; - goodix_auto_test(); + goodix_auto_test(false); goto exit; } @@ -2471,7 +2722,7 @@ static ssize_t driver_test_write( ts_err("%s: invalid cmd param", CMD_AUTO_NOISE_TEST); goto exit; } - rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + rbuf = kzalloc(HUGE_SIZE, GFP_KERNEL); goodix_auto_noise_test(cmd_val, cmd_val2); goto exit; } @@ -2570,7 +2821,7 @@ static ssize_t driver_test_write( } ts_test->item[GTP_CAP_TEST] = true; ts_test->freq = cmd_val2; - goodix_auto_test(); + goodix_auto_test(false); goto exit; } @@ -2582,7 +2833,7 @@ static ssize_t driver_test_write( goto exit; } ts_test->item[GTP_SELFCAP_TEST] = true; - goodix_auto_test(); + goodix_auto_test(false); goto exit; } @@ -2594,7 +2845,110 @@ static ssize_t driver_test_write( goto exit; } ts_test->item[GTP_SHORT_TEST] = true; - goodix_auto_test(); + goodix_auto_test(false); + goto exit; + } + + if (!strncmp(p, CMD_GET_CONFIG, strlen(CMD_GET_CONFIG))) { + rbuf = kzalloc(LARGE_SIZE, GFP_KERNEL); + goodix_read_config(); + goto exit; + } + + if (!strncmp(p, CMD_GET_FW_STATUS, strlen(CMD_GET_FW_STATUS))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + goodix_get_fw_status(); + goto exit; + } + + if (!strncmp(p, CMD_SET_HIGHSENSE_MODE, + strlen(CMD_SET_HIGHSENSE_MODE))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_HIGHSENSE_MODE); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_HIGHSENSE_MODE); + goto exit; + } + if (cmd_val > 1 || cmd_val < 0) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_HIGHSENSE_MODE); + goto exit; + } + goodix_set_highsense_mode(cmd_val); + goto exit; + } + + if (!strncmp(p, CMD_SET_GRIP_DATA, strlen(CMD_SET_GRIP_DATA))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_GRIP_DATA); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_GRIP_DATA); + goto exit; + } + goodix_set_grip_data(cmd_val); + goto exit; + } + + if (!strncmp(p, CMD_SET_PALM_MODE, strlen(CMD_SET_PALM_MODE))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_PALM_MODE); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_PALM_MODE); + goto exit; + } + goodix_set_custom_mode(PALM_FUNC, cmd_val); + goto exit; + } + + if (!strncmp(p, CMD_SET_NOISE_MODE, strlen(CMD_SET_NOISE_MODE))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_NOISE_MODE); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_NOISE_MODE); + goto exit; + } + goodix_set_custom_mode(NOISE_FUNC, cmd_val); + goto exit; + } + + if (!strncmp(p, CMD_SET_WATER_MODE, strlen(CMD_SET_WATER_MODE))) { + rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL); + token = strsep(&p, ","); + if (!token || !p) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_WATER_MODE); + goto exit; + } + if (kstrtos32(p, 10, &cmd_val)) { + index = sprintf(rbuf, "%s: invalid cmd param\n", + CMD_SET_WATER_MODE); + goto exit; + } + goodix_set_custom_mode(WATER_FUNC, cmd_val); goto exit; } |