modify touchscreen ili2102 and add touchscreen support for a22
authorluowei <lw@rock-chips.com>
Fri, 25 Mar 2011 03:48:33 +0000 (11:48 +0800)
committerluowei <lw@rock-chips.com>
Fri, 25 Mar 2011 03:48:33 +0000 (11:48 +0800)
arch/arm/configs/rk29_a22_defconfig
drivers/input/touchscreen/ili2102_ts.c

index 67508a5421514d6572c61254d7130eec3a820dcc..a3709ab438384e2ad6271e522ced3c9c6a2a0656 100755 (executable)
@@ -788,11 +788,7 @@ CONFIG_KEYS_RK29=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_XPT2046_SPI_NOCHOOSE=y
-# CONFIG_TOUCHSCREEN_XPT2046_SPI is not set
-# CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI is not set
-# CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI is not set
-# CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI is not set
+CONFIG_TOUCHSCREEN_ILI2102_IIC=y
 # CONFIG_TOUCHSCREEN_IT7250 is not set
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
@@ -821,11 +817,10 @@ CONFIG_EETI_EGALAX_MAX_X=1087
 CONFIG_EETI_EGALAX_MAX_Y=800
 # CONFIG_EETI_EGALAX_DEBUG is not set
 # CONFIG_TOUCHSCREEN_IT7260 is not set
+# CONFIG_TOUCHSCREEN_GT801_IIC is not set
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_LPSENSOR_ISL29028=y
 # CONFIG_INPUT_LPSENSOR_CM3602 is not set
-# CONFIG_INPUT_LSENSOR_CM3623 is not set
-# CONFIG_INPUT_MPU3050 is not set
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
 # CONFIG_INPUT_KEYCHORD is not set
@@ -840,7 +835,6 @@ CONFIG_INPUT_WM831X_ON=y
 CONFIG_G_SENSOR_DEVICE=y
 # CONFIG_GS_MMA7660 is not set
 CONFIG_GS_MMA8452=y
-CONFIG_GS_FIH=y
 # CONFIG_INPUT_JOGBALL is not set
 
 #
@@ -1072,6 +1066,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
+# CONFIG_SOC_CAMERA_MT9M112 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
 # CONFIG_SOC_CAMERA_MT9P111 is not set
 # CONFIG_SOC_CAMERA_MT9D112 is not set
@@ -1216,14 +1211,19 @@ CONFIG_DISPLAY_SUPPORT=y
 # CONFIG_LCD_TJ048NC01CA is not set
 # CONFIG_LCD_HL070VM4AU is not set
 # CONFIG_LCD_HSD070IDW1 is not set
+# CONFIG_LCD_RGB_TFT480800_25_E is not set
 # CONFIG_LCD_HSD100PXN is not set
 # CONFIG_LCD_B101AW06 is not set
+# CONFIG_LCD_LS035Y8DX02A is not set
 # CONFIG_LCD_A060SE02 is not set
 # CONFIG_LCD_S1D13521 is not set
 # CONFIG_LCD_NT35582 is not set
 # CONFIG_LCD_NT35580 is not set
+# CONFIG_LCD_IPS1P5680_V1_E is not set
+# CONFIG_LCD_MCU_TFT480800_25_E is not set
 CONFIG_LCD_ILI9803_CPT4_3=y
 # CONFIG_LCD_ANX7150_720P is not set
+# CONFIG_LCD_AT070TNA2 is not set
 
 #
 # HDMI support
index b9327179c512c974e320ae62c852e5aa99cb3362..3cdedbdbf1d21192f49968d31a7916694c26836c 100755 (executable)
@@ -7,6 +7,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/types.h>
 #include <mach/iomux.h>
 #include <linux/platform_device.h>
 
 #define TOUCH_NUMBER 2
 
 static int touch_state[TOUCH_NUMBER] = {TOUCH_UP,TOUCH_UP};
