rk30 phone loquat:add touch screen driver ft5306
authorhhb <hhb@rock-chips.com>
Wed, 9 May 2012 05:29:54 +0000 (13:29 +0800)
committerhhb <hhb@rock-chips.com>
Wed, 9 May 2012 05:29:54 +0000 (13:29 +0800)
arch/arm/configs/rk30_phone_loquat_defconfig
arch/arm/mach-rk30/board-rk30-phone-loquat.c
arch/arm/mach-rk30/include/mach/board.h
drivers/input/touchscreen/ft5306_ts.c

index 47c59e5ba221d60e854a928b7e6c7a5021b7d598..0d993635cebae2d9199d557fd67f5bf7d0c94b84 100755 (executable)
@@ -225,6 +225,7 @@ CONFIG_INPUT_KEYRESET=y
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TABLET=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_FT5306=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_LPSENSOR_AL3006=y
 CONFIG_INPUT_KEYCHORD=y
@@ -283,7 +284,7 @@ CONFIG_DISPLAY_SUPPORT=y
 CONFIG_LCD_HJ050NA_06A=y
 CONFIG_FB_ROCKCHIP=y
 CONFIG_LCDC_RK30=y
-CONFIG_HDMI_RK30=y
+# CONFIG_LCDC1_RK30 is not set
 CONFIG_RGA_RK30=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
index 9a24097edf8a8f249048877e5053862c2365e65c..5e71b135ec2fc0a5ecb8ae77b3d9da4c7cb63b86 100755 (executable)
@@ -536,28 +536,34 @@ struct synaptics_rmi4_platform_data synaptics_s3202_info = {
 
 #if defined(CONFIG_TOUCHSCREEN_FT5306)
 
-#define TOUCH_RESET_PIN         RK30_PIN4_PC2
-#define TOUCH_INT_PIN   RK30_PIN4_PC2
+#define TOUCH_RESET_PIN         RK30_PIN6_PB1
+#define TOUCH_INT_PIN   RK30_PIN4_PD7
 int ft5306_init_platform_hw(void)
 {
+
+       printk("ft5406_init_platform_hw\n");
     if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){
       gpio_free(TOUCH_RESET_PIN);
-      printk("ft5306_init_platform_hw gpio_request error\n");
+      printk("ft5406_init_platform_hw gpio_request error\n");
       return -EIO;
     }
 
     if(gpio_request(TOUCH_INT_PIN,NULL) != 0){
       gpio_free(TOUCH_INT_PIN);
-      printk("ift5306_init_platform_hw gpio_request error\n");
+      printk("ift5406_init_platform_hw gpio_request error\n");
       return -EIO;
     }
-       gpio_pull_updown(TOUCH_INT_PIN, 0);
-       gpio_direction_output(TOUCH_RESET_PIN, GPIO_HIGH);
-       msleep(5);
+    rk30_mux_api_set(GPIO4D7_SMCDATA15_TRACEDATA15_NAME, 0);
+
+       gpio_direction_output(TOUCH_RESET_PIN, 0);
        gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
-       mdelay(5);
+       mdelay(10);
+       gpio_direction_input(TOUCH_INT_PIN);
+       mdelay(10);
        gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
+       msleep(300);
     return 0;
+
 }
 
 void ft5306_exit_platform_hw(void)
@@ -578,15 +584,16 @@ int ft5306_platform_wakeup(void)
 {
        //printk("ft5306_platform_wakeup\n");
        gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
+       msleep(300);
        return 0;
 }
 
