1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #include <linux/kernel.h>
3*4882a593Smuzhiyun #include <linux/module.h>
4*4882a593Smuzhiyun #include <linux/slab.h>
5*4882a593Smuzhiyun #include <linux/proc_fs.h>
6*4882a593Smuzhiyun #include <linux/fs.h>
7*4882a593Smuzhiyun #include <linux/uaccess.h>
8*4882a593Smuzhiyun #include <linux/i2c.h>
9*4882a593Smuzhiyun #include <linux/interrupt.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include "vtl_ts.h"
12*4882a593Smuzhiyun #include "chip.h"
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define APK_ITOUCH 0x01
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define INVALID 0x00
17*4882a593Smuzhiyun #define HW_RESET_CMD 0x01
18*4882a593Smuzhiyun #define CHIP_INFO_CMD 0x02
19*4882a593Smuzhiyun #define DRIVER_INFO_CMD 0x03
20*4882a593Smuzhiyun #define CHIP_ID_CMD 0x04
21*4882a593Smuzhiyun #define WRITE_CHIP_CMD 0x05
22*4882a593Smuzhiyun #define READ_CHIP_CMD 0x06
23*4882a593Smuzhiyun #define RECOVERY_CMD 0x07
24*4882a593Smuzhiyun #define INTERRUPT_CMD 0x08
25*4882a593Smuzhiyun #define READ_CHECKSUM_CMD 0x09
26*4882a593Smuzhiyun #define READ_FWCHECKSUM_CMD 0x0a
27*4882a593Smuzhiyun #define XY_DEBUG_CMD 0x0b
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define LINUX_SHELL 'c'
31*4882a593Smuzhiyun #define SHELL_CHECKSUM_CMD '1'
32*4882a593Smuzhiyun #define SHELL_UPDATE_CMD '2'
33*4882a593Smuzhiyun #define SHELL_DEBUG_CMD '3'
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun static struct ts_info * ts_object = NULL;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /*****************************************************************************
40*4882a593Smuzhiyun ** Function define
41*4882a593Smuzhiyun *****************************************************************************/
apk_i2c_transfer(struct i2c_client * client,unsigned char i2c_addr,unsigned char len,unsigned char * buf,unsigned char rw)42*4882a593Smuzhiyun static int apk_i2c_transfer(struct i2c_client *client,unsigned char i2c_addr,unsigned char len,unsigned char *buf,unsigned char rw)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun struct i2c_msg msgs[1];
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun DEBUG();
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun msgs[0].flags = rw;
49*4882a593Smuzhiyun msgs[0].addr = i2c_addr;
50*4882a593Smuzhiyun msgs[0].len = len;
51*4882a593Smuzhiyun msgs[0].buf = buf;
52*4882a593Smuzhiyun //msgs[0].scl_rate = TS_I2C_SPEED; //only for rockchip
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun if(i2c_transfer(client->adapter, msgs, 1)!= 1)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun return -1;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun return 0;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun
apk_open(struct inode * inode,struct file * file)63*4882a593Smuzhiyun static int apk_open(struct inode *inode, struct file *file)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun printk("___%s___\n",__func__);
66*4882a593Smuzhiyun DEBUG();
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun ts_object = vtl_ts_get_object();
69*4882a593Smuzhiyun if(ts_object == NULL)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun return -1;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun return 0;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
apk_close(struct inode * inode,struct file * file)76*4882a593Smuzhiyun static int apk_close(struct inode *inode, struct file *file)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun printk("___%s___\n",__func__);
79*4882a593Smuzhiyun DEBUG();
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun return 0;
82*4882a593Smuzhiyun }
apk_write(struct file * file,const char __user * buff,size_t count,loff_t * offp)83*4882a593Smuzhiyun static ssize_t apk_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun struct i2c_client *client = ts_object->driver->client;
86*4882a593Smuzhiyun unsigned char frame_data[255] = {0};
87*4882a593Smuzhiyun int bin_checksum = 0;
88*4882a593Smuzhiyun int fw_checksum = 0;
89*4882a593Smuzhiyun int ret = 0;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun DEBUG();
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun if(copy_from_user(frame_data, buff, count)){
94*4882a593Smuzhiyun return -EFAULT;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun if(frame_data[0]==APK_ITOUCH){
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun switch(frame_data[1]){
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun case HW_RESET_CMD :{
102*4882a593Smuzhiyun vtl_ts_hw_reset();
103*4882a593Smuzhiyun }break;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun case INTERRUPT_CMD :{
106*4882a593Smuzhiyun if(frame_data[4]){
107*4882a593Smuzhiyun enable_irq(ts_object->config_info.irq_number);
108*4882a593Smuzhiyun }else{
109*4882a593Smuzhiyun disable_irq(ts_object->config_info.irq_number);
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun }break;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun case RECOVERY_CMD :{
114*4882a593Smuzhiyun ret = update(client);
115*4882a593Smuzhiyun }break;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun case WRITE_CHIP_CMD:{
118*4882a593Smuzhiyun ret = apk_i2c_transfer(client,frame_data[2],frame_data[3],&frame_data[4],0);
119*4882a593Smuzhiyun }break;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun case XY_DEBUG_CMD :{
122*4882a593Smuzhiyun if(ts_object->debug){
123*4882a593Smuzhiyun ts_object->debug = 0x00;
124*4882a593Smuzhiyun }else{
125*4882a593Smuzhiyun ts_object->debug = 0x01;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun }break;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun default :{
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun }break;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun }else if(frame_data[0]==LINUX_SHELL){
134*4882a593Smuzhiyun printk("CMD: %s,count = %zu\n",frame_data,count);
135*4882a593Smuzhiyun switch(frame_data[1]){
136*4882a593Smuzhiyun case SHELL_CHECKSUM_CMD :{
137*4882a593Smuzhiyun chip_get_checksum(client,&bin_checksum,&fw_checksum);
138*4882a593Smuzhiyun printk("bin_checksum = 0x%x,fw_checksum = 0x%x\n",bin_checksum,fw_checksum);
139*4882a593Smuzhiyun }break;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun case SHELL_UPDATE_CMD :{
142*4882a593Smuzhiyun chip_update(client);
143*4882a593Smuzhiyun }break;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun case SHELL_DEBUG_CMD :{
146*4882a593Smuzhiyun if(ts_object->debug){
147*4882a593Smuzhiyun ts_object->debug = 0x00;
148*4882a593Smuzhiyun }else{
149*4882a593Smuzhiyun ts_object->debug = 0x01;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun }break;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun default :{
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun }break;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun }else{
159*4882a593Smuzhiyun return -1;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun if(ret<0){
162*4882a593Smuzhiyun return -1;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun return count;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
apk_read(struct file * file,char __user * buff,size_t count,loff_t * offp)168*4882a593Smuzhiyun static ssize_t apk_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun struct i2c_client *client = ts_object->driver->client;
171*4882a593Smuzhiyun unsigned char frame_data[255];
172*4882a593Smuzhiyun int bin_checksum = 0;
173*4882a593Smuzhiyun int fw_checksum = 0;
174*4882a593Smuzhiyun int len = 0;
175*4882a593Smuzhiyun int ret = 0;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun DEBUG();
178*4882a593Smuzhiyun if(copy_from_user(frame_data, buff, count))
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun return -EFAULT;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun len = frame_data[3];
184*4882a593Smuzhiyun if(frame_data[0]==APK_ITOUCH){
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun switch(frame_data[1]){
187*4882a593Smuzhiyun case DRIVER_INFO_CMD :{
188*4882a593Smuzhiyun frame_data[0] = client->addr;
189*4882a593Smuzhiyun }break;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun case READ_CHIP_CMD :{
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun ret = apk_i2c_transfer(client,frame_data[2],frame_data[3],frame_data,1);
194*4882a593Smuzhiyun }break;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun case READ_CHECKSUM_CMD :{
197*4882a593Smuzhiyun ret = chip_get_checksum(client,&bin_checksum,&fw_checksum);
198*4882a593Smuzhiyun frame_data[0] = bin_checksum & 0x00ff;
199*4882a593Smuzhiyun frame_data[1] = bin_checksum >> 8;
200*4882a593Smuzhiyun frame_data[2] = fw_checksum & 0x00ff;
201*4882a593Smuzhiyun frame_data[3] = fw_checksum >> 8;
202*4882a593Smuzhiyun }break;
203*4882a593Smuzhiyun case READ_FWCHECKSUM_CMD :{
204*4882a593Smuzhiyun ret = chip_get_fwchksum(client,&fw_checksum);
205*4882a593Smuzhiyun frame_data[0] = fw_checksum & 0x00ff;
206*4882a593Smuzhiyun frame_data[1] = fw_checksum >> 8;
207*4882a593Smuzhiyun }break;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun default :{
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun }break;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun if(copy_to_user(buff, frame_data,len)){
216*4882a593Smuzhiyun return -EFAULT;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun if(ret<0){
219*4882a593Smuzhiyun return -1;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun return count;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun struct file_operations apk_fops = {
226*4882a593Smuzhiyun .owner = THIS_MODULE,
227*4882a593Smuzhiyun .open = apk_open,
228*4882a593Smuzhiyun .release = apk_close,
229*4882a593Smuzhiyun .write = apk_write,
230*4882a593Smuzhiyun .read = apk_read,
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun
233