-static struct workqueue_struct *ili2102_wq;
 
 struct ili2102_ts_data {
        u16             model;                  /* 801. */      
        bool    swap_xy;                /* swap x and y axes */ 
        u16             x_min, x_max;   
        u16             y_min, y_max;
-    uint16_t addr;
-    int        use_irq;
+       uint16_t addr;
+       int     use_irq;
        int     gpio_pendown;
        int     gpio_reset;
        int     gpio_reset_active_low;
@@ -40,11 +40,12 @@ struct ili2102_ts_data {
        char    resetpin_iomux_name[IOMUX_NAME_SIZE];   
        char    phys[32];
        char    name[32];
-    struct     i2c_client *client;
-    struct     input_dev *input_dev;
-    struct     hrtimer timer;
-    struct     work_struct  work;
-    struct     early_suspend early_suspend;
+       struct  i2c_client *client;
+       struct  input_dev *input_dev;
+       struct  hrtimer timer;
+       struct  work_struct  work;
+       struct  workqueue_struct *ts_wq;
+       struct  early_suspend early_suspend;
 };
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -65,9 +66,15 @@ static int verify_coord(struct ili2102_ts_data *ts,unsigned int *x,unsigned int
        return 0;
 }
 static int ili2102_init_panel(struct ili2102_ts_data *ts)
-{
-    return 0;
+{      
+       gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
+       gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
+       mdelay(1);
+       gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
+       mdelay(100);//need?
+       return 0;
 }
+#if 0
 static void ili2102_test(struct i2c_client *client)
 {
        int i;
@@ -98,82 +105,90 @@ static void ili2102_test(struct i2c_client *client)
     for(i=0; i<3; i++){
         printk("ili2102_test:buf[%d]=%x\n", i, buf[i]);
     }
-       
-
-       
+               
 }
+#endif
 static void ili2102_ts_work_func(struct work_struct *work)
 {
-    int i,ret;
-    int syn_flag = 0;
-    unsigned int x, y;
-    struct i2c_msg msg[2];
-    uint8_t start_reg;
-    uint32_t buf[4];
-    struct ili2102_ts_data *ts = container_of(work, struct ili2102_ts_data, work);
-       
+       int i,ret;
+       int syn_flag = 0;
+       unsigned int x, y;
+       struct i2c_msg msg[2];
+       uint8_t start_reg;
+       uint32_t buf[4];
+       struct ili2102_ts_data *ts = container_of(work, struct ili2102_ts_data, work);
+
        DBG("ili2102_ts_work_func\n");
-               
-    start_reg = 0x86;
+       
+       /*Touch Information Report*/
+       start_reg = 0x10;
 
-    msg[0].addr = ts->client->addr;
-    msg[0].flags = 0;
-    msg[0].len = 1;
-    msg[0].buf = &start_reg;
-    
-    msg[1].addr = ts->client->addr;
-    msg[1].flags = I2C_M_RD;
-    msg[1].len = 4 * TOUCH_NUMBER;
-    msg[1].buf = (u8*)&buf[0];
+       msg[0].addr = ts->client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 1;
+       msg[0].buf = &start_reg;
+
+       msg[1].addr = ts->client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 4 * TOUCH_NUMBER;
+       msg[1].buf = (u8*)&buf[0];
 
-    ret = i2c_transfer(ts->client->adapter, msg, 2);
+       ret = i2c_transfer(ts->client->adapter, msg, 2);
     
-    if (ret < 0) {
-      for(i=0; i<TOUCH_NUMBER; i++) buf[i] = 0xffffffff;
-         printk("ili2102_ts_work_func:i2c_transfer fail =%d\n",ret);
-    }
+       if (ret < 0) {
+       for(i=0; i<TOUCH_NUMBER; i++) buf[i] = 0xffffffff;
+       printk("ili2102_ts_work_func:i2c_transfer fail =%d\n",ret);
+       }
 
-    for(i=0; i<TOUCH_NUMBER; i++){
-      if(buf[i] == 0xffffffff || buf[i] == 0){
-               if (touch_state[i] == TOUCH_DOWN)
-               {
-                       DBG("ili2102_ts_work_func:buf[%d]=%d\n",i,buf[i]);
-               input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size
-               input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size
-               input_mt_sync(ts->input_dev);
-                       syn_flag = 1;
-                       touch_state[i] = TOUCH_UP;
-               }
-               
-      }
-      else{
-        x = ((buf[i] & 0xff) << 8) | ((buf[i] & 0xff00) >> 8);
-        y = ((buf[i] & 0xff0000) >> 8) | ((buf[i] & 0xff000000) >> 24);
+       for(i=0; i<TOUCH_NUMBER; i++)
+       {
+               if(buf[i] == 0xffffffff || buf[i] == 0)
+               {
+                       if (touch_state[i] == TOUCH_DOWN)
+                       {
+                               DBG("ili2102_ts_work_func:buf[%d]=%d\n",i,buf[i]);
+                               input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size
+                               input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size
+                               input_mt_sync(ts->input_dev);
+                               syn_flag = 1;
+                               touch_state[i] = TOUCH_UP;
+                       }
 
-               if (ts->swap_xy)
+               }
+               else
+               {
+                       #if 0
+                       x = ((buf[i] & 0xff) << 8) | ((buf[i] & 0xff00) >> 8);
+                       y = ((buf[i] & 0xff0000) >> 8) | ((buf[i] & 0xff000000) >> 24);
+                       #else
+                       x = (buf[i] & 0xff00)  | (buf[i] & 0xff);
+                       y = ((buf[i] & 0xff000000) >> 16) | ((buf[i] & 0xff0000) >> 16);
+                       #endif
+
+                       if (ts->swap_xy)
                        swap(x, y);
-               
-               if (verify_coord(ts,&x,&y))
+
+                       if (verify_coord(ts,&x,&y))
                        goto out;
-               
-        DBG("buf[%d]=%x X = %d, Y = %d\n", i, buf[i], x, y);
-
-        input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size
-        input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
-        input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
-        input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size
-        input_mt_sync(ts->input_dev);
-               syn_flag = 1;
-               touch_state[i] = TOUCH_DOWN;
-      }
-    }
+                               
+                       DBG("buf[%d]=%x X = %d, Y = %d\n", i, buf[i], x, y);
+
+                       input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
+                       input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size
+                       input_mt_sync(ts->input_dev);
+                       syn_flag = 1;
+                       touch_state[i] = TOUCH_DOWN;
+               }
+       }
        
        if(syn_flag)
-               input_sync(ts->input_dev);
+       input_sync(ts->input_dev);
 out:   
        
-    if (ts->use_irq) 
-               enable_irq(ts->client->irq);
+       if (ts->use_irq) 
+       enable_irq(ts->client->irq);
        
     return;
 }
@@ -183,7 +198,7 @@ static enum hrtimer_restart ili2102_ts_timer_func(struct hrtimer *timer)
     struct ili2102_ts_data *ts = container_of(timer, struct ili2102_ts_data, timer);
     DBG("ili2102_ts_timer_func\n"); 
 
-    queue_work(ili2102_wq, &ts->work);
+    queue_work(ts->ts_wq, &ts->work);
 
     hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
     return HRTIMER_NORESTART;
@@ -191,13 +206,12 @@ static enum hrtimer_restart ili2102_ts_timer_func(struct hrtimer *timer)
 
 static irqreturn_t ili2102_ts_irq_handler(int irq, void *dev_id)
 {
-    struct ili2102_ts_data *ts = dev_id;
+       struct ili2102_ts_data *ts = dev_id;
        DBG("ili2102_ts_irq_handler=%d,%d\n",ts->client->irq,ts->use_irq);
-       
-       //if (ts->use_irq)
-       disable_irq_nosync(ts->client->irq); //disable_irq(ts->client->irq);
-    queue_work(ili2102_wq, &ts->work);
-    return IRQ_HANDLED;
+
+       disable_irq_nosync(ts->client->irq); //disable_irq(ts->client->irq);
+       queue_work(ts->ts_wq, &ts->work);
+       return IRQ_HANDLED;
 }
 
 static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts_data *ts)
@@ -217,7 +231,7 @@ static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts
                return -EINVAL;
        }
 
