• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include <linux/delay.h>
20 #include <linux/input.h>
21 #include <linux/input/mt.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.h>
24 #include <linux/property.h>
25 #include <asm/irq.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/types.h>
29 #include <linux/fs.h>
30 #include <linux/errno.h>
31 #include <linux/miscdevice.h>
32 #include <linux/fcntl.h>
33 #include <linux/init.h>
34 #include <linux/proc_fs.h>
35 #include <linux/workqueue.h>
36 #include <asm/uaccess.h>
37 #include <asm/io.h>
38 #include <linux/slab.h>
39 #include <linux/string.h>
40 #include "hi_drv_i2c.h"
41 #include "hi_osal.h"
42 #include "hi_module.h"
43 #include "hi_drv_gpio.h"
44 
45 #define FST_ADDR (0xBB)
46 #define DEFAULT_MD_LEN (128)
47 
48 #define I2C_NUM (1)
49 #define I2C_BYTE_NUM (2)
50 #define I2C1_SDA_REG 0xF8A21000
51 #define I2C1_SCL_REG 0xF8A21004
52 
53 #define RST_GPIO_NUM (33) // GPIO4_1 = 4*8+1=33
54 #define INT_GPIO_NUM (34) // GPIO4_2 = 4*8+2=34
55 #define RST_GPIO_NUM_REG 0xF8A21470
56 #define INT_GPIO_NUM_REG 0xF8A21474
57 
58 /* *screen resolution */
59 #define GT_BIT0 0x01
60 #define GT_BIT1 0x02
61 #define GT_DATA_RECVIVED 0x80
62 #define GT_FINGGER_DATA_NUM (8)
63 #define GT_STAY_HIGH_TIME (100)
64 #define GT_STAY_LOW_TIME (20)
65 #define GT_BUFFER_STAT_ADDR (0x814E)
66 #define GT_FINGGER_DATA_BASE (0x814F)
67 #define GT_COORDINATE_X_LOWBYPE_BASE (0x8150)
68 #define GT_COORDINATE_X_HIGHBYPE_BASE (0x8151)
69 #define GT_COORDINATE_Y_LOWBYPE_BASE (0x8152)
70 #define GT_COORDINATE_Y_HIGHBYPE_BASE (0x8153)
71 
72 #define TP_MAX_TOUCH_POINTS (5)
73 #define TP_OUCH_POINTS_LIMIT (5)
74 /* *screen resolution */
75 #define TP_SCREEN_WIDTH_NUM (1024)
76 #define TP_SCREEN_HEIGHT_NUM (600)
77 #define TP_EVENT_PRESS_DOWN (0)
78 #define TP_EVENT_LIFT_UP (1)
79 #define TP_EVENT_CONTACT (2)
80 #define TP_SLOT_REPORT 0
81 #define TP_BIT_OFFSET1 1
82 #define TP_BIT_OFFSET2 2
83 #define TP_BIT_OFFSET3 3
84 #define TP_BIT_OFFSET4 4
85 #define TP_BIT_OFFSET5 5
86 #define TP_BIT_OFFSET6 6
87 #define TP_BIT_OFFSET7 7
88 #define TP_BIT_OFFSET8 8
89 /* start define of ft */
90 volatile unsigned long gpio_base;
91 static i2c_ext_func *g_i2c_func = HI_NULL;
92 static gpio_ext_func *g_pst_gpio_func = HI_NULL;
93 static struct work_struct g_work;
94 static struct input_dev *g_ts_dev = HI_NULL;
95 static struct workqueue_struct *g_tp_workqueue;
96 
97 extern hi_void hi_drv_gpio_set_irq_ctrl(hi_u32 gpio_no, hi_bool b_enable);
98 
99 static const struct i2c_device_id ft_id[] = {
100     { "ft", },
101     { }
102 };
103 
104 MODULE_DEVICE_TABLE(i2c, ft_id);
105 
tp_touch_down(struct input_dev * input_dev,hi_s32 id,hi_s32 x,hi_s32 y,hi_s32 w)106 static hi_void tp_touch_down(struct input_dev *input_dev, hi_s32 id, hi_s32 x, hi_s32 y, hi_s32 w)
107 {
108 #if TP_SLOT_REPORT
109     input_mt_slot(input_dev, id);
110     input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
111     input_report_abs(input_dev, ABS_MT_POSITION_X, x);
112     input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
113     input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, w);
114     input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, w);
115 #else
116     input_report_key(input_dev, BTN_TOUCH, 1);
117     input_report_abs(input_dev, ABS_MT_POSITION_X, x);
118     input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
119     input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, w);
120     input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, w);
121     input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
122     input_mt_sync(input_dev);
123 #endif
124 }
125 
tp_touch_up(struct input_dev * input_dev,hi_s32 id)126 static hi_void tp_touch_up(struct input_dev *input_dev, hi_s32 id)
127 {
128 #if TP_SLOT_REPORT
129     input_mt_slot(input_dev, id);
130     input_report_abs(input_dev, ABS_MT_TRACKING_ID, -1);
131 #else
132     input_report_key(input_dev, BTN_TOUCH, 0);
133 #endif
134 }
135 
tp_set_reg(hi_u32 addr,hi_u32 value)136 static hi_s32 tp_set_reg(hi_u32 addr, hi_u32 value)
137 {
138     hi_void *pmem = ioremap(addr, DEFAULT_MD_LEN);
139     if (pmem == HI_NULL) {
140         return -1;
141     }
142 
143     *(hi_u32 *)pmem = value;
144     iounmap(pmem);
145     return 0;
146 }
147 
tp_reset_buffer(hi_void)148 static hi_s32 tp_reset_buffer(hi_void)
149 {
150     hi_s32 i;
151     hi_u8 data[1] = {0};
152 
153     for (i = 0; i < TP_OUCH_POINTS_LIMIT; i++) {
154         g_i2c_func->pfn_i2c_write(1, FST_ADDR, GT_BUFFER_STAT_ADDR, I2C_BYTE_NUM, data, 1);
155     }
156     return 0;
157 }
158 
tp_report_by_slot(struct input_dev * input,hi_u16 * pretouch,hi_s32 fingernum)159 static void tp_report_by_slot(struct input_dev *input, hi_u16 *pretouch, hi_s32 fingernum)
160 {
161     hi_s32 i;
162     hi_s32 id = 0;
163     hi_s32 input_x = 0;
164     hi_s32 input_y = 0;
165     hi_s32 input_w = 0;
166     hi_s32 pos = 0;
167     hi_u16 touch_index = 0;
168     hi_u8 report_num = 0;
169     hi_u8 finggerdata[GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS] = {0};
170     hi_s32 ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_FINGGER_DATA_BASE, I2C_BYTE_NUM, finggerdata,
171         GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS);
172 
173     if (fingernum) {
174         id = finggerdata[pos] & 0x0F;
175         touch_index |= (0x01 << id);
176     }
177 
178     for (i = 0; i < TP_MAX_TOUCH_POINTS; i++) {
179         if ((touch_index & (0x01 << i))) {
180             input_x = finggerdata[pos + TP_BIT_OFFSET1] | (finggerdata[pos + TP_BIT_OFFSET2] << TP_BIT_OFFSET8);
181             input_y = finggerdata[pos + TP_BIT_OFFSET3] | (finggerdata[pos + TP_BIT_OFFSET4] << TP_BIT_OFFSET8);
182             input_w = finggerdata[pos + TP_BIT_OFFSET5] | (finggerdata[pos + TP_BIT_OFFSET6] << TP_BIT_OFFSET8);
183 
184             tp_touch_down(input, id, input_x, input_y, input_w);
185             *pretouch |= 0x01 << i;
186 
187             report_num++;
188             if (report_num < fingernum) {
189                 pos += TP_BIT_OFFSET8;
190                 id = finggerdata[pos] & 0x0F;
191                 touch_index |= (0x01 << id);
192             }
193         } else {
194             tp_touch_up(input, i);
195             *pretouch &= ~(0x01 << i);
196         }
197     }
198 }
199 
tp_report_by_point(struct input_dev * input,hi_u16 * pretouch,hi_s32 fingernum)200 static void tp_report_by_point(struct input_dev *input, hi_u16 *pretouch, hi_s32 fingernum)
201 {
202     hi_s32 i;
203     hi_s32 id = 0;
204     hi_s32 ret = 0;
205     hi_s32 input_x = 0;
206     hi_s32 input_y = 0;
207     hi_s32 input_w = 0;
208     if (fingernum > 0) {
209         hi_u8 finggerdata[GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS] = {0};
210         ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_FINGGER_DATA_BASE, I2C_BYTE_NUM, finggerdata,
211             GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS);
212 
213         for (i = 0; i < fingernum; i++) {
214             /* *Notice the  array bound !! */
215             input_x = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET1] & 0xFF) |
216                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET2] & 0xFF) << TP_BIT_OFFSET8);
217             input_y = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET3] & 0xFF) |
218                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET4] & 0xFF) << TP_BIT_OFFSET8);
219             input_w = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET5] & 0xFF) |
220                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET6] & 0xFF) << TP_BIT_OFFSET8);
221             id = finggerdata[i * GT_FINGGER_DATA_NUM] & 0x0F;
222             tp_touch_down(input, id, input_x, input_y, input_w);
223         }
224     } else if (*pretouch) {
225         tp_touch_up(input, 0);
226     }
227 
228     *pretouch = fingernum;
229 }
230 
tp_event_handler(struct input_dev * input)231 static hi_s32 tp_event_handler(struct input_dev *input)
232 {
233     hi_u8 data = 0;
234     hi_s32 fingernum = 0;
235     static hi_u16 pretouch = 0;
236 
237     hi_s32 ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_BUFFER_STAT_ADDR, I2C_BYTE_NUM, &data, 1);
238     if (ret != 0) {
239         printk("g_i2c_func->pfn_i2c_read failed \r\n");
240         return 0;
241     }
242 
243     if (data == 0) {
244         return 0;
245     }
246 
247     if ((data & GT_DATA_RECVIVED) == 0) {
248         goto exit_work_func;
249     }
250 
251     fingernum = data & (GT_BIT0 | GT_BIT1);
252 
253 #if TP_SLOT_REPORT
254     if (pretouch || fingernum) {
255         tp_report_by_slot(input, &pretouch, fingernum);
256     }
257 #else
258     tp_report_by_point(input, &pretouch, fingernum);
259 #endif
260 
261     input_sync(input);
262 
263 exit_work_func:
264     tp_reset_buffer();
265     return 0;
266 }
267 
tp_irq_handler(hi_u32 irq)268 hi_void tp_irq_handler(hi_u32 irq)
269 {
270     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 0);
271     queue_work(g_tp_workqueue, &g_work);
272 }
273 
tp_irq_register(hi_void)274 static hi_s32 tp_irq_register(hi_void)
275 {
276     g_pst_gpio_func->pfn_gpio_set_int_type(INT_GPIO_NUM, GPIO_INTTYPE_UPDOWN);
277     g_pst_gpio_func->pfn_gpio_register_server_func(INT_GPIO_NUM, tp_irq_handler);
278     g_pst_gpio_func->pfn_gpio_clear_bit_int(INT_GPIO_NUM);
279     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 1);
280     return 0;
281 }
282 
tp_devinput_init(hi_void)283 static hi_s32 tp_devinput_init(hi_void)
284 {
285     hi_s32 ret;
286     g_ts_dev = input_allocate_device();
287     if (g_ts_dev == HI_NULL) {
288         printk(" func:%s line:%d \r\n", __FUNCTION__, __LINE__);
289         return -1;
290     }
291     g_ts_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
292     set_bit(EV_SYN, g_ts_dev->evbit);
293     set_bit(EV_KEY, g_ts_dev->evbit);
294     set_bit(EV_ABS, g_ts_dev->evbit);
295     set_bit(INPUT_PROP_DIRECT, g_ts_dev->propbit);
296     input_set_abs_params(g_ts_dev, ABS_MT_POSITION_X, 0, TP_SCREEN_WIDTH_NUM, 0, 0);
297     input_set_abs_params(g_ts_dev, ABS_MT_POSITION_Y, 0, TP_SCREEN_HEIGHT_NUM, 0, 0);
298     input_set_abs_params(g_ts_dev, ABS_MT_TOUCH_MAJOR, 0, 0xff, 0, 0);
299     input_set_abs_params(g_ts_dev, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
300     input_set_abs_params(g_ts_dev, ABS_MT_TRACKING_ID, 0, 0xff, 0, 0);
301 
302 #if TP_SLOT_REPORT
303     input_mt_init_slots(g_ts_dev, 16, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); // 16 in case of "out of memory"
304 #else
305     g_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
306 #endif
307 
308     g_ts_dev->name = "tp";
309     g_ts_dev->id.bustype = BUS_I2C;
310 
311     ret = input_register_device(g_ts_dev);
312     if (ret != 0) {
313         dev_err(HI_NULL, "failed to register input device: %d\n", ret);
314         return ret;
315     }
316 
317     ret = tp_irq_register();
318     if (ret != 0) {
319         dev_err(HI_NULL, "failed to register input device: %d\n", ret);
320         return ret;
321     }
322 
323     return 0;
324 }
325 
tp_ts_work_func(struct work_struct * work)326 static hi_void tp_ts_work_func(struct work_struct *work)
327 {
328     struct input_dev *input = g_ts_dev;
329     hi_drv_gpio_set_irq_ctrl(INT_GPIO_NUM, 0);
330     tp_event_handler(input);
331 
332     g_pst_gpio_func->pfn_gpio_clear_bit_int(INT_GPIO_NUM);
333     hi_drv_gpio_set_irq_ctrl(INT_GPIO_NUM, 1);
334     return;
335 }
336 
337 #ifdef MODULE
tp_init(hi_void)338 static hi_s32 __init tp_init(hi_void)
339 #else
340 hi_s32 tp_init(hi_void)
341 #endif
342 {
343     hi_s32 ret = 0;
344     tp_set_reg(RST_GPIO_NUM_REG, 0x0); // GPIO4_1 reset 0
345     tp_set_reg(INT_GPIO_NUM_REG, 0x0); // GPIO4_2 hi_s32   0
346     tp_set_reg(I2C1_SDA_REG, 0x03);    // GPIO0_4 I2C    011:I2C1_SDA;
347     tp_set_reg(I2C1_SCL_REG, 0x03);    // GPIO0_5 I2C    011:I2C1_SCL;
348     msleep(1);
349 
350     ret = hi_drv_i2c_init();
351     if (ret != 0) {
352         dev_err(HI_NULL, "I2C init failed: %d\n", ret);
353         goto error_end;
354     }
355 
356     gpio_drv_get_gpio_ext_func(&g_pst_gpio_func);
357     if (g_pst_gpio_func == HI_NULL) {
358         printk("get gpio export function failed!\n");
359         goto error_end;
360     }
361 
362     i2c_drv_get_i2c_ext_func(&g_i2c_func);
363     if (g_i2c_func == HI_NULL) {
364         printk("HI_ID_I2C handle get failed \r\n");
365         return 0;
366     }
367 
368     /* *set INT and GPIO to be output */
369     g_pst_gpio_func->pfn_gpio_dir_set_bit(RST_GPIO_NUM, 0); // set GPIO1_0 Reset output
370     g_pst_gpio_func->pfn_gpio_dir_set_bit(INT_GPIO_NUM, 0); // set GPIO1_1 INT output
371     msleep(1);
372 
373     /* *Set Reset */
374     g_pst_gpio_func->pfn_gpio_write_bit(RST_GPIO_NUM, 0); // set Reset low level
375     g_pst_gpio_func->pfn_gpio_write_bit(INT_GPIO_NUM, 0); // set INT low level
376     msleep(GT_STAY_LOW_TIME);
377 
378     g_pst_gpio_func->pfn_gpio_write_bit(RST_GPIO_NUM, 1); // set Reset high level
379     msleep(GT_STAY_HIGH_TIME);
380 
381     g_pst_gpio_func->pfn_gpio_dir_set_bit(INT_GPIO_NUM, 1); // set GPIO1_1 INT input
382 
383     g_tp_workqueue = create_singlethread_workqueue("g_tp_workqueue");
384     if (!g_tp_workqueue) {
385         printk("Create workqueue failed.");
386         return -ENOMEM;
387     }
388     INIT_WORK(&g_work, tp_ts_work_func);
389     ret = tp_devinput_init();
390     if (ret != 0) {
391         dev_err(HI_NULL, " tp_devinput_init fail!\n");
392         goto error_end;
393     }
394 
395     return 0;
396 error_end:
397     return -1;
398 }
399 
400 #ifdef MODULE
tp_exit(hi_void)401 static hi_void __exit tp_exit(hi_void)
402 #else
403 hi_void tp_exit(hi_void)
404 #endif
405 {
406     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 0);
407     input_unregister_device(g_ts_dev);
408     input_free_device(g_ts_dev);
409     hi_drv_i2c_de_init();
410     if (g_tp_workqueue) {
411         destroy_workqueue(g_tp_workqueue);
412     }
413 }
414 
415 #if defined(MODULE) || defined(CFG_HI_USER_DRV)
416 module_init(tp_init);
417 module_exit(tp_exit);
418 #endif
419 
420 MODULE_LICENSE("GPL");
421 MODULE_AUTHOR("hisilicon");
422