OSDN Git Service

input: msg21xx_ts: update mstar driver to enable msg2138A
authorMao Li <maol@codeaurora.org>
Mon, 11 Aug 2014 06:19:09 +0000 (14:19 +0800)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 5 Aug 2016 11:35:02 +0000 (04:35 -0700)
Mstar reference driver is being cleaned up to be checkpatch
compliant. Add Kconfig and Makefile changes to enable Mstar
driver's compilation. And following new features are added to
the driver:
1. Pinctrl support
2. Threaded irq support
3. Release all touches in suspend
4. Protocol B compliance
5. Explicit suspend/resume function
6. Configure gpios in suspend/resume function
7. Add device tree parser function
8. Add dtsi support for gpio, regulator, I2C address, display coords

This patch is propagated from 3.18 kernel
'commit 091a01709e12 ("input: msg21xx_ts: update mstar
driver to enable msg2138A")'

Change-Id: Ic49a18de64ec210a0636405394ba7a8f52f336a9
Signed-off-by: Mao Li <maol@codeaurora.org>
Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
Signed-off-by: Sudhakar Manapati <smanap@codeaurora.org>
[abinayap@codeaurora.org: Fix checkpatch errors for 4.4 kernel
- Block comments use a trailing */ on a separate line
- Comparisons should place the constant on the right side of the test
- struct of_device_id should normally be const
- DT compatible string vendor "mstar" appears un-documented]
Signed-off-by: Abinaya P <abinayap@codeaurora.org>
Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/msg21xx_ts.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt
new file mode 100644 (file)
index 0000000..26f01ca
--- /dev/null
@@ -0,0 +1,60 @@
+Mstar touch controller
+
+The mstar controller is connected to host processor
+via i2c. The controller generates interrupts when the
+user touches the panel. The host controller is expected
+to read the touch coordinates over i2c and pass the coordinates
+to the rest of the system.
+
+Required properties:
+
+ - compatible          : should be "mstar,msg21xx".
+ - reg                 : i2c slave address of the device.
+ - interrupt-parent    : parent of interrupt.
+ - interrupts          : touch sample interrupt to indicate presense or release
+                               of fingers on the panel.
+ - vdd-supply          : Power supply needed to power up the device.
+ - vcc_i2c-supply      : Power source required to power up i2c bus.
+ - mstar,irq-gpio      : irq gpio which is to provide interrupts to host,
+                               same as "interrupts" node. It will also
+                               contain active low or active high information.
+ - mstar,reset-gpio    : reset gpio to control the reset of chip.
+ - mstar,display-coords : display coords in pixels. It is a four
+                               tuple consisting of min x, min y, max x and
+                               max y values.
+ - pinctrl-names : This should be defined if a target uses pinctrl framework.
+                       See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt.
+                       Specify the names of the configs that pinctrl can install in driver.
+                       Following are the pinctrl configs that can be installed:
+                       "pmx_ts_active" : Active configuration of pins, this should specify active
+                       config defined in pin groups of interrupt and reset gpio.
+                       "pmx_ts_suspend" : Disabled configuration of pins, this should specify sleep
+                       config defined in pin groups of interrupt and reset gpio.
+                       "pmx_ts_release" : Release configuration of pins, this should specify
+                       release config defined in pin groups of interrupt and reset gpio.
+
+Optional properties:
+
+ - mstar,button-map : button map of key codes. It is a three tuple consisting of key codes.
+ - mstar,panel-coords : panel coords for the chip in pixels.
+                               It is a four tuple consisting of min x,
+                               min y, max x and max y values.
+
+Example:
+       i2c@78b9000 { /* BLSP1 QUP5 */
+               mstar@26 {
+                       compatible = "mstar,msg21xx";
+                       reg = <0x26>;
+                       interrupt-parent = <&msm_gpio>;
+                       interrupts = <13 0x2008>;
+                       mstar,irq-gpio = <&msm_gpio 13 0x00000001>;
+                       mstar,reset-gpio = <&msm_gpio 12 0x0>;
+                       vdd-supply = <&pm8916_l17>;
+                       vcc_i2c-supply = <&pm8916_l6>;
+                       mstar,display-coords = <0 0 480 854>;
+                       pinctrl-names = "pmx_ts_active","pmx_ts_suspend";
+                       pinctrl-0 = <&ts_int_active &ts_reset_active>;
+                       pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+                       mstar,button-map= <172 139 158>;
+               };
+       };
index 4097b7c..aca2dd3 100644 (file)
@@ -146,6 +146,7 @@ mosaixtech  Mosaix Technologies, Inc.
 moxa   Moxa
 mpl    MPL AG
 msi    Micro-Star International Co. Ltd.
+mstar  MStar Semiconductor, Inc.
 mti    Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
 mundoreader    Mundo Reader S.L.
 murata Murata Manufacturing Co., Ltd.
index 529edb1..69028bd 100644 (file)
@@ -1110,6 +1110,17 @@ config TOUCHSCREEN_COLIBRI_VF50
          To compile this driver as a module, choose M here: the
          module will be called colibri_vf50_ts.
 
+config TOUCHSCREEN_MSTAR21XX
+       tristate "Mstar touchscreens"
+       depends on I2C
+       help
+        Say Y here if you have a mstar touchscreen.
+
+        If unsure, say N.
+
+        To compile this driver as a module, choose M here: the
+        module will be called msg21xx_ts.
+
 config TOUCHSCREEN_ROHM_BU21023
        tristate "ROHM BU21023/24 Dual touch support resistive touchscreens"
        depends on I2C
index e04e787..e1777f1 100644 (file)
@@ -97,3 +97,4 @@ obj-$(CONFIG_TOUCHSCREEN_TPS6507X)    += tps6507x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ZFORCE)       += zforce_ts.o
 obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
+obj-$(CONFIG_TOUCHSCREEN_MSTAR21XX)    += msg21xx_ts.o
index 4eb7fd4..72114eb 100644 (file)
@@ -5,6 +5,8 @@
  *
  * Copyright (C) 2012 Bruce Ding <bruce.ding@mstarsemi.com>
  *
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/timer.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <linux/sysfs.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <asm/unistd.h>
 #include <linux/cdev.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/regulator/consumer.h>
+
 #if defined(CONFIG_HAS_EARLYSUSPEND)
 #include <linux/earlysuspend.h>
 #endif
 #include <linux/notifier.h>
 #include <linux/fb.h>
 #endif
-#ifdef  CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
 #include <linux/input/vir_ps.h>
 #endif
 
-/*=============================================================*/
-// Macro Definition
-/*=============================================================*/
+/* Macro Definition */
 
 #define TOUCH_DRIVER_DEBUG 0
 #if (TOUCH_DRIVER_DEBUG == 1)
-#define DBG(fmt, arg...) pr_err(fmt, ##arg) //pr_info(fmt, ##arg)
+#define DBG(fmt, arg...) pr_info(fmt, ##arg)
 #else
 #define DBG(fmt, arg...)
 #endif
 
-/*=============================================================*/
-// Constant Value & Variable Definition
-/*=============================================================*/
+/* Constant Value & Variable Definition */
+
+static struct regulator *vdd;
+static struct regulator *vcc_i2c;
+
+#define MSTAR_VTG_MIN_UV       2800000
+#define MSTAR_VTG_MAX_UV       3300000
+#define MSTAR_I2C_VTG_MIN_UV   1800000
+#define MSTAR_I2C_VTG_MAX_UV   1800000
 
-#define U8         unsigned char
-#define U16        unsigned short
-#define U32        unsigned int
-#define S8         signed char
-#define S16        signed short
-#define S32        signed int
 
 #define TOUCH_SCREEN_X_MIN   (0)
 #define TOUCH_SCREEN_Y_MIN   (0)
-/*
- * Note.
- * Please change the below touch screen resolution according to the touch panel that you are using.
- */
-#define TOUCH_SCREEN_X_MAX   (480)
-#define TOUCH_SCREEN_Y_MAX   (800)
+
+#define MAX_BUTTONS            4
+#define FT_COORDS_ARR_SIZE     4
+
+
 /*
  * Note.
  * Please do not change the below setting.
 #define TPD_WIDTH   (2048)
 #define TPD_HEIGHT  (2048)
 
-/*
- * Note.
- * Please change the below GPIO pin setting to follow the platform that you are using
- */
-static int int_gpio = 1;
-static int reset_gpio = 0;
-#define MS_TS_MSG21XX_GPIO_RST   reset_gpio
-#define MS_TS_MSG21XX_GPIO_INT   int_gpio
-//---------------------------------------------------------------------//
-
-//#define SYSFS_AUTHORITY_CHANGE_FOR_CTS_TEST
-
-#ifdef SYSFS_AUTHORITY_CHANGE_FOR_CTS_TEST
-#define SYSFS_AUTHORITY (0644)
-#else
-#define SYSFS_AUTHORITY (0777)
-#endif
-
-#define FIRMWARE_AUTOUPDATE
 #ifdef FIRMWARE_AUTOUPDATE
-typedef enum {
-    SWID_START = 1,
-    SWID_TRULY = SWID_START,
-    SWID_NULL,
-} SWID_ENUM;
+enum {
+       SWID_START = 1,
+       SWID_TRULY = SWID_START,
+       SWID_NULL,
+};
 
-unsigned char MSG_FIRMWARE[1][33*1024] =
-{
-    {
-        #include "msg21xx_truly_update_bin.h"
-    }
+static unsigned char MSG_FIRMWARE[1][33*1024] = { {
+               #include "msg21xx_truly_update_bin.h"
+       }
 };
 #endif
 
 #define CONFIG_TP_HAVE_KEY
 
-/*
- * Note.
- * If the below virtual key value definition are not consistent with those that defined in key layout file of platform,
- * please change the below virtual key value to follow the platform that you are using.
- */
-#ifdef CONFIG_TP_HAVE_KEY
-#define TOUCH_KEY_MENU (139) //229
-#define TOUCH_KEY_HOME (172) //102
-#define TOUCH_KEY_BACK (158)
-#define TOUCH_KEY_SEARCH (217)
-
-const U16 tp_key_array[] = {TOUCH_KEY_MENU, TOUCH_KEY_HOME, TOUCH_KEY_BACK, TOUCH_KEY_SEARCH};
-#define MAX_KEY_NUM (sizeof(tp_key_array)/sizeof(tp_key_array[0]))
-#endif
+#define PINCTRL_STATE_ACTIVE   "pmx_ts_active"
+#define PINCTRL_STATE_SUSPEND  "pmx_ts_suspend"
+#define PINCTRL_STATE_RELEASE  "pmx_ts_release"
 
-#define SLAVE_I2C_ID_DBBUS         (0xC4>>1)
-#define SLAVE_I2C_ID_DWI2C      (0x4C>>1)
+#define SLAVE_I2C_ID_DBBUS              (0xC4>>1)
 
-#define DEMO_MODE_PACKET_LENGTH    (8)
-#define MAX_TOUCH_NUM           (2)     //5
+#define DEMO_MODE_PACKET_LENGTH        (8)
+#define MAX_TOUCH_NUM             (2)
 
 #define TP_PRINT
 #ifdef TP_PRINT
@@ -153,1600 +124,2020 @@ static int tp_print_proc_read(void);
 static void tp_print_create_entry(void);
 #endif
 
-static char *fw_version = NULL; // customer firmware version
-static U16 fw_version_major = 0;
-static U16 fw_version_minor = 0;
-static U8 temp[94][1024];
-static U32 crc32_table[256];
-static int FwDataCnt = 0;
-static U8 bFwUpdating = 0;
-static struct class *firmware_class = NULL;
-static struct device *firmware_cmd_dev = NULL;
+static char *fw_version; /* customer firmware version */
+static unsigned short fw_version_major;
+static unsigned short fw_version_minor;
+static unsigned char temp[94][1024];
+static unsigned int crc32_table[256];
+static int FwDataCnt;
+static unsigned char bFwUpdating;
+static struct class *firmware_class;
+static struct device *firmware_cmd_dev;
+
+static struct i2c_client *i2c_client;
+
+static u32 button_map[MAX_BUTTONS];
+
+static u32 num_buttons;
+
+struct msg21xx_ts_platform_data {
+       const char *name;
+       const char *fw_name;
+       u32 irqflags;
+       u32 irq_gpio;
+       u32 irq_gpio_flags;
+       u32 reset_gpio;
+       u32 reset_gpio_flags;
+       u32 family_id;
+       u32 x_max;
+       u32 y_max;
+       u32 x_min;
+       u32 y_min;
+       u32 panel_minx;
+       u32 panel_miny;
+       u32 panel_maxx;
+       u32 panel_maxy;
+       u32 group_id;
+       u32 hard_rst_dly;
+       u32 soft_rst_dly;
+       u32 num_max_touches;
+       bool fw_vkey_support;
+       bool no_force_update;
+       bool i2c_pull_up;
+       bool ignore_id_check;
+       int (*power_init)(bool);
+       int (*power_on)(bool);
+};
+
+static struct msg21xx_ts_platform_data *pdata;
+
+struct msg21xx_ts_data {
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+       const struct msg21xx_ts_platform_data *pdata;
+       struct regulator *vdd;
+       struct regulator *vcc_i2c;
+       bool loading_fw;
+       u8 family_id;
+       struct dentry *dir;
+       u16 addr;
+       bool suspended;
+       char *ts_info;
+       u8 *tch_data;
+       u32 tch_data_len;
+       u8 fw_ver[3];
+       u8 fw_vendor_id;
+#if defined(CONFIG_FB)
+       struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+       struct early_suspend early_suspend;
+#endif
+       struct pinctrl *ts_pinctrl;
+       struct pinctrl_state *pinctrl_state_active;
+       struct pinctrl_state *pinctrl_state_suspend;
+       struct pinctrl_state *pinctrl_state_release;
+       struct mutex ts_mutex;
+};
 
-static struct i2c_client *i2c_client = NULL;
+static struct msg21xx_ts_data *ts_data;
 
 #if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
-static struct notifier_block msg21xx_fb_notif;
-#elif defined (CONFIG_HAS_EARLYSUSPEND)
+static int fb_notifier_callback(struct notifier_block *self,
+                       unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
 static struct early_suspend mstar_ts_early_suspend;
 #endif
 
 #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static U8 bEnableTpProximity = 0;
-static U8 bFaceClosingTp = 0;
+static unsigned char bEnableTpProximity;
+static unsigned char bFaceClosingTp;
 #endif
-static U8 bTpInSuspend = 0;
 
-static int irq_msg21xx = -1;
-static struct work_struct msg21xx_wk;
 static struct mutex msg21xx_mutex;
-static struct input_dev *input_dev = NULL;
+static struct input_dev *input_dev;
 
-/*=============================================================*/
-// Data Type Definition
-/*=============================================================*/
 
-typedef struct
-{
-    U16 x;
-    U16 y;
-}   touchPoint_t;
+/* Data Type Definition */
 
-/// max 80+1+1 = 82 bytes
-typedef struct
-{
-    touchPoint_t point[MAX_TOUCH_NUM];
-    U8 count;
-    U8 keycode;
-}   touchInfo_t;
+struct touchPoint_t {
+       unsigned short x;
+       unsigned short y;
+};
 
-enum i2c_speed
-{
-    I2C_SLOW = 0,
-    I2C_NORMAL = 1, /* Enable erasing/writing for 10 msec. */
-    I2C_FAST = 2,   /* Disable EWENB before 10 msec timeout. */
+struct touchInfo_t {
+       struct touchPoint_t point[MAX_TOUCH_NUM];
+       unsigned char count;
+       unsigned char keycode;
 };
 
-typedef enum
-{
-    EMEM_ALL = 0,
-    EMEM_MAIN,
-    EMEM_INFO,
-} EMEM_TYPE_t;
+enum i2c_speed {
+       I2C_SLOW = 0,
+       I2C_NORMAL = 1, /* Enable erasing/writing for 10 msec. */
+       I2C_FAST = 2,   /* Disable EWENB before 10 msec timeout. */
+};
 
-/*=============================================================*/
-// Function Definition
-/*=============================================================*/
+enum EMEM_TYPE_t {
+       EMEM_ALL = 0,
+       EMEM_MAIN,
+       EMEM_INFO,
+};
 
-/// CRC
-static U32 _CRC_doReflect(U32 ref, S8 ch)
-{
-    U32 value = 0;
-    U32 i = 0;
-
-    for (i = 1; i < (ch + 1); i ++)
-    {
-        if (ref & 1)
-        {
-            value |= 1 << (ch - i);
-        }
-        ref >>= 1;
-    }
-
-    return value;
-}
+/* Function Definition */
 
-U32 _CRC_getValue(U32 text, U32 prevCRC)
+static unsigned int _CRC_doReflect(unsigned int ref, signed char ch)
 {
-    U32 ulCRC = prevCRC;
+       unsigned int value = 0;
+       unsigned int i = 0;
 
-    ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ text];
+       for (i = 1; i < (ch + 1); i++) {
+               if (ref & 1)
+                       value |= 1 << (ch - i);
+               ref >>= 1;
+       }
 
-    return ulCRC;
+       return value;
 }
 
-static void _CRC_initTable(void)
-{
-    U32 magic_number = 0x04c11db7;
-    U32 i, j;
-
-    for (i = 0; i <= 0xFF; i ++)
-    {
-        crc32_table[i] = _CRC_doReflect (i, 8) << 24;
-        for (j = 0; j < 8; j ++)
-        {
-            crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (0x80000000L) ? magic_number : 0);
-        }
-        crc32_table[i] = _CRC_doReflect(crc32_table[i], 32);
-    }
-}
-
-static void reset_hw(void)
+static unsigned int _CRC_getValue(unsigned int text, unsigned int prevCRC)
 {
-    DBG("reset_hw()\n");
+       unsigned int ulCRC = prevCRC;
 
-    gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
-    gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-    mdelay(100);     /* Note that the RST must be in LOW 10ms at least */
-    gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
-    mdelay(100);     /* Enable the interrupt service thread/routine for INT after 50ms */
-}
+       ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ text];
 