-struct ft5406_platform_data ft5306_info = {
+struct ft5x0x_platform_data ft5306_info = {
 
   .init_platform_hw= ft5306_init_platform_hw,
   .exit_platform_hw= ft5306_exit_platform_hw,
-  .platform_sleep  = ft5306_platform_sleep,
-  .platform_wakeup = ft5306_platform_wakeup,
+  .ft5x0x_platform_sleep  = ft5306_platform_sleep,
+  .ft5x0x_platform_wakeup = ft5306_platform_wakeup,
 };
 
 
@@ -1110,7 +1117,7 @@ struct rk29fb_info lcdc1_screen_info = {
        #if defined(CONFIG_HDMI_RK30)
        .prop           = EXTEND,       //extend display device
        .lcd_info  = NULL,
-       .set_screen_info = hdmi_init_lcdc,
+       .set_screen_info = hdmi_set_info,
        #endif
 };
 #endif
@@ -1658,7 +1665,7 @@ static struct i2c_board_info __initdata i2c2_info[] = {
        .type           = "ft5x0x_ts",
        .addr           = 0x38,
        .flags          = 0,
-       .irq            = RK30_PIN4_PC2,
+       .irq            = RK30_PIN4_PD7,//RK30_PIN2_PC2,
        .platform_data = &ft5306_info,
 },
 #endif
@@ -1756,16 +1763,6 @@ static void rk30_pm_power_off(void)
 static ssize_t rk_virtual_keys_show(struct kobject *kobj,
                        struct kobj_attribute *attr, char *buf)
 {
-#if defined (CONFIG_TOUCHSCREEN_FT5306)
-        printk("rk_virtual_keys_show\n");
-    /* centerx;centery;width;height; */
-       return sprintf(buf,
-               __stringify(EV_KEY) ":" __stringify(KEY_BACK)        ":900:400:100:100"
-               ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU)   ":1300:500:100:100"
-               ":" __stringify(EV_KEY) ":" __stringify(KEY_HOMEPAGE)   ":1300:600:120:60"
-               ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":900:700:50:60"
-               "\n");
-#endif
 #if (defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3202))
         printk("rk_virtual_keys_show S3202\n");
     /* centerx;centery;width;height; */
@@ -1783,8 +1780,6 @@ static struct kobj_attribute rk_virtual_keys_attr = {
        .attr = {
 #if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3202)
                .name = "virtualkeys.synaptics_rmi4_i2c",
-#elif defined(CONFIG_TOUCHSCREEN_FT5306)
-               .name = "virtualkeys.ft5x0x_ts",
 #else
                .name = "virtualkeys",
 #endif
@@ -1838,7 +1833,7 @@ static void __init machine_rk30_board_init(void)
        rk29sdk_wifi_bt_gpio_control_init();
 #endif
 
-#if (defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3202) || defined(CONFIG_TOUCHSCREEN_FT5306))
+#if (defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3202))
        rk_virtual_keys_init();
 #endif
 
index a03686db380c555017bb6c18eee5b820a5f08da9..f481fc608d66c1822fd7f0cd4b6ba410c729e672 100755 (executable)
@@ -52,6 +52,17 @@ struct wifi_platform_data {
 };
 #endif
 
+#if defined (CONFIG_TOUCHSCREEN_FT5306)
+struct ft5x0x_platform_data{
+         u16     model;
+    int     (*get_pendown_state)(void);
+    int     (*init_platform_hw)(void);
+    int     (*ft5x0x_platform_sleep)(void);
+    int     (*ft5x0x_platform_wakeup)(void);
+    void    (*exit_platform_hw)(void);
+};
+#endif
+
 extern struct rk29_sdmmc_platform_data default_sdmmc0_data;
 extern struct rk29_sdmmc_platform_data default_sdmmc1_data;
 
index 1a8e41c93d45088874355151c1ed24f1bf8f6759..974d071ba0a27774701626917b5e97ec42745169 100755 (executable)
  *
  *     note: only support mulititouch  Wenfs 2010-10-01
  */
-
-#include <linux/input.h>
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/fcntl.h>
 #include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/timer.h>
-#include <linux/jiffies.h>
-#include <linux/miscdevice.h>
-#include <linux/types.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/input-polldev.h>
+#include <linux/hrtimer.h>
 #include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/async.h>
 #include <linux/workqueue.h>
-#ifdef CONFIG_ANDROID_POWER
-#include <linux/android_power.h>
-#endif
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
-#include <asm/hardware/gic.h>
-#include <mach/iomux.h>
+#include <linux/slab.h>
 #include <mach/gpio.h>
-#include <mach/irqs.h>
-#include <mach/rk29_iomap.h>
+#include <linux/irq.h>
 #include <mach/board.h>
-#include <mach/rk29_nand.h>
-#include <mach/rk29_camera.h>                          /* ddl@rock-chips.com : camera support */
-#include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
-#include <mach/vpu_mem.h>
-#include <mach/sram.h>
+#include <linux/input/mt.h>
+
+
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
-#include <linux/input/mt.h>
 
 
-#if 0
-#define FTprintk(x...) printk(x)
-#else
-#define FTprintk(x...) do{} while(0)
+#define CONFIG_FT5X0X_MULTITOUCH 1
+#define CONFIG_TOUCH_PANEL_KEY   1
+#define NEW_PAL_DRV
+#define CHECK_KEY
+#define LONGPRESS_LOCK_SPECKEY  //是否使用长按某键(如search键)锁住功能键的功能
+#ifdef LONGPRESS_LOCK_SPECKEY
+#define KEY_LOCK 195
+#define ORIGIN_KEY KEY_SEARCH
+#define LOCK_LONG_PRESS_CNT 100
+static int Origin2LockPressCnt = 0;
+static int lockflag =0;
+static int touch_key_hold_press = 0;
+
+ssize_t glock_status_show(struct device *dev, char *buf)
+{
+         printk("lockflag === %d\n",lockflag);
+       return sprintf(buf, "%d", lockflag);
+}
 #endif
 
-#define CONFIG_FT5X0X_MULTITOUCH  1
-#define MAX_POINT                 5
-#define FT5306_IIC_SPEED          400*1000    //300*1000
-#define TOUCH_RESET_PIN           RK29_PIN6_PC3
-#define FT5X0X_REG_THRES          0x80         /* Thresshold, the threshold be low, the sensitivy will be high */
-#define FT5X0X_REG_REPORT_RATE    0x88         /* **************report rate, in unit of 10Hz **************/
-#define FT5X0X_REG_PMODE          0xA5         /* Power Consume Mode 0 -- active, 1 -- monitor, 3 -- sleep */    
-#define FT5X0X_REG_FIRMID         0xA6         /* ***************firmware version **********************/
-#define FT5X0X_REG_NOISE_MODE     0xb2         /* to enable or disable power noise, 1 -- enable, 0 -- disable */
-#define SCREEN_MAX_X              480
-#define SCREEN_MAX_Y              800
-#define PRESS_MAX                 255
-#define FT5X0X_NAME                  "ft5x0x_ts"//"synaptics_i2c_rmi"//"synaptics-rmi-ts"// 
-#define TOUCH_MAJOR_MAX           200
-#define WIDTH_MAJOR_MAX           200
-//FT5X0X_REG_PMODE
-#define PMODE_ACTIVE              0x00
-#define PMODE_MONITOR             0x01
-#define PMODE_STANDBY             0x02
-#define PMODE_HIBERNATE           0x03
 
+static int err_ft5X06 = 0;     //w++记载有没有此设备
+static int debug1=1;
+module_param(debug1, int, S_IRUGO|S_IWUSR);
 
-struct ts_event {
-       u16     x1;
-       u16     y1;
-       u16     x2;
-       u16     y2;
-       u16     x3;
-       u16     y3;
-       u16     x4;
-       u16     y4;
-       u16     x5;
-       u16     y5;
-       u16     pressure;
-    s16  touch_ID1;
-       s16  touch_ID2;
-    s16  touch_ID3;
-    s16  touch_ID4;
-       s16  touch_ID5;
-       u8   touch_point;
-       u8   status;
+static int gpress = 0;
+extern void gpio_enable1();
+static int Motoenble = 0;
+module_param(Motoenble, int, S_IRUGO|S_IWUSR);
+static int MotoStart = 0;
+
+/*
+ * Added by yick @RockChip
+ * Compatible with both types of firmware
+ * default: point - only pressdown finger num
+ *                     event - both down and up event
+ */
+#define USE_POINT 1
+#if USE_POINT
+uint16_t down_table    = 0;
+uint16_t up_table      = ~0;
+#endif
+
+#define SCREEN_MAX_X    480
+#define SCREEN_MAX_Y    800
+#define PRESS_MAX       255
+
+#define FT5X0X_NAME    "ft5x0x_ts"
+#define MAX_CONTACTS 5
+enum ft5x0x_ts_regs {
+       FT5X0X_REG_PMODE        = 0xA5, /* Power Consume Mode           */
+};
+
+#define KEY_MIN_X      800
+#define KEY_NUM        4
+
+int touch_key_press[] = {0, 0, 0, 0};
+//int touch_key_code[] = { KEY_BACK,KEY_HOME, KEY_MENU};
+//int touch_key_min[KEY_NUM] ={-1,59,105};
+//int touch_key_max[KEY_NUM] ={2,73,121};
+
+int touch_key_code[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK, KEY_SEARCH};
+int touch_key_min[KEY_NUM] ={30,150,270,390};
+int touch_key_max[KEY_NUM] ={90,210,330,450};
+
+//FT5X0X_REG_PMODE
+#define PMODE_ACTIVE        0x00
+#define PMODE_MONITOR       0x01
+#define PMODE_STANDBY       0x02
+#define PMODE_HIBERNATE     0x03
+
+#ifndef ABS_MT_TOUCH_MAJOR
+#define ABS_MT_TOUCH_MAJOR     0x30    /* touching ellipse */
+#define ABS_MT_TOUCH_MINOR     0x31    /* (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR     0x32    /* approaching ellipse */
+#define ABS_MT_WIDTH_MINOR     0x33    /* (omit if circular) */
+#define ABS_MT_ORIENTATION     0x34    /* Ellipse orientation */
+#define ABS_MT_POSITION_X        0x35  /* Center X ellipse position */
+#define ABS_MT_POSITION_Y        0x36  /* Center Y ellipse position */
+#define ABS_MT_TOOL_TYPE         0x37  /* Type of touching device */
+#define ABS_MT_BLOB_ID           0x38  /* Group set of pkts as blob */
+#endif /* ABS_MT_TOUCH_MAJOR */
+
+struct point_data {
+       u8 status;
+       u8 id;
+       u16 x;
+       u16 y;
 };
 
-struct tp_event {
-       u16     x;
-       u16     y;
-    s16 id;
-       u16     pressure;
-       u8  touch_point;
-       u8  flag;
+struct ts_event {
+  u16  touch_point;
+  struct point_data point[5];
 };
 
-struct ft5x0x_ts_data {
-       struct i2c_client *client;
+struct ft5x0x_ts_dev {
+  struct i2c_client *client;
        struct input_dev        *input_dev;
        int    irq;
-       int     (*platform_sleep)(void);
-    int     (*platform_wakeup)(void);
        struct ts_event         event;
        struct work_struct      pen_event_work;
        struct workqueue_struct *ts_workqueue;
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       struct early_suspend ft5306_early_suspend;
+       struct early_suspend    early_suspend;
+
+#ifdef CHECK_KEY
+                       struct timer_list timer;
 #endif
 };
-static struct i2c_client *this_client;
 
-/***********************************************************************/
+static struct ft5x0x_ts_dev *g_dev;
+static bool rember_point_into = true;
 
-#define    FTS_PACKET_LENGTH        128
 
-
-static u8 CTPM_FW[]=
+static ssize_t Moto_status(struct device_driver *_drv,char *_buf)
 {
-#include "ft_app_5306.i"
-};
-
-typedef enum
+       //printk("Moto_status Motoenble==%d\n", Motoenble);
+   if(Motoenble)
+       return sprintf(_buf, "Ledlevel is Low\n");
+   else
+          return sprintf(_buf, "Ledlevel is High\n");
+}
+static ssize_t Moto_control(struct device_driver *_drv, const char *_buf, size_t _count)
 {
-    ERR_OK,
-    ERR_MODE,
-    ERR_READID,
-    ERR_ERASE,
-    ERR_STATUS,
-    ERR_ECC,
-    ERR_DL_ERASE_FAIL,
-    ERR_DL_PROGRAM_FAIL,
-    ERR_DL_VERIFY_FAIL
-}E_UPGRADE_ERR_TYPE;
-
-/***********************************************************************/
-
-/***********************************************************************
-    [function]: 
-                          callback:                send data to ctpm by i2c interface;
-    [parameters]:
-                           txdata[in]:              data buffer which is used to send data;
-                           length[in]:              the length of the data buffer;
-    [return]:
-                           FTS_TRUE:              success;
-                           FTS_FALSE:             fail;
-************************************************************************/
-static int fts_i2c_txdata(u8 *txdata, int length)
+               char temp[5];
+               //printk("Read data from Android: %s\n", _buf);
+               strncpy(temp, _buf, 1);
+               Motoenble = simple_strtol(temp, NULL, 10);
+               //printk("Moto_control Motoenble=%d\n", Motoenble);
+}
+
+
+static int ft5x0x_i2c_rxdata(char *rxdata, int length)
 {
        int ret;
 
-       struct i2c_msg msg;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr   = g_dev->client->addr,
+                       .flags  = 0,
+                       .len    = 1,
+                       .buf    = rxdata,
+                       .scl_rate = 200 * 1000,
+               },
+               {
+                       .addr   = g_dev->client->addr,
+                       .flags  = I2C_M_RD,
+                       .len    = length,
+                       .buf    = rxdata,
+                       .scl_rate = 200 * 1000,
+               },
+       };
+
+       ret = i2c_transfer(g_dev->client->adapter, msgs, 2);
+       if (ret < 0)
+               pr_err("msg %s i2c read error: %d\n", __func__, ret);
+
+       return ret;
+}
+
+static int ft5x0x_i2c_txdata(char *txdata, int length)
+{
+       int ret;
 
-      msg.addr = this_client->addr;
-      msg.flags = 0;
-      msg.len = length;
-      msg.buf = txdata;
-      msg.scl_rate = FT5306_IIC_SPEED;
-       ret = i2c_transfer(this_client->adapter, &msg, 1);
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = g_dev->client->addr,
+                       .flags  = 0,
+                       .len    = length,
+                       .buf    = txdata,
+                       .scl_rate = 200 * 1000,
+               },
+       };
+
+       ret = i2c_transfer(g_dev->client->adapter, msg, 1);
        if (ret < 0)
                pr_err("%s i2c write error: %d\n", __func__, ret);
 
        return ret;
 }
 
