xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch/focaltech_ex_fun.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *
3  * FocalTech TouchScreen driver.
4  *
5  * Copyright (c) 2012-2018, Focaltech Ltd. All rights reserved.
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 /*****************************************************************************
19 *
20 * File Name: Focaltech_ex_fun.c
21 *
22 * Author: Focaltech Driver Team
23 *
24 * Created: 2016-08-08
25 *
26 * Abstract:
27 *
28 * Reference:
29 *
30 *****************************************************************************/
31 
32 /*****************************************************************************
33 * 1.Included header files
34 *****************************************************************************/
35 #include "focaltech_core.h"
36 
37 /*****************************************************************************
38 * Private constant and macro definitions using #define
39 *****************************************************************************/
40 /*create apk debug channel*/
41 #define PROC_UPGRADE                            0
42 #define PROC_READ_REGISTER                      1
43 #define PROC_WRITE_REGISTER                     2
44 #define PROC_AUTOCLB                            4
45 #define PROC_UPGRADE_INFO                       5
46 #define PROC_WRITE_DATA                         6
47 #define PROC_READ_DATA                          7
48 #define PROC_SET_TEST_FLAG                      8
49 #define PROC_SET_SLAVE_ADDR                     10
50 #define PROC_HW_RESET                           11
51 #define PROC_NAME                               "ftxxxx-debug"
52 #define PROC_BUF_SIZE                           256
53 
54 /*****************************************************************************
55 * Private enumerations, structures and unions using typedef
56 *****************************************************************************/
57 
58 /*****************************************************************************
59 * Static variables
60 *****************************************************************************/
61 #if FTS_SYSFS_NODE_EN
62 enum {
63     RWREG_OP_READ = 0,
64     RWREG_OP_WRITE = 1,
65 };
66 static struct rwreg_operation_t {
67     int type;         /*  0: read, 1: write */
68     int reg;        /*  register */
69     int len;        /*  read/write length */
70     int val;      /*  length = 1; read: return value, write: op return */
71     int res;     /*  0: success, otherwise: fail */
72     char *opbuf;        /*  length >= 1, read return value, write: op return */
73 } rw_op;
74 #endif
75 
76 #if FTS_APK_NODE_EN
77 
78 /*****************************************************************************
79 * Global variable or extern global variabls/functions
80 *****************************************************************************/
81 /*****************************************************************************
82 * Static function prototypes
83 *****************************************************************************/
84 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
85 /************************************************************************
86 *   Name: fts_debug_write
87 *  Brief:interface of write proc
88 * Input: file point, data buf, data len, no use
89 * Output: no
90 * Return: data len
91 ***********************************************************************/
fts_debug_write(struct file * filp,const char __user * buff,size_t count,loff_t * ppos)92 static ssize_t fts_debug_write(struct file *filp, const char __user *buff, size_t count, loff_t *ppos)
93 {
94     u8 *writebuf = NULL;
95     u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
96     int buflen = count;
97     int writelen = 0;
98     int ret = 0;
99     char tmp[25];
100     struct fts_ts_data *ts_data = fts_data;
101     struct i2c_client *client = ts_data->client;
102 
103     if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
104         FTS_ERROR("apk proc wirte count(%d) fail", buflen);
105         return -EINVAL;
106     }
107 
108     if (buflen > PROC_BUF_SIZE) {
109         writebuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
110         if (NULL == writebuf) {
111             FTS_ERROR("apk proc wirte buf zalloc fail");
112             return -ENOMEM;
113         }
114     } else {
115         writebuf = tmpbuf;
116     }
117 
118     if (copy_from_user(writebuf, buff, buflen)) {
119         FTS_ERROR("[APK]: copy from user error!!");
120         ret = -EFAULT;
121         goto proc_write_err;
122     }
123 
124     ts_data->proc_opmode = writebuf[0];
125 
126     switch (ts_data->proc_opmode) {
127     case PROC_SET_TEST_FLAG:
128         FTS_INFO("[APK]: PROC_SET_TEST_FLAG = %x!!", writebuf[1]);
129 #if FTS_ESDCHECK_EN
130         if (writebuf[1] == 0) {
131             fts_esdcheck_switch(ENABLE);
132         } else {
133             fts_esdcheck_switch(DISABLE);
134         }
135 #endif
136         break;
137     case PROC_READ_REGISTER:
138         writelen = 1;
139         ret = fts_i2c_write(client, writebuf + 1, writelen);
140         if (ret < 0) {
141             FTS_ERROR("[APK]: write iic error!!");
142             goto proc_write_err;
143         }
144         break;
145     case PROC_WRITE_REGISTER:
146         writelen = 2;
147         ret = fts_i2c_write(client, writebuf + 1, writelen);
148         if (ret < 0) {
149             FTS_ERROR("[APK]: write iic error!!");
150             goto proc_write_err;
151         }
152         break;
153     case PROC_SET_SLAVE_ADDR:
154 #if (FTS_CHIP_TYPE == _FT8201)
155         FTS_INFO("Original i2c addr 0x%x", client->addr << 1);
156         if (writebuf[1] != client->addr) {
157             client->addr = writebuf[1];
158             FTS_INFO("Change i2c addr 0x%x to 0x%x", client->addr << 1, writebuf[1] << 1);
159         }
160 #endif
161         break;
162 
163     case PROC_HW_RESET:
164         snprintf(tmp, 25, "%s", writebuf + 1);
165         if (buflen > 25) {
166             FTS_INFO("PROC_HW_RESET bufflen %d is too long\n", buflen);
167             break;
168         }
169         tmp[buflen - 1] = '\0';
170         if (strncmp(tmp, "focal_driver", 12) == 0) {
171             FTS_INFO("APK execute HW Reset");
172             fts_reset_proc(0);
173         }
174         break;
175 
176     case PROC_READ_DATA:
177     case PROC_WRITE_DATA:
178         writelen = buflen - 1;
179         if (writelen > 0) {
180             ret = fts_i2c_write(client, writebuf + 1, writelen);
181             if (ret < 0) {
182                 FTS_ERROR("[APK]: write iic error!!");
183                 goto proc_write_err;
184             }
185         }
186         break;
187     default:
188         break;
189     }
190 
191     ret = buflen;
192 proc_write_err:
193     if ((buflen > PROC_BUF_SIZE) && writebuf) {
194         kfree(writebuf);
195         writebuf = NULL;
196     }
197     return ret;
198 }
199 
200 /************************************************************************
201 *   Name: fts_debug_read
202 *  Brief:interface of read proc
203 * Input: point to the data, no use, no use, read len, no use, no use
204 * Output: page point to data
205 * Return: read char number
206 ***********************************************************************/
fts_debug_read(struct file * filp,char __user * buff,size_t count,loff_t * ppos)207 static ssize_t fts_debug_read(struct file *filp, char __user *buff, size_t count, loff_t *ppos)
208 {
209     int ret = 0;
210     int num_read_chars = 0;
211     int buflen = count;
212     u8 *buf = NULL;
213     u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
214     struct fts_ts_data *ts_data = fts_data;
215     struct i2c_client *client = ts_data->client;
216 
217     if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
218         FTS_ERROR("apk proc read count(%d) fail", buflen);
219         return -EINVAL;
220     }
221 
222     if (buflen > PROC_BUF_SIZE) {
223         buf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
224         if (NULL == buf) {
225             FTS_ERROR("apk proc wirte buf zalloc fail");
226             return -ENOMEM;
227         }
228     } else {
229         buf = tmpbuf;
230     }
231 
232 #if FTS_ESDCHECK_EN
233     fts_esdcheck_proc_busy(1);
234 #endif
235 
236     switch (ts_data->proc_opmode) {
237     case PROC_READ_REGISTER:
238         num_read_chars = 1;
239         ret = fts_i2c_read(client, NULL, 0, buf, num_read_chars);
240         if (ret < 0) {
241 #if FTS_ESDCHECK_EN
242             fts_esdcheck_proc_busy(0);
243 #endif
244             FTS_ERROR("[APK]: read iic error!!");
245             goto proc_read_err;
246         }
247         break;
248     case PROC_READ_DATA:
249         num_read_chars = buflen;
250         ret = fts_i2c_read(client, NULL, 0, buf, num_read_chars);
251         if (ret < 0) {
252 #if FTS_ESDCHECK_EN
253             fts_esdcheck_proc_busy(0);
254 #endif
255             FTS_ERROR("[APK]: read iic error!!");
256             goto proc_read_err;
257         }
258         break;
259     case PROC_WRITE_DATA:
260         break;
261     default:
262         break;
263     }
264 
265 #if FTS_ESDCHECK_EN
266     fts_esdcheck_proc_busy(0);
267 #endif
268 
269     if (copy_to_user(buff, buf, num_read_chars)) {
270         FTS_ERROR("[APK]: copy to user error!!");
271         ret = -EFAULT;
272         goto proc_read_err;
273     }
274 
275     ret = num_read_chars;
276 proc_read_err:
277     if ((buflen > PROC_BUF_SIZE) && buf) {
278         kfree(buf);
279         buf = NULL;
280     }
281     return ret;
282 }
283 
284 static const struct file_operations fts_proc_fops = {
285     .owner  = THIS_MODULE,
286     .read   = fts_debug_read,
287     .write  = fts_debug_write,
288 };
289 
290 #else
291 /* interface of write proc */
292 /************************************************************************
293 *   Name: fts_debug_write
294 *  Brief:interface of write proc
295 * Input: file point, data buf, data len, no use
296 * Output: no
297 * Return: data len
298 ***********************************************************************/
fts_debug_write(struct file * filp,const char __user * buff,unsigned long len,void * data)299 static int fts_debug_write(struct file *filp,
300                            const char __user *buff, unsigned long len, void *data)
301 {
302     int ret = 0;
303     u8 *writebuf = NULL;
304     u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
305     int buflen = len;
306     int writelen = 0;
307     char tmp[25];
308     struct fts_ts_data *ts_data = fts_data;
309     struct i2c_client *client = ts_data->client;
310 
311     if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
312         FTS_ERROR("apk proc wirte count(%d) fail", buflen);
313         return -EINVAL;
314     }
315 
316     if (buflen > PROC_BUF_SIZE) {
317         writebuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
318         if (NULL == writebuf) {
319             FTS_ERROR("apk proc wirte buf zalloc fail");
320             return -ENOMEM;
321         }
322     } else {
323         writebuf = tmpbuf;
324     }
325 
326     if (copy_from_user(writebuf, buff, buflen)) {
327         FTS_ERROR("[APK]: copy from user error!!");
328         ret = -EFAULT;
329         goto proc_write_err;
330     }
331 
332     ts_data->proc_opmode = writebuf[0];
333 
334     switch (ts_data->proc_opmode) {
335     case PROC_SET_TEST_FLAG:
336         FTS_DEBUG("[APK]: PROC_SET_TEST_FLAG = %x!!", writebuf[1]);
337 #if FTS_ESDCHECK_EN
338         if (writebuf[1] == 0) {
339             fts_esdcheck_switch(ENABLE);
340         } else {
341             fts_esdcheck_switch(DISABLE);
342         }
343 #endif
344         break;
345     case PROC_READ_REGISTER:
346         writelen = 1;
347         ret = fts_i2c_write(client, writebuf + 1, writelen);
348         if (ret < 0) {
349             FTS_ERROR("[APK]: write iic error!!n");
350             goto proc_write_err;
351         }
352         break;
353     case PROC_WRITE_REGISTER:
354         writelen = 2;
355         ret = fts_i2c_write(client, writebuf + 1, writelen);
356         if (ret < 0) {
357             FTS_ERROR("[APK]: write iic error!!");
358             goto proc_write_err;
359         }
360         break;
361     case PROC_SET_SLAVE_ADDR:
362 #if (FTS_CHIP_TYPE == _FT8201)
363         ret = client->addr;
364         FTS_DEBUG("Original i2c addr 0x%x ", ret << 1 );
365         if (writebuf[1] != client->addr) {
366             client->addr = writebuf[1];
367             FTS_DEBUG("Change i2c addr 0x%x to 0x%x", ret << 1, writebuf[1] << 1);
368         }
369 #endif
370         break;
371 
372     case PROC_HW_RESET:
373         snprintf(tmp, PAGE_SIZE, "%s", writebuf + 1);
374         tmp[buflen - 1] = '\0';
375         if (strncmp(tmp, "focal_driver", 12) == 0) {
376             FTS_INFO("Begin HW Reset");
377             fts_reset_proc(0);
378         }
379         break;
380 
381     case PROC_READ_DATA:
382     case PROC_WRITE_DATA:
383         writelen = buflen - 1;
384         if (writelen > 0) {
385             ret = fts_i2c_write(client, writebuf + 1, writelen);
386             if (ret < 0) {
387                 FTS_ERROR("[APK]: write iic error!!");
388                 goto proc_write_err;
389             }
390         }
391         break;
392     default:
393         break;
394     }
395 
396     ret = buflen;
397 proc_write_err:
398     if ((buflen > PROC_BUF_SIZE) && writebuf) {
399         kfree(writebuf);
400         writebuf = NULL;
401     }
402     return ret;
403 }
404 
405 /* interface of read proc */
406 /************************************************************************
407 *   Name: fts_debug_read
408 *  Brief:interface of read proc
409 * Input: point to the data, no use, no use, read len, no use, no use
410 * Output: page point to data
411 * Return: read char number
412 ***********************************************************************/
fts_debug_read(char * page,char ** start,off_t off,int count,int * eof,void * data)413 static int fts_debug_read( char *page, char **start,
414                            off_t off, int count, int *eof, void *data )
415 {
416     int ret = 0;
417     u8 *buf = NULL;
418     u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
419     int num_read_chars = 0;
420     int buflen = count;
421     struct fts_ts_data *ts_data = fts_data;
422     struct i2c_client *client = ts_data->client;
423 
424     if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
425         FTS_ERROR("apk proc read count(%d) fail", buflen);
426         return -EINVAL;
427     }
428 
429     if (buflen > PROC_BUF_SIZE) {
430         buf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
431         if (NULL == buf) {
432             FTS_ERROR("apk proc wirte buf zalloc fail");
433             return -ENOMEM;
434         }
435     } else {
436         buf = tmpbuf;
437     }
438 
439 #if FTS_ESDCHECK_EN
440     fts_esdcheck_proc_busy(1);
441 #endif
442     switch (ts_data->proc_opmode) {
443     case PROC_READ_REGISTER:
444         num_read_chars = 1;
445         ret = fts_i2c_read(client, NULL, 0, buf, num_read_chars);
446         if (ret < 0) {
447 #if FTS_ESDCHECK_EN
448             fts_esdcheck_proc_busy(0);
449 #endif
450             FTS_ERROR("[APK]: read iic error!!");
451             goto proc_read_err;
452         }
453         break;
454     case PROC_READ_DATA:
455         num_read_chars = buflen;
456         ret = fts_i2c_read(client, NULL, 0, buf, num_read_chars);
457         if (ret < 0) {
458 #if FTS_ESDCHECK_EN
459             fts_esdcheck_proc_busy(0);
460 #endif
461             FTS_ERROR("[APK]: read iic error!!");
462             goto proc_read_err;
463         }
464         break;
465     case PROC_WRITE_DATA:
466         break;
467     default:
468         break;
469     }
470 
471 #if FTS_ESDCHECK_EN
472     fts_esdcheck_proc_busy(0);
473 #endif
474 
475     memcpy(page, buf, num_read_chars);
476 
477     ret = num_read_chars;
478 proc_read_err:
479     if ((buflen > PROC_BUF_SIZE) && buf) {
480         kfree(buf);
481         buf = NULL;
482     }
483     return ret;
484 }
485 #endif /* LINUX_VERSION_CODE */
486 
487 /************************************************************************
488 * Name: fts_create_apk_debug_channel
489 * Brief:  create apk debug channel
490 * Input: i2c info
491 * Output:
492 * Return: return 0 if success
493 ***********************************************************************/
fts_create_apk_debug_channel(struct fts_ts_data * ts_data)494 int fts_create_apk_debug_channel(struct fts_ts_data *ts_data)
495 {
496 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
497     ts_data->proc = proc_create(PROC_NAME, 0664, NULL, &fts_proc_fops);
498 #else
499     ts_data->proc = create_proc_entry(PROC_NAME, 0664, NULL);
500 #endif
501     if (NULL == ts_data->proc) {
502         FTS_ERROR("create proc entry fail");
503         return -ENOMEM;
504     } else {
505         FTS_INFO("Create proc entry success!");
506 
507 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
508         ts_data->proc->write_proc = fts_debug_write;
509         ts_data->proc->read_proc = fts_debug_read;
510 #endif
511     }
512 
513     return 0;
514 }
515 
516 /************************************************************************
517 * Name: fts_release_apk_debug_channel
518 * Brief:  release apk debug channel
519 * Input:
520 * Output:
521 * Return:
522 ***********************************************************************/
fts_release_apk_debug_channel(struct fts_ts_data * ts_data)523 void fts_release_apk_debug_channel(struct fts_ts_data *ts_data)
524 {
525 
526     if (ts_data->proc) {
527 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
528         proc_remove(ts_data->proc);
529 #else
530         remove_proc_entry(PROC_NAME, NULL);
531 #endif
532     }
533 }
534 #endif /* FTS_APK_NODE_EN */
535 
536 #if FTS_SYSFS_NODE_EN
537 
538 /************************************************************************
539  * sysfs interface
540  ***********************************************************************/
541 
542 /*
543  * fts_hw_reset interface
544  */
fts_hw_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)545 static ssize_t fts_hw_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
546 {
547     return -EPERM;
548 }
549 
fts_hw_reset_show(struct device * dev,struct device_attribute * attr,char * buf)550 static ssize_t fts_hw_reset_show(struct device *dev, struct device_attribute *attr, char *buf)
551 {
552     struct input_dev *input_dev = fts_data->input_dev;
553     ssize_t count = 0;
554 
555     mutex_lock(&input_dev->mutex);
556     fts_reset_proc(0);
557     count = snprintf(buf, PAGE_SIZE, "hw reset executed\n");
558     mutex_unlock(&input_dev->mutex);
559 
560     return count;
561 }
562 
563 /*
564  * fts_irq interface
565  */
fts_irq_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)566 static ssize_t fts_irq_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
567 {
568     struct input_dev *input_dev = fts_data->input_dev;
569 
570     mutex_lock(&input_dev->mutex);
571     if (FTS_SYSFS_ECHO_ON(buf)) {
572         FTS_INFO("[EX-FUN]enable irq");
573         fts_irq_enable();
574     } else if (FTS_SYSFS_ECHO_OFF(buf)) {
575         FTS_INFO("[EX-FUN]disable irq");
576         fts_irq_disable();
577     }
578     mutex_unlock(&input_dev->mutex);
579     return count;
580 }
581 
fts_irq_show(struct device * dev,struct device_attribute * attr,char * buf)582 static ssize_t fts_irq_show(struct device *dev, struct device_attribute *attr, char *buf)
583 {
584     return -EPERM;
585 }
586 
587 /*
588  * fts_tpfwver interface
589  */
fts_tpfwver_show(struct device * dev,struct device_attribute * attr,char * buf)590 static ssize_t fts_tpfwver_show(struct device *dev, struct device_attribute *attr, char *buf)
591 {
592     struct fts_ts_data *ts_data = fts_data;
593     struct input_dev *input_dev = ts_data->input_dev;
594     struct i2c_client *client = ts_data->client;
595     ssize_t num_read_chars = 0;
596     u8 fwver = 0;
597 
598     mutex_lock(&input_dev->mutex);
599 
600 #if FTS_ESDCHECK_EN
601     fts_esdcheck_proc_busy(1);
602 #endif
603     if (fts_i2c_read_reg(client, FTS_REG_FW_VER, &fwver) < 0) {
604         num_read_chars = snprintf(buf, PAGE_SIZE, "I2c transfer error!\n");
605 		goto error;
606     }
607 #if FTS_ESDCHECK_EN
608     fts_esdcheck_proc_busy(0);
609 #endif
610     if ((fwver == 0xFF) || (fwver == 0x00))
611         num_read_chars = snprintf(buf, PAGE_SIZE, "get tp fw version fail!\n");
612     else
613         num_read_chars = snprintf(buf, PAGE_SIZE, "%02x\n", fwver);
614 
615 error:
616     mutex_unlock(&input_dev->mutex);
617     return num_read_chars;
618 }
619 
fts_tpfwver_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)620 static ssize_t fts_tpfwver_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
621 {
622     return -EPERM;
623 }
624 
625 /************************************************************************
626 * Name: fts_tprwreg_show
627 * Brief:  no
628 * Input: device, device attribute, char buf
629 * Output: no
630 * Return: EPERM
631 ***********************************************************************/
fts_tprwreg_show(struct device * dev,struct device_attribute * attr,char * buf)632 static ssize_t fts_tprwreg_show(struct device *dev, struct device_attribute *attr, char *buf)
633 {
634     int count;
635     int i;
636     struct input_dev *input_dev = fts_data->input_dev;
637 
638     mutex_lock(&input_dev->mutex);
639 
640     if (rw_op.len < 0) {
641         count = snprintf(buf, PAGE_SIZE, "Invalid cmd line\n");
642     } else if (rw_op.len == 1) {
643         if (RWREG_OP_READ == rw_op.type) {
644             if (rw_op.res == 0) {
645                 count = snprintf(buf, PAGE_SIZE, "Read %02X: %02X\n", rw_op.reg, rw_op.val);
646             } else {
647                 count = snprintf(buf, PAGE_SIZE, "Read %02X failed, ret: %d\n", rw_op.reg,  rw_op.res);
648             }
649         } else {
650             if (rw_op.res == 0) {
651                 count = snprintf(buf, PAGE_SIZE, "Write %02X, %02X success\n", rw_op.reg,  rw_op.val);
652             } else {
653                 count = snprintf(buf, PAGE_SIZE, "Write %02X failed, ret: %d\n", rw_op.reg,  rw_op.res);
654             }
655         }
656     } else {
657         if (RWREG_OP_READ == rw_op.type) {
658             count = snprintf(buf, PAGE_SIZE, "Read Reg: [%02X]-[%02X]\n", rw_op.reg, rw_op.reg + rw_op.len);
659             count += snprintf(buf + count, PAGE_SIZE, "Result: ");
660             if (rw_op.res) {
661                 count += snprintf(buf + count, PAGE_SIZE, "failed, ret: %d\n", rw_op.res);
662             } else {
663                 if (rw_op.opbuf) {
664                     for (i = 0; i < rw_op.len; i++) {
665                         count += snprintf(buf + count, PAGE_SIZE, "%d ", rw_op.opbuf[i]);
666                     }
667                     count += snprintf(buf + count, PAGE_SIZE, "\n");
668                 }
669             }
670         } else {
671             ;
672             count = snprintf(buf, PAGE_SIZE, "Write Reg: [%02X]-[%02X]\n", rw_op.reg, rw_op.reg + rw_op.len - 1);
673             count += snprintf(buf + count, PAGE_SIZE, "Write Data: ");
674             if (rw_op.opbuf) {
675                 for (i = 1; i < rw_op.len; i++) {
676                     count += snprintf(buf + count, PAGE_SIZE, "%d ", rw_op.opbuf[i]);
677                 }
678                 count += snprintf(buf + count, PAGE_SIZE, "\n");
679             }
680             if (rw_op.res) {
681                 count += snprintf(buf + count, PAGE_SIZE, "Result: failed, ret: %d\n", rw_op.res);
682             } else {
683                 count += snprintf(buf + count, PAGE_SIZE, "Result: success\n");
684             }
685         }
686         /*if (rw_op.opbuf) {
687             kfree(rw_op.opbuf);
688             rw_op.opbuf = NULL;
689         }*/
690     }
691     mutex_unlock(&input_dev->mutex);
692 
693     return count;
694 }
695 
shex_to_int(const char * hex_buf,int size)696 static int shex_to_int(const char *hex_buf, int size)
697 {
698     int i;
699     int base = 1;
700     int value = 0;
701     char single;
702 
703     for (i = size - 1; i >= 0; i--) {
704         single = hex_buf[i];
705 
706         if ((single >= '0') && (single <= '9')) {
707             value += (single - '0') * base;
708         } else if ((single >= 'a') && (single <= 'z')) {
709             value += (single - 'a' + 10) * base;
710         } else if ((single >= 'A') && (single <= 'Z')) {
711             value += (single - 'A' + 10) * base;
712         } else {
713             return -EINVAL;
714         }
715 
716         base *= 16;
717     }
718 
719     return value;
720 }
721 
722 
shex_to_u8(const char * hex_buf,int size)723 static u8 shex_to_u8(const char *hex_buf, int size)
724 {
725     return (u8)shex_to_int(hex_buf, size);
726 }
727 /*
728  * Format buf:
729  * [0]: '0' write, '1' read(reserved)
730  * [1-2]: addr, hex
731  * [3-4]: length, hex
732  * [5-6]...[n-(n+1)]: data, hex
733  */
fts_parse_buf(const char * buf,size_t cmd_len)734 static int fts_parse_buf(const char *buf, size_t cmd_len)
735 {
736     int length;
737     int i;
738     char *tmpbuf;
739 
740     rw_op.reg = shex_to_u8(buf + 1, 2);
741     length = shex_to_int(buf + 3, 2);
742 
743     if (buf[0] == '1') {
744         rw_op.len = length;
745         rw_op.type = RWREG_OP_READ;
746         FTS_DEBUG("read %02X, %d bytes", rw_op.reg, rw_op.len);
747     } else {
748         if (cmd_len < (length * 2 + 5)) {
749             pr_err("data invalided!\n");
750             return -EINVAL;
751         }
752         FTS_DEBUG("write %02X, %d bytes", rw_op.reg, length);
753 
754         /* first byte is the register addr */
755         rw_op.type = RWREG_OP_WRITE;
756         rw_op.len = length + 1;
757     }
758 
759     if (rw_op.len > 0) {
760         tmpbuf = (char *)kzalloc(rw_op.len, GFP_KERNEL);
761         if (!tmpbuf) {
762             FTS_ERROR("allocate memory failed!\n");
763             return -ENOMEM;
764         }
765 
766         if (RWREG_OP_WRITE == rw_op.type) {
767             tmpbuf[0] = rw_op.reg & 0xFF;
768             FTS_DEBUG("write buffer: ");
769             for (i = 1; i < rw_op.len; i++) {
770                 tmpbuf[i] = shex_to_u8(buf + 5 + i * 2 - 2, 2);
771                 FTS_DEBUG("buf[%d]: %02X", i, tmpbuf[i] & 0xFF);
772             }
773         }
774         rw_op.opbuf = tmpbuf;
775     }
776 
777     return rw_op.len;
778 }
779 
780 /************************************************************************
781 * Name: fts_tprwreg_store
782 * Brief:  read/write register
783 * Input: device, device attribute, char buf, char count
784 * Output: print register value
785 * Return: char count
786 ***********************************************************************/
fts_tprwreg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)787 static ssize_t fts_tprwreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
788 {
789     struct input_dev *input_dev = fts_data->input_dev;
790     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
791     ssize_t cmd_length = 0;
792 
793     mutex_lock(&input_dev->mutex);
794     cmd_length = count - 1;
795 
796     if (rw_op.opbuf) {
797         kfree(rw_op.opbuf);
798         rw_op.opbuf = NULL;
799     }
800 
801     FTS_DEBUG("cmd len: %d, buf: %s", (int)cmd_length, buf);
802     /* compatible old ops */
803     if (2 == cmd_length) {
804         rw_op.type = RWREG_OP_READ;
805         rw_op.len = 1;
806 
807         rw_op.reg = shex_to_int(buf, 2);
808     } else if (4 == cmd_length) {
809         rw_op.type = RWREG_OP_WRITE;
810         rw_op.len = 1;
811         rw_op.reg = shex_to_int(buf, 2);
812         rw_op.val = shex_to_int(buf + 2, 2);
813 
814     } else if (cmd_length < 5) {
815         FTS_ERROR("Invalid cmd buffer");
816         mutex_unlock(&input_dev->mutex);
817         return -EINVAL;
818     } else {
819         rw_op.len = fts_parse_buf(buf, cmd_length);
820     }
821 
822 #if FTS_ESDCHECK_EN
823     fts_esdcheck_proc_busy(1);
824 #endif
825     if (rw_op.len < 0) {
826         FTS_ERROR("cmd buffer error!");
827 
828     } else {
829         if (RWREG_OP_READ == rw_op.type) {
830             if (rw_op.len == 1) {
831                 u8 reg, val;
832                 reg = rw_op.reg & 0xFF;
833                 rw_op.res = fts_i2c_read_reg(client, reg, &val);
834                 rw_op.val = val;
835             } else {
836                 char reg;
837                 reg = rw_op.reg & 0xFF;
838 
839                 rw_op.res = fts_i2c_read(client, &reg, 1, rw_op.opbuf, rw_op.len);
840             }
841 
842             if (rw_op.res < 0) {
843                 FTS_ERROR("Could not read 0x%02x", rw_op.reg);
844             } else {
845                 FTS_INFO("read 0x%02x, %d bytes successful", rw_op.reg, rw_op.len);
846                 rw_op.res = 0;
847             }
848 
849         } else {
850             if (rw_op.len == 1) {
851                 u8 reg, val;
852                 reg = rw_op.reg & 0xFF;
853                 val = rw_op.val & 0xFF;
854                 rw_op.res = fts_i2c_write_reg(client, reg, val);
855             } else {
856                 rw_op.res = fts_i2c_write(client, rw_op.opbuf, rw_op.len);
857             }
858             if (rw_op.res < 0) {
859                 FTS_ERROR("Could not write 0x%02x", rw_op.reg);
860 
861             } else {
862                 FTS_INFO("Write 0x%02x, %d bytes successful", rw_op.val, rw_op.len);
863                 rw_op.res = 0;
864             }
865         }
866     }
867 
868 #if FTS_ESDCHECK_EN
869     fts_esdcheck_proc_busy(0);
870 #endif
871     mutex_unlock(&input_dev->mutex);
872 
873     return count;
874 }
875 
876 /*
877  * fts_upgrade_bin interface
878  */
fts_fwupgradebin_show(struct device * dev,struct device_attribute * attr,char * buf)879 static ssize_t fts_fwupgradebin_show(struct device *dev, struct device_attribute *attr, char *buf)
880 {
881     return -EPERM;
882 }
883 
fts_fwupgradebin_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)884 static ssize_t fts_fwupgradebin_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
885 {
886     char fwname[FILE_NAME_LENGTH];
887     struct fts_ts_data *ts_data = fts_data;
888     struct input_dev *input_dev = ts_data->input_dev;
889     struct i2c_client *client = ts_data->client;
890 
891     if ((count <= 1) || (count >= FILE_NAME_LENGTH - 32)) {
892         FTS_ERROR("fw bin name's length(%d) fail", (int)count);
893         return -EINVAL;
894     }
895     memset(fwname, 0, sizeof(fwname));
896     snprintf(fwname, sizeof(fwname), "%s", buf);
897     fwname[count - 1] = '\0';
898 
899     FTS_INFO("upgrade with bin file through sysfs node");
900     mutex_lock(&input_dev->mutex);
901     ts_data->fw_loading = 1;
902     fts_irq_disable();
903 #if FTS_ESDCHECK_EN
904     fts_esdcheck_switch(DISABLE);
905 #endif
906 
907     fts_upgrade_bin(client, fwname, 0);
908 
909 #if FTS_ESDCHECK_EN
910     fts_esdcheck_switch(ENABLE);
911 #endif
912     fts_irq_enable();
913     ts_data->fw_loading = 0;
914     mutex_unlock(&input_dev->mutex);
915 
916     return count;
917 }
918 
919 /*
920  * fts_force_upgrade interface
921  */
fts_fwforceupg_show(struct device * dev,struct device_attribute * attr,char * buf)922 static ssize_t fts_fwforceupg_show(struct device *dev, struct device_attribute *attr, char *buf)
923 {
924     return -EPERM;
925 }
926 
fts_fwforceupg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)927 static ssize_t fts_fwforceupg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
928 {
929     char fwname[FILE_NAME_LENGTH];
930     struct fts_ts_data *ts_data = fts_data;
931     struct input_dev *input_dev = ts_data->input_dev;
932     struct i2c_client *client = ts_data->client;
933 
934     if ((count <= 1) || (count >= FILE_NAME_LENGTH - 32)) {
935         FTS_ERROR("fw bin name's length(%d) fail", (int)count);
936         return -EINVAL;
937     }
938     memset(fwname, 0, sizeof(fwname));
939     snprintf(fwname, sizeof(fwname), "%s", buf);
940     fwname[count - 1] = '\0';
941 
942     FTS_INFO("force upgrade through sysfs node");
943     mutex_lock(&input_dev->mutex);
944     ts_data->fw_loading = 1;
945     fts_irq_disable();
946 #if FTS_ESDCHECK_EN
947     fts_esdcheck_switch(DISABLE);
948 #endif
949 
950     fts_upgrade_bin(client, fwname, 1);
951 
952 #if FTS_ESDCHECK_EN
953     fts_esdcheck_switch(ENABLE);
954 #endif
955     fts_irq_enable();
956     ts_data->fw_loading = 0;
957     mutex_unlock(&input_dev->mutex);
958 
959     return count;
960 }
961 
962 /*
963  * fts_driver_info interface
964  */
fts_driverinfo_show(struct device * dev,struct device_attribute * attr,char * buf)965 static ssize_t fts_driverinfo_show(struct device *dev, struct device_attribute *attr, char *buf)
966 {
967     int count = 0;
968     struct fts_ts_data *ts_data = fts_data;
969     struct fts_ts_platform_data *pdata = ts_data->pdata;
970     struct input_dev *input_dev = ts_data->input_dev;
971 
972     mutex_lock(&input_dev->mutex);
973     count += snprintf(buf + count, PAGE_SIZE, "Driver Ver:%s\n", FTS_DRIVER_VERSION);
974 
975     count += snprintf(buf + count, PAGE_SIZE, "Resolution:(%d,%d)~(%d,%d)\n",
976                       pdata->x_min, pdata->y_min, pdata->x_max, pdata->y_max);
977 
978     count += snprintf(buf + count, PAGE_SIZE, "Max Touchs:%d\n", pdata->max_touch_number);
979 
980     count += snprintf(buf + count, PAGE_SIZE, "reset gpio:%d,int gpio:%d,irq:%d\n",
981                       pdata->reset_gpio, pdata->irq_gpio, ts_data->irq);
982 
983     count += snprintf(buf + count, PAGE_SIZE, "IC ID:0x%02x%02x\n",
984                       ts_data->ic_info.ids.chip_idh, ts_data->ic_info.ids.chip_idl);
985     mutex_unlock(&input_dev->mutex);
986 
987     return count;
988 }
989 
fts_driverinfo_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)990 static ssize_t fts_driverinfo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
991 {
992     return -EPERM;
993 }
994 
995 /*
996  * fts_dump_reg interface
997  */
fts_dumpreg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)998 static ssize_t fts_dumpreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
999 {
1000     return -EPERM;
1001 }
1002 
fts_dumpreg_show(struct device * dev,struct device_attribute * attr,char * buf)1003 static ssize_t fts_dumpreg_show(struct device *dev, struct device_attribute *attr, char *buf)
1004 {
1005     int count = 0;
1006     u8 val = 0;
1007     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1008     struct input_dev *input_dev = fts_data->input_dev;
1009 
1010     mutex_lock(&input_dev->mutex);
1011 #if FTS_ESDCHECK_EN
1012     fts_esdcheck_proc_busy(1);
1013 #endif
1014     fts_i2c_read_reg(client, FTS_REG_POWER_MODE, &val);
1015     count += snprintf(buf + count, PAGE_SIZE, "Power Mode:0x%02x\n", val);
1016 
1017     fts_i2c_read_reg(client, FTS_REG_FW_VER, &val);
1018     count += snprintf(buf + count, PAGE_SIZE, "FW Ver:0x%02x\n", val);
1019 
1020     fts_i2c_read_reg(client, FTS_REG_LIC_VER, &val);
1021     count += snprintf(buf + count, PAGE_SIZE, "LCD Initcode Ver:0x%02x\n", val);
1022 
1023     fts_i2c_read_reg(client, FTS_REG_IDE_PARA_VER_ID, &val);
1024     count += snprintf(buf + count, PAGE_SIZE, "Param Ver:0x%02x\n", val);
1025 
1026     fts_i2c_read_reg(client, FTS_REG_IDE_PARA_STATUS, &val);
1027     count += snprintf(buf + count, PAGE_SIZE, "Param status:0x%02x\n", val);
1028 
1029     fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &val);
1030     count += snprintf(buf + count, PAGE_SIZE, "Vendor ID:0x%02x\n", val);
1031 
1032     fts_i2c_read_reg(client, FTS_REG_LCD_BUSY_NUM, &val);
1033     count += snprintf(buf + count, PAGE_SIZE, "LCD Busy Number:0x%02x\n", val);
1034 
1035     fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val);
1036     count += snprintf(buf + count, PAGE_SIZE, "Gesture Mode:0x%02x\n", val);
1037 
1038     fts_i2c_read_reg(client, FTS_REG_CHARGER_MODE_EN, &val);
1039     count += snprintf(buf + count, PAGE_SIZE, "charge stat:0x%02x\n", val);
1040 
1041     fts_i2c_read_reg(client, FTS_REG_INT_CNT, &val);
1042     count += snprintf(buf + count, PAGE_SIZE, "INT count:0x%02x\n", val);
1043 
1044     fts_i2c_read_reg(client, FTS_REG_FLOW_WORK_CNT, &val);
1045     count += snprintf(buf + count, PAGE_SIZE, "ESD count:0x%02x\n", val);
1046 #if FTS_ESDCHECK_EN
1047     fts_esdcheck_proc_busy(0);
1048 #endif
1049 
1050     mutex_unlock(&input_dev->mutex);
1051     return count;
1052 }
1053 
1054 /* get the fw version  example:cat fw_version */
1055 static DEVICE_ATTR(fts_fw_version, S_IRUGO | S_IWUSR, fts_tpfwver_show, fts_tpfwver_store);
1056 
1057 /* read and write register(s)
1058 *   All data type is **HEX**
1059 *   Single Byte:
1060 *       read:   echo 88 > rw_reg ---read register 0x88
1061 *       write:  echo 8807 > rw_reg ---write 0x07 into register 0x88
1062 *   Multi-bytes:
1063 *       [0:rw-flag][1-2: reg addr, hex][3-4: length, hex][5-6...n-n+1: write data, hex]
1064 *       rw-flag: 0, write; 1, read
1065 *       read:  echo 10005           > rw_reg ---read reg 0x00-0x05
1066 *       write: echo 000050102030405 > rw_reg ---write reg 0x00-0x05 as 01,02,03,04,05
1067 *  Get result:
1068 *       cat rw_reg
1069 */
1070 static DEVICE_ATTR(fts_rw_reg, S_IRUGO | S_IWUSR, fts_tprwreg_show, fts_tprwreg_store);
1071 /*  upgrade from fw bin file   example:echo "*.bin" > fts_upgrade_bin */
1072 static DEVICE_ATTR(fts_upgrade_bin, S_IRUGO | S_IWUSR, fts_fwupgradebin_show, fts_fwupgradebin_store);
1073 static DEVICE_ATTR(fts_force_upgrade, S_IRUGO | S_IWUSR, fts_fwforceupg_show, fts_fwforceupg_store);
1074 static DEVICE_ATTR(fts_driver_info, S_IRUGO | S_IWUSR, fts_driverinfo_show, fts_driverinfo_store);
1075 static DEVICE_ATTR(fts_dump_reg, S_IRUGO | S_IWUSR, fts_dumpreg_show, fts_dumpreg_store);
1076 static DEVICE_ATTR(fts_hw_reset, S_IRUGO | S_IWUSR, fts_hw_reset_show, fts_hw_reset_store);
1077 static DEVICE_ATTR(fts_irq, S_IRUGO | S_IWUSR, fts_irq_show, fts_irq_store);
1078 
1079 /* add your attr in here*/
1080 static struct attribute *fts_attributes[] = {
1081     &dev_attr_fts_fw_version.attr,
1082     &dev_attr_fts_rw_reg.attr,
1083     &dev_attr_fts_dump_reg.attr,
1084     &dev_attr_fts_upgrade_bin.attr,
1085     &dev_attr_fts_force_upgrade.attr,
1086     &dev_attr_fts_driver_info.attr,
1087     &dev_attr_fts_hw_reset.attr,
1088     &dev_attr_fts_irq.attr,
1089     NULL
1090 };
1091 
1092 static struct attribute_group fts_attribute_group = {
1093     .attrs = fts_attributes
1094 };
1095 
1096 /************************************************************************
1097 * Name: fts_create_sysfs
1098 * Brief: create sysfs interface
1099 * Input:
1100 * Output:
1101 * Return: return 0 if success
1102 ***********************************************************************/
fts_create_sysfs(struct i2c_client * client)1103 int fts_create_sysfs(struct i2c_client *client)
1104 {
1105     int ret = 0;
1106 
1107     ret = sysfs_create_group(&client->dev.kobj, &fts_attribute_group);
1108     if (ret) {
1109         FTS_ERROR("[EX]: sysfs_create_group() failed!!");
1110         sysfs_remove_group(&client->dev.kobj, &fts_attribute_group);
1111         return -ENOMEM;
1112     } else {
1113         FTS_INFO("[EX]: sysfs_create_group() succeeded!!");
1114     }
1115 
1116     return ret;
1117 }
1118 /************************************************************************
1119 * Name: fts_remove_sysfs
1120 * Brief: remove sysfs interface
1121 * Input:
1122 * Output:
1123 * Return:
1124 ***********************************************************************/
fts_remove_sysfs(struct i2c_client * client)1125 int fts_remove_sysfs(struct i2c_client *client)
1126 {
1127     sysfs_remove_group(&client->dev.kobj, &fts_attribute_group);
1128     return 0;
1129 }
1130 #endif
1131