1 /* drivers/input/touchscreen/goodix_tool.c
3 * 2010 - 2012 Goodix Technology.
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.
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.
17 * V1.0:2012/05/01,create file.
18 * V1.2:2012/10/17,reset_guitar etc.
19 * V1.4: 2013/06/08, new proc name
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 <linux/device.h>
34 #include <linux/miscdevice.h>
35 #include <asm/uaccess.h>
36 #include <linux/proc_fs.h> /*proc*/
38 #include "tpd_custom_gt9xx.h"
42 u8 wr
; //write read flag£¬0:R 1:W 2:PID 3:
43 u8 flag
; //0:no need flag/int 1: need flag 2:need int
44 u8 flag_addr
[2]; //flag address
45 u8 flag_val
; //flag val
46 u8 flag_relation
; //flag_val:flag 0:not equal 1:equal 2:> 3:<
47 u16 circle
; //polling cycle
48 u8 times
; //plling times
49 u8 retry
; //I2C retry times
50 u16 delay
; //delay befor read or after write
51 u16 data_len
; //data length
52 u8 addr_len
; //address length
55 u8
*data
; //data pointer
60 #define UPDATE_FUNCTIONS
61 #define DATA_LENGTH_UINT 512
62 #define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8*))
63 static char procname
[20] = {0};
64 extern struct i2c_client
*i2c_client_point
;
65 extern unsigned int touch_irq
;
66 static struct i2c_client
*gt_client
= NULL
;
68 #ifdef UPDATE_FUNCTIONS
69 extern s32
gup_enter_update_mode(struct i2c_client
*client
);
70 extern void gup_leave_update_mode(void);
71 extern s32
gup_update_proc(void *dir
);
73 extern s32
gup_load_hotknot_system(void);
74 extern s32
gup_load_fx_system(void);
75 extern s32
gup_recovery_main_system(void);
76 extern s32
gup_load_main_system(char *filepath
);
78 //static struct proc_dir_entry *goodix_proc_entry;
80 static s32
goodix_tool_write(struct file
*filp
, const char __user
*buff
, unsigned long len
, void *data
);
81 static s32
goodix_tool_read(char *page
, char **start
, off_t off
, int count
, int *eof
, void *data
);
82 static s32(*tool_i2c_read
)(u8
*, u16
);
83 static s32(*tool_i2c_write
)(u8
*, u16
);
86 extern void gtp_esd_switch(struct i2c_client
*client
, s32 on
);
89 #if (GTP_ESD_PROTECT || GTP_COMPATIBLE_MODE)
90 extern u8 is_reseting
;
95 s8 IC_TYPE
[16] = "GT9XX";
98 DECLARE_WAIT_QUEUE_HEAD(bp_waiter
);
99 u8 got_hotknot_state
= 0;
100 u8 got_hotknot_extra_state
= 0;
101 u8 wait_hotknot_state
= 0;
102 u8 force_wake_flag
= 0;
105 #define HOTKNOTNAME "hotknot"
107 static ssize_t
hotknot_read(struct file
*file
, char __user
*buffer
,
108 size_t count
, loff_t
*ppos
)
110 return goodix_tool_read(buffer
, NULL
,0, count
, NULL
, ppos
);
113 static ssize_t
hotknot_write(struct file
*file
, const char __user
*buffer
,
114 size_t count
, loff_t
*ppos
)
116 return goodix_tool_write(file
, buffer
, count
, ppos
);
119 static struct file_operations hotknot_fops
=
121 // .owner = THIS_MODULE,
122 .read
= hotknot_read
,
123 .write
= hotknot_write
,
126 static struct miscdevice hotknot_misc_device
=
128 .minor
= MISC_DYNAMIC_MINOR
,
130 .fops
= &hotknot_fops
,
132 static ssize_t
goodix_tool_upper_read(struct file
*file
, char __user
*buffer
,
133 size_t count
, loff_t
*ppos
)
135 return goodix_tool_read(buffer
, NULL
,0, count
, NULL
, ppos
);
138 static ssize_t
goodix_tool_upper_write(struct file
*file
, const char __user
*buffer
,
139 size_t count
, loff_t
*ppos
)
141 return goodix_tool_write(file
, buffer
, count
, ppos
);
144 static const struct file_operations gt_tool_fops
= {
145 .write
= goodix_tool_upper_write
,
146 .read
= goodix_tool_upper_read
,
149 static void tool_set_proc_name(char * procname
)
152 char *months
[12] = {"Jan", "Feb", "Mar", "Apr", "May",
153 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
156 int i
= 0, n_month
= 1, n_day
= 0, n_year
= 0;
158 sprintf(date
, "%s", __DATE__
);
160 //GTP_DEBUG("compile date: %s", date);
162 sscanf(date
, "%s %d %d", month
, &n_day
, &n_year
);
164 for (i
= 0; i
< 12; ++i
)
166 if (!memcmp(months
[i
], month
, 3))
173 sprintf(procname
, "gmnode%04d%02d%02d", n_year
, n_month
, n_day
);
175 sprintf(procname
, HOTKNOTNAME
);
177 //GTP_DEBUG("procname = %s", procname);
179 static s32
tool_i2c_read_no_extra(u8
*buf
, u16 len
)
183 ret
= gtp_i2c_read(gt_client
, buf
, len
+ GTP_ADDR_LENGTH
);
187 static s32
tool_i2c_write_no_extra(u8
*buf
, u16 len
)
191 ret
= gtp_i2c_write(gt_client
, buf
, len
);
195 static s32
tool_i2c_read_with_extra(u8
*buf
, u16 len
)
198 u8 pre
[2] = {0x0f, 0xff};
199 u8 end
[2] = {0x80, 0x00};
201 tool_i2c_write_no_extra(pre
, 2);
202 ret
= tool_i2c_read_no_extra(buf
, len
);
203 tool_i2c_write_no_extra(end
, 2);
208 static s32
tool_i2c_write_with_extra(u8
*buf
, u16 len
)
211 u8 pre
[2] = {0x0f, 0xff};
212 u8 end
[2] = {0x80, 0x00};
214 tool_i2c_write_no_extra(pre
, 2);
215 ret
= tool_i2c_write_no_extra(buf
, len
);
216 tool_i2c_write_no_extra(end
, 2);
221 static void register_i2c_func(void)
223 // if (!strncmp(IC_TYPE, "GT818", 5) || !strncmp(IC_TYPE, "GT816", 5)
224 // || !strncmp(IC_TYPE, "GT811", 5) || !strncmp(IC_TYPE, "GT818F", 6)
225 // || !strncmp(IC_TYPE, "GT827", 5) || !strncmp(IC_TYPE,"GT828", 5)
226 // || !strncmp(IC_TYPE, "GT813", 5))
227 if (strncmp(IC_TYPE
, "GT8110", 6) && strncmp(IC_TYPE
, "GT8105", 6)
228 && strncmp(IC_TYPE
, "GT801", 5) && strncmp(IC_TYPE
, "GT800", 5)
229 && strncmp(IC_TYPE
, "GT801PLUS", 9) && strncmp(IC_TYPE
, "GT811", 5)
230 && strncmp(IC_TYPE
, "GTxxx", 5) && strncmp(IC_TYPE
, "GT9XX", 5))
232 tool_i2c_read
= tool_i2c_read_with_extra
;
233 tool_i2c_write
= tool_i2c_write_with_extra
;
234 GTP_DEBUG("I2C function: with pre and end cmd!");
238 tool_i2c_read
= tool_i2c_read_no_extra
;
239 tool_i2c_write
= tool_i2c_write_no_extra
;
240 GTP_INFO("I2C function: without pre and end cmd!");
244 static void unregister_i2c_func(void)
246 tool_i2c_read
= NULL
;
247 tool_i2c_write
= NULL
;
248 GTP_INFO("I2C function: unregister i2c transfer function!");
251 s32
init_wr_node(struct i2c_client
*client
)
255 gt_client
= i2c_client_point
;
257 memset(&cmd_head
, 0, sizeof(cmd_head
));
258 cmd_head
.data
= NULL
;
262 while ((!cmd_head
.data
) && i
)
264 cmd_head
.data
= kzalloc(i
* DATA_LENGTH_UINT
, GFP_KERNEL
);
266 if (NULL
!= cmd_head
.data
)
276 DATA_LENGTH
= i
* DATA_LENGTH_UINT
+ GTP_ADDR_LENGTH
;
277 GTP_INFO("Applied memory size:%d.", DATA_LENGTH
);
281 GTP_ERROR("Apply for memory failed.");
285 cmd_head
.addr_len
= 2;
290 tool_set_proc_name(procname
);
292 goodix_proc_entry
= create_proc_entry(procname
, 0660, NULL
);
293 if (goodix_proc_entry
== NULL
)
295 GTP_ERROR("Couldn't create proc entry!");
300 GTP_INFO("Create proc entry success!");
301 goodix_proc_entry
->write_proc
= goodix_tool_write
;
302 goodix_proc_entry
->read_proc
= goodix_tool_read
;
305 if(proc_create(procname
, 0660, NULL
, >_tool_fops
)== NULL
)
307 GTP_ERROR("create_proc_entry %s failed", procname
);
312 #if 1 // setting by hotknot feature
313 if (misc_register(&hotknot_misc_device
))
315 printk("mtk_tpd: hotknot_device register failed\n");
323 void uninit_wr_node(void)
325 kfree(cmd_head
.data
);
326 cmd_head
.data
= NULL
;
327 unregister_i2c_func();
328 remove_proc_entry(procname
, NULL
);
331 static u8
relation(u8 src
, u8 dst
, u8 rlt
)
338 ret
= (src
!= dst
) ? true : false;
342 ret
= (src
== dst
) ? true : false;
343 GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", src
, dst
, (s32
)ret
);
347 ret
= (src
> dst
) ? true : false;
351 ret
= (src
< dst
) ? true : false;
355 ret
= (src
& dst
) ? true : false;
359 ret
= (!(src
| dst
)) ? true : false;
370 /*******************************************************
377 ********************************************************/
378 static u8
comfirm(void)
383 // memcpy(&buf[GTP_ADDR_LENGTH - cmd_head.addr_len], &cmd_head.flag_addr, cmd_head.addr_len);
384 // memcpy(buf, &cmd_head.flag_addr, cmd_head.addr_len);//Modified by Scott, 2012-02-17
385 memcpy(buf
, cmd_head
.flag_addr
, cmd_head
.addr_len
);
387 for (i
= 0; i
< cmd_head
.times
; i
++)
389 if (tool_i2c_read(buf
, 1) <= 0)
391 GTP_ERROR("Read flag data failed!");
395 if (true == relation(buf
[GTP_ADDR_LENGTH
], cmd_head
.flag_val
, cmd_head
.flag_relation
))
397 GTP_DEBUG("value at flag addr:0x%02x.", buf
[GTP_ADDR_LENGTH
]);
398 GTP_DEBUG("flag value:0x%02x.", cmd_head
.flag_val
);
402 msleep(cmd_head
.circle
);
405 if (i
>= cmd_head
.times
)
407 GTP_ERROR("Didn't get the flag to continue!");
414 /*******************************************************
416 Goodix tool write function.
418 standard proc write function param.
421 ********************************************************/
422 static s32
goodix_tool_write(struct file
*filp
, const char __user
*buff
, unsigned long len
, void *data
)
426 GTP_DEBUG_ARRAY((u8
*)buff
, len
);
428 if(tpd_halt
== 1||is_reseting
== 1)
430 //GTP_ERROR("[Write]tpd_halt =1 fail!");
434 ret
= copy_from_user(&cmd_head
, buff
, CMD_HEAD_LENGTH
);
438 GTP_ERROR("copy_from_user failed.");
441 GTP_DEBUG("wr :0x%02x.", cmd_head
.wr
);
443 GTP_DEBUG("flag:0x%02x.", cmd_head.flag);
444 GTP_DEBUG("flag addr:0x%02x%02x.", cmd_head.flag_addr[0], cmd_head.flag_addr[1]);
445 GTP_DEBUG("flag val:0x%02x.", cmd_head.flag_val);
446 GTP_DEBUG("flag rel:0x%02x.", cmd_head.flag_relation);
447 GTP_DEBUG("circle :%d.", (s32)cmd_head.circle);
448 GTP_DEBUG("times :%d.", (s32)cmd_head.times);
449 GTP_DEBUG("retry :%d.", (s32)cmd_head.retry);
450 GTP_DEBUG("delay :%d.", (s32)cmd_head.delay);
451 GTP_DEBUG("data len:%d.", (s32)cmd_head.data_len);
452 GTP_DEBUG("addr len:%d.", (s32)cmd_head.addr_len);
453 GTP_DEBUG("addr:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]);
454 GTP_DEBUG("len:%d.", (s32)len);
455 GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]);
458 if (1 == cmd_head
.wr
)
460 // copy_from_user(&cmd_head.data[cmd_head.addr_len], &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
461 ret
= copy_from_user(&cmd_head
.data
[GTP_ADDR_LENGTH
], &buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
465 GTP_ERROR("copy_from_user failed.");
468 memcpy(&cmd_head
.data
[GTP_ADDR_LENGTH
- cmd_head
.addr_len
], cmd_head
.addr
, cmd_head
.addr_len
);
470 GTP_DEBUG_ARRAY(cmd_head
.data
, cmd_head
.data_len
+ cmd_head
.addr_len
);
471 GTP_DEBUG_ARRAY((u8
*)&buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
473 if (1 == cmd_head
.flag
)
475 if (FAIL
== comfirm())
477 GTP_ERROR("[WRITE]Comfirm fail!");
481 else if (2 == cmd_head
.flag
)
486 if (tool_i2c_write(&cmd_head
.data
[GTP_ADDR_LENGTH
- cmd_head
.addr_len
],
487 cmd_head
.data_len
+ cmd_head
.addr_len
) <= 0)
489 GTP_ERROR("[WRITE]Write data failed!");
493 GTP_DEBUG_ARRAY(&cmd_head
.data
[GTP_ADDR_LENGTH
- cmd_head
.addr_len
], cmd_head
.data_len
+ cmd_head
.addr_len
);
497 msleep(cmd_head
.delay
);
500 return cmd_head
.data_len
+ CMD_HEAD_LENGTH
;
502 else if (3 == cmd_head
.wr
) //Write ic type
504 memcpy(IC_TYPE
, cmd_head
.data
, cmd_head
.data_len
);
507 return cmd_head
.data_len
+ CMD_HEAD_LENGTH
;
509 else if (5 == cmd_head
.wr
)
511 //memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
513 return cmd_head
.data_len
+ CMD_HEAD_LENGTH
;
515 else if (7 == cmd_head
.wr
)//disable irq!
517 #ifdef CONFIG_OF_TOUCH
518 disable_irq(touch_irq
);
520 mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM
);
524 gtp_esd_switch(i2c_client_point
, SWITCH_OFF
);
526 return CMD_HEAD_LENGTH
;
528 else if (9 == cmd_head
.wr
) //enable irq!
530 #ifdef CONFIG_OF_TOUCH
531 enable_irq(touch_irq
);
533 mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM
);
537 gtp_esd_switch(i2c_client_point
, SWITCH_ON
);
539 return CMD_HEAD_LENGTH
;
541 else if (17 == cmd_head
.wr
)
543 ret
= copy_from_user(&cmd_head
.data
[GTP_ADDR_LENGTH
], &buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
547 GTP_DEBUG("copy_from_user failed.");
550 if (cmd_head
.data
[GTP_ADDR_LENGTH
])
552 GTP_DEBUG("gtp enter rawdiff.");
553 gtp_rawdiff_mode
= true;
557 gtp_rawdiff_mode
= false;
558 GTP_DEBUG("gtp leave rawdiff.");
561 return CMD_HEAD_LENGTH
;
564 #ifdef UPDATE_FUNCTIONS
565 else if (11 == cmd_head
.wr
) //Enter update mode!
567 if (FAIL
== gup_enter_update_mode(gt_client
))
572 else if (13 == cmd_head
.wr
)//Leave update mode!
574 gup_leave_update_mode();
576 else if (15 == cmd_head
.wr
) //Update firmware!
580 if ((cmd_head
.data
== NULL
)
581 || (cmd_head
.data_len
>= DATA_LENGTH
)
582 || (cmd_head
.data_len
>= (len
- CMD_HEAD_LENGTH
))) {
583 GTP_ERROR("copy_from_user data out of range.");
587 memset(cmd_head
.data
, 0, cmd_head
.data_len
+ 1);
588 ret
= copy_from_user(cmd_head
.data
, &buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
591 GTP_ERROR("copy_from_user failed.");
593 GTP_DEBUG("update firmware, filename: %s", cmd_head
.data
);
594 if (FAIL
== gup_update_proc((void *)cmd_head
.data
))
601 else if (19 == cmd_head
.wr
) //load subsystem
603 ret
= copy_from_user(&cmd_head
.data
[0], &buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
604 if(0 == cmd_head
.data
[0])
606 if (FAIL
== gup_load_hotknot_system())
611 else if(1 == cmd_head
.data
[0])
613 if (FAIL
== gup_load_fx_system())
618 else if(2 == cmd_head
.data
[0])
620 if (FAIL
== gup_recovery_main_system())
625 else if(3 == cmd_head
.data
[0])
627 if (FAIL
== gup_load_main_system(NULL
))
634 else if (21 == cmd_head
.wr
)
636 u16 wait_hotknot_timeout
= 0;
637 u8 rqst_hotknot_state
;
639 ret
= copy_from_user(&cmd_head
.data
[GTP_ADDR_LENGTH
],
640 &buff
[CMD_HEAD_LENGTH
], cmd_head
.data_len
);
644 GTP_ERROR("copy_from_user failed.");
647 rqst_hotknot_state
= cmd_head
.data
[GTP_ADDR_LENGTH
];
648 wait_hotknot_state
|= rqst_hotknot_state
;
649 wait_hotknot_timeout
= (cmd_head
.data
[GTP_ADDR_LENGTH
+ 1]<<8) +
650 cmd_head
.data
[GTP_ADDR_LENGTH
+ 2];
651 GTP_DEBUG("Goodix tool received wait polling state:0x%x,timeout:%d, all wait state:0x%x",
652 rqst_hotknot_state
, wait_hotknot_timeout
, wait_hotknot_state
);
653 got_hotknot_state
&= (~rqst_hotknot_state
);
654 //got_hotknot_extra_state = 0;
655 switch(rqst_hotknot_state
)
657 set_current_state(TASK_INTERRUPTIBLE
);
658 case HN_DEVICE_PAIRED
:
659 hotknot_paired_flag
= 0;
660 wait_event_interruptible(bp_waiter
, force_wake_flag
||
661 rqst_hotknot_state
== (got_hotknot_state
&rqst_hotknot_state
));
662 wait_hotknot_state
&= (~rqst_hotknot_state
);
663 if(rqst_hotknot_state
!= (got_hotknot_state
&rqst_hotknot_state
))
665 GTP_ERROR("Wait 0x%x block polling waiter failed.", rqst_hotknot_state
);
671 case HN_SLAVE_RECEIVED
:
672 wait_event_interruptible_timeout(bp_waiter
, force_wake_flag
||
673 rqst_hotknot_state
== (got_hotknot_state
&rqst_hotknot_state
),
674 wait_hotknot_timeout
);
675 wait_hotknot_state
&= (~rqst_hotknot_state
);
676 if(rqst_hotknot_state
== (got_hotknot_state
&rqst_hotknot_state
))
678 return got_hotknot_extra_state
;
682 GTP_ERROR("Wait 0x%x block polling waiter timeout.", rqst_hotknot_state
);
687 case HN_MASTER_DEPARTED
:
688 case HN_SLAVE_DEPARTED
:
689 wait_event_interruptible_timeout(bp_waiter
, force_wake_flag
||
690 rqst_hotknot_state
== (got_hotknot_state
&rqst_hotknot_state
),
691 wait_hotknot_timeout
);
692 wait_hotknot_state
&= (~rqst_hotknot_state
);
693 if(rqst_hotknot_state
!= (got_hotknot_state
&rqst_hotknot_state
))
695 GTP_ERROR("Wait 0x%x block polling waitor timeout.", rqst_hotknot_state
);
701 GTP_ERROR("Invalid rqst_hotknot_state in goodix_tool.");
706 else if(23 == cmd_head
.wr
)
708 GTP_DEBUG("Manual wakeup all block polling waiter!");
709 got_hotknot_state
= 0;
710 wait_hotknot_state
= 0;
712 hotknot_paired_flag
= 0;
713 wake_up_interruptible(&bp_waiter
);
716 return CMD_HEAD_LENGTH
;
719 /*******************************************************
721 Goodix tool read function.
723 standard proc read function param.
726 ********************************************************/
727 static s32
goodix_tool_read(char *page
, char **start
, off_t off
, int count
, int *eof
, void *data
)
732 if(tpd_halt
== 1||is_reseting
== 1)
734 //GTP_ERROR("[READ]tpd_halt =1 fail!");
739 GTP_ERROR("[READ] invaild operator fail!");
742 else if (!cmd_head
.wr
)
748 if (1 == cmd_head
.flag
)
750 if (FAIL
== comfirm())
752 GTP_ERROR("[READ]Comfirm fail!");
756 else if (2 == cmd_head
.flag
)
761 memcpy(cmd_head
.data
, cmd_head
.addr
, cmd_head
.addr_len
);
763 GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head
.data
[0], cmd_head
.data
[1]);
764 GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head
.addr
[0], cmd_head
.addr
[1]);
768 msleep(cmd_head
.delay
);
771 data_len
= cmd_head
.data_len
;
775 if (data_len
> DATA_LENGTH
)
784 data_len
-= DATA_LENGTH
;
786 if (tool_i2c_read(cmd_head
.data
, len
) <= 0)
788 GTP_ERROR("[READ]Read data failed!");
792 ret
= copy_to_user(&page
[loc
], &cmd_head
.data
[GTP_ADDR_LENGTH
], len
);
795 GTP_ERROR("copy_from_user failed.");
800 GTP_DEBUG_ARRAY(&cmd_head
.data
[GTP_ADDR_LENGTH
], len
);
801 GTP_DEBUG_ARRAY(page
, len
);
804 else if (2 == cmd_head
.wr
)
806 // memcpy(page, "gt8", cmd_head.data_len);
807 // memcpy(page, "GT818", 5);
810 GTP_DEBUG("Return ic type:%s len:%d.", page
, (s32
)cmd_head
.data_len
);
811 return cmd_head
.data_len
;
812 //return sizeof(IC_TYPE_NAME);
814 else if (4 == cmd_head
.wr
)
816 page
[0] = show_len
>> 8;
817 page
[1] = show_len
& 0xff;
818 page
[2] = total_len
>> 8;
819 page
[3] = total_len
& 0xff;
821 return cmd_head
.data_len
;
823 else if (6 == cmd_head
.wr
)
827 else if (8 == cmd_head
.wr
) //Read driver version
829 // memcpy(page, GTP_DRIVER_VERSION, strlen(GTP_DRIVER_VERSION));
831 tmp_len
= strlen(GTP_DRIVER_VERSION
);
832 ret
= copy_to_user(page
, GTP_DRIVER_VERSION
, tmp_len
);
835 GTP_ERROR("copy_from_user failed.");
841 return cmd_head
.data_len
;