-/***********************************************************************
-    [function]: 
-                          callback:               write data to ctpm by i2c interface;
-    [parameters]:
-                           buffer[in]:             data buffer;
-                           length[in]:            the length of the data buffer;
-    [return]:
-                           FTS_TRUE:            success;
-                           FTS_FALSE:           fail;
-************************************************************************/
-static bool  i2c_write_interface(u8* pbt_buf, int dw_lenth)
+static int ft5x0x_set_reg(u8 addr, u8 para)
 {
-    int ret;
-    ret=i2c_master_send(this_client, pbt_buf, dw_lenth);
-    if(ret<=0)
-    {
-        FTprintk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);
-        return false;
+    u8 buf[3];
+    int ret = -1;
+
+    buf[0] = addr;
+    buf[1] = para;
+    ret = ft5x0x_i2c_txdata(buf, 2);
+    if (ret < 0) {
+        pr_err("write reg failed! %#x ret: %d", buf[0], ret);
+        return -1;
     }
-
-    return true;
+    
+    return 0;
 }
 
-/***********************************************************************
-    [function]: 
-                          callback:                read register value ftom ctpm by i2c interface;
-    [parameters]:
-                        reg_name[in]:         the register which you want to write;
-                           tx_buf[in]:              buffer which is contained of the writing value;
-    [return]:
-                           FTS_TRUE:              success;
-                           FTS_FALSE:             fail;
-************************************************************************/
-static bool fts_register_write(u8 reg_name, u8* tx_buf)
+static int ft5x0x_read_data(void)
 {
-       u8 write_cmd[2] = {0};
-
-       write_cmd[0] = reg_name;
-       write_cmd[1] = *tx_buf;
+       struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
+       struct ts_event *event = &data->event;
 
-       /*call the write callback function*/
-       return i2c_write_interface(write_cmd, 2);
-}
+       u8 buf[32]= {0};//set send addr to 0x00 *important*
+       int ret = -1;
+       int key;
 
-/***********************************************************************
-[function]: 
-                      callback:         send a command to ctpm.
-[parameters]:
-                         btcmd[in]:       command code;
-                         btPara1[in]:     parameter 1;    
-                         btPara2[in]:     parameter 2;    
-                         btPara3[in]:     parameter 3;    
-                      num[in]:         the valid input parameter numbers, 
-                                           if only command code needed and no 
-                                           parameters followed,then the num is 1;    
-[return]:
-                         FTS_TRUE:      success;
-                         FTS_FALSE:     io fail;
-************************************************************************/
-static bool cmd_write(u8 btcmd,u8 btPara1,u8 btPara2,u8 btPara3,u8 num)
-{
-    u8 write_cmd[4] = {0};
 
-    write_cmd[0] = btcmd;
-    write_cmd[1] = btPara1;
-    write_cmd[2] = btPara2;
-    write_cmd[3] = btPara3;
-    return i2c_write_interface(write_cmd, num);
-}
+       if(Motoenble)
+       {
+               if(!MotoStart)
+               {
+                       //printk("the moto is enable!\n");
+                       //gpio_enable1();
+                       MotoStart =1;
+               }
+       }
 
-/***********************************************************************
-    [function]: 
-                          callback:              read data from ctpm by i2c interface;
-    [parameters]:
-                           buffer[in]:            data buffer;
-                           length[in]:           the length of the data buffer;
-    [return]:
-                           FTS_TRUE:            success;
-                           FTS_FALSE:           fail;
-************************************************************************/
-static bool i2c_read_interface(u8* pbt_buf, int dw_lenth)
-{
-    int ret;
-    
-    ret=i2c_master_recv(this_client, pbt_buf, dw_lenth);
 
-    if(ret<=0)
-    {
-        FTprintk("[TSP]i2c_read_interface error\n");
-        return false;
-    }
-  
-    return true;
-}
+               ret = ft5x0x_i2c_rxdata(buf, 32);
 
+       if (ret < 0) {
+                       printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
+                       return ret;
+               }
+#if 0  // Just for debug
+               u8 uc_ecc;
+               int i;
+               uc_ecc = buf[2];
+               for (i=0; i<5; i++)
+               {
+                       uc_ecc ^= buf[3+6*i];
+                       uc_ecc ^= buf[4+6*i];
+                       uc_ecc ^= buf[5+6*i];
+                       uc_ecc ^= buf[6+6*i];
+               }
+//             if (uc_ecc == buf[1])  break;
+//     }
 
-/***********************************************************************
-[function]: 
-                      callback:         read a byte data  from ctpm;
-[parameters]:
-                         buffer[in]:       read buffer;
-                         length[in]:      the size of read data;    
-[return]:
-                         FTS_TRUE:      success;
-                         FTS_FALSE:     io fail;
-************************************************************************/
-static bool byte_read(u8* buffer, int length)
-{
-    return i2c_read_interface(buffer, length);
-}
 
-/***********************************************************************
-[function]: 
-                      callback:         write a byte data  to ctpm;
-[parameters]:
-                         buffer[in]:       write buffer;
-                         length[in]:      the size of write data;    
-[return]:
-                         FTS_TRUE:      success;
-                         FTS_FALSE:     io fail;
-************************************************************************/
-static bool byte_write(u8* buffer, int length)
-{
-    
-    return i2c_write_interface(buffer, length);
-}
+       if (uc_ecc != buf[1])
+       {
+               printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]);
+               return 1;
+       }
+#endif
 
