万利达c1014:增加GT8110 触摸驱动和hj101na lcd 驱动
authorwdc <wdc@rock-chips.com>
Mon, 24 Sep 2012 08:45:22 +0000 (16:45 +0800)
committerwdc <wdc@rock-chips.com>
Mon, 24 Sep 2012 08:48:53 +0000 (16:48 +0800)
[modifled-files]
arch/arm/mach-rk30/board-rk30-phonepad.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/gt8110_ts.c
drivers/video/display/screen/Kconfig
drivers/video/display/screen/Makefile
drivers/video/display/screen/lcd_hj101na.c
include/linux/gt8110.h

arch/arm/mach-rk30/board-rk30-phonepad.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/gt8110_ts.c [new file with mode: 0755]
drivers/video/display/screen/Kconfig
drivers/video/display/screen/Makefile
drivers/video/display/screen/lcd_hj101na.c [new file with mode: 0644]
include/linux/gt8110.h [new file with mode: 0755]

index ab328c8b5c5e885de08e7444f8261524c74d697b..428d72a604c504b64d73936f62504863b367e133 100755 (executable)
@@ -83,6 +83,9 @@
 #if defined(CONFIG_ANDROID_TIMED_GPIO)
 #include "../../../drivers/staging/android/timed_gpio.h"
 #endif
+#if defined(CONFIG_TOUCHSCREEN_GT8110)
+#include <linux/gt8110.h>
+#endif
 
 #if defined(CONFIG_MT6620)
 #include <linux/gps.h>
@@ -782,6 +785,7 @@ static struct rmi_device_platform_data s3202_platformdata = {
 #if defined(CONFIG_TOUCHSCREEN_GT8XX)
 #define TOUCH_RESET_PIN  RK30_PIN4_PD0
 #define TOUCH_PWR_PIN    INVALID_GPIO
+
 int goodix_init_platform_hw(void)
 {
        int ret;
@@ -952,6 +956,59 @@ static struct ct360_platform_data ct360_info = {
 #endif
 
 
+#ifdef CONFIG_TOUCHSCREEN_GT8110 
+#define TOUCH_ENABLE_PIN       INVALID_GPIO
+#define TOUCH_INT_PIN          RK30_PIN4_PC2
+#define TOUCH_RESET_PIN                RK30_PIN4_PD0
+int goodix_init_platform_hw(void)
+{
+
+       int ret;
+       rk30_mux_api_set(GPIO4D0_SMCDATA8_TRACEDATA8_NAME, GPIO4D_GPIO4D0);
+       rk30_mux_api_set(GPIO4C2_SMCDATA2_TRACEDATA2_NAME, GPIO4C_GPIO4C2);
+       printk("%s:0x%x,0x%x\n",__func__,rk30_mux_api_get(GPIO4D0_SMCDATA8_TRACEDATA8_NAME),rk30_mux_api_get(GPIO4C2_SMCDATA2_TRACEDATA2_NAME));
+
+       if (TOUCH_ENABLE_PIN != INVALID_GPIO) {
+               ret = gpio_request(TOUCH_ENABLE_PIN, "goodix power pin");
+               if (ret != 0) {
+                       gpio_free(TOUCH_ENABLE_PIN);
+                       printk("goodix power error\n");
+                       return -EIO;
+               }
+               gpio_direction_output(TOUCH_ENABLE_PIN, 0);
+               gpio_set_value(TOUCH_ENABLE_PIN, GPIO_LOW);
+               msleep(100);
+       }
+
+       if (TOUCH_RESET_PIN != INVALID_GPIO) {
+               ret = gpio_request(TOUCH_RESET_PIN, "goodix reset pin");
+               if (ret != 0) {
+                       gpio_free(TOUCH_RESET_PIN);
+                       printk("goodix gpio_request error\n");
+                       return -EIO;
+               }
+               gpio_direction_output(TOUCH_RESET_PIN, 0);
+               //msleep(100);
+               gpio_set_value(TOUCH_RESET_PIN, GPIO_LOW);
+               msleep(100);
+               //gpio_set_value(TOUCH_RESET_PIN, GPIO_HIGH);
+               //msleep(500);
+       }
+       return 0;
+}
+
+int goodix_exit_platform_hw(void)
+{
+    return 0;
+}
+
+struct goodix_8110_platform_data  goodix_info = {
+       .irq_pin = TOUCH_INT_PIN,
+       .reset= TOUCH_RESET_PIN,
+        .hw_init = goodix_init_platform_hw,
+        .hw_exit = goodix_exit_platform_hw,
+};
+#endif
 
 static struct spi_board_info board_spi_devices[] = {
 };
@@ -2503,7 +2560,15 @@ static struct i2c_board_info __initdata i2c2_info[] = {
        },
 #endif
 
-
+#if  defined(CONFIG_TOUCHSCREEN_GT8110)
+       {
+               .type          = "Goodix-TS",
+               .addr          = 0x5c,
+               .flags         = 0,
+               .irq           = TOUCH_INT_PIN,
+               .platform_data = &goodix_info,
+       },
+#endif
 };
 #endif
 
index d2ab259581d05848b37d55467c703877549608a6..7e52d0be83693bfa8f7cfd06a66fc9fa74d71c21 100644 (file)
@@ -999,6 +999,11 @@ config TOUCHSCREEN_GT819
        tristate "GT819 based touchscreens"
        depends on I2C2_RK29
 
+
+config TOUCHSCREEN_GT8110
+        tristate "GT8110 based touchscreens"
+        depends on I2C2_RK29 || I2C_RK30
+
 config TOUCHSCREEN_CT360_IIC
        tristate "CT360 based touchscreens"
        depends on I2C_RK29 || I2C_RK30
index 4959df0a7342df898ffd726258ceb90c9ae00b94..b26f7e4393bf94802e45a668bdfa57f808b4d97c 100644 (file)
@@ -77,6 +77,7 @@ obj-$(CONFIG_ATMEL_MXT1386)           += atmel_mxt1386.o
 obj-$(CONFIG_TOUCHSCREEN_GT801_IIC)    += gt801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GT82X_IIC)    += goodix_touch_82x.o
 obj-$(CONFIG_TOUCHSCREEN_GT818_IIC)    += gt818_ts.o
+obj-$(CONFIG_TOUCHSCREEN_GT8110)        += gt8110_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CT360_IIC)    += ct360_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC)  += ili2102_ts.o
 obj-$(CONFIG_D70_L3188A)               += goodix_touch.o