-static int read_i2c_seq(U8 addr, U8* buf, U16 size)
-{
-    int rc = 0;
-    struct i2c_msg msgs[] =
-    {
-        {
-            .addr = addr,
-            .flags = I2C_M_RD, // read flag
-            .len = size,
-            .buf = buf,
-        },
-    };
-
-    /* If everything went ok (i.e. 1 msg transmitted), return #bytes
-       transmitted, else error code. */
-    if (i2c_client != NULL)
-    {
-        rc = i2c_transfer(i2c_client->adapter, msgs, 1);
-        if (rc < 0)
-        {
-            DBG("read_i2c_seq() error %d\n", rc);
-        }
-    }
-    else
-    {
-        DBG("i2c_client is NULL\n");
-    }
-
-    return rc;
+       return ulCRC;
 }
 
-static int write_i2c_seq(U8 addr, U8* buf, U16 size)
+static void _CRC_initTable(void)
 {
-    int rc = 0;
-    struct i2c_msg msgs[] =
-    {
-        {
-            .addr = addr,
-            .flags = 0, // if read flag is undefined, then it means write flag.
-            .len = size,
-            .buf = buf,
-        },
-    };
-
-    /* If everything went ok (i.e. 1 msg transmitted), return #bytes
-       transmitted, else error code. */
-    if (i2c_client != NULL)
-    {
-        rc = i2c_transfer(i2c_client->adapter, msgs, 1);
-        if ( rc < 0 )
-        {
-            DBG("write_i2c_seq() error %d\n", rc);
-        }
-    }
-    else
-    {
-        DBG("i2c_client is NULL\n");
-    }
-
-    return rc;
+       unsigned int magic_number = 0x04c11db7;
+       unsigned int i, j;
+
+       for (i = 0; i <= 0xFF; i++) {
+               crc32_table[i] = _CRC_doReflect(i, 8) << 24;
+               for (j = 0; j < 8; j++)
+                       crc32_table[i] = (crc32_table[i] << 1) ^
+                               (crc32_table[i] & (0x80000000L) ?
+                                       magic_number : 0);
+               crc32_table[i] = _CRC_doReflect(crc32_table[i], 32);
+       }
 }
 
-static U16 read_reg(U8 bank, U8 addr)
+static void reset_hw(void)
 {
-    U8 tx_data[3] = {0x10, bank, addr};
-    U8 rx_data[2] = {0};
-
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3);
-    read_i2c_seq(SLAVE_I2C_ID_DBBUS, &rx_data[0], 2);
-
-    return (rx_data[1] << 8 | rx_data[0]);
+       DBG("reset_hw()\n");
+
+       gpio_direction_output(pdata->reset_gpio, 1);
+       gpio_set_value_cansleep(pdata->reset_gpio, 0);
+       msleep(100);     /* Note that the RST must be in LOW 10ms at least */
+       gpio_set_value_cansleep(pdata->reset_gpio, 1);
+       /* Enable the interrupt service thread/routine for INT after 50ms */
+       msleep(100);
 }
 
-static void write_reg(U8 bank, U8 addr, U16 data)
+static int read_i2c_seq(unsigned char addr, unsigned char *buf,
+                                       unsigned short size)
 {
-    U8 tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8};
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5);
+       int rc = 0;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = addr,
+                       .flags = I2C_M_RD, /* read flag*/
+                       .len = size,
+                       .buf = buf,
+               },
+       };
+
+       /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+        * transmitted, else error code.
+        */
+       if (i2c_client != NULL) {
+               rc = i2c_transfer(i2c_client->adapter, msgs, 1);
+               if (rc < 0)
+                       DBG("read_i2c_seq() error %d\n", rc);
+       } else {
+               DBG("i2c_client is NULL\n");
+       }
+
+       return rc;
 }
 
-static void write_reg_8bit(U8 bank, U8 addr, U8 data)
+static int write_i2c_seq(unsigned char addr, unsigned char *buf,
+                                       unsigned short size)
 {
-    U8 tx_data[4] = {0x10, bank, addr, data};
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4);
+       int rc = 0;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = addr,
+                       /* if read flag is undefined,
+                        * then it means write flag.
+                        */
+                       .flags = 0,
+                       .len = size,
+                       .buf = buf,
+               },
+       };
+
+       /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+        * transmitted, else error code.
+        */
+       if (i2c_client != NULL) {
+               rc = i2c_transfer(i2c_client->adapter, msgs, 1);
+               if (rc < 0)
+                       DBG("write_i2c_seq() error %d\n", rc);
+       } else {
+               DBG("i2c_client is NULL\n");
+       }
+
+       return rc;
 }
 
-void dbbusDWIICEnterSerialDebugMode(void)
+static unsigned short read_reg(unsigned char bank, unsigned char addr)
 {
-    U8 data[5];
+       unsigned char tx_data[3] = {0x10, bank, addr};
+       unsigned char rx_data[2] = {0};
 
-    // Enter the Serial Debug Mode
-    data[0] = 0x53;
-    data[1] = 0x45;
-    data[2] = 0x52;
-    data[3] = 0x44;
-    data[4] = 0x42;
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3);
+       read_i2c_seq(SLAVE_I2C_ID_DBBUS, &rx_data[0], 2);
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 5);
+       return rx_data[1] << 8 | rx_data[0];
 }
 
-void dbbusDWIICStopMCU(void)
+static void write_reg(unsigned char bank, unsigned char addr,
+                                               unsigned short data)
 {
-    U8 data[1];
-
-    // Stop the MCU
-    data[0] = 0x37;
+       unsigned char tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8};
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5);
 }
 
-void dbbusDWIICIICUseBus(void)
+static void write_reg_8bit(unsigned char bank, unsigned char addr,
+                                               unsigned char data)
 {
-    U8 data[1];
+       unsigned char tx_data[4] = {0x10, bank, addr, data};
 
-    // IIC Use Bus
-    data[0] = 0x35;
-
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4);
 }
 
-void dbbusDWIICIICReshape(void)
+static void dbbusDWIICEnterSerialDebugMode(void)
 {
-    U8 data[1];
+       unsigned char data[5];
 
-    // IIC Re-shape
-    data[0] = 0x71;
+       /* Enter the Serial Debug Mode */
+       data[0] = 0x53;
+       data[1] = 0x45;
+       data[2] = 0x52;
+       data[3] = 0x44;
+       data[4] = 0x42;
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 5);
 }
 
-void dbbusDWIICIICNotUseBus(void)
+static void dbbusDWIICStopMCU(void)
 {
-    U8 data[1];
+       unsigned char data[1];
 
-    // IIC Not Use Bus
-    data[0] = 0x34;
+       /* Stop the MCU */
+       data[0] = 0x37;
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
 }
 
-void dbbusDWIICNotStopMCU(void)
+static void dbbusDWIICIICUseBus(void)
 {
-    U8 data[1];
+       unsigned char data[1];
 
-    // Not Stop the MCU
-    data[0] = 0x36;
+       /* IIC Use Bus */
+       data[0] = 0x35;
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
 }
 
-void dbbusDWIICExitSerialDebugMode(void)
+static void dbbusDWIICIICReshape(void)
 {
-    U8 data[1];
-
-    // Exit the Serial Debug Mode
-    data[0] = 0x45;
+       unsigned char data[1];
 
-    write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+       /* IIC Re-shape */
+       data[0] = 0x71;
 
-    // Delay some interval to guard the next transaction
-    //udelay ( 200 );        // delay about 0.2ms
+       write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
 }
 
-//---------------------------------------------------------------------//
-
-static U8 get_ic_type(void)
+static unsigned char get_ic_type(void)
 {
-    U8 ic_type = 0;
-
-    reset_hw();
-    dbbusDWIICEnterSerialDebugMode();
-    dbbusDWIICStopMCU();
-    dbbusDWIICIICUseBus();
-    dbbusDWIICIICReshape();
-    mdelay ( 300 );
-
-    // stop mcu
-    write_reg_8bit ( 0x0F, 0xE6, 0x01 );
-    // disable watch dog
-    write_reg ( 0x3C, 0x60, 0xAA55 );
-    // get ic type
-    ic_type = (0xff)&(read_reg(0x1E, 0xCC));
-
-    if (ic_type != 1        //msg2133
-        && ic_type != 2     //msg21xxA
-        && ic_type !=  3)   //msg26xxM
-    {
-        ic_type = 0;
-    }
-
-    reset_hw();
-
-    return ic_type;
+       unsigned char ic_type = 0;
+
+       reset_hw();
+       dbbusDWIICEnterSerialDebugMode();
+       dbbusDWIICStopMCU();
+       dbbusDWIICIICUseBus();
+       dbbusDWIICIICReshape();
+       msleep(300);
+
+       /* stop mcu */
+       write_reg_8bit(0x0F, 0xE6, 0x01);
+       /* disable watch dog */
+       write_reg(0x3C, 0x60, 0xAA55);
+       /* get ic type */
+       ic_type = (0xff)&(read_reg(0x1E, 0xCC));
+
+       if (ic_type != 1                /* msg2133 */
+               && ic_type != 2  /* msg21xxA */
+               && ic_type !=  3)   /* msg26xxM */ {
+               ic_type = 0;
+       }
+
+       reset_hw();
+
+       return ic_type;
 }
 
 static int get_customer_firmware_version(void)
 {
-    U8 dbbus_tx_data[3] = {0};
-    U8 dbbus_rx_data[4] = {0};
-    int ret = 0;
+       unsigned char dbbus_tx_data[3] = {0};
+       unsigned char dbbus_rx_data[4] = {0};
+       int ret = 0;
+
+       DBG("get_customer_firmware_version()\n");
 
-    DBG("get_customer_firmware_version()\n");
+       dbbus_tx_data[0] = 0x53;
+       dbbus_tx_data[1] = 0x00;
+       dbbus_tx_data[2] = 0x2A;
+       mutex_lock(&msg21xx_mutex);
+       write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+       read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+       mutex_unlock(&msg21xx_mutex);
+       fw_version_major = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
+       fw_version_minor = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
 
-    dbbus_tx_data[0] = 0x53;
-    dbbus_tx_data[1] = 0x00;
-    dbbus_tx_data[2] = 0x2A;
-    mutex_lock(&msg21xx_mutex);
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4);
-    mutex_unlock(&msg21xx_mutex);
-    fw_version_major = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
-    fw_version_minor = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
+       DBG("*** major = %d ***\n", fw_version_major);
+       DBG("*** minor = %d ***\n", fw_version_minor);
 
-    DBG("*** major = %d ***\n", fw_version_major);
-    DBG("*** minor = %d ***\n", fw_version_minor);
+       if (fw_version == NULL)
+               fw_version = kzalloc(sizeof(char), GFP_KERNEL);
 
-    if (fw_version == NULL)
-    {
-        fw_version = kzalloc(sizeof(char), GFP_KERNEL);
-    }
+       snprintf(fw_version, sizeof(char) - 1, "%03d%03d",
+                               fw_version_major, fw_version_minor);
 
-    sprintf(fw_version, "%03d%03d", fw_version_major, fw_version_minor);
 
-    return ret;
+       return ret;
 }
 
-static int firmware_erase_c33 ( EMEM_TYPE_t emem_type )
+static int firmware_erase_c33(enum EMEM_TYPE_t emem_type)
 {
-    // stop mcu
-    write_reg ( 0x0F, 0xE6, 0x0001 );
+       /* stop mcu */
+       write_reg(0x0F, 0xE6, 0x0001);
 
-    //disable watch dog
-    write_reg_8bit ( 0x3C, 0x60, 0x55 );
-    write_reg_8bit ( 0x3C, 0x61, 0xAA );
+       /* disable watch dog */
+       write_reg_8bit(0x3C, 0x60, 0x55);
+       write_reg_8bit(0x3C, 0x61, 0xAA);
 
-    // set PROGRAM password
-    write_reg_8bit ( 0x16, 0x1A, 0xBA );
-    write_reg_8bit ( 0x16, 0x1B, 0xAB );
+       /* set PROGRAM password */
+       write_reg_8bit(0x16, 0x1A, 0xBA);
+       write_reg_8bit(0x16, 0x1B, 0xAB);
 
-    write_reg_8bit ( 0x16, 0x18, 0x80 );
+       write_reg_8bit(0x16, 0x18, 0x80);
 
-    if ( emem_type == EMEM_ALL )
-    {
-        write_reg_8bit ( 0x16, 0x08, 0x10 ); //mark
-    }
+       if (emem_type == EMEM_ALL)
+               write_reg_8bit(0x16, 0x08, 0x10);
 
-    write_reg_8bit ( 0x16, 0x18, 0x40 );
-    mdelay ( 10 );
+       write_reg_8bit(0x16, 0x18, 0x40);
+       msleep(20);
 
-    // clear pce
-    write_reg_8bit ( 0x16, 0x18, 0x80 );
+       /* clear pce */
+       write_reg_8bit(0x16, 0x18, 0x80);
 
-    // erase trigger
-    if ( emem_type == EMEM_MAIN )
-    {
-        write_reg_8bit ( 0x16, 0x0E, 0x04 ); //erase main
-    }
-    else
-    {
-        write_reg_8bit ( 0x16, 0x0E, 0x08 ); //erase all block
-    }
+       /* erase trigger */
+       if (emem_type == EMEM_MAIN)
+               write_reg_8bit(0x16, 0x0E, 0x04); /* erase main */
+       else
+               write_reg_8bit(0x16, 0x0E, 0x08); /* erase all block */
 
-    return ( 1 );
+       return 1;
 }
 