-/***********************************************************************
-    [function]: 
-                          callback:                 read register value ftom ctpm by i2c interface;
-    [parameters]:
-                        reg_name[in]:         the register which you want to read;
-                           rx_buf[in]:              data buffer which is used to store register value;
-                           rx_length[in]:          the length of the data buffer;
-    [return]:
-                           FTS_TRUE:              success;
-                           FTS_FALSE:             fail;
-************************************************************************/
-static bool fts_register_read(u8 reg_name, u8* rx_buf, int rx_length)
-{
-       u8 read_cmd[2]= {0};
-       u8 cmd_len      = 0;
 
-       read_cmd[0] = reg_name;
-       cmd_len = 1;    
+       memset(event, ~0x00, sizeof(struct ts_event));
 
-       /*send register addr*/
-       if(!i2c_write_interface(&read_cmd[0], cmd_len))
-       {
-               return false;
+#if USE_POINT
+       event->touch_point = buf[2] & 0x07;// 0000 1111
+#else
+       event->touch_point = buf[2] >>4;// 0000 1111
+#endif
+   if (event->touch_point == 0) {
+               rember_point_into = false;
+#ifdef LONGPRESS_LOCK_SPECKEY
+               if(Origin2LockPressCnt)
+               {//说明按到了search键
+                       if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
+                       {//没有长按
+                               if(lockflag ==0)
+                               {//键盘没锁
+                                       input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
+                                       input_sync(data->input_dev);
+                                       input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
+                                       input_sync(data->input_dev);
+                                       //printk("menu is up ==========================\n");
+                               }
+                       }
+                       else
+                       {
+                               //printk("release long press !!!!!!!!!!!!!!!!!\n");
+                               input_report_key(data->input_dev, KEY_LOCK, 0);
+                               //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
+                               input_sync(data->input_dev);
+                       }
+                       Origin2LockPressCnt = 0;
+                       touch_key_hold_press = 0;
+               }
+#endif
+#ifdef NEW_PAL_DRV
+               if(touch_key_hold_press)
+               {
+                       touch_key_hold_press = 0;
+                       for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
+                       {
+                               if(touch_key_press[key])
+                               {
+                                       input_report_key(data->input_dev, touch_key_code[key], 0);
+                                       touch_key_press[key] = 0;
+                                        input_sync(data->input_dev);
+                                       //printk("up::KEY: %d\n", touch_key_code[key]);
+                               }
+                       }
+               }
+#endif
+               gpress = 0;
+               MotoStart =0;
+               //printk("release point !!!!!!!!!!!!!!!!!\n");
+               //ft5x0x_ts_release(data);
+               #ifdef CHECK_KEY
+               //event->penddown = Release;
+               #endif
+               return 0;
        }
 
-       /*call the read callback function to get the register value*/           
-       if(!i2c_read_interface(rx_buf, rx_length))
-       {
-               return false;
+#ifdef CONFIG_FT5X0X_MULTITOUCH
+    switch (event->touch_point) {
+               case 5:
+                       event->point[4].status = (buf[0x1b] & 0xc0)>>6;
+                       event->point[4].id = (buf[0x1d] & 0xf0)>>4;
+                       event->point[4].x = (s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c];
+                       event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e];
+               case 4:
+                       event->point[3].status = (buf[0x15] & 0xc0)>>6;
+                       event->point[3].id = (buf[0x17] & 0xf0)>>4;
+                       event->point[3].x = (s16)(buf[0x15] & 0x07)<<8 | (s16)buf[0x16];
+                       event->point[3].y = (s16)(buf[0x17] & 0x07)<<8 | (s16)buf[0x18];
+               case 3:
+                       event->point[2].status = (buf[0x0f] & 0xc0)>>6;
+                       event->point[2].id = (buf[0x11] & 0xf0)>>4;
+                       event->point[2].x = (s16)(buf[0x0f] & 0x07)<<8 | (s16)buf[0x10];
+                       event->point[2].y = (s16)(buf[0x11] & 0x07)<<8 | (s16)buf[0x12];
+               case 2:
+                       event->point[1].status = (buf[0x09] & 0xc0)>>6;
+                       event->point[1].id = (buf[0x0b] & 0xf0)>>4;
+                       event->point[1].x = (s16)(buf[0x09] & 0x07)<<8 | (s16)buf[0x0a];
+                       event->point[1].y = (s16)(buf[0x0b] & 0x07)<<8 | (s16)buf[0x0c];
+               case 1:
+                       event->point[0].status = (buf[0x03] & 0xc0)>>6;
+                       event->point[0].id = (buf[0x05] & 0xf0)>>4;
+
+                       event->point[0].y = (s16)(buf[0x03] & 0x0f)<<8 | (s16)buf[0x04];
+                       event->point[0].x = (s16)(buf[0x05] & 0x0f)<<8 | (s16)buf[0x06];
+                       event->point[0].x = 480 - event->point[0].x;
+                       if(event->point[0].x < 0){
+                               event->point[0].x = 0;
+                       }
+
+        default:
+                   return 0;
        }
-       return true;
+#endif
 }
 
+static void ft5x0x_report_value(void)
+{
+       struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
+       struct ts_event *event = &data->event;
+       u8 j;
+       u8 i = 0;
+       int key_id = 0xff;
+#if 0
+       printk("point is %d x0 is %d y0 is %d\n",
+                       //P1 status is %x ID1 is %x x1 is 0x%x y1 is 0x%x\n\n",
+                                       event->touch_point,
+                                       //event->point[0].status,       //event->point[0].id,
+                                       event->point[0].y, event->point[0].x);
+                                       //event->point[1].status, event->point[1].id,
+                                       //event->point[1].x, event->point[1].y);
+#endif
+#if USE_POINT
+       down_table = 0;
+
+               for(i=0; i<event->touch_point; i++) {
+               //================
+               //printk("event->x[%d]:%d,event->y[%d]:%d\n", i,event->x[i],i,event->y[i]);
+               if((event->point[i].y > KEY_MIN_X) && (debug1)/*&&(posx[i]<KEY_MAX_X)*/)
+                               {
+                                for(j=0;j<KEY_NUM;j++)
+                                  {
+                                               //printk("i === %d,event->point[i].x==%d,event->point[i].y===%d\n",i,event->point[i].x,event->point[i].y);
+                                     if((event->point[i].x >touch_key_min[j])&&(event->point[i].x <touch_key_max[j]))
+                                     {
+                                         key_id = j;
+                                               //  printk("touch_key_hold_press = %d\n",touch_key_hold_press);
+                                             if((touch_key_press[key_id] == 0) && (touch_key_hold_press == 0))
+                                             {
+                                        #ifdef  LONGPRESS_LOCK_SPECKEY
+                                             //        printk("touch_key_code[%d]:%d\n",key_id,touch_key_code[key_id]);
+
+                                               if(touch_key_code[key_id] == ORIGIN_KEY)
+                                                       {      /*
+                                                               if(++Origin2LockPressCnt>LOCK_LONG_PRESS_CNT)
+                                                                       {
+                                                                       Origin2LockPressCnt = LOCK_LONG_PRESS_CNT + 2;
+                                                                       input_report_key(data->input_dev, KEY_LOCK, 1);
+                                                                       touch_key_hold_press = 1;
+                                                                       if(lockflag)
+                                                                               lockflag =0;
+                                                                       else
+                                                                               lockflag =1;
+                                                                       }*/
+                                                                       Origin2LockPressCnt=1;
+                                                               break;
+                                                               }
+                                                  //if(lockflag)
+                                                               //goto out;
+                                               #endif
+                                              input_report_key(data->input_dev, touch_key_code[key_id], 1);
+                                              touch_key_press[key_id] = 1;
+                                              touch_key_hold_press = 1;
+                                            //  printk("down::KEY: %d\n", touch_key_code[key_id]);
+                                             }
+                                                 break;
+                                     }
+                                  }
+                               }
+               else
+                               {
+                               input_mt_slot(data->input_dev, event->point[i].id);
+
+                                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
+
+                                       down_table |= 1 << event->point[i].id;
+                                       input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 100);
+                                       input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
+                                       input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
+                                       input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
+                                 // printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i].id,event->point[i].x,event->point[i].y);
+
+                               }
 
 
-/***********************************************************************
-[function]: 
-                        callback:          burn the FW to ctpm.
-[parameters]:
-                           pbt_buf[in]:     point to Head+FW ;
-                           dw_lenth[in]:   the length of the FW + 6(the Head length);    
-[return]:
-                           ERR_OK:          no error;
-                           ERR_MODE:      fail to switch to UPDATE mode;
-                           ERR_READID:   read id fail;
-                           ERR_ERASE:     erase chip fail;
-                           ERR_STATUS:   status error;
-                           ERR_ECC:        ecc error.
-************************************************************************/
-E_UPGRADE_ERR_TYPE  fts_ctpm_fw_upgrade(u8* pbt_buf, int dw_lenth)
-{
-    u8  cmd,reg_val[2] = {0};
-       u8  buffer[2] = {0};
-    u8  packet_buf[FTS_PACKET_LENGTH + 6];
-    u8  auc_i2c_write_buf[10];
-    u8  bt_ecc;
-       
-    int  j,temp,lenght,i_ret,packet_number, i = 0;
-    int  i_is_new_protocol = 0;
-       
+                       }
 
-    /******write 0xaa to register 0xfc******/
-    cmd=0xaa;
-    fts_register_write(0xfc,&cmd);
-    mdelay(50);
-       
-     /******write 0x55 to register 0xfc******/
-    cmd=0x55;
-    fts_register_write(0xfc,&cmd);
-    FTprintk("[TSP] Step 1: Reset CTPM test\n");
-   
-    mdelay(10);   
-
-
-    /*******Step 2:Enter upgrade mode ****/
-    FTprintk("\n[TSP] Step 2:enter new update mode\n");
-    auc_i2c_write_buf[0] = 0x55;
-    auc_i2c_write_buf[1] = 0xaa;
-    do
-    {
-        i ++;
-        i_ret = fts_i2c_txdata(auc_i2c_write_buf, 2);
-        mdelay(5);
-    }while(i_ret <= 0 && i < 10 );
-
-    if (i > 1)
-    {
-        i_is_new_protocol = 1;
-    }
+       for(i=0; i<MAX_CONTACTS; i++) {
+               if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
+               {
+                       input_mt_slot(data->input_dev, i);
+                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
+                         /*printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i]
+.id,event->point[i].y,event->point[i].x);*/
+               }
+       }
+       up_table = ~down_table;
+        input_sync(data->input_dev);
+#else
 
-    /********Step 3:check READ-ID********/        
-    cmd_write(0x90,0x00,0x00,0x00,4);
-    byte_read(reg_val,2);
-    if (reg_val[0] == 0x79 && reg_val[1] == 0x3)
-    {
-        FTprintk("[TSP] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]);
-    }
-    else
-    {
-        return ERR_READID;
-        //i_is_new_protocol = 1;
-    }
-    
+       for(i=0; i<event->touch_point; i++) {
+               if(event->point[i].status == 0 || event->point[i].status == 2 ) {
+                       input_mt_slot(data->input_dev, event->point[i].id);
+                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
+                       input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 200);
+                       input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
+                       input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
+                       input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
+               }
+               else if(event->point[i].status == 1) {
+                       input_mt_slot(data->input_dev, event->point[i].id);
+                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
+               }
+       }
+       input_sync(data->input_dev);
+#endif
 
-     /*********Step 4:erase app**********/
-    if (i_is_new_protocol)
-    {
-        cmd_write(0x61,0x00,0x00,0x00,1);
-    }
-    else
-    {
-        cmd_write(0x60,0x00,0x00,0x00,1);
-    }
-    mdelay(1500);
-    FTprintk("[TSP] Step 4: erase. \n");
-
-
-
-    /*Step 5:write firmware(FW) to ctpm flash*/
-    bt_ecc = 0;
-    FTprintk("[TSP] Step 5: start upgrade. \n");
-    dw_lenth = dw_lenth - 8;
-    packet_number = (dw_lenth) / FTS_PACKET_LENGTH;
-    packet_buf[0] = 0xbf;
-    packet_buf[1] = 0x00;
-       FTprintk("[TSP]  packet_number = %d\n",packet_number);
-    for (j=0;j<packet_number;j++)
-    {
-        temp = j * FTS_PACKET_LENGTH;
-        packet_buf[2] = (u8)(temp>>8);
-        packet_buf[3] = (u8)temp;
-        lenght = FTS_PACKET_LENGTH;
-        packet_buf[4] = (u8)(lenght>>8);
-        packet_buf[5] = (u8)lenght;
-
-        for (i=0;i<FTS_PACKET_LENGTH;i++)
-        {
-            packet_buf[6+i] = pbt_buf[j*FTS_PACKET_LENGTH + i]; 
-            bt_ecc ^= packet_buf[6+i];
-        }
-        
-        byte_write(&packet_buf[0],FTS_PACKET_LENGTH + 6);
-        mdelay(FTS_PACKET_LENGTH/6 + 1);
-        if ((j * FTS_PACKET_LENGTH % 1024) == 0)
-        {
-              FTprintk("[TSP] upgrade the 0x%x th byte.\n", ((unsigned int)j) * FTS_PACKET_LENGTH);
-        }
-    }
 
-    if ((dw_lenth) % FTS_PACKET_LENGTH > 0)
-    {
-        temp = packet_number * FTS_PACKET_LENGTH;
-        packet_buf[2] = (u8)(temp>>8);
-        packet_buf[3] = (u8)temp;
 
-        temp = (dw_lenth) % FTS_PACKET_LENGTH;
-        packet_buf[4] = (u8)(temp>>8);
-        packet_buf[5] = (u8)temp;
 
-        for (i=0;i<temp;i++)
-        {
-            packet_buf[6+i] = pbt_buf[ packet_number*FTS_PACKET_LENGTH + i]; 
-            bt_ecc ^= packet_buf[6+i];
-        }
+ out:
+ ;
+#ifdef CHECK_KEY
+                                        data->timer.expires    = jiffies +8;
+                                       add_timer(&data->timer);
+                                       down_table = 0;
 
-        byte_write(&packet_buf[0],temp+6);    
-        mdelay(20);
-    }
+#endif
 
-    /***********send the last six byte**********/
-    for (i = 0; i<6; i++)
-    {
-        temp = 0x6ffa + i;
-        packet_buf[2] = (u8)(temp>>8);
-        packet_buf[3] = (u8)temp;
-        temp =1;
-        packet_buf[4] = (u8)(temp>>8);
-        packet_buf[5] = (u8)temp;
-        packet_buf[6] = pbt_buf[ dw_lenth + i]; 
-        bt_ecc ^= packet_buf[6];
-
-        byte_write(&packet_buf[0],7);  
-        mdelay(20);
-    }
 
-    /********send the opration head************/
-    cmd_write(0xcc,0x00,0x00,0x00,1);
-    byte_read(reg_val,1);
-    FTprintk("[TSP] Step 6:  ecc read 0x%x, new firmware 0x%x. \n", reg_val[0], bt_ecc);
-    if(reg_val[0] != bt_ecc)
-    {
-        return ERR_ECC;
-    }
 
-    /*******Step 7: reset the new FW**********/
-    cmd_write(0x07,0x00,0x00,0x00,1);
-       mdelay(100);//100ms     
-       fts_register_read(0xfc, buffer, 1);     
-       if (buffer[0] == 1)
-       {
-       cmd=4;
-       fts_register_write(0xfc, &cmd);
-       mdelay(2500);//2500ms   
-        do     
-        {      
-        fts_register_read(0xfc, buffer, 1);    
-        mdelay(100);//100ms    
-        }while (buffer[0] != 1);                       
+
+}      /*end ft5x0x_report_value*/
+
+static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
+{
+       int ret = -1;
+       //printk("==ft5x0x_ts_pen_work =\n");
+       ret = ft5x0x_read_data();
+       if (ret == 0) {
+               ft5x0x_report_value();
        }
-    return ERR_OK;
+  enable_irq(g_dev->irq);
 }
 
+static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
+{
+       struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
 
-/***********************************************************************/
+#ifdef CHECK_KEY
 
-int fts_ctpm_fw_upgrade_with_i_file(void)
-{
-   u8*     pbt_buf = 0;
-   int i_ret;
-    
-   pbt_buf = CTPM_FW;
-   i_ret =  fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW));
-   
-   return i_ret;
-}
+                       del_timer(&ft5x0x_ts->timer);
+#endif
+       disable_irq_nosync(g_dev->irq);
+  //printk("==ft5x0x_ts_interrupt =\n");
+       queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
 
-/***********************************************************************/
+       return IRQ_HANDLED;
+}
 
