summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWendly Li <wendlyli@google.com>2022-09-05 10:12:22 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2022-09-05 10:12:22 +0000
commit5fff099fe55ba7bfc97e7dce6ccbcca7997337f3 (patch)
treedd369b89a52d4b89d18f14969ed5f467e804d8f3
parentaa8c95f9a4b81a9d34ea399acbe041906e32ff35 (diff)
parent4b6547193acf4c42323d6407ea29da2fa04cf564 (diff)
downloadgoodix_touch-5fff099fe55ba7bfc97e7dce6ccbcca7997337f3.tar.gz
Merge changes I64268295,Id853e7e4 into android13-gs-pixel-5.10-tm-qpr1
* changes: touch/goodix: Import v1.1.1 driver touch/goodix: Import v1.1.0 driver
-rw-r--r--goodix_brl_hw.c17
-rw-r--r--goodix_ts_core.c19
-rw-r--r--goodix_ts_core.h6
-rw-r--r--goodix_ts_gesture.c58
-rw-r--r--goodix_ts_proc.c489
5 files changed, 510 insertions, 79 deletions
diff --git a/goodix_brl_hw.c b/goodix_brl_hw.c
index 29fa48d..be127d4 100644
--- a/goodix_brl_hw.c
+++ b/goodix_brl_hw.c
@@ -828,6 +828,10 @@ static int convert_ic_info(struct goodix_ic_info *info, const u8 *data)
LE16_TO_CPU(misc->stylus_rawdata_len);
LE32_TO_CPU(misc->noise_data_addr);
LE32_TO_CPU(misc->esd_addr);
+ LE32_TO_CPU(misc->auto_scan_cmd_addr);
+ LE32_TO_CPU(misc->auto_scan_info_addr);
+ LE32_TO_CPU(misc->self_tx_cfg_addr);
+ LE32_TO_CPU(misc->self_rx_cfg_addr);
return 0;
}
@@ -896,6 +900,10 @@ static void print_ic_info(struct goodix_ic_info *ic_info)
misc->stylus_rawdata_addr, misc->stylus_rawdata_len);
ts_info("esd_addr: 0x%04X", misc->esd_addr);
ts_info("frame_data_addr: 0x%04X", misc->frame_data_addr);
+ ts_info("self_tx_cfg_addr: 0x%04x",
+ misc->self_tx_cfg_addr);
+ ts_info("self_rx_cfg_addr: 0x%04x",
+ misc->self_rx_cfg_addr);
}
static int brl_get_ic_info(
@@ -986,7 +994,7 @@ static int brl_esd_check(struct goodix_ts_core *cd)
return ret;
}
- if (esd_value == GOODIX_ESD_TICK_WRITE_DATA) {
+ if (esd_value != 0xFF) {
ts_err("esd check failed, 0x%x", esd_value);
return -EINVAL;
}
@@ -1126,12 +1134,10 @@ static int goodix_touch_handler(struct goodix_ts_core *cd,
point_type = event_data->data[0] & 0x0F;
if (point_type == POINT_TYPE_STYLUS ||
point_type == POINT_TYPE_STYLUS_HOVER) {
- ret = checksum_cmp(event_data->data,
- BYTES_PER_POINT * 2 + 2, CHECKSUM_MODE_U8_LE);
+ ret = checksum_cmp(event_data->data, 16 + 2, CHECKSUM_MODE_U8_LE);
if (ret) {
ts_debug("touch data checksum error");
- ts_debug("data:%*ph", BYTES_PER_POINT * 2 + 2,
- event_data->data);
+ ts_debug("data:%*ph", 16 + 2, event_data->data);
return -EINVAL;
}
} else {
@@ -1218,6 +1224,7 @@ static int brl_event_handler(
CHECKSUM_MODE_U8_LE)) {
ts_debug("touch head checksum err[%*ph]", IRQ_EVENT_HEAD_LEN,
event_data);
+ hw_ops->after_event_handler(cd);
return -EINVAL;
}
diff --git a/goodix_ts_core.c b/goodix_ts_core.c
index 1734f19..9293e88 100644
--- a/goodix_ts_core.c
+++ b/goodix_ts_core.c
@@ -2111,7 +2111,7 @@ static void goodix_ts_esd_work(struct work_struct *work)
if (ts_esd->irq_status)
goto exit;
- if (!atomic_read(&ts_esd->esd_on))
+ if (!atomic_read(&ts_esd->esd_on) || atomic_read(&cd->suspended))
return;
if (!hw_ops->esd_check)
@@ -2120,9 +2120,22 @@ static void goodix_ts_esd_work(struct work_struct *work)
ret = hw_ops->esd_check(cd);
if (ret) {
ts_err("esd check failed");
- goodix_ts_power_off(cd);
+ gpio_direction_output(cd->board_data.reset_gpio, 0);
+ if (cd->iovdd)
+ ret = regulator_disable(cd->iovdd);
+ if (cd->avdd)
+ ret = regulator_disable(cd->avdd);
+
usleep_range(5000, 5100);
- goodix_ts_power_on(cd);
+
+ if (cd->iovdd) {
+ ret = regulator_enable(cd->iovdd);
+ usleep_range(3000, 3100);
+ }
+ if (cd->avdd)
+ ret = regulator_enable(cd->avdd);
+ usleep_range(15000, 15100);
+ gpio_direction_output(cd->board_data.reset_gpio, 1);
}
exit:
diff --git a/goodix_ts_core.h b/goodix_ts_core.h
index 10259e3..2ed9f37 100644
--- a/goodix_ts_core.h
+++ b/goodix_ts_core.h
@@ -50,7 +50,7 @@
#define GOODIX_CORE_DRIVER_NAME "goodix_ts"
#define GOODIX_PEN_DRIVER_NAME "goodix_ts,pen"
-#define GOODIX_DRIVER_VERSION "v1.0.13"
+#define GOODIX_DRIVER_VERSION "v1.1.1"
#define GOODIX_MAX_TOUCH 10
#define GOODIX_PEN_MAX_PRESSURE 4096
#define GOODIX_MAX_PEN_KEY 2
@@ -267,6 +267,10 @@ struct goodix_ic_info_misc { /* other data */
u16 stylus_rawdata_len;
u32 noise_data_addr;
u32 esd_addr;
+ u32 auto_scan_cmd_addr;
+ u32 auto_scan_info_addr;
+ u32 self_tx_cfg_addr;
+ u32 self_rx_cfg_addr;
};
struct goodix_ic_info {
diff --git a/goodix_ts_gesture.c b/goodix_ts_gesture.c
index 903022c..d4246b0 100644
--- a/goodix_ts_gesture.c
+++ b/goodix_ts_gesture.c
@@ -225,7 +225,8 @@ static int gsx_gesture_ist(
{
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
struct goodix_ts_event gs_event = { 0 };
- int fodx, fody, overlay_area;
+ int coor_x, coor_y, coor_size, coor_press;
+ int major, minor, orientation;
int ret;
if (atomic_read(&cd->suspended) == 0 || cd->gesture_type == 0)
@@ -247,15 +248,43 @@ static int gsx_gesture_ist(
if (gs_event.event_type & EVENT_STATUS)
goodix_ts_report_status(cd, &gs_event);
+ coor_x = le16_to_cpup((__le16 *)gs_event.gesture_data.data);
+ coor_y = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 2));
+ coor_size = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 4));
+ coor_press = gs_event.gesture_data.data[6];
+ major = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 7));
+ minor = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 9));
+ orientation = (s8)gs_event.gesture_data.data[11];
+
switch (gs_event.gesture_data.gesture_type) {
case GOODIX_GESTURE_SINGLE_TAP:
if (cd->gesture_type & GESTURE_SINGLE_TAP) {
ts_info("get SINGLE-TAP gesture");
+ ts_debug(
+ "fodx:%d fody:%d size:%d press:%d maj:%d min:%d ori:%d",
+ coor_x, coor_y, coor_size, coor_press, major,
+ minor, orientation);
+ input_report_key(cd->input_dev, BTN_TOUCH, 1);
+ input_mt_slot(cd->input_dev, 0);
+ input_mt_report_slot_state(
+ cd->input_dev, MT_TOOL_FINGER, 1);
+ input_report_abs(
+ cd->input_dev, ABS_MT_POSITION_X, coor_x);
+ input_report_abs(
+ cd->input_dev, ABS_MT_POSITION_Y, coor_y);
+ input_report_abs(
+ cd->input_dev, ABS_MT_PRESSURE, coor_press);
+ input_report_abs(
+ cd->input_dev, ABS_MT_TOUCH_MAJOR, major);
+ input_report_abs(
+ cd->input_dev, ABS_MT_TOUCH_MINOR, minor);
input_report_key(cd->input_dev, KEY_WAKEUP, 1);
- // input_report_key(cd->input_dev, KEY_GOTO, 1);
input_sync(cd->input_dev);
+ input_report_key(cd->input_dev, BTN_TOUCH, 0);
+ input_mt_slot(cd->input_dev, 0);
+ input_mt_report_slot_state(
+ cd->input_dev, MT_TOOL_FINGER, 0);
input_report_key(cd->input_dev, KEY_WAKEUP, 0);
- // input_report_key(cd->input_dev, KEY_GOTO, 0);
input_sync(cd->input_dev);
} else {
ts_debug("not enable SINGLE-TAP");
@@ -275,20 +304,24 @@ static int gsx_gesture_ist(
case GOODIX_GESTURE_FOD_DOWN:
if (cd->gesture_type & GESTURE_FOD_PRESS) {
ts_info("get FOD-DOWN gesture");
- fodx = le16_to_cpup((__le16 *)gs_event.gesture_data.data);
- fody = le16_to_cpup(
- (__le16 *)(gs_event.gesture_data.data + 2));
- overlay_area = gs_event.gesture_data.data[4];
- ts_debug("fodx:%d fody:%d overlay_area:%d", fodx, fody,
- overlay_area);
+ ts_debug(
+ "fodx:%d fody:%d size:%d press:%d maj:%d min:%d ori:%d",
+ coor_x, coor_y, coor_size, coor_press, major,
+ minor, orientation);
input_report_key(cd->input_dev, BTN_TOUCH, 1);
input_mt_slot(cd->input_dev, 0);
input_mt_report_slot_state(
cd->input_dev, MT_TOOL_FINGER, 1);
input_report_abs(
- cd->input_dev, ABS_MT_POSITION_X, fodx);
+ cd->input_dev, ABS_MT_POSITION_X, coor_x);
+ input_report_abs(
+ cd->input_dev, ABS_MT_POSITION_Y, coor_y);
+ input_report_abs(
+ cd->input_dev, ABS_MT_PRESSURE, coor_press);
+ input_report_abs(
+ cd->input_dev, ABS_MT_TOUCH_MAJOR, major);
input_report_abs(
- cd->input_dev, ABS_MT_POSITION_Y, fody);
+ cd->input_dev, ABS_MT_TOUCH_MINOR, minor);
input_sync(cd->input_dev);
} else {
ts_debug("not enable FOD-DOWN");
@@ -297,9 +330,6 @@ static int gsx_gesture_ist(
case GOODIX_GESTURE_FOD_UP:
if (cd->gesture_type & GESTURE_FOD_PRESS) {
ts_info("get FOD-UP gesture");
- // fodx = le16_to_cpup((__le16 *)gs_event.gesture_data);
- // fody = le16_to_cpup((__le16 *)(gs_event.gesture_data
- // + 2)); overlay_area = gs_event.gesture_data[4];
input_report_key(cd->input_dev, BTN_TOUCH, 0);
input_mt_slot(cd->input_dev, 0);
input_mt_report_slot_state(
diff --git a/goodix_ts_proc.c b/goodix_ts_proc.c
index fff016f..3f90291 100644
--- a/goodix_ts_proc.c
+++ b/goodix_ts_proc.c
@@ -45,6 +45,9 @@
#define CMD_SET_NOISE_MODE "set_noise_mode"
#define CMD_SET_WATER_MODE "set_water_mode"
#define CMD_SET_HEATMAP "set_heatmap"
+#define CMD_GET_SELF_COMPEN "get_self_compensation"
+#define CMD_SET_REPORT_RATE "set_report_rate"
+#define CMD_GET_DUMP_LOG "get_dump_log"
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,
@@ -58,11 +61,14 @@ char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST,
CMD_GET_TX_FREQ, CMD_RESET, CMD_SET_SENSE_MODE, CMD_GET_CONFIG,
CMD_GET_FW_STATUS, CMD_SET_HIGHSENSE_MODE, CMD_SET_GRIP_DATA,
CMD_SET_GRIP_MODE, CMD_SET_PALM_MODE, CMD_SET_NOISE_MODE,
- CMD_SET_WATER_MODE, CMD_SET_HEATMAP, NULL };
+ CMD_SET_WATER_MODE, CMD_SET_HEATMAP, CMD_GET_SELF_COMPEN,
+ CMD_SET_REPORT_RATE, CMD_GET_DUMP_LOG, NULL };
/* test limits keyword */
#define CSV_TP_SPECIAL_RAW_MIN "special_raw_min"
#define CSV_TP_SPECIAL_RAW_MAX "special_raw_max"
+#define CSV_TP_SPECIAL_FREQ_RAW_MIN "special_freq_raw_min"
+#define CSV_IP_SPECIAL_FREQ_RAW_MAX "special_freq_raw_max"
#define CSV_TP_SPECIAL_RAW_DELTA "special_raw_delta"
#define CSV_TP_SHORT_THRESHOLD "shortciurt_threshold"
#define CSV_TP_SPECIAL_SELFRAW_MAX "special_selfraw_max"
@@ -77,7 +83,7 @@ char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST,
#define GRIP_FUNC 3
#define SHORT_SIZE 150
-#define LARGE_SIZE 4096
+#define LARGE_SIZE 5 * 1024
#define MAX_FRAME_CNT 50
#define HUGE_SIZE MAX_FRAME_CNT * 20 * 1024
static struct goodix_ts_core *cd;
@@ -100,11 +106,50 @@ static uint32_t index;
#define TEST_OK 1
#define TEST_NG 0
-#define MAX_LINE_LEN (1024 * 6)
-#define MAX_DRV_NUM 17
-#define MAX_SEN_NUM 35
+#define MAX_LINE_LEN (1024 * 10)
+#define MAX_DRV_NUM 52
+#define MAX_SEN_NUM 75
#define MAX_SHORT_NUM 15
+/* berlin B */
+#define MAX_DRV_NUM_BRB 52
+#define MAX_SEN_NUM_BRB 75
+#define SHORT_TEST_TIME_REG_BRB 0x26AE0
+#define DFT_ADC_DUMP_NUM_BRB 762
+#define DFT_SHORT_THRESHOLD_BRB 100
+#define DFT_DIFFCODE_SHORT_THRESHOLD_BRB 32
+#define SHORT_TEST_STATUS_REG_BRB 0x20400
+#define SHORT_TEST_RESULT_REG_BRB 0x20410
+#define DRV_DRV_SELFCODE_REG_BRB 0x2049A
+#define SEN_SEN_SELFCODE_REG_BRB 0x21AF2
+#define DRV_SEN_SELFCODE_REG_BRB 0x248A6
+#define DIFF_CODE_DATA_REG_BRB 0x269E0
+
+/* berlinD */
+#define MAX_DRV_NUM_BRD 20
+#define MAX_SEN_NUM_BRD 40
+#define SHORT_TEST_TIME_REG_BRD 0x14D7A
+#define DFT_ADC_DUMP_NUM_BRD 762
+#define DFT_SHORT_THRESHOLD_BRD 100
+#define DFT_DIFFCODE_SHORT_THRESHOLD_BRD 32
+#define SHORT_TEST_STATUS_REG_BRD 0x13400
+#define SHORT_TEST_RESULT_REG_BRD 0x13408
+#define DRV_DRV_SELFCODE_REG_BRD 0x1344E
+#define SEN_SEN_SELFCODE_REG_BRD 0x137E6
+#define DRV_SEN_SELFCODE_REG_BRD 0x14556
+#define DIFF_CODE_DATA_REG_BRD 0x14D00
+
+/* nottingham */
+#define MAX_DRV_NUM_NOT 17
+#define MAX_SEN_NUM_NOT 35
+#define SHORT_TEST_TIME_REG_NOT 0x1479E
+#define SHORT_TEST_STATUS_REG_NOT 0x13400
+#define SHORT_TEST_RESULT_REG_NOT 0x13408
+#define DRV_DRV_SELFCODE_REG_NOT 0x13446
+#define SEN_SEN_SELFCODE_REG_NOT 0x136EE
+#define DRV_SEN_SELFCODE_REG_NOT 0x14152
+#define DIFF_CODE_DATA_REG_NOT 0x14734
+
#define GESTURE_STTW 0
#define GESTURE_LPTW 1
typedef union __attribute__((packed)) {
@@ -162,6 +207,85 @@ typedef struct __attribute__((packed)) {
u16 checksum;
} test_result_t;
+/* berlin B drv-sen map */
+static u8 brl_b_drv_map[] = { 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126 };
+
+static u8 brl_b_sen_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74 };
+
+/* berlin D drv-sen map */
+static u8 brl_d_drv_map[] = {
+ 40,
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+};
+
+static u8 brl_d_sen_map[] = {
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+};
+
/* nottingham drv-sen map */
static u8 not_drv_map[] = { 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51 };
@@ -170,6 +294,74 @@ static u8 not_sen_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34 };
+struct ts_short_test_info {
+ u32 max_drv_num;
+ u32 max_sen_num;
+ u8 *drv_map;
+ u8 *sen_map;
+ u32 short_test_time_reg;
+ u32 short_test_status_reg;
+ u32 short_test_result_reg;
+ u32 drv_drv_selfcode_reg;
+ u32 sen_sen_selfcode_reg;
+ u32 drv_sen_selfcode_reg;
+ u32 diffcode_data_reg;
+ u16 short_test_dump_num;
+ u16 dft_short_threshold;
+ u16 short_diffcode_threshold;
+};
+
+static struct ts_short_test_info params_brb = {
+ MAX_DRV_NUM_BRB,
+ MAX_SEN_NUM_BRB,
+ brl_b_drv_map,
+ brl_b_sen_map,
+ SHORT_TEST_TIME_REG_BRB,
+ SHORT_TEST_STATUS_REG_BRB,
+ SHORT_TEST_RESULT_REG_BRB,
+ DRV_DRV_SELFCODE_REG_BRB,
+ SEN_SEN_SELFCODE_REG_BRB,
+ DRV_SEN_SELFCODE_REG_BRB,
+ DIFF_CODE_DATA_REG_BRB,
+ DFT_ADC_DUMP_NUM_BRB,
+ DFT_SHORT_THRESHOLD_BRB,
+ DFT_DIFFCODE_SHORT_THRESHOLD_BRB,
+};
+
+static struct ts_short_test_info params_brd = {
+ MAX_DRV_NUM_BRD,
+ MAX_SEN_NUM_BRD,
+ brl_d_drv_map,
+ brl_d_sen_map,
+ SHORT_TEST_TIME_REG_BRD,
+ SHORT_TEST_STATUS_REG_BRD,
+ SHORT_TEST_RESULT_REG_BRD,
+ DRV_DRV_SELFCODE_REG_BRD,
+ SEN_SEN_SELFCODE_REG_BRD,
+ DRV_SEN_SELFCODE_REG_BRD,
+ DIFF_CODE_DATA_REG_BRD,
+ DFT_ADC_DUMP_NUM_BRD,
+ DFT_SHORT_THRESHOLD_BRD,
+ DFT_DIFFCODE_SHORT_THRESHOLD_BRD,
+};
+
+static struct ts_short_test_info params_not = {
+ MAX_DRV_NUM_NOT,
+ MAX_SEN_NUM_NOT,
+ not_drv_map,
+ not_sen_map,
+ SHORT_TEST_TIME_REG_NOT,
+ SHORT_TEST_STATUS_REG_NOT,
+ SHORT_TEST_RESULT_REG_NOT,
+ DRV_DRV_SELFCODE_REG_NOT,
+ SEN_SEN_SELFCODE_REG_NOT,
+ DRV_SEN_SELFCODE_REG_NOT,
+ DIFF_CODE_DATA_REG_NOT,
+ 0,
+ 0,
+ 0,
+};
+
struct ts_short_res {
u8 short_num;
s16 short_msg[4 * MAX_SHORT_NUM];
@@ -210,10 +402,47 @@ struct goodix_ts_test {
struct ts_test_rawdata *deltadata;
struct ts_test_rawdata *noisedata;
struct ts_test_self_rawdata selfrawdata;
+ struct ts_short_test_info *params_info;
struct ts_short_res short_res;
};
static struct goodix_ts_test *ts_test;
+static int cal_cha_to_cha_res(int v1, int v2)
+{
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
+ return (v1 - v2) * 63 / v2;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_B)
+ return (v1 - v2) * 74 / v2 + 20;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_D)
+ return (v1 / v2 - 1) * 70 + 59;
+ else
+ return (v1 / v2 - 1) * 55 + 45;
+}
+
+static int cal_cha_to_avdd_res(int v1, int v2)
+{
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
+ return 64 * (2 * v2 - 25) * 40 / v1 - 40;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_B)
+ return 64 * (2 * v2 - 25) * 99 / v1 - 60;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_D)
+ return 64 * (2 * v2 - 25) * 93 / v1 - 20;
+ else
+ return 64 * (2 * v2 - 25) * 76 / v1 - 15;
+}
+
+static int cal_cha_to_gnd_res(int v)
+{
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
+ return 64148 / v - 40;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_B)
+ return 150500 / v - 60;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_D)
+ return 145000 / v - 15;
+ else
+ return 120000 / v - 16;
+}
+
static int malloc_test_resource(void)
{
ts_test = kzalloc(sizeof(*ts_test), GFP_KERNEL);
@@ -249,26 +478,17 @@ static void release_test_resource(void)
#define CHN_VDD 0xFF
#define CHN_GND 0x7F
#define DRV_CHANNEL_FLAG 0x80
-#define SHORT_TEST_TIME_REG_NOT 0x1479E
-#define SHORT_TEST_STATUS_REG_NOT 0x13400
-#define SHORT_TEST_RESULT_REG_NOT 0x13408
-#define DRV_DRV_SELFCODE_REG_NOT 0x13446
-#define SEN_SEN_SELFCODE_REG_NOT 0x136EE
-#define DRV_SEN_SELFCODE_REG_NOT 0x14152
-#define DIFF_CODE_DATA_REG_NOT 0x14734
-#define CAL_CHAN_TO_CHAN_RES(v1, v2) (v1 / v2 - 1) * 55 + 45
-#define CAL_CHAN_TO_AVDD_RES(v1, v2) 64 * (2 * v2 - 25) * 76 / v1 - 15
-#define CAL_CHAN_TO_GND_RES(v) 120000 / v - 16
static u32 map_die2pin(u32 chn_num)
{
int i = 0;
u32 res = 255;
if (chn_num & DRV_CHANNEL_FLAG)
- chn_num = (chn_num & ~DRV_CHANNEL_FLAG) + MAX_SEN_NUM;
+ chn_num = (chn_num & ~DRV_CHANNEL_FLAG) +
+ ts_test->params_info->max_sen_num;
- for (i = 0; i < MAX_SEN_NUM; i++) {
- if (not_sen_map[i] == chn_num) {
+ for (i = 0; i < ts_test->params_info->max_sen_num; i++) {
+ if (ts_test->params_info->sen_map[i] == chn_num) {
res = i;
break;
}
@@ -277,13 +497,13 @@ static u32 map_die2pin(u32 chn_num)
if (res != 255)
return res;
/* if cannot find in SenMap try find in DrvMap */
- for (i = 0; i < MAX_DRV_NUM; i++) {
- if (not_drv_map[i] == chn_num) {
+ for (i = 0; i < ts_test->params_info->max_drv_num; i++) {
+ if (ts_test->params_info->drv_map[i] == chn_num) {
res = i;
break;
}
}
- if (i >= MAX_DRV_NUM)
+ if (i >= ts_test->params_info->max_drv_num)
ts_err("Faild found corrresponding channel num:%d", chn_num);
else
res |= DRV_CHANNEL_FLAG;
@@ -335,9 +555,9 @@ static int gdix_check_tx_tx_shortcircut(u8 short_ch_num)
u16 adc_signal = 0;
u8 master_pin_num, slave_pin_num;
u8 *data_buf;
- u32 data_reg = DRV_DRV_SELFCODE_REG_NOT;
- int max_drv_num = MAX_DRV_NUM;
- int max_sen_num = MAX_SEN_NUM;
+ u32 data_reg = ts_test->params_info->drv_drv_selfcode_reg;
+ int max_drv_num = ts_test->params_info->max_drv_num;
+ int max_sen_num = ts_test->params_info->max_sen_num;
u16 self_capdata, short_die_num = 0;
size = 4 + max_drv_num * 2 + 2;
@@ -384,8 +604,8 @@ static int gdix_check_tx_tx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r =
- CAL_CHAN_TO_CHAN_RES(self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(
+ self_capdata, adc_signal);
if (short_r < r_threshold) {
master_pin_num = map_die2pin(
short_die_num + max_sen_num);
@@ -426,8 +646,8 @@ static int gdix_check_rx_rx_shortcircut(u8 short_ch_num)
u16 adc_signal = 0;
u8 master_pin_num, slave_pin_num;
u8 *data_buf;
- u32 data_reg = SEN_SEN_SELFCODE_REG_NOT;
- int max_sen_num = MAX_SEN_NUM;
+ u32 data_reg = ts_test->params_info->sen_sen_selfcode_reg;
+ int max_sen_num = ts_test->params_info->max_sen_num;
u16 self_capdata, short_die_num = 0;
size = 4 + max_sen_num * 2 + 2;
@@ -472,8 +692,8 @@ static int gdix_check_rx_rx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r =
- CAL_CHAN_TO_CHAN_RES(self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(
+ self_capdata, adc_signal);
if (short_r < r_threshold) {
master_pin_num = map_die2pin(short_die_num);
slave_pin_num = map_die2pin(j);
@@ -513,9 +733,9 @@ static int gdix_check_tx_rx_shortcircut(u8 short_ch_num)
u16 adc_signal = 0;
u8 master_pin_num, slave_pin_num;
u8 *data_buf = NULL;
- u32 data_reg = DRV_SEN_SELFCODE_REG_NOT;
- int max_drv_num = MAX_DRV_NUM;
- int max_sen_num = MAX_SEN_NUM;
+ u32 data_reg = ts_test->params_info->drv_sen_selfcode_reg;
+ int max_drv_num = ts_test->params_info->max_drv_num;
+ int max_sen_num = ts_test->params_info->max_sen_num;
u16 self_capdata, short_die_num = 0;
size = 4 + max_drv_num * 2 + 2;
@@ -560,8 +780,8 @@ static int gdix_check_tx_rx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r =
- CAL_CHAN_TO_CHAN_RES(self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(
+ self_capdata, adc_signal);
if (short_r < r_threshold) {
master_pin_num = map_die2pin(short_die_num);
slave_pin_num = map_die2pin(j + max_sen_num);
@@ -600,8 +820,8 @@ static int gdix_check_resistance_to_gnd(u16 adc_signal, u32 pos)
u16 chn_id_tmp = 0;
u8 pin_num = 0;
unsigned short short_type;
- int max_drv_num = MAX_DRV_NUM;
- int max_sen_num = MAX_SEN_NUM;
+ int max_drv_num = ts_test->params_info->max_drv_num;
+ int max_sen_num = ts_test->params_info->max_sen_num;
avdd_value = ts_test->avdd_value;
short_type = adc_signal & 0x8000;
@@ -611,10 +831,10 @@ static int gdix_check_resistance_to_gnd(u16 adc_signal, u32 pos)
if (short_type == 0) {
/* short to GND */
- r = CAL_CHAN_TO_GND_RES(adc_signal);
+ r = cal_cha_to_gnd_res(adc_signal);
} else {
/* short to VDD */
- r = CAL_CHAN_TO_AVDD_RES(adc_signal, avdd_value);
+ r = cal_cha_to_avdd_res(adc_signal, avdd_value);
}
if (pos < max_drv_num)
@@ -648,10 +868,10 @@ static int gdix_check_gndvdd_shortcircut(void)
int ret = 0, err = 0;
int size = 0, i = 0;
u16 adc_signal = 0;
- u32 data_reg = DIFF_CODE_DATA_REG_NOT;
+ u32 data_reg = ts_test->params_info->diffcode_data_reg;
u8 *data_buf = NULL;
- int max_drv_num = MAX_DRV_NUM;
- int max_sen_num = MAX_SEN_NUM;
+ int max_drv_num = ts_test->params_info->max_drv_num;
+ int max_sen_num = ts_test->params_info->max_sen_num;
size = (max_drv_num + max_sen_num) * 2 + 2;
data_buf = kzalloc(size, GFP_KERNEL);
@@ -688,22 +908,33 @@ err_out:
return err;
}
+#define NOTT_CHECKSUM_LEN 54
+#define BRLD_CHECKSUM_LEN 62
+#define BRLB_CHECKSUM_LEN 129
static int goodix_shortcircut_analysis(void)
{
int ret;
int err = 0;
- u8 temp_buf[62];
+ u8 temp_buf[140];
test_result_t test_result;
+ int checksum_len = 0;
- ret = cd->hw_ops->read(
- cd, SHORT_TEST_RESULT_REG_NOT, temp_buf, sizeof(temp_buf));
+ ret = cd->hw_ops->read(cd, ts_test->params_info->short_test_result_reg,
+ temp_buf, sizeof(temp_buf));
if (ret < 0) {
ts_err("Read TEST_RESULT_REG failed");
return ret;
}
- if (checksum_cmp(&temp_buf[sizeof(test_result)],
- sizeof(temp_buf) - sizeof(test_result),
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_B) {
+ checksum_len = BRLB_CHECKSUM_LEN;
+ } else if (cd->bus->ic_type == IC_TYPE_BERLIN_D) {
+ checksum_len = BRLD_CHECKSUM_LEN;
+ } else if (cd->bus->ic_type == IC_TYPE_NOTTINGHAM) {
+ checksum_len = NOTT_CHECKSUM_LEN;
+ }
+
+ if (checksum_cmp(&temp_buf[sizeof(test_result)], checksum_len,
CHECKSUM_MODE_U8_LE)) {
ts_err("short result checksum err");
return -EINVAL;
@@ -792,8 +1023,8 @@ static int goodix_shortcircut_test(void)
}
/* get short test time */
- ret = cd->hw_ops->read(
- cd, SHORT_TEST_TIME_REG_NOT, (u8 *)&test_time, 2);
+ ret = cd->hw_ops->read(cd, ts_test->params_info->short_test_time_reg,
+ (u8 *)&test_time, 2);
if (ret < 0) {
ts_err("Failed to get test_time, default %dms",
DEFAULT_TEST_TIME_MS);
@@ -815,8 +1046,9 @@ static int goodix_shortcircut_test(void)
msleep(test_time);
retry = 50;
while (retry--) {
- ret = cd->hw_ops->read(
- cd, SHORT_TEST_STATUS_REG_NOT, &status, 1);
+ ret = cd->hw_ops->read(cd,
+ ts_test->params_info->short_test_status_reg, &status,
+ 1);
if (!ret && status == SHORT_TEST_FINISH_FLAG)
break;
msleep(50);
@@ -1489,6 +1721,8 @@ static int goodix_obtain_testlimits(void)
int rx = cd->ic_info.parm.sen_num;
char limit_file[100] = { 0 };
char *temp_buf = NULL;
+ char *raw_limit_min = CSV_TP_SPECIAL_RAW_MIN;
+ char *raw_limit_max = CSV_TP_SPECIAL_RAW_MAX;
s16 data_buf[7];
int ret;
@@ -1515,16 +1749,21 @@ static int goodix_obtain_testlimits(void)
memcpy(temp_buf, firmware->data, firmware->size);
if (ts_test->item[GTP_CAP_TEST]) {
+ if (ts_test->freq > 0) {
+ raw_limit_min = CSV_TP_SPECIAL_FREQ_RAW_MIN;
+ raw_limit_max = CSV_IP_SPECIAL_FREQ_RAW_MAX;
+ }
+
/* obtain mutual_raw min */
- ret = parse_csvfile(temp_buf, firmware->size,
- CSV_TP_SPECIAL_RAW_MIN, ts_test->min_limits, rx, tx);
+ ret = parse_csvfile(temp_buf, firmware->size, raw_limit_min,
+ ts_test->min_limits, rx, tx);
if (ret < 0) {
ts_err("Failed get min_limits");
goto exit_free;
}
/* obtain mutual_raw max */
- ret = parse_csvfile(temp_buf, firmware->size,
- CSV_TP_SPECIAL_RAW_MAX, ts_test->max_limits, rx, tx);
+ ret = parse_csvfile(temp_buf, firmware->size, raw_limit_max,
+ ts_test->max_limits, rx, tx);
if (ret < 0) {
ts_err("Failed get max_limits");
goto exit_free;
@@ -1583,6 +1822,13 @@ static int goodix_obtain_testlimits(void)
ts_test->r_drv_gnd_threshold = data_buf[4];
ts_test->r_sen_gnd_threshold = data_buf[5];
ts_test->avdd_value = data_buf[6];
+
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_B)
+ ts_test->params_info = &params_brb;
+ else if (cd->bus->ic_type == IC_TYPE_BERLIN_D)
+ ts_test->params_info = &params_brd;
+ else if (cd->bus->ic_type == IC_TYPE_NOTTINGHAM)
+ ts_test->params_info = &params_not;
}
exit_free:
@@ -1955,13 +2201,17 @@ static void goodix_auto_noise_test(u16 cnt, int threshold)
u32 raw_addr;
int tx = cd->ic_info.parm.drv_num;
int rx = cd->ic_info.parm.sen_num;
- s16 tmp_buf[MAX_DRV_NUM * MAX_SEN_NUM];
+ s16 *tmp_buf;
int tmp_val;
u8 status;
int retry = 10;
int err_cnt = 0;
int i;
+ tmp_buf = kcalloc(MAX_DRV_NUM * MAX_SEN_NUM, 2, GFP_KERNEL);
+ if (tmp_buf == NULL)
+ return;
+
raw_addr = cd->ic_info.misc.frame_data_addr +
cd->ic_info.misc.frame_data_head_len +
cd->ic_info.misc.fw_attr_len + cd->ic_info.misc.fw_log_len +
@@ -2033,6 +2283,7 @@ static void goodix_auto_noise_test(u16 cnt, int threshold)
index += sprintf(&rbuf[index], "Result: PASS\n");
exit:
+ kfree(tmp_buf);
cd->hw_ops->reset(cd, 100);
cd->hw_ops->irq_enable(cd, true);
goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
@@ -2600,6 +2851,103 @@ static void goodix_set_heatmap(int val)
cd->hw_ops->irq_enable(cd, true);
}
+static void goodix_get_self_compensation(void)
+{
+ u8 *cfg;
+ int len;
+ int cfg_num;
+ int sub_cfg_index;
+ int sub_cfg_len;
+ int tx = cd->ic_info.parm.drv_num;
+ int rx = cd->ic_info.parm.sen_num;
+ s16 val;
+ int i, j;
+
+ cfg = kzalloc(GOODIX_CFG_MAX_SIZE, GFP_KERNEL);
+ if (cfg == NULL)
+ return;
+
+ len = cd->hw_ops->read_config(cd, cfg, GOODIX_CFG_MAX_SIZE);
+ if (len < 0) {
+ ts_err("read config failed");
+ return;
+ }
+
+ cfg_num = cfg[61];
+ cfg += 64;
+ for (i = 0; i < cfg_num; i++) {
+ sub_cfg_len = cfg[0] - 2;
+ sub_cfg_index = cfg[1];
+ if (sub_cfg_index == 13) { // TX self cancel
+ ts_info("sub_cfg_len:%d", sub_cfg_len);
+ index += sprintf(&rbuf[index], "Tx:");
+ for (j = 0; j < tx; j++) {
+ val = le16_to_cpup((__le16 *)&cfg[2 + j * 4]) +
+ le16_to_cpup((__le16 *)&cfg[4 + j * 4]);
+ index += sprintf(&rbuf[index], "%d,", val);
+ }
+ index += sprintf(&rbuf[index], "\n");
+ } else if (sub_cfg_index == 14) { // RX self cancel
+ ts_info("sub_cfg_len:%d", sub_cfg_len);
+ index += sprintf(&rbuf[index], "Rx:");
+ for (j = 0; j < rx; j++) {
+ val = le16_to_cpup((__le16 *)&cfg[2 + j * 2]);
+ index += sprintf(&rbuf[index], "%d,", val);
+ }
+ index += sprintf(&rbuf[index], "\n");
+ }
+ cfg += (sub_cfg_len + 2);
+ }
+}
+
+static void goodix_set_report_rate(int rate)
+{
+ struct goodix_ts_cmd temp_cmd;
+
+ index = sprintf(rbuf, "set report rate %d\n", rate);
+ ts_info("set report rate %d", rate);
+ temp_cmd.len = 5;
+ temp_cmd.cmd = 0x9D;
+ temp_cmd.data[0] = rate;
+ cd->hw_ops->send_cmd(cd, &temp_cmd);
+}
+
+#define DUMP_AREA1_ADDR 0x10194
+#define DUMP_AREA1_LEN 132
+#define DUMP_AREA2_ADDR 0x10400
+#define DUMP_AREA2_LEN 596
+#define DUMP_AREA3_ADDR 0x10308
+#define DUMP_AREA3_LEN 64
+static void goodix_get_dump_log(void)
+{
+ u8 buf[600];
+ int i;
+
+ cd->hw_ops->read(cd, DUMP_AREA1_ADDR, buf, DUMP_AREA1_LEN);
+ index += sprintf(&rbuf[index], "0x%04x:\n", DUMP_AREA1_ADDR);
+ for (i = 0; i < DUMP_AREA1_LEN; i++) {
+ index += sprintf(&rbuf[index], "%02x,", buf[i]);
+ if ((i + 1) % 32 == 0)
+ index += sprintf(&rbuf[index], "\n");
+ }
+
+ cd->hw_ops->read(cd, DUMP_AREA2_ADDR, buf, DUMP_AREA2_LEN);
+ index += sprintf(&rbuf[index], "\n0x%04x:\n", DUMP_AREA2_ADDR);
+ for (i = 0; i < DUMP_AREA2_LEN; i++) {
+ index += sprintf(&rbuf[index], "%02x,", buf[i]);
+ if ((i + 1) % 32 == 0)
+ index += sprintf(&rbuf[index], "\n");
+ }
+
+ cd->hw_ops->read(cd, DUMP_AREA3_ADDR, buf, DUMP_AREA3_LEN);
+ index += sprintf(&rbuf[index], "\n0x%04x:\n", DUMP_AREA3_ADDR);
+ for (i = 0; i < DUMP_AREA3_LEN; i++) {
+ index += sprintf(&rbuf[index], "%02x,", buf[i]);
+ if ((i + 1) % 32 == 0)
+ index += sprintf(&rbuf[index], "\n");
+ }
+}
+
static ssize_t driver_test_write(
struct file *file, const char __user *buf, size_t count, loff_t *pos)
{
@@ -3280,6 +3628,35 @@ static ssize_t driver_test_write(
goto exit;
}
+ if (!strncmp(p, CMD_GET_SELF_COMPEN, strlen(CMD_GET_SELF_COMPEN))) {
+ rbuf = kzalloc(LARGE_SIZE, GFP_KERNEL);
+ goodix_get_self_compensation();
+ goto exit;
+ }
+
+ if (!strncmp(p, CMD_SET_REPORT_RATE, strlen(CMD_SET_REPORT_RATE))) {
+ rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL);
+ token = strsep(&p, ",");
+ if (!token || !p) {
+ index = sprintf(rbuf, "%s: invalid cmd param\n",
+ CMD_SET_REPORT_RATE);
+ goto exit;
+ }
+ if (kstrtos32(p, 10, &cmd_val)) {
+ index = sprintf(rbuf, "%s: invalid cmd param\n",
+ CMD_SET_REPORT_RATE);
+ goto exit;
+ }
+ goodix_set_report_rate(cmd_val);
+ goto exit;
+ }
+
+ if (!strncmp(p, CMD_GET_DUMP_LOG, strlen(CMD_GET_DUMP_LOG))) {
+ rbuf = kzalloc(LARGE_SIZE, GFP_KERNEL);
+ goodix_get_dump_log();
+ goto exit;
+ }
+
rbuf = kzalloc(SHORT_SIZE, GFP_KERNEL);
index = sprintf(rbuf, "not support cmd %s\n", p);
ts_err("not support cmd[%s]", p);