-static ssize_t firmware_update_c33 ( struct device *dev, struct device_attribute *attr,
-                                     const char *buf, size_t size, EMEM_TYPE_t emem_type )
-{
-    U32 i, j;
-    U32 crc_main, crc_main_tp;
-    U32 crc_info, crc_info_tp;
-    U16 reg_data = 0;
-    int update_pass = 1;
-
-    crc_main = 0xffffffff;
-    crc_info = 0xffffffff;
-
-    reset_hw();
-    dbbusDWIICEnterSerialDebugMode();
-    dbbusDWIICStopMCU();
-    dbbusDWIICIICUseBus();
-    dbbusDWIICIICReshape();
-    mdelay ( 300 );
-
-    //erase main
-    firmware_erase_c33 ( EMEM_MAIN );
-    mdelay ( 1000 );
-
-    reset_hw();
-    dbbusDWIICEnterSerialDebugMode();
-    dbbusDWIICStopMCU();
-    dbbusDWIICIICUseBus();
-    dbbusDWIICIICReshape();
-    mdelay ( 300 );
-
-    /////////////////////////
-    // Program
-    /////////////////////////
-
-    //polling 0x3CE4 is 0x1C70
-    if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
-    {
-        do
-        {
-            reg_data = read_reg ( 0x3C, 0xE4 );
-        }
-        while ( reg_data != 0x1C70 );
-    }
-
-    switch ( emem_type )
-    {
-        case EMEM_ALL:
-            write_reg ( 0x3C, 0xE4, 0xE38F );  // for all-blocks
-            break;
-        case EMEM_MAIN:
-            write_reg ( 0x3C, 0xE4, 0x7731 );  // for main block
-            break;
-        case EMEM_INFO:
-            write_reg ( 0x3C, 0xE4, 0x7731 );  // for info block
-
-            write_reg_8bit ( 0x0F, 0xE6, 0x01 );
-
-            write_reg_8bit ( 0x3C, 0xE4, 0xC5 );
-            write_reg_8bit ( 0x3C, 0xE5, 0x78 );
-
-            write_reg_8bit ( 0x1E, 0x04, 0x9F );
-            write_reg_8bit ( 0x1E, 0x05, 0x82 );
-
-            write_reg_8bit ( 0x0F, 0xE6, 0x00 );
-            mdelay ( 100 );
-            break;
-    }
-
-    // polling 0x3CE4 is 0x2F43
-    do
-    {
-        reg_data = read_reg ( 0x3C, 0xE4 );
-    }
-    while ( reg_data != 0x2F43 );
-
-    // calculate CRC 32
-    _CRC_initTable ();
-
-    for ( i = 0; i < 32; i++ ) // total  32 KB : 2 byte per R/W
-    {
-        if ( i == 31 )
-        {
-            temp[i][1014] = 0x5A;
-            temp[i][1015] = 0xA5;
-
-            for ( j = 0; j < 1016; j++ )
-            {
-                crc_main = _CRC_getValue ( temp[i][j], crc_main);
-            }
-        }
-        else
-        {
-            for ( j = 0; j < 1024; j++ )
-            {
-                crc_main = _CRC_getValue ( temp[i][j], crc_main);
-            }
-        }
-
-        //write_i2c_seq(SLAVE_I2C_ID_DWI2C, temp[i], 1024);
-        for (j = 0; j < 8; j++)
-        {
-            write_i2c_seq(SLAVE_I2C_ID_DWI2C, &temp[i][j*128], 128 );
-        }
-        msleep (100);
-
-        // polling 0x3CE4 is 0xD0BC
-        do
-        {
-            reg_data = read_reg ( 0x3C, 0xE4 );
-        }
-        while ( reg_data != 0xD0BC );
-
-        write_reg ( 0x3C, 0xE4, 0x2F43 );
-    }
-
-    if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
-    {
-        // write file done and check crc
-        write_reg ( 0x3C, 0xE4, 0x1380 );
-    }
-    mdelay ( 10 );
-
-    if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
-    {
-        // polling 0x3CE4 is 0x9432
-        do
-        {
-            reg_data = read_reg ( 0x3C, 0xE4 );
-        }while ( reg_data != 0x9432 );
-    }
-
-    crc_main = crc_main ^ 0xffffffff;
-    crc_info = crc_info ^ 0xffffffff;
-
-    if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
-    {
-        // CRC Main from TP
-        crc_main_tp = read_reg ( 0x3C, 0x80 );
-        crc_main_tp = ( crc_main_tp << 16 ) | read_reg ( 0x3C, 0x82 );
-
-        // CRC Info from TP
-        crc_info_tp = read_reg ( 0x3C, 0xA0 );
-        crc_info_tp = ( crc_info_tp << 16 ) | read_reg ( 0x3C, 0xA2 );
-    }
-
-    update_pass = 1;
-    if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
-    {
-        if ( crc_main_tp != crc_main )
-            update_pass = 0;
-
-        /*
-        if ( crc_info_tp != crc_info )
-            update_pass = 0;
-        */
-    }
-
-    if ( !update_pass )
-    {
-        DBG( "update_C33 failed\n" );
-        reset_hw();
-        FwDataCnt = 0;
-        return 0;
-    }
-
-    DBG( "update_C33 OK\n" );
-    reset_hw();
-    FwDataCnt = 0;
-    return size;
+static ssize_t firmware_update_c33(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t size,
+                                               enum EMEM_TYPE_t emem_type) {
+       unsigned int i, j;
+       unsigned int crc_main, crc_main_tp;
+       unsigned int crc_info, crc_info_tp;
+       unsigned short reg_data = 0;
+       int update_pass = 1;
+
+       crc_main = 0xffffffff;
+       crc_info = 0xffffffff;
+
+       reset_hw();
+       dbbusDWIICEnterSerialDebugMode();
+       dbbusDWIICStopMCU();
+       dbbusDWIICIICUseBus();
+       dbbusDWIICIICReshape();
+       msleep(300);
+
+       /* erase main */
+       firmware_erase_c33(EMEM_MAIN);
+       msleep(1000);
+
+       reset_hw();
+       dbbusDWIICEnterSerialDebugMode();
+       dbbusDWIICStopMCU();
+       dbbusDWIICIICUseBus();
+       dbbusDWIICIICReshape();
+       msleep(300);
+
+       /* polling 0x3CE4 is 0x1C70 */
+       if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+               do {
+                       reg_data = read_reg(0x3C, 0xE4);
+               } while (reg_data != 0x1C70);
+       }
+
+       switch (emem_type) {
+       case EMEM_ALL:
+               write_reg(0x3C, 0xE4, 0xE38F);  /* for all-blocks */
+               break;
+       case EMEM_MAIN:
+               write_reg(0x3C, 0xE4, 0x7731);  /* for main block */
+               break;
+       case EMEM_INFO:
+               write_reg(0x3C, 0xE4, 0x7731);  /* for info block */
+
+               write_reg_8bit(0x0F, 0xE6, 0x01);
+
+               write_reg_8bit(0x3C, 0xE4, 0xC5);
+               write_reg_8bit(0x3C, 0xE5, 0x78);
+
+               write_reg_8bit(0x1E, 0x04, 0x9F);
+               write_reg_8bit(0x1E, 0x05, 0x82);
+
+               write_reg_8bit(0x0F, 0xE6, 0x00);
+               msleep(100);
+               break;
+       }
+
+       /* polling 0x3CE4 is 0x2F43 */
+       do {
+               reg_data = read_reg(0x3C, 0xE4);
+       } while (reg_data != 0x2F43);
+
+       /* calculate CRC 32 */
+       _CRC_initTable();
+
+       /* total  32 KB : 2 byte per R/W */
+       for (i = 0; i < 32; i++) {
+               if (i == 31) {
+                       temp[i][1014] = 0x5A;
+                       temp[i][1015] = 0xA5;
+
+                       for (j = 0; j < 1016; j++)
+                               crc_main = _CRC_getValue(temp[i][j], crc_main);
+               } else {
+                       for (j = 0; j < 1024; j++)
+                               crc_main = _CRC_getValue(temp[i][j], crc_main);
+               }
+
+               for (j = 0; j < 8; j++)
+                       write_i2c_seq(ts_data->client->addr,
+                                               &temp[i][j*128], 128);
+               msleep(100);
+
+               /* polling 0x3CE4 is 0xD0BC */
+               do {
+                       reg_data = read_reg(0x3C, 0xE4);
+               } while (reg_data != 0xD0BC);
+
+               write_reg(0x3C, 0xE4, 0x2F43);
+       }
+
+       if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+               /* write file done and check crc */
+               write_reg(0x3C, 0xE4, 0x1380);
+       }
+       msleep(20);
+
+       if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+               /* polling 0x3CE4 is 0x9432 */
+               do {
+                       reg_data = read_reg(0x3C, 0xE4);
+               } while (reg_data != 0x9432);
+       }
+
+       crc_main = crc_main ^ 0xffffffff;
+       crc_info = crc_info ^ 0xffffffff;
+
+       if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+               /* CRC Main from TP */
+               crc_main_tp = read_reg(0x3C, 0x80);
+               crc_main_tp = (crc_main_tp << 16) | read_reg(0x3C, 0x82);
+
+               /* CRC Info from TP */
+               crc_info_tp = read_reg(0x3C, 0xA0);
+               crc_info_tp = (crc_info_tp << 16) | read_reg(0x3C, 0xA2);
+       }
+
+       update_pass = 1;
+       if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+               if (crc_main_tp != crc_main)
+                       update_pass = 0;
+       }
+
+       if (!update_pass) {
+               DBG("update_C33 failed\n");
+               reset_hw();
+               FwDataCnt = 0;
+               return 0;
+       }
+
+       DBG("update_C33 OK\n");
+       reset_hw();
+       FwDataCnt = 0;
+       return size;
 }
-
 #ifdef FIRMWARE_AUTOUPDATE
-unsigned short main_sw_id = 0x7FF, info_sw_id = 0x7FF;
-U32 bin_conf_crc32 = 0;
+static unsigned short main_sw_id = 0x7FF, info_sw_id = 0x7FF;
+static unsigned int bin_conf_crc32;
 
-static U32 _CalMainCRC32(void)
+static unsigned int _CalMainCRC32(void)
 {
-    U32 ret=0;
-    U16  reg_data=0;
+       unsigned int ret = 0;
+       unsigned short reg_data = 0;
 
-    reset_hw();
+       reset_hw();
 
-    dbbusDWIICEnterSerialDebugMode();
-    dbbusDWIICStopMCU();
-    dbbusDWIICIICUseBus();
-    dbbusDWIICIICReshape();
-    msleep ( 100 );
+       dbbusDWIICEnterSerialDebugMode();
+       dbbusDWIICStopMCU();
+       dbbusDWIICIICUseBus();
+       dbbusDWIICIICReshape();
+       msleep(100);
 
-    //Stop MCU
-    write_reg ( 0x0F, 0xE6, 0x0001 );
+       /* Stop MCU */
+       write_reg(0x0F, 0xE6, 0x0001);
 
-    // Stop Watchdog
-    write_reg_8bit ( 0x3C, 0x60, 0x55 );
-    write_reg_8bit ( 0x3C, 0x61, 0xAA );
+       /* Stop Watchdog */
+       write_reg_8bit(0x3C, 0x60, 0x55);
+       write_reg_8bit(0x3C, 0x61, 0xAA);
 
-    //cmd
-    write_reg ( 0x3C, 0xE4, 0xDF4C );
-    write_reg ( 0x1E, 0x04, 0x7d60 );
-    // TP SW reset
-    write_reg ( 0x1E, 0x04, 0x829F );
+       /* cmd */
+       write_reg(0x3C, 0xE4, 0xDF4C);
+       write_reg(0x1E, 0x04, 0x7d60);
+       /* TP SW reset */
+       write_reg(0x1E, 0x04, 0x829F);
 
-    //MCU run
-    write_reg ( 0x0F, 0xE6, 0x0000 );
+       /* MCU run */
+       write_reg(0x0F, 0xE6, 0x0000);
 
-    //polling 0x3CE4
-    do
-    {
-        reg_data = read_reg ( 0x3C, 0xE4 );
-    }while ( reg_data != 0x9432 );
+       /* polling 0x3CE4 */
+       do {
+               reg_data = read_reg(0x3C, 0xE4);
+       } while (reg_data != 0x9432);
 
-    // Cal CRC Main from TP
-    ret = read_reg ( 0x3C, 0x80 );
-    ret = ( ret << 16 ) | read_reg ( 0x3C, 0x82 );
+       /* Cal CRC Main from TP */
+       ret = read_reg(0x3C, 0x80);
+       ret = (ret << 16) | read_reg(0x3C, 0x82);
 
-    DBG("[21xxA]:Current main crc32=0x%x\n",ret);
-    return (ret);
+       DBG("[21xxA]:Current main crc32=0x%x\n", ret);
+       return ret;
 }
 