-unsigned char fts_ctpm_get_upg_ver(void)
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ft5x0x_ts_suspend(struct early_suspend *handler)
 {
-    unsigned int ui_sz;
+       int ret;
+       struct ft5x0x_ts_dev *ts;
+       ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
        
-    ui_sz = sizeof(CTPM_FW);
-    if (ui_sz > 2)
-    {
-        return CTPM_FW[ui_sz - 2];
-    }
-    else
-        return 0xff; 
+       if(ts->irq)
+               disable_irq_nosync(ts->irq);
+
+       ret = cancel_work_sync(&ts->pen_event_work);
+       if (ret && ts->irq) /* if work was pending disable-count is now 2 */
+               enable_irq(ts->irq);
+       // ==set mode ==,
+//  ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
 }
 
-/*read the it7260 register ,used i2c bus*/
-static int ft5306_read_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned len)
+static void ft5x0x_ts_resume(struct early_suspend *handler)
 {
-       int ret; 
-       ret = i2c_master_reg8_recv(client, reg, buf, len, FT5306_IIC_SPEED);
-       return ret; 
-}
+       struct ft5x0x_ts_dev *ts;
+       ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
+       // wake the mode
+//     gpio_direction_output(RK29_PIN6_PC3, 0);
+//     gpio_set_value(RK29_PIN6_PC3,GPIO_LOW);
+//     msleep(50);
+//     gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH);
+
+#if USE_POINT
+       down_table      = 0;
+       up_table        = ~0;
+#endif
 
