input: touchscreen: add touch screen of gslx680 for rk3399-firefly-edp
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / it7260_ts.c
1 /****************************************************************************************\r
2  * driver/input/touchscreen/i2cpca955x.c\r
3  *Copyright     :ROCKCHIP  Inc\r
4  *Author        :       sfm\r
5  *Date          :  2010.2.5\r
6  *This driver use for rk28 chip extern touchscreen. Use i2c IF ,the chip is pca955x\r
7  *description£º\r
8  ********************************************************************************************/\r
9 #include <linux/module.h>\r
10 #include <linux/delay.h>\r
11 #include <linux/earlysuspend.h>\r
12 #include <linux/hrtimer.h>\r
13 #include <linux/i2c.h>\r
14 #include <linux/input.h>\r
15 #include <linux/interrupt.h>\r
16 #include <linux/io.h>\r
17 #include <linux/platform_device.h>\r
18 #include <linux/async.h>\r
19 #include <linux/workqueue.h>\r
20 #include <mach/gpio.h>\r
21 #include <linux/irq.h>\r
22 #include <mach/board.h>\r
23 \r
24 #ifdef CONFIG_ANDROID_POWER\r
25 #include <linux/android_power.h>\r
26 #endif\r
27 \r
28 #define         IT7260_DEBUG     0\r
29 \r
30 #if IT7260_DEBUG\r
31 #define it7250_debug(msg...) printk(msg)\r
32 #else\r
33 #define it7250_debug(msg...)\r
34 #endif\r
35 \r
36 /******************************************\r
37                 DEBUG\r
38 *** ***************************************/\r
39 #define IT7260_IIC_SPEED                200*1000\r
40 \r
41 #define IT7260_MAX_X     800//1024//1020//800\r
42 #define IT7260_MAX_Y    600//768//600//480\r
43 \r
44 #define Mulitouch_Mode  1\r
45 #define Singltouch_Mode 0\r
46 \r
47 struct touch_event{\r
48         short x;\r
49         short y;\r
50 };\r
51 struct MultiTouch_event{\r
52         short x1;\r
53         short y1;\r
54         short x2;\r
55         short y2;\r
56         char p1_press;\r
57         char p2_press;  \r
58 };\r
59 #define TS_POLL_DELAY   (10*1000000) /* ns delay before the first sample */\r
60 #define TS_POLL_PERIOD  (15*1000000) /* ns delay between samples */\r
61 \r
62 struct it7260_dev{      \r
63         struct i2c_client *client;\r
64         struct input_dev *input;\r
65         spinlock_t      lock;\r
66         char    phys[32];\r
67         int             irq;\r
68 #if Singltouch_Mode\r
69         struct touch_event  point;  \r
70 #else\r
71         struct MultiTouch_event  point;\r
72         char   P_state;\r
73         char   p_DelayTime;\r
74 #endif\r
75 \r
76         struct delayed_work work;\r
77         struct workqueue_struct *wq;\r
78         bool            pendown;\r
79         bool     status;\r
80         bool    pass;\r
81         struct timer_list timer;//hrtimer  timer;\r
82         int has_relative_report;\r
83 };\r
84 \r
85 \r
86 #define COMMAND_BUFFER_INDEX 0x20\r
87 #define QUERY_BUFFER_INDEX 0x80\r
88 #define COMMAND_RESPONSE_BUFFER_INDEX 0xA0\r
89 #define POINT_BUFFER_INDEX 0xE0\r
90 #define QUERY_SUCCESS 0x00\r
91 #define QUERY_BUSY 0x01\r
92 #define QUERY_ERROR 0x02\r
93 #define QUERY_POINT 0x80\r
94 \r
95 \r
96 static char cal_status = 0;\r
97 \r
98 /*read the it7260 register ,used i2c bus*/\r
99 static int it7260_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)\r
100 {\r
101         int ret; \r
102         ret = i2c_master_reg8_recv(client, reg, buf, len, IT7260_IIC_SPEED);\r
103         return ret; \r
104 }\r
105 \r
106 \r
107 /* set the it7260 registe,used i2c bus*/\r
108 static int it7260_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)\r
109 {\r
110         int ret; \r
111         ret = i2c_master_reg8_send(client, reg, buf, (int)len, IT7260_IIC_SPEED);\r
112         return ret;\r
113 }\r
114 \r
115 void ReadQueryBuffer(struct i2c_client *client,u8 pucData[])\r
116 {\r
117         it7260_read_regs(client,QUERY_BUFFER_INDEX,pucData,1);\r
118 }\r
119 \r
120 bool ReadCommandResponseBuffer(struct i2c_client *client,u8 pucData[], unsigned int unDataLength)\r
121 {\r
122         return  it7260_read_regs(client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,unDataLength);\r
123 \r
124 }\r
125 \r
126 bool ReadPointBuffer(struct i2c_client *client,u8 pucData[])\r
127 {\r
128         return  it7260_read_regs(client,POINT_BUFFER_INDEX,pucData,14);\r
129 \r
130 }\r
131 \r
132 \r
133 int WriteCommandBuffer(struct i2c_client *client,u8 pucData[], unsigned int unDataLength)\r
134 {\r
135         return it7260_set_regs(client,COMMAND_BUFFER_INDEX,pucData,unDataLength);\r
136 }\r
137 \r
138 \r
139 \r
140 /*\r
141 sleep\r
142 */\r
143 static void it7260_chip_sleep(void)\r
144 {       \r
145 /*\r
146         u8 pucPoint1[12] ={0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};\r
147         u8 pucPoint2[12] ={0x11,0x01,0x01};\r
148         int aaa;\r
149         aaa = WriteCommandBuffer(ts_dev->client,pucPoint1, 10);\r
150         if(aaa <0)\r
151         {\r
152                 printk("set mode err\n");\r
153         }\r
154         aaa = WriteCommandBuffer(ts_dev->client,pucPoint2, 3);\r
155 */\r
156 }\r
157 /*\r
158 wake up\r
159 */\r
160 static void it7260_chip_wakeup(void)\r
161 {\r
162 \r
163 }\r
164 \r
165 \r
166 struct it7260_dev *g_dev;\r
167 #if 1\r
168 void ite_ts_test()\r
169 {\r
170 \r
171         u8 ucWriteLength, ucReadLength;\r
172         u8 pucData[128];\r
173         u8 ucQuery;\r
174         ucWriteLength = 1;\r
175         ucReadLength = 0x0A;\r
176         pucData[0] = 0x00;\r
177         \r
178         // Query\r
179         \r
180         do\r
181         {\r
182                 ReadQueryBuffer(g_dev->client,&ucQuery);\r
183                 if(ucQuery == 0)\r
184                         break;\r
185         }while(ucQuery & QUERY_BUSY);\r
186 \r
187        //IdentifyCapSensor \r
188        WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);\r
189 \r
190         it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,10);\r
191         printk("[%c][%c][%c][%c][%c][%c][%c]\n",pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],pucData[7]);\r
192 \r
193        // \r
194        ucWriteLength = 2;\r
195         pucData[0] = 0x01;\r
196         pucData[1] = 0x04;\r
197        WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);\r
198            \r
199        it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,2);\r
200        printk("[%x][%x]\n",pucData[0],pucData[1]);\r
201 \r
202         ucWriteLength = 4;\r
203         pucData[0] = 0x02;\r
204         pucData[1] = 0x04;\r
205         pucData[2] = 0x01;\r
206         pucData[3] = 0x00;\r
207        WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);\r
208 \r
209         ucWriteLength = 2;\r
210         pucData[0] = 0x01;\r
211         pucData[1] = 0x04;\r
212        WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);\r
213            \r
214        it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,2);\r
215            \r
216        printk("[%x][%x]\n",pucData[0],pucData[1]);\r
217 //      printk("[%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x]\n",pucData[0],pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],\r
218 //              pucData[7],pucData[8],pucData[9],pucData[10],pucData[11],pucData[12],pucData[13]);\r
219       \r
220 \r
221 /*      if(pucData[1] != 'I'\r
222         || pucData[2] != 'T'\r
223         || pucData[3] != 'E'\r
224         || pucData[4] != '7'\r
225         || pucData[5] != '2'\r
226         || pucData[6] != '6'\r
227         || pucData[7] != '0')\r
228         {\r
229                 // firmware signature is not match\r
230                 return false;\r
231         }*/\r
232 \r
233         return ;\r
234 \r
235 }\r
236 #endif\r
237 \r
238 \r
239 \r
240 \r
241 static int set_mode(struct it7260_dev *ts_dev)\r
242 {\r
243         u8 pucPoint[12] ={0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};\r
244         int ret;\r
245         printk("start to calibration......\n");\r
246         ret = WriteCommandBuffer(ts_dev->client,pucPoint, 12);\r
247         if(ret <0)\r
248         {\r
249                 printk("set mode err\n");\r
250                 cal_status = 0;\r
251         }\r
252         else\r
253         {\r
254                 printk("it7260 set mode ok\n");\r
255                 cal_status = 1;\r
256         }\r
257         return ret;\r
258 }\r
259 \r
260 static int set_sleep_mode(struct it7260_dev *ts_dev)\r
261 {\r
262         u8 pucPoint[3] ={0x04,0x00,0x02};\r
263         u8 pucPoint1[2] ={0x11,0x01};\r
264         int aaa;\r
265         aaa = WriteCommandBuffer(ts_dev->client,pucPoint1, 2);\r
266         //aaa = WriteCommandBuffer(ts_dev->client,pucPoint, 3);\r
267         if(aaa <0)\r
268         {\r
269                 printk("set mode err\n");\r
270         }\r
271 \r
272 }\r
273 \r
274 static int set_active_mode(struct it7260_dev *ts_dev)\r
275 {\r
276         u8 pucPoint[12] ={0x04,0x00,0x00};\r
277         int aaa;\r
278         aaa = WriteCommandBuffer(ts_dev->client,pucPoint, 3);\r
279         if(aaa <0)\r
280         {\r
281                 printk("set mode err\n");\r
282         }\r
283 }\r
284 \r
285 \r
286 static int read_point(struct it7260_dev *ts_dev )\r
287 {\r
288 \r
289 \r
290         u8 pucPoint[20];\r
291         u8 ucQuery =0;\r
292         u8 readbuf[2];\r
293         u8 i;\r
294         int xraw, yraw, xtmp, ytmp;\r
295         char pressure_point,z,w;\r
296         int finger2_pressed=0;\r
297 \r
298 \r
299         ReadQueryBuffer(ts_dev->client,&ucQuery);\r
300         it7250_debug("ucQuery = 0x%x\n",ucQuery);\r
301         if(ucQuery == 0 )\r
302         {       \r
303                 it7250_debug("ucQuery == 0  return \n");\r
304 \r
305                 return 0;\r
306         }\r
307 \r
308         \r
309         if(ucQuery == 2)\r
310         {\r
311                 ReadCommandResponseBuffer(ts_dev->client,readbuf, 2);\r
312                 it7250_debug(" read buf [0] = 0x0%x , buf [1] = 0x0%x\n",readbuf[0],readbuf[1]);\r
313                 it7260_read_regs(ts_dev->client,POINT_BUFFER_INDEX,pucPoint,14);\r
314 \r
315                 return 0;\r
316         }\r
317         else\r
318         {\r
319                 if(ucQuery & 0x80)\r
320                 {\r
321                         it7260_read_regs(ts_dev->client,POINT_BUFFER_INDEX,pucPoint,14);\r
322 \r
323                         if(pucPoint[0] & 0xF0)                          \r
324                         {\r
325                                 it7250_debug("a\n");\r
326                                 return 0;\r
327                         }                               \r
328                         else    {                                       \r
329                                 if(pucPoint[1] & 0x01)                                  \r
330                                 {\r
331                                         it7250_debug("b\n");\r
332                                         return 0;\r
333                                 }                       \r
334                         }\r
335 \r
336 \r
337                         if(((pucPoint[0] & 0x07)==0)/*|| GPIOGetPinLevel(it7260_IRQ_PIN)*/)                             \r
338                         {                               \r
339                                 //sisdbg("=Read_Point pull=  [%d][%d]\n",pucPoint[0] & 0x07,GPIOGetPinLevel(it7260_IRQ_PIN));\r
340 #if Singltouch_Mode                                     \r
341                                 ts_dev->status = 0;\r
342                                 ts_dev->pass = 1;\r
343 \r
344                                 input_report_key(ts_dev->input, BTN_TOUCH, 0);                                  \r
345                                 //input_report_abs(ts_dev->input, ABS_PRESSURE, 0);                                     \r
346                                 input_sync(ts_dev->input);\r
347                                 return;\r
348 #else                                   \r
349                                 ts_dev->pass = 1;       \r
350                                 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, 0);                                 \r
351                                 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, 15);        \r
352                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, ts_dev->point.x1);                                   \r
353                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ts_dev->point.y1);\r
354                                 input_report_key(ts_dev->input, BTN_TOUCH, 0);\r
355                                 input_mt_sync(ts_dev->input);\r
356                                 it7250_debug("TP up\n");\r
357                                 if(ts_dev->has_relative_report ==2)\r
358                                 {\r
359                                         ts_dev->has_relative_report = 0;\r
360                                         input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, 0);                                 \r
361                                         input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, 15);        \r
362                                         input_report_abs(ts_dev->input, ABS_MT_POSITION_X, ts_dev->point.x2);                                   \r
363                                         input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ts_dev->point.y2);   \r
364                                         input_report_key(ts_dev->input, BTN_2, 0);\r
365                                         it7250_debug("TP up\n");\r
366                                         input_mt_sync(ts_dev->input);\r
367                                 }\r
368                                 input_sync(ts_dev->input);\r
369                                 \r
370                                 return 0;\r
371 #endif                  \r
372         \r
373                         }       \r
374                         else\r
375                         {\r
376                                         if(pucPoint[0] & 0x01)                          \r
377                                         {                                                                               \r
378                                                                                         \r
379                                                 xraw = ((pucPoint[3] & 0x0F) << 8) + pucPoint[2];                                       \r
380                                                 yraw = ((pucPoint[3] & 0xF0) << 4) + pucPoint[4];                                       \r
381                                                 pressure_point=pucPoint[5]&0x0f;                                                                                \r
382                                                 xtmp = xraw;                            \r
383                                                 ytmp = yraw;            \r
384 #if Mulitouch_Mode\r
385                                                 ts_dev->point.x1 = xtmp;\r
386                                                 ts_dev->point.y1 = ytmp;\r
387                                                 ts_dev->has_relative_report = 1;\r
388 #endif\r
389                                                 if(pressure_point==4)                                   \r
390                                                 {                                               \r
391                                                         z=10;                                           \r
392                                                         w=15;                                   \r
393                                                 }                                       \r
394                                                 else                                    \r
395                                                 {                                               \r
396                                                         z=10;                                           \r
397                                                         w=15;                                   \r
398                                                 }                                       \r
399                                                 it7250_debug("=Read_Point1 x=%d y=%d p=%d=\n",xtmp,ytmp,pressure_point);\r
400                                                 \r
401 #if Singltouch_Mode             \r
402                                                 if(ts_dev->pass == 1)\r
403                                                 {\r
404                                                         ts_dev->pass = 0;\r
405                                                         return 0;\r
406                                                 }///\r
407 \r
408                                                 if(ts_dev->status == 0)\r
409                                                 {\r
410                                                         ts_dev->status = 1;\r
411                                                         input_report_abs(ts_dev->input, ABS_X, xtmp);                                   \r
412                                                         input_report_abs(ts_dev->input, ABS_Y, ytmp);   \r
413                                                         input_report_key(ts_dev->input, BTN_TOUCH, 1);          \r
414                                                 }else{\r
415                                                         input_report_abs(ts_dev->input, ABS_X, xtmp);                                   \r
416                                                         input_report_abs(ts_dev->input, ABS_Y, ytmp);\r
417                                                 }\r
418                                         \r
419                                                 input_report_abs(ts_dev->input, ABS_PRESSURE, 1);                                       \r
420                                                 ts_dev->pendown = 1;\r
421                                                 input_sync(ts_dev->input);\r
422                                                 \r
423 #else                                                                           \r
424                                                 if(ts_dev->pass == 1)\r
425                                                 {\r
426                                                         ts_dev->pass = 0;\r
427                                                         return 0;\r
428                                                 }///\r
429 \r
430                                                 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, z);                                 \r
431                                                 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, w);                                                                         \r
432                                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, xtmp);                                       \r
433                                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ytmp);               \r
434                                                 input_report_key(ts_dev->input, BTN_TOUCH, 1);\r
435                                                 ts_dev->pendown = 1;\r
436                                                 it7250_debug("TP down\n");\r
437                                                 input_mt_sync(ts_dev->input);\r
438                                                 \r
439 #endif                                                                                          \r
440                                         }\r
441 #if Mulitouch_Mode\r
442 \r
443                                          if(pucPoint[0] & 0x02)                         \r
444                                          {                                      \r
445                                                 xraw = ((pucPoint[7] & 0x0F) << 8) + pucPoint[6];                                       \r
446                                                 yraw = ((pucPoint[7] & 0xF0) << 4) + pucPoint[8];                                       \r
447                                                 pressure_point=pucPoint[9]&0x0f;                                        \r
448                                                 xtmp = xraw;                                    \r
449                                                 ytmp = yraw;          \r
450                                                 ts_dev->point.x2 = xtmp;\r
451                                                 ts_dev->point.y2 = ytmp;\r
452                                                 ts_dev->has_relative_report = 2;\r
453                                                 it7250_debug("=Read_Point2 x=%d y=%d p=%d=\n",xtmp,ytmp,pressure_point);                                        \r
454                                                 if(pressure_point==4)                                   \r
455                                                 {                                               \r
456                                                         z=10;                                           \r
457                                                         w=15;                                   \r
458                                                 }                                       \r
459                                                 else                                    \r
460                                                         {                                               \r
461                                                         z=10;                                           \r
462                                                         w=15;                                   \r
463                                                 }\r
464 #if Singltouch_Mode             \r
465                                                 if(ts_dev->pass == 1)\r
466                                                 {\r
467                                                         ts_dev->pass = 0;\r
468                                                         return 0;\r
469                                                 }\r
470 \r
471                                                 input_report_abs(ts_dev->input, ABS_X, xtmp);                                   \r
472                                                 input_report_abs(ts_dev->input, ABS_Y, ytmp);                                   \r
473                                                 input_report_key(ts_dev->input, BTN_TOUCH, 1);                                  \r
474                                                 ts_dev->pendown = 1;\r
475                                                 input_sync(ts_dev->input);\r
476 #else                                   \r
477                                                 if(ts_dev->pass == 1)\r
478                                                 {\r
479                                                         ts_dev->pass = 0;\r
480                                                         return 0;\r
481                                                 }\r
482 \r
483                                                 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, z);                                 \r
484                                                 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, w);                                 \r
485                                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, xtmp);                                       \r
486                                                 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ytmp);       \r
487                                                 input_report_key(ts_dev->input, BTN_2, 1);\r
488                                                 ts_dev->pendown = 1;\r
489                                                 it7250_debug("TP down\n");\r
490                                                 input_mt_sync(ts_dev->input);\r
491 #endif\r
492                                         \r
493                                         }               \r
494 #endif\r
495         \r
496                                 }\r
497                         input_sync(ts_dev->input);      \r
498                 }\r
499                 \r
500         }\r
501         return 0;\r
502 }\r
503 \r
504  static void it7260_dostimer(unsigned long data)\r
505  {\r
506          struct it7260_dev *ts_dev = (struct it7260_dev *)data;  \r
507          read_point(ts_dev);\r
508  }\r
509 \r
510 \r
511  static void it7260_work(struct work_struct *work)\r
512 {
513         struct it7260_dev *ts_dev =\r
514                 container_of(to_delayed_work(work), struct it7260_dev, work);\r
515         read_point(ts_dev);\r
516
517 out:               
518         if (ts_dev->pendown){\r
519                 queue_delayed_work(ts_dev->wq, &ts_dev->work, msecs_to_jiffies(10));\r
520                 ts_dev->pendown = 0;\r
521         }
522         else{
523                 enable_irq(ts_dev->irq);\r
524         }\r
525         \r
526 }
527 static irqreturn_t it7260_irq_hander(int irq, void *handle)\r
528 {
529         struct it7260_dev *ts_dev = handle;\r
530 \r
531         if (1/*!ts_dev->get_pendown || likely(ts_dev->get_pendown_state())*/) {\r
532                 disable_irq_nosync(ts_dev->irq);\r
533                 queue_delayed_work(ts_dev->wq, &ts_dev->work, 0);\r
534         }
535
536         return IRQ_HANDLED;
537 }\r
538 \r
539 static int it7260_detach_client(struct i2c_client *client)\r
540 {\r
541         printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);\r
542         return 0;\r
543 }\r
544 \r
545 static void it7260_shutdown(struct i2c_client *client)\r
546 {\r
547         printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);\r
548 }\r
549 #ifdef CONFIG_ANDROID_POWER\r
550 static void suspend(android_early_suspend_t *h)\r
551 {\r
552         printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);\r
553 }\r
554 static void resume(android_early_suspend_t *h)\r
555 {\r
556         printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);\r
557 }\r
558 static android_early_suspend_t ts_early_suspend;\r
559 #endif\r
560 \r
561 ssize_t tp_cal_show(struct kobject *kobj, struct kobj_attribute *attr,\r
562                          const char *buf, size_t count)\r
563 {\r
564     \r
565         if(cal_status)\r
566                 return sprintf(buf,"successful");\r
567         else\r
568                 return sprintf(buf,"fail");\r
569 }\r
570 \r
571 ssize_t tp_cal_store(struct kobject *kobj, struct kobj_attribute *attr,\r
572                          const char *buf, size_t count)\r
573 {\r
574     \r
575     if( !strncmp(buf,"tp_cal" , strlen("tp_cal")) )\r
576     {\r
577                 set_mode(g_dev);\r
578     }\r
579 \r
580     return count;\r
581 }\r
582 \r
583 struct kobj_attribute tp_cal_attrs = \r
584 {\r
585         .attr = {\r
586                 .name = "tp_calibration",\r
587                 .mode = 0777},\r
588         .show = tp_cal_show,\r
589         .store = tp_cal_store,\r
590 };\r
591 \r
592 struct attribute *tp_attrs[] = \r
593 {\r
594         &tp_cal_attrs.attr,\r
595         NULL\r
596 };\r
597 \r
598 static struct kobj_type tp_kset_ktype = {\r
599         .sysfs_ops      = &kobj_sysfs_ops,\r
600         .default_attrs = &tp_attrs[0],\r
601 };\r
602 static int tp_cal_add_attr(struct it7260_dev *ts_dev)\r
603 {\r
604         int result;\r
605         struct input_dev *input;\r
606         struct kobject *parentkobject; \r
607         struct kobject * me = kmalloc(sizeof(struct kobject) , GFP_KERNEL );\r
608         if( !me )\r
609                 return -ENOMEM;\r
610         memset(me ,0,sizeof(struct kobject));\r
611         kobject_init( me , &tp_kset_ktype );\r
612         parentkobject = &ts_dev->input->dev.kobj ;\r
613         result = kobject_add( me , parentkobject->parent->parent->parent, "%s", "tp_calibration" );     \r
614         return result;\r
615 }\r
616 \r
617 static void it7260_remove(struct i2c_client * client)\r
618 {\r
619 \r
620 }\r
621 static int it7260_probe(struct i2c_client *client ,const struct i2c_device_id *id)\r
622 {\r
623         struct it7260_dev *ts_dev;\r
624         struct input_dev *input;\r
625         struct it7260_platform_data *pdata = pdata = client->dev.platform_data;\r
626         int i, ret=0;\r
627 \r
628         \r
629         if (!pdata) {\r
630                 dev_err(&client->dev, "platform data is required!\n");\r
631                 return -EINVAL;\r
632         }\r
633 \r
634         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))\r
635                 return -EIO;\r
636 \r
637         ts_dev=kzalloc(sizeof(struct it7260_dev), GFP_KERNEL);\r
638         if(!ts_dev)\r
639         {\r
640                 printk("it7260 failed to allocate memory!!\n");\r
641                 goto nomem;\r
642         }\r
643 \r
644         input = input_allocate_device();\r
645         if(!input)\r
646         {\r
647                 printk("it7260 allocate input device failed!!!\n"); \r
648                 goto fail1;\r
649         }       \r
650 \r
651         ts_dev->client = client;\r
652         ts_dev->status = 0;\r
653         ts_dev->pendown = 0;\r
654         ts_dev->pass = 0;\r
655         ts_dev->input = input;          \r
656         ts_dev->irq = client->irq;\r
657         ts_dev->has_relative_report = 0;\r
658         snprintf(ts_dev->phys, sizeof(ts_dev->phys),\r
659          "%s/input0", dev_name(&client->dev));\r
660         input->name = "it7260 touchscreen";\r
661         input->phys = ts_dev->phys;\r
662         input->id.bustype = BUS_I2C;\r
663 \r
664         \r
665         ts_dev->wq = create_rt_workqueue("it7260_wq");\r
666         INIT_DELAYED_WORK(&ts_dev->work, it7260_work);\r
667         \r
668 #if Singltouch_Mode\r
669         input->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);\r
670         input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);\r
671         input_set_abs_params(input, ABS_X, 0, IT7260_MAX_X, 0, 0);\r
672         input_set_abs_params(input, ABS_Y, 35, IT7260_MAX_Y     , 0, 0);\r
673 #else\r
674         input->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);\r
675         input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);\r
676         input->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); //jaocbchen for dual\r
677 \r
678         input_set_abs_params(input, ABS_X, 0, IT7260_MAX_X, 0, 0);\r
679         input_set_abs_params(input, ABS_Y, 0, IT7260_MAX_Y, 0, 0);\r
680         input_set_abs_params(input, ABS_PRESSURE, 0, 255, 0, 0);\r
681         input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 15, 0, 0);\r
682         input_set_abs_params(input, ABS_HAT0X, 0, IT7260_MAX_X, 0, 0);\r
683         input_set_abs_params(input, ABS_HAT0Y, 0, IT7260_MAX_Y, 0, 0);\r
684         input_set_abs_params(input, ABS_MT_POSITION_X,0, IT7260_MAX_X, 0, 0);\r
685         input_set_abs_params(input, ABS_MT_POSITION_Y, 0, IT7260_MAX_Y, 0, 0);\r
686         input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);\r
687         input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);\r
688 \r
689         for (i = 0; i < (BITS_TO_LONGS(ABS_CNT)); i++)\r
690                 printk("%s::input->absbit[%d] = 0x%x \n",__FUNCTION__,i,input->absbit[i]);\r
691 #endif\r
692 \r
693         if (pdata->init_platform_hw)\r
694                 pdata->init_platform_hw();\r
695 \r
696         if (!ts_dev->irq) {\r
697                 dev_dbg(&ts_dev->client->dev, "no IRQ?\n");\r
698                 return -ENODEV;\r
699         }else{\r
700                 ts_dev->irq = gpio_to_irq(ts_dev->irq);\r
701         }\r
702 \r
703         printk("client->dev.driver->name %s\n",client->dev.driver->name);\r
704         ret = request_irq(ts_dev->irq, it7260_irq_hander, IRQF_TRIGGER_LOW,\r
705                         client->dev.driver->name, ts_dev);\r
706         \r
707         if (ret < 0) {\r
708                 dev_err(&client->dev, "irq %d busy?\n", ts_dev->irq);\r
709                 goto fail3;\r
710         }\r
711         \r
712         ret = input_register_device(input);     \r
713         if(ret<0)\r
714         {\r
715                 printk("it7260 register input device failed!!!!\n");\r
716                 goto fail2;\r
717         }\r
718         \r
719 #ifdef CONFIG_ANDROID_POWER\r
720         ts_early_suspend.suspend = suspend;\r
721     ts_early_suspend.resume = resume;\r
722     android_register_early_suspend(&ts_early_suspend);\r
723 #endif  \r
724         g_dev = ts_dev;\r
725 //      ite_ts_test();\r
726         set_mode(ts_dev);\r
727      \r
728         printk("it7260 register input device ok!!!!\n");\r
729         return 0;\r
730 \r
731 fail3:\r
732         free_irq(ts_dev->irq,ts_dev);\r
733 fail2:\r
734 \r
735         input_unregister_device(input);\r
736         input = NULL;\r
737 fail1:\r
738         input_free_device(input);\r
739 nomem:\r
740         kfree(ts_dev);\r
741         return ret;\r
742 \r
743 }\r
744 \r
745 \r
746 static struct i2c_device_id it7260_idtable[] = {\r
747         { "it7260_touch", 0 },\r
748         { }\r
749 };\r
750 \r
751 MODULE_DEVICE_TABLE(i2c, it7260_idtable);\r
752 \r
753 static struct i2c_driver it7260_driver  = {\r
754         .driver = {\r
755                 .owner  = THIS_MODULE,\r
756                 .name   = "it7260_touch"\r
757         },\r
758         .id_table       = it7260_idtable,\r
759         .probe = it7260_probe,\r
760         .remove         = __devexit_p(it7260_remove),\r
761 };\r
762 \r
763 static int __init it7260_init(void)\r
764\r
765         return i2c_add_driver(&it7260_driver);\r
766 }\r
767 \r
768 static void __exit it7260_exit(void)\r
769 {\r
770         i2c_del_driver(&it7260_driver);\r
771 }\r
772 module_init(it7260_init);\r
773 module_exit(it7260_exit);\r
774 MODULE_DESCRIPTION ("it7260 touchscreen driver");\r
775 MODULE_AUTHOR("llx<llx@rockchip.com>");\r
776 MODULE_LICENSE("GPL");\r
777 \r
778 \r