-static void _ReadBinConfig ( void )
+static void _ReadBinConfig(void)
 {
-    U8  dbbus_tx_data[5]={0};
-    U8  dbbus_rx_data[4]={0};
-    U16 reg_data=0;
-
-    reset_hw();
-
-    dbbusDWIICEnterSerialDebugMode();
-    dbbusDWIICStopMCU();
-    dbbusDWIICIICUseBus();
-    dbbusDWIICIICReshape();
-    msleep ( 100 );
-
-    //Stop MCU
-    write_reg ( 0x0F, 0xE6, 0x0001 );
-
-    // Stop Watchdog
-    write_reg_8bit ( 0x3C, 0x60, 0x55 );
-    write_reg_8bit ( 0x3C, 0x61, 0xAA );
-
-    //cmd
-    write_reg ( 0x3C, 0xE4, 0xA4AB );
-    write_reg ( 0x1E, 0x04, 0x7d60 );
-
-    // TP SW reset
-    write_reg ( 0x1E, 0x04, 0x829F );
-
-    //MCU run
-    write_reg ( 0x0F, 0xE6, 0x0000 );
-
-   //polling 0x3CE4
-    do
-    {
-        reg_data = read_reg ( 0x3C, 0xE4 );
-    }
-    while ( reg_data != 0x5B58 );
-
-    dbbus_tx_data[0] = 0x72;
-    dbbus_tx_data[1] = 0x7F;
-    dbbus_tx_data[2] = 0x55;
-    dbbus_tx_data[3] = 0x00;
-    dbbus_tx_data[4] = 0x04;
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
-    if ((dbbus_rx_data[0]>=0x30 && dbbus_rx_data[0]<=0x39)
-        &&(dbbus_rx_data[1]>=0x30 && dbbus_rx_data[1]<=0x39)
-        &&(dbbus_rx_data[2]>=0x31 && dbbus_rx_data[2]<=0x39))
-    {
-       main_sw_id = (dbbus_rx_data[0]-0x30)*100+(dbbus_rx_data[1]-0x30)*10+(dbbus_rx_data[2]-0x30);
-    }
-
-    dbbus_tx_data[0] = 0x72;
-    dbbus_tx_data[1] = 0x7F;
-    dbbus_tx_data[2] = 0xFC;
-    dbbus_tx_data[3] = 0x00;
-    dbbus_tx_data[4] = 0x04;
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
-    bin_conf_crc32 = dbbus_rx_data[0];
-    bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[1];
-    bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[2];
-    bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[3];
-
-    dbbus_tx_data[0] = 0x72;
-    dbbus_tx_data[1] = 0x83;
-    dbbus_tx_data[2] = 0x00;
-    dbbus_tx_data[3] = 0x00;
-    dbbus_tx_data[4] = 0x04;
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
-    if ((dbbus_rx_data[0]>=0x30 && dbbus_rx_data[0]<=0x39)
-        &&(dbbus_rx_data[1]>=0x30 && dbbus_rx_data[1]<=0x39)
-        &&(dbbus_rx_data[2]>=0x31 && dbbus_rx_data[2]<=0x39))
-    {
-       info_sw_id = (dbbus_rx_data[0]-0x30)*100+(dbbus_rx_data[1]-0x30)*10+(dbbus_rx_data[2]-0x30);
-    }
-
-    DBG("[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32=0x%x\n", main_sw_id, info_sw_id, bin_conf_crc32);
+       unsigned char dbbus_tx_data[5] = {0};
+       unsigned char dbbus_rx_data[4] = {0};
+       unsigned short reg_data = 0;
+
+       reset_hw();
+
+       dbbusDWIICEnterSerialDebugMode();
+       dbbusDWIICStopMCU();
+       dbbusDWIICIICUseBus();
+       dbbusDWIICIICReshape();
+       msleep(100);
+
+       /* Stop MCU */
+       write_reg(0x0F, 0xE6, 0x0001);
+
+       /* Stop Watchdog */
+       write_reg_8bit(0x3C, 0x60, 0x55);
+       write_reg_8bit(0x3C, 0x61, 0xAA);
+
+       /* cmd */
+       write_reg(0x3C, 0xE4, 0xA4AB);
+       write_reg(0x1E, 0x04, 0x7d60);
+
+       /* TP SW reset */
+       write_reg(0x1E, 0x04, 0x829F);
+
+       /* MCU run */
+       write_reg(0x0F, 0xE6, 0x0000);
+
+       /* polling 0x3CE4 */
+       do {
+               reg_data = read_reg(0x3C, 0xE4);
+       } while (reg_data != 0x5B58);
+
+       dbbus_tx_data[0] = 0x72;
+       dbbus_tx_data[1] = 0x7F;
+       dbbus_tx_data[2] = 0x55;
+       dbbus_tx_data[3] = 0x00;
+       dbbus_tx_data[4] = 0x04;
+       write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+       read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+       if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39)
+               && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39)
+               && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) {
+               main_sw_id = (dbbus_rx_data[0] - 0x30) * 100 +
+                                       (dbbus_rx_data[1] - 0x30) * 10 +
+                                       (dbbus_rx_data[2] - 0x30);
+       }
+
+       dbbus_tx_data[0] = 0x72;
+       dbbus_tx_data[1] = 0x7F;
+       dbbus_tx_data[2] = 0xFC;
+       dbbus_tx_data[3] = 0x00;
+       dbbus_tx_data[4] = 0x04;
+       write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+       read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+       bin_conf_crc32 = dbbus_rx_data[0];
+       bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[1];
+       bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[2];
+       bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[3];
+
+       dbbus_tx_data[0] = 0x72;
+       dbbus_tx_data[1] = 0x83;
+       dbbus_tx_data[2] = 0x00;
+       dbbus_tx_data[3] = 0x00;
+       dbbus_tx_data[4] = 0x04;
+       write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+       read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+       if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39)
+               && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39)
+               && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) {
+               info_sw_id = (dbbus_rx_data[0] - 0x30) * 100 +
+                                       (dbbus_rx_data[1] - 0x30) * 10 +
+                                       (dbbus_rx_data[2] - 0x30);
+       }
+
+       DBG("[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32=0x%x\n",
+                       main_sw_id, info_sw_id, bin_conf_crc32);
 }
 
 static int fwAutoUpdate(void *unused)
 {
-    int time = 0;
-    ssize_t ret = 0;
-
-    for (time = 0; time < 5; time++)
-    {
-        DBG("fwAutoUpdate time = %d\n",time);
-        ret = firmware_update_c33(NULL, NULL, NULL, 1, EMEM_MAIN);
-        if (ret == 1)
-        {
-            DBG("AUTO_UPDATE OK!!!");
-            break;
-        }
-    }
-    if (time == 5)
-    {
-        DBG("AUTO_UPDATE failed!!!");
-    }
-    enable_irq(irq_msg21xx);
-    return 0;
+       int time = 0;
+       ssize_t ret = 0;
+
+       for (time = 0; time < 5; time++) {
+               DBG("fwAutoUpdate time = %d\n", time);
+               ret = firmware_update_c33(NULL, NULL, NULL, 1, EMEM_MAIN);
+               if (ret == 1) {
+                       DBG("AUTO_UPDATE OK!!!");
+                       break;
+               }
+       }
+       if (time == 5)
+               DBG("AUTO_UPDATE failed!!!");
+       enable_irq(ts_data->client->irq);
+       return 0;
 }
 #endif
 
-//------------------------------------------------------------------------------//
 static ssize_t firmware_update_show(struct device *dev,
-                                    struct device_attribute *attr, char *buf)
+                                               struct device_attribute *attr,
+                                               char *buf)
 {
-    DBG("*** firmware_update_show() fw_version = %s ***\n", fw_version);
+       DBG("*** firmware_update_show() fw_version = %s ***\n", fw_version);
 
-    return sprintf(buf, "%s\n", fw_version);
+       return snprintf(buf, sizeof(char) - 1, "%s\n", fw_version);
 }
 
 static ssize_t firmware_update_store(struct device *dev,
-                                     struct device_attribute *attr, const char *buf, size_t size)
+                                               struct device_attribute *attr,
+                                               const char *buf,
+                                               size_t size)
 {
-    bFwUpdating = 1;
-    disable_irq(irq_msg21xx);
+       bFwUpdating = 1;
+       disable_irq(ts_data->client->irq);
 
-    DBG("*** update fw size = %d ***\n", FwDataCnt);
-    size = firmware_update_c33 (dev, attr, buf, size, EMEM_MAIN);
+       DBG("*** update fw size = %d ***\n", FwDataCnt);
+       size = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN);
 
-    enable_irq(irq_msg21xx);
-    bFwUpdating = 0;
+       enable_irq(ts_data->client->irq);
+       bFwUpdating = 0;
 
-    return size;
+       return size;
 }
 
-static DEVICE_ATTR(update, SYSFS_AUTHORITY, firmware_update_show, firmware_update_store);
+static DEVICE_ATTR(update, (S_IRUGO | S_IWUSR),
+                                       firmware_update_show,
+                                       firmware_update_store);
 
 static ssize_t firmware_version_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+                                       struct device_attribute *attr,
+                                       char *buf)
 {
-    DBG("*** firmware_version_show() fw_version = %s ***\n", fw_version);
+       DBG("*** firmware_version_show() fw_version = %s ***\n", fw_version);
 
-    return sprintf(buf, "%s\n", fw_version);
+       return snprintf(buf, sizeof(char) - 1, "%s\n", fw_version);
 }
 
 static ssize_t firmware_version_store(struct device *dev,
-                                      struct device_attribute *attr, const char *buf, size_t size)
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t size)
 {
-    get_customer_firmware_version();
+       get_customer_firmware_version();
 
-    DBG("*** firmware_version_store() fw_version = %s ***\n", fw_version);
+       DBG("*** firmware_version_store() fw_version = %s ***\n", fw_version);
 
-    return size;
+       return size;
 }
 
-static DEVICE_ATTR(version, SYSFS_AUTHORITY, firmware_version_show, firmware_version_store);
+static DEVICE_ATTR(version, (S_IRUGO | S_IWUSR),
+                                       firmware_version_show,
+                                       firmware_version_store);
 
 static ssize_t firmware_data_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
+                                         struct device_attribute *attr,
+                                         char *buf)
 {
-    DBG("*** firmware_data_show() FwDataCnt = %d ***\n", FwDataCnt);
+       DBG("*** firmware_data_show() FwDataCnt = %d ***\n", FwDataCnt);
 
-    return FwDataCnt;
+       return FwDataCnt;
 }
 
 static ssize_t firmware_data_store(struct device *dev,
-                                   struct device_attribute *attr, const char *buf, size_t size)
+                                       struct device_attribute *attr,
+                                       const char *buf,
+                                       size_t size)
 {
-    int count = size / 1024;
-    int i;
+       int count = size / 1024;
+       int i;
 
-    for (i = 0; i < count; i ++)
-    {
-        memcpy(temp[FwDataCnt], buf+(i*1024), 1024);
+       for (i = 0; i < count; i++) {
+               memcpy(temp[FwDataCnt], buf + (i * 1024), 1024);
 
-        FwDataCnt ++;
-    }
+               FwDataCnt++;
+       }
 
-    DBG("***FwDataCnt = %d ***\n", FwDataCnt);
+       DBG("***FwDataCnt = %d ***\n", FwDataCnt);
 
-    if (buf != NULL)
-    {
-        DBG("*** buf[0] = %c ***\n", buf[0]);
-    }
+       if (buf != NULL)
+               DBG("*** buf[0] = %c ***\n", buf[0]);
 
-    return size;
+       return size;
 }
 
-static DEVICE_ATTR(data, SYSFS_AUTHORITY, firmware_data_show, firmware_data_store);
+static DEVICE_ATTR(data, (S_IRUGO | S_IWUSR),
+                       firmware_data_show, firmware_data_store);
 
 #ifdef TP_PRINT
 static ssize_t tp_print_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+                               struct device_attribute *attr,
+                               char *buf)
 {
-    tp_print_proc_read();
+       tp_print_proc_read();
 
-    return sprintf(buf, "%d\n", bTpInSuspend);
+       return snprintf(buf, sizeof(char) - 1, "%d\n", ts_data->suspended);
 }
 
 static ssize_t tp_print_store(struct device *dev,
-                                      struct device_attribute *attr, const char *buf, size_t size)
+                               struct device_attribute *attr,
+                               const char *buf,
+                               size_t size)
 {
-    DBG("*** tp_print_store() ***\n");
+       DBG("*** tp_print_store() ***\n");
 
-    return size;
+       return size;
 }
 
-static DEVICE_ATTR(tpp, SYSFS_AUTHORITY, tp_print_show, tp_print_store);
+static DEVICE_ATTR(tpp, (S_IRUGO | S_IWUSR),
+                               tp_print_show, tp_print_store);
 #endif
 
-//------------------------------------------------------------------------------//
 #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static void _msg_enable_proximity(void)
+static void _msg_enable_proximity(void
 {
-    U8 tx_data[4] = {0};
-
-    DBG("_msg_enable_proximity!");
-    tx_data[0] = 0x52;
-    tx_data[1] = 0x00;
-    tx_data[2] = 0x47;
-    tx_data[3] = 0xa0;
-    mutex_lock(&msg21xx_mutex);
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &tx_data[0], 4);
-    mutex_unlock(&msg21xx_mutex);
-
-    bEnableTpProximity = 1;
+       unsigned char tx_data[4] = {0};
+
+       DBG("_msg_enable_proximity!");
+       tx_data[0] = 0x52;
+       tx_data[1] = 0x00;
+       tx_data[2] = 0x47;
+       tx_data[3] = 0xa0;
+       mutex_lock(&msg21xx_mutex);
+       write_i2c_seq(ts_data->client->addr, &tx_data[0], 4);
+       mutex_unlock(&msg21xx_mutex);
+
+       bEnableTpProximity = 1;
 }
 
 static void _msg_disable_proximity(void)
 {
-    U8 tx_data[4] = {0};
-
-    DBG("_msg_disable_proximity!");
-    tx_data[0] = 0x52;
-    tx_data[1] = 0x00;
-    tx_data[2] = 0x47;
-    tx_data[3] = 0xa1;
-    mutex_lock(&msg21xx_mutex);
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &tx_data[0], 4);
-    mutex_unlock(&msg21xx_mutex);
-
-    bEnableTpProximity = 0;
-    bFaceClosingTp = 0;
+       unsigned char tx_data[4] = {0};
+
+       DBG("_msg_disable_proximity!");
+       tx_data[0] = 0x52;
+       tx_data[1] = 0x00;
+       tx_data[2] = 0x47;
+       tx_data[3] = 0xa1;
+       mutex_lock(&msg21xx_mutex);
+       write_i2c_seq(ts_data->client->addr, &tx_data[0], 4);
+       mutex_unlock(&msg21xx_mutex);
+
+       bEnableTpProximity = 0;
+       bFaceClosingTp = 0;
 }
 
-void tsps_msg21xx_enable(int en)
+static void tsps_msg21xx_enable(int en)
 {
-    if (en)
-    {
-        _msg_enable_proximity();
-    }
-    else
-    {
-        _msg_disable_proximity();
-    }
+       if (en)
+               _msg_enable_proximity();
+       else
+               _msg_disable_proximity();
 }
 
-int tsps_msg21xx_data(void)
+static int tsps_msg21xx_data(void)
 {
-    return bFaceClosingTp;
+       return bFaceClosingTp;
 }
 #endif
 