diff --git a/drivers/input/touchscreen/gt8110_ts.c b/drivers/input/touchscreen/gt8110_ts.c
new file mode 100755 (executable)
index 0000000..6df4eda
--- /dev/null
@@ -0,0 +1,1842 @@
+/* drivers/input/touchscreen/goodix_touch.c\r
+ *\r
+ * Copyright (C) 2010 - 2011 Goodix, Inc.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but WITHOUT\r
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
+ * more details.\r
+ *\r
+ */\r
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/time.h>\r
+#include <linux/delay.h>\r
+#include <linux/device.h>\r
+#include <linux/earlysuspend.h>\r
+#include <linux/hrtimer.h>\r
+#include <linux/i2c.h>\r
+#include <linux/input.h>\r
+#include <linux/input/mt.h>\r
+\r
+#include <linux/interrupt.h>\r
+#include <linux/io.h>\r
+#include <linux/platform_device.h>\r
+#include <mach/gpio.h>\r
+\r
+#include <linux/irq.h>\r
+#include <linux/syscalls.h>\r
+#include <linux/reboot.h>\r
+#include <linux/proc_fs.h>\r
+#include <linux/async.h>\r
+#include <linux/gt8110.h>
+\r
+#include <linux/vmalloc.h>\r
+#include <linux/fs.h>\r
+#include <linux/string.h>\r
+#include <linux/completion.h>\r
+#include <asm/uaccess.h>\r
+#include <mach/board.h>\r
+\r
+#define PEN_DOWN 1\r
+#define PEN_RELEASE 0\r
+#define PEN_DOWN_UP 2\r
+
+
+#define GOODIX_I2C_NAME "Goodix-TS"
+
+#define POLL_TIME              10      //actual query spacing interval:POLL_TIME+6
+
+#define MAX_FINGER_NUM  10
+
+struct rk_touch_info
+{
+       u32 press;
+       u32 x ;
+       u32 y ;
+       int status ; // 0 1
+} ;\r
+
+struct rk_ts_data{
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+       int irq;
+       int irq_pin;
+       int pwr_pin;
+       int rst_pin;
+       int read_mode;
+       struct hrtimer timer;
+       struct workqueue_struct *ts_wq;
+       struct delayed_work  ts_work;
+       char phys[32];
+       struct early_suspend early_suspend;
+       int (*power)(struct rk_ts_data * ts, int on);
+       int (*ts_init)(struct rk_ts_data*ts);
+       int (*input_parms_init)(struct rk_ts_data *ts);
+       void (*get_touch_info)(struct rk_ts_data *ts,char *point_num,struct rk_touch_info *info_buf);  //get touch data info
+       uint16_t abs_x_max;
+       uint16_t abs_y_max;
+       uint8_t max_touch_num;
+       bool            pendown;
+};
+
+struct goodix_ts_data {
+       uint16_t addr;
+       uint8_t bad_data;
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+       int use_reset;
+       int use_irq;
+       int read_mode;
+       struct hrtimer timer;
+       struct delayed_work  work;
+       char phys[32];
+       int retry;
+       struct early_suspend early_suspend;
+       int (*power)(struct goodix_ts_data * ts, int on);
+       uint16_t abs_x_max;
+       uint16_t abs_y_max;
+       uint8_t max_touch_num;
+       uint8_t int_trigger_type;
+       bool            pendown;
+};
+
+static const char *rk_ts_name = "Goodix Capacitive TouchScreen";
+static struct workqueue_struct *goodix_wq;
+static struct i2c_client * i2c_connect_client = NULL;
+static struct proc_dir_entry *goodix_proc_entry;
+
+
+#define READ_COOR_ADDR 0x01
+
+
+
+//*************************Firmware Update part*******************************
+#define CONFIG_TOUCHSCREEN_GOODIX_IAP
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
+#define UPDATE_NEW_PROTOCOL
+
+static unsigned int oldcrc32 = 0xFFFFFFFF;
+static unsigned int crc32_table[256];
+static unsigned int ulPolynomial = 0x04c11db7;
+static unsigned char rd_cfg_addr;
+static unsigned char rd_cfg_len;
+static unsigned char g_enter_isp = 0;
+
+static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data);
+static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data );
+
+#define PACK_SIZE                                      64                                      //update file package size
+#define MAX_TIMEOUT                                    60000                           //update time out conut
+#define MAX_I2C_RETRIES                                20                                      //i2c retry times
+
+//I2C buf address
+#define ADDR_CMD                                       80
+#define ADDR_STA                                       81
+#ifdef UPDATE_NEW_PROTOCOL
+       #define ADDR_DAT                                0
+#else
+       #define ADDR_DAT                                82
+#endif
+
+//moudle state
+#define NEW_UPDATE_START                       0x01
+#define UPDATE_START                           0x02
+#define SLAVE_READY                                    0x08
+#define UNKNOWN_ERROR                          0x00
+#define FRAME_ERROR                                    0x10
+#define CHECKSUM_ERROR                         0x20
+#define TRANSLATE_ERROR                                0x40
+#define FLASH_ERROR                                    0X80
+
+//error no
+#define ERROR_NO_FILE                          2       //ENOENT
+#define ERROR_FILE_READ                                23      //ENFILE
+#define ERROR_FILE_TYPE                                21      //EISDIR
+#define ERROR_GPIO_REQUEST                     4       //EINTR
+#define ERROR_I2C_TRANSFER                     5       //EIO
+#define ERROR_NO_RESPONSE                      16      //EBUSY
+#define ERROR_TIMEOUT                          110     //ETIMEDOUT
+
+//update steps
+#define STEP_SET_PATH              1
+#define STEP_CHECK_FILE            2
+#define STEP_WRITE_SYN             3
+#define STEP_WAIT_SYN              4
+#define STEP_WRITE_LENGTH          5
+#define STEP_WAIT_READY            6
+#define STEP_WRITE_DATA            7
+#define STEP_READ_STATUS           8
+#define FUN_CLR_VAL                9
+#define FUN_CMD                    10
+#define FUN_WRITE_CONFIG           11
+
+//fun cmd
+#define CMD_DISABLE_TP             0
+#define CMD_ENABLE_TP              1
+#define CMD_READ_VER               2
+#define CMD_READ_RAW               3
+#define CMD_READ_DIF               4
+#define CMD_READ_CFG               5
+#define CMD_SYS_REBOOT             101
+
+//read mode
+#define MODE_RD_VER                1
+#define MODE_RD_RAW                2
+#define MODE_RD_DIF                3
+#define MODE_RD_CFG                4
+#endif
+\r
+static struct rk_touch_info *info_buf;\r
+\r
+static int dbg_thresd = 0;\r
+#define DBG(x...) do { if(unlikely(dbg_thresd)) printk(KERN_INFO x); } while (0)\r
+\r
+\r
+/*******************************************************       \r
+Description:\r
+       Read data from the i2c slave device;\r
+       This operation consisted of 2 i2c_msgs,the first msg used\r
+       to write the operate address,the second msg used to read data.\r
+\r
+Parameter:\r
+       client: i2c device.\r
+       buf[0]:operate address.\r
+       buf[1]~buf[len]:read data buffer.\r
+       len:operate length.\r
+       \r
+return:\r
+       numbers of i2c_msgs to transfer\r
+*********************************************************/\r
+static int goodix_i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len)\r
+{\r
+       struct i2c_msg msgs[2];\r
+       int ret=-1;\r
+       int retries = 0;\r
+\r
+       msgs[0].flags = client->flags;\r
+       msgs[0].addr=client->addr;\r
+       msgs[0].len=1;\r
+       msgs[0].buf=&buf[0];\r
+       msgs[0].udelay = client->udelay;\r
+       msgs[0].scl_rate=200 * 1000;\r
+\r
+       msgs[1].flags = client->flags | I2C_M_RD;\r
+       msgs[1].addr=client->addr;\r
+       msgs[1].len=len-1;\r
+       msgs[1].buf=&buf[1];\r
+       msgs[1].udelay = client->udelay;\r
+       msgs[0].scl_rate=200 * 1000;\r
+\r
+       while(retries<5)\r
+       {\r
+               ret=i2c_transfer(client->adapter,msgs, 2);\r
+               if(ret == 2)break;\r
+               retries++;\r
+       }\r
+       return ret;\r
+}\r
+\r
+/*******************************************************       \r
+Description:\r
+       write data to the i2c slave device.\r
+\r
+Parameter:\r
+       client: i2c device.\r
+       buf[0]:operate address.\r
+       buf[1]~buf[len]:write data buffer.\r
+       len:operate length.\r
+       \r
+return:\r
+       numbers of i2c_msgs to transfer.\r
+*********************************************************/\r
+static int goodix_i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len)\r
+{\r
+       struct i2c_msg msg;\r
+       int ret=-1;\r
+       int retries = 0;\r
+\r
+       msg.flags=!I2C_M_RD;\r
+       msg.addr=client->addr;\r
+       msg.len=len;\r
+       msg.buf=data;           \r
+       msg.udelay = client->udelay;\r
+       msg.scl_rate=200 * 1000;\r
+       \r
+       while(retries<5)\r
+       {\r
+               ret=i2c_transfer(client->adapter,&msg, 1);\r
+               if(ret == 1)break;\r
+               retries++;\r
+       }\r
+       return ret;\r
+}\r
+\r
+static int goodix_config_ok(struct rk_ts_data *ts)\r
+{\r
+        int ret = 0;\r
+        unsigned int w,h, n;\r
+       uint8_t rd_cfg_buf[7] = {0x66,};\r
+        \r
+       ret = goodix_i2c_read_bytes(ts->client, rd_cfg_buf, 7);\r
+\r
+       w = (rd_cfg_buf[2]<<8) + rd_cfg_buf[1];\r
+       h = (rd_cfg_buf[4]<<8) + rd_cfg_buf[3];\r
+        n = rd_cfg_buf[5];\r
+\r
+\r
+       ts->abs_x_max = w;\r
+       ts->abs_y_max = h;\r
+       ts->max_touch_num = n;\r
+        \r
+       printk("goodix_ts_init: X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d\n",ts->abs_x_max,ts->abs_y_max,ts->max_touch_num);\r
+\r
+        return 0;\r
+}\r
+/*******************************************************\r
+Description:\r
+       Goodix touchscreen initialize function.\r
+\r
+Parameter:\r
+       ts:     i2c client private struct.\r
+       \r
+return:\r
+       Executive outcomes.0---succeed.\r
+*******************************************************/\r
+static int goodix_init_panel(struct rk_ts_data *ts)\r
+{\r
+       int ret=-1, retry = 10;\r
+       uint8_t rd_cfg_buf[7] = {0x66,};\r
+       char test_data = 0;\r
+\r
+       uint8_t config_info[] = {\r
+       0x65,0x02,0x00,0x10,0x00,0x10,0x0A,0x62,0x4A,0x00,
+       0x0F,0x28,0x02,0x10,0x10,0x00,0x00,0x20,0x00,0x00,
+       0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,
+       0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,
+       0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+       0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,
+       0x00,0x3C,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00\r
+        };\r
+\r
+        ret=goodix_i2c_write_bytes(ts->client,config_info,95);
+        if( ret == 1)
+        {
+               printk("GT8110 send config para successfully!\n");
+       }
+       else
+       {
+               printk("GT8110 send config para failed!\n");
+       }       \r
+       ts->abs_x_max = 4096;\r
+       ts->abs_y_max = 4096;\r
+        ts->max_touch_num = 10;\r
+        \r
+       return 0;\r
+\r
+}\r
+\r
+//fjp add ===============================\r
+static bool goodix_get_status(char *p1,int*p2)\r
+{\r
+       bool status = PEN_DOWN;\r
+       if((*p2==PEN_DOWN) && (*p1==PEN_RELEASE))\r
+               {\r
+                       *p2 = PEN_DOWN_UP; //¸Õ¸Õµ¯Æð\r
+                        status = PEN_RELEASE; \r
+               }\r
+       else if((*p2==PEN_RELEASE) && (*p1==PEN_RELEASE))\r
+               {\r
+                  *p2 = PEN_RELEASE;\r
+                       status = PEN_RELEASE; \r
+               }\r
+       else\r
+               {\r
+                       *p2 = PEN_DOWN;\r
+               }\r
+       return status;\r
+}\r
+\r
+//===================================\r
+/*******************************************************\r
+Description:\r
+       Read goodix touchscreen version function.\r
+\r
+Parameter:\r
+       ts:     i2c client private struct.\r
+       \r
+return:\r
+       Executive outcomes.0---succeed.\r
+*******************************************************/\r
+static int  goodix_read_version(struct rk_ts_data *ts, char **version)\r
+{\r
+       int ret = -1, count = 0;\r
+       char *version_data;\r
+       char *p;\r
+\r
+       *version = (char *)vmalloc(18);\r
+       version_data = *version;\r
+       if(!version_data)\r
+               return -ENOMEM;\r
+       p = version_data;\r
+       memset(version_data, 0, 18);\r
+       version_data[0]=240;    \r
+       ret=goodix_i2c_read_bytes(ts->client,version_data, 17);\r
+       if (ret < 0) \r
+               return ret;\r
+       version_data[17]='\0';\r
+       \r
+       if(*p == '\0')\r
+               return 0;       \r
+       do                                      \r
+       {\r
+               if((*p > 122) || (*p < 48 && *p != 32) || (*p >57 && *p  < 65) \r
+                       ||(*p > 90 && *p < 97 && *p  != '_'))           //check illeqal character\r
+                       count++;\r
+       }while(*++p != '\0' );\r
+       if(count > 2)\r
+               return 0;\r
+       else \r
+               return 1;       \r
+}\r
+\r
+static int last_touch_num = -1;\r
+static void goodix_get_touch_info(struct rk_ts_data *ts,char *point_num,struct rk_touch_info* info_buf)\r
+{\r
+       uint8_t  point_data[(1-READ_COOR_ADDR)+1+2+5*MAX_FINGER_NUM+1]={ 0 };  //read address(1byte)+key index(1byte)+point mask(2bytes)+5bytes*MAX_FINGER_NUM+coor checksum(1byte)\r
+       uint8_t  check_sum = 0;\r
+       int ret ;\r
+       uint16_t  finger_current = 0;\r
+       uint16_t  finger_bit = 0;\r
+       unsigned int  count = 0, point_count = 0;\r
+       unsigned char touch_num = 0;\r
+       uint8_t chksum_err = 0;\r
+       unsigned int position = 0;      \r
+       uint8_t track_id[MAX_FINGER_NUM] = {0};\r
+       u8 index;\r
+       u8 temp =0;\r
+       point_data[0] =  0;//READ_COOR_ADDR;//0x65;//READ_COOR_ADDR;            //read coor address\r
+       \r
+       if(!ts||!info_buf)\r
+       {\r
+               printk("goodix ts or info_buf is null\n");\r
+               return;\r
+       }\r
+\r
+       ret=goodix_i2c_read_bytes(ts->client, point_data, sizeof(point_data)/sizeof(point_data[0]));\r
+       if(ret != 2)    \r
+       {\r
+           printk("goodix read error\n");\r
+       }       \r
+       finger_current =  (point_data[2]<<8) + point_data[1];\r
+       \r
+       DBG("finger_current:%d ==== max_touch_num:%d\n", finger_current,ts->max_touch_num);//add by fjp 2010-9-28\r
+       \r
+       /*printk(" GT8110 read point data info\n");\r
+       for(index = 0 ; index < 20 ; index++)\r
+       {\r
+               printk("  %x ",point_data[index]);\r
+       }*/\r
+       \r
+       if(finger_current)\r
+       {       \r
+               point_count = 0;\r
+               finger_bit = finger_current;\r
+               for(count = 0; (finger_bit != 0) && (count < ts->max_touch_num); count++)//cal how many point touch currntly\r
+               {\r
+                       if(finger_bit & 0x01)\r
+                       {\r
+                               track_id[count] = PEN_DOWN;\r
+                               point_count++;\r
+                       }\r
+                       finger_bit >>= 1;\r
+               }\r
+               touch_num = point_count;\r
+\r
+               check_sum = point_data[2 - READ_COOR_ADDR] + point_data[3 - READ_COOR_ADDR];                    //cal coor checksum\r
+               count = 4 - READ_COOR_ADDR;\r
+               for(point_count *= 5; point_count > 0; point_count--)\r
+                       check_sum += point_data[count++];\r
+               check_sum += point_data[count];\r
+               //if(check_sum  != 0)                   //checksum verify error\r
+               if(0)\r
+               {\r
+                       printk("coor checksum error!\n");\r
+               }\r
+               else\r
+               {\r
+                       chksum_err = 0;\r
+               }\r
+       }\r
+\r
+       //printk("current point num:%d\n",touch_num);\r
+       *point_num = touch_num;\r
+       if(touch_num < last_touch_num)  //some flinger release\r
+       {\r
+               //printk("%d flinger release\n",last_touch_num-touch_num);\r
+               /*for(index = touch_num; index < last_touch_num; index++)\r
+                       info_buf[index].status = 0;*/\r
+               *point_num = last_touch_num;\r
+                touch_num = last_touch_num;\r
+       }\r
+       last_touch_num = touch_num;\r
+       //printk(" X and Y point value is\n");  \r
+       for(index = 0; index < touch_num; index++)\r
+       {\r
+            if(goodix_get_status(&track_id[index],&info_buf[index].status))\r
+               {\r
+               position = 3 + 4*(temp++);\r
+               info_buf[index].x = (unsigned int) (point_data[position+1]<<8) + (unsigned int)( point_data[position]);\r
+               info_buf[index].y  = (unsigned int)(point_data[position+3]<<8) + (unsigned int) (point_data[position+2]);\r
+               info_buf[index].press = (unsigned int) (point_data[position+4]);\r
+               //printk(" x = %d , y = %d , p =  %d ",         info_buf[index].x,info_buf[index].y, info_buf[index].press);\r
+               }\r
+       }\r
+       \r
+}\r
+\r
+\r
+/*******************************************************\r
+Description:\r
+       Goodix touchscreen work function.\r
+\r
+Parameter:\r
+       ts:     i2c client private struct.\r
+       \r
+return:\r
+       Executive outcomes.0---succeed.\r
+*******************************************************/\r
+static void  rk_ts_work_func(struct work_struct *pwork)\r
+{      \r
+       int i =0;\r
+       char point_num;\r
+       struct rk_ts_data *ts = container_of(to_delayed_work(pwork), struct rk_ts_data, ts_work);\r
+\r
+       if(!ts)\r
+       {\r
+               printk("container of rk_ts_data fail\n");\r
+               return;\r
+       }\r
+       if(!info_buf)\r
+       {\r
+               printk("info_buf fail\n");\r
+               return;\r
+       }\r
+\r
+       if(ts->get_touch_info)\r
+       {\r
+                ts->get_touch_info(ts,&point_num,info_buf);\r
+       }\r
+       for(i=0; i< point_num; i++)\r
+       {\r
+          DBG("info_buf[i].status =====%d\n",info_buf[i].status);\r
+             if(info_buf[i].status==PEN_DOWN_UP)\r
+               {\r
+                      info_buf[i].status=PEN_RELEASE;\r
+                          DBG("the key %d is up------\n",i);\r
+                       input_mt_slot(ts->input_dev, i);\r
+                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
+                       continue;\r
+               }\r
+               if(info_buf[i].status==PEN_DOWN)\r
+               {\r
+                       input_mt_slot(ts->input_dev, i);\r
+                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
+                       input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, info_buf[i].press);\r
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_X, info_buf[i].x);\r
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, info_buf[i].y);\r
+                        DBG("touch point %d %d >>x:%d>>y:%d\n",i,info_buf[i].status,info_buf[i].x,info_buf[i].y);//add by fjp 2010-9-28        \r
+               }\r
+               \r
+       \r
+          \r
+               \r
+               \r
+       }\r
+       input_sync(ts->input_dev);\r
+       \r
+    if(gpio_get_value(ts->irq_pin) == GPIO_LOW)\r
+    //if(point_num)\r
+    {\r
+       \r
+        DBG("touch down .............\n");//add by fjp 2010-9-28\r
+               queue_delayed_work(ts->ts_wq, &ts->ts_work,msecs_to_jiffies(20));\r
+       //      goto exit;\r
+               \r
+    }\r
+    else\r
+    {\r
+               \r
+        DBG("touch up>>x:%d>>y:%d\n",info_buf[0].x,info_buf[0].y);//add by fjp 2010-9-28\r
+               /*input_mt_slot(ts->input_dev, 0);\r
+               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
+               input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
+               \r
+               input_mt_slot(ts->input_dev, 0);\r
+               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);*/\r
+\r
+               DBG("point_num+++++++++++ = %d\n", point_num);//add by fjp 2010-9-28\r
+               for(i=0; i< point_num; i++)\r
+               {\r
+       //        printk("info_buf[i].status +++++++%d\n",info_buf[i].status);\r
+                        if(info_buf[i].status)\r
+                       {\r
+                     input_mt_slot(ts->input_dev, i);//°´ÐòºÅÉϱ¨\r
+                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);               \r
+                       //input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
+                       info_buf[i].status= PEN_RELEASE;\r
+                       \r
+\r
+                       DBG("release+++++++++++ = %d\n", i);//add by fjp 2010-9-28\r
+\r
+                       }\r
+               }\r
+               input_sync(ts->input_dev);\r
+               ts->pendown =PEN_RELEASE;\r
+               last_touch_num = 0;\r
+               \r
+       enable_irq(ts->irq);            \r
+      }\r
+         \r
+      \r
+//exit:\r
+         //kfree(info_buf);\r
+         \r
+  }\r
+       \r
+       \r
+/*******************************************************\r
+Description:\r
+       Timer interrupt service routine.\r
+\r
+Parameter:\r
+       timer:  timer struct pointer.\r
+       \r
+return:\r
+       Timer work mode. HRTIMER_NORESTART---not restart mode\r
+*******************************************************/\r
+static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)\r
+{\r
+       struct rk_ts_data *ts = container_of(timer, struct rk_ts_data, timer);\r
+       queue_delayed_work(goodix_wq,&ts->ts_work,0);\r
+       hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);\r
+       return HRTIMER_NORESTART;\r
+}\r
+/*******************************************************\r
+Description:\r
+       External interrupt service routine.\r
+\r
+Parameter:\r
+       irq:    interrupt number.\r
+       dev_id: private data pointer.\r
+       \r
+return:\r
+       irq execute status.\r
+*******************************************************/\r
+static irqreturn_t rk_ts_irq_handler(int irq, void *dev_id)\r
+{\r
+\r
+       struct rk_ts_data *ts = (struct rk_ts_data*)dev_id;\r
+       disable_irq_nosync(ts->irq);\r
+       queue_delayed_work(ts->ts_wq, &ts->ts_work,0);\r
+       \r
+       return IRQ_HANDLED;\r
+}\r
+\r
+static int rk_ts_suspend(struct i2c_client *client, pm_message_t mesg)\r
+{\r
+       int ret;\r
+       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
+\r
+       \r
+       \r
+       disable_irq(ts->irq);\r
+       \r
+#if 1\r
+       if (ts->power) {\r
+               ret = ts->power(ts, 0);\r
+               if (ret < 0)\r
+                       printk(KERN_ERR "goodix_ts_resume power off failed\n");\r
+       }\r
+#endif\r
+       return 0;\r
+}\r
+\r
+static int rk_ts_resume(struct i2c_client *client)\r
+{\r
+       int ret;\r
+       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
+       \r
+#if 1\r
+       if (ts->power) {\r
+               ret = ts->power(ts, 1);\r
+               if (ret < 0)\r
+                       printk(KERN_ERR "goodix_ts_resume power on failed\n");\r
+       }\r
+#endif\r
+       \r
+       enable_irq(client->irq);\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+static void rk_ts_early_suspend(struct early_suspend *h)\r
+{\r
+       struct rk_ts_data *ts;\r
+       ts = container_of(h, struct rk_ts_data, early_suspend);\r
+       rk_ts_suspend(ts->client, PMSG_SUSPEND);\r
+}\r
+\r
+static void rk_ts_late_resume(struct early_suspend *h)\r
+{\r
+       struct rk_ts_data *ts;\r
+       ts = container_of(h, struct rk_ts_data, early_suspend);\r
+       rk_ts_resume(ts->client);\r
+}\r
+#endif\r
+\r
+/*******************************************************\r
+Description:\r
+       Goodix touchscreen power manage function.\r
+\r
+Parameter:\r
+       on:     power status.0---suspend;1---resume.\r
+       \r
+return:\r
+       Executive outcomes.-1---i2c transfer error;0---succeed.\r
+*******************************************************/\r
+static int goodix_ts_power(struct rk_ts_data * ts, int on)\r
+{\r
+       int ret = -1;\r
+       unsigned char i2c_control_buf[2] = {0x38,  0x56};               //suspend cmd\r
+       int retry = 0;\r
+       if(on != 0 && on !=1)\r
+       {\r
+               printk(KERN_DEBUG "%s: Cant't support this command.", rk_ts_name);\r
+               return -EINVAL;\r
+       }\r
+       \r
+       \r
+       if(on == 0)             //suspend\r
+       { 
+               gpio_set_value(ts->rst_pin,GPIO_LOW);\r
+               msleep(20);\r
+               gpio_set_value(ts->rst_pin,GPIO_HIGH);
+               msleep(200);\r
+        while(retry<5)\r
+               {\r
+                       ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
+                       if(ret == 1)\r
+                       {\r
+                               printk(KERN_DEBUG "touch goodix Send suspend cmd successed \n");\r
+                               break;\r
+                       }\r
+                      retry++;\r
+                       msleep(10);\r
+               }\r
+               if(ret > 0)\r
+                 ret = 0;\r
+       }\r
+       else if(on == 1)                //resume\r
+       {\r
+               printk(KERN_DEBUG "touch goodix int resume\n");\r
+               gpio_set_value(ts->rst_pin,GPIO_LOW);   \r
+               msleep(20);\r
+           gpio_set_value(ts->rst_pin,GPIO_HIGH);\r
+               ret = 0;\r
+       }        \r
+       return ret;\r
+}\r
+\r
+\r
+static int goodix_input_params_init(struct rk_ts_data *ts)\r
+{\r
+       int ret ;\r
+       ts->input_dev = input_allocate_device();\r
+       if (ts->input_dev == NULL) {\r
+               ret = -ENOMEM;\r
+               printk(KERN_ALERT "Failed to allocate input device\n");\r
+               return ret;\r
+       }\r
+\r
+\r
+       __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);\r
+       __set_bit(EV_ABS, ts->input_dev->evbit);\r
+\r
+       input_mt_init_slots(ts->input_dev, ts->max_touch_num);\r
+       input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);\r
+       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, /*ts->abs_x_max*/4096, 0, 0);\r
+       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, /*ts->abs_y_max*/4096, 0, 0);\r
+       sprintf(ts->phys, "input/rkts");\r
+       ts->input_dev->name = rk_ts_name;\r
+       ts->input_dev->phys = ts->phys;\r
+       ts->input_dev->id.bustype = BUS_I2C;\r
+       ts->input_dev->id.vendor = 0xDEAD;\r
+       ts->input_dev->id.product = 0xBEEF;\r
+       ts->input_dev->id.version = 10427;      //screen firmware version\r
+       \r
+       ret = input_register_device(ts->input_dev);\r
+       if (ret) {\r
+               printk(KERN_ALERT "Probe: Unable to register %s input device\n", ts->input_dev->name);\r
+               return -1;\r
+       }\r
+\r
+       return 0 ;\r
+       \r
+}\r
+       \r
+static int goodix_ts_init(struct rk_ts_data *ts)\r
+{\r
+       int ret ;\r
+       char *version_info = NULL;\r
+#if 1\r
+       char test_data = 1;\r
+       char retry;\r
+       for(retry=0;retry < 30; retry++)    //test goodix\r
+       {\r
+               ret =goodix_i2c_write_bytes(ts->client, &test_data, 1);\r
+               if (ret > 0)\r
+                       break;\r
+       }\r
+       if(ret <= 0)\r
+       {\r
+               printk(KERN_INFO "I2C communication ERROR!Goodix touchscreen driver become invalid\n");\r
+               return -1;\r
+       }       \r
+#endif \r
+       \r
+       ret = goodix_read_version(ts, &version_info);\r
+       if(ret <= 0)\r
+       {\r
+               printk(KERN_INFO"Read version data failed!\n");\r
+       }\r
+       else\r
+       {\r
+               printk("goodix_ts_init: version %s\n", (version_info+1));\r
+       }\r
+       \r
+       ret=goodix_init_panel(ts);\r
+       if(ret != 0) {\r
+               printk("goodix panel init fail\n");\r
+               return -1;\r
+       }\r
+\r
+       vfree(version_info);\r
+       #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
+       goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL);\r
+       if(goodix_proc_entry == NULL)\r
+       {\r
+               printk("Couldn't create proc entry!\n");\r
+               ret = -ENOMEM;\r
+               return ret ;\r
+       }\r
+       else\r
+       {\r
+               printk("goodix_ts_init: create proc entry success!\n");\r
+               goodix_proc_entry->write_proc = goodix_update_write;\r
+               goodix_proc_entry->read_proc = goodix_update_read;\r
+\r
+       }\r
+#endif\r
+\r
+       return 0;\r
+}\r
+/*******************************************************\r
+Description:\r
+       Goodix touchscreen probe function.\r
+\r
+Parameter:\r
+       client: i2c device struct.\r
+       id:device id.\r
+       \r
+return:\r
+       Executive outcomes. 0---succeed.\r
+*******************************************************/\r
+static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
+{\r
+       int ret = 0;\r
+       struct rk_ts_data *ts;\r
+       struct goodix_8110_platform_data *pdata ;\r
+       \r
+       printk(KERN_INFO "Install touch driver.\n");\r
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) \r
+       {\r
+               dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");\r
+               ret = -ENODEV;\r
+               goto exit;\r
+       }\r
+\r
+       ts = kzalloc(sizeof(struct rk_ts_data), GFP_KERNEL);\r
+       if (ts == NULL) {\r
+               printk(KERN_ALERT "alloc for struct rk_ts_data fail\n");\r
+               ret = -ENOMEM;\r
+               goto exit;\r
+       }
+\r
+\r
+       pdata = client->dev.platform_data;\r
+       ts->irq_pin = pdata->irq_pin;\r
+       ts->rst_pin = pdata->reset;\r
+       ts->pendown =PEN_RELEASE;\r
+       ts->client = client;\r
+       ts->ts_init = goodix_ts_init;   \r
+       ts->power = goodix_ts_power;\r
+       ts->get_touch_info = goodix_get_touch_info;\r
+       ts->input_parms_init = goodix_input_params_init;\r
+       i2c_set_clientdata(client, ts);
+
+   if(pdata->hw_init)
+       pdata->hw_init();
+\r
+\r
+       gpio_set_value(pdata->reset, 1);\r
+       msleep(200);\r
+       \r
+       if(ts->ts_init)\r
+       {\r
+               ret = ts->ts_init(ts);\r
+               if(ret < 0)\r
+               {\r
+                       printk(KERN_ALERT "rk ts init fail\n");\r
+                       goto exit;\r
+               }\r
+       }\r
+\r
+       if(ts->input_parms_init)\r
+       {\r
+               ts->input_parms_init(ts);\r
+       }\r
+\r
+       i2c_connect_client = client;\r
+       #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)\r
+               ts->ts_wq= create_rt_workqueue("rk_ts_wq");             //create a work queue and worker thread\r
+       #else\r
+               ts->ts_wq= create_workqueue("rk_ts_wq"); \r
+       #endif\r
+       if (!ts->ts_wq){\r
+               printk(KERN_ALERT "creat touch screen workqueue failed\n");\r
+           return -ENOMEM;\r
+       }\r
+       \r
+       INIT_DELAYED_WORK(&ts->ts_work, rk_ts_work_func);\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+       ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;\r
+       ts->early_suspend.suspend = rk_ts_early_suspend;\r
+       ts->early_suspend.resume = rk_ts_late_resume;\r
+       register_early_suspend(&ts->early_suspend);\r
+#endif\r
+\r
+       info_buf= kzalloc(ts->max_touch_num*sizeof(struct rk_touch_info), GFP_KERNEL);\r
+       if(!info_buf)\r
+       {\r
+               printk(KERN_ALERT "alloc for rk_touch_info fail\n");\r
+               goto err_input_register_device_failed;\r
+       }\r
+\r
+       ts->irq=gpio_to_irq(ts->irq_pin)        ;               //If not defined in client\r
+       if (ts->irq)\r
+       {\r
+               ret = gpio_request(pdata->irq_pin, "TS_IRQ_PIN");       //Request IO\r
+               if (ret < 0) \r
+               {\r
+                       printk(KERN_ALERT "Failed to request for touch irq\n");\r
+                       goto err_input_register_device_failed;\r
+               }\r
+               else\r
+               {\r
+                       gpio_direction_input(pdata->irq_pin);\r
+               }\r
+\r
+               ret  = request_irq(ts->irq, rk_ts_irq_handler ,IRQ_TYPE_LEVEL_LOW/*IRQF_TRIGGER_FALLING*/,client->name, ts);\r
+               if (ret != 0) {\r
+                       printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", ret);\r
+                       gpio_free(ts->irq_pin);\r
+                       goto err_input_register_device_failed;\r
+               }\r
+       }\r
+       printk("goodix_ts_init: probe successfully!\n");\r
+       return 0;\r
+\r
+       \r
+err_input_register_device_failed:\r
+       input_free_device(ts->input_dev);\r
+       i2c_set_clientdata(client, NULL);       \r
+       kfree(ts);\r
+exit:\r
+       return ret;\r
+}\r
+\r
+\r
+/*******************************************************\r
+Description:\r
+       Goodix touchscreen driver release function.\r
+\r
+Parameter:\r
+       client: i2c device struct.\r
+       \r
+return:\r
+       Executive outcomes. 0---succeed.\r
+*******************************************************/\r
+static int rk_ts_remove(struct i2c_client *client)\r
+{\r
+       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+       unregister_early_suspend(&ts->early_suspend);\r
+#endif\r
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
+       remove_proc_entry("goodix-update", NULL);\r
+#endif\r
+       \r
+       gpio_free(ts->irq_pin);\r
+       free_irq(ts->irq, ts);\r
+       dev_notice(&client->dev,"The driver is removing...\n");\r
+       i2c_set_clientdata(client, NULL);\r
+       input_unregister_device(ts->input_dev);\r
+       if(info_buf)\r
+               kfree(info_buf);\r
+       kfree(ts);\r
+       return 0;\r
+}\r
+\r
+static void rk_ts_shutdown(struct i2c_client *client)\r
+{\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
+       unregister_early_suspend(&ts->early_suspend);\r
+#endif\r
+}\r
+\r
+//******************************Begin of firmware update surpport*******************************\r
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
+/**\r
+@brief CRC cal proc,include : Reflect,init_crc32_table,GenerateCRC32\r
+@param global var oldcrc32\r
+@return states\r
+*/\r
+static unsigned int Reflect(unsigned long int ref, char ch)\r
+{\r
+       unsigned int value=0;\r
+       int i;\r
+       for(i = 1; i < (ch + 1); i++)\r
+       {\r
+               if(ref & 1)\r
+                       value |= 1 << (ch - i);\r
+               ref >>= 1;\r
+       }\r
+       return value;\r
+}\r
+/*---------------------------------------------------------------------------------------------------------*/\r
+/*  CRC Check Program INIT                                                                                                                        */\r
+/*---------------------------------------------------------------------------------------------------------*/\r
+static void init_crc32_table(void)\r
+{\r
+       unsigned int temp;\r
+       unsigned int t1,t2;\r
+       unsigned int flag;\r
+       int i,j;\r
+       for(i = 0; i <= 0xFF; i++)\r
+       {\r
+               temp=Reflect(i, 8);\r
+               crc32_table[i]= temp<< 24;\r
+               for (j = 0; j < 8; j++)\r
+               {\r
+\r
+                       flag=crc32_table[i]&0x80000000;\r
+                       t1=(crc32_table[i] << 1);\r
+                       if(flag==0)\r
+                               t2=0;\r
+                       else\r
+                               t2=ulPolynomial;\r
+                       crc32_table[i] =t1^t2 ;\r
+\r
+               }\r
+               crc32_table[i] = Reflect(crc32_table[i], 32);\r
+       }\r
+}\r
+/*---------------------------------------------------------------------------------------------------------*/\r
+/*  CRC main Program                                                                                                                              */\r
+/*---------------------------------------------------------------------------------------------------------*/\r
+static void GenerateCRC32(unsigned char * buf, unsigned int len)\r
+{\r
+       unsigned int i;\r
+       unsigned int t;\r
+\r
+       for (i = 0; i != len; ++i)\r
+       {\r
+               t = (oldcrc32 ^ buf[i]) & 0xFF;\r
+               oldcrc32 = ((oldcrc32 >> 8) & 0xFFFFFF) ^ crc32_table[t];\r
+       }\r
+}\r
+\r
+static struct file * update_file_open(char * path, mm_segment_t * old_fs_p)\r
+{\r
+       struct file * filp = NULL;\r
+       int errno = -1;\r
+               \r
+       filp = filp_open(path, O_RDONLY, 0644);\r
+       \r
+       if(!filp || IS_ERR(filp))\r
+       {\r
+               if(!filp)\r
+                       errno = -ENOENT;\r
+               else \r
+                       errno = PTR_ERR(filp);                                  \r
+               printk(KERN_ERR "The update file for Guitar open error.\n");\r
+               return NULL;\r
+       }\r
+       *old_fs_p = get_fs();\r
+       set_fs(get_ds());\r
+\r
+       filp->f_op->llseek(filp,0,0);\r
+       return filp ;\r
+}\r
+\r
+static void update_file_close(struct file * filp, mm_segment_t old_fs)\r
+{\r
+       set_fs(old_fs);\r
+       if(filp)\r
+               filp_close(filp, NULL);\r
+}\r
+static int update_get_flen(char * path)\r
+{\r
+       struct file * file_ck = NULL;\r
+       mm_segment_t old_fs;\r
+       int length ;\r
+       \r
+       file_ck = update_file_open(path, &old_fs);\r
+       if(file_ck == NULL)\r
+               return 0;\r
+\r
+       length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);\r
+       //printk("File length: %d\n", length);\r
+       if(length < 0)\r
+               length = 0;\r
+       update_file_close(file_ck, old_fs);\r
+       return length;  \r
+}\r
+static int update_file_check(char * path)\r
+{\r
+       unsigned char buffer[64] = { 0 } ;\r
+       struct file * file_ck = NULL;\r
+       mm_segment_t old_fs;\r
+       int count, ret, length ;\r
+       \r
+       file_ck = update_file_open(path, &old_fs);\r
+       \r
+       if(path != NULL)\r
+               printk("File Path:%s\n", path);\r
+       \r
+       if(file_ck == NULL)\r
+               return -ERROR_NO_FILE;\r
+\r
+       length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);\r
+#ifdef GUITAR_MESSAGE\r
+       printk(KERN_INFO "gt801 update: File length: %d\n",length);\r
+#endif \r
+       if(length <= 0 || (length%4) != 0)\r
+       {\r
+               update_file_close(file_ck, old_fs);\r
+               return -ERROR_FILE_TYPE;\r
+       }\r
+       \r
+       //set file point to the begining of the file\r
+       file_ck->f_op->llseek(file_ck, 0, SEEK_SET);    \r
+       oldcrc32 = 0xFFFFFFFF;\r
+       init_crc32_table();\r
+       while(length > 0)\r
+       {\r
+               ret = file_ck->f_op->read(file_ck, buffer, sizeof(buffer), &file_ck->f_pos);\r
+               if(ret > 0)\r
+               {\r
+                       for(count = 0; count < ret;  count++)   \r
+                               GenerateCRC32(&buffer[count],1);                        \r
+               }\r
+               else \r
+               {\r
+                       update_file_close(file_ck, old_fs);\r
+                       return -ERROR_FILE_READ;\r
+               }\r
+               length -= ret;\r
+       }\r
+       oldcrc32 = ~oldcrc32;\r
+#ifdef GUITAR_MESSAGE  \r
+       printk("CRC_Check: %u\n", oldcrc32);\r
+#endif \r
+       update_file_close(file_ck, old_fs);\r
+       return 1;       \r
+}\r
+\r
+unsigned char wait_slave_ready(struct rk_ts_data *ts, unsigned short *timeout)\r
+{\r
+       unsigned char i2c_state_buf[2] = {ADDR_STA, UNKNOWN_ERROR};\r
+       int ret;\r
+       while(*timeout < MAX_TIMEOUT)\r
+       {\r
+               ret = goodix_i2c_read_bytes(ts->client, i2c_state_buf, 2);\r
+               if(ret <= 0)\r
+                       return ERROR_I2C_TRANSFER;\r
+               if(i2c_state_buf[1] & SLAVE_READY)\r
+               {\r
+                       return i2c_state_buf[1];\r
+                       //return 1;\r
+               }\r
+               msleep(10);\r
+               *timeout += 5;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data)\r
+{\r
+       unsigned char cmd[220];\r
+       int ret = -1;\r
+\r
+       static unsigned char update_path[100];\r
+       static unsigned short time_count = 0;\r
+       static unsigned int file_len = 0;\r
+       \r
+       unsigned char i2c_control_buf[2] = {ADDR_CMD, 0};\r
+       unsigned char i2c_states_buf[2] = {ADDR_STA, 0};\r
+       unsigned char i2c_data_buf[PACK_SIZE+1+8] = {ADDR_DAT,};\r
+       //unsigned char i2c_rd_buf[1+4+PACK_SIZE+4];\r
+       unsigned char i2c_rd_buf[160];\r
+       unsigned char retries = 0;\r
+       unsigned int rd_len;\r
+       unsigned char i = 0;\r
+       static unsigned char update_need_config = 0;\r
+\r
+       unsigned char checksum_error_times = 0;\r
+#ifdef UPDATE_NEW_PROTOCOL\r
+       unsigned int frame_checksum = 0;\r
+       unsigned int frame_number = 0;\r
+#else\r
+       unsigned char send_crc = 0;\r
+#endif\r
+\r
+       struct file * file_data = NULL;\r
+       mm_segment_t old_fs;\r
+       struct rk_ts_data *ts;\r
+       \r
+       ts = i2c_get_clientdata(i2c_connect_client);\r
+       if(ts==NULL)\r
+               return 0;\r
+       \r
+       if(copy_from_user(&cmd, buff, len))\r
+       {\r
+               return -EFAULT;\r
+       }\r
+       switch(cmd[0])\r
+       {\r
+               case STEP_SET_PATH:\r
+                       printk(KERN_INFO"Write cmd is:%d,cmd arg is:%s,write len is:%ld\n",cmd[0], &cmd[1], len);\r
+                       memset(update_path, 0, 100);\r
+                       strncpy(update_path, cmd+1, 100);\r
+                       if(update_path[0] == 0)\r
+                               return 0;\r
+                       else\r
+                               return 1;\r
+               case STEP_CHECK_FILE:\r
+                       printk(KERN_INFO"Begin to firmware update ......\n");\r
+                       ret = update_file_check(update_path);\r
+                       if(ret <= 0)\r
+                       {\r
+                               printk(KERN_INFO"fialed to check update file!\n");\r
+                               return ret;\r
+                       }\r
+                       msleep(500);\r
+                       printk(KERN_INFO"Update check file success!\n");\r
+                       return 1;\r
+               case STEP_WRITE_SYN:\r
+                       printk(KERN_INFO"STEP1:Write synchronization signal!\n");\r
+                       i2c_control_buf[1] = UPDATE_START;\r
+                       ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
+                       if(ret <= 0)\r
+                       {\r
+                               ret = ERROR_I2C_TRANSFER;\r
+                               return ret;\r
+                       }\r
+                       //the time include time(APROM -> LDROM) and time(LDROM init)\r
+                       msleep(1000);\r
+                       return 1;\r
+               case STEP_WAIT_SYN:\r
+                       printk(KERN_INFO"STEP2:Wait synchronization signal!\n");\r
+                       while(retries < MAX_I2C_RETRIES)\r
+                       {\r
+                               i2c_states_buf[1] = UNKNOWN_ERROR;\r
+                               ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2);\r
+                               printk(KERN_INFO"The read byte is:%d\n", i2c_states_buf[1]);\r
+                               if(i2c_states_buf[1] & UPDATE_START)\r
+                               {\r
+                                       if(i2c_states_buf[1] & NEW_UPDATE_START)\r
+                                       {\r
+                                       #ifdef UPDATE_NEW_PROTOCOL\r
+                                               update_need_config = 1;\r
+                                               return 2;\r
+                                       #else\r
+                                               return 1;\r
+                                       #endif\r
+                                       }\r
+                                       break;\r
+                               }\r
+                               msleep(5);\r
+                               retries++;\r
+                               time_count += 10;\r
+                       }\r
+                       if((retries >= MAX_I2C_RETRIES) && (!(i2c_states_buf[1] & UPDATE_START)))\r
+                       {\r
+                               if(ret <= 0)\r
+                                       return 0;\r
+                               else\r
+                                       return -1;\r
+                       }\r
+                       return 1;\r
+               case STEP_WRITE_LENGTH:\r
+                       printk(KERN_INFO"STEP3:Write total update file length!\n");\r
+                       file_len = update_get_flen(update_path);\r
+                       if(file_len <= 0)\r
+                       {\r
+                               printk(KERN_INFO"get update file length failed!\n");\r
+                               return -1;\r
+                       }\r
+                       file_len += 4;\r
+                       i2c_data_buf[1] = (file_len>>24) & 0xff;\r
+                       i2c_data_buf[2] = (file_len>>16) & 0xff;\r
+                       i2c_data_buf[3] = (file_len>>8) & 0xff;\r
+                       i2c_data_buf[4] = file_len & 0xff;\r
+                       file_len -= 4;\r
+                       ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 5);\r
+                       if(ret <= 0)\r
+                       {\r
+                               ret = ERROR_I2C_TRANSFER;\r
+                               return 0;\r
+                       }\r
+                       return 1;\r
+               case STEP_WAIT_READY:\r
+                       printk(KERN_INFO"STEP4:Wait slave ready!\n");\r
+                       ret = wait_slave_ready(ts, &time_count);\r
+                       if(ret == ERROR_I2C_TRANSFER)\r
+                               return 0;\r
+                       if(!ret)\r
+                       {\r
+                               return -1;\r
+                       }\r
+                       printk(KERN_INFO"Slave ready!\n");\r
+                       return 1;\r
+               case STEP_WRITE_DATA:\r
+#ifdef UPDATE_NEW_PROTOCOL\r
+                       printk(KERN_INFO"STEP5:Begin to send file data use NEW protocol!\n");\r
+                       file_data = update_file_open(update_path, &old_fs);\r
+                       if(file_data == NULL)\r
+                       {\r
+                               return -1;\r
+                       }\r
+                       frame_number = 0;\r
+                       while(file_len >= 0)\r
+                       {\r
+                               i2c_data_buf[0] = ADDR_DAT;\r
+                               rd_len = (file_len >= PACK_SIZE) ? PACK_SIZE : file_len;\r
+                               frame_checksum = 0;\r
+                               if(file_len)\r
+                               {\r
+                                       ret = file_data->f_op->read(file_data, i2c_data_buf+1+4, rd_len, &file_data->f_pos);\r
+                                       if(ret <= 0)\r
+                                       {\r
+                                               printk("[GOODiX_ISP_NEW]:Read File Data Failed!\n");\r
+                                               return -1;\r
+                                       }\r
+                                       i2c_data_buf[1] = (frame_number>>24)&0xff;\r
+                                       i2c_data_buf[2] = (frame_number>>16)&0xff;\r
+                                       i2c_data_buf[3] = (frame_number>>8)&0xff;\r
+                                       i2c_data_buf[4] = frame_number&0xff;\r
+                                       frame_number++;\r
+                                       frame_checksum = 0;\r
+                                       for(i=0; i<rd_len; i++)\r
+                                       {\r
+                                               frame_checksum += i2c_data_buf[5+i];\r
+                                       }\r
+                                       frame_checksum = 0 - frame_checksum;\r
+                                       i2c_data_buf[5+rd_len+0] = frame_checksum&0xff;\r
+                                       i2c_data_buf[5+rd_len+1] = (frame_checksum>>8)&0xff;\r
+                                       i2c_data_buf[5+rd_len+2] = (frame_checksum>>16)&0xff;\r
+                                       i2c_data_buf[5+rd_len+3] = (frame_checksum>>24)&0xff;\r
+                               }\r
+rewrite:\r
+                               printk(KERN_INFO"[GOODiX_ISP_NEW]:%d\n", file_len);                             \r
+                               ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 1+4+rd_len+4);\r
+                                       //if(ret <= 0)\r
+                               if(ret != 1)\r
+                               {\r
+                                       printk("[GOODiX_ISP_NEW]:Write File Data Failed!Return:%d\n", ret);\r
+                                       return 0;\r
+                               }\r
+\r
+                               memset(i2c_rd_buf, 0x00, 1+4+rd_len+4);\r
+                               ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, 1+4+rd_len+4);\r
+                               if(ret != 2)\r
+                               {\r
+                                       printk("[GOODiX_ISP_NEW]:Read File Data Failed!Return:%d\n", ret);\r
+                                       return 0;\r
+                               }\r
+                               for(i=1; i<(1+4+rd_len+4); i++)                                         //check communication\r
+                               {\r
+                                       if(i2c_rd_buf[i] != i2c_data_buf[i])\r
+                                       {\r
+                                               i = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if(!i)\r
+                               {\r
+                                       i2c_control_buf[0] = ADDR_CMD;\r
+                                       i2c_control_buf[1] = 0x03;\r
+                                       goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);         //communication error\r
+                                       printk("[GOODiX_ISP_NEW]:File Data Frame readback check Error!\n");\r
+                               }\r
+                               else\r
+                               {\r
+                                       i2c_control_buf[1] = 0x04;                                                                                                      //let LDROM write flash\r
+                                       goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
+                               }\r
+                               \r
+                               //Wait for slave ready signal.and read the checksum\r
+                               ret = wait_slave_ready(ts, &time_count);\r
+                               if((ret & CHECKSUM_ERROR)||(!i))\r
+                               {\r
+                                       if(i)\r
+                                       {\r
+                                               printk("[GOODiX_ISP_NEW]:File Data Frame checksum Error!\n");\r
+                                       }\r
+                                       checksum_error_times++;\r
+                                       msleep(20);\r
+                                       if(checksum_error_times > 20)                           //max retry times.\r
+                                               return 0;\r
+                                       goto rewrite;\r
+                               }\r
+                               checksum_error_times = 0;\r
+                               if(ret & (FRAME_ERROR))\r
+                               {\r
+                                       printk("[GOODiX_ISP_NEW]:File Data Frame Miss!\n");\r
+                                       return 0;\r
+                               }\r
+                               if(ret == ERROR_I2C_TRANSFER)\r
+                                       return 0;\r
+                               if(!ret)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               if(file_len < PACK_SIZE)\r
+                               {\r
+                                       update_file_close(file_data, old_fs);\r
+                                       break;\r
+                               }\r
+                               file_len -= rd_len;\r
+                       }//end of while((file_len >= 0))\r
+                       return 1;\r
+#else\r
+                       printk(KERN_INFO"STEP5:Begin to send file data use OLD protocol!\n");\r
+                       file_data = update_file_open(update_path, &old_fs);\r
+                       if(file_data == NULL)   //file_data has been opened at the last time\r
+                       {\r
+                               return -1;\r
+                       }\r
+                       while((file_len >= 0) && (!send_crc))\r
+                       {\r
+                               printk(KERN_INFO"[GOODiX_ISP_OLD]:%d\n", file_len);\r
+                               i2c_data_buf[0] = ADDR_DAT;\r
+                               rd_len = (file_len >= PACK_SIZE) ? PACK_SIZE : file_len;\r
+                               if(file_len)\r
+                               {\r
+                                       ret = file_data->f_op->read(file_data, i2c_data_buf+1, rd_len, &file_data->f_pos);\r
+                                       if(ret <= 0)\r
+                                       {\r
+                                               return -1;\r
+                                       }\r
+                               }\r
+                               if(file_len < PACK_SIZE)\r
+                               {\r
+                                       send_crc = 1;\r
+                                       update_file_close(file_data, old_fs);\r
+                                       i2c_data_buf[file_len+1] = oldcrc32&0xff;\r
+                                       i2c_data_buf[file_len+2] = (oldcrc32>>8)&0xff;\r
+                                       i2c_data_buf[file_len+3] = (oldcrc32>>16)&0xff;\r
+                                       i2c_data_buf[file_len+4] = (oldcrc32>>24)&0xff;\r
+                                       ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, (file_len+1+4));\r
+                                       //if(ret <= 0)\r
+                                       if(ret != 1)\r
+                                       {\r
+                                               printk("[GOODiX_ISP_OLD]:Write File Data Failed!Return:%d\n", ret);\r
+                                               return 0;\r
+                                       }\r
+                                       break;\r
+                               }\r
+                               else\r
+                               {\r
+                                       ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, PACK_SIZE+1);\r
+                                       //if(ret <= 0)\r
+                                       if(ret != 1)\r
+                                       {\r
+                                               printk("[GOODiX_ISP_OLD]:Write File Data Failed!Return:%d\n", ret);\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                               file_len -= rd_len;\r
+                       \r
+                               //Wait for slave ready signal.\r
+                               ret = wait_slave_ready(ts, &time_count);\r
+                               if(ret == ERROR_I2C_TRANSFER)\r
+                                       return 0;\r
+                               if(!ret)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               //Slave is ready.\r
+                       }//end of while((file_len >= 0) && (!send_crc))\r
+                       return 1;\r
+#endif\r
+               case STEP_READ_STATUS:\r
+                       printk(KERN_INFO"STEP6:Read update status!\n");\r
+                       while(time_count < MAX_TIMEOUT)\r
+                       {\r
+                               ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2);\r
+                               if(ret <= 0)\r
+                               {\r
+                                       return 0;\r
+                               }\r
+                               if(i2c_states_buf[1] & SLAVE_READY)\r
+                               {\r
+                                       if(!(i2c_states_buf[1] &0xf0))\r
+                                       {\r
+                                               printk(KERN_INFO"The firmware updating succeed!update state:0x%x\n",i2c_states_buf[1]);\r
+                                               return 1;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               printk(KERN_INFO"The firmware updating failed!update state:0x%x\n",i2c_states_buf[1]);\r
+                                               return 0;\r
+\r
+                                       }\r
+                               }\r
+                               msleep(1);\r
+                               time_count += 5;\r
+                       }\r
+                       return -1;\r
+               case FUN_CLR_VAL:                                                               //clear the static val\r
+                       time_count = 0;\r
+                       file_len = 0;\r
+                       update_need_config = 0;\r
+                       return 1;\r
+               case FUN_CMD:                                                   //functional command\r
+                       if(cmd[1] == CMD_DISABLE_TP)\r
+                       {\r
+                               printk(KERN_INFO"Disable TS int!\n");\r
+                               g_enter_isp = 1;\r
+                               disable_irq(ts->irq);\r
+                       }\r
+                       else if(cmd[1] == CMD_ENABLE_TP)\r
+                       {\r
+                               printk(KERN_INFO"Enable TS int!\n");\r
+                               g_enter_isp = 0;\r
+                               enable_irq(ts->irq);\r
+                       }\r
+                       else if(cmd[1] == CMD_READ_VER)\r
+                       {\r
+                               printk(KERN_INFO"Read version!\n");\r
+                               ts->read_mode = MODE_RD_VER;\r
+                       }\r
+                       else if(cmd[1] == CMD_READ_RAW)\r
+                       {\r
+                               printk(KERN_INFO"Read raw data!\n");\r
+                               ts->read_mode = MODE_RD_RAW;\r
+                               i2c_control_buf[1] = 201;\r
+                               ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);                   //read raw data cmd\r
+                               if(ret <= 0)\r
+                               {\r
+                                       printk(KERN_INFO"Write read raw data cmd failed!\n");\r
+                                       return 0;\r
+                               }\r
+                               msleep(200);\r
+                       }\r
+                       else if(cmd[1] == CMD_READ_DIF)\r
+                       {\r
+                               printk(KERN_INFO"Read diff data!\n");\r
+                               ts->read_mode = MODE_RD_DIF;\r
+                               i2c_control_buf[1] = 202;\r
+                               ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);                   //read diff data cmd\r
+                               if(ret <= 0)\r
+                               {\r
+                                       printk(KERN_INFO"Write read raw data cmd failed!\n");\r
+                                       return 0;\r
+                               }\r
+                               msleep(200);\r
+                       }\r
+                       else if(cmd[1] == CMD_READ_CFG)\r
+                       {\r
+                               printk(KERN_INFO"Read config info!\n");\r
+                               ts->read_mode = MODE_RD_CFG;\r
+                               rd_cfg_addr = cmd[2];\r
+                               rd_cfg_len = cmd[3];\r
+                       }\r
+                       else if(cmd[1] == CMD_SYS_REBOOT)\r
+                       {\r
+                               printk(KERN_INFO"System reboot!\n");\r
+                               sys_sync();\r
+                               msleep(200);\r
+                               kernel_restart(NULL);\r
+                       }\r
+                       return 1;\r
+               case FUN_WRITE_CONFIG:\r
+                       \r
+                       printk(KERN_INFO"Begin write config info!Config length:%d\n",cmd[1]);\r
+                       for(i=3; i<cmd[1];i++)\r
+                       {\r
+                               //if((i-3)%5 == 0)printk("\n");\r
+                               printk("(%d):0x%x ", i-3, cmd[i]);\r
+                       }\r
+                       printk("\n");\r
+\r
+                       if((cmd[2]>83)&&(cmd[2]<240)&&cmd[1])\r
+                       {\r
+                               checksum_error_times = 0;\r
+reconfig:\r
+                               ret = goodix_i2c_write_bytes(ts->client, cmd+2, cmd[1]); \r
+                               if(ret != 1)\r
+                               {\r
+                                       printk("Write Config failed!return:%d\n",ret);\r
+                                       return -1;\r
+                               }\r
+                               if(!update_need_config)return 1;\r
+                               \r
+                               i2c_rd_buf[0] = cmd[2];\r
+                               ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, cmd[1]);\r
+                               if(ret != 2)\r
+                               {\r
+                                       printk("Read Config failed!return:%d\n",ret);\r
+                                       return -1;\r
+                               }\r
+                               for(i=0; i<cmd[1]; i++)\r
+                               {\r
+                                       if(i2c_rd_buf[i] != cmd[i+2])\r
+                                       {\r
+                                               printk("Config readback check failed!\n");\r
+                                               i = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if(!i)\r
+                               {\r
+                                       i2c_control_buf[0] = ADDR_CMD;\r
+                                       i2c_control_buf[1] = 0x03;\r
+                                       goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);         //communication error\r
+                                       checksum_error_times++;\r
+                                       msleep(20);\r
+                                       if(checksum_error_times > 20)                           //max retry times.\r
+                                               return 0;\r
+                                       goto reconfig;\r
+                               }\r
+                               else\r
+                               {\r
+                                       i2c_control_buf[0] = ADDR_CMD;\r
+                                       i2c_control_buf[1] = 0x04;                                      //let LDROM write flash\r
+                                       goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
+                                       return 1;\r
+                               }\r
+                               \r
+                       }\r
+                       else\r
+                       {\r
+                               printk(KERN_INFO"Invalid config addr!\n");\r
+                               return -1;\r
+                       }\r
+               default:\r
+                       return -ENOSYS;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data )\r
+{\r
+       int ret = -1;\r
+       struct rk_ts_data *ts;\r
+       int len = 0;\r
+       char *version_info = NULL;\r
+       static unsigned char read_data[1201] = {80, };\r
+\r
+       ts = i2c_get_clientdata(i2c_connect_client);\r
+       if(ts==NULL)\r
+               return 0;\r
+\r
+       if(ts->read_mode == MODE_RD_VER)                //read version data\r
+       {\r
+               ret = goodix_read_version(ts, &version_info);\r
+               if(ret <= 0)\r
+               {\r
+                       printk(KERN_INFO"Read version data failed!\n");\r
+                       vfree(version_info);\r
+                       return 0;\r
+               }\r
+\r
+               for(len=0;len<100;len++)\r
+               {\r
+                       if(*(version_info + len) == '\0')\r
+                               break;\r
+               }\r
+               printk(KERN_INFO"GOODiX Touchscreen Version is:%s\n", (version_info+1));\r
+               strncpy(page, version_info+1, len + 1);\r
+               vfree(version_info);\r
+               *eof = 1;\r
+               return len+1;\r
+       }\r
+       else if((ts->read_mode == MODE_RD_RAW)||(ts->read_mode == MODE_RD_DIF))         //read raw data or diff\r
+       {\r
+               //printk(KERN_INFO"Read raw data\n");\r
+               ret = goodix_i2c_read_bytes(ts->client, read_data, 1201);\r
+               if(ret <= 0)\r
+               {\r
+                       if(ts->read_mode == 2)\r
+                               printk(KERN_INFO"Read raw data failed!\n");\r
+                       if(ts->read_mode == 3)\r
+                               printk(KERN_INFO"Read diff data failed!\n");\r
+                       return 0;\r
+               }\r
+               memcpy(page, read_data+1, 1200);\r
+               *eof = 1;\r
+               *start = NULL;\r
+               return 1200;\r
+       }\r
+       else if(ts->read_mode == MODE_RD_CFG)\r
+       {\r
+               if((rd_cfg_addr>83)&&(rd_cfg_addr<240))\r
+               {\r
+                       read_data[0] = rd_cfg_addr;\r
+                       printk("read config addr is:%d\n", rd_cfg_addr);\r
+               }\r
+               else\r
+               {\r
+                       read_data[0] = 101;\r
+                       printk("invalid read config addr,use default!\n");\r
+               }\r
+               if((rd_cfg_len<0)||(rd_cfg_len>156))\r
+               {\r
+                       printk("invalid read config length,use default!\n");\r
+                       rd_cfg_len = 239 - read_data[0];\r
+               }\r
+               printk("read config length is:%d\n", rd_cfg_len);\r
+               ret = goodix_i2c_read_bytes(ts->client, read_data, rd_cfg_len);\r
+               if(ret <= 0)\r
+               {\r
+                       printk(KERN_INFO"Read config info failed!\n");\r
+                       return 0;\r
+               }\r
+               memcpy(page, read_data+1, rd_cfg_len);\r
+               return rd_cfg_len;\r
+       }\r
+       return len;\r
+}\r
+              \r
+#endif\r
+//******************************End of firmware update surpport*******************************\r
+static const struct i2c_device_id goodix_ts_id[] = {\r
+       { "Goodix-TS", 0 },\r
+       { }\r
+};\r
+\r
+static struct i2c_driver rk_ts_driver = {\r
+       .probe          = rk_ts_probe,\r
+       .remove         = rk_ts_remove,\r
+       .shutdown       = rk_ts_shutdown,\r
+#ifndef CONFIG_HAS_EARLYSUSPEND\r
+       .suspend        = rk_ts_suspend,\r
+       .resume         = rk_ts_resume,\r
+#endif\r
+       .id_table       = goodix_ts_id,\r
+       .driver = {\r
+               .name   = "Goodix-TS",\r
+               .owner = THIS_MODULE,\r
+       },\r
+};\r
+\r
+\r
+static struct class *ts_debug_class = NULL;\r
+static ssize_t dbg_mode_show(struct class *cls,struct class_attribute *attr, char *_buf)\r
+{\r
+       printk("%s>>>>>>>>\n",__func__);\r
+       return 0;\r
+}\r
+\r
+static ssize_t dbg_mode_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t _count)\r
+{\r
+       dbg_thresd = simple_strtol(buf,NULL,10);\r
+       if(dbg_thresd)\r
+       {\r
+               printk(KERN_INFO "ts debug open\n");\r
+       }\r
+       else\r
+       {\r
+               printk(KERN_INFO "ts debug close");\r
+       }\r
+      \r
+    return _count;\r
+}\r
+static CLASS_ATTR(debug, 0664, dbg_mode_show, dbg_mode_store);\r
+\r
+static int dbg_sys_init(void)\r
+{\r
+       int ret ;\r
+       ts_debug_class = class_create(THIS_MODULE, "ts_debug");\r
+       ret =  class_create_file(ts_debug_class, &class_attr_debug);\r
+    if (ret)\r
+    {\r
+       printk("Fail to creat class hkrkfb.\n");\r
+    }\r
+   return 0;\r
+}\r
+\r
+\r
+/*******************************************************       \r
+Description:\r
+       Driver Install function.\r
+return:\r
+       Executive Outcomes. 0---succeed.\r
+********************************************************/\r
+\r
+static void __init rk_ts_init_async(void *unused, async_cookie_t cookie)\r
+{\r
+       i2c_add_driver(&rk_ts_driver);\r
+       dbg_sys_init();  //for debug\r
+}\r
+\r
+static int __init rk_ts_init(void)\r
+{\r
+       async_schedule(rk_ts_init_async, NULL);\r
+       return 0;\r
+}\r
+\r
+/*******************************************************       \r
+Description:\r
+       Driver uninstall function.\r
+return:\r
+       Executive Outcomes. 0---succeed.\r
+********************************************************/\r
+static void __exit rk_ts_exit(void)\r
+{\r
+       printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");\r
+       i2c_del_driver(&rk_ts_driver);\r
+}\r
+\r
+module_init(rk_ts_init);\r
+module_exit(rk_ts_exit);\r
+\r
+MODULE_DESCRIPTION("Goodix Touchscreen Driver");\r
+MODULE_LICENSE("GPL");\r
+\r
index 9ef4c7054770c70436231685896efdf5f59c77ac..b48432077a67586146a1f8265f96d07eb5f994b2 100755 (executable)
@@ -96,6 +96,10 @@ config LCD_RK2928_A720
         bool "RK2928 A720 panel 800x480"
 config LCD_HJ080NA
        bool "HJ080NA_4J 1024X768"
