From: yxj Date: Sat, 19 Nov 2011 09:13:37 +0000 (+0800) Subject: mutitouch support for goodix touch screen X-Git-Tag: firefly_0821_release~9735^2~4 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6b15d21704148f03fc1c2ab31e58ab4e9f1016fc;p=firefly-linux-kernel-4.4.55.git mutitouch support for goodix touch screen --- diff --git a/arch/arm/mach-rk29/board-rk29-k97.c b/arch/arm/mach-rk29/board-rk29-k97.c index caccc0718a80..6356dd76144d 100755 --- a/arch/arm/mach-rk29/board-rk29-k97.c +++ b/arch/arm/mach-rk29/board-rk29-k97.c @@ -743,6 +743,7 @@ int goodix_init_platform_hw(void) struct goodix_platform_data goodix_info = { .model= 8105, + .irq_pin = RK29_PIN0_PA2, .rest_pin = TOUCH_RESET_PIN, .init_platform_hw = goodix_init_platform_hw, }; diff --git a/arch/arm/mach-rk29/include/mach/board.h b/arch/arm/mach-rk29/include/mach/board.h index 99953b5f61b2..3fdad366bcd7 100755 --- a/arch/arm/mach-rk29/include/mach/board.h +++ b/arch/arm/mach-rk29/include/mach/board.h @@ -276,6 +276,7 @@ struct ft5406_platform_data { struct goodix_platform_data { int model ; int rest_pin; + int irq_pin ; int (*get_pendown_state)(void); int (*init_platform_hw)(void); int (*platform_sleep)(void); diff --git a/drivers/input/touchscreen/rk29_i2c_goodix.c b/drivers/input/touchscreen/rk29_i2c_goodix.c index 329178ca605e..61440836f141 100755 --- a/drivers/input/touchscreen/rk29_i2c_goodix.c +++ b/drivers/input/touchscreen/rk29_i2c_goodix.c @@ -48,7 +48,7 @@ #define PEN_DOWN 1 #define PEN_RELEASE 0 #define MAX_SUPPORT_POINT 2 -#define fjp_debug 1 +//#define fjp_debug 0 //#define fjp_debug /******************************************************* @@ -66,7 +66,7 @@ Parameter: return: numbers of i2c_msgs to transfer *********************************************************/ -static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len) +static int goodix_i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len) { struct i2c_msg msgs[2]; int ret=-1; @@ -86,14 +86,14 @@ static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len) msgs[1].udelay = client->udelay; msgs[1].scl_rate=200 * 1000; - disable_irq(client->irq); + //disable_irq(client->irq); while(retries<5) { ret=i2c_transfer(client->adapter,msgs, 2); if(ret == 2)break; retries++; } - enable_irq(client->irq); + //enable_irq(client->irq); return ret; } @@ -110,7 +110,7 @@ Parameter: return: numbers of i2c_msgs to transfer. *********************************************************/ -static int i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len) +static int goodix_i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len) { struct i2c_msg msg; int ret=-1; @@ -123,14 +123,14 @@ static int i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len) msg.udelay = client->udelay; msg.scl_rate=200 * 1000; - disable_irq(client->irq); + //disable_irq(client->irq); while(retries<5) { ret=i2c_transfer(client->adapter,&msg, 1); if(ret == 1)break; retries++; } - enable_irq(client->irq); + //enable_irq(client->irq); return ret; } @@ -144,7 +144,7 @@ Parameter: return: Executive outcomes.0---succeed. *******************************************************/ -static int goodix_init_panel(struct goodix_ts_data *ts) +static int goodix_init_panel(struct rk_ts_data *ts) { int ret=-1; uint8_t rd_cfg_buf[7] = {0x66,}; @@ -186,17 +186,15 @@ static int goodix_init_panel(struct goodix_ts_data *ts) 0x00,0x00,0x00,0x00 }; #endif - ret=i2c_write_bytes(ts->client,config_info, (sizeof(config_info)/sizeof(config_info[0]))); + ret=goodix_i2c_write_bytes(ts->client,config_info, (sizeof(config_info)/sizeof(config_info[0]))); if (ret < 0) { printk("goodix write cfg info err"); return ret; } - ret=i2c_read_bytes(ts->client, rd_cfg_buf, 7); + ret=goodix_i2c_read_bytes(ts->client, rd_cfg_buf, 7); if(ret != 2) { dev_info(&ts->client->dev, "Read resolution & max_touch_num failed, use default value!\n"); - ts->abs_x_max = TOUCH_MAX_HEIGHT; - ts->abs_y_max = TOUCH_MAX_WIDTH; ts->max_touch_num = MAX_FINGER_NUM; ts->int_trigger_type = INT_TRIGGER; return 0; @@ -207,24 +205,23 @@ static int goodix_init_panel(struct goodix_ts_data *ts) ts->int_trigger_type = rd_cfg_buf[6]&0x03; if((!ts->abs_x_max)||(!ts->abs_y_max)||(!ts->max_touch_num)) { - dev_info(&ts->client->dev, "Read invalid resolution & max_touch_num, use default value!\n"); - ts->abs_x_max = TOUCH_MAX_HEIGHT; - ts->abs_y_max = TOUCH_MAX_WIDTH; + printk(KERN_INFO "Read invalid resolution & max_touch_num, use default value!\n"); ts->max_touch_num = MAX_FINGER_NUM; } - dev_info(&ts->client->dev,"X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d\n",ts->abs_x_max,ts->abs_y_max,ts->max_touch_num); - dev_info(&ts->client->dev,"int_trigger type is %d\n",rd_cfg_buf[6]); + printk(KERN_INFO "X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d\n",ts->abs_x_max,ts->abs_y_max,ts->max_touch_num); + printk(KERN_INFO "int_trigger type is %d\n",rd_cfg_buf[6]); //test rd_cfg_buf[0] = 0x6e; rd_cfg_buf[1] = 0x00; - i2c_read_bytes(ts->client, rd_cfg_buf, 2); + goodix_i2c_read_bytes(ts->client, rd_cfg_buf, 2); if((rd_cfg_buf[1]&0x0f)==0x0f) { dev_info(&ts->client->dev, "Need int wake up from green mode!\n"); } - msleep(10); + //msleep(10); + printk("max_point:%d\n",ts->max_touch_num); return 0; } @@ -239,12 +236,12 @@ Parameter: return: Executive outcomes.0---succeed. *******************************************************/ -static int goodix_read_version(struct goodix_ts_data *ts, char **version) +static int goodix_read_version(struct rk_ts_data *ts, char **version) { int ret = -1, count = 0; char *version_data; char *p; - + *version = (char *)vmalloc(18); version_data = *version; if(!version_data) @@ -252,7 +249,7 @@ static int goodix_read_version(struct goodix_ts_data *ts, char **version) p = version_data; memset(version_data, 0, sizeof(version_data)); version_data[0]=240; - ret=i2c_read_bytes(ts->client,version_data, 17); + ret=goodix_i2c_read_bytes(ts->client,version_data, 17); if (ret < 0) return ret; version_data[17]='\0'; @@ -270,137 +267,40 @@ static int goodix_read_version(struct goodix_ts_data *ts, char **version) else return 1; } -unsigned int last_x = 0; -unsigned int last_y = 0; - - -/******************************************************* -Description: - Goodix touchscreen work function. -Parameter: - ts: i2c client private struct. - -return: - Executive outcomes.0---succeed. -*******************************************************/ -static void goodix_ts_work_func(struct work_struct *pwork) -{ - int ret=-1; - int tmp = 0; +static last_touch_num = -1; +static void goodix_get_touch_info(struct rk_ts_data *ts,char *point_num,struct rk_touch_info* info_buf) +{ 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) uint8_t check_sum = 0; + int ret ; uint16_t finger_current = 0; uint16_t finger_bit = 0; unsigned int count = 0, point_count = 0; - unsigned int position = 0; - uint8_t track_id[MAX_FINGER_NUM] = {0}; - unsigned int input_x = 0; - unsigned int input_y = 0; - unsigned int input_w = 0; - unsigned int index = 0; unsigned char touch_num = 0; uint8_t chksum_err = 0; + unsigned int position = 0; + uint8_t track_id[MAX_FINGER_NUM] = {0}; + u8 index; + point_data[0] = READ_COOR_ADDR; //read coor address - - - struct goodix_ts_data *ts = container_of(pwork, struct goodix_ts_data, work); - - //printk("enter the goodix_ts_timer_func!\n"); -// if(g_enter_isp)return; -#if defined(INT_PORT) -COORDINATE_POLL: - if(gpio_get_value(INT_PORT) != GPIO_LOW) - { - #ifdef fjp_debug - printk("NO_ACTION--NO_ACTION--NO_ACTION\n"); //add by fjp 2010-9-28 - #endif - goto NO_ACTION; - } -#endif - - - if( tmp > 9) { - printk("XFER_ERROR--XFER_ERROR--XFER_ERROR\n"); - dev_info(&(ts->client->dev), "I2C transfer error,touchscreen stop working.\n"); - goto XFER_ERROR ; - } - if(ts->bad_data) - msleep(20); -read_one_more_time: - - //printk("prepare for I2C transfer!\n"); - point_data[0] = READ_COOR_ADDR; //read coor address - ret=i2c_read_bytes(ts->client, point_data, sizeof(point_data)/sizeof(point_data[0])); + ret=goodix_i2c_read_bytes(ts->client, point_data, sizeof(point_data)/sizeof(point_data[0])); if(ret != 2) { - printk("I2C transfer error--I2C transfer error--I2C transfer error\n"); - dev_err(&(ts->client->dev),"I2C transfer error. Number:%d\n ", ret); + printk("goodix read error\n"); ts->bad_data = 1; - tmp ++; - ts->retry++; - #if defined(INT_PORT) - if(ts->int_trigger_type> 2) - goto COORDINATE_POLL; - else - goto XFER_ERROR; - #endif } - /* - for( i=0;ibad_data = 0; finger_current = (point_data[3 - READ_COOR_ADDR]<<8) + point_data[2 - READ_COOR_ADDR]; #ifdef fjp_debug - printk("finger_current ====%d\n", finger_current);//add by fjp 2010-9-28 - #endif - //===add by fjp=============== - /* if(0x200&finger_current) - current_num =0xa; - else if(0x100&finger_current) - current_num =0x9; - else if (0x80&finger_current) - current_num =0x8; - else if (0x40&finger_current) - current_num =0x7; - else if (0x20&finger_current) - current_num =0x6; - else if (0x10&finger_current) - current_num =0x5; - else if (0x8&finger_current) - current_num =0x4; - else if (0x4&finger_current) - current_num =0x3; - else if (0x2&finger_current) - current_num =0x2; - else if (0x1&finger_current) - current_num =0x1; - #ifdef fjp_debug - printk("current_num ====%d\n", current_num); + printk("finger_current:%d ==== max_touch_num:%d\n", finger_current,ts->max_touch_num);//add by fjp 2010-9-28 #endif - point_data[0] = READ_COOR_ADDR; - ret=i2c_read_bytes(ts->client, point_data, ((1-READ_COOR_ADDR)+1+2+5*current_num+1)); - if(ret != 2) - { - #ifdef fjp_debug - printk("I2C transfer error--I2C transfer error--I2C transfer error\n"); - #endif - dev_err(&(ts->client->dev),"I2C transfer error. Number:%d\n ", ret); - ts->bad_data = 1; - tmp ++; - ts->retry++; - goto XFER_ERROR; - - } - ts->bad_data = 0; */ - //================================== + if(finger_current) { - point_count = 0, finger_bit = finger_current; + point_count = 0; + finger_bit = finger_current; for(count = 0; (finger_bit != 0) && (count < ts->max_touch_num); count++)//cal how many point touch currntly { if(finger_bit & 0x01) @@ -419,27 +319,7 @@ read_one_more_time: check_sum += point_data[count]; if(check_sum != 0) //checksum verify error { - #if 0 - dev_info(&ts->client->dev, "Check_sum:%d, Data:%d\n", check_sum, point_data[count]); - printk(KERN_INFO "Finger Bit:%d\n",finger_current); - for( ; count > 0; count--) - printk(KERN_INFO "count=%d:%d ",count, point_data[count]); - printk(KERN_INFO "\n"); - #endif - #ifdef fjp_debug printk("coor checksum error!\n"); - #endif - if(!chksum_err) - { - chksum_err = 1; - goto read_one_more_time; - } - #if defined(INT_PORT) - if(ts->int_trigger_type> 2) - goto COORDINATE_POLL; - else - goto XFER_ERROR; - #endif } else { @@ -447,113 +327,121 @@ read_one_more_time: } } - if(touch_num) + //printk("current point num:%d\n",touch_num); + *point_num = touch_num; + if(touch_num < last_touch_num) //some flinger release { - for(index=0; index ts->abs_x_max)||(input_y > ts->abs_y_max)) - continue; - - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); - //input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); - - //input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); - //input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, track_id[index]); - //input_mt_sync(ts->input_dev); - - - } - ts->pendown =PEN_DOWN; - input_sync(ts->input_dev); + //printk("%d flinger release\n",last_touch_num-touch_num); + for(index = touch_num; index < last_touch_num; index++) + info_buf[index].status = 0; + *point_num = last_touch_num; + } + last_touch_num = touch_num; + for(index = 0; index < touch_num; index++) + { + position = 4 - READ_COOR_ADDR + 5*index; + info_buf[index].x = (unsigned int) (point_data[position]<<8) + (unsigned int)( point_data[position+1]); + info_buf[index].y = (unsigned int)(point_data[position+2]<<8) + (unsigned int) (point_data[position+3]); + info_buf[index].status = !gpio_get_value(ts->irq_pin); } +} - #ifdef HAVE_TOUCH_KEY - //printk(KERN_INFO"HAVE KEY DOWN!0x%x\n",point_data[1]); - for(count = 0; count < MAX_KEY_NUM; count++) + +/******************************************************* +Description: + Goodix touchscreen work function. + +Parameter: + ts: i2c client private struct. + +return: + Executive outcomes.0---succeed. +*******************************************************/ +static int rk_ts_work_func(struct work_struct *pwork) +{ + int i =0; + struct rk_touch_info *info_buf; + char point_num; + + if(pwork==NULL) { - input_report_key(ts->input_dev, touch_key_array[count], !!(point_data[1]&(0x01<>>>>>>>err:null pwork\n",__func__); + return -1; + } - -#if defined(INT_PORT) - if(ts->int_trigger_type> 2) + struct rk_ts_data *ts = container_of(pwork, struct rk_ts_data, ts_work); + if(!ts) { - msleep(POLL_TIME); - goto COORDINATE_POLL; + printk("container of rk_ts_data fail\n"); + return -1; + } + + info_buf= kzalloc(ts->max_touch_num*sizeof(struct rk_touch_info), GFP_KERNEL); + if(!info_buf) + { + printk(KERN_ALERT "alloc for rk_touch_info fail\n"); + return -1; } -#endif - goto END_WORK_FUNC; - -NO_ACTION: -#ifdef HAVE_TOUCH_KEY - //printk(KERN_INFO"HAVE KEY DOWN!0x%x\n",point_data[1]); - for(count = 0; count < MAX_KEY_NUM; count++) + if(ts->get_touch_info) { - input_report_key(ts->input_dev, touch_key_array[count], !!(point_data[1]&(0x01<get_touch_info(ts,&point_num,info_buf); } - input_sync(ts->input_dev); -#endif -END_WORK_FUNC: -XFER_ERROR: - //=========add by fjp send last up touchkey============== - if(gpio_get_value(INT_PORT) == GPIO_LOW) - { - #ifdef fjp_debug - printk("touch down .............\n");//add by fjp 2010-9-28 - #endif - queue_delayed_work(goodix_wq, &ts->work,msecs_to_jiffies(30)); - } - else - { - if((ts->pendown)) - { - #if 0 - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); - input_mt_sync(ts->input_dev); - input_sync(ts->input_dev); - #ifdef fjp_debug - printk("touch finish finsih\n");//add by fjp 2010-9-28 - #endif - #else - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - //input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, last_x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, last_y); - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); - input_sync(ts->input_dev); - ts->pendown =PEN_RELEASE; - #ifdef fjp_debug - printk("touch up>>x:%d>>y:%d\n",last_x,last_y);//add by fjp 2010-9-28 - #endif - #endif - } - if(ts->use_irq) - enable_irq(ts->client->irq); + for(i=0; i< point_num; i++) + { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, info_buf[i].status); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, info_buf[i].x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, info_buf[i].y); + #ifdef fjp_debug + printk("touch point %d %s >>x:%d>>y:%d\n",i,info_buf[i].status? "down":"up",info_buf[i].x,info_buf[i].y);//add by fjp 2010-9-28 + #endif + if(!info_buf[i].status) + { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); + } + + } + input_sync(ts->input_dev); + + if(gpio_get_value(ts->irq_pin) == GPIO_LOW) + { + #ifdef fjp_debug + printk("touch down .............\n");//add by fjp 2010-9-28 + #endif + queue_delayed_work(ts->ts_wq, &ts->ts_work,msecs_to_jiffies(30)); + goto exit; + + } + else + { + #ifdef fjp_debug + printk("touch up>>x:%d>>y:%d\n",info_buf[0].x,info_buf[0].y);//add by fjp 2010-9-28 + #endif + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); + //input_report_abs(ts->input_dev, ABS_MT_POSITION_X, info_buf[0].x); + //input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, info_buf[0].y); + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); + input_sync(ts->input_dev); + ts->pendown =PEN_RELEASE; + + } + + enable_irq(ts->irq); +exit: + kfree(info_buf); + return 0; + } + - //============================================ -} /******************************************************* Description: @@ -567,9 +455,8 @@ return: *******************************************************/ static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer) { - struct goodix_ts_data *ts = container_of(timer, struct goodix_ts_data, timer); - //queue_work(goodix_wq, &ts->work); - queue_delayed_work(goodix_wq,&ts->work,0); + struct rk_ts_data *ts = container_of(timer, struct rk_ts_data, timer); + queue_delayed_work(goodix_wq,&ts->ts_work,0); hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL); return HRTIMER_NORESTART; } @@ -585,19 +472,78 @@ Parameter: return: irq execute status. *******************************************************/ -static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +static irqreturn_t rk_ts_irq_handler(int irq, void *dev_id) { - struct goodix_ts_data *ts = dev_id; + struct rk_ts_data *ts = (struct rk_ts_data*)dev_id; #ifdef fjp_debug - printk("entry goodix_ts_irq_handler\n");//add by fjp 2010-9-28 - #endif - disable_irq_nosync(ts->client->irq); - queue_delayed_work(goodix_wq, &ts->work,0); + printk("entry goodix_ts_irq_handler irq:%d\n",ts->irq);//add by fjp 2010-9-28 +#endif + disable_irq_nosync(ts->irq); + queue_delayed_work(ts->ts_wq, &ts->ts_work,0); return IRQ_HANDLED; } +static int rk_ts_suspend(struct i2c_client *client, pm_message_t mesg) +{ + int ret; + struct rk_ts_data *ts = i2c_get_clientdata(client); + + + if (ts->use_irq) + disable_irq(client->irq); + else + hrtimer_cancel(&ts->timer); +#if 1 + if (ts->power) { + ret = ts->power(ts, 0); + if (ret < 0) + printk(KERN_ERR "goodix_ts_resume power off failed\n"); + } +#endif + return 0; +} + +static int rk_ts_resume(struct i2c_client *client) +{ + int ret; + struct rk_ts_data *ts = i2c_get_clientdata(client); + +#if 1 + if (ts->power) { + ret = ts->power(ts, 1); + if (ret < 0) + printk(KERN_ERR "goodix_ts_resume power on failed\n"); + } +#endif + if (ts->use_irq) + enable_irq(client->irq); + else + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + //gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH); + + return 0; +} + + + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void rk_ts_early_suspend(struct early_suspend *h) +{ + struct rk_ts_data *ts; + ts = container_of(h, struct rk_ts_data, early_suspend); + rk_ts_suspend(ts->client, PMSG_SUSPEND); +} + +static void rk_ts_late_resume(struct early_suspend *h) +{ + struct rk_ts_data *ts; + ts = container_of(h, struct rk_ts_data, early_suspend); + rk_ts_resume(ts->client); +} +#endif + /******************************************************* Description: Goodix touchscreen power manage function. @@ -608,14 +554,14 @@ Parameter: return: Executive outcomes.-1---i2c transfer error;0---succeed. *******************************************************/ -static int goodix_ts_power(struct goodix_ts_data * ts, int on) +static int goodix_ts_power(struct rk_ts_data * ts, int on) { int ret = -1; unsigned char i2c_control_buf[2] = {80, 1}; //suspend cmd int retry = 0; if(on != 0 && on !=1) { - printk(KERN_DEBUG "%s: Cant't support this command.", goodix_ts_name); + printk(KERN_DEBUG "%s: Cant't support this command.", rk_ts_name); return -EINVAL; } @@ -624,9 +570,9 @@ static int goodix_ts_power(struct goodix_ts_data * ts, int on) if(on == 0) //suspend { - while(retry<5) + while(retry<5) { - ret = i2c_write_bytes(ts->client, i2c_control_buf, 2); + ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); if(ret == 1) { printk(KERN_INFO"Send suspend cmd\n"); @@ -649,229 +595,102 @@ static int goodix_ts_power(struct goodix_ts_data * ts, int on) return ret; } -#if 0 -/******************************************************* -Description: - Goodix debug sysfs cat version function. -Parameter: - standard sysfs show param. - -return: - Executive outcomes. 0---failed. -*******************************************************/ -static ssize_t goodix_debug_version_show(struct device *dev, - struct device_attribute *attr, char *buf) +static int goodix_input_params_init(struct rk_ts_data *ts) { - int ret = 0; - char *version_info = NULL; - struct goodix_ts_data *ts; - - ts = i2c_get_clientdata(i2c_connect_client); - if(ts==NULL) - return 0; - - ret = goodix_read_version(ts, &version_info); - if(ret <= 0) - { - printk(KERN_INFO"Read version data failed!\n"); - vfree(version_info); - return 0; + int ret ; + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + ret = -ENOMEM; + printk(KERN_ALERT "Failed to allocate input device\n"); + return ret; } - printk(KERN_INFO"Goodix TouchScreen Version:%s\n", (version_info+1)); - sprintf(buf,"Goodix TouchScreen Version:%s\n",(version_info+1)); - vfree(version_info); - ret = strlen(buf); - return ret; -} -/******************************************************* -Description: - Goodix debug sysfs cat resolution function. + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + __set_bit(EV_ABS, ts->input_dev->evbit); -Parameter: - standard sysfs show param. + input_mt_init_slots(ts->input_dev, MAX_SUPPORT_POINT); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); + sprintf(ts->phys, "input/ts"); + ts->input_dev->name = rk_ts_name; + ts->input_dev->phys = ts->phys; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0xDEAD; + ts->input_dev->id.product = 0xBEEF; + ts->input_dev->id.version = 10427; //screen firmware version -return: - Executive outcomes. 0---failed. -*******************************************************/ -static ssize_t goodix_debug_resolution_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct goodix_ts_data *ts; - ts = i2c_get_clientdata(i2c_connect_client); - dev_info(&ts->client->dev,"ABS_X_MAX = %d,ABS_Y_MAX = %d\n",ts->abs_x_max,ts->abs_y_max); - sprintf(buf,"ABS_X_MAX = %d,ABS_Y_MAX = %d\n",ts->abs_x_max,ts->abs_y_max); + ret = input_register_device(ts->input_dev); + if (ret) { + printk(KERN_ALERT "Probe: Unable to register %s input device\n", ts->input_dev->name); + return -1; + } + ts->bad_data = 0; - return strlen(buf); + return 0 ; + } -/******************************************************* -Description: - Goodix debug sysfs cat version function. - -Parameter: - standard sysfs show param. -return: - Executive outcomes. 0---failed. -*******************************************************/ -static ssize_t goodix_debug_diffdata_show(struct device *dev, - struct device_attribute *attr, char *buf) +static int goodix_ts_init(struct rk_ts_data *ts) { - //char diff_data[300]; - unsigned char diff_data[2241] = {00,}; - int ret = -1; - char diff_data_cmd[2] = {80, 202}; - int i; - int short_tmp; - struct goodix_ts_data *ts; - - disable_irq(TS_INT); - - ts = i2c_get_clientdata(i2c_connect_client); - //memset(diff_data, 0, sizeof(diff_data)); - ret = i2c_write_bytes(ts->client, diff_data_cmd, 2); - if(ret != 1) + char retry; + char ret ; + char test_data = 1; + char *version_info = NULL; + for(retry=0;retry < 30; retry++) //test goodix { - dev_info(&ts->client->dev, "Write diff data cmd failed!\n"); - enable_irq(TS_INT); - return 0; + ret =goodix_i2c_write_bytes(ts->client, &test_data, 1); + if (ret > 0) + break; } - - while(gpio_get_value(INT_PORT)); - ret = i2c_read_bytes(ts->client, diff_data, sizeof(diff_data)); - if(ret != 2) + if(ret <= 0) { - dev_info(&ts->client->dev, "Read diff data failed!\n"); - enable_irq(TS_INT); - return 0; + printk(KERN_INFO "I2C communication ERROR!Goodix touchscreen driver become invalid\n"); + return -1; + } + + + ret=goodix_init_panel(ts); + if(ret != 0) { + printk("goodix panel init fail\n"); + ts->bad_data=1; + return -1; } - for(i=1; i>>>>>>max_point %d\n",__func__,ts->max_touch_num); } - - diff_data_cmd[1] = 0; - ret = i2c_write_bytes(ts->client, diff_data_cmd, 2); - if(ret != 1) + ret = goodix_read_version(ts, &version_info); + if(ret <= 0) { - dev_info(&ts->client->dev, "Write diff data cmd failed!\n"); - enable_irq(TS_INT); - return 0; + printk(KERN_INFO"Read version data failed!\n"); } - enable_irq(TS_INT); - /*for (i=0; i<1024; i++) - { - sprintf(buf+strlen(buf)," %d",i); - }*/ - - return strlen(buf); -} - - -/******************************************************* -Description: - Goodix debug sysfs echo calibration function. - -Parameter: - standard sysfs store param. - -return: - Executive outcomes.. -*******************************************************/ -static ssize_t goodix_debug_calibration_store(struct device *dev, - struct device_attribute *attr, const char *buf, ssize_t count) -{ - int ret = -1; - char cal_cmd_buf[] = {110,1}; - struct goodix_ts_data *ts; - - ts = i2c_get_clientdata(i2c_connect_client); - dev_info(&ts->client->dev,"Begin calibration......\n"); - if((*buf == 10)||(*buf == 49)) + else { - ret = i2c_write_bytes(ts->client,cal_cmd_buf,2); - if(ret!=1) - { - dev_info(&ts->client->dev,"Calibration failed!\n"); - return count; - } - else - { - dev_info(&ts->client->dev,"Calibration succeed!\n"); - } + printk(KERN_INFO"Goodix TouchScreen Version:%s>>>max_point:%d\n", (version_info+1),ts->max_touch_num); } - return count; -} - -static DEVICE_ATTR(version, S_IRUGO, goodix_debug_version_show, NULL); -static DEVICE_ATTR(resolution, S_IRUGO, goodix_debug_resolution_show, NULL); -static DEVICE_ATTR(diffdata, S_IRUGO, goodix_debug_diffdata_show, NULL); -static DEVICE_ATTR(calibration, S_IWUSR , NULL, goodix_debug_calibration_store); - - -/******************************************************* -Description: - Goodix debug sysfs init function. - -Parameter: - none. - -return: - Executive outcomes. 0---succeed. -*******************************************************/ -static int goodix_debug_sysfs_init(void) -{ - int ret ; - struct goodix_ts_data *ts; - ts = i2c_get_clientdata(i2c_connect_client); - - goodix_debug_kobj = kobject_create_and_add("goodix_debug", NULL) ; - if (goodix_debug_kobj == NULL) { - printk(KERN_ERR "%s: subsystem_register failed\n", __func__); + vfree(version_info); + #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP + goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL); + if(goodix_proc_entry == NULL) + { + printk("Couldn't create proc entry!\n"); ret = -ENOMEM; - return ret; - } - ret = sysfs_create_file(goodix_debug_kobj, &dev_attr_version.attr); - if (ret) { - printk(KERN_ERR "%s: sysfs_create_version_file failed\n", __func__); - return ret; - } - ret = sysfs_create_file(goodix_debug_kobj, &dev_attr_calibration.attr); - if (ret) { - printk(KERN_ERR "%s: sysfs_create_calibration_file failed\n", __func__); - return ret; + return ret ; } - ret = sysfs_create_file(goodix_debug_kobj, &dev_attr_diffdata.attr); - if (ret) + else { - printk(KERN_ERR "%s: sysfs_create_diffdata_file failed\n", __func__); - return ret; - } - ret = sysfs_create_file(goodix_debug_kobj, &dev_attr_resolution.attr); - if (ret) { - printk(KERN_ERR "%s: sysfs_create_resolution_file failed\n", __func__); - return ret; + printk("Create proc entry success!\n"); + goodix_proc_entry->write_proc = goodix_update_write; + goodix_proc_entry->read_proc = goodix_update_read; + //goodix_proc_entry->owner = THIS_MODULE; } - dev_info(&ts->client->dev,"Goodix debug sysfs create success!\n"); - return 0 ; -} +#endif -static void goodix_debug_sysfs_deinit(void) -{ - sysfs_remove_file(goodix_debug_kobj, &dev_attr_version.attr); - sysfs_remove_file(goodix_debug_kobj, &dev_attr_resolution.attr); - sysfs_remove_file(goodix_debug_kobj, &dev_attr_diffdata.attr); - sysfs_remove_file(goodix_debug_kobj, &dev_attr_calibration.attr); - kobject_del(goodix_debug_kobj); + return 0; } -#endif /******************************************************* Description: Goodix touchscreen probe function. @@ -883,18 +702,13 @@ Parameter: return: Executive outcomes. 0---succeed. *******************************************************/ -static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; - int retry=0; - struct goodix_ts_data *ts; - char *version_info = NULL; - char test_data = 1; + struct rk_ts_data *ts; + struct goodix_platform_data *pdata ; - struct goodix_platform_data *pdata = pdata = client->dev.platform_data; - dev_dbg(&client->dev,"Install touch driver.\n"); - - + printk(KERN_INFO "Install touch driver.\n"); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n"); @@ -902,191 +716,96 @@ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id goto err_check_functionality_failed; } - ts = kzalloc(sizeof(*ts), GFP_KERNEL); + ts = kzalloc(sizeof(struct rk_ts_data), GFP_KERNEL); if (ts == NULL) { + printk(KERN_ALERT "alloc for struct rk_ts_data fail\n"); ret = -ENOMEM; goto err_alloc_data_failed; } + pdata = client->dev.platform_data; + ts->abs_x_max = TS_MAX_X; + ts->abs_y_max = TS_MAX_Y; + ts->irq_pin = pdata->irq_pin; + ts->pendown =PEN_RELEASE; + ts->client = client; + ts->ts_init = goodix_ts_init; + ts->power = goodix_ts_power; + ts->get_touch_info = goodix_get_touch_info; + ts->input_parms_init = goodix_input_params_init; + i2c_set_clientdata(client, ts); + + if (pdata->init_platform_hw) { pdata->init_platform_hw(); } - i2c_connect_client = client; - for(retry=0;retry < 30; retry++) + if(ts->ts_init) { - ret =i2c_write_bytes(client, &test_data, 1); - if (ret > 0) - break; - printk("GOODiX i2c test failed!\n"); + ret = ts->ts_init(ts); + if(ret < 0) + { + printk(KERN_ALERT "rk ts init fail\n"); + //return -1; + } } - if(ret <= 0) + if(ts->input_parms_init) { - dev_err(&client->dev, "I2C communication ERROR!Goodix touchscreen driver become invalid\n"); - goto err_i2c_failed; - } - - INIT_DELAYED_WORK(&ts->work, goodix_ts_work_func); - ts->client = client; - i2c_set_clientdata(client, ts); - pdata = client->dev.platform_data; - - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) { - ret = -ENOMEM; - dev_dbg(&client->dev,"Failed to allocate input device\n"); - goto err_input_dev_alloc_failed; - } -#if 1 - for(retry=0; retry<3; retry++) - { - ret=goodix_init_panel(ts); - msleep(2); - if(ret != 0) - continue; - else - break; - } - if(ret != 0) { - ts->bad_data=1; - goto err_init_godix_ts; + ts->input_parms_init(ts); } -#endif - __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - __set_bit(EV_ABS, ts->input_dev->evbit); - - //ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; - //ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - //ts->input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); // absolute coor (x,y) -#if 0 -#ifdef HAVE_TOUCH_KEY - for(retry = 0; retry < MAX_KEY_NUM; retry++) - { - input_set_capability(ts->input_dev,EV_KEY,touch_key_array[retry]); + i2c_connect_client = client; + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32) + ts->ts_wq= create_rt_workqueue("rk_ts_wq"); //create a work queue and worker thread + #else + ts->ts_wq= create_workqueue("rk_ts_wq"); + #endif + if (!ts->ts_wq){ + printk(KERN_ALERT "creat touch screen workqueue failed\n"); + return -ENOMEM; } -#endif + + INIT_DELAYED_WORK(&ts->ts_work, rk_ts_work_func); +#ifdef CONFIG_HAS_EARLYSUSPEND + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = rk_ts_early_suspend; + ts->early_suspend.resume = rk_ts_late_resume; + register_early_suspend(&ts->early_suspend); #endif - //input_set_abs_params(ts->input_dev, ABS_X, 0, ts->abs_x_max, 0, 0); - //input_set_abs_params(ts->input_dev, ABS_Y, 0, ts->abs_y_max, 0, 0); - //input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0); + -#ifdef GOODIX_MULTI_TOUCH - input_mt_init_slots(ts->input_dev, MAX_SUPPORT_POINT); - //input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); - //input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, ts->max_touch_num, 0, 0); - //input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); -#endif - - sprintf(ts->phys, "input/ts"); - ts->input_dev->name = goodix_ts_name; - ts->input_dev->phys = ts->phys; - ts->input_dev->id.bustype = BUS_I2C; - ts->input_dev->id.vendor = 0xDEAD; - ts->input_dev->id.product = 0xBEEF; - ts->input_dev->id.version = 10427; //screen firmware version - - ret = input_register_device(ts->input_dev); - if (ret) { - dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name); - goto err_input_register_device_failed; - } - ts->bad_data = 0; -#ifdef INT_PORT - client->irq=TS_INT; //If not defined in client - if (client->irq) + ts->irq=gpio_to_irq(ts->irq_pin) ; //If not defined in client + if (ts->irq) { - ret = gpio_request(INT_PORT, "TS_INT"); //Request IO + ret = gpio_request(pdata->irq_pin, "TS_IRQ_PIN"); //Request IO if (ret < 0) { - dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)INT_PORT,ret); + printk(KERN_ALERT "Failed to request for touch irq\n"); goto err_gpio_request_failed; } - // s3c_gpio_setpull(INT_PORT, S3C_GPIO_PULL_UP); //ret > 0 ? - // s3c_gpio_cfgpin(INT_PORT, INT_CFG); //Set IO port function - // printk("irq is %d\n",irq_table[ts->int_trigger_type]);//add by fjp 2010-9-28 - ret = request_irq(client->irq, goodix_ts_irq_handler , /* irq_table[ts->int_trigger_type]*/IRQ_TYPE_LEVEL_LOW, - client->name, ts); + else + { + gpio_direction_input(pdata->irq_pin); + } + + ret = request_irq(ts->irq, rk_ts_irq_handler ,IRQ_TYPE_LEVEL_LOW,client->name, ts); if (ret != 0) { - dev_err(&client->dev,"Cannot allocate ts INT!ERRNO:%d\n", ret); - gpio_direction_input(INT_PORT); + printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", ret); gpio_free(INT_PORT); goto err_gpio_request_failed; } else { - disable_irq(client->irq); - ts->use_irq = 1; - dev_dbg(&client->dev,"Reques EIRQ %d succesd on GPIO:%d\n",TS_INT,INT_PORT); + enable_irq(ts->irq); + } } -#endif - if (!ts->use_irq) - { - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ts->timer.function = goodix_ts_timer_func; - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } - -#if defined(INT_PORT) - if(ts->use_irq) - ts->power = goodix_ts_power; -#endif - -#if 1 - ret = goodix_read_version(ts, &version_info); - if(ret <= 0) - { - printk(KERN_INFO"Read version data failed!\n"); - } - else - { - printk(KERN_INFO"Goodix TouchScreen Version:%s\n", (version_info+1)); - } - vfree(version_info); -#endif - -#ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = goodix_ts_early_suspend; - ts->early_suspend.resume = goodix_ts_late_resume; - register_early_suspend(&ts->early_suspend); -#endif -#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP - goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL); - if(goodix_proc_entry == NULL) - { - dev_info(&client->dev, "Couldn't create proc entry!\n"); - ret = -ENOMEM; - goto err_create_proc_entry; - } - else - { - dev_info(&client->dev, "Create proc entry success!\n"); - printk("Create proc entry success!\n"); - goodix_proc_entry->write_proc = goodix_update_write; - goodix_proc_entry->read_proc = goodix_update_read; - //goodix_proc_entry->owner = THIS_MODULE; - } -#endif - ts->pendown =PEN_RELEASE; -#if 0 - goodix_debug_sysfs_init(); - dev_info(&client->dev,"Start %s in %s mode\n", - ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); - dev_info(&client->dev, "Driver Modify Date:2011-06-13\n"); -#endif - - if(ts->use_irq) - enable_irq(client->irq); - printk("Goodix TS probe successfully!\n"); + printk("Goodix TS probe successfully! max_x:%d>>max_y:%d>>max_support_point:%d\n", + ts->abs_x_max,ts->abs_y_max,ts->max_touch_num); return 0; err_init_godix_ts: if(ts->use_irq) @@ -1126,9 +845,9 @@ Parameter: return: Executive outcomes. 0---succeed. *******************************************************/ -static int goodix_ts_remove(struct i2c_client *client) +static int rk_ts_remove(struct i2c_client *client) { - struct goodix_ts_data *ts = i2c_get_clientdata(client); + struct rk_ts_data *ts = i2c_get_clientdata(client); #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&ts->early_suspend); #endif @@ -1154,62 +873,7 @@ static int goodix_ts_remove(struct i2c_client *client) return 0; } -static int goodix_ts_suspend(struct i2c_client *client, pm_message_t mesg) -{ - int ret; - struct goodix_ts_data *ts = i2c_get_clientdata(client); - - if (ts->use_irq) - disable_irq(client->irq); - else - hrtimer_cancel(&ts->timer); -#if 1 - if (ts->power) { - ret = ts->power(ts, 0); - if (ret < 0) - printk(KERN_ERR "goodix_ts_resume power off failed\n"); - } -#endif - return 0; -} - -static int goodix_ts_resume(struct i2c_client *client) -{ - int ret; - struct goodix_ts_data *ts = i2c_get_clientdata(client); - -#if 1 - if (ts->power) { - ret = ts->power(ts, 1); - if (ret < 0) - printk(KERN_ERR "goodix_ts_resume power on failed\n"); - } -#endif - if (ts->use_irq) - enable_irq(client->irq); - else - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - //gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH); - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void goodix_ts_early_suspend(struct early_suspend *h) -{ - struct goodix_ts_data *ts; - ts = container_of(h, struct goodix_ts_data, early_suspend); - goodix_ts_suspend(ts->client, PMSG_SUSPEND); -} - -static void goodix_ts_late_resume(struct early_suspend *h) -{ - struct goodix_ts_data *ts; - ts = container_of(h, struct goodix_ts_data, early_suspend); - goodix_ts_resume(ts->client); -} -#endif //******************************Begin of firmware update surpport******************************* #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP @@ -1371,13 +1035,13 @@ static int update_file_check(char * path) return 1; } -unsigned char wait_slave_ready(struct goodix_ts_data *ts, unsigned short *timeout) +unsigned char wait_slave_ready(struct rk_ts_data *ts, unsigned short *timeout) { unsigned char i2c_state_buf[2] = {ADDR_STA, UNKNOWN_ERROR}; int ret; while(*timeout < MAX_TIMEOUT) { - ret = i2c_read_bytes(ts->client, i2c_state_buf, 2); + ret = goodix_i2c_read_bytes(ts->client, i2c_state_buf, 2); if(ret <= 0) return ERROR_I2C_TRANSFER; if(i2c_state_buf[1] & SLAVE_READY) @@ -1420,7 +1084,7 @@ static int goodix_update_write(struct file *filp, const char __user *buff, unsig struct file * file_data = NULL; mm_segment_t old_fs; - struct goodix_ts_data *ts; + struct rk_ts_data *ts; ts = i2c_get_clientdata(i2c_connect_client); if(ts==NULL) @@ -1454,7 +1118,7 @@ static int goodix_update_write(struct file *filp, const char __user *buff, unsig case STEP_WRITE_SYN: printk(KERN_INFO"STEP1:Write synchronization signal!\n"); i2c_control_buf[1] = UPDATE_START; - ret = i2c_write_bytes(ts->client, i2c_control_buf, 2); + ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); if(ret <= 0) { ret = ERROR_I2C_TRANSFER; @@ -1468,7 +1132,7 @@ static int goodix_update_write(struct file *filp, const char __user *buff, unsig while(retries < MAX_I2C_RETRIES) { i2c_states_buf[1] = UNKNOWN_ERROR; - ret = i2c_read_bytes(ts->client, i2c_states_buf, 2); + ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2); printk(KERN_INFO"The read byte is:%d\n", i2c_states_buf[1]); if(i2c_states_buf[1] & UPDATE_START) { @@ -1509,7 +1173,7 @@ static int goodix_update_write(struct file *filp, const char __user *buff, unsig i2c_data_buf[3] = (file_len>>8) & 0xff; i2c_data_buf[4] = file_len & 0xff; file_len -= 4; - ret = i2c_write_bytes(ts->client, i2c_data_buf, 5); + ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 5); if(ret <= 0) { ret = ERROR_I2C_TRANSFER; @@ -1567,7 +1231,7 @@ static int goodix_update_write(struct file *filp, const char __user *buff, unsig } rewrite: printk(KERN_INFO"[GOODiX_ISP_NEW]:%d\n", file_len); - ret = i2c_write_bytes(ts->client, i2c_data_buf, 1+4+rd_len+4); + ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 1+4+rd_len+4); //if(ret <= 0) if(ret != 1) { @@ -1576,7 +1240,7 @@ rewrite: } memset(i2c_rd_buf, 0x00, 1+4+rd_len+4); - ret = i2c_read_bytes(ts->client, i2c_rd_buf, 1+4+rd_len+4); + ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, 1+4+rd_len+4); if(ret != 2) { printk("[GOODiX_ISP_NEW]:Read File Data Failed!Return:%d\n", ret); @@ -1594,13 +1258,13 @@ rewrite: { i2c_control_buf[0] = ADDR_CMD; i2c_control_buf[1] = 0x03; - i2c_write_bytes(ts->client, i2c_control_buf, 2); //communication error + goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); //communication error printk("[GOODiX_ISP_NEW]:File Data Frame readback check Error!\n"); } else { i2c_control_buf[1] = 0x04; //let LDROM write flash - i2c_write_bytes(ts->client, i2c_control_buf, 2); + goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); } //Wait for slave ready signal.and read the checksum @@ -1665,7 +1329,7 @@ rewrite: i2c_data_buf[file_len+2] = (oldcrc32>>8)&0xff; i2c_data_buf[file_len+3] = (oldcrc32>>16)&0xff; i2c_data_buf[file_len+4] = (oldcrc32>>24)&0xff; - ret = i2c_write_bytes(ts->client, i2c_data_buf, (file_len+1+4)); + ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, (file_len+1+4)); //if(ret <= 0) if(ret != 1) { @@ -1676,7 +1340,7 @@ rewrite: } else { - ret = i2c_write_bytes(ts->client, i2c_data_buf, PACK_SIZE+1); + ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, PACK_SIZE+1); //if(ret <= 0) if(ret != 1) { @@ -1702,7 +1366,7 @@ rewrite: printk(KERN_INFO"STEP6:Read update status!\n"); while(time_count < MAX_TIMEOUT) { - ret = i2c_read_bytes(ts->client, i2c_states_buf, 2); + ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2); if(ret <= 0) { return 0; @@ -1755,7 +1419,7 @@ rewrite: printk(KERN_INFO"Read raw data!\n"); ts->read_mode = MODE_RD_RAW; i2c_control_buf[1] = 201; - ret = i2c_write_bytes(ts->client, i2c_control_buf, 2); //read raw data cmd + ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); //read raw data cmd if(ret <= 0) { printk(KERN_INFO"Write read raw data cmd failed!\n"); @@ -1768,7 +1432,7 @@ rewrite: printk(KERN_INFO"Read diff data!\n"); ts->read_mode = MODE_RD_DIF; i2c_control_buf[1] = 202; - ret = i2c_write_bytes(ts->client, i2c_control_buf, 2); //read diff data cmd + ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); //read diff data cmd if(ret <= 0) { printk(KERN_INFO"Write read raw data cmd failed!\n"); @@ -1805,7 +1469,7 @@ rewrite: { checksum_error_times = 0; reconfig: - ret = i2c_write_bytes(ts->client, cmd+2, cmd[1]); + ret = goodix_i2c_write_bytes(ts->client, cmd+2, cmd[1]); if(ret != 1) { printk("Write Config failed!return:%d\n",ret); @@ -1814,7 +1478,7 @@ reconfig: if(!update_need_config)return 1; i2c_rd_buf[0] = cmd[2]; - ret = i2c_read_bytes(ts->client, i2c_rd_buf, cmd[1]); + ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, cmd[1]); if(ret != 2) { printk("Read Config failed!return:%d\n",ret); @@ -1833,7 +1497,7 @@ reconfig: { i2c_control_buf[0] = ADDR_CMD; i2c_control_buf[1] = 0x03; - i2c_write_bytes(ts->client, i2c_control_buf, 2); //communication error + goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); //communication error checksum_error_times++; msleep(20); if(checksum_error_times > 20) //max retry times. @@ -1844,7 +1508,7 @@ reconfig: { i2c_control_buf[0] = ADDR_CMD; i2c_control_buf[1] = 0x04; //let LDROM write flash - i2c_write_bytes(ts->client, i2c_control_buf, 2); + goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2); return 1; } @@ -1863,7 +1527,7 @@ reconfig: static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data ) { int ret = -1; - struct goodix_ts_data *ts; + struct rk_ts_data *ts; int len = 0; char *version_info = NULL; unsigned char read_data[1201] = {80, }; @@ -1896,7 +1560,7 @@ static int goodix_update_read( char *page, char **start, off_t off, int count, i else if((ts->read_mode == MODE_RD_RAW)||(ts->read_mode == MODE_RD_DIF)) //read raw data or diff { //printk(KERN_INFO"Read raw data\n"); - ret = i2c_read_bytes(ts->client, read_data, 1201); + ret = goodix_i2c_read_bytes(ts->client, read_data, 1201); if(ret <= 0) { if(ts->read_mode == 2) @@ -1928,7 +1592,7 @@ static int goodix_update_read( char *page, char **start, off_t off, int count, i rd_cfg_len = 239 - read_data[0]; } printk("read config length is:%d\n", rd_cfg_len); - ret = i2c_read_bytes(ts->client, read_data, rd_cfg_len); + ret = goodix_i2c_read_bytes(ts->client, read_data, rd_cfg_len); if(ret <= 0) { printk(KERN_INFO"Read config info failed!\n"); @@ -1947,12 +1611,12 @@ static const struct i2c_device_id goodix_ts_id[] = { { } }; -static struct i2c_driver goodix_ts_driver = { - .probe = goodix_ts_probe, - .remove = goodix_ts_remove, +static struct i2c_driver rk_ts_driver = { + .probe = rk_ts_probe, + .remove = rk_ts_remove, #ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = goodix_ts_suspend, - .resume = goodix_ts_resume, + .suspend = rk_ts_suspend, + .resume = rk_ts_resume, #endif .id_table = goodix_ts_id, .driver = { @@ -1967,20 +1631,10 @@ Description: return: Executive Outcomes. 0---succeed. ********************************************************/ -static int __devinit goodix_ts_init(void) +static int __devinit rk_ts_init(void) { - int ret; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) - goodix_wq = create_rt_workqueue("goodix_wq"); //create a work queue and worker thread -#else - goodix_wq = create_workqueue("goodix_touch_wq"); -#endif - if (!goodix_wq) { - printk(KERN_ALERT "creat workqueue faiked\n"); - return -ENOMEM; - - } - ret=i2c_add_driver(&goodix_ts_driver); + int ret ; + ret=i2c_add_driver(&rk_ts_driver); return ret; } @@ -1990,16 +1644,14 @@ Description: return: Executive Outcomes. 0---succeed. ********************************************************/ -static void __exit goodix_ts_exit(void) +static void __exit rk_ts_exit(void) { printk(KERN_ALERT "Touchscreen driver of guitar exited.\n"); - i2c_del_driver(&goodix_ts_driver); - if (goodix_wq) - destroy_workqueue(goodix_wq); //release our work queue + i2c_del_driver(&rk_ts_driver); } -module_init(goodix_ts_init); -module_exit(goodix_ts_exit); +module_init(rk_ts_init); +module_exit(rk_ts_exit); MODULE_DESCRIPTION("Goodix Touchscreen Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/rk29_i2c_goodix.h b/drivers/input/touchscreen/rk29_i2c_goodix.h index a5d13f876623..7edbe7c7da2b 100755 --- a/drivers/input/touchscreen/rk29_i2c_goodix.h +++ b/drivers/input/touchscreen/rk29_i2c_goodix.h @@ -26,15 +26,11 @@ //*************************TouchScreen Work Part***************************** #define GOODIX_I2C_NAME "Goodix-TS" -#define GOODIX_1024X768 -#ifdef GOODIX_1024X768 -#define TOUCH_MAX_HEIGHT 1024 -#define TOUCH_MAX_WIDTH 768 -#else -//define resolution of the touchscreen -#define TOUCH_MAX_HEIGHT 1280 -#define TOUCH_MAX_WIDTH 800 -#endif +#define GOODIX_1024X768 1 + +#define TS_MAX_X 1024 +#define TS_MAX_Y 768 + #if 1 #define INT_PORT RK29_PIN0_PA2 #ifdef INT_PORT @@ -63,6 +59,41 @@ //#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) +struct rk_touch_info +{ + u32 status; // 1:down,0:up + u32 x ; + u32 y ; +} ; +struct rk_ts_data{ + uint16_t addr; + uint8_t bad_data; + struct i2c_client *client; + struct input_dev *input_dev; + int use_reset; //use RESET flag + int use_irq; //use EINT flag + int irq; + int irq_pin; + int read_mode; //read moudle mode,20110221 by andrew + struct hrtimer timer; + struct workqueue_struct *ts_wq; + struct delayed_work ts_work; + char phys[32]; + int retry; + 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; + uint8_t int_trigger_type; + bool pendown; +}; + + + struct goodix_ts_data { uint16_t addr; uint8_t bad_data; @@ -84,7 +115,7 @@ struct goodix_ts_data { bool pendown; }; -static const char *goodix_ts_name = "Goodix Capacitive TouchScreen"; +static const char *rk_ts_name = "Goodix Capacitive TouchScreen"; static struct workqueue_struct *goodix_wq; struct i2c_client * i2c_connect_client = NULL; static struct proc_dir_entry *goodix_proc_entry;