Support touchscreen class for novatek

TP:
Support touchscreen class for novatek.

Change-Id: I040d2124988660366cfd88cb9880fbddc9d500a3
Reviewed-on: https://gerrit.mot.com/1923438
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Jichao Zou <zoujc@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
litong 2021-04-22 13:51:41 +08:00 • committed by litong
commit 4c23a76ad2
6 changed files with 306 additions and 8 deletions

View file

@ -49,6 +49,9 @@ endif
ifneq ($(BOARD_USES_EDGE_SUPPRESSION),)
KERNEL_CFLAGS += CONFIG_INPUT_NOVA_EDGE_SUPPRESSION=y
endif
ifeq ($(DRM_PANEL_NOTIFICATIONS),true)
KERNEL_CFLAGS += CONFIG_DRM_PANEL_NOTIFICATIONS=y
endif
include $(CLEAR_VARS)
ifneq ($(BOARD_USES_DOUBLE_TAP),)
LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/sensors_class.ko
@ -59,5 +62,9 @@ endif
LOCAL_MODULE := nova_0flash_mmi.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(NOVA_MMI_MODULE_PATH)
ifneq ($(findstring touchscreen_mmi.ko,$(BOARD_VENDOR_KERNEL_MODULES)),)
KERNEL_CFLAGS += 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

View file

@ -51,3 +51,11 @@ nova_0flash_mmi-objs += nt36xxx.o
nova_0flash_mmi-objs += nt36xxx_ext_proc.o
nova_0flash_mmi-objs += nt36xxx_fw_update.o
nova_0flash_mmi-objs += nt36xxx_mp_ctrlram.o
ifneq ($(filter m y,$(CONFIG_DRM_PANEL_NOTIFICATIONS)),)
EXTRA_CFLAGS += -DCONFIG_DRM_PANEL_NOTIFICATIONS
endif
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_MMI)),)
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers
EXTRA_CFLAGS += -DCONFIG_INPUT_TOUCHSCREEN_MMI
nova_0flash_mmi-objs += nt36xxx_mmi_class.o
endif

View file

