diff options
author | Super Liu <supercjliu@google.com> | 2023-04-06 05:19:59 +0000 |
---|---|---|
committer | Super Liu <supercjliu@google.com> | 2023-04-06 08:02:14 +0000 |
commit | 8da5744724d93c45251f91a2f09c5420de8da65c (patch) | |
tree | 9d21ed3b371727a1e000b8b5fb1e0644c67a4c11 /goodix_ts_core.c | |
parent | a17332d87e6dd4f008e9575cb2f5a15fffa24fe9 (diff) | |
download | goodix_touch-8da5744724d93c45251f91a2f09c5420de8da65c.tar.gz |
Revert^2 "touch/goodix: Import driver v1.2.5"
a17332d87e6dd4f008e9575cb2f5a15fffa24fe9
Change-Id: I6bd8676543a4370522f1df88c676f2075659e12e
Diffstat (limited to 'goodix_ts_core.c')
-rw-r--r-- | goodix_ts_core.c | 875 |
1 files changed, 251 insertions, 624 deletions
diff --git a/goodix_ts_core.c b/goodix_ts_core.c index 120c4f5..2380555 100644 --- a/goodix_ts_core.c +++ b/goodix_ts_core.c @@ -31,257 +31,60 @@ // #include "../../../video/fbdev/core/fb_firefly.h" #define GOODIX_DEFAULT_CFG_NAME "goodix_cfg_group.cfg" -#define GOOIDX_INPUT_PHYS "goodix_ts/input0" -struct goodix_module goodix_modules; -int core_module_prob_sate = CORE_MODULE_UNPROBED; +struct goodix_device_manager goodix_devices; -static const struct dev_pm_ops dev_pm_ops; +static const struct dev_pm_ops dev_pm_ops; /* [GOOG] */ -static int goodix_send_ic_config(struct goodix_ts_core *cd, int type); -/** - * __do_register_ext_module - register external module - * to register into touch core modules structure - * return 0 on success, otherwise return < 0 - */ -static int __do_register_ext_module(struct goodix_ext_module *module) +static void goodix_device_manager_init(void) { - struct goodix_ext_module *ext_module, *next; - struct list_head *insert_point = &goodix_modules.head; - - /* prority level *must* be set */ - if (module->priority == EXTMOD_PRIO_RESERVED) { - ts_err("Priority of module [%s] needs to be set", module->name); - return -EINVAL; - } - mutex_lock(&goodix_modules.mutex); - /* find insert point for the specified priority */ - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (ext_module == module) { - ts_info("Module [%s] already exists", - module->name); - mutex_unlock(&goodix_modules.mutex); - return 0; - } - } - - /* smaller priority value with higher priority level */ - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (ext_module->priority >= module->priority) { - insert_point = &ext_module->list; - break; - } - } - } - - if (module->funcs && module->funcs->init) { - if (module->funcs->init(goodix_modules.core_data, module) < 0) { - ts_err("Module [%s] init error", - module->name ? module->name : " "); - mutex_unlock(&goodix_modules.mutex); - return -EFAULT; - } - } - - list_add(&module->list, insert_point->prev); - mutex_unlock(&goodix_modules.mutex); - - return 0; -} - -static void goodix_register_ext_module_work(struct work_struct *work) -{ - struct goodix_ext_module *module = - container_of(work, struct goodix_ext_module, work); - - ts_info("module register work IN"); - - /* driver probe failed */ - if (core_module_prob_sate != CORE_MODULE_PROB_SUCCESS) { - ts_err("Can't register ext_module core error"); + if (goodix_devices.initialized) return; - } - - if (__do_register_ext_module(module)) - ts_err("failed register module: %s", module->name); - else - ts_info("success register module: %s", module->name); + goodix_devices.initialized = true; + INIT_LIST_HEAD(&goodix_devices.list); + mutex_init(&goodix_devices.mutex); } -static void goodix_core_module_init(void) +static void goodix_device_manager_exit(void) { - if (goodix_modules.initialized) - return; - goodix_modules.initialized = true; - INIT_LIST_HEAD(&goodix_modules.head); - mutex_init(&goodix_modules.mutex); -} - -/** - * goodix_register_ext_module - interface for register external module - * to the core. This will create a workqueue to finish the real register - * work and return immediately. The user need to check the final result - * to make sure registe is success or fail. - * - * @module: pointer to external module to be register - * return: 0 ok, <0 failed - */ -int goodix_register_ext_module(struct goodix_ext_module *module) -{ - if (!module) - return -EINVAL; - - ts_info("IN"); - - goodix_core_module_init(); - INIT_WORK(&module->work, goodix_register_ext_module_work); - schedule_work(&module->work); - - ts_info("OUT"); - return 0; -} - -/** - * goodix_register_ext_module_no_wait - * return: 0 ok, <0 failed - */ -int goodix_register_ext_module_no_wait(struct goodix_ext_module *module) -{ - if (!module) - return -EINVAL; - - ts_info("IN"); - goodix_core_module_init(); - /* driver probe failed */ - if (core_module_prob_sate != CORE_MODULE_PROB_SUCCESS) { - ts_err("Can't register ext_module core error"); - return -EINVAL; - } - return __do_register_ext_module(module); -} - -/** - * goodix_unregister_ext_module - interface for external module - * to unregister external modules - * - * @module: pointer to external module - * return: 0 ok, <0 failed - */ -int goodix_unregister_ext_module(struct goodix_ext_module *module) -{ - struct goodix_ext_module *ext_module, *next; - bool found = false; - - if (!module) - return -EINVAL; - - if (!goodix_modules.initialized) - return -EINVAL; - - if (!goodix_modules.core_data) - return -ENODEV; + struct goodix_device_resource *res, *next; - mutex_lock(&goodix_modules.mutex); - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (ext_module == module) { - found = true; - break; - } + if (!list_empty(&goodix_devices.list)) { + list_for_each_entry_safe(res, next, &goodix_devices.list, list) { + platform_device_unregister(&res->pdev); + kfree(res); } - } else { - mutex_unlock(&goodix_modules.mutex); - return 0; } - - if (!found) { - ts_debug("Module [%s] never registed", module->name); - mutex_unlock(&goodix_modules.mutex); - return 0; - } - - list_del(&module->list); - mutex_unlock(&goodix_modules.mutex); - - if (module->funcs && module->funcs->exit) - module->funcs->exit(goodix_modules.core_data, module); - - ts_info("Module [%s] unregistered", module->name ? module->name : " "); - return 0; -} - -static void goodix_ext_sysfs_release(struct kobject *kobj) -{ - ts_info("Kobject released!"); -} - -#define to_ext_module(kobj) container_of(kobj, struct goodix_ext_module, kobj) -#define to_ext_attr(attr) container_of(attr, struct goodix_ext_attribute, attr) - -static ssize_t goodix_ext_sysfs_show( - struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct goodix_ext_module *module = to_ext_module(kobj); - struct goodix_ext_attribute *ext_attr = to_ext_attr(attr); - - if (ext_attr->show) - return ext_attr->show(module, buf); - - return -EIO; } -static ssize_t goodix_ext_sysfs_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) +int goodix_device_register(struct goodix_device_resource *device) { - struct goodix_ext_module *module = to_ext_module(kobj); - struct goodix_ext_attribute *ext_attr = to_ext_attr(attr); - - if (ext_attr->store) - return ext_attr->store(module, buf, count); - - return -EIO; -} - -static const struct sysfs_ops goodix_ext_ops = { .show = goodix_ext_sysfs_show, - .store = goodix_ext_sysfs_store }; + if (!device) + return -ENXIO; -static struct kobj_type goodix_ext_ktype = { - .release = goodix_ext_sysfs_release, - .sysfs_ops = &goodix_ext_ops, -}; + mutex_lock(&goodix_devices.mutex); + list_add(&device->list, &goodix_devices.list); + device->id = goodix_devices.nums++; + sprintf(device->name, "%s.%d", GOODIX_CORE_DRIVER_NAME, device->id); + mutex_unlock(&goodix_devices.mutex); + ts_info("register device %s", device->name); -struct kobj_type *goodix_get_default_ktype(void) -{ - return &goodix_ext_ktype; + return 0; } -struct kobject *goodix_get_default_kobj(void) -{ - struct kobject *kobj = NULL; - - if (goodix_modules.core_data && goodix_modules.core_data->pdev) - kobj = &goodix_modules.core_data->pdev->dev.kobj; - return kobj; -} +static int goodix_send_ic_config(struct goodix_ts_core *cd, int type); /* show driver information */ -static ssize_t driver_info_show( - struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t driver_info_show(struct device *dev, + struct device_attribute *attr, char *buf) { - return snprintf( - buf, PAGE_SIZE, "DriverVersion:%s\n", GOODIX_DRIVER_VERSION); + return snprintf(buf, PAGE_SIZE, "DriverVersion:%s\n", + GOODIX_DRIVER_VERSION); } /* show chip infoamtion */ -static ssize_t chip_info_show( - struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t chip_info_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct goodix_ts_core *cd = dev_get_drvdata(dev); struct goodix_ts_hw_ops *hw_ops = cd->hw_ops; @@ -670,13 +473,15 @@ static ssize_t goodix_ts_esd_info_show( static ssize_t goodix_ts_esd_info_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct goodix_ts_core *cd = dev_get_drvdata(dev); + if (!buf || count <= 0) return -EINVAL; if (buf[0] != '0') - goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + goodix_ts_esd_on(cd); else - goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + goodix_ts_esd_off(cd); return count; } @@ -706,35 +511,19 @@ static ssize_t goodix_ts_debug_log_store(struct device *dev, return count; } -#define GOODIX_MAX_PEN_FREQ_DATA_LEN 16 -#define GOODIX_HOGP_INFO_LEN 3 - -#pragma pack(1) -struct goodix_hid_hogp { - u16 pressure; - u8 key; -}; -#pragma pack() - -struct goodix_ble_data { - u8 freq[GOODIX_MAX_PEN_FREQ_DATA_LEN]; - u8 hogp[GOODIX_HOGP_INFO_LEN]; - int hogp_ready; - int freq_ready; - struct mutex lock; -} goodix_ble_data; - int goodix_update_pen_freq(struct goodix_ts_core *cd, u8 *data, int len) { - if (len > sizeof(goodix_ble_data.freq)) { + struct goodix_ble_data *ble_data = &cd->ble_data; + + if (len > sizeof(ble_data->freq)) { ts_err("pen freq data exceed limit"); return -EINVAL; } - mutex_lock(&goodix_ble_data.lock); - memset(goodix_ble_data.freq, 0, sizeof(goodix_ble_data.freq)); - memcpy(goodix_ble_data.freq, data, len); - goodix_ble_data.freq_ready = 1; - mutex_unlock(&goodix_ble_data.lock); + mutex_lock(&ble_data->lock); + memset(ble_data->freq, 0, sizeof(ble_data->freq)); + memcpy(ble_data->freq, data, len); + ble_data->freq_ready = 1; + mutex_unlock(&ble_data->lock); sysfs_notify(&cd->pdev->dev.kobj, NULL, "pen_freq"); ts_debug("send pen freq hop event"); return 0; @@ -744,11 +533,14 @@ int goodix_update_pen_freq(struct goodix_ts_core *cd, u8 *data, int len) static ssize_t goodix_ts_pen_freq_show( struct device *dev, struct device_attribute *attr, char *buf) { - mutex_lock(&goodix_ble_data.lock); - memcpy(buf, goodix_ble_data.freq, sizeof(goodix_ble_data.freq)); - goodix_ble_data.freq_ready = 0; - mutex_unlock(&goodix_ble_data.lock); - return sizeof(goodix_ble_data.freq); + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ble_data *ble_data = &core_data->ble_data; + + mutex_lock(&ble_data->lock); + memcpy(buf, ble_data->freq, sizeof(ble_data->freq)); + ble_data->freq_ready = 0; + mutex_unlock(&ble_data->lock); + return sizeof(ble_data->freq); } /* debug level store */ @@ -757,12 +549,13 @@ static ssize_t goodix_ts_pen_debug_store(struct device *dev, { int pen_freq; struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ble_data *ble_data = &core_data->ble_data; sscanf(buf, "%d", &pen_freq); ts_debug("set new pen_freq %d", pen_freq); - goodix_ble_data.freq[0] = 0xC0; - goodix_ble_data.freq[1] = 1; - goodix_ble_data.freq[2] = pen_freq & 0xFF; + ble_data->freq[0] = 0xC0; + ble_data->freq[1] = 1; + ble_data->freq[2] = pen_freq & 0xFF; sysfs_notify(&core_data->pdev->dev.kobj, NULL, "pen_freq"); return count; @@ -772,18 +565,20 @@ static ssize_t goodix_ts_pen_hogp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct goodix_hid_hogp *tmp_prs; + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ble_data *ble_data = &core_data->ble_data; - if (count < sizeof(goodix_ble_data.hogp)) { + if (count < sizeof(ble_data->hogp)) { ts_err("data count to short"); return -EINVAL; } - mutex_lock(&goodix_ble_data.lock); - memcpy(goodix_ble_data.hogp, buf, sizeof(goodix_ble_data.hogp)); - goodix_ble_data.hogp_ready = 1; - mutex_unlock(&goodix_ble_data.lock); + mutex_lock(&ble_data->lock); + memcpy(ble_data->hogp, buf, sizeof(ble_data->hogp)); + ble_data->hogp_ready = 1; + mutex_unlock(&ble_data->lock); - tmp_prs = (struct goodix_hid_hogp *)goodix_ble_data.hogp; + tmp_prs = (struct goodix_hid_hogp *)ble_data->hogp; ts_debug("set ble pen data: %d, key %x", tmp_prs->pressure, tmp_prs->key); return count; @@ -841,6 +636,7 @@ static void goodix_ts_sysfs_exit(struct goodix_ts_core *core_data) sysfs_remove_group(&core_data->pdev->dev.kobj, &sysfs_group); } +/* [GOOG] */ #if IS_ENABLED(CONFIG_TOUCHSCREEN_MOTION_FILTER) int set_continuously_report_enabled(struct device *dev, bool enabled) { @@ -907,10 +703,10 @@ int set_sensing_enabled(struct device *dev, bool enabled) if (enabled) { cd->hw_ops->resume(cd); cd->hw_ops->irq_enable(cd, true); - goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + goodix_ts_esd_on(cd); ts_info("set sense ON"); } else { - goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + goodix_ts_esd_off(cd); cd->hw_ops->irq_enable(cd, false); cd->hw_ops->suspend(cd); ts_info("set sense OFF"); @@ -969,8 +765,8 @@ static int get_mutual_sensor_data( cmd->buffer = (u8 *)cd->mutual_data; cmd->size = tx * rx * sizeof(uint16_t); } else { - /* close esd */ - goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + /* disable esd */ + goodix_ts_esd_off(cd); ret = -EINVAL; if (cmd->type == GTI_SENSOR_DATA_TYPE_MS_DIFF) { @@ -985,9 +781,8 @@ static int get_mutual_sensor_data( cmd->buffer = (u8 *)cd->mutual_data_manual; cmd->size = tx * rx * sizeof(uint16_t); } - /* enable esd */ - goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + goodix_ts_esd_on(cd); } return ret; } @@ -1006,7 +801,7 @@ static int get_self_sensor_data( } else { /* disable irq & close esd */ cd->hw_ops->irq_enable(cd, false); - goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + goodix_ts_esd_off(cd); ret = -EINVAL; if (cmd->type == GTI_SENSOR_DATA_TYPE_SS_DIFF) { @@ -1024,7 +819,7 @@ static int get_self_sensor_data( /* enable irq & esd */ cd->hw_ops->irq_enable(cd, true); - goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + goodix_ts_esd_on(cd); } return ret; } @@ -1188,8 +983,10 @@ static int gti_ping(void *private_data, struct gti_ping_cmd *cmd) static int gti_selftest(void *private_data, struct gti_selftest_cmd *cmd) { + struct goodix_ts_core *cd = private_data; + cmd->result = GTI_SELFTEST_RESULT_DONE; - return driver_test_selftest(cmd->buffer); + return driver_test_selftest(cd, cmd->buffer); } static int gti_get_context_driver(void *private_data, @@ -1207,6 +1004,7 @@ static int gti_set_report_rate(void *private_data, } #endif +/*~[GOOG] */ /* prosfs create */ static int rawdata_proc_show(struct seq_file *m, void *v) @@ -1257,8 +1055,8 @@ exit: static int rawdata_proc_open(struct inode *inode, struct file *file) { - return single_open_size( - file, rawdata_proc_show, PDE_DATA(inode), PAGE_SIZE * 10); + return single_open_size(file, rawdata_proc_show, + PDE_DATA(inode), PAGE_SIZE * 10); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) @@ -1279,78 +1077,51 @@ static const struct file_operations rawdata_proc_fops = { static int goodix_ts_procfs_init(struct goodix_ts_core *core_data) { + int dev_id = core_data->pdev->id; struct proc_dir_entry *proc_entry; - int ret = 0; + char proc_node[32] = {0}; + int ret = 0; /* [GOOG] */ - proc_entry = proc_mkdir("goodix_ts", NULL); - if (proc_entry == NULL) { - ts_err("failed to create proc entry: goodix_ts"); - return -ENOMEM; - } + sprintf(proc_node, "goodix_ts.%d", dev_id); - proc_entry = proc_create_data("goodix_ts/tp_capacitance_data", 0664, - NULL, &rawdata_proc_fops, core_data); - if (proc_entry == NULL) { - ts_err("failed to create proc entry: goodix_ts/tp_capacitance_data"); + core_data->proc_dir_entry = proc_mkdir(proc_node, NULL); + if (!core_data->proc_dir_entry) + return -ENOMEM; + proc_entry = proc_create_data("tp_capacitance_data", + 0664, core_data->proc_dir_entry, &rawdata_proc_fops, core_data); + if (!proc_entry) { + ts_err("failed to create proc entry: goodix_ts.%d/tp_capacitance_data", + dev_id); ret = -ENOMEM; goto err_create_data; } ret = driver_test_proc_init(core_data); if (ret != 0) { - ts_err("failed to create proc entry: goodix_ts/driver_test"); + ts_err("failed to create proc entry: goodix_ts.%d/driver_test", dev_id); ret = -ENOMEM; goto err_create_driver; } - return ret; + + return 0; err_create_driver: - remove_proc_entry("goodix_ts/tp_capacitance_data", NULL); + remove_proc_entry("tp_capacitance_data", core_data->proc_dir_entry); err_create_data: - remove_proc_entry("goodix_ts", NULL); + remove_proc_entry(proc_node, NULL); return ret; } static void goodix_ts_procfs_exit(struct goodix_ts_core *core_data) { - driver_test_proc_remove(); - remove_proc_entry("goodix_ts/tp_capacitance_data", NULL); - remove_proc_entry("goodix_ts", NULL); -} + int dev_id = core_data->pdev->id; + char proc_node[32] = {0}; -/* event notifier */ -static BLOCKING_NOTIFIER_HEAD(ts_notifier_list); -/** - * goodix_ts_register_client - register a client notifier - * @nb: notifier block to callback on events - * see enum ts_notify_event in goodix_ts_core.h - */ -int goodix_ts_register_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&ts_notifier_list, nb); -} + sprintf(proc_node, "goodix_ts.%d", dev_id); -/** - * goodix_ts_unregister_client - unregister a client notifier - * @nb: notifier block to callback on events - * see enum ts_notify_event in goodix_ts_core.h - */ -int goodix_ts_unregister_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&ts_notifier_list, nb); -} - -/** - * fb_notifier_call_chain - notify clients of fb_events - * see enum ts_notify_event in goodix_ts_core.h - */ -int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v) -{ - int ret; - - ret = blocking_notifier_call_chain( - &ts_notifier_list, (unsigned long)evt, v); - return ret; + driver_test_proc_remove(core_data); + remove_proc_entry("tp_capacitance_data", core_data->proc_dir_entry); + remove_proc_entry(proc_node, NULL); } #if IS_ENABLED(CONFIG_OF) @@ -1619,8 +1390,8 @@ static void goodix_ts_report_pen( { struct input_dev *dev = cd->pen_dev; int i; - static unsigned int pen_pressure; struct goodix_hid_hogp *hogp; + struct goodix_ble_data *ble_data = &cd->ble_data; char trace_tag[128]; ktime_t pen_ktime; @@ -1635,21 +1406,21 @@ static void goodix_ts_report_pen( ktime_to_ns(ktime_sub(pen_ktime, cd->coords_timestamp))); ATRACE_BEGIN(trace_tag); input_report_key(dev, BTN_TOUCH, 1); - input_report_key(dev, pen_data->coords.tool_type, 1); + input_report_key(dev, BTN_TOOL_PEN, 1); input_report_abs(dev, ABS_X, pen_data->coords.x); input_report_abs(dev, ABS_Y, pen_data->coords.y); - mutex_lock(&goodix_ble_data.lock); - if (goodix_ble_data.hogp_ready) { - hogp = (struct goodix_hid_hogp *)goodix_ble_data.hogp; - pen_pressure = hogp->pressure; + mutex_lock(&ble_data->lock); + if (ble_data->hogp_ready) { + hogp = (struct goodix_hid_hogp *)ble_data->hogp; + cd->pen_pressure = hogp->pressure; ts_debug("update pen pressure from ble %d", - pen_pressure); + cd->pen_pressure); } - goodix_ble_data.hogp_ready = 0; - mutex_unlock(&goodix_ble_data.lock); + ble_data->hogp_ready = 0; + mutex_unlock(&ble_data->lock); - if (pen_data->coords.p && pen_pressure) - pen_data->coords.p = pen_pressure; + if (pen_data->coords.p && cd->pen_pressure) + pen_data->coords.p = cd->pen_pressure; input_report_abs(dev, ABS_PRESSURE, pen_data->coords.p); if (pen_data->coords.p == 0) input_report_abs(dev, ABS_DISTANCE, 1); @@ -1670,9 +1441,9 @@ static void goodix_ts_report_pen( ktime_to_ns(cd->coords_timestamp), ktime_to_ns(pen_ktime), ktime_to_ns(ktime_sub(pen_ktime, cd->coords_timestamp))); ATRACE_BEGIN(trace_tag); - pen_pressure = 0; + cd->pen_pressure = 0; input_report_key(dev, BTN_TOUCH, 0); - input_report_key(dev, pen_data->coords.tool_type, 0); + input_report_key(dev, BTN_TOOL_PEN, 0); } /* report pen button */ for (i = 0; i < GOODIX_MAX_PEN_KEY; i++) { @@ -1850,9 +1621,8 @@ static int goodix_ts_request_handle( else if (ts_event->request_code == REQUEST_TYPE_RESET) ret = hw_ops->reset(cd, GOODIX_NORMAL_RESET_DELAY_MS); else if (ts_event->request_code == REQUEST_TYPE_UPDATE) - ret = goodix_do_fw_update( - NULL, UPDATE_MODE_FORCE | UPDATE_MODE_BLOCK | - UPDATE_MODE_SRC_REQUEST); + ret = goodix_do_fw_update(cd, UPDATE_MODE_FORCE | UPDATE_MODE_BLOCK | + UPDATE_MODE_SRC_REQUEST); else if (ts_event->request_code == REQUEST_PEN_FREQ_HOP) ret = goodix_update_pen_freq(cd, ts_event->request_data, sizeof(ts_event->request_data)); @@ -1949,7 +1719,6 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data) { struct goodix_ts_core *core_data = data; struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops; - struct goodix_ext_module *ext_module, *next; struct goodix_ts_event *ts_event = &core_data->ts_event; struct goodix_ts_esd *ts_esd = &core_data->ts_esd; int ret; @@ -1962,29 +1731,18 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data) } #endif - /* +/* [GOOG] + * Remove the control to enable/disable the interrupt for bottom-half. + disable_irq_nosync(core_data->irq); + */ + + /* [GOOG] * Since we received an interrupt from touch firmware, it means touch * firmware is still alive. So skip esd check once. */ ts_esd->skip_once = true; core_data->irq_trig_cnt++; - /* inform external module */ - mutex_lock(&goodix_modules.mutex); - list_for_each_entry_safe(ext_module, next, &goodix_modules.head, list) - { - if (!ext_module->funcs->irq_event) - continue; - ret = ext_module->funcs->irq_event(core_data, ext_module); - if (ret == EVT_CANCEL_IRQEVT) { - mutex_unlock(&goodix_modules.mutex); -#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) && IS_ENABLED(CONFIG_GTI_PM) - goog_pm_wake_unlock_nosync(core_data->gti, GTI_PM_WAKELOCK_TYPE_IRQ); -#endif - return IRQ_HANDLED; - } - } - mutex_unlock(&goodix_modules.mutex); /* read touch data from touch device */ ret = hw_ops->event_handler(core_data, ts_event); @@ -2012,10 +1770,16 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data) goodix_ts_request_handle(core_data, ts_event); if (ts_event->event_type & EVENT_STATUS) goodix_ts_report_status(core_data, ts_event); + if (ts_event->event_type & EVENT_GESTURE) + goodix_ts_report_gesture(core_data, ts_event); /* read done */ - hw_ops->after_event_handler(core_data); + hw_ops->after_event_handler(core_data); /* [GOOG] */ } +/* [GOOG] + * Remove the control to enable/disable the interrupt for bottom-half. + enable_irq(core_data->irq); + */ #if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) && IS_ENABLED(CONFIG_GTI_PM) goog_pm_wake_unlock_nosync(core_data->gti, GTI_PM_WAKELOCK_TYPE_IRQ); @@ -2240,6 +2004,7 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data) { struct goodix_ts_board_data *ts_bdata = board_data(core_data); struct input_dev *input_dev = NULL; + int dev_id = core_data->pdev->id; int r; input_dev = input_allocate_device(); @@ -2248,12 +2013,15 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data) return -ENOMEM; } - input_dev->name = GOODIX_CORE_DRIVER_NAME; - input_dev->phys = GOOIDX_INPUT_PHYS; - input_dev->uniq = "goodix_ts"; - input_dev->id.product = 0xDEAD; - input_dev->id.vendor = 0xBEEF; - input_dev->id.version = 10427; + sprintf(core_data->input_name, "%s%d", GOODIX_CORE_DRIVER_NAME, dev_id); + input_dev->dev.parent = &core_data->pdev->dev; /* [GOOG] */ + input_dev->name = core_data->input_name; + input_dev->uniq = input_dev->name; + input_dev->phys = input_dev->name; + input_dev->id.bustype = core_data->bus->bus_type; + input_dev->id.product = 0x0100 + dev_id; + input_dev->id.vendor = 0x27C6; + input_dev->id.version = 0x0100; set_bit(EV_SYN, input_dev->evbit); set_bit(EV_KEY, input_dev->evbit); @@ -2302,6 +2070,7 @@ static int goodix_ts_pen_dev_config(struct goodix_ts_core *core_data) { struct goodix_ts_board_data *ts_bdata = board_data(core_data); struct input_dev *pen_dev = NULL; + int dev_id = core_data->pdev->id; int r; pen_dev = input_allocate_device(); @@ -2310,12 +2079,15 @@ static int goodix_ts_pen_dev_config(struct goodix_ts_core *core_data) return -ENOMEM; } - pen_dev->name = GOODIX_PEN_DRIVER_NAME; - pen_dev->phys = "goodix_ts,pen/input0"; - pen_dev->uniq = "goodix_ts,pen"; - pen_dev->id.product = 0xDEAD; - pen_dev->id.vendor = 0xBEEF; - pen_dev->id.version = 10427; + sprintf(core_data->input_pen_name, "%s%d%s", GOODIX_CORE_DRIVER_NAME, dev_id, ",pen"); + pen_dev->dev.parent = &core_data->pdev->dev; /* [GOOG] */ + pen_dev->name = core_data->input_pen_name; + pen_dev->uniq = pen_dev->name; + pen_dev->phys = pen_dev->name; + pen_dev->id.bustype = core_data->bus->bus_type; + pen_dev->id.product = 0x0200 + dev_id; + pen_dev->id.vendor = 0x27C6; + pen_dev->id.version = 0x0100; pen_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); set_bit(ABS_X, pen_dev->absbit); @@ -2362,7 +2134,7 @@ void goodix_ts_pen_dev_remove(struct goodix_ts_core *core_data) { if (!core_data->pen_dev) return; - mutex_destroy(&goodix_ble_data.lock); + mutex_destroy(&core_data->ble_data.lock); input_unregister_device(core_data->pen_dev); core_data->pen_dev = NULL; } @@ -2420,7 +2192,7 @@ exit: /** * goodix_ts_esd_on - turn on esd protection */ -static void goodix_ts_esd_on(struct goodix_ts_core *cd) +void goodix_ts_esd_on(struct goodix_ts_core *cd) { struct goodix_ic_info_misc *misc = &cd->ic_info.misc; struct goodix_ts_esd *ts_esd = &cd->ts_esd; @@ -2441,7 +2213,7 @@ static void goodix_ts_esd_on(struct goodix_ts_core *cd) /** * goodix_ts_esd_off - turn off esd protection */ -static void goodix_ts_esd_off(struct goodix_ts_core *cd) +void goodix_ts_esd_off(struct goodix_ts_core *cd) { struct goodix_ts_esd *ts_esd = &cd->ts_esd; int ret; @@ -2455,40 +2227,6 @@ static void goodix_ts_esd_off(struct goodix_ts_core *cd) } /** - * goodix_esd_notifier_callback - notification callback - * under certain condition, we need to turn off/on the esd - * protector, we use kernel notify call chain to achieve this. - * - * for example: before firmware update we need to turn off the - * esd protector and after firmware update finished, we should - * turn on the esd protector. - */ -static int goodix_esd_notifier_callback( - struct notifier_block *nb, unsigned long action, void *data) -{ - struct goodix_ts_esd *ts_esd = - container_of(nb, struct goodix_ts_esd, esd_notifier); - - switch (action) { - case NOTIFY_FWUPDATE_START: - case NOTIFY_SUSPEND: - case NOTIFY_ESD_OFF: - goodix_ts_esd_off(ts_esd->ts_core); - break; - case NOTIFY_FWUPDATE_FAILED: - case NOTIFY_FWUPDATE_SUCCESS: - case NOTIFY_RESUME: - case NOTIFY_ESD_ON: - goodix_ts_esd_on(ts_esd->ts_core); - break; - default: - break; - } - - return 0; -} - -/** * goodix_ts_esd_init - initialize esd protection */ int goodix_ts_esd_init(struct goodix_ts_core *cd) @@ -2504,8 +2242,6 @@ int goodix_ts_esd_init(struct goodix_ts_core *cd) INIT_DELAYED_WORK(&ts_esd->esd_work, goodix_ts_esd_work); ts_esd->ts_core = cd; atomic_set(&ts_esd->esd_on, 0); - ts_esd->esd_notifier.notifier_call = goodix_esd_notifier_callback; - goodix_ts_register_notifier(&ts_esd->esd_notifier); goodix_ts_esd_on(cd); return 0; @@ -2516,10 +2252,13 @@ void goodix_ts_esd_uninit(struct goodix_ts_core *cd) struct goodix_ts_esd *ts_esd = &cd->ts_esd; if (atomic_read(&ts_esd->esd_on)) goodix_ts_esd_off(cd); - goodix_ts_unregister_notifier(&ts_esd->esd_notifier); } -#if !IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) +#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) +static void goodix_ts_release_connects(struct goodix_ts_core *core_data) +{ +} +#else static void goodix_ts_release_connects(struct goodix_ts_core *core_data) { struct input_dev *input_dev = core_data->input_dev; @@ -2545,9 +2284,7 @@ static void goodix_ts_release_connects(struct goodix_ts_core *core_data) */ static int goodix_ts_suspend(struct goodix_ts_core *core_data) { - struct goodix_ext_module *ext_module, *next; struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops; - int ret; if (core_data->init_stage < CORE_INIT_STAGE2 || atomic_read(&core_data->suspended)) @@ -2557,68 +2294,23 @@ static int goodix_ts_suspend(struct goodix_ts_core *core_data) atomic_set(&core_data->suspended, 1); /* disable irq */ hw_ops->disable_irq_nosync(core_data); + goodix_ts_esd_off(core_data); - /* - * notify suspend event, inform the esd protector - * and charger detector to turn off the work - */ - goodix_ts_blocking_notify(NOTIFY_SUSPEND, NULL); - - /* inform external module */ - mutex_lock(&goodix_modules.mutex); - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (!ext_module->funcs->before_suspend) - continue; - - ret = ext_module->funcs->before_suspend( - core_data, ext_module); - if (ret == EVT_CANCEL_SUSPEND) { - mutex_unlock(&goodix_modules.mutex); - ts_info("Canceled by module:%s", - ext_module->name); - goto out; - } - } - } - mutex_unlock(&goodix_modules.mutex); - - /* enter sleep mode or power off */ - if (core_data->board_data.sleep_enable) - hw_ops->suspend(core_data); - else - goodix_ts_power_off(core_data); - - /* inform exteranl modules */ - mutex_lock(&goodix_modules.mutex); - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (!ext_module->funcs->after_suspend) - continue; - - ret = ext_module->funcs->after_suspend( - core_data, ext_module); - if (ret == EVT_CANCEL_SUSPEND) { - mutex_unlock(&goodix_modules.mutex); - ts_info("Canceled by module:%s", - ext_module->name); - goto out; - } - } + if (core_data->gesture_type) { + /* enter gesture mode */ + hw_ops->gesture(core_data, 0); + hw_ops->irq_enable(core_data, true); + enable_irq_wake(core_data->irq); + } else { + /* enter sleep mode or power off */ + if (core_data->board_data.sleep_enable) + hw_ops->suspend(core_data); + else + goodix_ts_power_off(core_data); } - mutex_unlock(&goodix_modules.mutex); - - goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND); - -out: -#if !IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) goodix_ts_release_connects(core_data); -#endif + goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND); /* [GOOG] */ ts_info("Suspend end"); return 0; } @@ -2674,80 +2366,49 @@ static void monitor_gesture_event(struct work_struct *work) */ static int goodix_ts_resume(struct goodix_ts_core *core_data) { - struct goodix_ext_module *ext_module, *next; struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops; - struct goodix_gesture_data* gesture_data = &core_data->ts_event.gesture_data; - int ret; - if (core_data->init_stage < CORE_INIT_STAGE2 || !atomic_read(&core_data->suspended)) return 0; ts_info("Resume start"); - goodix_set_pinctrl_state(core_data, PINCTRL_MODE_ACTIVE); + goodix_set_pinctrl_state(core_data, PINCTRL_MODE_ACTIVE); /* [GOOG] */ atomic_set(&core_data->suspended, 0); hw_ops->irq_enable(core_data, false); - mutex_lock(&goodix_modules.mutex); - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (!ext_module->funcs->before_resume) - continue; - - ret = ext_module->funcs->before_resume( - core_data, ext_module); - if (ret == EVT_CANCEL_RESUME) { - mutex_unlock(&goodix_modules.mutex); - ts_info("Canceled by module:%s", - ext_module->name); - goto out; - } - } - } - mutex_unlock(&goodix_modules.mutex); - + /* [GOOG] */ if (check_gesture_mode(core_data)) { + struct goodix_gesture_data *gesture_data = + &core_data->ts_event.gesture_data; + gesture_data->gesture_type = GOODIX_GESTURE_UNKNOWN; core_data->gesture_down_timeout = ktime_add_ms(ktime_get(), 100); core_data->gesture_up_timeout = ktime_add_ms(ktime_get(), 200); queue_delayed_work(core_data->event_wq, &core_data->monitor_gesture_work, msecs_to_jiffies(5)); } else { - /* reset device or power on*/ - if (core_data->board_data.sleep_enable) + if (core_data->gesture_type) { + disable_irq_wake(core_data->irq); hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS); - else - goodix_ts_power_on(core_data); - } - - mutex_lock(&goodix_modules.mutex); - if (!list_empty(&goodix_modules.head)) { - list_for_each_entry_safe( - ext_module, next, &goodix_modules.head, list) - { - if (!ext_module->funcs->after_resume) - continue; - - ret = ext_module->funcs->after_resume( - core_data, ext_module); - if (ret == EVT_CANCEL_RESUME) { - mutex_unlock(&goodix_modules.mutex); - ts_info("Canceled by module:%s", - ext_module->name); - goto out; + } else { + /* [GOOG] + * Force to reset T-IC as touch resume process instead using brl_resume(). + */ + /* reset device or power on*/ + if (core_data->board_data.sleep_enable) { + hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS); + //hw_ops->resume(core_data); /* [GOOG] */ + } else { + goodix_ts_power_on(core_data); } } } - mutex_unlock(&goodix_modules.mutex); -out: /* enable irq */ hw_ops->irq_enable(core_data, true); /* open esd */ - goodix_ts_blocking_notify(NOTIFY_RESUME, NULL); + goodix_ts_esd_on(core_data); ts_info("Resume end"); return 0; } @@ -2804,37 +2465,6 @@ static int goodix_ts_pm_resume(struct device *dev) #endif #endif -/** - * goodix_generic_noti_callback - generic notifier callback - * for goodix touch notification event. - */ -static int goodix_generic_noti_callback( - struct notifier_block *self, unsigned long action, void *data) -{ - struct goodix_ts_core *cd = - container_of(self, struct goodix_ts_core, ts_notifier); - const struct goodix_ts_hw_ops *hw_ops = cd->hw_ops; - - if (cd->init_stage < CORE_INIT_STAGE2) - return 0; - - ts_info("notify event type 0x%x", (unsigned int)action); - switch (action) { - case NOTIFY_FWUPDATE_START: - hw_ops->irq_enable(cd, 0); - break; - case NOTIFY_FWUPDATE_SUCCESS: - case NOTIFY_FWUPDATE_FAILED: - if (hw_ops->read_version(cd, &cd->fw_version)) - ts_info("failed read fw version info[ignore]"); - hw_ops->irq_enable(cd, 1); - break; - default: - break; - } - return 0; -} - int goodix_ts_stage2_init(struct goodix_ts_core *cd) { int ret; @@ -2866,7 +2496,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) ts_err("failed set pen device"); goto err_finger; } - mutex_init(&goodix_ble_data.lock); + mutex_init(&cd->ble_data.lock); } #if IS_ENABLED(CONFIG_FB) @@ -2978,7 +2608,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) #if IS_ENABLED(CONFIG_GOODIX_GESTURE) /* gesture init */ - ret = gesture_module_init(); + ret = gesture_module_init(cd); if (ret < 0) { ts_err("failed set init gesture"); goto err_init_gesture; @@ -2986,12 +2616,18 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) #endif /* inspect init */ - ret = inspect_module_init(); + ret = inspect_module_init(cd); if (ret < 0) { ts_err("failed set init inspect"); goto err_init_inspect; } +/* + * [GOOG] + * Touch frame package will read into `struct goodix_rx_package`. + * The total read size for SPI is `touch_frame_size` + 8 bytes(SPI prefix header). + * Therefore, `touch_frame_package` will need to allocate 8 extra bytes for SPI I/O. + */ cd->touch_frame_size = touch_frame_size; cd->touch_frame_package = devm_kzalloc(&cd->pdev->dev, touch_frame_size + 8, GFP_KERNEL); @@ -3027,6 +2663,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) ret = -ENOMEM; goto err_setup_irq; } +/*~[GOOG]*/ /* request irq line */ ret = goodix_ts_irq_setup(cd); @@ -3039,10 +2676,10 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) return 0; err_setup_irq: - inspect_module_exit(); + inspect_module_exit(cd); err_init_inspect: #if IS_ENABLED(CONFIG_GOODIX_GESTURE) - gesture_module_exit(); + gesture_module_exit(cd); err_init_gesture: #endif goodix_ts_esd_uninit(cd); @@ -3120,10 +2757,16 @@ static int goodix_later_init_thread(void *data) if (ret < 0) { ts_err("failed to get version info, try to upgrade"); update_flag |= UPDATE_MODE_FORCE; - goto upgrade; } - /* step 2: get config data from config bin */ + /* step 2: read ic info */ + ret = hw_ops->get_ic_info(cd, &cd->ic_info); + if (ret < 0) { + ts_err("failed to get ic info, try to upgrade"); + update_flag |= UPDATE_MODE_FORCE; + } + + /* step 3: get config data from config bin */ ret = goodix_get_config_proc(cd); if (ret < 0) ts_info("no valid ic config found"); @@ -3132,35 +2775,20 @@ static int goodix_later_init_thread(void *data) else ts_info("one binary, no need find config"); -upgrade: - /* step 3: init fw struct add try do fw upgrade */ + /* step 4: init fw struct add try do fw upgrade */ ret = goodix_fw_update_init(cd); if (ret) { ts_err("failed init fw update module"); goto err_out; } + /* step 5: do upgrade */ ts_info("update flag: 0x%X", update_flag); - ret = goodix_do_fw_update( - cd->ic_configs[CONFIG_TYPE_NORMAL], update_flag); + ret = goodix_do_fw_update(cd, update_flag); if (ret) ts_err("failed do fw update"); - /* step 4: get fw version and ic_info - * at this step we believe that the ic is in normal mode, - * if the version info is invalid there must have some - * problem we cann't cover so exit init directly. - */ - ret = hw_ops->read_version(cd, &cd->fw_version); - if (ret) { - ts_err("invalid fw version, abort"); - goto uninit_fw; - } - ret = hw_ops->get_ic_info(cd, &cd->ic_info); - if (ret) { - ts_err("invalid ic info, abort"); - goto uninit_fw; - } + print_ic_info(&cd->ic_info); /* the recommend way to update ic config is throuth ISP, * if not we will send config with interactive mode @@ -3178,7 +2806,7 @@ upgrade: return 0; uninit_fw: - goodix_fw_update_uninit(); + goodix_fw_update_uninit(cd); err_out: ts_err("stage2 init failed"); cd->init_stage = CORE_INIT_FAIL; @@ -3220,25 +2848,16 @@ static int goodix_start_later_init(struct goodix_ts_core *ts_core) */ static int goodix_ts_probe(struct platform_device *pdev) { - struct goodix_ts_core *core_data = NULL; + struct goodix_device_resource *dev_res = + container_of(pdev, struct goodix_device_resource, pdev); + struct goodix_ts_core *core_data; struct goodix_bus_interface *bus_interface; int ret; ts_info("IN"); - bus_interface = pdev->dev.platform_data; - if (!bus_interface) { - ts_err("Invalid touch device"); - core_module_prob_sate = CORE_MODULE_PROB_FAILED; - return -ENODEV; - } - - core_data = devm_kzalloc( - &pdev->dev, sizeof(struct goodix_ts_core), GFP_KERNEL); - if (!core_data) { - core_module_prob_sate = CORE_MODULE_PROB_FAILED; - return -ENOMEM; - } + core_data = &dev_res->core_data; + bus_interface = &dev_res->bus; if (IS_ENABLED(CONFIG_OF) && bus_interface->dev->of_node) { /* parse devicetree property */ @@ -3256,11 +2875,10 @@ static int goodix_ts_probe(struct platform_device *pdev) core_data->hw_ops = goodix_get_hw_ops(); if (!core_data->hw_ops) { ts_err("hw ops is NULL"); - core_module_prob_sate = CORE_MODULE_PROB_FAILED; return -EINVAL; } mutex_init(&core_data->cmd_lock); - goodix_core_module_init(); + /* touch core layer is a platform driver */ core_data->pdev = pdev; core_data->bus = bus_interface; @@ -3298,12 +2916,8 @@ static int goodix_ts_probe(struct platform_device *pdev) goto err_setup_gpio; } - /* generic notifier callback */ - core_data->ts_notifier.notifier_call = goodix_generic_noti_callback; - goodix_ts_register_notifier(&core_data->ts_notifier); - /* debug node init */ - ret = goodix_tools_init(); + ret = goodix_tools_init(core_data); if (ret) { ts_err("failed init tools"); goto err_init_tools; @@ -3313,8 +2927,6 @@ static int goodix_ts_probe(struct platform_device *pdev) // fb_firefly_register(test_suspend, test_resume); core_data->init_stage = CORE_INIT_STAGE1; - goodix_modules.core_data = core_data; - core_module_prob_sate = CORE_MODULE_PROB_SUCCESS; /* Try start a thread to get config-bin info */ ret = goodix_start_later_init(core_data); @@ -3327,16 +2939,14 @@ static int goodix_ts_probe(struct platform_device *pdev) return 0; err_start_late_init: - goodix_tools_exit(); + goodix_tools_exit(core_data); err_init_tools: - goodix_ts_unregister_notifier(&core_data->ts_notifier); goodix_ts_power_off(core_data); err_setup_gpio: goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND); err_out: mutex_destroy(&core_data->cmd_lock); core_data->init_stage = CORE_INIT_FAIL; - core_module_prob_sate = CORE_MODULE_PROB_FAILED; ts_err("goodix_ts_core failed, ret:%d", ret); return ret; } @@ -3345,38 +2955,45 @@ static int goodix_ts_remove(struct platform_device *pdev) { struct goodix_ts_core *core_data = platform_get_drvdata(pdev); struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops; + struct goodix_ts_esd *ts_esd = &core_data->ts_esd; + if (core_data->init_stage >= CORE_INIT_STAGE2) { +/* [GOOG] + * Follow the reversed order of probe() to release resources. + */ hw_ops->irq_enable(core_data, false); - inspect_module_exit(); + + /* goodix_ts_stage2_init() */ + inspect_module_exit(core_data); #if IS_ENABLED(CONFIG_GOODIX_GESTURE) - gesture_module_exit(); + gesture_module_exit(core_data); #endif - core_module_prob_sate = CORE_MODULE_REMOVED; - goodix_ts_esd_uninit(core_data); + if (atomic_read(&ts_esd->esd_on)) + goodix_ts_esd_off(core_data); goodix_ts_procfs_exit(core_data); - #if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) #if IS_ENABLED(CONFIG_GTI_PM) goog_pm_unregister_notification(core_data->gti); #endif + goog_touch_interface_remove(core_data->gti); destroy_workqueue(core_data->event_wq); touch_apis_deinit(&core_data->pdev->dev); - goog_touch_interface_remove(core_data->gti); - goodix_ts_sysfs_exit(core_data); #endif + goodix_ts_sysfs_exit(core_data); #if IS_ENABLED(CONFIG_FB) fb_unregister_client(&core_data->fb_notifier); #endif goodix_ts_pen_dev_remove(core_data); goodix_ts_input_dev_remove(core_data); - - goodix_fw_update_uninit(); + /* goodix_later_init_thread() */ + goodix_fw_update_uninit(core_data); } - goodix_tools_exit(); - goodix_ts_unregister_notifier(&core_data->ts_notifier); + /* goodix_ts_probe() */ + goodix_tools_exit(core_data); goodix_ts_power_off(core_data); +/*~[GOOG] */ goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND); mutex_destroy(&core_data->cmd_lock); @@ -3416,15 +3033,23 @@ static int __init goodix_ts_core_init(void) int ret; ts_info("Core layer init:%s", GOODIX_DRIVER_VERSION); + goodix_device_manager_init(); + #ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_SPI ret = goodix_spi_bus_init(); -#else - ret = goodix_i2c_bus_init(); + if (ret) { + ts_err("failed add spi bus driver"); + return ret; + } #endif +#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_I2C + ret = goodix_i2c_bus_init(); if (ret) { - ts_err("failed add bus driver"); + ts_err("failed add i2c bus driver"); return ret; } +#endif + return platform_driver_register(&goodix_ts_driver); } @@ -3434,9 +3059,11 @@ static void __exit goodix_ts_core_exit(void) platform_driver_unregister(&goodix_ts_driver); #ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_SPI goodix_spi_bus_exit(); -#else +#endif +#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_I2C goodix_i2c_bus_exit(); #endif + goodix_device_manager_exit(); } late_initcall(goodix_ts_core_init); |