-static U8 calculate_checksum(U8 *msg, S32 length)
+static int msg21xx_pinctrl_init(void)
+{
+       int retval;
+
+       /* Get pinctrl if target uses pinctrl */
+       ts_data->ts_pinctrl = devm_pinctrl_get(&(i2c_client->dev));
+       if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) {
+               retval = PTR_ERR(ts_data->ts_pinctrl);
+               dev_dbg(&i2c_client->dev,
+                       "Target does not use pinctrl %d\n", retval);
+               goto err_pinctrl_get;
+       }
+
+       ts_data->pinctrl_state_active = pinctrl_lookup_state(
+                       ts_data->ts_pinctrl, PINCTRL_STATE_ACTIVE);
+       if (IS_ERR_OR_NULL(ts_data->pinctrl_state_active)) {
+               retval = PTR_ERR(ts_data->pinctrl_state_active);
+               dev_dbg(&i2c_client->dev,
+                       "Can't lookup %s pinstate %d\n",
+                       PINCTRL_STATE_ACTIVE, retval);
+               goto err_pinctrl_lookup;
+       }
+
+       ts_data->pinctrl_state_suspend = pinctrl_lookup_state(
+                       ts_data->ts_pinctrl, PINCTRL_STATE_SUSPEND);
+       if (IS_ERR_OR_NULL(ts_data->pinctrl_state_suspend)) {
+               retval = PTR_ERR(ts_data->pinctrl_state_suspend);
+               dev_dbg(&i2c_client->dev,
+                       "Can't lookup %s pinstate %d\n",
+                       PINCTRL_STATE_SUSPEND, retval);
+               goto err_pinctrl_lookup;
+       }
+
+       ts_data->pinctrl_state_release = pinctrl_lookup_state(
+                       ts_data->ts_pinctrl, PINCTRL_STATE_RELEASE);
+       if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+               retval = PTR_ERR(ts_data->pinctrl_state_release);
+               dev_dbg(&i2c_client->dev,
+                       "Can't lookup %s pinstate %d\n",
+                       PINCTRL_STATE_RELEASE, retval);
+       }
+
+       return 0;
+
+err_pinctrl_lookup:
+       devm_pinctrl_put(ts_data->ts_pinctrl);
+err_pinctrl_get:
+       ts_data->ts_pinctrl = NULL;
+       return retval;
+}
+
+static unsigned char calculate_checksum(unsigned char *msg, int length)
 {
-    S32 Checksum = 0;
-    S32 i;
+       int Checksum = 0, i;
 
-    for (i = 0; i < length; i ++)
-    {
-        Checksum += msg[i];
-    }
+       for (i = 0; i < length; i++)
+               Checksum += msg[i];
 
-    return (U8)((-Checksum) & 0xFF);
+       return (unsigned char)((-Checksum) & 0xFF);
 }
 
-static S32 parse_info(touchInfo_t *info)
+static int parse_info(struct touchInfo_t *info)
 {
-    U8 data[DEMO_MODE_PACKET_LENGTH] = {0};
-    U8 checksum = 0;
-    U32 x = 0, y = 0;
-    U32 x2 = 0, y2 = 0;
-    U32 delta_x = 0, delta_y = 0;
-
-    mutex_lock(&msg21xx_mutex);
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &data[0], DEMO_MODE_PACKET_LENGTH);
-    mutex_unlock(&msg21xx_mutex);
-    checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1));
-    DBG("check sum: [%x] == [%x]? \n", data[DEMO_MODE_PACKET_LENGTH-1], checksum);
-
-    if(data[DEMO_MODE_PACKET_LENGTH-1] != checksum)
-    {
-        DBG("WRONG CHECKSUM\n");
-        return -1;
-    }
-
-    if(data[0] != 0x52)
-    {
-        DBG("WRONG HEADER\n");
-        return -1;
-    }
-
-    info->keycode = 0xFF;
-    if ((data[1] == 0xFF) && (data[2] == 0xFF) && (data[3] == 0xFF) && (data[4] == 0xFF) && (data[6] == 0xFF))
-    {
-        if ((data[5] == 0xFF) || (data[5] == 0))
-        {
-            info->keycode = 0xFF;
-        }
-        else if ((data[5] == 1) || (data[5] == 2) || (data[5] == 4) || (data[5] == 8))
-        {
-            if (data[5] == 1)
-            {
-                info->keycode = 0;
-            }
-            else if (data[5] == 2)
-            {
-                info->keycode = 1;
-            }
-            else if (data[5] == 4)
-            {
-                info->keycode = 2;
-            }
-            else if (data[5] == 8)
-            {
-                info->keycode = 3;
-            }
-        }
-    #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-        else if (bEnableTpProximity &&((data[5] == 0x80) || (data[5] == 0x40)))
-        {
-            if (data[5] == 0x80)
-            {
-                bFaceClosingTp = 1;
-            }
-            else if (data[5] == 0x40)
-            {
-                bFaceClosingTp = 0;
-            }
-            DBG("bEnableTpProximity=%d; bFaceClosingTp=%d; data[5]=%x;\n", bEnableTpProximity, bFaceClosingTp, data[5]);
-            return -1;
-        }
-    #endif
-        else
-        {
-            DBG("WRONG KEY\n");
-            return -1;
-        }
-    }
-    else
-    {
-        x = (((data[1] & 0xF0 ) << 4) | data[2]);
-        y = ((( data[1] & 0x0F) << 8) | data[3]);
-        delta_x = (((data[4] & 0xF0) << 4 ) | data[5]);
-        delta_y = (((data[4] & 0x0F) << 8 ) | data[6]);
-
-        if ((delta_x == 0) && (delta_y == 0))
-        {
-            info->point[0].x = x * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
-            info->point[0].y = y * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
-            info->count = 1;
-        }
-        else
-        {
-            if (delta_x > 2048)
-            {
-                delta_x -= 4096;
-            }
-            if (delta_y > 2048)
-            {
-                delta_y -= 4096;
-            }
-            x2 = (U32)((S16)x + (S16)delta_x);
-            y2 = (U32)((S16)y + (S16)delta_y);
-            info->point[0].x = x * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
-            info->point[0].y = y * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
-            info->point[1].x = x2 * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
-            info->point[1].y = y2 * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
-            info->count = 2;
-        }
-    }
-
-    return 0;
+       unsigned char data[DEMO_MODE_PACKET_LENGTH] = {0};
+       unsigned char checksum = 0;
+       unsigned int x = 0, y = 0;
+       unsigned int x2 = 0, y2 = 0;
+       unsigned int delta_x = 0, delta_y = 0;
+
+       mutex_lock(&msg21xx_mutex);
+       read_i2c_seq(ts_data->client->addr, &data[0], DEMO_MODE_PACKET_LENGTH);
+       mutex_unlock(&msg21xx_mutex);
+       checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1));
+       DBG("check sum: [%x] == [%x]?\n",
+                       data[DEMO_MODE_PACKET_LENGTH-1], checksum);
+
+       if (data[DEMO_MODE_PACKET_LENGTH-1] != checksum) {
+               DBG("WRONG CHECKSUM\n");
+               return -EINVAL;
+       }
+
+       if (data[0] != 0x52) {
+               DBG("WRONG HEADER\n");
+               return -EINVAL;
+       }
+
+       info->keycode = 0xFF;
+       if ((data[1] == 0xFF) && (data[2] == 0xFF) &&
+               (data[3] == 0xFF) && (data[4] == 0xFF) &&
+               (data[6] == 0xFF)) {
+               if ((data[5] == 0xFF) || (data[5] == 0)) {
+                       info->keycode = 0xFF;
+               } else if ((data[5] == 1) || (data[5] == 2) ||
+                               (data[5] == 4) || (data[5] == 8)) {
+                       info->keycode = data[5] >> 1;
+
+                       DBG("info->keycode index %d\n", info->keycode);
+               }
+       #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+               else if (bEnableTpProximity && ((data[5] == 0x80) ||
+                                       (data[5] == 0x40))) {
+                       if (data[5] == 0x80)
+                               bFaceClosingTp = 1;
+                       else if (data[5] == 0x40)
+                               bFaceClosingTp = 0;
+
+                       return -EINVAL;
+               }
+       #endif
+               else {
+                       DBG("WRONG KEY\n");
+                       return -EINVAL;
+               }
+       } else {
+               x = (((data[1] & 0xF0) << 4) | data[2]);
+               y = (((data[1] & 0x0F) << 8) | data[3]);
+               delta_x = (((data[4] & 0xF0) << 4) | data[5]);
+               delta_y = (((data[4] & 0x0F) << 8) | data[6]);
+
+               if ((delta_x == 0) && (delta_y == 0)) {
+                       info->point[0].x = x * pdata->x_max / TPD_WIDTH;
+                       info->point[0].y = y * pdata->y_max / TPD_HEIGHT;
+                       info->count = 1;
+               } else {
+                       if (delta_x > 2048)
+                               delta_x -= 4096;
+
+                       if (delta_y > 2048)
+                               delta_y -= 4096;
+
+                       x2 = (unsigned int)((signed short)x +
+                                               (signed short)delta_x);
+                       y2 = (unsigned int)((signed short)y +
+                                               (signed short)delta_y);
+                       info->point[0].x = x * pdata->x_max / TPD_WIDTH;
+                       info->point[0].y = y * pdata->y_max / TPD_HEIGHT;
+                       info->point[1].x = x2 * pdata->x_max / TPD_WIDTH;
+                       info->point[1].y = y2 * pdata->y_max / TPD_HEIGHT;
+                       info->count = 2;
+               }
+       }
+
+       return 0;
 }
 
-static void touch_driver_touch_pressed(int x, int y)
+static void touch_driver_touch_released(void)
 {
-    DBG("point touch pressed");
+       int i;
+
+       DBG("point touch released\n");
+
+       for (i = 0; i < MAX_TOUCH_NUM; i++) {
+               input_mt_slot(input_dev, i);
+               input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+       }
 
-    input_report_key(input_dev, BTN_TOUCH, 1);
-    input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 1);
-    input_report_abs(input_dev, ABS_MT_POSITION_X, x);
-    input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
-    input_mt_sync(input_dev);
+       input_report_key(input_dev, BTN_TOUCH, 0);
+       input_report_key(input_dev, BTN_TOOL_FINGER, 0);
+       input_sync(input_dev);
 }
 