@ -27,6 +27,7 @@
#include <linux/power_supply.h>
#include <linux/version.h>
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
#include <linux/msm_drm_notify.h>
@ -45,10 +46,6 @@
#include <linux/earlysuspend.h>
#endif
#endif //end version code >= 5.4.0
#include "nt36xxx.h"
#if NVT_TOUCH_ESD_PROTECT
#include <linux/jiffies.h>
#endif /* #if NVT_TOUCH_ESD_PROTECT */
#ifdef NVT_CONFIG_PANEL_NOTIFICATIONS
#define register_panel_notifier panel_register_notifier
@ -61,6 +58,16 @@ enum touch_state {
#define register_panel_notifier(...) rc
#define unregister_panel_notifier(...) rc
#endif
#endif //end touchscreen_mmi
#include "nt36xxx.h"
#if NVT_TOUCH_ESD_PROTECT
#include <linux/jiffies.h>
#endif /* #if NVT_TOUCH_ESD_PROTECT */
#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI
extern int nvt_mmi_init(struct nvt_ts_data *ts_data, bool enable);
#endif
#ifdef NVT_SENSOR_EN
#ifdef CONFIG_HAS_WAKELOCK
@ -111,12 +118,14 @@ extern void nvt_mp_proc_deinit(void);
struct nvt_ts_data *ts;
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
static struct drm_panel *active_panel;
static const char *active_panel_name = NULL;
#endif
#endif
#endif
#if BOOT_UPDATE_FIRMWARE
static struct workqueue_struct *nvt_fwu_wq;
@ -127,6 +136,7 @@ extern void Boot_Update_Firmware(struct work_struct *work);
int nvt_mcu_pen_detect_set(uint8_t pen_detect);
#endif
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
@ -151,6 +161,7 @@ static void nvt_ts_late_resume(struct early_suspend *h);
static int nvt_panel_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
#endif
#endif //end version code >= 5.4.0
#endif //end touchscreen_mmi
uint32_t ENG_RST_ADDR = 0x7FFF80;
uint32_t SWRST_N8_ADDR = 0; //read from dtsi
@ -229,7 +240,7 @@ Description:
return:
n.a.
*******************************************************/
static void nvt_irq_enable(bool enable)
void nvt_irq_enable(bool enable)
{
struct irq_desc *desc;
@ -1138,6 +1149,7 @@ static int nvt_get_dt_def_coords(struct device *dev, char *name)
return rc;
}
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
static int nova_check_dt(struct device_node *np)
@ -1183,16 +1195,19 @@ static int nova_check_dt(struct device_node *np)
}
#endif
#endif
#endif
static int32_t nvt_parse_dt(struct device *dev)
{
struct device_node *np = dev->of_node;
int32_t ret = 0;
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
int num_of_panel_supplier;
int j;
const char *panel_supplier;
#endif
#endif
#if NVT_TOUCH_SUPPORT_HW_RST
ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, &ts->reset_flags);
@ -1209,7 +1224,8 @@ static int32_t nvt_parse_dt(struct device *dev)
NVT_LOG("SWRST_N8_ADDR=0x%06X\n", SWRST_N8_ADDR);
}
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL)) &&\
(!defined CONFIG_INPUT_TOUCHSCREEN_MMI)
num_of_panel_supplier = of_property_count_strings(np, "novatek,panel-supplier");
NVT_LOG("%s: get novatek,panel-supplier count=%d", __func__, num_of_panel_supplier);
if (active_panel_name && num_of_panel_supplier > 1) {
@ -1252,6 +1268,7 @@ static int32_t nvt_parse_dt(struct device *dev)
snprintf(nvt_mp_firmware_name, NVT_FILE_NAME_LENGTH, "%s_novatek_ts_mp.bin",
ts->panel_supplier);
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
//Support FW name with panel & IC info
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
if (active_panel_name) {
@ -1276,6 +1293,7 @@ static int32_t nvt_parse_dt(struct device *dev)
}
}
}
#endif
#endif
}
NVT_LOG("boot firmware %s, mp firmware %s", nvt_boot_firmware_name, nvt_mp_firmware_name);
@ -2216,6 +2234,7 @@ static int32_t nvt_ts_probe(struct spi_device *client)
#ifdef NVT_SENSOR_EN
static bool initialized_sensor;
#endif
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
struct device_node *dp = client->dev.of_node;
@ -2224,6 +2243,7 @@ static int32_t nvt_ts_probe(struct spi_device *client)
NVT_LOG("panel error\n");
return ret;
}
#endif
#endif
NVT_LOG("start\n");
@ -2502,9 +2522,11 @@ static int32_t nvt_ts_probe(struct spi_device *client)
goto err_create_nvt_fwu_wq_failed;
}
INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware);
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
// please make sure boot update start after display reset(RESX) sequence
queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(14000));
#endif
#endif
#ifdef LCM_FAST_LIGHTUP
INIT_WORK(&ts_resume_work, nova_resume_work_func);
#endif
@ -2557,6 +2579,7 @@ static int32_t nvt_ts_probe(struct spi_device *client)
}
#endif
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
ts->drm_notif.notifier_call = nvt_drm_notifier_callback;
@ -2605,8 +2628,13 @@ static int32_t nvt_ts_probe(struct spi_device *client)
}
#endif
#endif //end version code >= 5.4.0
#endif //end touchscreen_mmi
#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
ret = nvt_mmi_init(ts, true);
#else
ret = nvt_fw_class_init(true);
#endif
if (ret) {
NVT_ERR("Create touchscreen class failed. ret=%d\n", ret);
goto err_create_touchscreen_class_failed;
@ -2618,7 +2646,12 @@ static int32_t nvt_ts_probe(struct spi_device *client)
nvt_irq_enable(true);
return 0;
err_create_touchscreen_class_failed:
#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
nvt_mmi_init(ts, false);
#endif
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
if (active_panel) {
@ -2643,6 +2676,7 @@ err_register_fb_notif_failed:
err_register_early_suspend_failed:
#endif
#endif //end version code >= 5.4.0
#endif //end touchscreen_mmi
#ifdef NOVATECH_PEN_NOTIFIER
if (pen_detection_unregister_client(&ts->pen_notif))
NVT_ERR("Error occurred while unregistering pen_notifier.\n");
@ -2740,8 +2774,13 @@ static int32_t nvt_ts_remove(struct spi_device *client)
{
NVT_LOG("Removing driver...\n");
#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
nvt_mmi_init(ts, false);
#else
nvt_fw_class_init(false);
#endif
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
if (active_panel) {
@ -2767,6 +2806,7 @@ static int32_t nvt_ts_remove(struct spi_device *client)
NVT_ERR("Error occurred while unregistering panel_notifier.\n");
#endif
#endif //end version code >= 5.4.0
#endif //end touchscren_mmi
#ifdef NOVATECH_PEN_NOTIFIER
if (pen_detection_unregister_client(&ts->pen_notif))
NVT_ERR("Error occurred while unregistering pen_notifier.\n");
@ -2841,6 +2881,7 @@ static void nvt_ts_shutdown(struct spi_device *client)
nvt_irq_enable(false);
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
if (active_panel) {
@ -2866,6 +2907,7 @@ static void nvt_ts_shutdown(struct spi_device *client)
NVT_ERR("Error occurred while unregistering panel_notifier.\n");
#endif
#endif //end version code >= 5.4.0
#endif //end touchscreen_mmi
#if NVT_TOUCH_MP
nvt_mp_proc_deinit();
#endif
@ -2905,7 +2947,7 @@ Description:
return:
Executive outcomes. 0---succeed.
*******************************************************/
static int32_t nvt_ts_suspend(struct device *dev)
int32_t nvt_ts_suspend(struct device *dev)
{
uint8_t buf[4] = {0};
#if MT_PROTOCOL_B
@ -3015,7 +3057,7 @@ Description:
return:
Executive outcomes. 0---succeed.
*******************************************************/
static int32_t nvt_ts_resume(struct device *dev)
int32_t nvt_ts_resume(struct device *dev)
{
#ifdef NVT_SENSOR_EN
@ -3081,6 +3123,7 @@ static int32_t nvt_ts_resume(struct device *dev)
return 0;
}
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(NVT_CONFIG_DRM_PANEL))
#if defined(CONFIG_DRM)
#ifdef LCM_FAST_LIGHTUP
@ -3263,6 +3306,7 @@ static void nvt_ts_late_resume(struct early_suspend *h)
}
#endif
#endif //version code >= 5.4.0
#endif //end touchscreen_mmi
static const struct spi_device_id nvt_ts_id[] = {
{ NVT_SPI_NAME, 0 },

View file

@ -232,6 +232,7 @@ struct nvt_ts_data {
#endif
char product_id[10];
uint8_t fw_type;
atomic_t loading_fw;
uint32_t build_id;
uint32_t config_id;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
@ -319,6 +320,7 @@ void nvt_sw_reset_idle(void);
void nvt_boot_ready(void);
void nvt_bld_crc_enable(void);
void nvt_fw_crc_enable(void);
void nvt_irq_enable(bool enable);
int32_t nvt_update_firmware(char *firmware_name);
int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state);
int32_t nvt_get_fw_info(void);
@ -326,6 +328,8 @@ int32_t nvt_clear_fw_status(void);
int32_t nvt_check_fw_status(void);
int32_t nvt_set_page(uint32_t addr);
int32_t nvt_write_addr(uint32_t addr, uint8_t data);
int32_t nvt_ts_suspend(struct device *dev);
int32_t nvt_ts_resume(struct device *dev);
#ifdef NVT_SET_TOUCH_STATE
int touch_set_state(int state, int panel_idx);
int check_touch_state(int *state, int panel_idx);

View file

@ -952,6 +952,7 @@ int32_t nvt_update_firmware(char *firmware_name)
{
int32_t ret = 0;
atomic_set(&ts->loading_fw, 1);
// request bin file in "/etc/firmware"
ret = update_firmware_request(firmware_name);
if (ret) {
@ -999,6 +1000,7 @@ download_fail:
update_firmware_release();
request_firmware_fail:
atomic_set(&ts->loading_fw, 0);
return ret;
}

View file

@ -0,0 +1,233 @@
/*
* 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 <linux/gpio.h>
#include <linux/touchscreen_mmi.h>
#include <linux/regulator/consumer.h>
#include "nt36xxx.h"
#define GET_TS_DATA(dev) { \
ts_data = dev_get_drvdata(dev); \
if (!ts_data) { \
NVT_ERR("Failed to get driver data"); \
return -ENODEV; \
} \
}
static int nvt_mmi_methods_get_vendor(struct device *dev, void *cdata)
{
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "novatek_ts");
}
static int nvt_mmi_methods_get_productinfo(struct device *dev, void *cdata)
{
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_INFO_LEN, "%s", ts->product_id);
}
static int nvt_mmi_methods_get_build_id(struct device *dev, void *cdata)
{
struct nvt_ts_data *ts_data;
int buildid;
GET_TS_DATA(dev);
buildid = (ts->nvt_pid ? ts->nvt_pid : ts->config_id);
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%04x", buildid);
}
/* Read fw_version, date_Y, date_M, date_D */
static int nvt_mmi_methods_get_config_id(struct device *dev, void *cdata)
{
struct nvt_ts_data *ts_data;
uint8_t tmp_buf[8] = {0};
uint8_t fw_version = 0;
uint8_t date_Y = 0;
uint8_t date_M = 0;
uint8_t date_D = 0;
GET_TS_DATA(dev);
//---set xdata index to EVENT BUF ADDR---
nvt_set_page(ts_data->mmap->EVENT_BUF_ADDR | EVENT_MAP_FWINFO);
tmp_buf[0] = EVENT_MAP_FWINFO;
CTP_SPI_READ(ts_data->client, tmp_buf, 2);
fw_version = tmp_buf[1];
//---set xdata index to EVENT BUF ADDR---
nvt_set_page(ts_data->mmap->EVENT_BUF_ADDR | EVENT_MAP_PROJECTID);
tmp_buf[0] = EVENT_MAP_PROJECTID;
CTP_SPI_READ(ts_data->client, tmp_buf, 6);
date_Y = tmp_buf[3];
date_M = tmp_buf[4];
date_D = tmp_buf[5];
nvt_set_page(ts_data->mmap->EVENT_BUF_ADDR);
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%02d%02d%02d%02x",
date_Y, date_M, date_D, fw_version);
}
static int nvt_mmi_methods_get_bus_type(struct device *dev, void *idata)
{
struct nvt_ts_data *ts_data;
struct input_dev *input_dev;
GET_TS_DATA(dev);
input_dev = ts_data->input_dev;
TO_INT(idata) = ts->input_dev->id.bustype == BUS_SPI ?
TOUCHSCREEN_MMI_BUS_TYPE_SPI : TOUCHSCREEN_MMI_BUS_TYPE_I2C;
return 0;
}
static int nvt_mmi_methods_get_irq_status(struct device *dev, void *idata)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
TO_INT(idata) = gpio_get_value(ts_data->irq_gpio);
return 0;
}
static int nvt_mmi_methods_get_drv_irq(struct device *dev, void *idata)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
TO_INT(idata) = ts_data->irq_enabled ? 1 : 0;
return 0;
}
static int nvt_mmi_methods_get_poweron(struct device *dev, void *idata)
{
TO_INT(idata) = 1;
return 0;
}
static int nvt_mmi_methods_get_flashprog(struct device *dev, void *idata)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
TO_INT(idata) = atomic_read(&ts_data->loading_fw);
return 0;
}
static int nvt_mmi_methods_drv_irq(struct device *dev, int state)
{
int ret = 0;
if (state == 1)
nvt_irq_enable(true);
else if (state == 0) {
nvt_irq_enable(false);
} else {
dev_err(dev, "%s: invalid value\n", __func__);
ret = -EINVAL;
}
return ret;
}
static int nvt_mmi_methods_reset(struct device *dev, int type)
{
nvt_sw_reset();
return 0;
}
static int nvt_mmi_firmware_update(struct device *dev, char *fwname)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
mutex_lock(&ts->lock);
snprintf(nvt_boot_firmware_name, NVT_FILE_NAME_LENGTH, "%s", fwname);
snprintf(nvt_mp_firmware_name, NVT_FILE_NAME_LENGTH, "mp-%s", fwname);
nvt_update_firmware(nvt_boot_firmware_name);
mutex_unlock(&ts->lock);
return 0;
}
static int nvt_mmi_panel_state(struct device *dev,
enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
dev_dbg(dev, "%s: panel state change: %d->%d\n", __func__, from, to);
pr_info("panel state change: %d->%d\n", from, to);
switch (to) {
case TS_MMI_PM_GESTURE:
case TS_MMI_PM_DEEPSLEEP:
nvt_ts_suspend(&ts_data->client->dev);
break;
case TS_MMI_PM_ACTIVE:
break;
default:
dev_warn(dev, "panel mode %d is invalid.\n", to);
return -EINVAL;
}
pr_info("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS");
return 0;
}
static int nvt_mmi_post_resume(struct device *dev)
{
struct nvt_ts_data *ts_data;
GET_TS_DATA(dev);
pr_info("enter\n");
dev_dbg(dev, "%s\n", __func__);
nvt_ts_resume(&ts_data->client->dev);
pr_info("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS");
return 0;
}
static struct ts_mmi_methods nvt_mmi_methods = {
.get_vendor = nvt_mmi_methods_get_vendor,
.get_productinfo = nvt_mmi_methods_get_productinfo,
.get_build_id = nvt_mmi_methods_get_build_id,
.get_config_id = nvt_mmi_methods_get_config_id,
.get_bus_type = nvt_mmi_methods_get_bus_type,
.get_irq_status = nvt_mmi_methods_get_irq_status,
.get_drv_irq = nvt_mmi_methods_get_drv_irq,
.get_flashprog = nvt_mmi_methods_get_flashprog,
.get_poweron = nvt_mmi_methods_get_poweron,
/* SET methods */
.reset = nvt_mmi_methods_reset,
.drv_irq = nvt_mmi_methods_drv_irq,
/* Firmware */
.firmware_update = nvt_mmi_firmware_update,
/* PM callback */
.panel_state = nvt_mmi_panel_state,
.post_resume = nvt_mmi_post_resume,
};
int nvt_mmi_init(struct nvt_ts_data *ts_data, bool enable) {
int ret = 0;
if (enable) {
ret = ts_mmi_dev_register(&ts_data->client->dev, &nvt_mmi_methods);
if (ret)
dev_err(&ts_data->client->dev, "Failed to register ts mmi\n");
} else
ts_mmi_dev_unregister(&ts_data->client->dev);
return ret;
}