1 #include <linux/module.h>
2 #include <linux/init.h>
3 #include <linux/input.h>
4 #include <linux/gpio.h>
5 #include <linux/interrupt.h>
6 #include <linux/i2c.h>
7 #include <linux/slab.h>
8 #include <linux/delay.h>
9
10 #include <plat/gpio-cfg.h>
11
12 #define TS_MAX_WIDTH 800
13 #define TS_MAX_HEIGHT 480
14
15
16 #define TS_INT_GPIO S5PV210_GPH1(6)
17 #define TS_RESET_GPIO S5PV210_GPD0(3)
18
19
20 //设计一个全局的设备对象
21 struct ts_global{
22 int irqno;
23 int flags; // 中断触发方式
24 struct i2c_client *client; //记录匹配之后的i2c client
25 struct input_dev *inputdev;
26
27 struct work_struct work; //中断下半部
28 };
29
30 struct ts_global *gt811_dev;
31
32
33
34 //重写类似于i2c_master_send()/i2c_master_recv()
35 int gt811_i2c_send(struct i2c_client *client, char *buf, int count)
36 {
37 int ret;
38
39 struct i2c_adapter *adapter = client->adapter;
40 struct i2c_msg msg;
41
42 msg.addr = client->addr;
43 msg.flags = 0; //读1还是写0
44 msg.len = count;
45 msg.buf = buf;
46 //参数1---适配器--来自于i2c client
47 //参数2--数据包
48 //参数3--数据包的个数
49 //返回值--正确返回消息的个数,错误返回负数
50 ret = i2c_transfer(adapter, &msg, 1);
51
52 return ret==1?count:ret;
53
54 }
55
56
57 // char rbuf[10] = {0x7, 0x21 /*寄存器地址*/, }; // 后面8个字节用于存放读取到的数据
58 // gt811_i2c_recv_reg(client , rbuf, 10);
59 int gt811_i2c_recv_reg(struct i2c_client *client, char *buf, int count)
60 {
61 int ret;
62
63 struct i2c_adapter *adapter = client->adapter;
64 struct i2c_msg msg[2];
65
66 msg[0].addr = client->addr;
67 msg[0].flags = 0; //先写
68 msg[0].len = 2; //寄存器地址为16bit
69 msg[0].buf = &buf[0];
70
71 msg[1].addr = client->addr;
72 msg[1].flags = 1; //后读
73 msg[1].len = count-2; //
74 msg[1].buf = &buf[2];
75
76 //参数1---适配器--来自于i2c client
77 //参数2--数据包
78 //参数3--数据包的个数
79 //返回值--正确返回消息的个数,错误返回负数
80 ret = i2c_transfer(adapter, msg, 2);
81
82 return ret==2?count-2:ret;
83
84 }
85
86
87 int gt811_init_reg(void)
88 {
89 int ret;
90
91 uint8_t config_info[] = {
92 0x06,0xA2, //寄存器地址
93
94 0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0x05,0x55,0x15,0x55,0x25,0x55,
95 0x35,0x55,0x45,0x55,0x55,0x55,0x65,0x55,0x75,0x55,0x85,0x55,0x95,0x55,0xA5,0x55,
96 0xB5,0x55,0xC5,0x55,0xD5,0x55,0xE5,0x55,0xF5,0x55,0x1B,0x03,0x00,0x00,0x00,0x13,
97 0x13,0x13,0x0F,0x0F,0x0A,0x50,0x30,0x0D,0x03,0x00,0x05,0x58,0x02,0x00,0x04,0x00,
98 0x00,0x32,0x2C,0x34,0x2E,0x00,0x00,0x04,0x14,0x22,0x04,0x00,0x00,0x00,0x00,0x00,
99 0x20,0x14,0xEC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,
100 0x25,0x28,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x01
101 };
102
103 config_info[57] &= ~(1<<3);
104 gt811_dev->flags = IRQF_TRIGGER_FALLING;
105
106 config_info[61] = TS_MAX_HEIGHT & 0xff;
107 config_info[62] = TS_MAX_HEIGHT >> 8;
108
109 config_info[63] = TS_MAX_WIDTH& 0xff;
110 config_info[64] = TS_MAX_WIDTH >> 8;
111
112 ret = gt811_i2c_send(gt811_dev->client, config_info, ARRAY_SIZE(config_info));
113
114 return ret>0?0:ret;
115
116 }
117
118
119
120 void gt811_irq_work(struct work_struct *work)
121 {
122
123 /*
124 1,通过i2c_tranfser(会导致休眠)读取到坐标
125 2, 分析坐标
126 3, 上报坐标
127
128 */
129
130 int ret;
131 uint8_t axis_buf[36] = {0x7, 0x21,};
132
133 ret = gt811_i2c_recv_reg(gt811_dev->client, axis_buf, 36);
134 if(ret < 0)
135 {
136 printk("gt811_i2c_recv_reg error
");
137 return;
138 }
139
140 //先进行校验
141 //先要知道当前是哪几个点
142 unsigned char temp = axis_buf[2] & 0x1f; // 取低5bit
143 int i;
144 unsigned char soft_chksum = 0;
145 int index;
146 switch(temp)
147 {
148 case 0: //没有点,表示抬起
149 index = 4;
150 break;
151 case 1: //表示第0点被点
152 index = 9;
153 break;
154 case 2:
155 case 3: //表示第1点被点
156 index = 14;
157 break;
158
159 default: //表示 2, 3, 4点
160 index = 35;
161 break;
162
163 }
164 for(i=2; i<index; i++)
165 soft_chksum += axis_buf[i];
166
167 if(soft_chksum != axis_buf[index])
168 {
169 printk("check sum error
");
170 return ;
171 }
172
173 // 判断出当前有几个点,具体是那几个点
174 temp = axis_buf[2] & 0x1f; // 取低5bit
175 int pcount = 0 ; //点的个数
176 int pset[5]; //当前被点的点号集合
177 for(i=0; i<5; i++)
178 {
179 if(temp & 1)
180 {
181 pset[pcount++] = i;
182 }
183 temp = temp >> 1;
184 }
185
186 int j;
187 __u16 x;
188 __u16 y;
189 __u8 p;
190 int pindex = 0;
191 if(pcount > 0)
192 {
193 for(j=0; j<pcount; j++)
194 {
195 switch(pset[j])
196 {
197 case 0:
198 pindex = 4;
199 break;
200 case 1:
201 pindex = 9;
202 break;
203 case 2:
204 pindex = 14;
205 break;
206 case 3:
207 pindex = 19;
208 break;
209 case 4:
210 pindex = 30;
211 break;
212 }
213 if(pset[j] == 3)
214 {
215 x = axis_buf[19]<<8 | axis_buf[26];
216 y = axis_buf[27]<<8 | axis_buf[28];
217 p = axis_buf[29];
218 }else
219 {
220 x = axis_buf[pindex]<<8 | axis_buf[pindex+1];
221 y = axis_buf[pindex+2]<<8 | axis_buf[pindex+3];
222 p = axis_buf[pindex+4];
223 }
224
225 swap(x, y);
226
227 y = 480-y;
228 //printk("x = %d, y = %d, p = %d, id = %d
", x, y, p, pset[j]);
229
230 input_event(gt811_dev->inputdev, EV_ABS, ABS_MT_POSITION_X, x);
231 input_event(gt811_dev->inputdev, EV_ABS, ABS_MT_POSITION_Y, y);
232 input_event(gt811_dev->inputdev, EV_ABS, ABS_MT_PRESSURE, p);
233 input_event(gt811_dev->inputdev, EV_ABS, ABS_MT_TOUCH_MAJOR, p);
234 input_event(gt811_dev->inputdev, EV_ABS, ABS_MT_TRACKING_ID, pset[j]);
235 input_mt_sync(gt811_dev->inputdev);
236
237 }
238 }
239 //按下和抬起
240 input_report_key(gt811_dev->inputdev, BTN_TOUCH, pcount > 0);
241 input_sync(gt811_dev->inputdev);
242 }
243
244
245 irqreturn_t gt811_irq_svc(int irqno, void *dev_id)
246 {
247
248
249 //启动下半部--委托
250 schedule_work(>811_dev->work);
251
252
253 return IRQ_HANDLED;
254 }
255
256
257
258 int gt811_drv_probe(struct i2c_client *client, const struct i2c_device_id *id)
259 {
260 int ret;
261
262 gt811_dev = kzalloc(sizeof(struct ts_global), GFP_KERNEL);
263
264 // 0--记录当前的i2c client
265 gt811_dev->client = client;
266
267 /*
268 4, 硬件初始化:
269 a, 初始化寄存器
270 1, 设置中断引脚为悬浮输入态,RESET设置成GPIO(内部上拉)
271 2, RESET引脚设置成输出低(开始复位), 延时1ms, 转成输入态
272 3, 延迟至少20ms,通过i2c寻址gt811 (确认复位是否成功)
273 4,如果有响应,分一次或者多次初始化寄存器
274 5,如果没有响应,重复2步骤
275 b, 申请中断--request_irq(), 还要用中断下半部(tasklet, 工作队列(选择这个))
276 |
277 1,通过i2c_tranfser读取到坐标
278 2, 分析坐标
279 3, 上报坐标
280
281 */
282
283 gpio_request(TS_INT_GPIO, "ts_int");
284 gpio_direction_input(TS_INT_GPIO);
285 gpio_free(TS_INT_GPIO);
286
287 gpio_request(TS_RESET_GPIO, "ts_reset");
288 s3c_gpio_setpull(TS_RESET_GPIO, S3C_GPIO_PULL_UP);
289 mdelay(2);
290 gpio_direction_output(TS_RESET_GPIO, 0);
291 mdelay(1);
292 gpio_direction_input(TS_RESET_GPIO);
293 gpio_free(TS_RESET_GPIO);
294
295 mdelay(25);
296 //通过发送数据给gt811, 看看是否成功
297 char test = 1;
298 ret = i2c_master_send(gt811_dev->client, &test, 1);
299 if(ret < 0)
300 {
301 printk("gt811 reset failed or not found
");
302 kfree(gt811_dev);
303 return ret;
304 }else
305 {
306 printk("gt811 reset ok
");
307 }
308
309 ret = gt811_init_reg();
310 if(ret < 0)
311 {
312 printk("gt811_init_reg failed
");
313 kfree(gt811_dev);
314 return ret;
315 }else
316 {
317 printk("gt811 init ok
");
318 }
319
320 // 4, 硬件初始化,获取到硬件的数据,上报给input handler
321 //申请中断
322 //初始化中断下半部
323 INIT_WORK(>811_dev->work, gt811_irq_work);
324
325 gt811_dev->irqno = gpio_to_irq(TS_INT_GPIO);
326 ret = request_irq(gt811_dev->irqno, gt811_irq_svc, gt811_dev->flags,
327 "ts_eint14", NULL);
328
329 // 1, 构建一个input device
330 gt811_dev->inputdev = input_allocate_device();
331
332 //为输入设备提供额外信息--供用户查看--/sys/class/input/eventX/device/..
333 gt811_dev->inputdev->name = "gt811_ts";
334 gt811_dev->inputdev->phys = "goodix/ts/input0";
335 gt811_dev->inputdev->uniq = "goodix/gt811";
336 gt811_dev->inputdev->id.bustype = BUS_I2C;
337 gt811_dev->inputdev->id.vendor = 0xDEAD;
338 gt811_dev->inputdev->id.product = 0x0007;
339 gt811_dev->inputdev->id.version = 0x0001;
340
341 // 2, 初始化 input device
342 // 2.1 设置当前输入设备能够产生那些类型数据
343 __set_bit(EV_ABS, gt811_dev->inputdev->evbit);
344 __set_bit(EV_KEY, gt811_dev->inputdev->evbit);
345
346
347 // 2.2设置要产生那些按键
348 __set_bit(BTN_TOUCH, gt811_dev->inputdev->keybit);
349 __set_bit(KEY_MENU, gt811_dev->inputdev->keybit);
350 __set_bit(KEY_HOME, gt811_dev->inputdev->keybit);
351 __set_bit(KEY_ESC, gt811_dev->inputdev->keybit);
352
353
354 // 2.3 设置要产生那些绝对数据
355 //针对单点
356 __set_bit(ABS_X, gt811_dev->inputdev->absbit);
357 __set_bit(ABS_Y, gt811_dev->inputdev->absbit);
358 __set_bit(ABS_PRESSURE, gt811_dev->inputdev->absbit);
359
360 //针对多点
361 __set_bit(ABS_MT_POSITION_X, gt811_dev->inputdev->absbit);
362 __set_bit(ABS_MT_POSITION_Y, gt811_dev->inputdev->absbit);
363 __set_bit(ABS_MT_PRESSURE, gt811_dev->inputdev->absbit);
364 __set_bit(ABS_MT_TOUCH_MAJOR, gt811_dev->inputdev->absbit);
365 __set_bit(ABS_MT_TRACKING_ID, gt811_dev->inputdev->absbit);
366
367
368 // 2.4 --如果有abs的值,还需要设置abs的最大值和最小值
369 //参数1---设置哪个设备
370 //参数2--坐标
371 //参数3-4;最小值和最大值
372 //参数5-6: 一般填0
373 input_set_abs_params(gt811_dev->inputdev, ABS_X, 0, TS_MAX_WIDTH, 0, 0);
374 input_set_abs_params(gt811_dev->inputdev, ABS_Y, 0, TS_MAX_HEIGHT, 0, 0);
375 input_set_abs_params(gt811_dev->inputdev, ABS_PRESSURE, 0, 16, 0, 0);
376
377 input_set_abs_params(gt811_dev->inputdev, ABS_MT_POSITION_X, 0, TS_MAX_WIDTH, 0, 0);
378 input_set_abs_params(gt811_dev->inputdev, ABS_MT_POSITION_Y, 0, TS_MAX_HEIGHT, 0, 0);
379 input_set_abs_params(gt811_dev->inputdev, ABS_MT_PRESSURE, 0, 16, 0, 0);
380 input_set_abs_params(gt811_dev->inputdev, ABS_MT_TOUCH_MAJOR, 0, 16, 0, 0);
381 input_set_abs_params(gt811_dev->inputdev, ABS_MT_TRACKING_ID, 0, 4, 0, 0);
382
383 // 3, 注册input device
384 ret = input_register_device(gt811_dev->inputdev);
385
386
387
388
389
390
391
392 return 0;
393
394 }
395
396
397 int gt811_drv_remove(struct i2c_client *client)
398 {
399
400 input_unregister_device(gt811_dev->inputdev);
401 input_free_device(gt811_dev->inputdev);
402
403 cancel_work_sync(>811_dev->work);
404 free_irq(gt811_dev->irqno, NULL);
405
406 kfree(gt811_dev);
407
408 return 0;
409 }
410
411
412 const struct i2c_device_id gt811_id_table[] = {
413 {"gt811_i2c_ts", 0x811},
414 {}
415 };
416
417
418 struct i2c_driver gt811_i2c_drv = {
419 .probe = gt811_drv_probe,
420 .remove = gt811_drv_remove,
421 .driver = {
422 .name = "gt811_drv",
423 },
424 .id_table = gt811_id_table,
425
426 };
427
428
429
430
431 static int __init gt811_drv_init(void)
432 {
433 //注册一个i2c driver
434 return i2c_add_driver(>811_i2c_drv);
435
436 }
437
438
439 static void __exit gt811_drv_exit(void)
440 {
441
442 i2c_del_driver(>811_i2c_drv);
443 }
444
445 module_init(gt811_drv_init);
446 module_exit(gt811_drv_exit);
447 MODULE_LICENSE("GPL");