-static void touch_driver_touch_released(void)
+/* read data through I2C then report data to input
+ *sub-system when interrupt occurred
+ */
+static irqreturn_t msg21xx_ts_interrupt(int irq, void *dev_id)
+{
+       struct touchInfo_t info;
+       int i = 0;
+       static int last_keycode = 0xFF;
+       static int last_count;
+
+       DBG("touch_driver_do_work()\n");
+
+       memset(&info, 0x0, sizeof(info));
+       if (parse_info(&info) == 0) {
+       #ifdef CONFIG_TP_HAVE_KEY
+               if (info.keycode != 0xFF) {   /* key touch pressed */
+                       if (info.keycode < num_buttons) {
+                               if (info.keycode != last_keycode) {
+                                       DBG("key touch pressed");
+
+                                       input_report_key(input_dev,
+                                                       BTN_TOUCH, 1);
+                                       input_report_key(input_dev,
+                                               button_map[info.keycode], 1);
+
+                                       last_keycode = info.keycode;
+                               } else {
+                                       /* pass duplicate key-pressing */
+                                       DBG("REPEATED KEY\n");
+                               }
+                       } else {
+                               DBG("WRONG KEY\n");
+                       }
+               } else {  /* key touch released */
+                       if (last_keycode != 0xFF) {
+                               DBG("key touch released");
+
+                               input_report_key(input_dev,
+                                               BTN_TOUCH, 0);
+                               input_report_key(input_dev,
+                                               button_map[last_keycode],
+                                                       0);
+
+                               last_keycode = 0xFF;
+                       }
+               }
+       #endif /* CONFIG_TP_HAVE_KEY */
+
+               if (info.count > 0)     { /* point touch pressed */
+                       for (i = 0; i < info.count; i++) {
+                               input_mt_slot(input_dev, i);
+                               input_mt_report_slot_state(input_dev,
+                                       MT_TOOL_FINGER, 1);
+                               input_report_abs(input_dev,
+                                       ABS_MT_TOUCH_MAJOR, 1);
+                               input_report_abs(input_dev,
+                                       ABS_MT_POSITION_X,
+                                       info.point[i].x);
+                               input_report_abs(input_dev,
+                                       ABS_MT_POSITION_Y,
+                                       info.point[i].y);
+                       }
+                       last_count = info.count;
+               } else if (last_count > 0) { /* point touch released */
+                       for (i = 0; i < last_count; i++) {
+                               input_mt_slot(input_dev, i);
+                               input_mt_report_slot_state(input_dev,
+                                       MT_TOOL_FINGER, 0);
+                       }
+                       last_count = 0;
+               }
+
+               input_report_key(input_dev, BTN_TOUCH, info.count > 0);
+               input_report_key(input_dev, BTN_TOOL_FINGER, info.count > 0);
+
+               input_sync(input_dev);
+       }
+
+       return IRQ_HANDLED;
+}
+
+
+static int msg21xx_ts_power_init(void)
+{
+       int rc;
+
+       vdd = regulator_get(&i2c_client->dev, "vdd");
+       if (IS_ERR(vdd)) {
+               rc = PTR_ERR(vdd);
+               dev_err(&i2c_client->dev,
+                       "Regulator get failed vdd rc=%d\n", rc);
+               return rc;
+       }
+
+       if (regulator_count_voltages(vdd) > 0) {
+               rc = regulator_set_voltage(vdd, MSTAR_VTG_MIN_UV,
+                                          MSTAR_VTG_MAX_UV);
+               if (rc) {
+                       dev_err(&i2c_client->dev,
+                               "Regulator set_vtg failed vdd rc=%d\n", rc);
+                       goto reg_vdd_put;
+               }
+       }
+
+       vcc_i2c = regulator_get(&i2c_client->dev, "vcc_i2c");
+       if (IS_ERR(vcc_i2c)) {
+               rc = PTR_ERR(vcc_i2c);
+               dev_err(&i2c_client->dev,
+                       "Regulator get failed vcc_i2c rc=%d\n", rc);
+               goto reg_vdd_set_vtg;
+       }
+
+       if (regulator_count_voltages(vcc_i2c) > 0) {
+               rc = regulator_set_voltage(vcc_i2c, MSTAR_I2C_VTG_MIN_UV,
+                                          MSTAR_I2C_VTG_MAX_UV);
+               if (rc) {
+                       dev_err(&i2c_client->dev,
+                       "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
+                       goto reg_vcc_i2c_put;
+               }
+       }
+
+       return 0;
+
+reg_vcc_i2c_put:
+       regulator_put(vcc_i2c);
+reg_vdd_set_vtg:
+       if (regulator_count_voltages(vdd) > 0)
+               regulator_set_voltage(vdd, 0, MSTAR_VTG_MAX_UV);
+reg_vdd_put:
+       regulator_put(vdd);
+       return rc;
+}
+
+
+static int msg21xx_ts_power_deinit(void)
+{
+       if (regulator_count_voltages(vdd) > 0)
+               regulator_set_voltage(vdd, 0, MSTAR_VTG_MAX_UV);
+
+       regulator_put(vdd);
+
+       if (regulator_count_voltages(vcc_i2c) > 0)
+               regulator_set_voltage(vcc_i2c, 0, MSTAR_I2C_VTG_MAX_UV);
+
+       regulator_put(vcc_i2c);
+       return 0;
+}
+
+static int msg21xx_ts_power_on(void)
 {
-    DBG("point touch released");
+       int rc;
+
+       DBG("*** %s ***\n", __func__);
+       rc = regulator_enable(vdd);
+       if (rc) {
+               dev_err(&i2c_client->dev,
+                       "Regulator vdd enable failed rc=%d\n", rc);
+               return rc;
+       }
+
+       rc = regulator_enable(vcc_i2c);
+       if (rc) {
+               dev_err(&i2c_client->dev,
+                       "Regulator vcc_i2c enable failed rc=%d\n", rc);
+               regulator_disable(vdd);
+       }
+
+       return rc;
+}
+
+static int msg21xx_ts_power_off(void)
+{
+       int rc;
+
+       DBG("*** %s ***\n", __func__);
+       rc = regulator_disable(vdd);
+       if (rc) {
+               dev_err(&i2c_client->dev,
+                       "Regulator vdd disable failed rc=%d\n", rc);
+               return rc;
+       }
+
+       rc = regulator_disable(vcc_i2c);
+       if (rc) {
+               dev_err(&i2c_client->dev,
+                       "Regulator vcc_i2c disable failed rc=%d\n", rc);
+               rc = regulator_enable(vdd);
+       }
+
+       return rc;
+}
 
-    input_report_key(input_dev, BTN_TOUCH, 0);
-    input_mt_sync(input_dev);
+static int msg21xx_ts_gpio_configure(bool on)
+{
+       int ret = 0;
+
+       if (on) {
+               if (gpio_is_valid(pdata->irq_gpio)) {
+                       ret = gpio_request(pdata->irq_gpio, "msg21xx_irq_gpio");
+                       if (ret) {
+                               dev_err(&i2c_client->dev,
+                                       "Failed to request GPIO[%d], %d\n",
+                                       pdata->irq_gpio, ret);
+                               goto err_irq_gpio_req;
+                       }
+                       ret = gpio_direction_input(pdata->irq_gpio);
+                       if (ret) {
+                               dev_err(&i2c_client->dev,
+                                       "Failed to set direction for gpio[%d], %d\n",
+                                       pdata->irq_gpio, ret);
+                               goto err_irq_gpio_dir;
+                       }
+                       gpio_set_value_cansleep(pdata->irq_gpio, 1);
+               } else {
+                       dev_err(&i2c_client->dev, "irq gpio not provided\n");
+                       goto err_irq_gpio_req;
+               }
+
+               if (gpio_is_valid(pdata->reset_gpio)) {
+                       ret = gpio_request(pdata->reset_gpio,
+                                               "msg21xx_reset_gpio");
+                       if (ret) {
+                               dev_err(&i2c_client->dev,
+                                       "Failed to request GPIO[%d], %d\n",
+                                       pdata->reset_gpio, ret);
+                               goto err_reset_gpio_req;
+                       }
+
+                       /* power on TP */
+                       ret = gpio_direction_output(pdata->reset_gpio, 1);
+                       if (ret) {
+                               dev_err(&i2c_client->dev,
+                                       "Failed to set direction for GPIO[%d], %d\n",
+                                       pdata->reset_gpio, ret);
+                               goto err_reset_gpio_dir;
+                       }
+                       msleep(100);
+                       gpio_set_value_cansleep(pdata->reset_gpio, 0);
+                       msleep(20);
+                       gpio_set_value_cansleep(pdata->reset_gpio, 1);
+                       msleep(200);
+               } else {
+                       dev_err(&i2c_client->dev, "reset gpio not provided\n");
+                       goto err_reset_gpio_req;
+               }
+
+       } else {
+               if (gpio_is_valid(pdata->irq_gpio))
+                       gpio_free(pdata->irq_gpio);
+               if (gpio_is_valid(pdata->reset_gpio)) {
+                       gpio_set_value_cansleep(pdata->reset_gpio, 0);
+                       ret = gpio_direction_input(pdata->reset_gpio);
+                       if (ret)
+                               dev_err(&i2c_client->dev,
+                                       "Unable to set direction for gpio [%d]\n",
+                                       pdata->reset_gpio);
+                       gpio_free(pdata->reset_gpio);
+               }
+       }
+       return 0;
+err_reset_gpio_dir:
+       if (gpio_is_valid(pdata->reset_gpio))
+               gpio_free(pdata->irq_gpio);
+err_reset_gpio_req:
+err_irq_gpio_dir:
+       if (gpio_is_valid(pdata->irq_gpio))
+               gpio_free(pdata->irq_gpio);
+err_irq_gpio_req:
+       return ret;
 }
 
-/* read data through I2C then report data to input sub-system when interrupt occurred */
-void touch_driver_do_work(struct work_struct *work)
+#ifdef CONFIG_PM
+static int msg21xx_ts_resume(struct device *dev)
 {
-    touchInfo_t info;
-    int i = 0;
-    static int last_keycode = 0xFF;
-    static int last_count = 0;
-
-    DBG("touch_driver_do_work()\n");
-
-    memset(&info, 0x0, sizeof(info));
-    if (0 == parse_info(&info))
-    {
-    #ifdef CONFIG_TP_HAVE_KEY
-        if (info.keycode != 0xFF)   //key touch pressed
-        {
-            DBG("touch_driver_do_work() info.keycode=%x, last_keycode=%x, tp_key_array[%d]=%d\n", info.keycode, last_keycode, info.keycode, tp_key_array[info.keycode]);
-            if (info.keycode < MAX_KEY_NUM)
-            {
-                if (info.keycode != last_keycode)
-                {
-                    DBG("key touch pressed");
-
-                    input_report_key(input_dev, BTN_TOUCH, 1);
-                    input_report_key(input_dev, tp_key_array[info.keycode], 1);
-
-                    last_keycode = info.keycode;
-                }
-                else
-                {
-                    /// pass duplicate key-pressing
-                    DBG("REPEATED KEY\n");
-                }
-            }
-            else
-            {
-                DBG("WRONG KEY\n");
-            }
-        }
-        else                        //key touch released
-        {
-            if (last_keycode != 0xFF)
-            {
-                DBG("key touch released");
-
-                input_report_key(input_dev, BTN_TOUCH, 0);
-                input_report_key(input_dev, tp_key_array[last_keycode], 0);
-
-                last_keycode = 0xFF;
-            }
-        }
-    #endif //CONFIG_TP_HAVE_KEY
-
-        if (info.count > 0)          //point touch pressed
-        {
-            for (i = 0; i < info.count; i ++)
-            {
-                touch_driver_touch_pressed(info.point[i].x, info.point[i].y);
-            }
-            last_count = info.count;
-        }
-        else if (last_count > 0)                        //point touch released
-        {
-            touch_driver_touch_released();
-            last_count = 0;
-        }
-
-        input_sync(input_dev);
-    }
-
-    enable_irq(irq_msg21xx);
+       int retval;
+
+       mutex_lock(&ts_data->ts_mutex);
+       if (ts_data->suspended) {
+               if (ts_data->ts_pinctrl) {
+                       retval = pinctrl_select_state(ts_data->ts_pinctrl,
+                                       ts_data->pinctrl_state_active);
+                       if (retval < 0) {
+                               dev_err(dev, "Cannot get active pinctrl state\n");
+                               mutex_unlock(&ts_data->ts_mutex);
+                               return retval;
+                       }
+               }
+
+               retval = msg21xx_ts_gpio_configure(true);
+               if (retval) {
+                       dev_err(dev, "Failed to put gpios in active state %d",
+                                       retval);
+                       mutex_unlock(&ts_data->ts_mutex);
+                       return retval;
+               }
+
+               enable_irq(ts_data->client->irq);
+
+               retval = msg21xx_ts_power_on();
+               if (retval) {
+                       dev_err(dev, "msg21xx_ts power on failed");
+                       mutex_unlock(&ts_data->ts_mutex);
+                       return retval;
+               }
+
+               ts_data->suspended = 0;
+       } else {
+               dev_info(dev, "msg21xx_ts already in resume\n");
+       }
+       mutex_unlock(&ts_data->ts_mutex);
+
+       return 0;
 }
 
-/* The interrupt service routine will be triggered when interrupt occurred */
-irqreturn_t touch_driver_isr(int irq, void *dev_id)
+static int msg21xx_ts_suspend(struct device *dev)
 {
-    DBG("touch_driver_isr()\n");
+       int retval;
+
+       if (bFwUpdating) {
+               DBG("suspend bFwUpdating=%d\n", bFwUpdating);
+               return 0;
+       }
 
-    disable_irq_nosync(irq_msg21xx);
-    schedule_work(&msg21xx_wk);
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+       if (bEnableTpProximity) {
+               DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
+               return 0;
+       }
+#endif
 
-    return IRQ_HANDLED;
+       mutex_lock(&ts_data->ts_mutex);
+       if (ts_data->suspended == 0) {
+               disable_irq(ts_data->client->irq);
+
+               touch_driver_touch_released();
+
+               retval = msg21xx_ts_power_off();
+               if (retval) {
+                       dev_err(dev, "msg21xx_ts power off failed");
+                       mutex_unlock(&ts_data->ts_mutex);
+                       return retval;
+               }
+
+               if (ts_data->ts_pinctrl) {
+                       retval = pinctrl_select_state(ts_data->ts_pinctrl,
+                                       ts_data->pinctrl_state_suspend);
+                       if (retval < 0) {
+                               dev_err(&i2c_client->dev, "Cannot get idle pinctrl state\n");
+                               mutex_unlock(&ts_data->ts_mutex);
+                               return retval;
+                       }
+               }
+
+               retval = msg21xx_ts_gpio_configure(false);
+               if (retval) {
+                       dev_err(dev, "Failed to put gpios in idle state %d",
+                                       retval);
+                       mutex_unlock(&ts_data->ts_mutex);
+                       return retval;
+               }
+
+               ts_data->suspended = 1;
+       } else {
+               dev_err(dev, "msg21xx_ts already in suspend\n");
+       }
+       mutex_unlock(&ts_data->ts_mutex);
+
+
+       return 0;
 }
+#else
+static int msg21xx_ts_resume(struct device *dev)
+{
+       return 0;
+}
+static int msg21xx_ts_suspend(struct device *dev)
+{
+       return 0;
+}
+#endif
 
 #if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
+static int fb_notifier_callback(struct notifier_block *self,
+                               unsigned long event, void *data)
 {
-    struct fb_event *evdata = data;
-    int *blank;
-
-    if (evdata && evdata->data && event == FB_EVENT_BLANK )
-    {
-        blank = evdata->data;
-        if (*blank == FB_BLANK_UNBLANK)
-        {
-            if (bTpInSuspend)
-            {
-                gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
-                mdelay(10);
-                gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-                mdelay(10);
-                gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
-                mdelay(200);
-
-                touch_driver_touch_released();
-                input_sync(input_dev);
-
-                enable_irq(irq_msg21xx);
-            }
-            bTpInSuspend = 0;
-        }
-        else if (*blank == FB_BLANK_POWERDOWN)
-        {
-            if (bFwUpdating)
-            {
-                DBG("suspend bFwUpdating=%d\n", bFwUpdating);
-                return 0;
-            }
-
-        #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-            if (bEnableTpProximity)
-            {
-                DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
-                return 0;
-            }
-        #endif
-
-            if (bTpInSuspend == 0)
-            {
-                disable_irq(irq_msg21xx);
-                gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-            }
-            bTpInSuspend = 1;
-        }
-    }
-
-    return 0;
+       struct fb_event *evdata = data;
+       int *blank;
+
+       if (evdata && evdata->data && event == FB_EVENT_BLANK) {
+               blank = evdata->data;
+               if (*blank == FB_BLANK_UNBLANK)
+                       msg21xx_ts_resume(&i2c_client->dev);
+               else if (*blank == FB_BLANK_POWERDOWN)
+                       msg21xx_ts_suspend(&i2c_client->dev);
+       }
+
+       return 0;
 }
 #endif
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
-void touch_driver_early_suspend(struct early_suspend *p)
+static void touch_driver_early_suspend(struct early_suspend *p)
 {
-    DBG("touch_driver_early_suspend()\n");
+       DBG("touch_driver_early_suspend()\n");
 
-    if (bFwUpdating)
-    {
-        DBG("suspend bFwUpdating=%d\n", bFwUpdating);
-        return;
-    }
+       if (bFwUpdating) {
+               DBG("suspend bFwUpdating=%d\n", bFwUpdating);
+               return;
+       }
 
 #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-    if (bEnableTpProximity)
-    {
-        DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
-        return;
-    }
+       if (bEnableTpProximity) {
+               DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
+               return;
+       }
 #endif
 
-    if (bTpInSuspend == 0)
-    {
-        disable_irq(irq_msg21xx);
-        gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-    }
-    bTpInSuspend = 1;
+       if (bTpInSuspend == 0) {
+               disable_irq(ts_data->client->irq);
+               gpio_set_value_cansleep(pdata->reset_gpio, 0);
+       }
+
+
+       if (msg21xx_ts_power_off())
+               return;
+       bTpInSuspend = 1;
 }
 
-void touch_driver_early_resume(struct early_suspend *p)
+static void touch_driver_early_resume(struct early_suspend *p)
 {
-    DBG("touch_driver_early_resume() bTpInSuspend=%d\n", bTpInSuspend);
-
-    if (bTpInSuspend)
-    {
-        gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
-        mdelay(10);
-        gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-        mdelay(10);
-        gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
-        mdelay(200);
-
-        touch_driver_touch_released();
-        input_sync(input_dev);
-
-        enable_irq(irq_msg21xx);
-    }
-    bTpInSuspend = 0;
+       DBG("touch_driver_early_resume() bTpInSuspend=%d\n", bTpInSuspend);
+
+       if (bTpInSuspend) {
+               gpio_direction_output(pdata->reset_gpio, 1);
+               msleep(20);
+               gpio_set_value_cansleep(pdata->reset_gpio, 0);
+               msleep(20);
+               gpio_set_value_cansleep(pdata->reset_gpio, 1);
+               msleep(200);
+
+               touch_driver_touch_released();
+               input_sync(input_dev);
+
+               enable_irq(ts_data->client->irq);
+
+               if (msg21xx_ts_power_on())
+                       return;
+       }
+       bTpInSuspend = 0;
 }
 #endif
 
-/* probe function is used for matching and initializing input device */
-static int touch_driver_probe(struct i2c_client *client,
-        const struct i2c_device_id *id)
+static int msg21xx_get_dt_coords(struct device *dev, char *name,
+                               struct msg21xx_ts_platform_data *pdata)
+{
+       u32 coords[FT_COORDS_ARR_SIZE];
+       struct property *prop;
+       struct device_node *np = dev->of_node;
+       int coords_size, rc;
+
+       prop = of_find_property(np, name, NULL);
+       if (!prop)
+               return -EINVAL;
+       if (!prop->value)
+               return -ENODATA;
+
+       coords_size = prop->length / sizeof(u32);
+       if (coords_size != FT_COORDS_ARR_SIZE) {
+               dev_err(dev, "invalid %s\n", name);
+               return -EINVAL;
+       }
+
+       rc = of_property_read_u32_array(np, name, coords, coords_size);
+       if (rc && (rc != -EINVAL)) {
+               dev_err(dev, "Unable to read %s\n", name);
+               return rc;
+       }
+
+       if (!strcmp(name, "mstar,panel-coords")) {
+               pdata->panel_minx = coords[0];
+               pdata->panel_miny = coords[1];
+               pdata->panel_maxx = coords[2];
+               pdata->panel_maxy = coords[3];
+       } else if (!strcmp(name, "mstar,display-coords")) {
+               pdata->x_min = coords[0];
+               pdata->y_min = coords[1];
+               pdata->x_max = coords[2];
+               pdata->y_max = coords[3];
+       } else {
+               dev_err(dev, "unsupported property %s\n", name);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int msg21xx_parse_dt(struct device *dev,
+                       struct msg21xx_ts_platform_data *pdata)
 {
+       int rc;
+       struct device_node *np = dev->of_node;
+       struct property *prop;
+       u32 temp_val;
+
+       rc = msg21xx_get_dt_coords(dev, "mstar,panel-coords", pdata);
+       if (rc && (rc != -EINVAL))
+               return rc;
+
+       rc = msg21xx_get_dt_coords(dev, "mstar,display-coords", pdata);
+       if (rc)
+               return rc;
+
+       /* reset, irq gpio info */
+       pdata->reset_gpio = of_get_named_gpio_flags(np, "mstar,reset-gpio",
+                               0, &pdata->reset_gpio_flags);
+       if (pdata->reset_gpio < 0)
+               return pdata->reset_gpio;
+
+       pdata->irq_gpio = of_get_named_gpio_flags(np, "mstar,irq-gpio",
+                               0, &pdata->irq_gpio_flags);
+       if (pdata->irq_gpio < 0)
+               return pdata->irq_gpio;
+
+
+       prop = of_find_property(np, "mstar,button-map", NULL);
+       if (prop) {
+               num_buttons = prop->length / sizeof(temp_val);
+               if (num_buttons > MAX_BUTTONS)
+                       return -EINVAL;
+
+               rc = of_property_read_u32_array(np,
+                       "mstar,button-map", button_map,
+                       num_buttons);
+               if (rc) {
+                       dev_err(dev, "Unable to read key codes\n");
+                       return rc;
+               }
+       }
+
+       return 0;
+}
+
+/* probe function is used for matching and initializing input device */
+static int msg21xx_ts_probe(struct i2c_client *client,
+               const struct i2c_device_id *id) {
 #ifdef FIRMWARE_AUTOUPDATE
-    unsigned short update_bin_major = 0, update_bin_minor = 0;
-    int i, update_flag = 0;
+       unsigned short update_bin_major = 0, update_bin_minor = 0;
+       int i, update_flag = 0;
 #endif
-    int ret = 0;
-
-    if (input_dev != NULL)
-    {
-        DBG("input device has found\n");
-        return -1;
-    }
-
-    DBG("*** %s ***\n", __FUNCTION__);
-
-    i2c_client = client;
-
-    ret = gpio_request(MS_TS_MSG21XX_GPIO_RST, "reset");
-    if (ret < 0)
-    {
-        pr_err("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG21XX_GPIO_RST, ret);
-        goto err0;
-    }
-
-    // power on TP
-    gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
-    mdelay(100);
-    gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
-    mdelay(10);
-    gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
-    mdelay(200);
-    if (0 == get_ic_type())
-    {
-        pr_err("the currnet ic is not Mstar\n");
-        ret = -1;
-        goto err0;
-    }
-
-    mutex_init(&msg21xx_mutex);
-
-    /* allocate an input device */
-    input_dev = input_allocate_device();
-    if (!input_dev)
-    {
-        ret = -ENOMEM;
-        pr_err("*** input device allocation failed ***\n");
-        goto err1;
-    }
-
-    input_dev->name = client->name;
-    input_dev->phys = "I2C";
-    input_dev->dev.parent = &client->dev;
-    input_dev->id.bustype = BUS_I2C;
-
-    /* set the supported event type for input device */
-    set_bit(EV_ABS, input_dev->evbit);
-    set_bit(EV_SYN, input_dev->evbit);
-    set_bit(EV_KEY, input_dev->evbit);
-    set_bit(BTN_TOUCH, input_dev->keybit);
-    set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+       int ret = 0;
+
+       if (input_dev != NULL) {
+               DBG("input device has found\n");
+               return -EINVAL;
+       }
+
+       if (client->dev.of_node) {
+               pdata = devm_kzalloc(&client->dev,
+                       sizeof(struct msg21xx_ts_platform_data), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+
+               ret = msg21xx_parse_dt(&client->dev, pdata);
+               if (ret) {
+                       dev_err(&client->dev, "DT parsing failed\n");
+                       return ret;
+               }
+       } else
+               pdata = client->dev.platform_data;
+
+       ts_data = devm_kzalloc(&client->dev,
+                       sizeof(struct msg21xx_ts_data), GFP_KERNEL);
+       if (!ts_data)
+               return -ENOMEM;
+
+       DBG("*** %s ***\n", __func__);
+
+       i2c_client = client;
+
+       ret = msg21xx_ts_power_init();
+       if (ret)
+               dev_err(&client->dev, "Mstar power init failed\n");
+
+       ret = msg21xx_ts_power_on();
+       if (ret) {
+               dev_err(&client->dev, "Mstar power on failed\n");
+               goto exit_deinit_power;
+       }
+
+       ret = msg21xx_pinctrl_init();
+       if (!ret && ts_data->ts_pinctrl) {
+               ret = pinctrl_select_state(ts_data->ts_pinctrl,
+                               ts_data->pinctrl_state_active);
+               if (ret < 0)
+                       goto exit_pinctrl_select;
+       } else {
+               goto exit_pinctrl_init;
+       }
+
+       ret = msg21xx_ts_gpio_configure(true);
+       if (ret) {
+               dev_err(&client->dev, "Failed to configure gpio %d\n", ret);
+               goto exit_gpio_config;
+       }
+
+       if (get_ic_type() == 0) {
+               pr_err("the currnet ic is not Mstar\n");
+               ret = -1;
+               goto err_wrong_ic_type;
+       }
+
+       mutex_init(&msg21xx_mutex);
+       mutex_init(&ts_data->ts_mutex);
+
+       /* allocate an input device */
+       input_dev = input_allocate_device();
+       if (!input_dev) {
+               ret = -ENOMEM;
+               pr_err("*** input device allocation failed ***\n");
+               goto err_input_allocate_dev;
+       }
+
+       input_dev->name = client->name;
+       input_dev->phys = "I2C";
+       input_dev->dev.parent = &client->dev;
+       input_dev->id.bustype = BUS_I2C;
+
+       /* set the supported event type for input device */
+       set_bit(EV_ABS, input_dev->evbit);
+       set_bit(EV_SYN, input_dev->evbit);
+       set_bit(EV_KEY, input_dev->evbit);
+       set_bit(BTN_TOUCH, input_dev->keybit);
+       set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+       set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+       ts_data->input_dev = input_dev;
+       ts_data->client = client;
+       ts_data->pdata = pdata;
+
+       input_set_drvdata(input_dev, ts_data);
+       i2c_set_clientdata(client, ts_data);
 
 #ifdef CONFIG_TP_HAVE_KEY
-    {
-        int i;
-        for (i = 0; i < MAX_KEY_NUM; i ++)
-        {
-            input_set_capability(input_dev, EV_KEY, tp_key_array[i]);
-        }
-    }
+       {
+               int i;
+
+               for (i = 0; i < num_buttons; i++)
+                       input_set_capability(input_dev, EV_KEY, button_map[i]);
+       }
 #endif
 
-    input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 2, 0, 0);
-    input_set_abs_params(input_dev, ABS_MT_POSITION_X, TOUCH_SCREEN_X_MIN, TOUCH_SCREEN_X_MAX, 0, 0);
-    input_set_abs_params(input_dev, ABS_MT_POSITION_Y, TOUCH_SCREEN_Y_MIN, TOUCH_SCREEN_Y_MAX, 0, 0);
-
-    /* register the input device to input sub-system */
-    ret = input_register_device(input_dev);
-    if (ret < 0)
-    {
-        pr_err("*** Unable to register ms-touchscreen input device ***\n");
-        goto err1;
-    }
-
-    /* set sysfs for firmware */
-    firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg20xx"); //client->name
-    if (IS_ERR(firmware_class))
-        pr_err("Failed to create class(firmware)!\n");
-
-    firmware_cmd_dev = device_create(firmware_class, NULL, 0, NULL, "device");
-    if (IS_ERR(firmware_cmd_dev))
-        pr_err("Failed to create device(firmware_cmd_dev)!\n");
-
-    // version
-    if (device_create_file(firmware_cmd_dev, &dev_attr_version) < 0)
-        pr_err("Failed to create device file(%s)!\n", dev_attr_version.attr.name);
-    // update
-    if (device_create_file(firmware_cmd_dev, &dev_attr_update) < 0)
-        pr_err("Failed to create device file(%s)!\n", dev_attr_update.attr.name);
-    // data
-    if (device_create_file(firmware_cmd_dev, &dev_attr_data) < 0)
-        pr_err("Failed to create device file(%s)!\n", dev_attr_data.attr.name);
+       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+                               0, 2, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+                       TOUCH_SCREEN_X_MIN, pdata->x_max, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+                       TOUCH_SCREEN_Y_MIN, pdata->y_max, 0, 0);
+       input_mt_init_slots(input_dev, MAX_TOUCH_NUM, 0);
+
+       /* register the input device to input sub-system */
+       ret = input_register_device(input_dev);
+       if (ret < 0) {
+               pr_err("*** Unable to register ms-touchscreen input device ***\n");
+               goto err_input_reg_dev;
+       }
+
+       /* set sysfs for firmware */
+       firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg20xx");
+       if (IS_ERR(firmware_class))
+               pr_err("Failed to create class(firmware)!\n");
+
+       firmware_cmd_dev = device_create(firmware_class, NULL, 0,
+                                       NULL, "device");
+       if (IS_ERR(firmware_cmd_dev))
+               pr_err("Failed to create device(firmware_cmd_dev)!\n");
+
+       /* version */
+       if (device_create_file(firmware_cmd_dev, &dev_attr_version) < 0)
+               pr_err("Failed to create device file(%s)!\n",
+                               dev_attr_version.attr.name);
+       /* update */
+       if (device_create_file(firmware_cmd_dev, &dev_attr_update) < 0)
+               pr_err("Failed to create device file(%s)!\n",
+                               dev_attr_update.attr.name);
+       /* data */
+       if (device_create_file(firmware_cmd_dev, &dev_attr_data) < 0)
+               pr_err("Failed to create device file(%s)!\n",
+                               dev_attr_data.attr.name);
 
 #ifdef TP_PRINT
-    tp_print_create_entry();
+       tp_print_create_entry();
 #endif
 
-    dev_set_drvdata(firmware_cmd_dev, NULL);
+       dev_set_drvdata(firmware_cmd_dev, NULL);
 
-    /* initialize the work queue */
-    INIT_WORK(&msg21xx_wk, touch_driver_do_work);
+       ret = request_threaded_irq(client->irq, NULL,
+                               msg21xx_ts_interrupt,
+                               pdata->irq_gpio_flags | IRQF_ONESHOT,
+                               "msg21xx", ts_data);
+       if (ret)
+               goto err_req_irq;
 
-    ret = gpio_request(MS_TS_MSG21XX_GPIO_INT, "interrupt");
-    if (ret < 0)
-    {
-        pr_err("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG21XX_GPIO_INT, ret);
-        goto err2;
-    }
-    gpio_direction_input(MS_TS_MSG21XX_GPIO_INT);
-    gpio_set_value(MS_TS_MSG21XX_GPIO_INT, 1);
-
-    irq_msg21xx = gpio_to_irq(MS_TS_MSG21XX_GPIO_INT);
-
-    /* request an irq and register the isr */
-    ret = request_irq(irq_msg21xx, touch_driver_isr, IRQF_TRIGGER_RISING, "msg21xx", NULL);
-    if (ret != 0)
-    {
-        pr_err("*** Unable to claim irq %d; error %d ***\n", MS_TS_MSG21XX_GPIO_INT, ret);
-        goto err3;
-    }
-
-    disable_irq(irq_msg21xx);
+       disable_irq(ts_data->client->irq);
 
 #if defined(CONFIG_FB)
-    msg21xx_fb_notif.notifier_call = fb_notifier_callback;
-    ret = fb_register_client(&msg21xx_fb_notif);
-#elif defined (CONFIG_HAS_EARLYSUSPEND)
-    mstar_ts_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
-    mstar_ts_early_suspend.suspend = touch_driver_early_suspend;
-    mstar_ts_early_suspend.resume = touch_driver_early_resume;
-    register_early_suspend(&mstar_ts_early_suspend);
+       ts_data->fb_notif.notifier_call = fb_notifier_callback;
+       ret = fb_register_client(&ts_data->fb_notif);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+       mstar_ts_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+       mstar_ts_early_suspend.suspend = touch_driver_early_suspend;
+       mstar_ts_early_suspend.resume = touch_driver_early_resume;
+       register_early_suspend(&mstar_ts_early_suspend);
 #endif
 
-#ifdef  CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-    tsps_assist_register_callback("msg21xx", &tsps_msg21xx_enable, &tsps_msg21xx_data);
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+       tsps_assist_register_callback("msg21xx", &tsps_msg21xx_enable,
+                               &tsps_msg21xx_data);
 #endif
 
 #ifdef FIRMWARE_AUTOUPDATE
-    get_customer_firmware_version();
-    _ReadBinConfig();
-
-    if (main_sw_id == info_sw_id)
-    {
-        if (_CalMainCRC32() == bin_conf_crc32)
-        {
-            if ((main_sw_id >= SWID_START) && (main_sw_id < SWID_NULL))
-            {
-                update_bin_major= (MSG_FIRMWARE[main_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[main_sw_id-SWID_START][0x7f4e];
-                update_bin_minor= (MSG_FIRMWARE[main_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[main_sw_id-SWID_START][0x7f50];
-
-                //check upgrading
-                if ((update_bin_major == fw_version_major) && (update_bin_minor > fw_version_minor))
-                {
-                    update_flag = 1;
-                }
-            }
-            DBG("MAIN sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",main_sw_id,update_flag,update_bin_major,update_bin_minor);
-        }
-        else
-        {
-            if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL))
-            {
-                update_bin_major= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4e];
-                update_bin_minor= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f50];
-                update_flag = 1;
-            }
-            DBG("INFO1 sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",info_sw_id,update_flag,update_bin_major,update_bin_minor);
-        }
-    }
-    else
-    {
-        if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL))
-        {
-            update_bin_major= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4e];
-            update_bin_minor= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f50];
-            update_flag = 1;
-        }
-        DBG("INFO2 sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",info_sw_id,update_flag,update_bin_major,update_bin_minor);
-    }
-
-    if (update_flag == 1)
-    {
-        DBG("MSG21XX_fw_auto_update begin....\n");
-        //transfer data
-        for (i = 0; i < 33; i++)
-        {
-            firmware_data_store(NULL, NULL, &(MSG_FIRMWARE[info_sw_id-SWID_START][i*1024]), 1024);
-        }
-
-        kthread_run(fwAutoUpdate, 0, "MSG21XX_fw_auto_update");
-        DBG("*** mstar touch screen registered ***\n");
-        return 0;
-    }
-
-    reset_hw();
+       get_customer_firmware_version();
+       _ReadBinConfig();
+
+       if (main_sw_id == info_sw_id) {
+               if (_CalMainCRC32() == bin_conf_crc32) {
+                       if ((main_sw_id >= SWID_START) &&
+                                               (main_sw_id < SWID_NULL)) {
+                               update_bin_major = (MSG_FIRMWARE
+                               [main_sw_id - SWID_START][0x7f4f] << 8)
+                               + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f4e];
+                               update_bin_minor = (MSG_FIRMWARE
+                               [main_sw_id - SWID_START][0x7f51] << 8)
+                               + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f50];
+
+                               /* check upgrading */
+                               if ((update_bin_major == fw_version_major) &&
+                                       (update_bin_minor > fw_version_minor)) {
+                                       update_flag = 1;
+                               }
+                       }
+               } else {
+                       if ((info_sw_id >= SWID_START) &&
+                               (info_sw_id < SWID_NULL)) {
+                               update_bin_major = (MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f4f] << 8)
+                                       + MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f4e];
+                               update_bin_minor = (MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f51] << 8)
+                                       + MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f50];
+                               update_flag = 1;
+                       }
+               }
+       } else {
+               if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL)) {
+                       update_bin_major = (MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f4f] << 8)
+                                       + MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f4e];
+                       update_bin_minor = (MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f51] << 8)
+                                       + MSG_FIRMWARE
+                                       [info_sw_id - SWID_START][0x7f50];
+                       update_flag = 1;
+               }
+       }
+
+       if (update_flag == 1) {
+               DBG("MSG21XX_fw_auto_update begin....\n");
+               /* transfer data */
+               for (i = 0; i < 33; i++) {
+                       firmware_data_store(NULL, NULL,
+                       &(MSG_FIRMWARE[info_sw_id - SWID_START][i * 1024]),
+                       1024);
+               }
+
+               kthread_run(fwAutoUpdate, 0, "MSG21XX_fw_auto_update");
+               DBG("*** mstar touch screen registered ***\n");
+               return 0;
+       }
+
+       reset_hw();
 #endif
 