-/* set the it7260 registe,used i2c bus*/
-static int ft5306_set_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned short len)
-{
-       int ret; 
-       ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5306_IIC_SPEED);
-       return ret;
+       if(ts->irq)
+               enable_irq(ts->irq);
 }
-
-static void ft5306_queue_work(struct work_struct *work)
+#endif  //CONFIG_HAS_EARLYSUSPEND
+#ifdef CHECK_KEY
+static void Touch_timer_release(unsigned long ft_ts_pdev)
 {
-       struct ft5x0x_ts_data *data = container_of(work, struct ft5x0x_ts_data, pen_event_work);
-       struct tp_event event;
-       u8 start_reg=0x0;
-       u8 buf[32] = {0};
-       int ret,i,offset,points;
-       static u8 points_last_flag[MAX_POINT]={0};
-       struct tp_event  current_events[MAX_POINT];
-               
-#if CONFIG_FT5X0X_MULTITOUCH
-       ret = ft5306_read_regs(data->client,start_reg, buf, 6*MAX_POINT+1);
-#else
-       ret = ft5306_read_regs(data->client,start_reg, buf, 7);
-#endif
-       if (ret < 0) {
-               dev_err(&data->client->dev, "ft5306_read_regs fail:%d!\n",ret);
-               enable_irq(data->irq);
-               return;
-       }
-#if 0
-       for (i=0; i<32; i++) {
-               FTprintk("buf[%d] = 0x%x \n", i, buf[i]);
-       }
+
+       struct ft5x0x_ts_dev *data = ft_ts_pdev;
+       int key, i=0;
+       int inflag =0;
+       /*if(rember_point_into)
+       {
+              for(i=0;i<MAX_CONTACTS;i++)
+                  {
+                     printk("hand to modefy with up !!!!!!\n");
+#if   1
+                      input_mt_slot(data->input_dev, i);
+                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
 #endif
-       
-       points = buf[2] & 0x07;
-       //dev_info(&data->client->dev, "ft5306_read_and_report_data points = %d\n",points);
-       if (points == 0) {
-#if   CONFIG_FT5X0X_MULTITOUCH
-               //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
-               //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0);
-               
-               for(i=0;i<MAX_POINT;i++)
+                 }
+
+       input_sync(data->input_dev);
+       rember_point_into = true;
+       }*/
+
+  for(i=0; i<MAX_CONTACTS; i++) {
+               if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
                {
-                       if(points_last_flag[i]!=0)
+                     printk("%d is up !!!!!!\n",i);
+                       input_mt_slot(data->input_dev, i);
+                       input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
+                               inflag =1;
+               }
+               }
+  if(inflag==1)input_sync(data->input_dev);
+    inflag = 0;
+//===================================
+#ifdef LONGPRESS_LOCK_SPECKEY
+
+               if(Origin2LockPressCnt)
+               {//说明按到了search键
+                       if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
+                       {//没有长按
+                               //if(lockflag ==0)
+                               {//键盘没锁
+                                       input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
+                                       input_sync(data->input_dev);
+                                       input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
+                                       input_sync(data->input_dev);
+                                       //printk("menu is up ==========================\n");
+                               }
+                       }
+                       else
                        {
-                               FTprintk("Point UP event.id=%d\n",i);
-                               input_mt_slot(data->input_dev, i);
-                               input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);                                     
+                               //printk("release long press !!!!!!!!!!!!!!!!!\n");
+                               //input_report_key(data->input_dev, KEY_LOCK, 0);
+                               //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
+                               //input_sync(data->input_dev);
                        }
+                       Origin2LockPressCnt = 0;
+                       touch_key_hold_press = 0;
                }
-
-               memset(points_last_flag, 0, sizeof(points_last_flag));
-               //input_mt_sync(data->input_dev);
-#else
-               input_report_abs(data->input_dev, ABS_PRESSURE, 0);
-               input_report_key(data->input_dev, BTN_TOUCH, 0);
 #endif
-               input_sync(data->input_dev);
-               enable_irq(data->irq);
-               return; 
-       }
-       memset(&event, 0, sizeof(struct tp_event));
-#if CONFIG_FT5X0X_MULTITOUCH
-  memset(current_events, 0, sizeof(current_events));
-  
-       for(i=0;i<points;i++){
-               offset = i*6+3;
-               event.x = (((s16)(buf[offset+0] & 0x0F))<<8) | ((s16)buf[offset+1]);
-               event.y = (((s16)(buf[offset+2] & 0x0F))<<8) | ((s16)buf[offset+3]);
-               event.id = (s16)(buf[offset+2] & 0xF0)>>4;
-               event.flag = ((buf[offset+0] & 0xc0) >> 6);
-               event.pressure = 200;
-               FTprintk("x=%d, y=%d event.id=%d event.flag=%d\n",event.x,event.y,event.id,event.flag);
-               if(event.x<=SCREEN_MAX_X && event.y<=SCREEN_MAX_Y+60){
-                       //dev_info(&data->client->dev, 
-                       //      "ft5306 multiple report event[%d]:x = %d,y = %d,id = %d,flag = %d,pressure = %d\n",
-                       //      i,event.x,event.y,event.id,event.flag,event.pressure);
-               if(event.flag)
-                       memcpy(&current_events[event.id], &event, sizeof(event));
-                       //points_current[event.id] = event.flag;                        
-               }
-       }
-       
-       for(i=0;i<MAX_POINT;i++)
-       {
-                 if((current_events[i].flag == 0) && (points_last_flag[i] != 0))
+#ifdef NEW_PAL_DRV
+               if((touch_key_hold_press)&&(debug1))
+               {
+                       touch_key_hold_press = 0;
+                       for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
                        {
-               FTprintk("Point UP event.id=%d\n",i);
-                                       input_mt_slot(data->input_dev, i);
-                                       input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);                                             
+                               if(touch_key_press[key])
+                               {
+                                       input_report_key(data->input_dev, touch_key_code[key], 0);
+                                       touch_key_press[key] = 0;
+                                       input_sync(data->input_dev);
+                                       //printk("up::KEY: %d\n", touch_key_code[key]);
+                               }
                        }
-                       else  if(current_events[i].flag)        
-                       {       
-                               FTprintk("Point DN event.id=%d\n",i);
-                                       input_mt_slot(data->input_dev, i);
-                                       input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true);
-                                       input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1);
-                                       //input_report_abs(data->input_dev, ABS_MT_PRESSURE, event.pressure);
-                                       input_report_abs(data->input_dev, ABS_MT_POSITION_X,  current_events[i].x);
-                                       input_report_abs(data->input_dev, ABS_MT_POSITION_Y,  current_events[i].y);                                                                     
-                       }               
-                       points_last_flag[i] =   current_events[i].flag;
-       }
-#else
-       event.x = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
-       event.y = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
-       event.pressure =200;
-       input_report_abs(data->input_dev, ABS_X, event.x);
-       input_report_abs(data->input_dev, ABS_Y, event.y);
-       //input_report_abs(data->input_dev, ABS_PRESSURE, event.pressure);
-       input_report_key(data->input_dev, BTN_TOUCH, 1);
-       
-       
-       //dev_info(&data->client->dev, "ft5306 single report event:x = %d,y = %d\n",event.x,event.y);
+               }
 #endif
