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