-    DBG("*** mstar touch screen registered ***\n");
-    enable_irq(irq_msg21xx);
-    return 0;
-
-err3:
-    free_irq(irq_msg21xx, input_dev);
-
-err2:
-    gpio_free(MS_TS_MSG21XX_GPIO_INT);
-
-err1:
-    mutex_destroy(&msg21xx_mutex);
-    input_unregister_device(input_dev);
-    input_free_device(input_dev);
-    input_dev = NULL;
-
-err0:
-    gpio_free(MS_TS_MSG21XX_GPIO_RST);
-
-    return ret;
+       DBG("*** mstar touch screen registered ***\n");
+       enable_irq(ts_data->client->irq);
+       return 0;
+
+err_req_irq:
+       free_irq(ts_data->client->irq, input_dev);
+
+err_input_reg_dev:
+err_input_allocate_dev:
+       mutex_destroy(&msg21xx_mutex);
+       mutex_destroy(&ts_data->ts_mutex);
+       input_unregister_device(input_dev);
+       input_free_device(input_dev);
+       input_dev = NULL;
+
+err_wrong_ic_type:
+       msg21xx_ts_gpio_configure(false);
+exit_gpio_config:
+exit_pinctrl_select:
+       if (ts_data->ts_pinctrl) {
+               if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+                       devm_pinctrl_put(ts_data->ts_pinctrl);
+                       ts_data->ts_pinctrl = NULL;
+               } else {
+                       ret = pinctrl_select_state(ts_data->ts_pinctrl,
+                                       ts_data->pinctrl_state_release);
+                       if (ret < 0)
+                               pr_err("Cannot get release pinctrl state\n");
+               }
+       }
+exit_pinctrl_init:
+       msg21xx_ts_power_off();
+exit_deinit_power:
+       msg21xx_ts_power_deinit();
+
+       return ret;
 }
 