-       //dev_info(&data->client->dev, "ft5306 sync\n",event.x,event.y);
-       input_sync(data->input_dev);
-       enable_irq(data->irq);
-       return;
-}
-
-static irqreturn_t ft5306_interrupt(int irq, void *dev_id)
-{
-       struct ft5x0x_ts_data *ft5x0x_ts = dev_id;
-       FTprintk("[TSP]  ft5306_interrupt\n");
-       disable_irq_nosync(ft5x0x_ts->irq);
-       if (!work_pending(&ft5x0x_ts->pen_event_work)) 
-               queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
-       return IRQ_HANDLED;
-}
-#ifdef CONFIG_HAS_EARLYSUSPEND
 
-static int ft5306_suspend(struct early_suspend *h)
-{
-       struct ft5x0x_ts_data *ft5x0x_ts;
-       char buf_w[1] = {3};
-       int err;
-    ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend);
-       FTprintk("TSP ft5306_suspend\n");
-       //if (ft5x0x_ts->platform_sleep){ 
-       //      ft5x0x_ts->platform_sleep();
-       //}
-               err = ft5306_set_regs(this_client,0xA5,buf_w,1);
-       if (err>0)
-               printk("ft5306_set_regs OK!!\n");
-       disable_irq(ft5x0x_ts->irq);
-       return 0;
+//===================================
+       
+       
+       
 }
 
-
-static int ft5306_resume(struct early_suspend *h)
-{
-       struct ft5x0x_ts_data *ft5x0x_ts;       
-       ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend);
-       FTprintk("TSP ft5306_resume\n");
-       enable_irq(ft5x0x_ts->irq);
-       //if (ft5x0x_ts->platform_wakeup)                              
-               //ft5x0x_ts->platform_wakeup();
-       gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
-       msleep(10);
-       gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
-       return 0;
-}
 #endif
 
-static int __devexit ft5306_remove(struct i2c_client *client)
-{
-       struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
-
-       free_irq(ft5x0x_ts->irq, ft5x0x_ts);
-       input_unregister_device(ft5x0x_ts->input_dev);
-       kfree(ft5x0x_ts);
-       cancel_work_sync(&ft5x0x_ts->pen_event_work);
-       destroy_workqueue(ft5x0x_ts->ts_workqueue);
-       i2c_set_clientdata(client, NULL);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-    unregister_early_suspend(&ft5x0x_ts->ft5306_early_suspend);
-#endif 
-    this_client = NULL;
-       return 0;
-}
-
-static int  ft5306_probe(struct i2c_client *client ,const struct i2c_device_id *id)
+static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-       struct ft5x0x_ts_data *ft5x0x_ts;
+       struct ft5x0x_ts_dev *ft5x0x_ts;
+       struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data;
        struct input_dev *input_dev;
-       struct ft5406_platform_data *pdata = client->dev.platform_data;
        int err = 0;
-       int ret = 0;
-       int retry = 0;
        u8 buf_w[1];
        u8 buf_r[1];
-       const u8 buf_test[1] = {0};
-    unsigned char reg_value;
-    unsigned char reg_version;
-
-       dev_info(&client->dev, "ft5306_ts_probe!\n");
-       if (!pdata) {
-               dev_err(&client->dev, "platform data is required!\n");
-               return -EINVAL;
+       u8 buf[3]={0};  //w++
+
+
+       if (pdata == NULL) {
+               dev_err(&client->dev, "%s: platform data is null\n", __func__);
+               goto exit_platform_data_null;
+       }
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               err = -ENODEV;
+               goto exit_check_functionality_failed;
        }
 
        if (pdata->init_platform_hw)                              
                pdata->init_platform_hw();
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){
-               dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
-               return -ENODEV;
+
+
+       err_ft5X06=i2c_master_reg8_recv(client, 0x02, buf, 2, 200*1000);  //w++6
+       //err_ft5X06 = i2c_master_reg8_recv(client, 0x00, buf, 2, 200 * 1000);  //w++5
+
+       //buf[0] = 0x00;
+       //err_ft5X06 = ft5x0x_i2c_rxdata(buf,1);
+       if(err_ft5X06<0){
+               printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,err);
+               return err;
        }
-       
-       ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
-       ft5x0x_ts->platform_wakeup = pdata->platform_wakeup;
-       ft5x0x_ts->platform_sleep = pdata->platform_sleep;      
+
+
+       ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
        if (!ft5x0x_ts) {
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto exit_alloc_data_failed;
        }
 
-       while(retry < 5)
-       {
-               ret=ft5306_set_regs(client,FT5X0X_REG_PMODE, buf_test,1);
-               if(ret > 0)break;
-               retry++;
-       }
-       if(ret <= 0)
-       {
-               FTprintk("FT5306 I2C TEST ERROR!\n");
-               err = -ENODEV;
-               goto exit_i2c_test_fail;
-       }
-       
        input_dev = input_allocate_device();
        if (!input_dev) {
                err = -ENOMEM;
-               FTprintk("failed to allocate input device\n");
+               dev_err(&client->dev, "failed to allocate input device\n");
                goto exit_input_dev_alloc_failed;
        }
-       ft5x0x_ts->client = this_client = client;
-       ft5x0x_ts->irq = client->irq;
+
        ft5x0x_ts->input_dev = input_dev;
+       ft5x0x_ts->client = client;
+       ft5x0x_ts->irq = client->irq;
 
-  #if   CONFIG_FT5X0X_MULTITOUCH
+       __set_bit(EV_ABS, input_dev->evbit);
+       __set_bit(EV_KEY, input_dev->evbit);
+       __set_bit(EV_REP,  input_dev->evbit);
        __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
-       __set_bit(EV_ABS, input_dev->evbit);    
-
-       input_mt_init_slots(input_dev, MAX_POINT);
-       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);      
-       input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
-       input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
-       //input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, MAX_POINT, 0, 0);
-       //input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
-       
-#else
-       set_bit(ABS_X, input_dev->absbit);
-       set_bit(ABS_Y, input_dev->absbit);
-       set_bit(ABS_PRESSURE, input_dev->absbit);
-       set_bit(BTN_TOUCH, input_dev->keybit);
-       input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
-       //input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);
+       set_bit(ABS_MT_POSITION_X, input_dev->absbit);
+       set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
+       set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
+       set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
+
+       input_mt_init_slots(input_dev, MAX_CONTACTS);
+
+       input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
+       input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
+       input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
+       input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
+#if  CONFIG_TOUCH_PANEL_KEY
+       set_bit(KEY_HOMEPAGE, input_dev->keybit);
+       set_bit(KEY_MENU, input_dev->keybit);
+       set_bit(KEY_BACK, input_dev->keybit);
+       set_bit(KEY_SEARCH, input_dev->keybit);
+#ifdef LONGPRESS_LOCK_SPECKEY
+       //      set_bit(KEY_SEARCH, input_dev->keybit);
+       set_bit(KEY_LOCK, input_dev->keybit);
+#endif
 #endif
 
-       //input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 
-       //input_dev->keybit[BIT_WORD(BTN_START)] = BIT_MASK(BTN_START);
-       //set_bit(EV_ABS, input_dev->evbit);
-       //set_bit(EV_KEY, input_dev->evbit);
-       
-       input_dev->name         = "ft5x0x_ts-touchscreen";              //dev_name(&client->dev)
+       input_dev->name         = FT5X0X_NAME;          //dev_name(&client->dev)
        err = input_register_device(input_dev);
        if (err) {
-               FTprintk("ft5306_ts_probe: failed to register input device: \n");
+               dev_err(&client->dev,
+               "ft5x0x_ts_probe: failed to register input device: %s\n",
+               dev_name(&client->dev));
                goto exit_input_register_device_failed;
        }
 
-       if (!ft5x0x_ts->irq) {
-               err = -ENODEV;
-               dev_err(&ft5x0x_ts->client->dev, "no IRQ?\n");
-               goto exit_no_irq_fail;
-       }else{
-               ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
-       }
+       g_dev = ft5x0x_ts;
 
-       INIT_WORK(&ft5x0x_ts->pen_event_work, ft5306_queue_work);
-       ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");
+       i2c_set_clientdata(client, ft5x0x_ts);
+       INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
+       ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME);
        if (!ft5x0x_ts->ts_workqueue) {
                err = -ESRCH;
                goto exit_create_singlethread;
        }
 
