input: touchscreen: add touch screen of gslx680 for rk3399-firefly-edp
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / ctp_it7250.c
1 #include <linux/init.h>\r
2 #include <linux/module.h>\r
3 #include <linux/kernel.h>\r
4 #include <linux/platform_device.h>\r
5 #include <linux/interrupt.h>\r
6 #include <linux/irq.h>\r
7 #include <linux/i2c.h>\r
8 //#include <asm/semaphore.h>\r
9 #include <linux/gpio.h>\r
10 #include <mach/gpio.h>\r
11 #include <linux/suspend.h>\r
12 #include <linux/input.h>\r
13 #include <mach/hardware.h>\r
14 \r
15 #include <linux/semaphore.h>\r
16 #include <linux/sched.h>\r
17 #include <linux/delay.h>\r
18 \r
19 #include <mach/iomux.h>\r
20 \r
21 #include <mach/spi_fpga.h>\r
22 \r
23 extern void rk2818_mux_api_set(char *name, unsigned int mode);\r
24 extern int lp8725_ldo_en(uint8_t ldo,uint8_t enble);\r
25 extern int lp8725_set_ldo_vol(uint8_t ldon,uint16_t vol);\r
26 extern int lp8725_set_lilo_vol(uint8_t lilon,uint16_t vol);\r
27 extern int lp8725_lilo_en(uint8_t lilon,uint8_t enble);\r
28 \r
29 \r
30 struct Ctp_it7250_data {\r
31     char  status;
32     char  curr_tate;
33         struct input_dev *input_dev;
34         struct i2c_client *client;
35         struct delayed_work delaywork;\r
36         int irq;  /* Our chip IRQ */\r
37         u32 temp_x;\r
38         u32 temp_y;\r
39 };\r
40 static struct i2c_client *Ctp_it7250_client;\r
41 \r
42 #define Ctp_it7250_GPIO_INT     RK2818_PIN_PE1\r
43 \r
44 #if 0\r
45 #define rk28printk(x...) printk(x)\r
46 #else\r
47 #define rk28printk(x...) \r
48 #endif\r
49 \r
50  struct KeyInfo
51 {
52         int value;\r
53         int key;\r
54 };
55
56 static struct KeyInfo panel_key_info[]={
57 {0x01, KEY_HOME},\r
58 {0x02, KEY_MENU},\r
59 {0x03, KEY_BACK},\r
60 {0x04, KEY_SEARCH},\r
61 };\r
62 \r
63 #define MAX_FINGER_NUM                          3\r
64 //#define DEVICE_ADDRESS                                        0x8C\r
65 #define COMMAND_BUFFER_INDEX                    0x20\r
66 #define QUERY_BUFFER_INDEX                              0x80\r
67 #define COMMAND_RESPONSE_BUFFER_INDEX   0xA0\r
68 #define POINT_BUFFER_INDEX                              0xE0\r
69 #define QUERY_SUCCESS                                   0x00\r
70 #define QUERY_BUSY                                      0x01\r
71 #define QUERY_ERROR                                     0x02\r
72 #define QUERY_POINT                                     0x80\r
73 \r
74 \r
75 static u8 gpucPointBuffer[14];\r
76 static u32 gpdwSampleX[3],gpdwSampleY[3],gpdwPressure[1];\r
77 \r
78 static int Ctp_it7250_rx_data(struct i2c_client *client, u8 reg,u8* rxData, int length)\r
79 {\r
80 #if 0\r
81    \r
82   int ret;\r
83     struct i2c_adapter *adap;int i;\r
84     struct i2c_msg msgs[2];
85     if(!client)\r
86                 return ret;    
87     adap = client->adapter;\r
88         \r
89     //·¢ËͼĴæÆ÷µØÖ·
90     msgs[0].addr = client->addr;\r
91     msgs[0].buf = &reg;\r
92     msgs[0].flags = client->flags;\r
93     msgs[0].len =1;\r
94     msgs[0].scl_rate = 400*1000;\r
95     //½ÓÊÕÊý¾Ý
96     \r
97 //    rk28printk("i2c addr=0x%x \r\n",msgs[0].addr);\r
98  //   rk28printk("msgs[0].buf = 0x%x rxData=0x%x\n",*(msgs[0].buf),*rxData);\r
99         \r
100         msgs[1].buf = rxData;\r
101     msgs[1].addr = client->addr;\r
102     msgs[1].flags = client->flags | I2C_M_RD;\r
103     msgs[1].len = length;\r
104     msgs[1].scl_rate = 400*1000;\r
105
106     ret = i2c_transfer(adap, msgs, 2);
107     //DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
108 //      rk28printk("\r\n msgs[1].buf = 0x%x ret=%d\n",*(msgs[1].buf),ret);\r
109 \r
110 \r
111         //for (i=0;i<length;i++)\r
112         //      rk28printk("rxData[%d]=%d \r\n",i,rxData[i]);\r
113 \r
114 #else\r
115 //int i;\r
116 return  i2c_master_reg8_recv(client, reg, rxData, length, 400 * 1000);\r
117 //for (i=0;i<length;i++)\r
118 //      rk28printk("rxData[%d]=%d \r\n",i,rxData[i]);\r
119 #endif\r
120         \r
121 }
122 \r
123 static int Ctp_it7250_tx_data(struct i2c_client *client, u8 reg,char *txData, int length)\r
124 {
125 #if 0\r
126     int ret,i;\r
127         struct i2c_adapter *adap = client->adapter;\r
128         struct i2c_msg msg;\r
129         \r
130         u8 buf[128];//128\r
131 //      rk28printk("reg=0x%x txData=0x%x  \r\n",reg,*txData);\r
132         buf[0]=reg;\r
133         for (i=0;i<length;i++)\r
134                 {\r
135                 buf[i+1]=*txData++;\r
136                 rk28printk("buf[%d]=0x%x   ",i+1,buf[i+1]);\r
137                 }\r
138         rk28printk("\r\n");\r
139 //      rk28printk("buf[0]=0x%x buf[1]=0x%x",buf[0],buf[1]);\r
140         msg.addr = client->addr;\r
141 //rk28printk("i2c addr=0x%x",msg.addr);\r
142         msg.buf =&buf[0];\r
143         msg.len = length+1;//+1 means add the reg length;by roberts\r
144         msg.flags = client->flags;\r
145         msg.scl_rate = 400*1000;\r
146     
147         ret = i2c_transfer(adap, &msg, 1);
148 return ret;\r
149 #else\r
150  return i2c_master_reg8_send(client, reg, txData, length, 400 * 1000);\r
151 #endif\r
152 \r
153 \r
154 \r
155 \r
156 }\r
157 \r
158 \r
159 \r
160 bool  ReadQueryBuffer(struct i2c_client *client, u8* pucData)\r
161 {\r
162         return Ctp_it7250_rx_data(client, QUERY_BUFFER_INDEX, pucData, 1);\r
163 }\r
164 \r
165 bool ReadCommandResponseBuffer(struct i2c_client *client, u8* pucData, unsigned int unDataLength)\r
166 {\r
167         return Ctp_it7250_rx_data(client, COMMAND_RESPONSE_BUFFER_INDEX, pucData, unDataLength);\r
168 }\r
169 \r
170 bool ReadPointBuffer(struct i2c_client *client, u8* pucData)\r
171 {\r
172         return Ctp_it7250_rx_data(client, POINT_BUFFER_INDEX, pucData, 14);\r
173 }\r
174 \r
175 bool WriteCommandBuffer(struct i2c_client *client, u8* pucData, unsigned int unDataLength)\r
176 {\r
177         return Ctp_it7250_tx_data(client, COMMAND_BUFFER_INDEX, pucData, unDataLength);\r
178 }\r
179 \r
180 static int Ctp_it7250_touch_open(struct input_dev *idev)\r
181 {\r
182         \r
183 //struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client);\r
184 \r
185 \r
186 //BTN_TOUCH =0 means no touch ;by robert\r
187         input_report_key(idev,BTN_TOUCH, 0);\r
188         input_sync(idev);\r
189 \r
190         return 0;\r
191 }\r
192 \r
193 static void Ctp_it7250_touch_close(struct input_dev *idev)\r
194 {\r
195 return ;\r
196 }\r
197 \r
198 static irqreturn_t Ctp_it7250_touch_irq(int irq, void *dev_id)\r
199 {       \r
200         struct Ctp_it7250_data *Ctp_it7250 = dev_id;\r
201         //printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
202         //rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
203         disable_irq_nosync(irq);\r
204         //rk28printk("%s++++ %d irq=%d\r\n",__FUNCTION__,__LINE__,irq);\r
205         schedule_delayed_work(&Ctp_it7250->delaywork,msecs_to_jiffies(10));     \r
206         \r
207         return IRQ_HANDLED; \r
208                 \r
209 }\r
210 \r
211 \r
212 \r
213 static int ts_input_init(struct i2c_client *client)\r
214 {\r
215         int ret = -1,i;\r
216         struct Ctp_it7250_data *Ctp_it7250;\r
217         Ctp_it7250 = i2c_get_clientdata(client);\r
218         /* register input device */\r
219         Ctp_it7250->input_dev = input_allocate_device();\r
220         if (Ctp_it7250->input_dev == NULL) {\r
221                 pr_emerg( "%s: failed to allocate input dev\n",\r
222                         __FUNCTION__);\r
223                 return -ENOMEM;\r
224         }\r
225 rk28printk("+++++++     %s+++++++\n", __FUNCTION__);\r
226         Ctp_it7250->input_dev->name = "CTS_Ctp_it7250";\r
227         Ctp_it7250->input_dev->phys = "CTS_Ctp_it7250/input1";\r
228         Ctp_it7250->input_dev->dev.parent = &client->dev;\r
229      //no need to open & close it,it will do it automaticlly;noted by robert\r
230         Ctp_it7250->input_dev->open = Ctp_it7250_touch_open;\r
231         Ctp_it7250->input_dev->close = Ctp_it7250_touch_close;\r
232 \r
233         __set_bit(EV_ABS, Ctp_it7250->input_dev->evbit);\r
234         __set_bit(ABS_X, Ctp_it7250->input_dev->absbit);\r
235         __set_bit(ABS_Y, Ctp_it7250->input_dev->absbit);\r
236 \r
237         __set_bit(EV_SYN, Ctp_it7250->input_dev->evbit);\r
238         __set_bit(EV_KEY, Ctp_it7250->input_dev->evbit);\r
239         __set_bit(BTN_TOUCH, Ctp_it7250->input_dev->keybit);\r
240 \r
241 for (i = 0; i < ARRAY_SIZE(panel_key_info); i++)\r
242 {rk28printk("ts_input_init  i=%d\r\n",i);\r
243         __set_bit(panel_key_info[i].key,Ctp_it7250->input_dev->keybit);\r
244 }\r
245         //__clear_bit(0, input_dev->keybit);\r
246 \r
247         input_set_abs_params(Ctp_it7250->input_dev, ABS_X, 0, 1000, 0, 0);\r
248         input_set_abs_params(Ctp_it7250->input_dev, ABS_Y, 0, 1000, 0, 0);\r
249 //pr_emerg("+++++++ %s\n", __FUNCTION__); \r
250         ret = input_register_device(Ctp_it7250->input_dev);\r
251         if (ret) {\r
252                 pr_emerg(\r
253                         "%s: unabled to register input device, ret = %d\n",\r
254                         __FUNCTION__, ret);\r
255                 return ret;\r
256         }\r
257         rk28printk("+++++++     %s+++++++END\n", __FUNCTION__);\r
258         return 0;\r
259 \r
260 }\r
261 \r
262 #if 0\r
263 static void CTS_configure_pin(struct i2c_client *client)\r
264 {\r
265         //add  reset pin;but we not used it ;robert\r
266         //had already do it it spi_gpio.c\r
267         //end add       \r
268         //RESET THE CTP;note by robert\r
269         spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH);\r
270         mdelay(5);\r
271         spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_LOW);\r
272         mdelay(5);\r
273         spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH);\r
274         mdelay(5);\r
275 }\r
276 #endif\r
277 \r
278 \r
279 static int Ctp_it7250_init_irq(struct i2c_client *client)\r
280 {\r
281         struct Ctp_it7250_data *Ctp_it7250;\r
282         int ret;\r
283         \r
284         Ctp_it7250 = i2c_get_clientdata(client);\r
285         #if 1\r
286         if ( !gpio_is_valid(client->irq)) {\r
287                 rk28printk("+++++++++++gpio_is_invalid\n");
288                 return -EINVAL;
289         }
290         ret = gpio_request(client->irq, "Ctp_it7250_int");\r
291         if (ret) {
292                 rk28printk( "failed to request Ctp_it7250_init_irq GPIO%d\n",gpio_to_irq(client->irq));\r
293                 return ret;
294         }\r
295 #if 1\r
296 ret = gpio_direction_input(client->irq);\r
297         if (ret) {\r
298                 rk28printk("failed to set CTS_configure_pin gpio input\n");\r
299                 //goto err_free_gpio;\r
300         }\r
301         gpio_pull_updown(client->irq,GPIOPullUp);\r
302 #endif\r
303         rk28printk("%s gpio_to_irq(%d) is %d\n",__FUNCTION__,client->irq,gpio_to_irq(client->irq));\r
304                 \r
305         Ctp_it7250->irq = gpio_to_irq(client->irq);\r
306         #endif\r
307         ret = request_irq(Ctp_it7250->irq, Ctp_it7250_touch_irq, IRQF_TRIGGER_LOW, client->dev.driver->name, Ctp_it7250);\r
308         rk28printk("%s request irq is %d,irq1 is %d,ret is  0x%x\n",__FUNCTION__,client->irq,Ctp_it7250->irq,ret);\r
309         if (ret ) {
310                 rk28printk(KERN_ERR "Ctp_it7250_init_irq: request irq failed,ret is %d\n",ret);\r
311         return ret;
312         }\r
313         return true;    \r
314 }\r
315 \r
316 // ================================================================================\r
317 // Function Name --- GetFirmwareInformation\r
318 // Description --- Get firmware information\r
319 // Input --- NULL\r
320 //Output --- return true if the command execute successfully, otherwuse return false.\r
321 // ================================================================================\r
322 bool GetFirmwareInformation(struct i2c_client *client)\r
323 {\r
324         u8 ucWriteLength, ucReadLength;\r
325         u8 pucData[128];\r
326         u8 ucQuery;\r
327 int i;\r
328         ucWriteLength = 2;\r
329         ucReadLength = 0x09;\r
330         pucData[0] = 0x01;\r
331         pucData[1] = 0x00;\r
332 \r
333         // Query\r
334         do\r
335         {\r
336                 if(!ReadQueryBuffer(client, &ucQuery))\r
337                 {\r
338                         ucQuery = QUERY_BUSY;\r
339                 }\r
340         }while(ucQuery & QUERY_BUSY);\r
341 \r
342         // Write Command\r
343         if(!WriteCommandBuffer(client, pucData, ucWriteLength))\r
344         {\r
345                 return false;\r
346         }\r
347 \r
348         // Query\r
349         do\r
350         {\r
351                 if(!ReadQueryBuffer(client, &ucQuery))\r
352                 {\r
353                         ucQuery = QUERY_BUSY;\r
354                 }\r
355         }while(ucQuery & QUERY_BUSY);\r
356         pucData[5]= 0 ;\r
357          pucData[6]= 0 ;\r
358          pucData[7]= 0 ;\r
359          pucData[8]= 0;\r
360         // Read Command Response\r
361         if(!ReadCommandResponseBuffer(client, pucData, ucReadLength))\r
362         {\r
363                 return false;\r
364         }\r
365 \r
366 \r
367         \r
368 for (i =0;i<ucReadLength;i++)\r
369         rk28printk("GetFirmwareInformation pucData[%d]=%d \r\n",i,pucData[i]);\r
370         if(pucData[5]== 0 \r
371         && pucData[6] == 0 \r
372         && pucData[7] == 0 \r
373         && pucData[8] == 0) \r
374         {\r
375                 // There is no flash code\r
376                 rk28printk("There is no flash code \r\n");\r
377                 return false;\r
378         }\r
379 \r
380         return true;\r
381 }\r
382 \r
383 // ================================================================================\r
384 // Function Name --- SetInterruptNotification\r
385 // Description --- Set It7260 interrupt mode\r
386 // Input --- \r
387 //      ucStatus- the interrupt status\r
388 //      ucType- the interrupt type\r
389 //Output --- return true if the command execute successfully, otherwuse return false.\r
390 // ================================================================================\r
391 bool SetInterruptNotification(struct i2c_client *client, u8 ucStatus, u8 ucType)\r
392 {\r
393         u8 ucWriteLength, ucReadLength;\r
394         u8 pucData[128];\r
395         u8 ucQuery;\r
396 int i;\r
397         ucWriteLength = 4;// 2\r
398         ucReadLength = 2;\r
399         pucData[0] = 0x02;\r
400         pucData[1] = 0x04;\r
401         pucData[2] = ucStatus;\r
402         pucData[3] = ucType;\r
403 \r
404         // Query\r
405         do\r
406         {\r
407                 if(!ReadQueryBuffer(client, &ucQuery))\r
408                 {\r
409                         ucQuery = QUERY_BUSY;\r
410                 }\r
411         }while(ucQuery & QUERY_BUSY);\r
412 \r
413         // Write Command\r
414         if(!WriteCommandBuffer(client, pucData, ucWriteLength))\r
415         {\r
416                 return false;\r
417         }\r
418 \r
419         // Query\r
420         do\r
421         {\r
422                 if(!ReadQueryBuffer(client, &ucQuery))\r
423                 {\r
424                         ucQuery = QUERY_BUSY;\r
425                 }\r
426         }while(ucQuery & QUERY_BUSY);\r
427 \r
428         // Read Command Response\r
429         if(!ReadCommandResponseBuffer(client, pucData, ucReadLength))\r
430         {\r
431                 return false;\r
432         }\r
433 \r
434 for (i =0;i<ucReadLength;i++)\r
435         rk28printk("SetInterruptNotification pucData[%d]=0x%x \r\n",i,pucData[i]);\r
436         if(*(u16*) pucData != 0) \r
437         {\r
438                 return false;\r
439         }\r
440         return true;\r
441 }\r
442 \r
443 \r
444 // ================================================================================\r
445 // Function Name --- IdentifyCapSensor\r
446 // Description --- Identify Capacitive Sensor information\r
447 // Input --- NULL\r
448 //Output --- return true if the command execute successfully, otherwuse return false.\r
449 // ================================================================================\r
450 bool IdentifyCapSensor(struct i2c_client *client)\r
451 {\r
452         u8 ucWriteLength, ucReadLength;\r
453         u8 pucData[128];\r
454         u8 ucQuery=0;int i;\r
455 \r
456         ucWriteLength = 1;\r
457         ucReadLength = 0x0A;\r
458         pucData[0] = 0x00;\r
459         rk28printk("%s\r\n",__FUNCTION__);\r
460         // Query\r
461         do\r
462         {//printk("first wait 111\r\n");\r
463                 if(!ReadQueryBuffer(client, &ucQuery))\r
464                 {\r
465                 \r
466                         rk28printk("first wait \r\n");\r
467                         //means we use resister touchscreen\r
468                         goto error_out;\r
469                         ucQuery = QUERY_BUSY;\r
470                 }\r
471                 rk28printk("%s ucQuery!!!!=0x%x \r\n",__FUNCTION__,ucQuery);\r
472                 if (0xff == ucQuery)\r
473                         goto error_out;\r
474                 mdelay(500);\r
475         }while(ucQuery & QUERY_BUSY);\r
476 \r
477 \r
478         // Write Command\r
479         //rk28printk("%s11\r\n",__FUNCTION__);\r
480         pucData[0] = 0x00;ucWriteLength = 1;\r
481         if(!WriteCommandBuffer(client, pucData, ucWriteLength))\r
482         {\r
483                 rk28printk("WriteCommandBuffer false \r\n");\r
484         //      return false;\r
485         }\r
486 //rk28printk("show1 %s\r\n",__FUNCTION__);\r
487         // Query\r
488         do\r
489         {\r
490                 if(!ReadQueryBuffer(client, &ucQuery))\r
491                 {\r
492                         rk28printk("second wait \r\n");\r
493                         ucQuery = QUERY_BUSY;\r
494                 }rk28printk("%s ucQuery1=0x%x \r\n",__FUNCTION__,ucQuery);\r
495         }while(ucQuery & QUERY_BUSY);\r
496 //rk28printk("show2 %s\r\n",__FUNCTION__);\r
497         // Read Command Response\r
498         for (i=0;i<ucReadLength;i++)\r
499                 {pucData[i]=0x0;\r
500                 rk28printk("pucData[%d]=%d \r\n",i,pucData[i]);\r
501                 }\r
502         if(!ReadCommandResponseBuffer(client, pucData, ucReadLength))\r
503         {\r
504                 rk28printk("ReadCommandResponseBuffer false \r\n");\r
505         //      return false;\r
506         }\r
507 //rk28printk("show %s\r\n",__FUNCTION__);\r
508 for (i=0;i<ucReadLength;i++)\r
509                 rk28printk("pucData[%d]=%d \r\n",i,pucData[i]);\r
510         rk28printk("pucData=%c %c %c %c %c %c %c \r\n",pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],pucData[7]);\r
511 \r
512         return true;\r
513 \r
514 \r
515 error_out:\r
516         return false;\r
517 }\r
518 \r
519 // ================================================================================\r
520 // Function Name --- Get2DResolutions\r
521 // Description --- Get the resolution of X and Y axes\r
522 // Input --- \r
523 //      pwXResolution - the X resolution\r
524 //      pwYResolution - the Y resolution\r
525 //      pucStep - the step\r
526 //Output --- return true if the command execute successfully, otherwuse return false.\r
527 // ================================================================================\r
528 bool Get2DResolutions(struct i2c_client *client, u32 *pwXResolution, u32*pwYResolution, u8 *pucStep)\r
529 {\r
530         u8 ucWriteLength, ucReadLength;\r
531         u8 pucData[128];\r
532         u8 ucQuery;\r
533 int i;\r
534 \r
535         ucWriteLength = 3;\r
536         ucReadLength = 0x07;\r
537         pucData[0] = 0x01;\r
538         pucData[1] = 0x02;\r
539         pucData[2] = 0x00;\r
540 \r
541         // Query\r
542         do\r
543         {\r
544                 if(!ReadQueryBuffer(client, &ucQuery))\r
545                 {\r
546                         ucQuery = QUERY_BUSY;\r
547                 }\r
548         }while(ucQuery & QUERY_BUSY);\r
549 \r
550         // Write Command\r
551         rk28printk("%s WriteCommandBuffer\r\n",__FUNCTION__);\r
552         if(!WriteCommandBuffer(client, pucData, ucWriteLength))\r
553         {\r
554                 return false;\r
555         }\r
556 \r
557         // Query\r
558         do\r
559         {\r
560                 if(!ReadQueryBuffer(client, &ucQuery))\r
561                 {\r
562                         ucQuery = QUERY_BUSY;\r
563                 }\r
564         }while(ucQuery & QUERY_BUSY);\r
565 rk28printk("%s ReadCommandResponseBuffer\r\n",__FUNCTION__);\r
566         // Read Command Response\r
567         if(!ReadCommandResponseBuffer(client, pucData, ucReadLength))\r
568         {\r
569                 return false;\r
570         }\r
571 rk28printk("%s ReadCommandResponseBuffer EDN\r\n",__FUNCTION__);\r
572 \r
573  for (i=0;i<ucReadLength;i++)\r
574         rk28printk("pucData[%d] = 0x%x \r\n",i,pucData[i]);\r
575  \r
576         if(pwXResolution != NULL) \r
577         {\r
578                 *pwXResolution = (pucData[2] | (pucData[3] << 8));\r
579         }\r
580         if(pwYResolution!= NULL) \r
581         {\r
582                 * pwYResolution = (pucData[4] | (pucData[5] << 8));\r
583         }\r
584         if(pucStep!= NULL) \r
585         {\r
586                 * pucStep = pucData[6];\r
587         }\r
588         rk28printk("%s x res=%d y res=%d !\r\n",__FUNCTION__,*pwXResolution,* pwYResolution);\r
589         return true;\r
590 }\r
591 \r
592 // *******************************************************************************************\r
593 // Function Name: CaptouchMode\r
594 // Description: \r
595 //   This function is mainly used to initialize cap-touch controller to active state.\r
596 // Parameters: \r
597 //   dwMode -- the power state to be entered\r
598 // Return value: \r
599 //   return zero if success, otherwise return non zero value\r
600 // *******************************************************************************************\r
601 int CaptouchMode(struct i2c_client *client, u8 dwMode)\r
602 {\r
603         u8 ucQueryResponse;\r
604         u8 pucCommandBuffer[128];\r
605 \r
606         do\r
607         {\r
608                 ReadQueryBuffer(client, &ucQueryResponse);\r
609         }\r
610         while(ucQueryResponse & QUERY_BUSY);\r
611 \r
612         pucCommandBuffer[0] = 0x04;\r
613         pucCommandBuffer[1] = 0x00;\r
614         switch(dwMode)\r
615         {\r
616                 case 0x00:\r
617                         pucCommandBuffer[2] = 0x00;\r
618                         break;\r
619                 case 0x01:\r
620                         pucCommandBuffer[2] = 0x01;\r
621                         break;\r
622                 case 0x02:\r
623                         pucCommandBuffer[2] = 0x02;\r
624                         break;\r
625                 default:\r
626                         return -1;\r
627         }\r
628 \r
629         if(!WriteCommandBuffer(client, pucCommandBuffer,3))\r
630         {\r
631                 return -1;\r
632         }\r
633 \r
634         return 0;\r
635 }\r
636 \r
637 // *******************************************************************************************\r
638 // Function Name: CaptouchReset\r
639 // Description: \r
640 //   This function is mainly used to reset cap-touch controller by sending reset command.\r
641 // Parameters: NULL\r
642 // Return value: \r
643 //   return TRUE if success, otherwise return FALSE\r
644 // *******************************************************************************************\r
645 int CaptouchReset(struct i2c_client *client)\r
646 {\r
647         u8 ucQueryResponse;\r
648         u8 pucCommandBuffer[128];\r
649 \r
650         do\r
651         {\r
652                 ReadQueryBuffer(client, &ucQueryResponse);\r
653         }\r
654         while(ucQueryResponse & QUERY_BUSY);\r
655 \r
656         pucCommandBuffer[0] = 0x6F;\r
657         if(!WriteCommandBuffer(client, pucCommandBuffer,1))\r
658         {\r
659                 return -1;\r
660         }\r
661         mdelay(200);\r
662         \r
663 \r
664         do\r
665         {\r
666                 ReadQueryBuffer(client, &ucQueryResponse);\r
667         }\r
668         while(ucQueryResponse & QUERY_BUSY);\r
669 \r
670 \r
671         if(!ReadCommandResponseBuffer(client, pucCommandBuffer,2))\r
672         {\r
673                 return -1;\r
674         }\r
675 \r
676         if(pucCommandBuffer[0] == 0 && pucCommandBuffer[1] == 0)\r
677         {\r
678                 return 0;\r
679         }\r
680 \r
681         return -1;\r
682 }\r
683 \r
684 \r
685 \r
686 // *******************************************************************************************\r
687 // Function Name: CaptouchHWInitial\r
688 // Description: \r
689 //   This function is mainly used to initialize cap-touch controller to active state.\r
690 // Parameters: NULL\r
691 // Return value: \r
692 //   return zero if success, otherwise return non zero value\r
693 // *******************************************************************************************\r
694 int CaptouchHWInitial(struct i2c_client *client)\r
695 {\r
696         u32 wXResolution=0,wYResolution=0;\r
697         u8 ucStep=0;\r
698         if (!IdentifyCapSensor(client))\r
699         {\r
700                 rk28printk("%s IdentifyCapSensor error \r\n",__FUNCTION__);\r
701                 printk("%s IdentifyCapSensor error \r\n",__FUNCTION__);\r
702                 return false;\r
703                 //goto resetagin;\r
704 }\r
705         #if 1\r
706 if (!GetFirmwareInformation (client))\r
707         {\r
708         rk28printk("%s GetFirmwareInformation error \r\n",__FUNCTION__);\r
709         printk("%s GetFirmwareInformation error \r\n",__FUNCTION__);\r
710         //      goto resetagin;\r
711 }\r
712 \r
713         if (!Get2DResolutions(client, &wXResolution, &wYResolution, &ucStep))\r
714         {\r
715         rk28printk("%s Get2DResolutions error \r\n",__FUNCTION__);\r
716         printk("%s Get2DResolutions error \r\n",__FUNCTION__);\r
717         //      goto resetagin;\r
718 }\r
719 \r
720 //no need to set interrupt mode because firmware has done that;note by robert\r
721         #if 0\r
722         if (!SetInterruptNotification(client, 0x01, 0x00))\r
723         {\r
724         rk28printk("%s SetInterruptNotification error \r\n",__FUNCTION__);\r
725         goto resetagin;\r
726 }\r
727         #endif\r
728         //note end\r
729 #endif\r
730         return true;\r
731 \r
732 #if 0\r
733 resetagin:\r
734         if (!CaptouchReset(client))\r
735                 rk28printk("CaptouchReset success \r\n");\r
736         mdelay(100);\r
737         #endif\r
738 //      if (!CaptouchMode(client, 0x00))\r
739         //      rk28printk("CaptouchMode success \r\n");\r
740 }\r
741 \r
742 \r
743 // *******************************************************************************************\r
744 // Function Name: CaptouchGetSampleValue\r
745 // Description: \r
746 //   This function is mainly used to get sample values which shall contain x, y position and pressure. \r
747 // Parameters:\r
748 //   pdwSampleX -- the pointer of returned X coordinates\r
749 //   pdwSampleY -- the pointer of returned Y coordinates\r
750 //   pdwPressure -- the pointer of returned pressures\r
751 // Return value: \r
752 //   The return value is the number of sample points. Return 0 if failing to get sample. The maximum //   return value is 10 in normal case. If the CTP controller does not support pressure measurement, //   the return value is the sample values OR with PRESSURE_INVALID.\r
753 // *******************************************************************************************\r
754 int CaptouchGetSampleValue(u32* pdwSampleX, u32* pdwSampleY, u32* pdwPressure)\r
755 {\r
756         int nRet;\r
757         int i;\r
758 \r
759         if(gpucPointBuffer[1] & 0x01)\r
760         {\r
761                 return MAX_FINGER_NUM + 1;\r
762         }\r
763 \r
764         nRet = 0;\r
765         for(i = 0; i < MAX_FINGER_NUM; i++)\r
766         {\r
767                 if(gpucPointBuffer[0] & (1 << i))\r
768                 {\r
769                         nRet++;\r
770                         #if 0\r
771                         pdwSampleX[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0x0F) << 8) + \r
772 (u32)gpucPointBuffer[i * 4 + 2];;\r
773                         pdwSampleY[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0xF0) << 4) + \r
774 (u32)gpucPointBuffer[i * 4 + 4];\r
775                         pdwPressure[i] = (u32)(gpucPointBuffer[i * 4 + 5] & 0x0F);\r
776                         #else \r
777                         pdwSampleX[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0x0F) << 8) | \r
778 gpucPointBuffer[i * 4 + 2];\r
779                         pdwSampleY[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0xF0) << 4) | \r
780 gpucPointBuffer[i * 4 + 4];\r
781                         pdwPressure[i] = (u32)(gpucPointBuffer[i * 4 + 5] & 0x0F);\r
782 \r
783                 //      rk28printk("%s x[%d]=%d  y[%d]=%d \r\n",__FUNCTION__,i,pdwSampleX[i],i,pdwSampleY[i]);\r
784                         #endif\r
785                 }\r
786                 else\r
787                 {\r
788                         pdwSampleX[i] = 0;\r
789                         pdwSampleY[i] = 0;\r
790                         pdwPressure[i] = 0;\r
791                 }\r
792         }\r
793         //add by robert for test\r
794         #if 0\r
795         for(i = 0; i < MAX_FINGER_NUM; i++)\r
796         {\r
797                 rk28printk("%s x[%d]=%d  y[%d]=%d \r\n",__FUNCTION__,0,pdwSampleX[0],0,pdwSampleY[0]);\r
798         }\r
799         #endif\r
800         return nRet;\r
801 }\r
802 \r
803 // *******************************************************************************************\r
804 // Function Name: CaptouchGetGesture\r
805 // Description: \r
806 //   This function is mainly used to initialize cap-touch controller to active state.\r
807 // Parameters: NULL\r
808 // Return value: \r
809 //   return gesture ID\r
810 // *******************************************************************************************\r
811 int CaptouchGetGesture(void)\r
812 {\r
813         return (int)gpucPointBuffer[1];\r
814 }\r
815 \r
816 static void  Ctp_it7250_delaywork_func(struct work_struct  *work)\r
817 {
818         
819         u8 ucQueryResponse;\r
820         u32 dwTouchEvent;\r
821         struct delayed_work *delaywork = container_of(work, struct delayed_work, work);\r
822         struct Ctp_it7250_data *Ctp_it7250 = container_of(delaywork, struct Ctp_it7250_data, delaywork);        \r
823         struct i2c_client *client = Ctp_it7250->client;\r
824         \r
825         int PE1status = 0;\r
826 \r
827 //      rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
828 \r
829 \r
830         //PE1status =  gpio_get_value(Ctp_it7250_GPIO_INT);\r
831         PE1status =  gpio_get_value(client->irq);\r
832         //  PE1status ÎªµÍ£¬±íʾµÍµçƽÖжÏÓÐЧ \r
833         if (!PE1status)\r
834                 {\r
835         //      rk28printk("%s PE1status low!!  \r\n",__FUNCTION__);\r
836         if(!ReadQueryBuffer(client, &ucQueryResponse))\r
837         {rk28printk("%s++++ %d  ucQueryResponse=0x%x \r\n",__FUNCTION__,__LINE__,ucQueryResponse);\r
838                 return false;\r
839         }\r
840 //rk28printk("%s++++ %d  ucQueryResponse=0x%x \r\n",__FUNCTION__,__LINE__,ucQueryResponse);\r
841         // Touch Event\r
842         if(ucQueryResponse & QUERY_POINT)\r
843         {//rk28printk("%s++++ %d  \r\n",__FUNCTION__,__LINE__);\r
844                 if(!ReadPointBuffer(client, gpucPointBuffer))\r
845                 {rk28printk("%s++++ %d  \r\n",__FUNCTION__,__LINE__);\r
846                         return false;\r
847                 }\r
848 //rk28printk("%s++++ %d  ucQueryResponse=0x%x gpucPointBuffer=0x%x\r\n",__FUNCTION__,__LINE__,ucQueryResponse,gpucPointBuffer[0] & 0xF0);\r
849                 switch(gpucPointBuffer[0] & 0xF0)\r
850                 {\r
851                         case 0x00:\r
852                                 dwTouchEvent = CaptouchGetSampleValue(gpdwSampleX, gpdwSampleY, gpdwPressure);\r
853                                 if(dwTouchEvent == 0)\r
854                                 {\r
855                                         //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_FINGER_RELEASE);\r
856                                         rk28printk("TOUCH Release  !!\r\n");\r
857                                         input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 0);\r
858                                         input_sync(Ctp_it7250->input_dev);\r
859                                 }\r
860                                 else if(dwTouchEvent <=MAX_FINGER_NUM) //CTP_MAX_FINGER_NUMBER)\r
861                                 {\r
862                                         //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_FINGER_ASSERT);\r
863                         if ((abs(Ctp_it7250->temp_x -gpdwSampleX[0])>10)  ||( abs(Ctp_it7250->temp_y-gpdwSampleY[0])>10))\r
864                                         {\r
865                                         input_report_abs(Ctp_it7250->input_dev, ABS_X, gpdwSampleX[0]);// & 0xfff\r
866                                         input_report_abs(Ctp_it7250->input_dev, ABS_Y, gpdwSampleY[0]); //& 0xfff\r
867                                         input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 1);\r
868                                         input_sync(Ctp_it7250->input_dev);\r
869                                         rk28printk("x=%d  y=%d \r\n",gpdwSampleX[0],gpdwSampleY[0]);\r
870                                         Ctp_it7250->temp_x=gpdwSampleX[0];\r
871                                         Ctp_it7250->temp_y=gpdwSampleY[0];\r
872                                         }\r
873                                 else\r
874                                         rk28printk("the same \r\n");\r
875                                 }\r
876                                 else\r
877                                 {\r
878                                         rk28printk("%s SYSTEM_TOUCH_EVENT_PALM_DETECT \r\n",__FUNCTION__);\r
879                                         //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_PALM_DETECT);\r
880                                 }\r
881                                 break;\r
882                         case 0x80:\r
883                                 dwTouchEvent = CaptouchGetGesture();\r
884                                 //SynchroSystemEvent(SYSTEM_GESTURE_EVENT);\r
885                                 rk28printk("gesture:0x%x \r\n",dwTouchEvent);\r
886                                 break;\r
887                         //for keypad below\r
888                         case 0x40:\r
889                                 rk28printk("ID of button is 0x%x status is 0x%x\r\n",gpucPointBuffer[1],gpucPointBuffer[2]);\r
890                                 switch (gpucPointBuffer[1]) \r
891                                         {case 0x01:\r
892                                                 rk28printk("home \r\n");\r
893                                                 if (gpucPointBuffer[2])\r
894                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
895                                                 else\r
896                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
897                                                 break;\r
898                                         case 0x02:\r
899                                                 rk28printk("menu \r\n");\r
900                                                 if (gpucPointBuffer[2])\r
901                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
902                                                 else\r
903                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
904                                                 break;\r
905                                         case 0x03:\r
906                                                 rk28printk("back \r\n");\r
907                                                 if (gpucPointBuffer[2])\r
908                                                         {\r
909                                                         rk28printk("back down key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
910                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
911                                                         }\r
912                                                 else\r
913                                                         {\r
914                                                         rk28printk("back up key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
915                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
916                                                         }\r
917                                                 break;\r
918                                         case 0x04:\r
919                                                 rk28printk("find \r\n");\r
920                                                 if (gpucPointBuffer[2])\r
921                                                         {\r
922                                                         rk28printk("find down key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
923                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
924                                                         }\r
925                                                 else\r
926                                                         {\r
927                                                         rk28printk("find up key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
928                                                         input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
929                                                         }\r
930                                                 break;          \r
931                                         default:\r
932                                                         rk28printk("shit default \r\n");\r
933                                                 break;\r
934                                         }\r
935                                 break;\r
936                         default:\r
937                                 rk28printk("default \r\n");\r
938                                 break;\r
939                 }\r
940         }\r
941         else if (ucQueryResponse & QUERY_ERROR)\r
942                 {\r
943                 if (!CaptouchReset(client))\r
944                 rk28printk("!! CaptouchReset success \r\n");\r
945                 mdelay(100);\r
946         //if (!CaptouchMode(client, 0x00))\r
947                 //rk28printk("!! CaptouchMode success \r\n");\r
948                 }\r
949         }\r
950 //      rk28printk("enable ctp_irq=%d \r\n",Ctp_it7250->irq);\r
951         \r
952         enable_irq(Ctp_it7250->irq);\r
953         //²»ÊDzéѯģʽ£¬²»ÐèÒªÂÖѯ\r
954 //schedule_delayed_work(&Ctp_it7250->delaywork,msecs_to_jiffies(1000));\r
955 \r
956 }\r
957 \r
958  static int  Ctp_it7250_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
959 {\r
960         struct Ctp_it7250_data *Ctp_it7250;\r
961 \r
962         Ctp_it7250_client = client;\r
963         rk28printk("+++++++     %s+++++++\n", __FUNCTION__);\r
964         Ctp_it7250 = kzalloc(sizeof(struct Ctp_it7250_data), GFP_KERNEL);\r
965         if (!Ctp_it7250) \r
966                 {\r
967                 rk28printk("[Ctp_it7250_probe]:alloc data failed.\n");\r
968                 return  -ENOMEM;\r
969                 }\r
970 \r
971 //      INIT_WORK(&Ctp_it7250->irq_work, Ctp_it7250_irq_worker);\r
972         INIT_DELAYED_WORK(&Ctp_it7250->delaywork, Ctp_it7250_delaywork_func);\r
973 \r
974         Ctp_it7250->client = client;\r
975         i2c_set_clientdata(client, Ctp_it7250);\r
976         \r
977         if (!CaptouchHWInitial(client))\r
978                 goto  err_free_mem;\r
979         Ctp_it7250_init_irq(client);    \r
980         ts_input_init(client);\r
981 //      CTS_configure_pin(client);\r
982 \r
983 #if 0\r
984         lp8725_lilo_en(2,0);\r
985         mdelay(100);\r
986 \r
987         lp8725_lilo_en(2,1);\r
988         mdelay(100);\r
989         lp8725_set_lilo_vol(2,300);\r
990         mdelay(5);\r
991 #endif\r
992 \r
993 //²»ÊDzéѯģʽ£¬²»ÐèÒªÂÖѯ\r
994 //schedule_delayed_work(&Ctp_it7250->delaywork,msecs_to_jiffies(50));\r
995 \r
996 \r
997         rk28printk("+++++++     %s+++++++\n", __FUNCTION__);\r
998         return 0;\r
999         err_free_mem:\r
1000         kfree(Ctp_it7250);\r
1001          return false;\r
1002 \r
1003 }\r
1004 \r
1005 \r
1006 \r
1007 static int Ctp_it7250_remove(struct i2c_client *client)\r
1008 {
1009         
1010         return 0;
1011 }
1012 \r
1013 \r
1014 \r
1015 #ifdef  CONFIG_PM\r
1016 static int Ctp_it7250_suspend(struct i2c_client *client, pm_message_t state)\r
1017 {//pr_emerg("\n irq1=%d \n",irq1);\r
1018         struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client);\r
1019 \r
1020         rk28printk("%s\n",__func__);\r
1021 \r
1022         CaptouchMode(client, 2);\r
1023         disable_irq(Ctp_it7250->irq);\r
1024 \r
1025         return 0;\r
1026 }\r
1027 \r
1028 static int Ctp_it7250_resume(struct i2c_client *client)\r
1029 {\r
1030         struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client);\r
1031 \r
1032         u8 ucQuery;\r
1033         rk28printk("%s\n",__func__);\r
1034 \r
1035         if(gpio_direction_output(client->irq,GPIO_LOW))\r
1036                 printk("%s:set pin output error\n",__func__);\r
1037         msleep(20);\r
1038         ReadQueryBuffer(client, &ucQuery);\r
1039         if (gpio_direction_input(client->irq)) \r
1040                 printk("%s:failed to set CTS_configure_pin gpio input\n",__func__);\r
1041         gpio_pull_updown(client->irq,GPIOPullUp);\r
1042         msleep(20);\r
1043         enable_irq(Ctp_it7250->irq);\r
1044         \r
1045         return 0;\r
1046 }\r
1047 #else\r
1048 #define Ctp_it7250_suspend              NULL\r
1049 #define Ctp_it7250_resume               NULL\r
1050 #endif\r
1051 \r
1052 static const struct i2c_device_id Ctp_it7250_id[] = {\r
1053                 {"Ctp_it7250", 0},\r
1054                 { }
1055 };\r
1056 \r
1057 static struct i2c_driver Ctp_it7250_driver = {\r
1058         .driver = {\r
1059                 .name   = "Ctp_it7250",\r
1060         },\r
1061         .id_table       = Ctp_it7250_id,\r
1062         .probe  = Ctp_it7250_probe,\r
1063          .remove     =  Ctp_it7250_remove,\r
1064          .suspend  = Ctp_it7250_suspend,\r
1065          .resume = Ctp_it7250_resume,\r
1066 };\r
1067 \r
1068 static int __init Ctp_it7250_init(void)\r
1069 {\r
1070         int ret;        \r
1071         rk28printk("+++++++     %s++\n", __FUNCTION__);\r
1072         ret=i2c_add_driver(&Ctp_it7250_driver);\r
1073         rk28printk("**Ctp_it7250_init_init return %d**\n",ret);\r
1074         return ret;\r
1075 }\r
1076 \r
1077 static void __exit Ctp_it7250_exit(void)\r
1078 {\r
1079         /* We move these codes here because we want to detect the\r
1080          * pen down event even when touch driver is not opened.\r
1081          */\r
1082         i2c_del_driver(&Ctp_it7250_driver);\r
1083 }\r
1084 \r
1085  late_initcall(Ctp_it7250_init);\r
1086 module_exit(Ctp_it7250_exit);\r
1087 \r
1088 MODULE_AUTHOR("Robert_mu<robert.mu@rahotech.com>");\r
1089 \r
1090 \r