Loading Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt +3 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ Optional properties: min y, max x and max y values. - goodix,i2c-pull-up : To specify pull up is required. - goodix,no-force-update : To specify force update is allowed. - goodix,enable-power-off : Power off touchscreen during suspend. - goodix,button-map : Button map of key codes. The number of key codes depend on panel. - goodix,cfg-data0 : Touch screen controller config data group 0. Ask vendor Loading @@ -55,6 +56,7 @@ Optional properties: to provide that. - goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor to provide that. - goodix,fw-name : Touch screen controller firmware file name. Example: i2c@f9927000 { goodix@5d { Loading Loading @@ -89,5 +91,6 @@ i2c@f9927000 { 20 21 22 24 26 28 29 2A FF FF FF FF FF FF FF FF FF 22 22 22 22 22 22 FF 07 01]; goodix,fw_name = "gtp_fw.bin"; }; }; drivers/input/touchscreen/gt9xx/goodix_tool.c +41 −57 Original line number Diff line number Diff line Loading @@ -85,7 +85,6 @@ static void tool_set_proc_name(char *procname) } snprintf(procname, 20, "gmnode%04d%02d%02d", n_year, n_month, n_day); /* GTP_DEBUG("procname = %s", procname); */ } static s32 tool_i2c_read_no_extra(u8 *buf, u16 len) Loading Loading @@ -180,11 +179,11 @@ static void register_i2c_func(void) && strcmp(IC_TYPE, "GTxxx")) { tool_i2c_read = tool_i2c_read_with_extra; tool_i2c_write = tool_i2c_write_with_extra; GTP_DEBUG("I2C function: with pre and end cmd!"); pr_debug("I2C function: with pre and end cmd!\n"); } else { tool_i2c_read = tool_i2c_read_no_extra; tool_i2c_write = tool_i2c_write_no_extra; GTP_INFO("I2C function: without pre and end cmd!"); pr_info("I2C function: without pre and end cmd!\n"); } } Loading @@ -192,7 +191,7 @@ static void unregister_i2c_func(void) { tool_i2c_read = NULL; tool_i2c_write = NULL; GTP_INFO("I2C function: unregister i2c transfer function!"); pr_info("I2C function: unregister i2c transfer function!\n"); } s32 init_wr_node(struct i2c_client *client) Loading @@ -215,7 +214,7 @@ s32 init_wr_node(struct i2c_client *client) DATA_LENGTH = i * DATA_LENGTH_UINT; dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH); } else { GTP_ERROR("Apply for memory failed."); pr_err("Apply for memory failed.\n"); return FAIL; } Loading @@ -228,7 +227,7 @@ s32 init_wr_node(struct i2c_client *client) tool_set_proc_name(procname); goodix_proc_entry = create_proc_entry(procname, 0660, NULL); if (goodix_proc_entry == NULL) { GTP_ERROR("Couldn't create proc entry!"); pr_err("Couldn't create proc entry!\n"); return FAIL; } GTP_INFO("Create proc entry success!"); Loading Loading @@ -257,7 +256,7 @@ static u8 relation(u8 src, u8 dst, u8 rlt) case 1: ret = (src == dst) ? true : false; GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", pr_debug("equal:src:0x%02x dst:0x%02x ret:%d.\n", src, dst, (s32)ret); break; Loading Loading @@ -308,14 +307,14 @@ static u8 comfirm(void) for (i = 0; i < cmd_head.times; i++) { if (tool_i2c_read(buf, 1) <= 0) { GTP_ERROR("Read flag data failed!"); pr_err("Read flag data failed!\n"); return FAIL; } if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, cmd_head.flag_relation)) { GTP_DEBUG("value at flag addr:0x%02x.", pr_debug("value at flag addr:0x%02x.\n", buf[GTP_ADDR_LENGTH]); GTP_DEBUG("flag value:0x%02x.", cmd_head.flag_val); pr_debug("flag value:0x%02x.\n", cmd_head.flag_val); break; } Loading @@ -323,7 +322,7 @@ static u8 comfirm(void) } if (i >= cmd_head.times) { GTP_ERROR("Didn't get the flag to continue!"); pr_debug("Didn't get the flag to continue!\n"); return FAIL; } Loading @@ -344,41 +343,38 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, { s32 ret = 0; GTP_DEBUG_FUNC(); GTP_DEBUG_ARRAY((u8 *)buff, len); mutex_lock(&lock); ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); if (ret) { GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); ret = -EACCES; goto exit; } GTP_DEBUG("wr :0x%02x.", cmd_head.wr); GTP_DEBUG("flag:0x%02x.", cmd_head.flag); GTP_DEBUG("flag addr:0x%02x%02x.", cmd_head.flag_addr[0], pr_debug("wr :0x%02x.\n", cmd_head.wr); pr_debug("flag:0x%02x.\n", cmd_head.flag); pr_debug("flag addr:0x%02x%02x.\n", cmd_head.flag_addr[0], cmd_head.flag_addr[1]); GTP_DEBUG("flag val:0x%02x.", cmd_head.flag_val); GTP_DEBUG("flag rel:0x%02x.", cmd_head.flag_relation); GTP_DEBUG("circle :%d.", (s32)cmd_head.circle); GTP_DEBUG("times :%d.", (s32)cmd_head.times); GTP_DEBUG("retry :%d.", (s32)cmd_head.retry); GTP_DEBUG("delay :%d.", (s32)cmd_head.delay); GTP_DEBUG("data len:%d.", (s32)cmd_head.data_len); GTP_DEBUG("addr len:%d.", (s32)cmd_head.addr_len); GTP_DEBUG("addr:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]); GTP_DEBUG("len:%d.", (s32)len); GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]); pr_debug("flag val:0x%02x.\n", cmd_head.flag_val); pr_debug("flag rel:0x%02x.\n", cmd_head.flag_relation); pr_debug("circle :%d.\n", (s32)cmd_head.circle); pr_debug("times :%d.\n", (s32)cmd_head.times); pr_debug("retry :%d.\n", (s32)cmd_head.retry); pr_debug("delay :%d.\n", (s32)cmd_head.delay); pr_debug("data len:%d.\n", (s32)cmd_head.data_len); pr_debug("addr len:%d.\n", (s32)cmd_head.addr_len); pr_debug("addr:0x%02x%02x.\n", cmd_head.addr[0], cmd_head.addr[1]); pr_debug("len:%d.\n", (s32)len); pr_debug("buf[20]:0x%02x.\n", buff[CMD_HEAD_LENGTH]); if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) { pr_err("data len %d > data buff %d, rejected!\n", pr_debug("data len %d > data buff %d, rejected!\n", cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH)); ret = -EINVAL; goto exit; } if (cmd_head.addr_len > GTP_ADDR_LENGTH) { pr_err(" addr len %d > data buff %d, rejected!\n", pr_debug(" addr len %d > data buff %d, rejected!\n", cmd_head.addr_len, GTP_ADDR_LENGTH); ret = -EINVAL; goto exit; Loading @@ -391,19 +387,14 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.addr, cmd_head.addr_len); GTP_DEBUG_ARRAY(cmd_head.data, cmd_head.data_len + cmd_head.addr_len); GTP_DEBUG_ARRAY((u8 *)&buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[WRITE]Comfirm fail!"); pr_err("[WRITE]Comfirm fail!\n"); ret = -EINVAL; goto exit; } Loading @@ -413,14 +404,11 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, if (tool_i2c_write( &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len) <= 0) { GTP_ERROR("[WRITE]Write data failed!"); pr_err("[WRITE]Write data failed!\n"); ret = -EIO; goto exit; } GTP_DEBUG_ARRAY( &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len); if (cmd_head.delay) msleep(cmd_head.delay); Loading @@ -431,10 +419,10 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); if (cmd_head.data_len > sizeof(IC_TYPE)) { pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n", pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", cmd_head.data_len, sizeof(IC_TYPE)); ret = -EINVAL; goto exit; Loading Loading @@ -473,13 +461,13 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_DEBUG("copy_from_user failed."); pr_debug("copy_from_user failed.\n"); if (cmd_head.data[GTP_ADDR_LENGTH]) { GTP_DEBUG("gtp enter rawdiff."); pr_debug("gtp enter rawdiff.\n"); ts->gtp_rawdiff_mode = true; } else { ts->gtp_rawdiff_mode = false; GTP_DEBUG("gtp leave rawdiff."); pr_debug("gtp leave rawdiff.\n"); } ret = CMD_HEAD_LENGTH; goto exit; Loading @@ -495,7 +483,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, show_len = 0; total_len = 0; if (cmd_head.data_len + 1 > DATA_LENGTH) { pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n", pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", cmd_head.data_len + 1, DATA_LENGTH); ret = -EINVAL; goto exit; Loading Loading @@ -530,7 +518,6 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, int *eof, void *data) { s32 ret; GTP_DEBUG_FUNC(); mutex_lock(&lock); if (cmd_head.wr % 2) { Loading @@ -544,7 +531,7 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[READ]Comfirm fail!"); pr_err("[READ]Comfirm fail!\n"); ret = -EINVAL; goto exit; } Loading @@ -554,9 +541,9 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len); GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0], pr_debug("[CMD HEAD DATA] ADDR:0x%02x%02x.\n", cmd_head.data[0], cmd_head.data[1]); GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0], pr_debug("[CMD HEAD ADDR] ADDR:0x%02x%02x.\n", cmd_head.addr[0], cmd_head.addr[1]); if (cmd_head.delay) Loading @@ -572,16 +559,13 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, data_len -= len; if (tool_i2c_read(cmd_head.data, len) <= 0) { GTP_ERROR("[READ]Read data failed!"); pr_err("[READ]Read data failed!\n"); ret = -EINVAL; goto exit; } memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len); loc += len; GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH], len); GTP_DEBUG_ARRAY(page, len); } } else if (cmd_head.wr == 2) { /* memcpy(page, "gt8", cmd_head.data_len); Loading @@ -589,7 +573,7 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, * page[5] = 0; */ GTP_DEBUG("Return ic type:%s len:%d.", page, pr_debug("Return ic type:%s len:%d.\n", page, (s32)cmd_head.data_len); ret = cmd_head.data_len; goto exit; Loading drivers/input/touchscreen/gt9xx/gt9xx.c +165 −55 Original line number Diff line number Diff line Loading @@ -77,19 +77,13 @@ #if GTP_HAVE_TOUCH_KEY static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK}; #if GTP_DEBUG_ON static const int key_codes[] = { KEY_HOME, KEY_BACK, KEY_MENU, KEY_SEARCH }; static const char *const key_names[] = { "Key_Home", "Key_Back", "Key_Menu", "Key_Search" }; #endif #endif static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms); static void gtp_int_sync(struct goodix_ts_data *ts, int ms); static int gtp_i2c_test(struct i2c_client *client); static int goodix_power_off(struct goodix_ts_data *ts); static int goodix_power_on(struct goodix_ts_data *ts); #if defined(CONFIG_FB) static int fb_notifier_callback(struct notifier_block *self, Loading Loading @@ -493,30 +487,19 @@ static void goodix_ts_work_func(struct work_struct *work) memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); } #if GTP_HAVE_TOUCH_KEY key_value = point_data[3 + 8 * touch_num]; if (key_value || pre_key) { for (i = 0; i < ARRAY_SIZE(touch_key_array); i++) { #if GTP_DEBUG_ON for (ret = 0; ret < 4; ++ret) { if (key_codes[ret] == touch_key_array[i]) { GTP_DEBUG("Key: %s %s", key_names[ret], (key_value & (0x01 << i)) ? "Down" : "Up"); break; } } #endif for (i = 0; i < ts->pdata->num_button; i++) { input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); ts->pdata->button_map[i], key_value & (0x01<<i)); } touch_num = 0; pre_touch = 0; } #endif pre_key = key_value; #if GTP_WITH_PEN Loading Loading @@ -754,7 +737,7 @@ Input: ts: private data. Output: Executive outcomes. 1: succeed, otherwise failed. >0: succeed, otherwise failed. *******************************************************/ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) { Loading @@ -765,12 +748,28 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) (u8)GTP_REG_SLEEP, 5}; ret = gpio_direction_output(ts->pdata->irq_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP sleep: Cannot reconfig gpio %d.\n", ts->pdata->irq_gpio); if (ts->pdata->enable_power_off) { ret = gpio_direction_output(ts->pdata->reset_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP sleep: Cannot reconfig gpio %d.\n", ts->pdata->reset_gpio); ret = goodix_power_off(ts); if (ret) { dev_err(&ts->client->dev, "GTP power off failed.\n"); return 0; } return 1; } usleep(5000); while (retry++ < GTP_I2C_RETRY_5) { ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); if (ret > 0) { dev_dbg(&ts->client->dev, "GTP enter sleep!"); if (ret == 1) { dev_dbg(&ts->client->dev, "GTP enter sleep!"); return ret; } msleep(20); Loading @@ -778,7 +777,7 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) dev_err(&ts->client->dev, "GTP send sleep cmd failed.\n"); return ret; } #endif #endif /* !GTP_SLIDE_WAKEUP */ /******************************************************* Function: Loading @@ -794,17 +793,36 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) u8 retry = 0; s8 ret = -1; #if GTP_POWER_CTRL_SLEEP if (ts->pdata->enable_power_off) { ret = gpio_direction_output(ts->pdata->irq_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP wakeup: Cannot reconfig gpio %d.\n", ts->pdata->irq_gpio); ret = gpio_direction_output(ts->pdata->reset_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP wakeup: Cannot reconfig gpio %d.\n", ts->pdata->reset_gpio); ret = goodix_power_on(ts); if (ret) { dev_err(&ts->client->dev, "GTP power on failed.\n"); return 0; } gtp_reset_guitar(ts, 20); ret = gtp_send_cfg(ts); if (ret > 0) { if (ret <= 0) { dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n"); return ret; } dev_dbg(&ts->client->dev, "Wakeup sleep send config success."); return 1; } #else while (retry++ < GTP_I2C_RETRY_10) { } else { err_retry: #if GTP_SLIDE_WAKEUP /* wakeup not by slide */ if (doze_status != DOZE_WAKEUP) Loading @@ -821,7 +839,7 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) } #endif ret = gtp_i2c_test(ts->client); if (ret > 0) { if (ret == 2) { dev_dbg(&ts->client->dev, "GTP wakeup sleep."); #if (!GTP_SLIDE_WAKEUP) if (chip_gt9xxs == 0) { Loading @@ -835,10 +853,10 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) return ret; } gtp_reset_guitar(ts, 20); } #endif if (retry++ < GTP_I2C_RETRY_10) goto err_retry; dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n"); } return ret; } #endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/ Loading Loading @@ -1051,9 +1069,7 @@ static int gtp_check_product_id(struct i2c_client *client) dev_info(&client->dev, "Goodix Product ID = %s\n", product_id); if (!IS_ERR(ts->pdata->product_id)) ret = strcmp(product_id, ts->pdata->product_id); if (ret != 0) return -EINVAL; Loading Loading @@ -1232,12 +1248,11 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts) /* in case of "out of memory" */ input_mt_init_slots(ts->input_dev, 10, 0); #if GTP_HAVE_TOUCH_KEY for (index = 0; index < ARRAY_SIZE(touch_key_array); index++) { for (index = 0; index < ts->pdata->num_button; index++) { input_set_capability(ts->input_dev, EV_KEY, touch_key_array[index]); EV_KEY, ts->pdata->button_map[index]); } #endif #if GTP_SLIDE_WAKEUP input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); Loading Loading @@ -1305,6 +1320,12 @@ static int goodix_power_on(struct goodix_ts_data *ts) { int ret; if (ts->power_on) { dev_info(&ts->client->dev, "Device already power on\n"); return 0; } if (!IS_ERR(ts->avdd)) { ret = reg_set_optimum_mode_check(ts->avdd, GOODIX_VDD_LOAD_MAX_UA); Loading Loading @@ -1371,6 +1392,7 @@ static int goodix_power_on(struct goodix_ts_data *ts) } } ts->power_on = true; return 0; err_enable_vcc_i2c: Loading @@ -1389,6 +1411,7 @@ err_set_vtg_vdd: regulator_disable(ts->avdd); err_enable_avdd: err_set_opt_avdd: ts->power_on = false; return ret; } Loading @@ -1402,6 +1425,12 @@ static int goodix_power_off(struct goodix_ts_data *ts) { int ret; if (!ts->power_on) { dev_info(&ts->client->dev, "Device already power off\n"); return 0; } if (!IS_ERR(ts->vcc_i2c)) { ret = regulator_set_voltage(ts->vcc_i2c, 0, GOODIX_I2C_VTG_MAX_UV); Loading Loading @@ -1434,6 +1463,7 @@ static int goodix_power_off(struct goodix_ts_data *ts) "Regulator avdd disable failed ret=%d\n", ret); } ts->power_on = false; return 0; } Loading Loading @@ -1486,6 +1516,50 @@ static int goodix_power_deinit(struct goodix_ts_data *ts) return 0; } static ssize_t gtp_fw_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct goodix_ts_data *ts = dev_get_drvdata(dev); if (!strlen(ts->fw_name)) return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1, "No fw name has been given."); else return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1, "%s\n", ts->fw_name); } static ssize_t gtp_fw_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct goodix_ts_data *ts = dev_get_drvdata(dev); if (size > GTP_FW_NAME_MAXSIZE - 1) { dev_err(dev, "FW name size exceeds the limit."); return -EINVAL; } strlcpy(ts->fw_name, buf, size); if (ts->fw_name[size-1] == '\n') ts->fw_name[size-1] = '\0'; return size; } static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP), gtp_fw_name_show, gtp_fw_name_store); static struct attribute *gtp_attrs[] = { &dev_attr_fw_name.attr, NULL }; static const struct attribute_group gtp_attr_grp = { .attrs = gtp_attrs, }; static int goodix_ts_get_dt_coords(struct device *dev, char *name, struct goodix_ts_platform_data *pdata) { Loading Loading @@ -1549,6 +1623,9 @@ static int goodix_parse_dt(struct device *dev, pdata->no_force_update = of_property_read_bool(np, "goodix,no-force-update"); pdata->enable_power_off = of_property_read_bool(np, "goodix,enable-power-off"); /* reset, irq gpio info */ pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &pdata->reset_gpio_flags); Loading @@ -1562,8 +1639,17 @@ static int goodix_parse_dt(struct device *dev, rc = of_property_read_string(np, "goodix,product-id", &pdata->product_id); if (rc < 0 || strlen(pdata->product_id) > GTP_PRODUCT_ID_MAXSIZE) return rc; if (rc && (rc != -EINVAL)) { dev_err(dev, "Failed to parse product_id."); return -EINVAL; } rc = of_property_read_string(np, "goodix,fw_name", &pdata->fw_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Failed to parse firmware name.\n"); return -EINVAL; } prop = of_find_property(np, "goodix,button-map", NULL); if (prop) { Loading @@ -1578,6 +1664,9 @@ static int goodix_parse_dt(struct device *dev, dev_err(dev, "Unable to read key codes\n"); return rc; } pdata->num_button = num_buttons; memcpy(pdata->button_map, button_map, pdata->num_button * sizeof(u32)); } read_cfg_num = 0; Loading Loading @@ -1670,6 +1759,7 @@ static int goodix_ts_probe(struct i2c_client *client, spin_lock_init(&ts->irq_lock); i2c_set_clientdata(client, ts); ts->gtp_rawdiff_mode = 0; ts->power_on = false; ret = gtp_request_io_port(ts); if (ret) { Loading Loading @@ -1697,12 +1787,16 @@ static int goodix_ts_probe(struct i2c_client *client, goto exit_power_off; } if (pdata->fw_name) strlcpy(ts->fw_name, pdata->fw_name, strlen(pdata->fw_name) + 1); #if GTP_AUTO_UPDATE ret = gup_init_update_proc(ts); if (ret < 0) { dev_err(&client->dev, "GTP Create firmware update thread error.\n"); goto exit_free_io_port; goto exit_power_off; } #endif Loading @@ -1719,7 +1813,9 @@ static int goodix_ts_probe(struct i2c_client *client, dev_err(&client->dev, "GTP request input dev failed.\n"); goto exit_free_inputdev; } input_set_drvdata(ts->input_dev, ts); mutex_init(&ts->lock); #if defined(CONFIG_FB) ts->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&ts->fb_notif); Loading Loading @@ -1762,9 +1858,16 @@ static int goodix_ts_probe(struct i2c_client *client, #if GTP_ESD_PROTECT gtp_esd_switch(client, SWITCH_ON); #endif ret = sysfs_create_group(&client->dev.kobj, >p_attr_grp); if (ret < 0) { dev_err(&client->dev, "sys file creation failed.\n"); goto exit_free_irq; } init_done = true; return 0; exit_free_irq: mutex_destroy(&ts->lock); #if defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) dev_err(&client->dev, Loading Loading @@ -1813,6 +1916,8 @@ static int goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); sysfs_remove_group(&ts->input_dev->dev.kobj, >p_attr_grp); #if defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) dev_err(&client->dev, Loading @@ -1820,6 +1925,7 @@ static int goodix_ts_remove(struct i2c_client *client) #elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif mutex_destroy(&ts->lock); #if GTP_CREATE_WR_NODE uninit_wr_node(); Loading Loading @@ -1873,6 +1979,7 @@ static void goodix_ts_suspend(struct goodix_ts_data *ts) { int ret = -1, i; mutex_lock(&ts->lock); #if GTP_ESD_PROTECT ts->gtp_is_suspend = 1; gtp_esd_switch(ts->client, SWITCH_OFF); Loading @@ -1893,12 +2000,13 @@ static void goodix_ts_suspend(struct goodix_ts_data *ts) ret = gtp_enter_sleep(ts); #endif if (ret < 0) if (ret <= 0) dev_err(&ts->client->dev, "GTP early suspend failed.\n"); /* to avoid waking up while not sleeping, * delay 48 + 10ms to ensure reliability */ msleep(58); mutex_unlock(&ts->lock); } /******************************************************* Loading @@ -1913,13 +2021,14 @@ static void goodix_ts_resume(struct goodix_ts_data *ts) { int ret = -1; mutex_lock(&ts->lock); ret = gtp_wakeup_sleep(ts); #if GTP_SLIDE_WAKEUP doze_status = DOZE_DISABLED; #endif if (ret < 0) if (ret <= 0) dev_err(&ts->client->dev, "GTP resume failed.\n"); if (ts->use_irq) Loading @@ -1932,6 +2041,7 @@ static void goodix_ts_resume(struct goodix_ts_data *ts) ts->gtp_is_suspend = 0; gtp_esd_switch(ts->client, SWITCH_ON); #endif mutex_unlock(&ts->lock); } #if defined(CONFIG_FB) Loading Loading @@ -2177,7 +2287,7 @@ static void __exit goodix_ts_exit(void) i2c_del_driver(&goodix_ts_driver); } late_initcall(goodix_ts_init); module_init(goodix_ts_init); module_exit(goodix_ts_exit); MODULE_DESCRIPTION("GTP Series Driver"); Loading drivers/input/touchscreen/gt9xx/gt9xx.h +12 −38 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/regulator/consumer.h> #include <linux/firmware.h> #include <linux/debugfs.h> #include <linux/mutex.h> #if defined(CONFIG_FB) #include <linux/notifier.h> Loading @@ -42,13 +43,17 @@ #define GOODIX_SUSPEND_LEVEL 1 #endif #define MAX_BUTTONS 4 #define GOODIX_MAX_CFG_GROUP 6 #define GTP_FW_NAME_MAXSIZE 50 struct goodix_ts_platform_data { int irq_gpio; u32 irq_gpio_flags; int reset_gpio; u32 reset_gpio_flags; const char *product_id; const char *fw_name; u32 x_max; u32 y_max; u32 x_min; Loading @@ -59,8 +64,11 @@ struct goodix_ts_platform_data { u32 panel_maxy; bool no_force_update; bool i2c_pull_up; bool enable_power_off; size_t config_data_len[GOODIX_MAX_CFG_GROUP]; u8 *config_data[GOODIX_MAX_CFG_GROUP]; u32 button_map[MAX_BUTTONS]; u8 num_button; }; struct goodix_ts_data { spinlock_t irq_lock; Loading @@ -70,6 +78,7 @@ struct goodix_ts_data { struct hrtimer timer; struct workqueue_struct *goodix_wq; struct work_struct work; struct delayed_work goodix_update_work; s32 irq_is_disabled; s32 use_irq; u16 abs_x_max; Loading @@ -86,6 +95,8 @@ struct goodix_ts_data { u8 fixed_cfg; u8 esd_running; u8 fw_error; bool power_on; struct mutex lock; struct regulator *avdd; struct regulator *vdd; struct regulator *vcc_i2c; Loading @@ -104,7 +115,6 @@ extern u16 total_len; #define GTP_CHANGE_X2Y 0 #define GTP_DRIVER_SEND_CFG 1 #define GTP_HAVE_TOUCH_KEY 1 #define GTP_POWER_CTRL_SLEEP 0 /* auto updated by .bin file as default */ #define GTP_AUTO_UPDATE 0 Loading @@ -117,14 +127,11 @@ extern u16 total_len; #define GTP_ESD_PROTECT 0 #define GTP_WITH_PEN 0 /* This cannot work when enable-power-off is on */ #define GTP_SLIDE_WAKEUP 0 /* double-click wakeup, function together with GTP_SLIDE_WAKEUP */ #define GTP_DBL_CLK_WAKEUP 0 #define GTP_DEBUG_ON 0 #define GTP_DEBUG_ARRAY_ON 0 #define GTP_DEBUG_FUNC_ON 0 /*************************** PART2:TODO define *******************************/ /* STEP_1(REQUIRED): Define Configuration Information Group(s) */ /* Sensor_ID Map: */ Loading Loading @@ -190,39 +197,6 @@ extern u16 total_len; #define RESOLUTION_LOC 3 #define TRIGGER_LOC 8 /* Log define */ #define GTP_DEBUG(fmt, arg...) do {\ if (GTP_DEBUG_ON) {\ pr_debug("<<-GTP-DEBUG->> [%d]"fmt"\n",\ __LINE__, ##arg); } \ } while (0) #define GTP_DEBUG_ARRAY(array, num) do {\ s32 i; \ u8 *a = array; \ if (GTP_DEBUG_ARRAY_ON) {\ pr_debug("<<-GTP-DEBUG-ARRAY->>\n");\ for (i = 0; i < (num); i++) { \ pr_debug("%02x ", (a)[i]);\ if ((i + 1) % 10 == 0) { \ pr_debug("\n");\ } \ } \ pr_debug("\n");\ } \ } while (0) #define GTP_DEBUG_FUNC() do {\ if (GTP_DEBUG_FUNC_ON)\ pr_debug("<<-GTP-FUNC->> Func:%s@Line:%d\n",\ __func__, __LINE__);\ } while (0) #define GTP_SWAP(x, y) do {\ typeof(x) z = x;\ x = y;\ y = z;\ } while (0) /*****************************End of Part III********************************/ void gtp_esd_switch(struct i2c_client *client, int on); Loading drivers/input/touchscreen/gt9xx/gt9xx_update.c +228 −264 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt +3 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ Optional properties: min y, max x and max y values. - goodix,i2c-pull-up : To specify pull up is required. - goodix,no-force-update : To specify force update is allowed. - goodix,enable-power-off : Power off touchscreen during suspend. - goodix,button-map : Button map of key codes. The number of key codes depend on panel. - goodix,cfg-data0 : Touch screen controller config data group 0. Ask vendor Loading @@ -55,6 +56,7 @@ Optional properties: to provide that. - goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor to provide that. - goodix,fw-name : Touch screen controller firmware file name. Example: i2c@f9927000 { goodix@5d { Loading Loading @@ -89,5 +91,6 @@ i2c@f9927000 { 20 21 22 24 26 28 29 2A FF FF FF FF FF FF FF FF FF 22 22 22 22 22 22 FF 07 01]; goodix,fw_name = "gtp_fw.bin"; }; };
drivers/input/touchscreen/gt9xx/goodix_tool.c +41 −57 Original line number Diff line number Diff line Loading @@ -85,7 +85,6 @@ static void tool_set_proc_name(char *procname) } snprintf(procname, 20, "gmnode%04d%02d%02d", n_year, n_month, n_day); /* GTP_DEBUG("procname = %s", procname); */ } static s32 tool_i2c_read_no_extra(u8 *buf, u16 len) Loading Loading @@ -180,11 +179,11 @@ static void register_i2c_func(void) && strcmp(IC_TYPE, "GTxxx")) { tool_i2c_read = tool_i2c_read_with_extra; tool_i2c_write = tool_i2c_write_with_extra; GTP_DEBUG("I2C function: with pre and end cmd!"); pr_debug("I2C function: with pre and end cmd!\n"); } else { tool_i2c_read = tool_i2c_read_no_extra; tool_i2c_write = tool_i2c_write_no_extra; GTP_INFO("I2C function: without pre and end cmd!"); pr_info("I2C function: without pre and end cmd!\n"); } } Loading @@ -192,7 +191,7 @@ static void unregister_i2c_func(void) { tool_i2c_read = NULL; tool_i2c_write = NULL; GTP_INFO("I2C function: unregister i2c transfer function!"); pr_info("I2C function: unregister i2c transfer function!\n"); } s32 init_wr_node(struct i2c_client *client) Loading @@ -215,7 +214,7 @@ s32 init_wr_node(struct i2c_client *client) DATA_LENGTH = i * DATA_LENGTH_UINT; dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH); } else { GTP_ERROR("Apply for memory failed."); pr_err("Apply for memory failed.\n"); return FAIL; } Loading @@ -228,7 +227,7 @@ s32 init_wr_node(struct i2c_client *client) tool_set_proc_name(procname); goodix_proc_entry = create_proc_entry(procname, 0660, NULL); if (goodix_proc_entry == NULL) { GTP_ERROR("Couldn't create proc entry!"); pr_err("Couldn't create proc entry!\n"); return FAIL; } GTP_INFO("Create proc entry success!"); Loading Loading @@ -257,7 +256,7 @@ static u8 relation(u8 src, u8 dst, u8 rlt) case 1: ret = (src == dst) ? true : false; GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", pr_debug("equal:src:0x%02x dst:0x%02x ret:%d.\n", src, dst, (s32)ret); break; Loading Loading @@ -308,14 +307,14 @@ static u8 comfirm(void) for (i = 0; i < cmd_head.times; i++) { if (tool_i2c_read(buf, 1) <= 0) { GTP_ERROR("Read flag data failed!"); pr_err("Read flag data failed!\n"); return FAIL; } if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, cmd_head.flag_relation)) { GTP_DEBUG("value at flag addr:0x%02x.", pr_debug("value at flag addr:0x%02x.\n", buf[GTP_ADDR_LENGTH]); GTP_DEBUG("flag value:0x%02x.", cmd_head.flag_val); pr_debug("flag value:0x%02x.\n", cmd_head.flag_val); break; } Loading @@ -323,7 +322,7 @@ static u8 comfirm(void) } if (i >= cmd_head.times) { GTP_ERROR("Didn't get the flag to continue!"); pr_debug("Didn't get the flag to continue!\n"); return FAIL; } Loading @@ -344,41 +343,38 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, { s32 ret = 0; GTP_DEBUG_FUNC(); GTP_DEBUG_ARRAY((u8 *)buff, len); mutex_lock(&lock); ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); if (ret) { GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); ret = -EACCES; goto exit; } GTP_DEBUG("wr :0x%02x.", cmd_head.wr); GTP_DEBUG("flag:0x%02x.", cmd_head.flag); GTP_DEBUG("flag addr:0x%02x%02x.", cmd_head.flag_addr[0], pr_debug("wr :0x%02x.\n", cmd_head.wr); pr_debug("flag:0x%02x.\n", cmd_head.flag); pr_debug("flag addr:0x%02x%02x.\n", cmd_head.flag_addr[0], cmd_head.flag_addr[1]); GTP_DEBUG("flag val:0x%02x.", cmd_head.flag_val); GTP_DEBUG("flag rel:0x%02x.", cmd_head.flag_relation); GTP_DEBUG("circle :%d.", (s32)cmd_head.circle); GTP_DEBUG("times :%d.", (s32)cmd_head.times); GTP_DEBUG("retry :%d.", (s32)cmd_head.retry); GTP_DEBUG("delay :%d.", (s32)cmd_head.delay); GTP_DEBUG("data len:%d.", (s32)cmd_head.data_len); GTP_DEBUG("addr len:%d.", (s32)cmd_head.addr_len); GTP_DEBUG("addr:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]); GTP_DEBUG("len:%d.", (s32)len); GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]); pr_debug("flag val:0x%02x.\n", cmd_head.flag_val); pr_debug("flag rel:0x%02x.\n", cmd_head.flag_relation); pr_debug("circle :%d.\n", (s32)cmd_head.circle); pr_debug("times :%d.\n", (s32)cmd_head.times); pr_debug("retry :%d.\n", (s32)cmd_head.retry); pr_debug("delay :%d.\n", (s32)cmd_head.delay); pr_debug("data len:%d.\n", (s32)cmd_head.data_len); pr_debug("addr len:%d.\n", (s32)cmd_head.addr_len); pr_debug("addr:0x%02x%02x.\n", cmd_head.addr[0], cmd_head.addr[1]); pr_debug("len:%d.\n", (s32)len); pr_debug("buf[20]:0x%02x.\n", buff[CMD_HEAD_LENGTH]); if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) { pr_err("data len %d > data buff %d, rejected!\n", pr_debug("data len %d > data buff %d, rejected!\n", cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH)); ret = -EINVAL; goto exit; } if (cmd_head.addr_len > GTP_ADDR_LENGTH) { pr_err(" addr len %d > data buff %d, rejected!\n", pr_debug(" addr len %d > data buff %d, rejected!\n", cmd_head.addr_len, GTP_ADDR_LENGTH); ret = -EINVAL; goto exit; Loading @@ -391,19 +387,14 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.addr, cmd_head.addr_len); GTP_DEBUG_ARRAY(cmd_head.data, cmd_head.data_len + cmd_head.addr_len); GTP_DEBUG_ARRAY((u8 *)&buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[WRITE]Comfirm fail!"); pr_err("[WRITE]Comfirm fail!\n"); ret = -EINVAL; goto exit; } Loading @@ -413,14 +404,11 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, if (tool_i2c_write( &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len) <= 0) { GTP_ERROR("[WRITE]Write data failed!"); pr_err("[WRITE]Write data failed!\n"); ret = -EIO; goto exit; } GTP_DEBUG_ARRAY( &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len); if (cmd_head.delay) msleep(cmd_head.delay); Loading @@ -431,10 +419,10 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_ERROR("copy_from_user failed."); pr_err("copy_from_user failed.\n"); if (cmd_head.data_len > sizeof(IC_TYPE)) { pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n", pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", cmd_head.data_len, sizeof(IC_TYPE)); ret = -EINVAL; goto exit; Loading Loading @@ -473,13 +461,13 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); if (ret) GTP_DEBUG("copy_from_user failed."); pr_debug("copy_from_user failed.\n"); if (cmd_head.data[GTP_ADDR_LENGTH]) { GTP_DEBUG("gtp enter rawdiff."); pr_debug("gtp enter rawdiff.\n"); ts->gtp_rawdiff_mode = true; } else { ts->gtp_rawdiff_mode = false; GTP_DEBUG("gtp leave rawdiff."); pr_debug("gtp leave rawdiff.\n"); } ret = CMD_HEAD_LENGTH; goto exit; Loading @@ -495,7 +483,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, show_len = 0; total_len = 0; if (cmd_head.data_len + 1 > DATA_LENGTH) { pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n", pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", cmd_head.data_len + 1, DATA_LENGTH); ret = -EINVAL; goto exit; Loading Loading @@ -530,7 +518,6 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, int *eof, void *data) { s32 ret; GTP_DEBUG_FUNC(); mutex_lock(&lock); if (cmd_head.wr % 2) { Loading @@ -544,7 +531,7 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[READ]Comfirm fail!"); pr_err("[READ]Comfirm fail!\n"); ret = -EINVAL; goto exit; } Loading @@ -554,9 +541,9 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len); GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0], pr_debug("[CMD HEAD DATA] ADDR:0x%02x%02x.\n", cmd_head.data[0], cmd_head.data[1]); GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0], pr_debug("[CMD HEAD ADDR] ADDR:0x%02x%02x.\n", cmd_head.addr[0], cmd_head.addr[1]); if (cmd_head.delay) Loading @@ -572,16 +559,13 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, data_len -= len; if (tool_i2c_read(cmd_head.data, len) <= 0) { GTP_ERROR("[READ]Read data failed!"); pr_err("[READ]Read data failed!\n"); ret = -EINVAL; goto exit; } memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len); loc += len; GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH], len); GTP_DEBUG_ARRAY(page, len); } } else if (cmd_head.wr == 2) { /* memcpy(page, "gt8", cmd_head.data_len); Loading @@ -589,7 +573,7 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, * page[5] = 0; */ GTP_DEBUG("Return ic type:%s len:%d.", page, pr_debug("Return ic type:%s len:%d.\n", page, (s32)cmd_head.data_len); ret = cmd_head.data_len; goto exit; Loading
drivers/input/touchscreen/gt9xx/gt9xx.c +165 −55 Original line number Diff line number Diff line Loading @@ -77,19 +77,13 @@ #if GTP_HAVE_TOUCH_KEY static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK}; #if GTP_DEBUG_ON static const int key_codes[] = { KEY_HOME, KEY_BACK, KEY_MENU, KEY_SEARCH }; static const char *const key_names[] = { "Key_Home", "Key_Back", "Key_Menu", "Key_Search" }; #endif #endif static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms); static void gtp_int_sync(struct goodix_ts_data *ts, int ms); static int gtp_i2c_test(struct i2c_client *client); static int goodix_power_off(struct goodix_ts_data *ts); static int goodix_power_on(struct goodix_ts_data *ts); #if defined(CONFIG_FB) static int fb_notifier_callback(struct notifier_block *self, Loading Loading @@ -493,30 +487,19 @@ static void goodix_ts_work_func(struct work_struct *work) memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); } #if GTP_HAVE_TOUCH_KEY key_value = point_data[3 + 8 * touch_num]; if (key_value || pre_key) { for (i = 0; i < ARRAY_SIZE(touch_key_array); i++) { #if GTP_DEBUG_ON for (ret = 0; ret < 4; ++ret) { if (key_codes[ret] == touch_key_array[i]) { GTP_DEBUG("Key: %s %s", key_names[ret], (key_value & (0x01 << i)) ? "Down" : "Up"); break; } } #endif for (i = 0; i < ts->pdata->num_button; i++) { input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); ts->pdata->button_map[i], key_value & (0x01<<i)); } touch_num = 0; pre_touch = 0; } #endif pre_key = key_value; #if GTP_WITH_PEN Loading Loading @@ -754,7 +737,7 @@ Input: ts: private data. Output: Executive outcomes. 1: succeed, otherwise failed. >0: succeed, otherwise failed. *******************************************************/ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) { Loading @@ -765,12 +748,28 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) (u8)GTP_REG_SLEEP, 5}; ret = gpio_direction_output(ts->pdata->irq_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP sleep: Cannot reconfig gpio %d.\n", ts->pdata->irq_gpio); if (ts->pdata->enable_power_off) { ret = gpio_direction_output(ts->pdata->reset_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP sleep: Cannot reconfig gpio %d.\n", ts->pdata->reset_gpio); ret = goodix_power_off(ts); if (ret) { dev_err(&ts->client->dev, "GTP power off failed.\n"); return 0; } return 1; } usleep(5000); while (retry++ < GTP_I2C_RETRY_5) { ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); if (ret > 0) { dev_dbg(&ts->client->dev, "GTP enter sleep!"); if (ret == 1) { dev_dbg(&ts->client->dev, "GTP enter sleep!"); return ret; } msleep(20); Loading @@ -778,7 +777,7 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) dev_err(&ts->client->dev, "GTP send sleep cmd failed.\n"); return ret; } #endif #endif /* !GTP_SLIDE_WAKEUP */ /******************************************************* Function: Loading @@ -794,17 +793,36 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) u8 retry = 0; s8 ret = -1; #if GTP_POWER_CTRL_SLEEP if (ts->pdata->enable_power_off) { ret = gpio_direction_output(ts->pdata->irq_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP wakeup: Cannot reconfig gpio %d.\n", ts->pdata->irq_gpio); ret = gpio_direction_output(ts->pdata->reset_gpio, 0); if (ret) dev_err(&ts->client->dev, "GTP wakeup: Cannot reconfig gpio %d.\n", ts->pdata->reset_gpio); ret = goodix_power_on(ts); if (ret) { dev_err(&ts->client->dev, "GTP power on failed.\n"); return 0; } gtp_reset_guitar(ts, 20); ret = gtp_send_cfg(ts); if (ret > 0) { if (ret <= 0) { dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n"); return ret; } dev_dbg(&ts->client->dev, "Wakeup sleep send config success."); return 1; } #else while (retry++ < GTP_I2C_RETRY_10) { } else { err_retry: #if GTP_SLIDE_WAKEUP /* wakeup not by slide */ if (doze_status != DOZE_WAKEUP) Loading @@ -821,7 +839,7 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) } #endif ret = gtp_i2c_test(ts->client); if (ret > 0) { if (ret == 2) { dev_dbg(&ts->client->dev, "GTP wakeup sleep."); #if (!GTP_SLIDE_WAKEUP) if (chip_gt9xxs == 0) { Loading @@ -835,10 +853,10 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) return ret; } gtp_reset_guitar(ts, 20); } #endif if (retry++ < GTP_I2C_RETRY_10) goto err_retry; dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n"); } return ret; } #endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/ Loading Loading @@ -1051,9 +1069,7 @@ static int gtp_check_product_id(struct i2c_client *client) dev_info(&client->dev, "Goodix Product ID = %s\n", product_id); if (!IS_ERR(ts->pdata->product_id)) ret = strcmp(product_id, ts->pdata->product_id); if (ret != 0) return -EINVAL; Loading Loading @@ -1232,12 +1248,11 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts) /* in case of "out of memory" */ input_mt_init_slots(ts->input_dev, 10, 0); #if GTP_HAVE_TOUCH_KEY for (index = 0; index < ARRAY_SIZE(touch_key_array); index++) { for (index = 0; index < ts->pdata->num_button; index++) { input_set_capability(ts->input_dev, EV_KEY, touch_key_array[index]); EV_KEY, ts->pdata->button_map[index]); } #endif #if GTP_SLIDE_WAKEUP input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); Loading Loading @@ -1305,6 +1320,12 @@ static int goodix_power_on(struct goodix_ts_data *ts) { int ret; if (ts->power_on) { dev_info(&ts->client->dev, "Device already power on\n"); return 0; } if (!IS_ERR(ts->avdd)) { ret = reg_set_optimum_mode_check(ts->avdd, GOODIX_VDD_LOAD_MAX_UA); Loading Loading @@ -1371,6 +1392,7 @@ static int goodix_power_on(struct goodix_ts_data *ts) } } ts->power_on = true; return 0; err_enable_vcc_i2c: Loading @@ -1389,6 +1411,7 @@ err_set_vtg_vdd: regulator_disable(ts->avdd); err_enable_avdd: err_set_opt_avdd: ts->power_on = false; return ret; } Loading @@ -1402,6 +1425,12 @@ static int goodix_power_off(struct goodix_ts_data *ts) { int ret; if (!ts->power_on) { dev_info(&ts->client->dev, "Device already power off\n"); return 0; } if (!IS_ERR(ts->vcc_i2c)) { ret = regulator_set_voltage(ts->vcc_i2c, 0, GOODIX_I2C_VTG_MAX_UV); Loading Loading @@ -1434,6 +1463,7 @@ static int goodix_power_off(struct goodix_ts_data *ts) "Regulator avdd disable failed ret=%d\n", ret); } ts->power_on = false; return 0; } Loading Loading @@ -1486,6 +1516,50 @@ static int goodix_power_deinit(struct goodix_ts_data *ts) return 0; } static ssize_t gtp_fw_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct goodix_ts_data *ts = dev_get_drvdata(dev); if (!strlen(ts->fw_name)) return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1, "No fw name has been given."); else return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1, "%s\n", ts->fw_name); } static ssize_t gtp_fw_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct goodix_ts_data *ts = dev_get_drvdata(dev); if (size > GTP_FW_NAME_MAXSIZE - 1) { dev_err(dev, "FW name size exceeds the limit."); return -EINVAL; } strlcpy(ts->fw_name, buf, size); if (ts->fw_name[size-1] == '\n') ts->fw_name[size-1] = '\0'; return size; } static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP), gtp_fw_name_show, gtp_fw_name_store); static struct attribute *gtp_attrs[] = { &dev_attr_fw_name.attr, NULL }; static const struct attribute_group gtp_attr_grp = { .attrs = gtp_attrs, }; static int goodix_ts_get_dt_coords(struct device *dev, char *name, struct goodix_ts_platform_data *pdata) { Loading Loading @@ -1549,6 +1623,9 @@ static int goodix_parse_dt(struct device *dev, pdata->no_force_update = of_property_read_bool(np, "goodix,no-force-update"); pdata->enable_power_off = of_property_read_bool(np, "goodix,enable-power-off"); /* reset, irq gpio info */ pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &pdata->reset_gpio_flags); Loading @@ -1562,8 +1639,17 @@ static int goodix_parse_dt(struct device *dev, rc = of_property_read_string(np, "goodix,product-id", &pdata->product_id); if (rc < 0 || strlen(pdata->product_id) > GTP_PRODUCT_ID_MAXSIZE) return rc; if (rc && (rc != -EINVAL)) { dev_err(dev, "Failed to parse product_id."); return -EINVAL; } rc = of_property_read_string(np, "goodix,fw_name", &pdata->fw_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Failed to parse firmware name.\n"); return -EINVAL; } prop = of_find_property(np, "goodix,button-map", NULL); if (prop) { Loading @@ -1578,6 +1664,9 @@ static int goodix_parse_dt(struct device *dev, dev_err(dev, "Unable to read key codes\n"); return rc; } pdata->num_button = num_buttons; memcpy(pdata->button_map, button_map, pdata->num_button * sizeof(u32)); } read_cfg_num = 0; Loading Loading @@ -1670,6 +1759,7 @@ static int goodix_ts_probe(struct i2c_client *client, spin_lock_init(&ts->irq_lock); i2c_set_clientdata(client, ts); ts->gtp_rawdiff_mode = 0; ts->power_on = false; ret = gtp_request_io_port(ts); if (ret) { Loading Loading @@ -1697,12 +1787,16 @@ static int goodix_ts_probe(struct i2c_client *client, goto exit_power_off; } if (pdata->fw_name) strlcpy(ts->fw_name, pdata->fw_name, strlen(pdata->fw_name) + 1); #if GTP_AUTO_UPDATE ret = gup_init_update_proc(ts); if (ret < 0) { dev_err(&client->dev, "GTP Create firmware update thread error.\n"); goto exit_free_io_port; goto exit_power_off; } #endif Loading @@ -1719,7 +1813,9 @@ static int goodix_ts_probe(struct i2c_client *client, dev_err(&client->dev, "GTP request input dev failed.\n"); goto exit_free_inputdev; } input_set_drvdata(ts->input_dev, ts); mutex_init(&ts->lock); #if defined(CONFIG_FB) ts->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&ts->fb_notif); Loading Loading @@ -1762,9 +1858,16 @@ static int goodix_ts_probe(struct i2c_client *client, #if GTP_ESD_PROTECT gtp_esd_switch(client, SWITCH_ON); #endif ret = sysfs_create_group(&client->dev.kobj, >p_attr_grp); if (ret < 0) { dev_err(&client->dev, "sys file creation failed.\n"); goto exit_free_irq; } init_done = true; return 0; exit_free_irq: mutex_destroy(&ts->lock); #if defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) dev_err(&client->dev, Loading Loading @@ -1813,6 +1916,8 @@ static int goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); sysfs_remove_group(&ts->input_dev->dev.kobj, >p_attr_grp); #if defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) dev_err(&client->dev, Loading @@ -1820,6 +1925,7 @@ static int goodix_ts_remove(struct i2c_client *client) #elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif mutex_destroy(&ts->lock); #if GTP_CREATE_WR_NODE uninit_wr_node(); Loading Loading @@ -1873,6 +1979,7 @@ static void goodix_ts_suspend(struct goodix_ts_data *ts) { int ret = -1, i; mutex_lock(&ts->lock); #if GTP_ESD_PROTECT ts->gtp_is_suspend = 1; gtp_esd_switch(ts->client, SWITCH_OFF); Loading @@ -1893,12 +2000,13 @@ static void goodix_ts_suspend(struct goodix_ts_data *ts) ret = gtp_enter_sleep(ts); #endif if (ret < 0) if (ret <= 0) dev_err(&ts->client->dev, "GTP early suspend failed.\n"); /* to avoid waking up while not sleeping, * delay 48 + 10ms to ensure reliability */ msleep(58); mutex_unlock(&ts->lock); } /******************************************************* Loading @@ -1913,13 +2021,14 @@ static void goodix_ts_resume(struct goodix_ts_data *ts) { int ret = -1; mutex_lock(&ts->lock); ret = gtp_wakeup_sleep(ts); #if GTP_SLIDE_WAKEUP doze_status = DOZE_DISABLED; #endif if (ret < 0) if (ret <= 0) dev_err(&ts->client->dev, "GTP resume failed.\n"); if (ts->use_irq) Loading @@ -1932,6 +2041,7 @@ static void goodix_ts_resume(struct goodix_ts_data *ts) ts->gtp_is_suspend = 0; gtp_esd_switch(ts->client, SWITCH_ON); #endif mutex_unlock(&ts->lock); } #if defined(CONFIG_FB) Loading Loading @@ -2177,7 +2287,7 @@ static void __exit goodix_ts_exit(void) i2c_del_driver(&goodix_ts_driver); } late_initcall(goodix_ts_init); module_init(goodix_ts_init); module_exit(goodix_ts_exit); MODULE_DESCRIPTION("GTP Series Driver"); Loading
drivers/input/touchscreen/gt9xx/gt9xx.h +12 −38 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/regulator/consumer.h> #include <linux/firmware.h> #include <linux/debugfs.h> #include <linux/mutex.h> #if defined(CONFIG_FB) #include <linux/notifier.h> Loading @@ -42,13 +43,17 @@ #define GOODIX_SUSPEND_LEVEL 1 #endif #define MAX_BUTTONS 4 #define GOODIX_MAX_CFG_GROUP 6 #define GTP_FW_NAME_MAXSIZE 50 struct goodix_ts_platform_data { int irq_gpio; u32 irq_gpio_flags; int reset_gpio; u32 reset_gpio_flags; const char *product_id; const char *fw_name; u32 x_max; u32 y_max; u32 x_min; Loading @@ -59,8 +64,11 @@ struct goodix_ts_platform_data { u32 panel_maxy; bool no_force_update; bool i2c_pull_up; bool enable_power_off; size_t config_data_len[GOODIX_MAX_CFG_GROUP]; u8 *config_data[GOODIX_MAX_CFG_GROUP]; u32 button_map[MAX_BUTTONS]; u8 num_button; }; struct goodix_ts_data { spinlock_t irq_lock; Loading @@ -70,6 +78,7 @@ struct goodix_ts_data { struct hrtimer timer; struct workqueue_struct *goodix_wq; struct work_struct work; struct delayed_work goodix_update_work; s32 irq_is_disabled; s32 use_irq; u16 abs_x_max; Loading @@ -86,6 +95,8 @@ struct goodix_ts_data { u8 fixed_cfg; u8 esd_running; u8 fw_error; bool power_on; struct mutex lock; struct regulator *avdd; struct regulator *vdd; struct regulator *vcc_i2c; Loading @@ -104,7 +115,6 @@ extern u16 total_len; #define GTP_CHANGE_X2Y 0 #define GTP_DRIVER_SEND_CFG 1 #define GTP_HAVE_TOUCH_KEY 1 #define GTP_POWER_CTRL_SLEEP 0 /* auto updated by .bin file as default */ #define GTP_AUTO_UPDATE 0 Loading @@ -117,14 +127,11 @@ extern u16 total_len; #define GTP_ESD_PROTECT 0 #define GTP_WITH_PEN 0 /* This cannot work when enable-power-off is on */ #define GTP_SLIDE_WAKEUP 0 /* double-click wakeup, function together with GTP_SLIDE_WAKEUP */ #define GTP_DBL_CLK_WAKEUP 0 #define GTP_DEBUG_ON 0 #define GTP_DEBUG_ARRAY_ON 0 #define GTP_DEBUG_FUNC_ON 0 /*************************** PART2:TODO define *******************************/ /* STEP_1(REQUIRED): Define Configuration Information Group(s) */ /* Sensor_ID Map: */ Loading Loading @@ -190,39 +197,6 @@ extern u16 total_len; #define RESOLUTION_LOC 3 #define TRIGGER_LOC 8 /* Log define */ #define GTP_DEBUG(fmt, arg...) do {\ if (GTP_DEBUG_ON) {\ pr_debug("<<-GTP-DEBUG->> [%d]"fmt"\n",\ __LINE__, ##arg); } \ } while (0) #define GTP_DEBUG_ARRAY(array, num) do {\ s32 i; \ u8 *a = array; \ if (GTP_DEBUG_ARRAY_ON) {\ pr_debug("<<-GTP-DEBUG-ARRAY->>\n");\ for (i = 0; i < (num); i++) { \ pr_debug("%02x ", (a)[i]);\ if ((i + 1) % 10 == 0) { \ pr_debug("\n");\ } \ } \ pr_debug("\n");\ } \ } while (0) #define GTP_DEBUG_FUNC() do {\ if (GTP_DEBUG_FUNC_ON)\ pr_debug("<<-GTP-FUNC->> Func:%s@Line:%d\n",\ __func__, __LINE__);\ } while (0) #define GTP_SWAP(x, y) do {\ typeof(x) z = x;\ x = y;\ y = z;\ } while (0) /*****************************End of Part III********************************/ void gtp_esd_switch(struct i2c_client *client, int on); Loading
drivers/input/touchscreen/gt9xx/gt9xx_update.c +228 −264 File changed.Preview size limit exceeded, changes collapsed. Show changes