-       /***wait CTP to bootup normally***/
-       msleep(200); 
-#if 1  //write firmware 
-       fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);
-       FTprintk("[TSP] firmware version = 0x%2x\n", reg_version);
-       if (fts_ctpm_get_upg_ver() != reg_version)  
-       {
-         FTprintk("[TSP] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver());
-         msleep(200);
-         err =  fts_ctpm_fw_upgrade_with_i_file();
-         if (err == 0)
-         {
-                 FTprintk("[TSP] ugrade successfuly.\n");
-                 msleep(300);
-                 fts_register_read(FT5X0X_REG_FIRMID, &reg_value,1);
-                 FTprintk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value);
-         }
-         else
-         {
-                 FTprintk("[TSP]  ugrade fail err=%d, line = %d.\n",err, __LINE__);
-         }
-         msleep(4000);
+  //if(pdata->init_platform_hw)
+     // pdata->init_platform_hw();
+
+  //ft5x0x_set_reg(0x80,0x64);
+
+  if(!ft5x0x_ts->irq)
+  {
+    dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
+    return -ENODEV;
+  }
+  else
+  {
+    ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
+  }
+
+  err = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING/*IRQF_DISABLED*/, "ft5x0x_ts", ft5x0x_ts);
+       if (err < 0) {
+               dev_err(&client->dev, "ft5x0x_probe: request irq failed\n");
+               goto exit_irq_request_failed;
        }
-#endif
-       ret = request_irq(ft5x0x_ts->irq, ft5306_interrupt, IRQF_TRIGGER_FALLING, client->dev.driver->name, ft5x0x_ts);
-       if (ret < 0) {
-               dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq);
-               goto exit_irq_request_fail;
-       }
-       i2c_set_clientdata(client, ft5x0x_ts);
+
+       disable_irq_nosync(g_dev->irq);
+
 #ifdef CONFIG_HAS_EARLYSUSPEND
-       ft5x0x_ts->ft5306_early_suspend.suspend =ft5306_suspend;
-       ft5x0x_ts->ft5306_early_suspend.resume =ft5306_resume;
-       ft5x0x_ts->ft5306_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;;
-       register_early_suspend(&ft5x0x_ts->ft5306_early_suspend);
+       ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+       ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend;
+       ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume;
+       register_early_suspend(&ft5x0x_ts->early_suspend);
+#endif
+#ifdef CHECK_KEY
+               setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts);
 #endif
+
+//wake the CTPM
+//     __gpio_as_output(GPIO_FT5X0X_WAKE);
+//     __gpio_clear_pin(GPIO_FT5X0X_WAKE);             //set wake = 0,base on system
+//      msleep(100);
+//     __gpio_set_pin(GPIO_FT5X0X_WAKE);                       //set wake = 1,base on system
+//     msleep(100);
+//     ft5x0x_set_reg(0x88, 0x05); //5, 6,7,8
+//     ft5x0x_set_reg(0x80, 30);
+//     msleep(50);
+
        buf_w[0] = 6;
-       err = ft5306_set_regs(client,0x88,buf_w,1);
-       buf_r[0] = 0;
-       err = ft5306_read_regs(client,0x88,buf_r,1);
-       FTprintk("read buf[0x88] = %d\n", buf_r[0]);
+       err = ft5x0x_set_reg(0x88,6);
+       //ft5x0x_i2c_txdata(0x88, buf_w, 1);    /* adjust frequency 60Hz */
+
+       buf_r[0] = 0x88;
+       err = ft5x0x_i2c_rxdata(buf_r,1);
+
+    enable_irq(g_dev->irq);
+
+printk("==ft5x0x_ts_probe = %0x\n", buf_r[0]);
+
     return 0;
 
-       i2c_set_clientdata(client, NULL);
-       free_irq(ft5x0x_ts->irq,ft5x0x_ts);
-exit_irq_request_fail:
-       cancel_work_sync(&ft5x0x_ts->pen_event_work);
-       destroy_workqueue(ft5x0x_ts->ts_workqueue);
-exit_create_singlethread:
-exit_no_irq_fail:
-       input_unregister_device(input_dev);
 exit_input_register_device_failed:
        input_free_device(input_dev);
 exit_input_dev_alloc_failed:
-exit_i2c_test_fail:
-       if (pdata->exit_platform_hw)                              
-               pdata->exit_platform_hw();
+       free_irq(client->irq, ft5x0x_ts);
+       //free_irq(IRQ_EINT(6), ft5x0x_ts);
+exit_irq_request_failed:
+exit_platform_data_null:
+       cancel_work_sync(&ft5x0x_ts->pen_event_work);
+       destroy_workqueue(ft5x0x_ts->ts_workqueue);
+exit_create_singlethread:
+       printk("==singlethread error =\n");
+       i2c_set_clientdata(client, NULL);
        kfree(ft5x0x_ts);
+exit_alloc_data_failed:
+exit_check_functionality_failed:
        return err;
 }
 
+static int __devexit ft5x0x_ts_remove(struct i2c_client *client)
+{
+       struct ft5x0x_ts_dev *ft5x0x_ts = i2c_get_clientdata(client);
+       unregister_early_suspend(&ft5x0x_ts->early_suspend);
+       free_irq(client->irq, ft5x0x_ts);
+       input_unregister_device(ft5x0x_ts->input_dev);
+       kfree(ft5x0x_ts);
+       cancel_work_sync(&ft5x0x_ts->pen_event_work);
+       destroy_workqueue(ft5x0x_ts->ts_workqueue);
+       i2c_set_clientdata(client, NULL);
+       return 0;
+}
 
-
-static struct i2c_device_id ft5306_idtable[] = {
-       { FT5X0X_NAME, 0 },
-       { }
+static const struct i2c_device_id ft5x0x_ts_id[] = {
+       { FT5X0X_NAME, 0 },{ }
 };
-
-MODULE_DEVICE_TABLE(i2c, ft5306_idtable);
-
-static struct i2c_driver ft5306_driver  = {
-       .driver = {
+MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);
+
+static struct i2c_driver ft5x0x_ts_driver = {
+       .probe          = ft5x0x_ts_probe,
+       .remove         = __devexit_p(ft5x0x_ts_remove),
+       .id_table       = ft5x0x_ts_id,
+       .driver = {
+               .name   = FT5X0X_NAME,
                .owner  = THIS_MODULE,
-               .name   = FT5X0X_NAME
        },
-       .id_table       = ft5306_idtable,
-       .probe      = ft5306_probe,
-    .suspend   = ft5306_suspend,
-       .resume     = ft5306_resume,
-       .remove         = __devexit_p(ft5306_remove),
 };
+#ifdef LONGPRESS_LOCK_SPECKEY
+static DRIVER_ATTR(get_lock_status, 0777, glock_status_show, NULL);
+#endif
+static DRIVER_ATTR(MOTOenable, 0666, Moto_status, Moto_control);
 
-static int __init ft5306_ts_init(void)
+static int __init ft5x0x_ts_init(void)
 {
-       return i2c_add_driver(&ft5306_driver);
+        int ret;
+ret = i2c_add_driver(&ft5x0x_ts_driver);
+        if (ret)
+        {
+            printk("Register 5406_ts driver failed.\n");
+            return ret;
+        }
+#ifdef LONGPRESS_LOCK_SPECKEY
+        if(err_ft5X06>=0)   //w++
+          ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
+#endif
+       if(err_ft5X06>=0)   //
+       ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
+           return ret;
 }
 
-static void __exit ft5306_ts_exit(void)
+static void __exit ft5x0x_ts_exit(void)
 {
-       FTprintk("Touchscreen driver of ft5306 exited.\n");
-       i2c_del_driver(&ft5306_driver);
+       i2c_del_driver(&ft5x0x_ts_driver);
+#ifdef LONGPRESS_LOCK_SPECKEY
+        driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
+#endif
+       driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
 }
 
-
-/***********************************************************************/
-
-module_init(ft5306_ts_init);
-module_exit(ft5306_ts_exit);
+module_init(ft5x0x_ts_init);
+module_exit(ft5x0x_ts_exit);
 
 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
+MODULE_LICENSE("GPL");