summaryrefslogtreecommitdiff
path: root/goodix_ts_core.c
diff options
context:
space:
mode:
authorSuper Liu <supercjliu@google.com>2023-04-06 05:19:59 +0000
committerSuper Liu <supercjliu@google.com>2023-04-06 08:02:14 +0000
commit8da5744724d93c45251f91a2f09c5420de8da65c (patch)
tree9d21ed3b371727a1e000b8b5fb1e0644c67a4c11 /goodix_ts_core.c
parenta17332d87e6dd4f008e9575cb2f5a15fffa24fe9 (diff)
downloadgoodix_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.c875
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);