1 /* drivers/input/touchscreen/gt811.c
\r
3 * Copyright (C) 2010 - 2011 Goodix, Inc.
\r
5 * This program is free software; you can redistribute it and/or modify
\r
6 * it under the terms of the GNU General Public License as published by
\r
7 * the Free Software Foundation; either version 2 of the License, or
\r
8 * (at your option) any later version.
\r
10 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
15 *Any problem,please contact andrew@goodix.com,+86 755-33338828
\r
19 #include <linux/kernel.h>
\r
20 #include <linux/module.h>
\r
21 #include <linux/time.h>
\r
22 #include <linux/delay.h>
\r
23 #include <linux/device.h>
\r
24 #include <linux/earlysuspend.h>
\r
25 #include <linux/hrtimer.h>
\r
26 #include <linux/i2c.h>
\r
27 #include <linux/input.h>
\r
28 #include <linux/interrupt.h>
\r
29 #include <linux/io.h>
\r
30 #include <linux/platform_device.h>
\r
31 #include <mach/gpio.h>
\r
32 //#include <plat/gpio-cfg.h>
\r
33 //#include <plat/gpio-bank-l.h>
\r
34 //#include <plat/gpio-bank-f.h>
\r
35 #include <linux/irq.h>
\r
36 #include <linux/syscalls.h>
\r
37 #include <linux/reboot.h>
\r
38 #include <linux/proc_fs.h>
\r
39 #include "86v_gt811_ts.h"
\r
40 #include "gt811_firmware.h"
\r
42 #include <linux/vmalloc.h>
\r
43 #include <linux/fs.h>
\r
44 #include <linux/string.h>
\r
45 #include <linux/completion.h>
\r
46 #include <asm/uaccess.h>
\r
47 #include <linux/input/mt.h>
\r
48 #include <mach/iomux.h>
\r
50 static struct workqueue_struct *goodix_wq;
\r
51 static const char *s3c_ts_name = "gt811_ts";
\r
52 //static struct point_queue finger_list;
\r
53 struct i2c_client * i2c_connect_client = NULL;
\r
54 //EXPORT_SYMBOL(i2c_connect_client);
\r
55 static struct proc_dir_entry *goodix_proc_entry;
\r
56 static short goodix_read_version(struct gt811_ts_data *ts);
\r
57 //static int tpd_button(struct gt811_ts_data *ts, unsigned int x, unsigned int y, unsigned int down);
\r
59 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
60 static void goodix_ts_early_suspend(struct early_suspend *h);
\r
61 static void goodix_ts_late_resume(struct early_suspend *h);
\r
62 int gt811_downloader( struct gt811_ts_data *ts, unsigned char * data);
\r
64 //used by firmware update CRC
\r
65 unsigned int oldcrc32 = 0xFFFFFFFF;
\r
66 unsigned int crc32_table[256];
\r
67 unsigned int ulPolynomial = 0x04c11db7;
\r
69 unsigned int raw_data_ready = RAW_DATA_NON_ACTIVE;
\r
73 int access_count = 0;
\r
76 #define HAVE_TOUCH_KEY
\r
77 //#define READ_KEY_VALUE
\r
78 //#define READ_KEY_COOR
\r
80 #ifdef HAVE_TOUCH_KEY
\r
81 const uint16_t touch_key_array[]={
\r
87 #define MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0]))
\r
90 /*******************************************************
\r
92 Read data from the slave
\r
93 Each read operation with two i2c_msg composition, for the first message sent from the machine address,
\r
94 Article 2 reads the address used to send and retrieve data; each message sent before the start signal
\r
96 client: i2c devices, including device address
\r
97 buf [0]: The first byte to read Address
\r
98 buf [1] ~ buf [len]: data buffer
\r
99 len: the length of read data
\r
102 *********************************************************/
\r
103 /*Function as i2c_master_send */
\r
104 static int i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len)
\r
106 struct i2c_msg msgs[2];
\r
109 msgs[0].flags=!I2C_M_RD;
\r
110 msgs[0].addr=client->addr;
\r
112 msgs[0].buf=&buf[0];
\r
113 msgs[0].scl_rate=200000;
\r
115 msgs[1].flags=I2C_M_RD;
\r
116 msgs[1].addr=client->addr;
\r
118 msgs[1].buf=&buf[2];
\r
119 msgs[1].scl_rate=200000;
\r
121 ret=i2c_transfer(client->adapter,msgs, 2);
\r
125 /*******************************************************
\r
127 Write data to a slave
\r
129 client: i2c devices, including device address
\r
130 buf [0]: The first byte of the write address
\r
131 buf [1] ~ buf [len]: data buffer
\r
135 *******************************************************/
\r
136 /*Function as i2c_master_send */
\r
137 static int i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len)
\r
139 struct i2c_msg msg;
\r
142 msg.flags=!I2C_M_RD;//å
\86\99æ¶
\88æ
\81? msg.addr=client->addr;
\r
145 msg.scl_rate=200000;
\r
146 msg.addr=client->addr;
\r
148 ret=i2c_transfer(client->adapter,&msg, 1);
\r
152 /*******************************************************
\r
154 Send a prefix command
\r
157 ts: client private data structure
\r
160 Results of the implementation code, 0 for normal execution
\r
161 *******************************************************/
\r
162 static int i2c_pre_cmd(struct gt811_ts_data *ts)
\r
165 uint8_t pre_cmd_data[2]={0};
\r
166 pre_cmd_data[0]=0x0f;
\r
167 pre_cmd_data[1]=0xff;
\r
168 ret=i2c_write_bytes(ts->client,pre_cmd_data,2);
\r
173 /*******************************************************
\r
175 Send a suffix command
\r
178 ts: client private data structure
\r
181 Results of the implementation code, 0 for normal execution
\r
182 *******************************************************/
\r
183 static int i2c_end_cmd(struct gt811_ts_data *ts)
\r
186 uint8_t end_cmd_data[2]={0};
\r
187 end_cmd_data[0]=0x80;
\r
188 end_cmd_data[1]=0x00;
\r
189 ret=i2c_write_bytes(ts->client,end_cmd_data,2);
\r
194 /********************************************************************
\r
196 *********************************************************************/
\r
198 static int list_key(s32 x_value, s32 y_value, u8* key)
\r
203 if (y_value <= AREA_Y)
\r
205 if (x_value <= AREA_X)
\r
211 for (i = 0; i < MAX_KEY_NUM; i++)
\r
213 if (abs(key_center[i][x] - x_value) < KEY_X
\r
214 && abs(key_center[i][y] - y_value) < KEY_Y)
\r
216 (*key) |= (0x01<<i);
\r
224 /*******************************************************
\r
226 Guitar initialization function, used to send configuration information, access to version information
\r
228 ts: client private data structure
\r
230 Results of the implementation code, 0 for normal execution
\r
231 *******************************************************/
\r
232 static int goodix_init_panel(struct gt811_ts_data *ts)
\r
235 uint8_t config_info[] = {
\r
238 0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x60,0x00,0x50,0x00,0x40,0x00,
\r
239 0x30,0x00,0x20,0x00,0x10,0x00,0x00,0x00,0x70,0x00,0x80,0x00,0x90,0x00,0xA0,0x00,
\r
240 0xB0,0x00,0xC0,0x00,0xD0,0x00,0xE0,0x00,0xF0,0x00,0x05,0x03,0x90,0x90,0x90,0x30,
\r
241 0x30,0x30,0x0F,0x0F,0x0A,0x50,0x3C,0x08,0x03,0x3C,0x05,0x00,0x14,0x00,0x20,0x04,
\r
242 0x04,0x64,0x5A,0x40,0x40,0x00,0x00,0x03,0x19,0x00,0x05,0x00,0x00,0x00,0x00,0x00,
\r
243 0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x50,
\r
244 0x3C,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x01
\r
246 /* 0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x13,0x33,0x23,0x33,0x33,0x33,
\r
247 0x43,0x33,0x53,0x33,0x63,0x33,0x73,0x33,0x83,0x33,0x93,0x33,0xA3,0x33,0xB3,0x33,
\r
248 0xC3,0x33,0xD3,0x33,0xE3,0x33,0xF3,0x33,0x03,0x33,0x3B,0x03,0x88,0x88,0x88,0x1B,
\r
249 0x1B,0x1B,0x0F,0x0F,0x0A,0x40,0x30,0x0F,0x03,0x00,0x05,0x00,0x14,0x00,0x1E,0x04,
\r
250 0x04,0x64,0x5A,0x40,0x40,0x00,0x00,0x05,0x19,0x05,0x05,0x00,0x00,0x00,0x00,0x00,
\r
251 0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x50,
\r
252 0x3C,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x01
\r
255 /* 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,
\r
256 0x02,0x22,0x12,0x22,0x22,0x22,0x32,0x22,0x42,0x22,
\r
257 0x52,0x22,0x62,0x22,0x72,0x22,0x82,0x22,0x92,0x22,
\r
258 0xA2,0x22,0xB2,0x22,0xC2,0x22,0xD2,0x22,0xE2,0x22,
\r
259 0xF2,0x22,0x1B,0x03,0x88,0x88,0x88,0x1D,0x1D,0x1D,
\r
260 0x10,0x0F,0x0A,0x47,0x2A,0x0D,0x03,0x00,0x05,0x00,
\r
261 0x03,0x00,0x04,0x00,0x00,0x38,0x33,0x35,0x30,0x00,
\r
262 0x00,0x07,0x20,0x05,0x05,0x00,0x00,0x00,0x00,0x00,
\r
263 0x32,0x16,0x80,0x03,0x00,0x40,0x17,0x88,0x1B,0x00,
\r
264 0x71,0x80,0x90,0xA0,0x0A,0x45,0x30,0x20,0x14,0x00,
\r
265 0x00,0x00,0x00,0x00,0x00,0x01*/
\r
267 /* 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,
\r
268 0x52,0x22,0x62,0x22,0x72,0x22,0x82,0x22,0x92,0x22,
\r
269 0xA2,0x22,0xB2,0x22,0xC2,0x22,0xD2,0x22,0xE2,0x22,
\r
270 0xF2,0x22,0x02,0x22,0x12,0x22,0x22,0x22,0x32,0x22,
\r
271 0x42,0x22,0x07,0x03,0x88,0x88,0x88,0x27,0x27,0x27,
\r
272 0x0B,0x0A,0x09,0x40,0x30,0x01,0x03,0x00,0x05,0xE0,
\r
273 0x01,0x20,0x03,0x00,0x00,0xFF,0xFF,0x42,0x2B,0x00,
\r
274 0x00,0x23,0x14,0x05,0x06,0x00,0x00,0x00,0x00,0x00,
\r
275 0x14,0x10,0xC6,0x02,0x00,0x40,0x17,0x88,0x20,0x00,
\r
276 0x60,0x70,0x80,0x90,0x0D,0x40,0x30,0x25,0x20,0x00,
\r
277 0x00,0x00,0x00,0x00,0x00,0x01*/
\r
278 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,
\r
279 0x02,0x22,0x12,0x22,0x22,0x22,0x32,0x22,0x42,0x22,
\r
280 0x52,0x22,0x62,0x22,0x72,0x22,0x83,0x22,0x92,0x22,
\r
281 0xA2,0x22,0xB2,0x22,0xC2,0x22,0xD2,0x22,0xE2,0x22,
\r
282 0xF2,0x22,0x1B,0x03,0x28,0x28,0x28,0x20,0x20,0x20,
\r
283 0x0F,0x0F,0x0A,0x45,0x30,0x04,0x03,0x00,0x05,0xE0,
\r
284 0x01,0x20,0x03,0x00,0x00,0x38,0x33,0x35,0x30,0x00,
\r
285 0x00,0x26,0x14,0x02,0x0A,0x00,0x00,0x00,0x00,0x00,
\r
286 0x14,0x10,0x30,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
\r
287 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
\r
288 0x00,0x00,0x00,0x00,0x00,0x01
\r
292 config_info[62] = TOUCH_MAX_WIDTH >> 8;
\r
293 config_info[61] = TOUCH_MAX_WIDTH & 0xff;
\r
294 config_info[64] = TOUCH_MAX_HEIGHT >> 8;
\r
295 config_info[63] = TOUCH_MAX_HEIGHT & 0xff;
\r
297 ret = i2c_write_bytes(ts->client, config_info, sizeof(config_info)/sizeof(config_info[0]));
\r
300 dev_info(&ts->client->dev, "GT811 Send config failed!\n");
\r
303 ts->abs_y_max = (config_info[62]<<8) + config_info[61];
\r
304 ts->abs_x_max = (config_info[64]<<8) + config_info[63];
\r
305 ts->max_touch_num = config_info[60];
\r
306 ts->int_trigger_type = ((config_info[57]>>3)&0x01);
\r
307 dev_info(&ts->client->dev, "GT811 init info:X_MAX=%d,Y_MAX=%d,TRIG_MODE=%s\n",
\r
308 ts->abs_x_max, ts->abs_y_max, ts->int_trigger_type?"RISING EDGE":"FALLING EDGE");
\r
313 /*******************************************************
\r
315 Read gt811 IC Version
\r
321 *******************************************************/
\r
322 static short goodix_read_version(struct gt811_ts_data *ts)
\r
325 uint8_t version_data[5]={0x07,0x17,0,0}; //store touchscreen version infomation
\r
326 uint8_t version_data2[5]={0x07,0x17,0,0}; //store touchscreen version infomation
\r
330 memset(version_data, 0, 5);
\r
331 version_data[0]=0x07;
\r
332 version_data[1]=0x17;
\r
334 ret=i2c_read_bytes(ts->client, version_data, 4);
\r
338 for(i = 0;i < 10;i++)
\r
340 i2c_read_bytes(ts->client, version_data2, 4);
\r
341 if((version_data[2] !=version_data2[2])||(version_data[3] != version_data2[3]))
\r
343 version_data[2] = version_data2[2];
\r
344 version_data[3] = version_data2[3];
\r
354 ts->version = (version_data[2]<<8)+version_data[3];
\r
355 dev_info(&ts->client->dev, "GT811 Verion:0x%04x\n", ts->version);
\r
360 dev_info(&ts->client->dev," Guitar Version Read Error: %d.%d\n",version_data[3],version_data[2]);
\r
361 ts->version = 0xffff;
\r
368 /******************start add by kuuga*******************/
\r
369 static void gt811_irq_enable(struct gt811_ts_data *ts)
\r
371 unsigned long irqflags;
\r
372 spin_lock_irqsave(&ts->irq_lock, irqflags);
\r
373 if (ts->irq_is_disable)
\r
375 enable_irq(ts->irq);
\r
376 ts->irq_is_disable = 0;
\r
378 spin_unlock_irqrestore(&ts->irq_lock, irqflags);
\r
381 static void gt811_irq_disable(struct gt811_ts_data *ts)
\r
383 unsigned long irqflags;
\r
384 spin_lock_irqsave(&ts->irq_lock, irqflags);
\r
385 if (!ts->irq_is_disable)
\r
387 disable_irq_nosync(ts->irq);
\r
388 ts->irq_is_disable = 1;
\r
390 spin_unlock_irqrestore(&ts->irq_lock, irqflags);
\r
393 /*****************end add by kuuga****************/
\r
395 /*******************************************************
\r
397 Touch-screen work function
\r
398 Triggered by the interruption, to accept a set of coordinate data,
\r
399 and then analyze the output parity
\r
401 ts: client private data structure
\r
403 Results of the implementation code, 0 for normal execution
\r
404 ********************************************************/
\r
405 static void goodix_ts_work_func(struct work_struct *work)
\r
407 uint8_t point_data[READ_BYTES_NUM] = {READ_TOUCH_ADDR_H,READ_TOUCH_ADDR_L,0};//point_data[8*MAX_FINGER_NUM+2]={ 0 };
\r
408 uint8_t check_sum = 0;
\r
409 uint8_t read_position = 0;
\r
410 uint8_t track_id[MAX_FINGER_NUM];
\r
411 uint8_t point_index = 0;
\r
412 uint8_t point_tmp = 0;
\r
413 uint8_t point_count = 0;
\r
414 uint16_t input_x = 0;
\r
415 uint16_t input_y = 0;
\r
416 uint8_t input_w = 0;
\r
417 static uint8_t last_key = 0;
\r
418 uint8_t finger = 0;
\r
420 unsigned int count = 0;
\r
421 unsigned int position = 0;
\r
425 struct gt811_ts_data *ts = container_of(work, struct gt811_ts_data, work);
\r
427 printk("int count :%d\n", ++int_count);
\r
428 printk("ready?:%d\n", raw_data_ready);
\r
430 if (RAW_DATA_ACTIVE == raw_data_ready)
\r
432 raw_data_ready = RAW_DATA_READY;
\r
434 printk("ready!\n");
\r
443 dev_info(&(ts->client->dev), "Because of transfer error,touchscreen stop working.\n");
\r
447 ret=i2c_read_bytes(ts->client, point_data, sizeof(point_data)/sizeof(point_data[0]));
\r
450 dev_err(&(ts->client->dev),"I2C transfer error. Number:%d\n ", ret);
\r
455 goto COORDINATE_POLL;
\r
461 for(count=0;count<(sizeof(point_data)/sizeof(point_data[0])); count++)
\r
463 printk("[%2d]:0x%2x", count, point_data[count]);
\r
464 if((count+1)%10==0)printk("\n");
\r
468 if(point_data[2]&0x20)
\r
470 if(point_data[3]==0xF0)
\r
472 gpio_direction_output(SHUTDOWN_PORT, 0);
\r
474 // gpio_direction_input(SHUTDOWN_PORT);
\r
475 gpio_set_value(SHUTDOWN_PORT,0);
\r
477 gpio_set_value(SHUTDOWN_PORT,1);
\r
480 goodix_init_panel(ts);
\r
481 goto WORK_FUNC_END;
\r
484 switch(point_data[2]& 0x1f)
\r
488 for(count=2; count<9; count++)
\r
489 check_sum += (int)point_data[count];
\r
494 for(count=2; count<14;count++)
\r
495 check_sum += (int)point_data[count];
\r
496 read_position = 14;
\r
498 default: //touch finger larger than 3
\r
499 for(count=2; count<35;count++)
\r
500 check_sum += (int)point_data[count];
\r
501 read_position = 35;
\r
503 if(check_sum != point_data[read_position])
\r
505 dev_info(&ts->client->dev, "coor chksum error!\n");
\r
509 point_index = point_data[2]&0x1f;
\r
510 point_tmp = point_index;
\r
511 for(position=0; (position<MAX_FINGER_NUM)&&point_tmp; position++)
\r
515 track_id[point_count++] = position;
\r
519 finger = point_count;
\r
522 for(count=0; count<finger; count++)
\r
524 if(track_id[count]!=3)
\r
526 if(track_id[count]<3)
\r
527 position = 4+track_id[count]*5;
\r
530 input_x = (uint16_t)(point_data[position]<<8)+(uint16_t)point_data[position+1];
\r
531 input_y = (uint16_t)(point_data[position+2]<<8)+(uint16_t)point_data[position+3];
\r
532 input_w = point_data[position+4];
\r
536 input_x = (uint16_t)(point_data[19]<<8)+(uint16_t)point_data[26];
\r
537 input_y = (uint16_t)(point_data[27]<<8)+(uint16_t)point_data[28];
\r
538 input_w = point_data[29];
\r
541 //printk("real_input_y = %d,real_input_y = %d,TOUCH_MAX_HEIGHT=%d,TOUCH_MAX_WIDTH=%d,input_x=%d,input_y=%d,input_w=%d\n",input_x,input_y, TOUCH_MAX_HEIGHT,TOUCH_MAX_WIDTH,input_y,TOUCH_MAX_WIDTH-input_x, input_w);
\r
542 //if((input_y > ts->abs_x_max)||(TOUCH_MAX_WIDTH-input_x > ts->abs_y_max))continue;
\r
543 input_mt_slot(ts->input_dev, track_id[count]);
\r
544 //input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
\r
545 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
\r
548 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_y);
\r
549 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, TOUCH_MAX_WIDTH-input_x);
\r
550 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
\r
551 //input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
\r
552 //input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, track_id[count]);
\r
553 //input_mt_sync(ts->input_dev);
\r
558 for(tmp=0; tmp< MAX_FINGER_NUM; tmp++)
\r
560 //printk("tmp=%d\n", tmp);
\r
561 input_mt_slot(ts->input_dev, tmp);//æ
\8c\89åº
\8få
\8f·ä¸
\8aæ
\8a? //input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
\r
562 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
\r
564 //input_mt_sync(ts->input_dev);
\r
567 //input_report_key(ts->input_dev, BTN_TOUCH, finger > 0);
\r
568 input_sync(ts->input_dev);
\r
570 #ifdef HAVE_TOUCH_KEY
\r
571 key = point_data[3]&0x0F;
\r
572 if((last_key != 0)||(key != 0))
\r
574 for(count = 0; count < MAX_KEY_NUM; count++)
\r
576 //printk("####################input_report_key++++++++++++%d\n",key);
\r
577 input_report_key(ts->input_dev, touch_key_array[count], !!(key&(0x01<<count)));
\r
585 #ifndef STOP_IRQ_TYPE
\r
587 gt811_irq_enable(ts); //KT ADD 1202
\r
591 /*******************************************************
\r
593 Response function timer
\r
594 Triggered by a timer, scheduling the work function of the touch screen operation; after re-timing
\r
596 timer: the timer function is associated
\r
598 Timer mode, HRTIMER_NORESTART that do not automatically restart
\r
599 ********************************************************/
\r
600 static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)
\r
602 struct gt811_ts_data *ts = container_of(timer, struct gt811_ts_data, timer);
\r
603 queue_work(goodix_wq, &ts->work);
\r
604 hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);
\r
605 return HRTIMER_NORESTART;
\r
608 /*******************************************************
\r
610 Interrupt response function
\r
611 Triggered by an interrupt, the scheduler runs the touch screen handler
\r
612 ********************************************************/
\r
613 static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
\r
615 struct gt811_ts_data *ts = dev_id;
\r
616 //printk("hjc:%s>>>>>>>>>>>>>>>>>>\n",__func__);
\r
617 #ifndef STOP_IRQ_TYPE
\r
618 gt811_irq_disable(ts); //KT ADD 1202
\r
620 //disable_irq_nosync(ts->client->irq);
\r
621 queue_work(goodix_wq, &ts->work);
\r
623 return IRQ_HANDLED;
\r
626 /*******************************************************
\r
628 Power management gt811, gt811 allowed to sleep or to wake up
\r
630 on: 0 that enable sleep, wake up 1
\r
632 Is set successfully, 0 for success
\r
633 Error code: -1 for the i2c error, -2 for the GPIO error;-EINVAL on error as a parameter
\r
634 ********************************************************/
\r
635 static int goodix_ts_power(struct gt811_ts_data * ts, int on)
\r
639 unsigned char i2c_control_buf[3] = {0x06,0x92,0x01}; //suspend cmd
\r
642 if(ts != NULL && !ts->use_irq)
\r
648 ret = i2c_write_bytes(ts->client, i2c_control_buf, 3);
\r
649 printk("ret++++++++++++++++= %d=\n",ret);
\r
650 dev_info(&ts->client->dev, "Send suspend cmd\n");
\r
651 if(ret < 0) //failed
\r
656 gpio_direction_output(SHUTDOWN_PORT,0);
\r
658 gpio_set_value(SHUTDOWN_PORT,0);
\r
660 gpio_set_value(SHUTDOWN_PORT,1);
\r
666 dev_info(&ts->client->dev, "%s: Cant't support this command.", s3c_ts_name);
\r
671 /*******************************************************
\r
673 Touch-screen detection function
\r
674 Called when the registration drive (required for a corresponding client);
\r
675 For IO, interrupts and other resources to apply; equipment registration; touch screen initialization, etc.
\r
677 client: the device structure to be driven
\r
680 Results of the implementation code, 0 for normal execution
\r
681 ********************************************************/
\r
682 static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
\r
686 char test_data = 1;
\r
687 char buf[2]={0}; //w++
\r
688 unsigned char read_data[2] = {0,0 };
\r
689 const char irq_table[2] = {IRQF_TRIGGER_FALLING,IRQF_TRIGGER_RISING};
\r
690 struct gt811_ts_data *ts;
\r
691 // struct gt811_platform_data *811data = client->dev.platform_data;
\r
692 struct gt811_platform_data *pdata;
\r
693 dev_info(&client->dev,"Install gt811 driver.\n");
\r
694 dev_info(&client->dev,"Driver Release Date:2012-02-08\n");
\r
696 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
\r
698 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
\r
700 goto err_check_functionality_failed;
\r
703 ret=i2c_read_bytes(client, read_data, sizeof(read_data)/sizeof(read_data[0]));
\r
706 dev_err(&client->dev, "Must have GT811.\n");
\r
707 goto err_check_functionality_failed;
\r
711 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
\r
714 goto err_alloc_data_failed;
\r
717 i2c_connect_client = client;
\r
719 gpio_free(SHUTDOWN_PORT);
\r
720 ret = gpio_request(SHUTDOWN_PORT, "RESET_INT");
\r
723 dev_err(&client->dev, "Failed to request RESET GPIO:%d, ERRNO:%d\n",(int)SHUTDOWN_PORT,ret);
\r
724 goto err_gpio_request;
\r
727 //rk29_mux_api_set(GPIO0D3_PWM_1_NAME,GPIO0D_GPIO0D3);
\r
728 gpio_pull_updown(SHUTDOWN_PORT, 1); //set GPIO pull-up
\r
730 for(retry=0;retry <= 10; retry++)
\r
732 gpio_direction_output(SHUTDOWN_PORT,0);
\r
734 // gpio_direction_input(SHUTDOWN_PORT);//setinput means not ack so set the reset high
\r
736 gpio_set_value(SHUTDOWN_PORT,1);
\r
738 gpio_set_value(SHUTDOWN_PORT,0);
\r
740 gpio_set_value(SHUTDOWN_PORT,1);
\r
743 val_ret = gpio_get_value(SHUTDOWN_PORT);
\r
744 ret = i2c_write_bytes(client, &test_data, 1);
\r
745 //ret =i2c_master_reg8_recv(client, 0x00, buf, 2, 200*1000);//i2c_write_bytes(client, &test_data, 1); //Test I2C connection.
\r
748 dev_info(&client->dev, "GT811 I2C TEST FAILED!Please check the HARDWARE connect\n");
\r
753 dev_err(&client->dev, "Warnning: I2C communication might be ERROR!\n");
\r
754 goto err_i2c_failed;
\r
757 INIT_WORK(&ts->work, goodix_ts_work_func); //init work_struct
\r
758 ts->client = client;
\r
759 i2c_set_clientdata(client, ts);
\r
760 pdata = client->dev.platform_data;
\r
761 /////////////////////////////// UPDATE STEP 1 START/////////////////////////////////////////////////////////////////
\r
762 #ifdef AUTO_UPDATE_GT811 //modify by andrew
\r
764 goodix_read_version(ts);
\r
766 ret = gt811_downloader( ts, goodix_gt811_firmware);
\r
769 dev_err(&client->dev, "Warnning: gt811 update might be ERROR!\n");
\r
770 //goto err_input_dev_alloc_failed;
\r
773 ///////////////////////////////UPDATE STEP 1 END////////////////////////////////////////////////////////////////
\r
775 client->irq=TS_INT; //If not defined in client
\r
778 gpio_free(INT_PORT);
\r
779 ret = gpio_request(INT_PORT, "TS_INT"); //Request IO
\r
782 dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)INT_PORT,ret);
\r
783 goto err_gpio_request_failed;
\r
786 gpio_pull_updown(INT_PORT, NULL); //ret > 0 ?
\r
789 #ifndef STOP_IRQ_TYPE
\r
790 ts->irq = TS_INT; //KT ADD 1202
\r
791 ts->irq_is_disable = 0; // enable irq
\r
796 err_gpio_request_failed:
\r
797 for(retry=0; retry<3; retry++)
\r
799 ret=goodix_init_panel(ts);
\r
801 if(ret != 0) //Initiall failed
\r
809 goto err_init_godix_ts;
\r
812 ts->input_dev = input_allocate_device();
\r
813 if (ts->input_dev == NULL)
\r
816 dev_dbg(&client->dev,"goodix_ts_probe: Failed to allocate input device\n");
\r
817 goto err_input_dev_alloc_failed;
\r
820 //ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
\r
821 //ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
\r
822 //////ts->input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
\r
823 #ifdef HAVE_TOUCH_KEY
\r
824 for(retry = 0; retry < MAX_KEY_NUM; retry++)
\r
826 input_set_capability(ts->input_dev,EV_KEY,touch_key_array[retry]);
\r
830 input_set_abs_params(ts->input_dev, ABS_X, 0, ts->abs_x_max, 0, 0);
\r
831 input_set_abs_params(ts->input_dev, ABS_Y, 0, ts->abs_y_max, 0, 0);
\r
832 input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
\r
834 #ifdef GOODIX_MULTI_TOUCH
\r
836 __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
\r
837 __set_bit(EV_ABS, ts->input_dev->evbit);
\r
839 input_mt_init_slots(ts->input_dev, ts->max_touch_num);
\r
840 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
\r
841 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0);
\r
842 #ifdef CONFIG_MACH_RK3168_86V_OLD
\r
843 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, 415, 0, 0);
\r
845 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0);
\r
847 //printk("\n\nhjc:%s,x_max=%d,y_max=%d\n",__func__,ts->abs_x_max,ts->abs_y_max);
\r
852 sprintf(ts->phys, "input/ts");
\r
853 ts->input_dev->name = s3c_ts_name;
\r
854 ts->input_dev->phys = ts->phys;
\r
855 ts->input_dev->id.bustype = BUS_I2C;
\r
856 ts->input_dev->id.vendor = 0xDEAD;
\r
857 ts->input_dev->id.product = 0xBEEF;
\r
858 ts->input_dev->id.version = 10427; //screen firmware version
\r
860 ret = input_register_device(ts->input_dev);
\r
862 dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name);
\r
863 goto err_input_register_device_failed;
\r
868 ret = request_irq(TS_INT, goodix_ts_irq_handler ,irq_table[ts->int_trigger_type],
\r
872 dev_err(&client->dev,"Cannot allocate ts INT!ERRNO:%d\n", ret);
\r
873 gpio_direction_input(INT_PORT);
\r
874 gpio_free(INT_PORT);
\r
875 goto err_init_godix_ts;
\r
879 #ifndef STOP_IRQ_TYPE
\r
880 gt811_irq_disable(ts); //KT ADD 1202
\r
882 // disable_irq(client->irq);
\r
885 dev_dbg(&client->dev,"Reques EIRQ %d succesd on GPIO:%d\n",TS_INT,INT_PORT);
\r
892 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
\r
893 ts->timer.function = goodix_ts_timer_func;
\r
894 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
\r
898 #ifndef STOP_IRQ_TYPE
\r
899 gt811_irq_enable(ts); //KT ADD 1202
\r
901 // enable_irq(client->irq);
\r
904 ts->power = goodix_ts_power;
\r
906 goodix_read_version(ts);
\r
908 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
909 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;//EARLY_SUSPEND_LEVEL_BLANK_SCREEN +1;
\r
910 ts->early_suspend.suspend = goodix_ts_early_suspend;
\r
911 ts->early_suspend.resume = goodix_ts_late_resume;
\r
912 register_early_suspend(&ts->early_suspend);
\r
915 /////////////////////////////// UPDATE STEP 2 START /////////////////////////////////////////////////////////////////
\r
916 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
\r
917 goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL);
\r
918 if(goodix_proc_entry == NULL)
\r
920 dev_info(&client->dev, "Couldn't create proc entry!\n");
\r
922 goto err_create_proc_entry;
\r
926 dev_info(&client->dev, "Create proc entry success!\n");
\r
927 goodix_proc_entry->write_proc = goodix_update_write;
\r
928 goodix_proc_entry->read_proc = goodix_update_read;
\r
931 ///////////////////////////////UPDATE STEP 2 END /////////////////////////////////////////////////////////////////
\r
932 dev_info(&client->dev,"Start %s in %s mode,Driver Modify Date:2012-01-05\n",
\r
933 ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
\r
941 free_irq(client->irq,ts);
\r
943 gpio_direction_input(INT_PORT);
\r
944 gpio_free(INT_PORT);
\r
948 hrtimer_cancel(&ts->timer);
\r
950 err_input_register_device_failed:
\r
951 input_free_device(ts->input_dev);
\r
953 err_input_dev_alloc_failed:
\r
954 i2c_set_clientdata(client, NULL);
\r
956 gpio_free(SHUTDOWN_PORT);
\r
959 err_alloc_data_failed:
\r
960 err_check_functionality_failed:
\r
961 err_create_proc_entry:
\r
966 /*******************************************************
\r
968 Drive the release of resources
\r
970 client: the device structure
\r
972 Results of the implementation code, 0 for normal execution
\r
973 ********************************************************/
\r
974 static int goodix_ts_remove(struct i2c_client *client)
\r
976 struct gt811_ts_data *ts = i2c_get_clientdata(client);
\r
977 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
978 unregister_early_suspend(&ts->early_suspend);
\r
980 /////////////////////////////// UPDATE STEP 3 START/////////////////////////////////////////////////////////////////
\r
981 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
\r
982 remove_proc_entry("goodix-update", NULL);
\r
984 /////////////////////////////////UPDATE STEP 3 END///////////////////////////////////////////////////////////////
\r
986 if (ts && ts->use_irq)
\r
989 gpio_direction_input(INT_PORT);
\r
990 gpio_free(INT_PORT);
\r
992 free_irq(client->irq, ts);
\r
995 hrtimer_cancel(&ts->timer);
\r
997 dev_notice(&client->dev,"The driver is removing...\n");
\r
998 i2c_set_clientdata(client, NULL);
\r
999 input_unregister_device(ts->input_dev);
\r
1005 static int goodix_ts_suspend(struct i2c_client *client, pm_message_t mesg)
\r
1008 struct gt811_ts_data *ts = i2c_get_clientdata(client);
\r
1009 disable_irq(client->irq);
\r
1012 ret = ts->power(ts, 0);
\r
1013 printk("suspend >>>>>>>>>ret=%d",ret);
\r
1015 printk(KERN_ERR "goodix_ts_suspend power on failed\n");
\r
1018 static int goodix_ts_resume(struct i2c_client *client)
\r
1021 struct gt811_ts_data *ts = i2c_get_clientdata(client);
\r
1024 ret = ts->power(ts, 1);
\r
1025 printk("resume >>>>>>>>>ret=%d",ret);
\r
1027 printk(KERN_ERR "goodix_ts_resume power on failed\n");
\r
1029 enable_irq(client->irq);
\r
1033 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
1034 static void goodix_ts_early_suspend(struct early_suspend *h)
\r
1036 struct gt811_ts_data *ts;
\r
1037 ts = container_of(h, struct gt811_ts_data, early_suspend);
\r
1038 goodix_ts_suspend(ts->client, PMSG_SUSPEND);
\r
1041 static void goodix_ts_late_resume(struct early_suspend *h)
\r
1043 struct gt811_ts_data *ts;
\r
1044 ts = container_of(h, struct gt811_ts_data, early_suspend);
\r
1045 goodix_ts_resume(ts->client);
\r
1048 /////////////////////////////// UPDATE STEP 4 START/////////////////////////////////////////////////////////////////
\r
1049 //******************************Begin of firmware update surpport*******************************
\r
1050 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
\r
1051 static struct file * update_file_open(char * path, mm_segment_t * old_fs_p)
\r
1053 struct file * filp = NULL;
\r
1056 filp = filp_open(path, O_RDONLY, 0644);
\r
1058 if(!filp || IS_ERR(filp))
\r
1063 errno = PTR_ERR(filp);
\r
1064 printk(KERN_ERR "The update file for Guitar open error.\n");
\r
1067 *old_fs_p = get_fs();
\r
1070 filp->f_op->llseek(filp,0,0);
\r
1074 static void update_file_close(struct file * filp, mm_segment_t old_fs)
\r
1078 filp_close(filp, NULL);
\r
1080 static int update_get_flen(char * path)
\r
1082 struct file * file_ck = NULL;
\r
1083 mm_segment_t old_fs;
\r
1086 file_ck = update_file_open(path, &old_fs);
\r
1087 if(file_ck == NULL)
\r
1090 length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);
\r
1091 //printk("File length: %d\n", length);
\r
1094 update_file_close(file_ck, old_fs);
\r
1098 static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data)
\r
1100 unsigned char cmd[120];
\r
1103 static unsigned char update_path[60];
\r
1104 struct gt811_ts_data *ts;
\r
1105 struct file * file_data = NULL;
\r
1106 mm_segment_t old_fs;
\r
1107 unsigned char *file_ptr = NULL;
\r
1108 unsigned int file_len;
\r
1110 ts = i2c_get_clientdata(i2c_connect_client);
\r
1113 printk(KERN_INFO"goodix write to kernel via proc file!@@@@@@\n");
\r
1117 //printk(KERN_INFO"goodix write to kernel via proc file!@@@@@@\n");
\r
1118 if(copy_from_user(&cmd, buff, len))
\r
1120 printk(KERN_INFO"goodix write to kernel via proc file!@@@@@@\n");
\r
1123 //printk(KERN_INFO"Write cmd is:%d,write len is:%ld\n",cmd[0], len);
\r
1126 case APK_UPDATE_TP:
\r
1127 printk(KERN_INFO"Write cmd is:%d,cmd arg is:%s,write len is:%ld\n",cmd[0], &cmd[1], len);
\r
1128 memset(update_path, 0, 60);
\r
1129 strncpy(update_path, cmd+1, 60);
\r
1131 #ifndef STOP_IRQ_TYPE
\r
1132 gt811_irq_disable(ts); //KT ADD 1202
\r
1134 // disable_irq(ts->client->irq);
\r
1136 file_data = update_file_open(update_path, &old_fs);
\r
1137 if(file_data == NULL) //file_data has been opened at the last time
\r
1139 dev_info(&ts->client->dev, "cannot open update file\n");
\r
1143 file_len = update_get_flen(update_path);
\r
1144 dev_info(&ts->client->dev, "Update file length:%d\n", file_len);
\r
1145 file_ptr = (unsigned char*)vmalloc(file_len);
\r
1146 if(file_ptr==NULL)
\r
1148 dev_info(&ts->client->dev, "cannot malloc memory!\n");
\r
1152 ret = file_data->f_op->read(file_data, file_ptr, file_len, &file_data->f_pos);
\r
1155 dev_info(&ts->client->dev, "read file data failed\n");
\r
1158 update_file_close(file_data, old_fs);
\r
1160 ret = gt811_downloader(ts, file_ptr);
\r
1164 printk(KERN_INFO"Warnning: GT811 update might be ERROR!\n");
\r
1168 // i2c_pre_cmd(ts);
\r
1170 gpio_direction_output(SHUTDOWN_PORT, 0);
\r
1172 gpio_direction_input(SHUTDOWN_PORT);
\r
1174 for(retry=0; retry<3; retry++)
\r
1176 ret=goodix_init_panel(ts);
\r
1178 if(ret != 0) //Initiall failed
\r
1180 dev_info(&ts->client->dev, "Init panel failed!\n");
\r
1188 // s3c_gpio_cfgpin(INT_PORT, INT_CFG); //Set IO port function
\r
1189 //gpio_direction_input(INT_PORT);
\r
1190 // s3c_gpio_setpull(INT_PORT, S3C_GPIO_PULL_UP);
\r
1191 // s3c_gpio_cfgpin(INT_PORT, INT_CFG); //Set IO port as interrupt port
\r
1192 //s3c_gpio_setpull(INT_PORT, S3C_GPIO_PULL_NONE);
\r
1194 #ifndef STOP_IRQ_TYPE
\r
1195 gt811_irq_enable(ts); //KT ADD 1202
\r
1197 // enable_irq(ts->client->irq);
\r
1199 // i2c_end_cmd(ts);
\r
1202 case APK_READ_FUN: //functional command
\r
1203 if(cmd[1] == CMD_READ_VER)
\r
1205 printk(KERN_INFO"Read version!\n");
\r
1206 ts->read_mode = MODE_RD_VER;
\r
1208 else if(cmd[1] == CMD_READ_CFG)
\r
1210 printk(KERN_INFO"Read config info!\n");
\r
1212 ts->read_mode = MODE_RD_CFG;
\r
1214 else if (cmd[1] == CMD_READ_RAW)
\r
1216 printk(KERN_INFO"Read raw data!\n");
\r
1218 ts->read_mode = MODE_RD_RAW;
\r
1220 else if (cmd[1] == CMD_READ_CHIP_TYPE)
\r
1222 printk(KERN_INFO"Read chip type!\n");
\r
1224 ts->read_mode = MODE_RD_CHIP_TYPE;
\r
1228 case APK_WRITE_CFG:
\r
1229 printk(KERN_INFO"Begin write config info!Config length:%d\n",cmd[1]);
\r
1231 ret = i2c_write_bytes(ts->client, cmd+2, cmd[1]+2);
\r
1235 printk("Write Config failed!return:%d\n",ret);
\r
1246 static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data )
\r
1250 int read_times = 0;
\r
1251 struct gt811_ts_data *ts;
\r
1253 unsigned char read_data[360] = {80, };
\r
1255 ts = i2c_get_clientdata(i2c_connect_client);
\r
1259 printk("___READ__\n");
\r
1260 if(ts->read_mode == MODE_RD_VER) //read version data
\r
1263 ret = goodix_read_version(ts);
\r
1267 printk(KERN_INFO"Read version data failed!\n");
\r
1271 read_data[1] = (char)(ts->version&0xff);
\r
1272 read_data[0] = (char)((ts->version>>8)&0xff);
\r
1274 memcpy(page, read_data, 2);
\r
1278 else if (ts->read_mode == MODE_RD_CHIP_TYPE)
\r
1283 else if(ts->read_mode == MODE_RD_CFG)
\r
1286 read_data[0] = 0x06;
\r
1287 read_data[1] = 0xa2; // cfg start address
\r
1288 printk("read config addr is:%x,%x\n", read_data[0],read_data[1]);
\r
1292 ret = i2c_read_bytes(ts->client, read_data, len+2);
\r
1296 printk(KERN_INFO"Read config info failed!\n");
\r
1300 memcpy(page, read_data+2, len);
\r
1303 else if (ts->read_mode == MODE_RD_RAW)
\r
1305 #define TIMEOUT (-100)
\r
1307 if (raw_data_ready != RAW_DATA_READY)
\r
1309 raw_data_ready = RAW_DATA_ACTIVE;
\r
1313 read_data[0] = 0x07;
\r
1314 read_data[1] = 0x11;
\r
1315 read_data[2] = 0x01;
\r
1317 ret = i2c_write_bytes(ts->client, read_data, 3);
\r
1320 sum += read_times;
\r
1321 printk("count :%d\n", ++access_count);
\r
1322 printk("A total of try times:%d\n", sum);
\r
1326 while (RAW_DATA_READY != raw_data_ready)
\r
1330 if (read_times++ > 10)
\r
1340 printk("read times:%d\n", read_times);
\r
1342 read_data[0] = 0x08;
\r
1343 read_data[1] = 0x80; // raw data address
\r
1350 ret = i2c_read_bytes(ts->client, read_data, len+2);
\r
1351 // i2c_end_cmd(ts);
\r
1355 printk(KERN_INFO"Read raw data failed!\n");
\r
1358 memcpy(page, read_data+2, len);
\r
1360 read_data[0] = 0x09;
\r
1361 read_data[1] = 0xC0;
\r
1362 // i2c_pre_cmd(ts);
\r
1363 ret = i2c_read_bytes(ts->client, read_data, len+2);
\r
1368 printk(KERN_INFO"Read raw data failed!\n");
\r
1371 memcpy(&page[160], read_data+2, len);
\r
1375 for (i = 0; i < 300; i++)
\r
1377 printk("%6x", page[i]);
\r
1379 if ((i+1) % 10 == 0)
\r
1384 //********************/
\r
1386 raw_data_ready = RAW_DATA_NON_ACTIVE;
\r
1394 //********************************************************************************************
\r
1395 static u8 is_equal( u8 *src , u8 *dst , int len )
\r
1400 for( i = 0 ; i < len ; i++ )
\r
1402 printk(KERN_INFO"[%02X:%02X]", src[i], dst[i]);
\r
1403 if((i+1)%10==0)printk("\n");
\r
1407 for( i = 0 ; i < len ; i++ )
\r
1409 if ( src[i] != dst[i] )
\r
1418 static u8 gt811_nvram_store( struct gt811_ts_data *ts )
\r
1422 u8 inbuf[3] = {REG_NVRCS_H,REG_NVRCS_L,0};
\r
1423 //u8 outbuf[3] = {};
\r
1424 ret = i2c_read_bytes( ts->client, inbuf, 3 );
\r
1431 if ( ( inbuf[2] & BIT_NVRAM_LOCK ) == BIT_NVRAM_LOCK )
\r
1436 inbuf[2] = (1<<BIT_NVRAM_STROE); //store command
\r
1438 for ( i = 0 ; i < 300 ; i++ )
\r
1440 ret = i2c_write_bytes( ts->client, inbuf, 3 );
\r
1449 static u8 gt811_nvram_recall( struct gt811_ts_data *ts )
\r
1452 u8 inbuf[3] = {REG_NVRCS_H,REG_NVRCS_L,0};
\r
1454 ret = i2c_read_bytes( ts->client, inbuf, 3 );
\r
1461 if ( ( inbuf[2]&BIT_NVRAM_LOCK) == BIT_NVRAM_LOCK )
\r
1466 inbuf[2] = ( 1 << BIT_NVRAM_RECALL ); //recall command
\r
1467 ret = i2c_write_bytes( ts->client , inbuf, 3);
\r
1471 static int gt811_reset( struct gt811_ts_data *ts )
\r
1476 unsigned char outbuf[3] = {0,0xff,0};
\r
1477 unsigned char inbuf[3] = {0,0xff,0};
\r
1480 gpio_direction_output(SHUTDOWN_PORT,0);
\r
1482 gpio_direction_input(SHUTDOWN_PORT);
\r
1484 for(retry=0;retry < 80; retry++)
\r
1486 ret =i2c_write_bytes(ts->client, inbuf, 0); //Test I2C connection.
\r
1490 ret =i2c_read_bytes(ts->client, inbuf, 3); //Test I2C connection.
\r
1493 if(inbuf[2] == 0x55)
\r
1495 ret =i2c_write_bytes(ts->client, outbuf, 3);
\r
1503 gpio_direction_output(SHUTDOWN_PORT,0);
\r
1505 gpio_direction_input(SHUTDOWN_PORT);
\r
1507 dev_info(&ts->client->dev, "i2c address failed\n");
\r
1511 dev_info(&ts->client->dev, "Detect address %0X\n", ts->client->addr);
\r
1516 static int gt811_reset2( struct gt811_ts_data *ts )
\r
1521 //unsigned char outbuf[3] = {0,0xff,0};
\r
1522 unsigned char inbuf[3] = {0,0xff,0};
\r
1525 gpio_direction_output(SHUTDOWN_PORT,0);
\r
1527 gpio_direction_input(SHUTDOWN_PORT);
\r
1529 for(retry=0;retry < 80; retry++)
\r
1531 ret =i2c_write_bytes(ts->client, inbuf, 0); //Test I2C connection.
\r
1535 ret =i2c_read_bytes(ts->client, inbuf, 3); //Test I2C connection.
\r
1538 // if(inbuf[2] == 0x55)
\r
1540 // ret =i2c_write_bytes(ts->client, outbuf, 3);
\r
1548 dev_info(&ts->client->dev, "Detect address %0X\n", ts->client->addr);
\r
1552 static int gt811_set_address_2( struct gt811_ts_data *ts )
\r
1554 unsigned char inbuf[3] = {0,0,0};
\r
1557 for ( i = 0 ; i < 12 ; i++ )
\r
1559 if ( i2c_read_bytes( ts->client, inbuf, 3) )
\r
1561 dev_info(&ts->client->dev, "Got response\n");
\r
1564 dev_info(&ts->client->dev, "wait for retry\n");
\r
1569 static u8 gt811_update_firmware( u8 *nvram, u16 start_addr, u16 length, struct gt811_ts_data *ts)
\r
1571 u8 ret,err,retry_time,i;
\r
1572 u16 cur_code_addr;
\r
1573 u16 cur_frame_num, total_frame_num, cur_frame_len;
\r
1574 u32 gt80x_update_rate;
\r
1576 unsigned char i2c_data_buf[PACK_SIZE+2] = {0,};
\r
1577 unsigned char i2c_chk_data_buf[PACK_SIZE+2] = {0,};
\r
1579 if( length > NVRAM_LEN - NVRAM_BOOT_SECTOR_LEN )
\r
1581 dev_info(&ts->client->dev, "Fw length %d is bigger than limited length %d\n", length, NVRAM_LEN - NVRAM_BOOT_SECTOR_LEN );
\r
1585 total_frame_num = ( length + PACK_SIZE - 1) / PACK_SIZE;
\r
1587 //gt80x_update_sta = _UPDATING;
\r
1588 gt80x_update_rate = 0;
\r
1590 for( cur_frame_num = 0 ; cur_frame_num < total_frame_num ; cur_frame_num++ )
\r
1594 dev_info(&ts->client->dev, "PACK[%d]\n",cur_frame_num);
\r
1595 cur_code_addr = /*NVRAM_UPDATE_START_ADDR*/start_addr + cur_frame_num * PACK_SIZE;
\r
1596 i2c_data_buf[0] = (cur_code_addr>>8)&0xff;
\r
1597 i2c_data_buf[1] = cur_code_addr&0xff;
\r
1599 i2c_chk_data_buf[0] = i2c_data_buf[0];
\r
1600 i2c_chk_data_buf[1] = i2c_data_buf[1];
\r
1602 if( cur_frame_num == total_frame_num - 1 )
\r
1604 cur_frame_len = length - cur_frame_num * PACK_SIZE;
\r
1608 cur_frame_len = PACK_SIZE;
\r
1611 //strncpy(&i2c_data_buf[2], &nvram[cur_frame_num*PACK_SIZE], cur_frame_len);
\r
1612 for(i=0;i<cur_frame_len;i++)
\r
1614 i2c_data_buf[2+i] = nvram[cur_frame_num*PACK_SIZE+i];
\r
1620 //ret = gt811_i2c_write( guitar_i2c_address, cur_code_addr, &nvram[cur_frame_num*I2C_FRAME_MAX_LENGTH], cur_frame_len );
\r
1621 ret = i2c_write_bytes(ts->client, i2c_data_buf, (cur_frame_len+2));
\r
1624 dev_info(&ts->client->dev, "write fail\n");
\r
1628 ret = i2c_read_bytes(ts->client, i2c_chk_data_buf, (cur_frame_len+2));
\r
1629 // ret = gt811_i2c_read( guitar_i2c_address, cur_code_addr, inbuf, cur_frame_len);
\r
1632 dev_info(&ts->client->dev, "read fail\n");
\r
1636 if( is_equal( &i2c_data_buf[2], &i2c_chk_data_buf[2], cur_frame_len ) == 0 )
\r
1638 dev_info(&ts->client->dev, "not equal\n");
\r
1642 } while ( err == 1 && (--retry_time) > 0 );
\r
1649 gt80x_update_rate = ( cur_frame_num + 1 )*128/total_frame_num;
\r
1655 dev_info(&ts->client->dev, "write nvram fail\n");
\r
1659 ret = gt811_nvram_store(ts);
\r
1665 dev_info(&ts->client->dev, "nvram store fail\n");
\r
1669 ret = gt811_nvram_recall(ts);
\r
1675 dev_info(&ts->client->dev, "nvram recall fail\n");
\r
1679 for ( cur_frame_num = 0 ; cur_frame_num < total_frame_num ; cur_frame_num++ ) // read out all the code
\r
1682 cur_code_addr = NVRAM_UPDATE_START_ADDR + cur_frame_num*PACK_SIZE;
\r
1684 i2c_chk_data_buf[0] = (cur_code_addr>>8)&0xff;
\r
1685 i2c_chk_data_buf[1] = cur_code_addr&0xff;
\r
1688 if ( cur_frame_num == total_frame_num-1 )
\r
1690 cur_frame_len = length - cur_frame_num*PACK_SIZE;
\r
1694 cur_frame_len = PACK_SIZE;
\r
1700 //ret = gt811_i2c_read( guitar_i2c_address, cur_code_addr, inbuf, cur_frame_len);
\r
1701 ret = i2c_read_bytes(ts->client, i2c_chk_data_buf, (cur_frame_len+2));
\r
1708 if( is_equal( &nvram[cur_frame_num*PACK_SIZE], &i2c_chk_data_buf[2], cur_frame_len ) == 0 )
\r
1712 } while ( err == 1 && (--retry_time) > 0 );
\r
1719 gt80x_update_rate = 127 + ( cur_frame_num + 1 )*128/total_frame_num;
\r
1722 gt80x_update_rate = 255;
\r
1723 //gt80x_update_sta = _UPDATECHKCODE;
\r
1727 dev_info(&ts->client->dev, "nvram validate fail\n");
\r
1734 static u8 gt811_update_proc( u8 *nvram, u16 start_addr , u16 length, struct gt811_ts_data *ts )
\r
1738 //struct tpd_info_t tpd_info;
\r
1739 GT811_SET_INT_PIN( 0 );
\r
1741 ret = gt811_reset(ts);
\r
1745 dev_info(&ts->client->dev, "reset fail\n");
\r
1749 ret = gt811_set_address_2( ts );
\r
1753 dev_info(&ts->client->dev, "set address fail\n");
\r
1757 ret = gt811_update_firmware( nvram, start_addr, length, ts);
\r
1761 dev_info(&ts->client->dev, "firmware update fail\n");
\r
1766 GT811_SET_INT_PIN( 1 );
\r
1767 // gpio_free(INT_PORT);
\r
1768 gpio_pull_updown(INT_PORT, NULL);
\r
1771 ret = gt811_reset2(ts);
\r
1775 dev_info(&ts->client->dev, "final reset fail\n");
\r
1783 // i2c_pre_cmd(ts);
\r
1784 while(goodix_read_version(ts)<0);
\r
1786 // i2c_end_cmd(ts);
\r
1790 u16 Little2BigEndian(u16 little_endian)
\r
1793 temp = little_endian&0xff;
\r
1794 return (temp<<8)+((little_endian>>8)&0xff);
\r
1797 int gt811_downloader( struct gt811_ts_data *ts, unsigned char * data)
\r
1799 struct tpd_firmware_info_t *fw_info = (struct tpd_firmware_info_t *)data;
\r
1801 //unsigned short checksum = 0;
\r
1802 //unsigned int checksum = 0;
\r
1803 unsigned int fw_checksum = 0;
\r
1804 //unsigned char fw_chip_type;
\r
1805 unsigned short fw_version;
\r
1806 unsigned short fw_start_addr;
\r
1807 unsigned short fw_length;
\r
1808 unsigned char *data_ptr;
\r
1809 //unsigned char *file_ptr = &(fw_info->chip_type);
\r
1810 int retry = 0,ret;
\r
1812 unsigned char rd_buf[4] = {0};
\r
1813 unsigned char *mandatory_base = "GOODIX";
\r
1814 unsigned char rd_rom_version;
\r
1815 unsigned char rd_chip_type;
\r
1816 unsigned char rd_nvram_flag;
\r
1818 //struct file * file_data = NULL;
\r
1819 //mm_segment_t old_fs;
\r
1820 //unsigned int rd_len;
\r
1821 //unsigned int file_len = 0;
\r
1822 //unsigned char i2c_data_buf[PACK_SIZE] = {0,};
\r
1827 ret = i2c_write_bytes(ts->client, rd_buf, 3);
\r
1830 dev_info(&ts->client->dev, "i2c write failed\n");
\r
1831 goto exit_downloader;
\r
1835 ret = i2c_read_bytes(ts->client, rd_buf, 3);
\r
1838 dev_info(&ts->client->dev, "i2c request failed!\n");
\r
1839 goto exit_downloader;
\r
1841 rd_chip_type = rd_buf[2];
\r
1844 ret = i2c_read_bytes(ts->client, rd_buf, 3);
\r
1847 dev_info(&ts->client->dev, "i2c read failed!\n");
\r
1848 goto exit_downloader;
\r
1850 rd_rom_version = rd_buf[2];
\r
1853 ret = i2c_read_bytes(ts->client, rd_buf, 3);
\r
1856 dev_info(&ts->client->dev, "i2c read failed!\n");
\r
1857 goto exit_downloader;
\r
1859 rd_nvram_flag = rd_buf[2];
\r
1861 fw_version = Little2BigEndian(fw_info->version);
\r
1862 fw_start_addr = Little2BigEndian(fw_info->start_addr);
\r
1863 fw_length = Little2BigEndian(fw_info->length);
\r
1864 data_ptr = &(fw_info->data);
\r
1866 dev_info(&ts->client->dev,"chip_type=0x%02x\n", fw_info->chip_type);
\r
1867 dev_info(&ts->client->dev,"version=0x%04x\n", fw_version);
\r
1868 dev_info(&ts->client->dev,"rom_version=0x%02x\n",fw_info->rom_version);
\r
1869 dev_info(&ts->client->dev,"start_addr=0x%04x\n",fw_start_addr);
\r
1870 dev_info(&ts->client->dev,"file_size=0x%04x\n",fw_length);
\r
1871 fw_checksum = ((u32)fw_info->checksum[0]<<16) + ((u32)fw_info->checksum[1]<<8) + ((u32)fw_info->checksum[2]);
\r
1872 dev_info(&ts->client->dev,"fw_checksum=0x%06x\n",fw_checksum);
\r
1873 dev_info(&ts->client->dev,"%s\n", __func__ );
\r
1874 dev_info(&ts->client->dev,"current version 0x%04X, target verion 0x%04X\n", ts->version, fw_version );
\r
1877 if(rd_chip_type!=fw_info->chip_type)
\r
1879 dev_info(&ts->client->dev, "Chip type not match,exit downloader\n");
\r
1880 goto exit_downloader;
\r
1883 //chk_mask_version:
\r
1884 if(!rd_rom_version)
\r
1886 if(fw_info->rom_version!=0x45)
\r
1888 dev_info(&ts->client->dev, "Rom version not match,exit downloader\n");
\r
1889 goto exit_downloader;
\r
1891 dev_info(&ts->client->dev, "Rom version E.\n");
\r
1892 goto chk_fw_version;
\r
1894 else if(rd_rom_version!=fw_info->rom_version);
\r
1896 dev_info(&ts->client->dev, "Rom version not match,exidownloader\n");
\r
1897 goto exit_downloader;
\r
1899 dev_info(&ts->client->dev, "Rom version %c\n",rd_rom_version);
\r
1902 if(rd_nvram_flag==0x55)
\r
1904 dev_info(&ts->client->dev, "NVRAM correct!\n");
\r
1905 goto chk_fw_version;
\r
1907 else if(rd_nvram_flag==0xAA)
\r
1909 dev_info(&ts->client->dev, "NVRAM incorrect!Need update.\n");
\r
1910 goto begin_upgrade;
\r
1914 dev_info(&ts->client->dev, "NVRAM other error![0x694]=0x%02x\n", rd_nvram_flag);
\r
1915 goto begin_upgrade;
\r
1918 // ts->version -= 1; //test by andrew
\r
1919 if( ts->version >= fw_version ) // current low byte higher than back-up low byte
\r
1921 dev_info(&ts->client->dev, "Fw verison not match.\n");
\r
1922 goto chk_mandatory_upgrade;
\r
1924 dev_info(&ts->client->dev,"Need to upgrade\n");
\r
1925 goto begin_upgrade;
\r
1926 chk_mandatory_upgrade:
\r
1927 // dev_info(&ts->client->dev, "%s\n", mandatory_base);
\r
1928 // dev_info(&ts->client->dev, "%s\n", fw_info->mandatory_flag);
\r
1929 ret = memcmp(mandatory_base, fw_info->mandatory_flag, 6);
\r
1932 dev_info(&ts->client->dev,"Not meet mandatory upgrade,exit downloader!ret:%d\n", ret);
\r
1933 goto exit_downloader;
\r
1935 dev_info(&ts->client->dev, "Mandatory upgrade!\n");
\r
1937 dev_info(&ts->client->dev, "Begin upgrade!\n");
\r
1938 // goto exit_downloader;
\r
1939 dev_info(&ts->client->dev,"STEP_0:\n");
\r
1942 dev_info(&ts->client->dev, "STEP_1:\n");
\r
1944 while( retry < 3 )
\r
1946 // ret = gt811_update_proc( data_ptr,fw_start_addr, fw_length, ts);
\r
1956 //mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT);
\r
1957 // mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ONE);
\r
1958 // gpio_direction_output(INT_PORT,1);
\r
1960 gpio_free(INT_PORT);
\r
1961 gpio_pull_updown(INT_PORT, NULL);
\r
1965 //******************************End of firmware update surpport*******************************
\r
1966 /////////////////////////////// UPDATE STEP 4 END /////////////////////////////////////////////////////////////////
\r
1968 //å
\8f¯ç
\94¨äº
\8e该驱å
\8a¨ç
\9a?设å¤
\87å
\90\8dâ
\80\94设å¤
\87ID å
\88\97表
\r
1970 static const struct i2c_device_id goodix_ts_id[] = {
\r
1971 { GOODIX_I2C_NAME, 0 },
\r
1975 //设å¤
\87驱å
\8a¨ç»
\93æ
\9e\84ä½?
\r
1976 static struct i2c_driver goodix_ts_driver = {
\r
1977 .probe = goodix_ts_probe,
\r
1978 .remove = goodix_ts_remove,
\r
1979 #ifndef CONFIG_HAS_EARLYSUSPEND
\r
1980 .suspend = goodix_ts_suspend,
\r
1981 .resume = goodix_ts_resume,
\r
1983 .id_table = goodix_ts_id,
\r
1985 .name = GOODIX_I2C_NAME,
\r
1986 .owner = THIS_MODULE,
\r
1990 /*******************************************************
\r
1991 å
\8a\9fè
\83½ï¼? 驱å
\8a¨å
\8a è½½å
\87½æ
\95°
\r
1992 returnï¼? æ
\89§è¡
\8cç»
\93æ
\9e\9cç
\81ï¼
\8c0表示æ£å¸¸æ
\89§è¡
\8c\r
1993 ********************************************************/
\r
1994 static int __devinit goodix_ts_init(void)
\r
1998 goodix_wq = create_workqueue("goodix_wq"); //create a work queue and worker thread
\r
2000 printk(KERN_ALERT "creat workqueue faiked\n");
\r
2004 ret=i2c_add_driver(&goodix_ts_driver);
\r
2008 /*******************************************************
\r
2009 å
\8a\9fè
\83½ï¼? 驱å
\8a¨å
\8d¸è½½å
\87½æ
\95°
\r
2010 å
\8f\82æ
\95°ï¼? clientï¼
\9a设å¤
\87ç»
\93æ
\9e\84ä½
\93\r
2011 ********************************************************/
\r
2012 static void __exit goodix_ts_exit(void)
\r
2014 printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");
\r
2015 i2c_del_driver(&goodix_ts_driver);
\r
2017 destroy_workqueue(goodix_wq); //release our work queue
\r
2020 late_initcall_sync(goodix_ts_init); //最后初始化驱动felix
\r
2021 module_exit(goodix_ts_exit);
\r
2023 MODULE_DESCRIPTION("Goodix Touchscreen Driver");
\r
2024 MODULE_LICENSE("GPL");
\r