From e083908af3742a542c2f85bf9b222b69362e0af8 Mon Sep 17 00:00:00 2001 From: luowei Date: Fri, 25 Mar 2011 11:48:33 +0800 Subject: [PATCH] modify touchscreen ili2102 and add touchscreen support for a22 --- arch/arm/configs/rk29_a22_defconfig | 16 +- drivers/input/touchscreen/ili2102_ts.c | 526 +++++++++++++------------ 2 files changed, 274 insertions(+), 268 deletions(-) diff --git a/arch/arm/configs/rk29_a22_defconfig b/arch/arm/configs/rk29_a22_defconfig index 67508a542151..a3709ab43838 100755 --- a/arch/arm/configs/rk29_a22_defconfig +++ b/arch/arm/configs/rk29_a22_defconfig @@ -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 diff --git a/drivers/input/touchscreen/ili2102_ts.c b/drivers/input/touchscreen/ili2102_ts.c index b9327179c512..3cdedbdbf1d2 100755 --- a/drivers/input/touchscreen/ili2102_ts.c +++ b/drivers/input/touchscreen/ili2102_ts.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -22,15 +23,14 @@ #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; iinput_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; iinput_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); -- 2.34.1