-    rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode); 
+       rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode); 
        err = gpio_request(ts->gpio_reset, "ili2102_resetPin");
        if (err) {
                dev_err(&client->dev, "failed to request resetPin GPIO%d\n",
@@ -225,7 +239,7 @@ static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts
                return err;
        }
        
-       gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
+       mdelay(100);
 
        err = gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
        if (err) {
@@ -235,7 +249,7 @@ static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts
                return err;
        }
        
-    mdelay(100);
+       mdelay(1);
 
        gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
 
@@ -270,7 +284,7 @@ static int __devinit setup_pendown(struct i2c_client *client, struct ili2102_ts_
                return -EINVAL;
        }
        
-    rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
+       rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
        err = gpio_request(ts->gpio_pendown, "ili2102_pendown");
        if (err) {
                dev_err(&client->dev, "failed to request pendown GPIO%d\n",
@@ -287,101 +301,86 @@ static int __devinit setup_pendown(struct i2c_client *client, struct ili2102_ts_
        }
        return 0;
 }
+
 static int ili2102_chip_Init(struct i2c_client *client)
-{
-       uint8_t buf0[6];
-    int ret = 0;
+{      
+       int ret = 0;
+       uint8_t start_reg;
+       uint8_t buf[6];
+       struct i2c_msg msg[2];
        
-#if (0)
-    /* = */
-    buf0[0] = 0x71;
-    buf0[1] = 0x00;//30MHz
-    buf0[2] = 0x01;
-    buf0[3] = 0x07;
-    buf0[4] = 0x0D;
-    buf0[5] = 0x00;
-    
-    ret = i2c_master_send(client, buf0, 6);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
+       /* get panel information:6bytes */
+       start_reg = 0x20;
+       msg[0].addr =client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 1;
+       msg[0].buf = &start_reg;
+
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 6;
+       msg[1].buf = (u8*)&buf[0];
+
+       ret = i2c_transfer(client->adapter, msg, 2);   
+       if (ret < 0) {
+       printk("%s:err\n",__FUNCTION__);
+       }
 
-    /* = */
-    buf0[0] = 0x76;
-    buf0[1] = 0x01;
-    buf0[2] = 0x1B;
-    ret = i2c_master_send(client, buf0, 3);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
-#endif /* (0) */
-    
+       DBG("%s:b[0]=0x%x,b[1]=0x%x,b[2]=0x%x,b[3]=0x%x,b[4]=0x%x,b[5]=0x%x\n", 
+               __FUNCTION__,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
 
-    /* IC internal power on */
-    buf0[0] = 0x81;
-    ret = i2c_master_send(client, buf0, 1);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
-    
-    msleep(120);
-    
-    /* MCU power on */
-    buf0[0] = 0x35;
-    buf0[1] = 0x02;
-    ret = i2c_master_send(client, buf0, 2);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
-    
-    msleep(10);
-    
-    /* flash power on */
-    buf0[0] = 0x36;
-    buf0[1] = 0x01;
-    ret = i2c_master_send(client, buf0, 2);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
-    
-    msleep(10);
-       
-    ili2102_test(client);
-       msleep(10);
-       
-    /* Start touch panel sensing */
-    buf0[0] = 0x83;
-    ret = i2c_master_send(client, buf0, 1);
-    if(ret < 0) {
-        printk(KERN_ERR "i2c_master_send failed\n");
-    }
+       /*get firmware version:3bytes */        
+       start_reg = 0x40;
+       msg[0].addr =client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 1;
+       msg[0].buf = &start_reg;
 
-       msleep(120);
-        
-       return ret;
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 3;
+       msg[1].buf = (u8*)&buf[0];
+
+       ret = i2c_transfer(client->adapter, msg, 2);
+       if (ret < 0) {
+       printk("%s:err\n",__FUNCTION__);
+       }
+
+       DBG("%s:Ver %d.%d.%d\n",__FUNCTION__,buf[0],buf[1],buf[2]);
+
+       return 0;
+    
 }
+
 static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-    struct ili2102_ts_data *ts;
+       struct ili2102_ts_data *ts;
        struct ili2102_platform_data    *pdata = client->dev.platform_data;
-    int ret = 0;
+       int ret = 0;
 
-    printk("ili2102 TS probe\n"); //[Step 1]
+       printk("ili2102 TS probe\n"); 
     
-    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-        printk(KERN_ERR "ili2102_ts_probe: need I2C_FUNC_I2C\n");
-        ret = -ENODEV;
-        goto err_check_functionality_failed;
-    }
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+           printk(KERN_ERR "ili2102_ts_probe: need I2C_FUNC_I2C\n");
+           ret = -ENODEV;
+           goto err_check_functionality_failed;
+       }
 
-    ts = kzalloc(sizeof(*ts), GFP_KERNEL);
-    if (ts == NULL) {
-        ret = -ENOMEM;
-        goto err_alloc_data_failed;
-    }
-    INIT_WORK(&ts->work, ili2102_ts_work_func);
-    ts->client = client;
-    i2c_set_clientdata(client, ts);
+       ts = kzalloc(sizeof(*ts), GFP_KERNEL);
+       if (ts == NULL) {
+           ret = -ENOMEM;
+           goto err_alloc_data_failed;
+       }
+       
+       ts->ts_wq = create_singlethread_workqueue("ts_wq");
+       if (!ts->ts_wq)
+       {
+               printk("%s:fail to create ts_wq,ret=0x%x\n",__FUNCTION__, ENOMEM);
+               return -ENOMEM;
+       }
+       INIT_WORK(&ts->work, ili2102_ts_work_func);
+       ts->client = client;
+       i2c_set_clientdata(client, ts);
 
        ret = setup_resetPin(client,ts);
        if(ret)
@@ -397,13 +396,13 @@ static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_i
                goto err_resetpin_failed;
        }
 
-    /* allocate input device */
-    ts->input_dev = input_allocate_device();
-    if (ts->input_dev == NULL) {
-        ret = -ENOMEM;
-        printk(KERN_ERR "ili2102_ts_probe: Failed to allocate input device\n");
-        goto err_input_dev_alloc_failed;
-    }
+       /* allocate input device */
+       ts->input_dev = input_allocate_device();
+       if (ts->input_dev == NULL) {
+           ret = -ENOMEM;
+           printk(KERN_ERR "ili2102_ts_probe: Failed to allocate input device\n");
+           goto err_input_dev_alloc_failed;
+       }
 
        ts->model = pdata->model ? : 801;
        ts->swap_xy = pdata->swap_xy;
@@ -418,120 +417,134 @@ static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_i
        ts->input_dev->dev.parent = &client->dev;
 
        ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS);