-/* remove function is triggered when the input device is removed from input sub-system */
+/* remove function is triggered when the input device is removed
+ *from input sub-system
+ */
 static int touch_driver_remove(struct i2c_client *client)
 {
-    DBG("touch_driver_remove()\n");
-
-    free_irq(irq_msg21xx, input_dev);
-    gpio_free(MS_TS_MSG21XX_GPIO_INT);
-    gpio_free(MS_TS_MSG21XX_GPIO_RST);
-    input_unregister_device(input_dev);
-    mutex_destroy(&msg21xx_mutex);
-
-    return 0;
+       int retval = 0;
+
+       DBG("touch_driver_remove()\n");
+
+       free_irq(ts_data->client->irq, input_dev);
+       gpio_free(pdata->irq_gpio);
+       gpio_free(pdata->reset_gpio);
+
+       if (ts_data->ts_pinctrl) {
+               if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+                       devm_pinctrl_put(ts_data->ts_pinctrl);
+                       ts_data->ts_pinctrl = NULL;
+               } else {
+                       retval = pinctrl_select_state(ts_data->ts_pinctrl,
+                                       ts_data->pinctrl_state_release);
+                       if (retval < 0)
+                               pr_err("Cannot get release pinctrl state\n");
+               }
+       }
+
+       input_unregister_device(input_dev);
+       mutex_destroy(&msg21xx_mutex);
+       mutex_destroy(&ts_data->ts_mutex);
+
+       return retval;
 }
 
-/* The I2C device list is used for matching I2C device and I2C device driver. */
-static const struct i2c_device_id touch_device_id[] =
-{
-    {"msg21xx", 0},
-    {}, /* should not omitted */
+/* The I2C device list is used for matching I2C device
+ *and I2C device driver.
+ */
+static const struct i2c_device_id touch_device_id[] = {
+       {"msg21xx", 0},
+       {}, /* should not omitted */
+};
+
+static const struct of_device_id msg21xx_match_table[] = {
+       { .compatible = "mstar,msg21xx", },
+       { },
 };
 
 MODULE_DEVICE_TABLE(i2c, touch_device_id);
 
-static struct i2c_driver touch_device_driver =
-{
-    .driver = {
-        .name = "msg21xx",
-        .owner = THIS_MODULE,
-    },
-    .probe = touch_driver_probe,
-    .remove = touch_driver_remove,
-    .id_table = touch_device_id,
+static struct i2c_driver touch_device_driver = {
+       .driver = {
+               .name = "ms-msg21xx",
+               .owner = THIS_MODULE,
+               .of_match_table = msg21xx_match_table,
+       },
+       .probe = msg21xx_ts_probe,
+       .remove = touch_driver_remove,
+       .id_table = touch_device_id,
 };
 
 static int __init touch_driver_init(void)
 {
-    int ret;
-
-    /* register driver */
-    ret = i2c_add_driver(&touch_device_driver);
-    if (ret < 0)
-    {
-        DBG("add touch_device_driver i2c driver failed.\n");
-        return -ENODEV;
-    }
-    DBG("add touch_device_driver i2c driver.\n");
-
-    return ret;
+       int ret;
+
+       /* register driver */
+       ret = i2c_add_driver(&touch_device_driver);
+       if (ret < 0) {
+               DBG("add touch_device_driver i2c driver failed.\n");
+               return -ENODEV;
+       }
+       DBG("add touch_device_driver i2c driver.\n");
+
+       return ret;
 }
 
 static void __exit touch_driver_exit(void)
 {
-    DBG("remove touch_device_driver i2c driver.\n");
+       DBG("remove touch_device_driver i2c driver.\n");
 
-    i2c_del_driver(&touch_device_driver);
+       i2c_del_driver(&touch_device_driver);
 }
 
 #ifdef TP_PRINT
 #include <linux/proc_fs.h>
 
-static U16 InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256;
-static U8 row, units, cnt;
+static unsigned short InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256;
+static unsigned char row, units, cnt;
 
 static int tp_print_proc_read(void)
 {
-    U16 i, j;
-    U16 left, offset = 0;
-    U8 dbbus_tx_data[3] = {0};
-    U8 u8Data;
-    S16 s16Data;
-    S32 s32Data;
-    char *buf = NULL;
-
-    left = cnt*row*units;
-    if ((bTpInSuspend == 0) && (InfoAddr != 0x0F) && (PoolAddr != 0x10) && (left > 0))
-    {
-        buf = kmalloc(left, GFP_KERNEL);
-        if (buf != NULL)
-        {
-            printk("tpp: \n");
-
-            while (left > 0)
-            {
-                dbbus_tx_data[0] = 0x53;
-                dbbus_tx_data[1] = ((PoolAddr + offset) >> 8) & 0xFF;
-                dbbus_tx_data[2] = (PoolAddr + offset) & 0xFF;
-                mutex_lock(&msg21xx_mutex);
-                write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
-                read_i2c_seq(SLAVE_I2C_ID_DWI2C, &buf[offset], left > TransLen ? TransLen : left);
-                mutex_unlock(&msg21xx_mutex);
-
-                if (left > TransLen)
-                {
-                    left -= TransLen;
-                    offset += TransLen;
-                }
-                else
-                {
-                    left = 0;
-                }
-            }
-
-            for (i = 0; i < cnt; i++)
-            {
-                printk("tpp: ");
-                for (j = 0; j < row; j++)
-                {
-                    if (units == 1)
-                    {
-                        u8Data = buf[i*row*units + j*units];
-                        printk("%d\t", u8Data);
-                    }
-                    else if (units == 2)
-                    {
-                        s16Data = buf[i*row*units + j*units] + (buf[i*row*units + j*units + 1] << 8);
-                        printk("%d\t", s16Data);
-                    }
-                    else if (units == 4)
-                    {
-                        s32Data = buf[i*row*units + j*units] + (buf[i*row*units + j*units + 1] << 8) + (buf[i*row*units + j*units + 2] << 16) + (buf[i*row*units + j*units + 3] << 24);
-                        printk("%d\t", s32Data);
-                    }
-                }
-                printk("\n");
-            }
-
-            kfree(buf);
-        }
-    }
-
-    return 0;
+       unsigned short i, j;
+       unsigned short left, offset = 0;
+       unsigned char dbbus_tx_data[3] = {0};
+       unsigned char u8Data;
+       signed short s16Data;
+       int s32Data;
+       char *buf = NULL;
+
+       left = cnt*row*units;
+       if ((ts_data->suspended == 0) &&
+                               (InfoAddr != 0x0F) &&
+                               (PoolAddr != 0x10) &&
+                               (left > 0)) {
+               buf = kmalloc(left, GFP_KERNEL);
+               if (buf != NULL) {
+
+                       while (left > 0) {
+                               dbbus_tx_data[0] = 0x53;
+                               dbbus_tx_data[1] = ((PoolAddr + offset) >> 8)
+                                                                       & 0xFF;
+                               dbbus_tx_data[2] = (PoolAddr + offset) & 0xFF;
+                               mutex_lock(&msg21xx_mutex);
+                               write_i2c_seq(ts_data->client->addr,
+                                                       &dbbus_tx_data[0], 3);
+                               read_i2c_seq(ts_data->client->addr,
+                                       &buf[offset],
+                                       left > TransLen ? TransLen : left);
+                               mutex_unlock(&msg21xx_mutex);
+
+                               if (left > TransLen) {
+                                       left -= TransLen;
+                                       offset += TransLen;
+                               } else {
+                                       left = 0;
+                               }
+                       }
+
+                       for (i = 0; i < cnt; i++) {
+                               for (j = 0; j < row; j++) {
+                                       if (units == 1) {
+                                               u8Data = buf[i * row * units +
+                                                               j * units];
+                                       } else if (units == 2) {
+                                               s16Data = buf[i * row * units +
+                                               j * units] +
+                                               (buf[i * row * units +
+                                               j * units + 1] << 8);
+                                       } else if (units == 4) {
+                                               s32Data = buf[i * row * units +
+                                               j * units] +
+                                               (buf[i * row * units +
+                                               j * units + 1] << 8) +
+                                               (buf[i * row * units +
+                                               j * units + 2] << 16) +
+                                               (buf[i * row * units +
+                                               j * units + 3] << 24);
+                                       }
+                               }
+                       }
+
+                       kfree(buf);
+               }
+       }
+
+       return 0;
 }
 
 static void tp_print_create_entry(void)
 {
-    U8 dbbus_tx_data[3] = {0};
-    U8 dbbus_rx_data[8] = {0};
-
-    dbbus_tx_data[0] = 0x53;
-    dbbus_tx_data[1] = 0x00;
-    dbbus_tx_data[2] = 0x58;
-    mutex_lock(&msg21xx_mutex);
-    write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
-    read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4);
-    mutex_unlock(&msg21xx_mutex);
-    InfoAddr = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
-    PoolAddr = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
-    printk("InfoAddr=0x%X\n", InfoAddr);
-    printk("PoolAddr=0x%X\n", PoolAddr);
-
-    if ((InfoAddr != 0x0F) && (PoolAddr != 0x10))
-    {
-        msleep(10);
-        dbbus_tx_data[0] = 0x53;
-        dbbus_tx_data[1] = (InfoAddr >> 8) & 0xFF;
-        dbbus_tx_data[2] = InfoAddr & 0xFF;
-        mutex_lock(&msg21xx_mutex);
-        write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
-        read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 8);
-        mutex_unlock(&msg21xx_mutex);
-
-        units = dbbus_rx_data[0];
-        row = dbbus_rx_data[1];
-        cnt = dbbus_rx_data[2];
-        TransLen = (dbbus_rx_data[7]<<8) + dbbus_rx_data[6];
-        printk("tpp: row=%d, units=%d\n", row, units);
-        printk("tpp: cnt=%d, TransLen=%d\n", cnt, TransLen);
-
-        // tpp
-        if (device_create_file(firmware_cmd_dev, &dev_attr_tpp) < 0)
-        {
-            pr_err("Failed to create device file(%s)!\n", dev_attr_tpp.attr.name);
-        }
-    }
+       unsigned char dbbus_tx_data[3] = {0};
+       unsigned char dbbus_rx_data[8] = {0};
+
+       dbbus_tx_data[0] = 0x53;
+       dbbus_tx_data[1] = 0x00;
+       dbbus_tx_data[2] = 0x58;
+       mutex_lock(&msg21xx_mutex);
+       write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+       read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+       mutex_unlock(&msg21xx_mutex);
+       InfoAddr = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
+       PoolAddr = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
+
+       if ((InfoAddr != 0x0F) && (PoolAddr != 0x10)) {
+               msleep(20);
+               dbbus_tx_data[0] = 0x53;
+               dbbus_tx_data[1] = (InfoAddr >> 8) & 0xFF;
+               dbbus_tx_data[2] = InfoAddr & 0xFF;
+               mutex_lock(&msg21xx_mutex);
+               write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+               read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 8);
+               mutex_unlock(&msg21xx_mutex);
+
+               units = dbbus_rx_data[0];
+               row = dbbus_rx_data[1];
+               cnt = dbbus_rx_data[2];
+               TransLen = (dbbus_rx_data[7]<<8) + dbbus_rx_data[6];
+
+               if (device_create_file(firmware_cmd_dev, &dev_attr_tpp) < 0) {
+                       pr_err("Failed to create device file(%s)!\n",
+                                       dev_attr_tpp.attr.name);
+               }
+       }
 }
 #endif
 
@@ -1754,4 +2145,3 @@ module_init(touch_driver_init);
 module_exit(touch_driver_exit);
 MODULE_AUTHOR("MStar Semiconductor, Inc.");
 MODULE_LICENSE("GPL v2");
-