+
+config LCD_HJ101NA
+        bool "HJ101NA_4J 1280X800"
+
 config LCD_HSD07PFW1
        depends on MFD_RK610
        bool "RGB lcd panel HSD07PFW1"
index c925c0374ef958b5f0e95d1f2a9120f8c3ddd3a3..e96a92379f9c782c7a2cb276ea3fcf2b2e7bc0d2 100755 (executable)
@@ -45,3 +45,4 @@ obj-$(CONFIG_LCD_COMMON)    += lcd_common.o
 obj-$(CONFIG_LCD_RK2928_A720) += lcd_YQ70CPT9160.o
 obj-$(CONFIG_LCD_HSD07PFW1) += lcd_hsd07pfw1.o\r
 obj-$(CONFIG_LCD_HJ080NA)    += lcd_hj080na.o
+obj-$(CONFIG_LCD_HJ101NA)   += lcd_hj101na.o
diff --git a/drivers/video/display/screen/lcd_hj101na.c b/drivers/video/display/screen/lcd_hj101na.c
new file mode 100644 (file)
index 0000000..eb8fea3
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * This Lcd Driver is for BYD 5' LCD BM800480-8545FTGE.
+ * written by Michael Lin, 2010-06-18
+ */
+
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include "../../rk29_fb.h"
+#include <mach/gpio.h>
+#include <mach/iomux.h>
+#include <mach/board.h>
+#include "screen.h"
+
+
+/* Base */
+#define OUT_TYPE               SCREEN_RGB
+#define OUT_FACE               OUT_P888
+#define OUT_CLK                        71000000
+#define LCDC_ACLK       300000000     //29 lcdc axi DMA ÆµÂÊ
+
+/* Timing */
+#define H_PW                   10
+#define H_BP                   160
+#define H_VD                   1280
+#define H_FP                   16
+
+#define V_PW                   3
+#define V_BP                   23
+#define V_VD                   800
+#define V_FP                   12
+
+
+/* Other */
+#define DCLK_POL               0
+#define SWAP_RB                        0
+
+#define LCD_WIDTH       216    //need modify
+#define LCD_HEIGHT      135
+
+static struct rk29lcd_info *gLcd_info = NULL;
+
+#define DRVDelayUs(i)   udelay(i*2)
+
+static int init(void);
+static int standby(u8 enable);
+
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
+{
+    /* screen type & face */
+    screen->type = OUT_TYPE;
+    screen->face = OUT_FACE;
+
+    /* Screen size */
+    screen->x_res = H_VD;
+    screen->y_res = V_VD;
+    screen->width = LCD_WIDTH;
+    screen->height = LCD_HEIGHT;
+
+    /* Timing */
+    screen->lcdc_aclk = LCDC_ACLK;
+    screen->pixclock = OUT_CLK;
+       screen->left_margin = H_BP;
+       screen->right_margin = H_FP;
+       screen->hsync_len = H_PW;
+       screen->upper_margin = V_BP;
+       screen->lower_margin = V_FP;
+       screen->vsync_len = V_PW;
+
+       /* Pin polarity */
+       screen->pin_hsync = 0;
+       screen->pin_vsync = 0;
+       screen->pin_den = 0;
+       screen->pin_dclk = DCLK_POL;
+
+       /* Swap rule */
+    screen->swap_rb = SWAP_RB;
+    screen->swap_rg = 0;
+    screen->swap_gb = 0;
+    screen->swap_delta = 0;
+    screen->swap_dumy = 0;
+
+    /* Operation function*/
+    /*screen->init = init;*/
+    screen->init = NULL; 
+    screen->standby = standby;
+}
+
+
+static int standby(u8 enable)
+{
+       printk(KERN_INFO "byd1024x600 lcd standby, enable=%d\n", enable);
+       if (enable)
+       {
+               //rockchip_mux_api_set(LED_CON_IOMUX_PINNAME, LED_CON_IOMUX_PINDIR);
+               //GPIOSetPinDirection(LED_CON_IOPIN,GPIO_OUT);
+               //GPIOSetPinLevel(LED_CON_IOPIN,GPIO_HIGH);
+//             gpio_set_value(LCD_DISP_ON_IOPIN, GPIO_LOW);
+       }
+       else
+       {
+               //rockchip_mux_api_set(LED_CON_IOMUX_PINNAME, 1);
+//             gpio_set_value(LCD_DISP_ON_IOPIN, GPIO_HIGH);
+       }
+       return 0;
+}
+
diff --git a/include/linux/gt8110.h b/include/linux/gt8110.h
new file mode 100755 (executable)
index 0000000..3baf910
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 - 2011 Goodix, Inc.
+ * 
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef        _LINUX_GOODIX_GT8110_TOUCH_H
+#define                _LINUX_GOODIX_GT8110_TOUCH_H
+
+struct goodix_8110_platform_data {
+       uint32_t version;       /* Use this entry for panels with */
+       int reset;
+       int irq_pin;
+        int power_control;
+        int mode_check_pin;
+        int (*hw_init) (void);
+        int (*hw_exit) (void);
+};
+
+#endif /* _LINUX_GOODIX_TOUCH_H */
+\r