import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / GT910 / goodix_tool.c
1 /* drivers/input/touchscreen/goodix_tool.c
2 *
3 * 2010 - 2012 Goodix Technology.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be a reference
11 * to you, when you are integrating the GOODiX's CTP IC into your system,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * Version:1.2
17 * V1.0:2012/05/01,create file.
18 * V1.2:2012/10/17,reset_guitar etc.
19 *
20 */
21
22 #include "tpd.h"
23 #include <linux/interrupt.h>
24 #include <cust_eint.h>
25 #include <linux/i2c.h>
26 #include <linux/sched.h>
27 #include <linux/kthread.h>
28 #include <linux/rtpm_prio.h>
29 #include <linux/wait.h>
30 #include <linux/time.h>
31 #include <linux/delay.h>
32 #include "cust_gpio_usage.h"
33 #include <asm/uaccess.h>
34
35 #include "tpd_custom_gt9xx.h"
36
37
38 #pragma pack(1)
39 typedef struct
40 {
41 u8 wr; //write read flag£¬0:R 1:W 2:PID 3:
42 u8 flag; //0:no need flag/int 1: need flag 2:need int
43 u8 flag_addr[2]; //flag address
44 u8 flag_val; //flag val
45 u8 flag_relation; //flag_val:flag 0:not equal 1:equal 2:> 3:<
46 u16 circle; //polling cycle
47 u8 times; //plling times
48 u8 retry; //I2C retry times
49 u16 delay; //delay befor read or after write
50 u16 data_len; //data length
51 u8 addr_len; //address length
52 u8 addr[2]; //address
53 u8 res[3]; //reserved
54 u8 *data; //data pointer
55 } st_cmd_head;
56 #pragma pack()
57 st_cmd_head cmd_head;
58
59 #define UPDATE_FUNCTIONS
60 #define DATA_LENGTH_UINT 512
61 #define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8*))
62 #define GOODIX_ENTRY_NAME "goodix_tool"
63 extern struct i2c_client *i2c_client_point;
64 static struct i2c_client *gt_client = NULL;
65
66 #ifdef UPDATE_FUNCTIONS
67 extern s32 gup_enter_update_mode(struct i2c_client *client);
68 extern void gup_leave_update_mode(void);
69 extern s32 gup_update_proc(void *dir);
70 #endif
71
72 static struct proc_dir_entry *goodix_proc_entry;
73
74 static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data);
75 static s32 goodix_tool_read(char *page, char **start, off_t off, int count, int *eof, void *data);
76 static s32(*tool_i2c_read)(u8 *, u16);
77 static s32(*tool_i2c_write)(u8 *, u16);
78
79 s32 DATA_LENGTH = 0;
80 s8 IC_TYPE[16] = {0};
81
82 static s32 tool_i2c_read_no_extra(u8 *buf, u16 len)
83 {
84 s32 ret = -1;
85
86 ret = gtp_i2c_read(gt_client, buf, len + GTP_ADDR_LENGTH);
87 return ret;
88 }
89
90 static s32 tool_i2c_write_no_extra(u8 *buf, u16 len)
91 {
92 s32 ret = -1;
93
94 ret = gtp_i2c_write(gt_client, buf, len);
95 return ret;
96 }
97
98 static s32 tool_i2c_read_with_extra(u8 *buf, u16 len)
99 {
100 s32 ret = -1;
101 u8 pre[2] = {0x0f, 0xff};
102 u8 end[2] = {0x80, 0x00};
103
104 tool_i2c_write_no_extra(pre, 2);
105 ret = tool_i2c_read_no_extra(buf, len);
106 tool_i2c_write_no_extra(end, 2);
107
108 return ret;
109 }
110
111 static s32 tool_i2c_write_with_extra(u8 *buf, u16 len)
112 {
113 s32 ret = -1;
114 u8 pre[2] = {0x0f, 0xff};
115 u8 end[2] = {0x80, 0x00};
116
117 tool_i2c_write_no_extra(pre, 2);
118 ret = tool_i2c_write_no_extra(buf, len);
119 tool_i2c_write_no_extra(end, 2);
120
121 return ret;
122 }
123
124 static void register_i2c_func(void)
125 {
126 // if (!strncmp(IC_TYPE, "GT818", 5) || !strncmp(IC_TYPE, "GT816", 5)
127 // || !strncmp(IC_TYPE, "GT811", 5) || !strncmp(IC_TYPE, "GT818F", 6)
128 // || !strncmp(IC_TYPE, "GT827", 5) || !strncmp(IC_TYPE,"GT828", 5)
129 // || !strncmp(IC_TYPE, "GT813", 5))
130 if (strncmp(IC_TYPE, "GT8110", 6) && strncmp(IC_TYPE, "GT8105", 6)
131 && strncmp(IC_TYPE, "GT801", 5) && strncmp(IC_TYPE, "GT800", 5)
132 && strncmp(IC_TYPE, "GT801PLUS", 9) && strncmp(IC_TYPE, "GT811", 5)
133 && strncmp(IC_TYPE, "GTxxx", 5))
134 {
135 tool_i2c_read = tool_i2c_read_with_extra;
136 tool_i2c_write = tool_i2c_write_with_extra;
137 GTP_DEBUG("I2C function: with pre and end cmd!");
138 }
139 else
140 {
141 tool_i2c_read = tool_i2c_read_no_extra;
142 tool_i2c_write = tool_i2c_write_no_extra;
143 GTP_INFO("I2C function: without pre and end cmd!");
144 }
145 }
146
147 static void unregister_i2c_func(void)
148 {
149 tool_i2c_read = NULL;
150 tool_i2c_write = NULL;
151 GTP_INFO("I2C function: unregister i2c transfer function!");
152 }
153
154
155 s32 init_wr_node(struct i2c_client *client)
156 {
157 s32 i;
158 const s8 entry_prefix[] = "GMNode_";
159 s8 gtp_tool_entry[30];
160
161 gt_client = i2c_client_point;
162 GTP_INFO("client %d.%d", (int)gt_client, (int)client);
163
164 memset(&cmd_head, 0, sizeof(cmd_head));
165 cmd_head.data = NULL;
166
167 i = 5;
168
169 while ((!cmd_head.data) && i)
170 {
171 cmd_head.data = kzalloc(i * DATA_LENGTH_UINT, GFP_KERNEL);
172
173 if (NULL != cmd_head.data)
174 {
175 break;
176 }
177
178 i--;
179 }
180
181 if (i)
182 {
183 DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH;
184 GTP_INFO("Applied memory size:%d.", DATA_LENGTH);
185 }
186 else
187 {
188 GTP_ERROR("Apply for memory failed.");
189 return FAIL;
190 }
191
192 cmd_head.addr_len = 2;
193 cmd_head.retry = 5;
194
195 register_i2c_func();
196
197 // goodix_proc_entry = create_proc_entry(GOODIX_ENTRY_NAME, 0664, NULL);
198
199 memset(gtp_tool_entry, 0, sizeof(gtp_tool_entry));
200 i = sizeof(entry_prefix)/sizeof(s8);
201 memcpy(gtp_tool_entry, entry_prefix, i-1);
202 memcpy(&gtp_tool_entry[i-1], __DATE__, sizeof(__DATE__)/sizeof(s8));
203 #if 0 //linux-3.10 procfs API changed
204 goodix_proc_entry = create_proc_entry(gtp_tool_entry, 0664, NULL);
205
206 if (goodix_proc_entry == NULL)
207 {
208 GTP_ERROR("Couldn't create proc entry!");
209 return FAIL;
210 }
211 else
212 {
213 GTP_INFO("Create proc entry success!");
214 goodix_proc_entry->write_proc = goodix_tool_write;
215 goodix_proc_entry->read_proc = goodix_tool_read;
216 }
217 #endif
218 return SUCCESS;
219 }
220
221 void uninit_wr_node(void)
222 {
223 kfree(cmd_head.data);
224 cmd_head.data = NULL;
225 unregister_i2c_func();
226 remove_proc_entry(GOODIX_ENTRY_NAME, NULL);
227 }
228
229 static u8 relation(u8 src, u8 dst, u8 rlt)
230 {
231 u8 ret = 0;
232
233 switch (rlt)
234 {
235 case 0:
236 ret = (src != dst) ? true : false;
237 break;
238
239 case 1:
240 ret = (src == dst) ? true : false;
241 GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", src, dst, (s32)ret);
242 break;
243
244 case 2:
245 ret = (src > dst) ? true : false;
246 break;
247
248 case 3:
249 ret = (src < dst) ? true : false;
250 break;
251
252 case 4:
253 ret = (src & dst) ? true : false;
254 break;
255
256 case 5:
257 ret = (!(src | dst)) ? true : false;
258 break;
259
260 default:
261 ret = false;
262 break;
263 }
264
265 return ret;
266 }
267
268 /*******************************************************
269 Function:
270 Comfirm function.
271 Input:
272 None.
273 Output:
274 Return write length.
275 ********************************************************/
276 static u8 comfirm(void)
277 {
278 s32 i = 0;
279 u8 buf[32];
280
281 // memcpy(&buf[GTP_ADDR_LENGTH - cmd_head.addr_len], &cmd_head.flag_addr, cmd_head.addr_len);
282 // memcpy(buf, &cmd_head.flag_addr, cmd_head.addr_len);//Modified by Scott, 2012-02-17
283 memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len);
284
285 for (i = 0; i < cmd_head.times; i++)
286 {
287 if (tool_i2c_read(buf, 1) <= 0)
288 {
289 GTP_ERROR("Read flag data failed!");
290 return FAIL;
291 }
292
293 if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, cmd_head.flag_relation))
294 {
295 GTP_DEBUG("value at flag addr:0x%02x.", buf[GTP_ADDR_LENGTH]);
296 GTP_DEBUG("flag value:0x%02x.", cmd_head.flag_val);
297 break;
298 }
299
300 msleep(cmd_head.circle);
301 }
302
303 if (i >= cmd_head.times)
304 {
305 GTP_ERROR("Didn't get the flag to continue!");
306 return FAIL;
307 }
308
309 return SUCCESS;
310 }
311
312 /*******************************************************
313 Function:
314 Goodix tool write function.
315 Input:
316 standard proc write function param.
317 Output:
318 Return write length.
319 ********************************************************/
320 static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data)
321 {
322 u64 ret = 0;
323 GTP_DEBUG_FUNC();
324 GTP_DEBUG_ARRAY((u8 *)buff, len);
325
326 ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH);
327
328 if (ret)
329 {
330 GTP_ERROR("copy_from_user failed.");
331 }
332
333 GTP_DEBUG("wr :0x%02x.", cmd_head.wr);
334 GTP_DEBUG("flag:0x%02x.", cmd_head.flag);
335 GTP_DEBUG("flag addr:0x%02x%02x.", cmd_head.flag_addr[0], cmd_head.flag_addr[1]);
336 GTP_DEBUG("flag val:0x%02x.", cmd_head.flag_val);
337 GTP_DEBUG("flag rel:0x%02x.", cmd_head.flag_relation);
338 GTP_DEBUG("circle :%d.", (s32)cmd_head.circle);
339 GTP_DEBUG("times :%d.", (s32)cmd_head.times);
340 GTP_DEBUG("retry :%d.", (s32)cmd_head.retry);
341 GTP_DEBUG("delay :%d.", (s32)cmd_head.delay);
342 GTP_DEBUG("data len:%d.", (s32)cmd_head.data_len);
343 GTP_DEBUG("addr len:%d.", (s32)cmd_head.addr_len);
344 GTP_DEBUG("addr:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]);
345 GTP_DEBUG("len:%d.", (s32)len);
346 GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]);
347
348 if (1 == cmd_head.wr)
349 {
350 // copy_from_user(&cmd_head.data[cmd_head.addr_len], &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
351 ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
352
353 if (ret)
354 {
355 GTP_ERROR("copy_from_user failed.");
356 }
357
358 memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.addr, cmd_head.addr_len);
359
360 GTP_DEBUG_ARRAY(cmd_head.data, cmd_head.data_len + cmd_head.addr_len);
361 GTP_DEBUG_ARRAY((u8 *)&buff[CMD_HEAD_LENGTH], cmd_head.data_len);
362
363 if (1 == cmd_head.flag)
364 {
365 if (FAIL == comfirm())
366 {
367 GTP_ERROR("[WRITE]Comfirm fail!");
368 return FAIL;
369 }
370 }
371 else if (2 == cmd_head.flag)
372 {
373 //Need interrupt!
374 }
375
376 if (tool_i2c_write(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
377 cmd_head.data_len + cmd_head.addr_len) <= 0)
378 {
379 GTP_ERROR("[WRITE]Write data failed!");
380 return FAIL;
381 }
382
383 GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len);
384
385 if (cmd_head.delay)
386 {
387 msleep(cmd_head.delay);
388 }
389
390 return cmd_head.data_len + CMD_HEAD_LENGTH;
391 }
392 else if (3 == cmd_head.wr) //Write ic type
393 {
394 memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
395 register_i2c_func();
396
397 return cmd_head.data_len + CMD_HEAD_LENGTH;
398 }
399 else if (5 == cmd_head.wr)
400 {
401 //memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
402
403 return cmd_head.data_len + CMD_HEAD_LENGTH;
404 }
405 else if (7 == cmd_head.wr)//disable irq!
406 {
407 // gtp_irq_disable(i2c_get_clientdata(gt_client));
408
409 return CMD_HEAD_LENGTH;
410 }
411 else if (9 == cmd_head.wr) //enable irq!
412 {
413 // gtp_irq_enable(i2c_get_clientdata(gt_client));
414
415 return CMD_HEAD_LENGTH;
416 }
417 else if (17 == cmd_head.wr)
418 {
419 //struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
420 ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
421
422 if (ret)
423 {
424 GTP_DEBUG("copy_from_user failed.");
425 }
426
427 if (cmd_head.data[GTP_ADDR_LENGTH])
428 {
429 GTP_DEBUG("gtp enter rawdiff.");
430 gtp_rawdiff_mode = true;
431 }
432 else
433 {
434 gtp_rawdiff_mode = false;
435 GTP_DEBUG("gtp leave rawdiff.");
436 }
437
438 return CMD_HEAD_LENGTH;
439 }
440
441 #ifdef UPDATE_FUNCTIONS
442 else if (11 == cmd_head.wr)//Enter update mode!
443 {
444 if (FAIL == gup_enter_update_mode(gt_client))
445 {
446 return FAIL;
447 }
448 }
449 else if (13 == cmd_head.wr)//Leave update mode!
450 {
451 gup_leave_update_mode();
452 }
453 else if (15 == cmd_head.wr) //Update firmware!
454 {
455 show_len = 0;
456 total_len = 0;
457 if ((cmd_head.data == NULL)
458 || (cmd_head.data_len >= DATA_LENGTH)
459 || (cmd_head.data_len >= (len - CMD_HEAD_LENGTH))) {
460 GTP_ERROR("copy_from_user data out of range.");
461 return -EINVAL;
462 }
463
464 memset(cmd_head.data, 0, cmd_head.data_len + 1);
465 memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
466
467 if (FAIL == gup_update_proc((void *)cmd_head.data))
468 {
469 return FAIL;
470 }
471 }
472
473 #endif
474
475 return CMD_HEAD_LENGTH;
476 }
477
478 /*******************************************************
479 Function:
480 Goodix tool read function.
481 Input:
482 standard proc read function param.
483 Output:
484 Return read length.
485 ********************************************************/
486 static s32 goodix_tool_read(char *page, char **start, off_t off, int count, int *eof, void *data)
487 {
488 GTP_DEBUG_FUNC();
489
490 if (cmd_head.wr % 2)
491 {
492 return FAIL;
493 }
494 else if (!cmd_head.wr)
495 {
496 u16 len = 0;
497 s16 data_len = 0;
498 u16 loc = 0;
499
500 if (1 == cmd_head.flag)
501 {
502 if (FAIL == comfirm())
503 {
504 GTP_ERROR("[READ]Comfirm fail!");
505 return FAIL;
506 }
507 }
508 else if (2 == cmd_head.flag)
509 {
510 //Need interrupt!
511 }
512
513 memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len);
514
515 GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0], cmd_head.data[1]);
516 GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]);
517
518 if (cmd_head.delay)
519 {
520 msleep(cmd_head.delay);
521 }
522
523 data_len = cmd_head.data_len;
524
525 while (data_len > 0)
526 {
527 if (data_len > DATA_LENGTH)
528 {
529 len = DATA_LENGTH;
530 }
531 else
532 {
533 len = data_len;
534 }
535
536 data_len -= DATA_LENGTH;
537
538 if (tool_i2c_read(cmd_head.data, len) <= 0)
539 {
540 GTP_ERROR("[READ]Read data failed!");
541 return FAIL;
542 }
543
544 memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len);
545 loc += len;
546
547 GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH], len);
548 GTP_DEBUG_ARRAY(page, len);
549 }
550 }
551 else if (2 == cmd_head.wr)
552 {
553 // memcpy(page, "gt8", cmd_head.data_len);
554 // memcpy(page, "GT818", 5);
555 // page[5] = 0;
556
557 GTP_DEBUG("Return ic type:%s len:%d.", page, (s32)cmd_head.data_len);
558 return cmd_head.data_len;
559 //return sizeof(IC_TYPE_NAME);
560 }
561 else if (4 == cmd_head.wr)
562 {
563 page[0] = show_len >> 8;
564 page[1] = show_len & 0xff;
565 page[2] = total_len >> 8;
566 page[3] = total_len & 0xff;
567
568 return cmd_head.data_len;
569 }
570 else if (6 == cmd_head.wr)
571 {
572 //Read error code!
573 }
574 else if (8 == cmd_head.wr) //Read driver version
575 {
576 // memcpy(page, GTP_DRIVER_VERSION, strlen(GTP_DRIVER_VERSION));
577 s32 tmp_len;
578 tmp_len = strlen(GTP_DRIVER_VERSION);
579 memcpy(page, GTP_DRIVER_VERSION, tmp_len);
580 page[tmp_len] = 0;
581 }
582
583 return cmd_head.data_len;
584 }