-    //ts->input_dev->absbit[0] = 
+       //ts->input_dev->absbit[0] = 
                //BIT(ABS_MT_POSITION_X) | BIT(ABS_MT_POSITION_Y) | 
                //BIT(ABS_MT_TOUCH_MAJOR) | BIT(ABS_MT_WIDTH_MAJOR);  // for android
-    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 
+       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 
                    ts->x_min ? : 0,
                        ts->x_max ? : 480,
                        0, 0);
-    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+       input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
                        ts->y_min ? : 0,
                        ts->y_max ? : 800,
                        0, 0);
-    input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); //Finger Size
-    input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0); //Touch Size
-
-    /* ts->input_dev->name = ts->keypad_info->name; */
-    ret = input_register_device(ts->input_dev);
-    if (ret) {
-        printk(KERN_ERR "ili2102_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
-        goto err_input_register_device_failed;
-    }
+       input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); //Finger Size
+       input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0); //Touch Size
+
+       /* ts->input_dev->name = ts->keypad_info->name; */
+       ret = input_register_device(ts->input_dev);
+       if (ret) {
+           printk(KERN_ERR "ili2102_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
+           goto err_input_register_device_failed;
+       }
 
        client->irq = gpio_to_irq(client->irq);
-    if (client->irq) {
+       if (client->irq) 
+       {
                ret = setup_pendown(client,ts);
                if(ret)
                {
                         printk("ili2102 TS setup_pendown fail\n");
                         goto err_input_register_device_failed;
                }
-        ret = request_irq(client->irq, ili2102_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, client->name, ts);
-        if (ret == 0) {
-            DBG("ili2102 TS register ISR (irq=%d)\n", client->irq);
-            ts->use_irq = 1;
-        }
-        else 
-                       dev_err(&client->dev, "request_irq failed\n");
-    }
+               ret = request_irq(client->irq, ili2102_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, client->name, ts);
+               if (ret == 0) {
+                   DBG("ili2102 TS register ISR (irq=%d)\n", client->irq);
+                   ts->use_irq = 1;
+               }
+               else 
+               dev_err(&client->dev, "request_irq failed\n");
+       }
     
-    if (!ts->use_irq) {
-        hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-        ts->timer.function = ili2102_ts_timer_func;
-        hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
-    }
+       if (!ts->use_irq) {
+       hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       ts->timer.function = ili2102_ts_timer_func;
+       hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+       }
 #ifdef CONFIG_HAS_EARLYSUSPEND
-    ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-    ts->early_suspend.suspend = ili2102_ts_early_suspend;
-    ts->early_suspend.resume = ili2102_ts_late_resume;
-    register_early_suspend(&ts->early_suspend);
+       ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+       ts->early_suspend.suspend = ili2102_ts_early_suspend;
+       ts->early_suspend.resume = ili2102_ts_late_resume;
+       register_early_suspend(&ts->early_suspend);
 #endif
 
-    printk(KERN_INFO "ili2102_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
+       printk(KERN_INFO "ili2102_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
 
-    return 0;
+       return 0;
 
-err_input_register_device_failed:
-    input_free_device(ts->input_dev);
-err_resetpin_failed:
+       err_input_register_device_failed:
+       input_free_device(ts->input_dev);
+       err_resetpin_failed:
        gpio_free(ts->gpio_reset);
-err_input_dev_alloc_failed:
-    kfree(ts);
-err_alloc_data_failed:
-err_check_functionality_failed:
-    return ret;
+       err_input_dev_alloc_failed:
+       kfree(ts);
+       err_alloc_data_failed:
+       err_check_functionality_failed:
+       return ret;
 }
 
 static int ili2102_ts_remove(struct i2c_client *client)
 {
-    struct ili2102_ts_data *ts = i2c_get_clientdata(client);
-    unregister_early_suspend(&ts->early_suspend);
-    if (ts->use_irq)
-        free_irq(client->irq, ts);
-    else
-        hrtimer_cancel(&ts->timer);
-    input_unregister_device(ts->input_dev);
-    kfree(ts);
-    return 0;
+       struct ili2102_ts_data *ts = i2c_get_clientdata(client);
+       unregister_early_suspend(&ts->early_suspend);
+       if (ts->use_irq)
+       free_irq(client->irq, ts);
+       else
+       hrtimer_cancel(&ts->timer);
+       input_unregister_device(ts->input_dev);
+       if (ts->ts_wq)
+       destroy_workqueue(ts->ts_wq);
+       kfree(ts);
+       return 0;
 }
 
 static int ili2102_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 {
-    int ret;
-    struct ili2102_ts_data *ts = i2c_get_clientdata(client);
-
-    printk("ili2102 TS Suspend\n");
-    
-    if (ts->use_irq)
-        disable_irq(client->irq);
-    else
-        hrtimer_cancel(&ts->timer);
-
-    ret = cancel_work_sync(&ts->work);
-    if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
-        enable_irq(client->irq);
-
-    // TODO do suspend
-    return 0;
+       int ret;
+       struct ili2102_ts_data *ts = i2c_get_clientdata(client);
+       uint8_t buf[2] = {0x30,0x30};
+       struct i2c_msg msg[1];
+       
+       if (ts->use_irq)
+       disable_irq(client->irq);
+       else
+       hrtimer_cancel(&ts->timer);
+
+       ret = cancel_work_sync(&ts->work);
+       if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
+       enable_irq(client->irq);
+
+       //to do suspend
+       msg[0].addr =client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 2;
+       msg[0].buf = buf;
+
+       ret = i2c_transfer(client->adapter, msg, 1);
+       if (ret < 0) {
+       printk("%s:err\n",__FUNCTION__);
+       }
+       
+       DBG("%s\n",__FUNCTION__);
+       
+       return 0;
 }
 
 static int ili2102_ts_resume(struct i2c_client *client)
 {
-    struct ili2102_ts_data *ts = i2c_get_clientdata(client);
-
-    ili2102_init_panel(ts);
-    
-    //TODO do resume
+       struct ili2102_ts_data *ts = i2c_get_clientdata(client);
+       
+       //to do resume
+       ili2102_init_panel(ts);
+       
+       if (ts->use_irq) {
+               printk("enabling IRQ %d\n", client->irq);
+               enable_irq(client->irq);
+       }
+       else
+       hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
 
-    printk("ili2102 TS Resume\n");
-    
-    if (ts->use_irq) {
-        printk("enabling IRQ %d\n", client->irq);
-        enable_irq(client->irq);
-    }
-    else
-        hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+       DBG("%s\n",__FUNCTION__);
 
     return 0;
 }
@@ -563,8 +576,8 @@ static struct i2c_driver ili2102_ts_driver = {
     .probe      = ili2102_ts_probe,
     .remove     = ili2102_ts_remove,
 #ifndef CONFIG_HAS_EARLYSUSPEND
-    .suspend    = ili2102_ts_suspend,
-    .resume     = ili2102_ts_resume,
+    .suspend    = ili2102_ts_early_suspend,
+    .resume     = ili2102_ts_late_resume,
 #endif
     .id_table   = ili2102_ts_id,
     .driver = {
@@ -574,19 +587,12 @@ static struct i2c_driver ili2102_ts_driver = {
 
 static int __devinit ili2102_ts_init(void)
 {
-    printk("ili2102 TS init\n"); //[Step 0]
-    ili2102_wq = create_singlethread_workqueue("ili2102_wq");
-    if (!ili2102_wq)
-        return -ENOMEM;
     return i2c_add_driver(&ili2102_ts_driver);
 }
 
 static void __exit ili2102_ts_exit(void)
 {
-    printk("ili2102 TS exit\n");
-    i2c_del_driver(&ili2102_ts_driver);
-    if (ili2102_wq)
-        destroy_workqueue(ili2102_wq);
+       i2c_del_driver(&ili2102_ts_driver);
 }
 
 module_init(ili2102_ts_init);