• 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 }
tp_report_by_slot(struct input_dev * input,hi_u16 * pretouch,hi_s32 fingernum)158 static void tp_report_by_slot(struct input_dev *input, hi_u16 *pretouch, hi_s32 fingernum)
159 {
160     hi_s32 i;
161     hi_s32 id = 0;
162     hi_s32 input_x = 0;
163     hi_s32 input_y = 0;
164     hi_s32 input_w = 0;
165     hi_s32 pos = 0;
166     hi_u16 touch_index = 0;
167     hi_u8 report_num = 0;
168     hi_u8 finggerdata[GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS] = {0};
169     hi_s32 ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_FINGGER_DATA_BASE, I2C_BYTE_NUM, finggerdata,
170         GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS);
171 
172     if (fingernum) {
173         id = finggerdata[pos] & 0x0F;
174         touch_index |= (0x01 << id);
175     }
176 
177     for (i = 0; i < TP_MAX_TOUCH_POINTS; i++) {
178         if ((touch_index & (0x01 << i))) {
179             input_x = finggerdata[pos + TP_BIT_OFFSET1] | (finggerdata[pos + TP_BIT_OFFSET2] << TP_BIT_OFFSET8);
180             input_y = finggerdata[pos + TP_BIT_OFFSET3] | (finggerdata[pos + TP_BIT_OFFSET4] << TP_BIT_OFFSET8);
181             input_w = finggerdata[pos + TP_BIT_OFFSET5] | (finggerdata[pos + TP_BIT_OFFSET6] << TP_BIT_OFFSET8);
182 
183             tp_touch_down(input, id, input_x, input_y, input_w);
184             *pretouch |= 0x01 << i;
185 
186             report_num++;
187             if (report_num < fingernum) {
188                 pos += TP_BIT_OFFSET8;
189                 id = finggerdata[pos] & 0x0F;
190                 touch_index |= (0x01 << id);
191             }
192         } else {
193             tp_touch_up(input, i);
194             *pretouch &= ~(0x01 << i);
195         }
196     }
197 }
tp_report_by_point(struct input_dev * input,hi_u16 * pretouch,hi_s32 fingernum)198 static void tp_report_by_point(struct input_dev *input, hi_u16 *pretouch, hi_s32 fingernum)
199 {
200     hi_s32 i;
201     hi_s32 id = 0;
202     hi_s32 ret = 0;
203     hi_s32 input_x = 0;
204     hi_s32 input_y = 0;
205     hi_s32 input_w = 0;
206     if (fingernum > 0) {
207         hi_u8 finggerdata[GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS] = {0};
208         ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_FINGGER_DATA_BASE, I2C_BYTE_NUM, finggerdata,
209             GT_FINGGER_DATA_NUM * TP_MAX_TOUCH_POINTS);
210 
211         for (i = 0; i < fingernum; i++) {
212             /* *Notice the  array bound !! */
213             input_x = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET1] & 0xFF) |
214                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET2] & 0xFF) << TP_BIT_OFFSET8);
215             input_y = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET3] & 0xFF) |
216                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET4] & 0xFF) << TP_BIT_OFFSET8);
217             input_w = (finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET5] & 0xFF) |
218                 ((finggerdata[i * GT_FINGGER_DATA_NUM + TP_BIT_OFFSET6] & 0xFF) << TP_BIT_OFFSET8);
219             id = finggerdata[i * GT_FINGGER_DATA_NUM] & 0x0F;
220             tp_touch_down(input, id, input_x, input_y, input_w);
221         }
222     } else if (*pretouch) {
223         tp_touch_up(input, 0);
224     }
225 
226     *pretouch = fingernum;
227 }
tp_event_handler(struct input_dev * input)228 static hi_s32 tp_event_handler(struct input_dev *input)
229 {
230     hi_u8 data = 0;
231     hi_s32 fingernum = 0;
232     static hi_u16 pretouch = 0;
233 
234     hi_s32 ret = g_i2c_func->pfn_i2c_read(I2C_NUM, FST_ADDR, GT_BUFFER_STAT_ADDR, I2C_BYTE_NUM, &data, 1);
235     if (ret != 0) {
236         printk("g_i2c_func->pfn_i2c_read failed \r\n");
237         return 0;
238     }
239 
240     if (data == 0) {
241         return 0;
242     }
243 
244     if ((data & GT_DATA_RECVIVED) == 0) {
245         goto exit_work_func;
246     }
247 
248     fingernum = data & (GT_BIT0 | GT_BIT1);
249 
250 #if TP_SLOT_REPORT
251     if (pretouch || fingernum) {
252         tp_report_by_slot(input, &pretouch, fingernum);
253     }
254 #else
255     tp_report_by_point(input, &pretouch, fingernum);
256 #endif
257 
258     input_sync(input);
259 
260 exit_work_func:
261     tp_reset_buffer();
262     return 0;
263 }
264 
tp_irq_handler(hi_u32 irq)265 hi_void tp_irq_handler(hi_u32 irq)
266 {
267     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 0);
268     queue_work(g_tp_workqueue, &g_work);
269 }
270 
tp_irq_register(hi_void)271 static hi_s32 tp_irq_register(hi_void)
272 {
273     g_pst_gpio_func->pfn_gpio_set_int_type(INT_GPIO_NUM, GPIO_INTTYPE_UPDOWN);
274     g_pst_gpio_func->pfn_gpio_register_server_func(INT_GPIO_NUM, tp_irq_handler);
275     g_pst_gpio_func->pfn_gpio_clear_bit_int(INT_GPIO_NUM);
276     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 1);
277     return 0;
278 }
279 
tp_devinput_init(hi_void)280 static hi_s32 tp_devinput_init(hi_void)
281 {
282     hi_s32 ret;
283     g_ts_dev = input_allocate_device();
284     if (g_ts_dev == HI_NULL) {
285         printk(" func:%s line:%d \r\n", __FUNCTION__, __LINE__);
286         return -1;
287     }
288     g_ts_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
289     set_bit(EV_SYN, g_ts_dev->evbit);
290     set_bit(EV_KEY, g_ts_dev->evbit);
291     set_bit(EV_ABS, g_ts_dev->evbit);
292     set_bit(INPUT_PROP_DIRECT, g_ts_dev->propbit);
293     input_set_abs_params(g_ts_dev, ABS_MT_POSITION_X, 0, TP_SCREEN_WIDTH_NUM, 0, 0);
294     input_set_abs_params(g_ts_dev, ABS_MT_POSITION_Y, 0, TP_SCREEN_HEIGHT_NUM, 0, 0);
295     input_set_abs_params(g_ts_dev, ABS_MT_TOUCH_MAJOR, 0, 0xff, 0, 0);
296     input_set_abs_params(g_ts_dev, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
297     input_set_abs_params(g_ts_dev, ABS_MT_TRACKING_ID, 0, 0xff, 0, 0);
298 
299 #if TP_SLOT_REPORT
300     input_mt_init_slots(g_ts_dev, 16, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); // 16 in case of "out of memory"
301 #else
302     g_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
303 #endif
304 
305     g_ts_dev->name = "tp";
306     g_ts_dev->id.bustype = BUS_I2C;
307 
308     ret = input_register_device(g_ts_dev);
309     if (ret != 0) {
310         dev_err(HI_NULL, "failed to register input device: %d\n", ret);
311         return ret;
312     }
313 
314     ret = tp_irq_register();
315     if (ret != 0) {
316         dev_err(HI_NULL, "failed to register input device: %d\n", ret);
317         return ret;
318     }
319 
320     return 0;
321 }
322 
tp_ts_work_func(struct work_struct * work)323 static hi_void tp_ts_work_func(struct work_struct *work)
324 {
325     struct input_dev *input = g_ts_dev;
326     hi_drv_gpio_set_irq_ctrl(INT_GPIO_NUM, 0);
327     tp_event_handler(input);
328 
329     g_pst_gpio_func->pfn_gpio_clear_bit_int(INT_GPIO_NUM);
330     hi_drv_gpio_set_irq_ctrl(INT_GPIO_NUM, 1);
331     return;
332 }
333 
334 #ifdef MODULE
tp_init(hi_void)335 static hi_s32 __init tp_init(hi_void)
336 #else
337 hi_s32 tp_init(hi_void)
338 #endif
339 {
340     hi_s32 ret = 0;
341     tp_set_reg(RST_GPIO_NUM_REG, 0x0); // GPIO4_1 reset 0
342     tp_set_reg(INT_GPIO_NUM_REG, 0x0); // GPIO4_2 hi_s32   0
343     tp_set_reg(I2C1_SDA_REG, 0x03);    // GPIO0_4 I2C    011:I2C1_SDA;
344     tp_set_reg(I2C1_SCL_REG, 0x03);    // GPIO0_5 I2C    011:I2C1_SCL;
345     msleep(1);
346 
347     ret = hi_drv_i2c_init();
348     if (ret != 0) {
349         dev_err(HI_NULL, "I2C init failed: %d\n", ret);
350         goto error_end;
351     }
352 
353     gpio_drv_get_gpio_ext_func(&g_pst_gpio_func);
354     if (g_pst_gpio_func == HI_NULL) {
355         printk("get gpio export function failed!\n");
356         goto error_end;
357     }
358 
359     i2c_drv_get_i2c_ext_func(&g_i2c_func);
360     if (g_i2c_func == HI_NULL) {
361         printk("HI_ID_I2C handle get failed \r\n");
362         return 0;
363     }
364 
365     /* *set INT and GPIO to be output */
366     g_pst_gpio_func->pfn_gpio_dir_set_bit(RST_GPIO_NUM, 0); // set GPIO1_0 Reset output
367     g_pst_gpio_func->pfn_gpio_dir_set_bit(INT_GPIO_NUM, 0); // set GPIO1_1 INT output
368     msleep(1);
369 
370     /* *Set Reset */
371     g_pst_gpio_func->pfn_gpio_write_bit(RST_GPIO_NUM, 0); // set Reset low level
372     g_pst_gpio_func->pfn_gpio_write_bit(INT_GPIO_NUM, 0); // set INT low level
373     msleep(GT_STAY_LOW_TIME);
374 
375     g_pst_gpio_func->pfn_gpio_write_bit(RST_GPIO_NUM, 1); // set Reset high level
376     msleep(GT_STAY_HIGH_TIME);
377 
378     g_pst_gpio_func->pfn_gpio_dir_set_bit(INT_GPIO_NUM, 1); // set GPIO1_1 INT input
379 
380     g_tp_workqueue = create_singlethread_workqueue("g_tp_workqueue");
381     if (!g_tp_workqueue) {
382         printk("Create workqueue failed.");
383         return -ENOMEM;
384     }
385     INIT_WORK(&g_work, tp_ts_work_func);
386     ret = tp_devinput_init();
387     if (ret != 0) {
388         dev_err(HI_NULL, " tp_devinput_init fail!\n");
389         goto error_end;
390     }
391 
392     return 0;
393 error_end:
394     return -1;
395 }
396 
397 #ifdef MODULE
tp_exit(hi_void)398 static hi_void __exit tp_exit(hi_void)
399 #else
400 hi_void tp_exit(hi_void)
401 #endif
402 {
403     g_pst_gpio_func->pfn_gpio_set_int_enable(INT_GPIO_NUM, 0);
404     input_unregister_device(g_ts_dev);
405     input_free_device(g_ts_dev);
406     hi_drv_i2c_de_init();
407     if (g_tp_workqueue) {
408         destroy_workqueue(g_tp_workqueue);
409     }
410 }
411 
412 #if defined(MODULE) || defined(CFG_HI_USER_DRV)
413 module_init(tp_init);
414 module_exit(tp_exit);
415 #endif
416 
417 MODULE_LICENSE("GPL");
418 MODULE_AUTHOR("hisilicon");
419