From c67f5d4ade216fb78652c7aa90cb9ca1fda5accb Mon Sep 17 00:00:00 2001 From: litong20 Date: Tue, 7 Sep 2021 18:31:10 +0800 Subject: [PATCH] Support touchscreen calss in the goodix drvier code. TP: Add initial support for touchscreen calss in the goodix drvier code. Change-Id: I056be5b1d6f5f92493a77c237727a5ee9eeb4e11 Reviewed-on: https://gerrit.mot.com/2038606 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jichao Zou Submit-Approved: Jira Key --- .../touchscreen/goodix_berlin_mmi/Android.mk | 8 + .../touchscreen/goodix_berlin_mmi/Kbuild | 9 + .../touchscreen/goodix_berlin_mmi/Makefile | 1 + .../goodix_berlin_mmi/goodix_brl_fwupdate.c | 14 +- .../goodix_berlin_mmi/goodix_brl_hw.c | 23 +- .../goodix_berlin_mmi/goodix_brl_i2c.c | 3 + .../goodix_berlin_mmi/goodix_cfg_bin.c | 2 +- .../goodix_berlin_mmi/goodix_ts_core.c | 44 ++- .../goodix_berlin_mmi/goodix_ts_core.h | 18 +- .../goodix_berlin_mmi/goodix_ts_inspect.c | 2 +- .../goodix_berlin_mmi/goodix_ts_mmi.c | 333 ++++++++++++++++++ .../goodix_berlin_mmi/goodix_ts_mmi.h | 21 ++ 12 files changed, 456 insertions(+), 22 deletions(-) create mode 100644 drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c create mode 100644 drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/Android.mk b/drivers/input/touchscreen/goodix_berlin_mmi/Android.mk index 301229b79490..724805ab3f68 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/Android.mk +++ b/drivers/input/touchscreen/goodix_berlin_mmi/Android.mk @@ -1,10 +1,18 @@ DLKM_DIR := motorola/kernel/modules LOCAL_PATH := $(call my-dir) +ifeq ($(DRM_PANEL_EVENT_NOTIFICATIONS),true) + KBUILD_OPTIONS += CONFIG_DRM_PANEL_EVENT_NOTIFICATIONS=y +endif + include $(CLEAR_VARS) LOCAL_MODULE := goodix_brl_mmi.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/mmi_info.ko +ifneq ($(findstring touchscreen_mmi.ko,$(BOARD_VENDOR_KERNEL_MODULES)),) + KBUILD_OPTIONS += CONFIG_INPUT_TOUCHSCREEN_MMI=y + LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/touchscreen_mmi.ko +endif KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki include $(DLKM_DIR)/AndroidKernelModule.mk diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/Kbuild b/drivers/input/touchscreen/goodix_berlin_mmi/Kbuild index aba626bc5169..4a19ecfe198a 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/Kbuild +++ b/drivers/input/touchscreen/goodix_berlin_mmi/Kbuild @@ -15,3 +15,12 @@ goodix_brl_mmi-objs := \ goodix_ts_gesture.o \ goodix_ts_inspect.o \ goodix_ts_tools.o + +ifneq ($(filter m y, $(CONFIG_DRM_PANEL_EVENT_NOTIFICATIONS)),) + EXTRA_CFLAGS += -DCONFIG_DRM_PANEL_EVENT_NOTIFICATIONS +endif + +ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_MMI)),) + EXTRA_CFLAGS += -DCONFIG_INPUT_TOUCHSCREEN_MMI + goodix_brl_mmi-objs += goodix_ts_mmi.o +endif diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/Makefile b/drivers/input/touchscreen/goodix_berlin_mmi/Makefile index c5b68ebf0326..ff20fa5e17dd 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/Makefile +++ b/drivers/input/touchscreen/goodix_berlin_mmi/Makefile @@ -14,3 +14,4 @@ clean: rm -rf .tmp_versions KBUILD_EXTRA_SYMBOLS += $(M)/../../../mmi_info/$(GKI_OBJ_MODULE_DIR)/Module.symvers +KBUILD_EXTRA_SYMBOLS += $(M)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_fwupdate.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_fwupdate.c index 726ea76d00ad..967ead7e608d 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_fwupdate.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_fwupdate.c @@ -266,6 +266,16 @@ struct fw_update_ctrl { }; static struct fw_update_ctrl goodix_fw_update_ctrl; +static int goodix_set_fwname(char* fw_name) { + if (fw_name != NULL) { + strlcpy(goodix_fw_update_ctrl.fw_name, fw_name, + sizeof(goodix_fw_update_ctrl.fw_name)); + return 0; + } + else + return -EINVAL; +} + static int goodix_fw_update_reset(int delay) { struct goodix_ts_hw_ops *hw_ops; @@ -280,7 +290,7 @@ static int get_fw_version_info(struct goodix_fw_version *fw_version) goodix_fw_update_ctrl.core_data->hw_ops; return hw_ops->read_version(goodix_fw_update_ctrl.core_data, - fw_version); + fw_version, true); } static int goodix_reg_write(unsigned int addr, @@ -1366,6 +1376,8 @@ int goodix_fw_update_init(struct goodix_ts_core *core_data) goodix_fw_update_ctrl.core_data = core_data; goodix_fw_update_ctrl.mode = 0; + core_data->set_fw_name = goodix_set_fwname; + strlcpy(goodix_fw_update_ctrl.fw_name, core_data->board_data.fw_name, sizeof(goodix_fw_update_ctrl.fw_name)); diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c index c7b04b1f0ea3..6b2bb73199c5 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_hw.c @@ -645,7 +645,7 @@ exit: * in this case the sensorID is valid. */ static int brl_read_version(struct goodix_ts_core *cd, - struct goodix_fw_version *version) + struct goodix_fw_version *version, bool dbg_on) { int ret, i; u32 fw_addr; @@ -681,13 +681,15 @@ static int brl_read_version(struct goodix_ts_core *cd, } memcpy(version, buf, sizeof(*version)); memcpy(temp_pid, version->rom_pid, sizeof(version->rom_pid)); - ts_info("rom_pid:%s", temp_pid); - ts_info("rom_vid:%*ph", (int)sizeof(version->rom_vid), - version->rom_vid); - ts_info("pid:%s", version->patch_pid); - ts_info("vid:%*ph", (int)sizeof(version->patch_vid), - version->patch_vid); - ts_info("sensor_id:%d", version->sensor_id); + if (dbg_on) { + ts_info("rom_pid:%s", temp_pid); + ts_info("rom_vid:%*ph", (int)sizeof(version->rom_vid), + version->rom_vid); + ts_info("pid:%s", version->patch_pid); + ts_info("vid:%*ph", (int)sizeof(version->patch_vid), + version->patch_vid); + ts_info("sensor_id:%d", version->sensor_id); + } return 0; } @@ -894,7 +896,7 @@ static void print_ic_info(struct goodix_ic_info *ic_info) } static int brl_get_ic_info(struct goodix_ts_core *cd, - struct goodix_ic_info *ic_info) + struct goodix_ic_info *ic_info, bool dbg_on) { int ret, i; u16 length = 0; @@ -953,7 +955,8 @@ static int brl_get_ic_info(struct goodix_ts_core *cd, return ret; } - print_ic_info(ic_info); + if (dbg_on) + print_ic_info(ic_info); /* check some key info */ if (!ic_info->misc.cmd_addr || !ic_info->misc.fw_buffer_addr || diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_i2c.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_i2c.c index 923589a43c33..f9fe3e71c206 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_i2c.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_brl_i2c.c @@ -196,6 +196,8 @@ static int goodix_i2c_probe(struct i2c_client *client, if (!goodix_pdev) return -ENOMEM; + i2c_set_clientdata(client, goodix_pdev); + goodix_pdev->name = GOODIX_CORE_DRIVER_NAME; goodix_pdev->id = 0; goodix_pdev->num_resources = 0; @@ -219,6 +221,7 @@ static int goodix_i2c_probe(struct i2c_client *client, return ret; err_pdev: + i2c_set_clientdata(client, NULL); kfree(goodix_pdev); goodix_pdev = NULL; ts_info("i2c probe out, %d", ret); diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_cfg_bin.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_cfg_bin.c index 838e70652827..aa695dbde99a 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_cfg_bin.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_cfg_bin.c @@ -323,7 +323,7 @@ err_out: int goodix_get_config_proc(struct goodix_ts_core *cd) { - if (cd->hw_ops->read_version(cd, &cd->fw_version)) { + if (cd->hw_ops->read_version(cd, &cd->fw_version, true)) { ts_info("version info abnormal, abort"); return -EINVAL; } diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c index c7846c7c7345..7b4d6a482ead 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c @@ -26,6 +26,7 @@ #endif #include "goodix_ts_core.h" +#include "goodix_ts_mmi.h" #define PINCTRL_STATE_ACTIVE "pmx_ts_active" #define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" @@ -294,7 +295,7 @@ static ssize_t goodix_ts_chip_info_show(struct device *dev, int cnt = -EINVAL; if (hw_ops->read_version) { - ret = hw_ops->read_version(core_data, &chip_ver); + ret = hw_ops->read_version(core_data, &chip_ver, true); if (!ret) { memcpy(temp_pid, chip_ver.rom_pid, sizeof(chip_ver.rom_pid)); cnt = snprintf(&buf[0], PAGE_SIZE, @@ -312,7 +313,7 @@ static ssize_t goodix_ts_chip_info_show(struct device *dev, } if (hw_ops->get_ic_info) { - ret = hw_ops->get_ic_info(core_data, &core_data->ic_info); + ret = hw_ops->get_ic_info(core_data, &core_data->ic_info, true); if (!ret) { cnt += snprintf(&buf[cnt], PAGE_SIZE, "config_id:%x\n", core_data->ic_info.version.config_id); @@ -1060,6 +1061,15 @@ static int goodix_parse_dt(struct device_node *node, return r; } + /* get ic compatible */ + r = of_property_read_string(node, "compatible", &name_tmp); + if (r) { + ts_err("get compatible failed"); + return r; + } else { + ts_info("ic_name form dt: %s", name_tmp); + strncpy(board_data->ic_name, name_tmp, sizeof(board_data->ic_name)); + } /*get pen-enable switch and pen keys, must after "key map"*/ board_data->pen_enable = of_property_read_bool(node, @@ -1711,7 +1721,7 @@ int goodix_ts_esd_init(struct goodix_ts_core *cd) return 0; } -static void goodix_ts_release_connects(struct goodix_ts_core *core_data) +void goodix_ts_release_connects(struct goodix_ts_core *core_data) { struct input_dev *input_dev = core_data->input_dev; int i; @@ -1940,6 +1950,7 @@ static int goodix_generic_noti_callback(struct notifier_block *self, 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; + int ret = 0; if (cd->init_stage < CORE_INIT_STAGE2) return 0; @@ -1947,13 +1958,21 @@ static int goodix_generic_noti_callback(struct notifier_block *self, ts_info("notify event type 0x%x", (unsigned int)action); switch (action) { case NOTIFY_FWUPDATE_START: + cd->update_status = 1; hw_ops->irq_enable(cd, 0); break; case NOTIFY_FWUPDATE_SUCCESS: + ret = hw_ops->get_ic_info(cd, &cd->ic_info, true); + if (ret) + ts_err("invalid ic info [ignore]"); + ret = goodix_send_ic_config(cd, CONFIG_TYPE_NORMAL); + if (ret) + ts_info("failed send normal config[ignore]"); case NOTIFY_FWUPDATE_FAILED: - if (hw_ops->read_version(cd, &cd->fw_version)) + if (hw_ops->read_version(cd, &cd->fw_version, true)) ts_info("failed read fw version info[ignore]"); hw_ops->irq_enable(cd, 1); + cd->update_status = 0; break; default: break; @@ -1998,8 +2017,10 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd) /* create procfs files */ goodix_ts_procfs_init(cd); +#ifdef GOODIX_ESD_ENABLE /* esd protector */ goodix_ts_esd_init(cd); +#endif /* gesture init */ gesture_module_init(); @@ -2068,21 +2089,23 @@ static int goodix_later_init_thread(void *data) goto err_out; } +#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI ret = goodix_do_fw_update(cd->ic_configs[CONFIG_TYPE_NORMAL], UPDATE_MODE_BLOCK | UPDATE_MODE_SRC_REQUEST); if (ret) ts_err("failed do fw update"); +#endif /* setp3: 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); + ret = hw_ops->read_version(cd, &cd->fw_version, true); if (ret) { ts_err("invalid fw version, abort"); goto uninit_fw; } - ret = hw_ops->get_ic_info(cd, &cd->ic_info); + ret = hw_ops->get_ic_info(cd, &cd->ic_info, true); if (ret) { ts_err("invalid ic info, abort"); goto uninit_fw; @@ -2231,6 +2254,15 @@ static int goodix_ts_probe(struct platform_device *pdev) /* debug node init */ goodix_tools_init(); +#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI + ts_info("%s:goodix_ts_mmi_dev_register",__func__); + ret = goodix_ts_mmi_dev_register(pdev); + if (ret) { + ts_info("Failed register touchscreen mmi."); + goto err_out; + } +#endif + core_data->init_stage = CORE_INIT_STAGE1; goodix_modules.core_data = core_data; core_module_prob_sate = CORE_MODULE_PROB_SUCCESS; diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h index 6629368a0bf5..12cf23330cae 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h @@ -32,7 +32,7 @@ #define GOODIX_MAX_PEN_KEY 2 #define GOODIX_PEN_MAX_TILT 90 #define GOODIX_CFG_MAX_SIZE 4096 -#define GOODIX_MAX_STR_LABLE_LEN 32 +#define GOODIX_MAX_STR_LABLE_LEN 64 #define GOODIX_NORMAL_RESET_DELAY_MS 100 #define GOODIX_HOLD_CPU_RESET_DELAY_MS 5 @@ -237,6 +237,7 @@ struct goodix_module { * @fw_name: name of the firmware image */ struct goodix_ts_board_data { + char ic_name[GOODIX_MAX_STR_LABLE_LEN]; char avdd_name[GOODIX_MAX_STR_LABLE_LEN]; char iovdd_name[GOODIX_MAX_STR_LABLE_LEN]; int reset_gpio; @@ -392,8 +393,10 @@ struct goodix_ts_hw_ops { int (*send_cmd)(struct goodix_ts_core *cd, struct goodix_ts_cmd *cmd); int (*send_config)(struct goodix_ts_core *cd, u8 *config, int len); int (*read_config)(struct goodix_ts_core *cd, u8 *config_data, int size); - int (*read_version)(struct goodix_ts_core *cd, struct goodix_fw_version *version); - int (*get_ic_info)(struct goodix_ts_core *cd, struct goodix_ic_info *ic_info); + int (*read_version)(struct goodix_ts_core *cd, + struct goodix_fw_version *version, bool dgb_on); + int (*get_ic_info)(struct goodix_ts_core *cd, + struct goodix_ic_info *ic_info, bool dbg_on); int (*esd_check)(struct goodix_ts_core *cd); int (*event_handler)(struct goodix_ts_core *cd, struct goodix_ts_event *ts_event); int (*after_event_handler)(struct goodix_ts_core *cd); /* clean sync flag */ @@ -463,6 +466,11 @@ struct goodix_ts_core { #ifdef CONFIG_FB struct notifier_block fb_notifier; #endif + + /* touchscreen_mmi */ + int (*set_fw_name)(char* fw_name); + int update_status; + int gesture_enabled; }; /* external module structures */ @@ -618,5 +626,9 @@ int inspect_module_init(void); void inspect_module_exit(void); int goodix_tools_init(void); void goodix_tools_exit(void); +void goodix_ts_release_connects(struct goodix_ts_core *core_data); + +int goodix_ts_power_on(struct goodix_ts_core *cd); +int goodix_ts_power_off(struct goodix_ts_core *cd); #endif diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_inspect.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_inspect.c index 267fff659698..1b171f6d7379 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_inspect.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_inspect.c @@ -343,7 +343,7 @@ static int ts_test_send_config(struct goodix_ts_test *ts_test, static int ts_test_read_version(struct goodix_ts_test *ts_test, struct goodix_fw_version *version) { - return ts_test->ts->hw_ops->read_version(ts_test->ts, version); + return ts_test->ts->hw_ops->read_version(ts_test->ts, version, true); } static void goto_next_line(char **ptr) diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c new file mode 100644 index 000000000000..029a5b783342 --- /dev/null +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2019 Motorola Mobility LLC + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "goodix_ts_mmi.h" +#include + +#define GET_GOODIX_DATA(dev) { \ + pdev = dev_get_drvdata(dev); \ + if (!pdev) { \ + ts_err("Failed to get platform device"); \ + return -ENODEV; \ + } \ + core_data = platform_get_drvdata(pdev); \ + if (!core_data) { \ + ts_err("Failed to get driver data"); \ + return -ENODEV; \ + } \ +} + +extern int goodix_ts_unregister_notifier(struct notifier_block *nb); +extern struct goodix_module goodix_modules; + +static int goodix_ts_mmi_methods_get_vendor(struct device *dev, void *cdata) { + return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "goodix"); +} + +static int goodix_ts_mmi_methods_get_productinfo(struct device *dev, void *cdata) { + int ret; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + struct goodix_fw_version fw_version; + + GET_GOODIX_DATA(dev); + + ret = core_data->hw_ops->read_version(core_data, &fw_version, false); + return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_INFO_LEN, "GT%s", + fw_version.patch_pid); +} + +static int goodix_ts_mmi_methods_get_build_id(struct device *dev, void *cdata) { + int ret; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + ret = core_data->hw_ops->get_ic_info(core_data, &core_data->ic_info, false); + if (!ret) { + ret = snprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, + "%08x", core_data->ic_info.version.config_id); + return ret; + } else + return -EINVAL; +} + +/*return firmware version*/ +static int goodix_ts_mmi_methods_get_config_id(struct device *dev, void *cdata) { + int ret; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + struct goodix_fw_version chip_ver; + + GET_GOODIX_DATA(dev); + ret = core_data->hw_ops->read_version(core_data, &chip_ver, false); + if (!ret) { + ret = snprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, + "%02x%02x", chip_ver.patch_vid[2], chip_ver.patch_vid[3]); + + return ret; + } else + return -EINVAL; +} + +static int goodix_ts_mmi_methods_get_bus_type(struct device *dev, void *idata) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + TO_INT(idata) = core_data->bus->bus_type == GOODIX_BUS_TYPE_I2C ? + TOUCHSCREEN_MMI_BUS_TYPE_I2C : TOUCHSCREEN_MMI_BUS_TYPE_SPI; + return 0; +} + +static int goodix_ts_mmi_methods_get_irq_status(struct device *dev, void *idata) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + struct goodix_ts_board_data *ts_bdata; + + GET_GOODIX_DATA(dev); + + ts_bdata = board_data(core_data); + if (!ts_bdata) { + ts_err("Failed to get ts board data"); + return -ENODEV; + } + TO_INT(idata) = gpio_get_value(ts_bdata->irq_gpio); + return 0; +} + +static int goodix_ts_mmi_methods_get_drv_irq(struct device *dev, void *idata) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + TO_INT(idata) = atomic_read(&core_data->irq_enabled); + return 0; +} + +static int goodix_ts_mmi_methods_get_poweron(struct device *dev, void *idata) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + TO_INT(idata) = core_data->power_on; + return 0; +} + +static int goodix_ts_mmi_methods_get_flashprog(struct device *dev, void *idata) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + TO_INT(idata) = core_data->update_status; + return 0; +} + +static int goodix_ts_mmi_methods_drv_irq(struct device *dev, int state) { + int ret = -ENODEV; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + if (core_data->hw_ops->irq_enable) + ret = core_data->hw_ops->irq_enable(core_data, !(!state)); + + return ret; +} + +/* reset chip + * type:can control software reset and hardware reset, + * but GOODIX has no software reset, + * so the type parameter is not used here. + */ +static int goodix_ts_mmi_methods_reset(struct device *dev, int type) { + int ret = -ENODEV; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + if (core_data->hw_ops->reset) + ret = core_data->hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS); + return ret; +} + +static int goodix_ts_firmware_update(struct device *dev, char *fwname) { + int ret = -ENODEV; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + ts_info("HW request update fw, %s", fwname); + /* set firmware image name */ + if (core_data->set_fw_name) + core_data->set_fw_name(fwname); + + ret = goodix_do_fw_update(NULL, + UPDATE_MODE_SRC_REQUEST | UPDATE_MODE_BLOCK | UPDATE_MODE_FORCE); + + if (ret) + ts_err("failed do fw update"); + + return 0; +} + +static int goodix_ts_mmi_methods_power(struct device *dev, int on) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + GET_GOODIX_DATA(dev); + + if (on == TS_MMI_POWER_ON) + return goodix_ts_power_on(core_data); + else if(on == TS_MMI_POWER_OFF) + return goodix_ts_power_off(core_data); + else { + ts_err("Invalid power parameter %d.\n", on); + return -EINVAL; + } +} + +static int goodix_ts_mmi_panel_state(struct device *dev, + enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to) +{ + struct platform_device *pdev; + struct goodix_ts_core *core_data; + const struct goodix_ts_hw_ops *hw_ops; + + GET_GOODIX_DATA(dev); + hw_ops = core_data->hw_ops; + + switch (to) { + case TS_MMI_PM_GESTURE: + if (hw_ops->gesture) + hw_ops->gesture(core_data, 0); + enable_irq_wake(core_data->irq); + core_data->gesture_enabled = true; + break; + case TS_MMI_PM_DEEPSLEEP: + /* enter sleep mode or power off */ + if (hw_ops->suspend) + hw_ops->suspend(core_data); + core_data->gesture_enabled = false; + break; + case TS_MMI_PM_ACTIVE: + break; + default: + ts_err("Invalid power state parameter %d.\n", to); + return -EINVAL; + } + + return 0; +} + +static int goodix_ts_mmi_pre_resume(struct device *dev) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + const struct goodix_ts_hw_ops *hw_ops; + + ts_info("Resume start"); + GET_GOODIX_DATA(dev); + hw_ops = core_data->hw_ops; + + GET_GOODIX_DATA(dev); + + atomic_set(&core_data->suspended, 0); + if (core_data->gesture_enabled) + disable_irq_wake(core_data->irq); + + if (hw_ops->resume) + hw_ops->resume(core_data); + + return 0; +} + +static int goodix_ts_mmi_pre_suspend(struct device *dev) { + struct platform_device *pdev; + struct goodix_ts_core *core_data; + const struct goodix_ts_hw_ops *hw_ops; + + GET_GOODIX_DATA(dev); + hw_ops = core_data->hw_ops; + + ts_info("Suspend start"); + atomic_set(&core_data->suspended, 1); + return 0; +} + +static int goodix_ts_mmi_post_suspend(struct device *dev) { + struct goodix_ts_core *core_data; + struct platform_device *pdev; + + GET_GOODIX_DATA(dev); + + goodix_ts_release_connects(core_data); + + ts_info("Suspend end"); + return 0; +} + +static struct ts_mmi_methods goodix_ts_mmi_methods = { + .get_vendor = goodix_ts_mmi_methods_get_vendor, + .get_productinfo = goodix_ts_mmi_methods_get_productinfo, + .get_build_id = goodix_ts_mmi_methods_get_build_id, + .get_config_id = goodix_ts_mmi_methods_get_config_id, + .get_bus_type = goodix_ts_mmi_methods_get_bus_type, + .get_irq_status = goodix_ts_mmi_methods_get_irq_status, + .get_drv_irq = goodix_ts_mmi_methods_get_drv_irq, + .get_poweron = goodix_ts_mmi_methods_get_poweron, + .get_flashprog = goodix_ts_mmi_methods_get_flashprog, + /* SET methods */ + .reset = goodix_ts_mmi_methods_reset, + .drv_irq = goodix_ts_mmi_methods_drv_irq, + .power = goodix_ts_mmi_methods_power, + /* Firmware */ + .firmware_update = goodix_ts_firmware_update, + /* PM callback */ + .panel_state = goodix_ts_mmi_panel_state, + .pre_resume = goodix_ts_mmi_pre_resume, + .pre_suspend = goodix_ts_mmi_pre_suspend, + .post_suspend = goodix_ts_mmi_post_suspend, +}; + +int goodix_ts_mmi_dev_register(struct platform_device *pdev) { + int ret; + struct goodix_ts_core *core_data; + core_data = platform_get_drvdata(pdev); + if (!core_data) { + ts_err("Failed to get driver data"); + return -ENODEV; + } + ret = ts_mmi_dev_register(core_data->bus->dev, &goodix_ts_mmi_methods); + if (ret) { + dev_err(&pdev->dev, "Failed to register ts mmi\n"); + return ret; + } + return 0; +} + +void goodix_ts_mmi_dev_unregister(struct platform_device *pdev) { + struct goodix_ts_core *core_data; + core_data = platform_get_drvdata(pdev); + if (!core_data) + ts_err("Failed to get driver data"); + ts_mmi_dev_unregister(&pdev->dev); +} diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h new file mode 100644 index 000000000000..055377a444bd --- /dev/null +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2019 Motorola Mobility LLC + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __GOODIX_TS_MMI_H__ +#define __GOODIX_TS_MMI_H__ + +#include "goodix_ts_core.h" + +extern int goodix_ts_mmi_dev_register(struct platform_device *ts_device); +extern void goodix_ts_mmi_dev_unregister(struct platform_device *ts_device); + +#endif