在目錄下amp\a53_linux\drv\extdrv\touchpad\ft6236
下能夠看到ft6236.c的文件linux
static int __init ft_init(void) { int ret = 0; hi_gpio_groupbit_info stIntInfo; hi_gpio_groupbit_info stRstInfo; stIntInfo.group_num = INT_GPIO_CHIP; stIntInfo.bit_num = INT_GPIO_OFFSET; stIntInfo.value = 0; stRstInfo.group_num = RST_GPIO_CHIP; stRstInfo.bit_num = RST_GPIO_OFFSET; stRstInfo.value = 1; ret = i2cdev_init(); if (ret) { dev_err(NULL, " i2cdev_init fail!\n"); goto error_end; } hi_gpio_set_dir(&stIntInfo); hi_gpio_set_dir(&stRstInfo); ret = ft_reset(&stRstInfo); if (ret) { dev_err(NULL, " ft_reset fail!\n"); goto error_end; } ret = devinput_init(); if (ret) { dev_err(NULL, " devinput_init fail!\n"); goto error_end; } return 0; error_end: return -1; }
INT_GPIO_CHIP
和INT_GPIO_OFFSET
都是在宏定義
#elif (defined(BOARD_DEMB) && (defined(HI3556AV100) || defined(HI3519AV100)))
下定義的ide
#define RST_GPIO_CHIP (2) #define RST_GPIO_OFFSET (6) #define INT_GPIO_CHIP (2) #define INT_GPIO_OFFSET (5)
這些管腳能夠在這裏《Hi3556AV100 Demo 單板使用指南.pdf》中看到,分別得出觸摸屏的中斷和復位管腳函數
static int ft_reset(hi_gpio_groupbit_info* pstRstInfo) { pstRstInfo->value = 1; hi_gpio_write_bit(pstRstInfo); pstRstInfo->value = 0; hi_gpio_write_bit(pstRstInfo); msleep(5); pstRstInfo->value = 1; hi_gpio_write_bit(pstRstInfo); return 0; }
對觸摸屏進行復位;code
static int devinput_init(void) { int error = 0; /* 1. distribution a "input_dev" structure */ ft_ts_dev = input_allocate_device(); if (ft_ts_dev == NULL) { printk(" func:%s line:%d \r\n", __FUNCTION__, __LINE__); return -1; } ft_ts_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); set_bit(EV_SYN, ft_ts_dev->evbit); set_bit(EV_KEY, ft_ts_dev->evbit); set_bit(EV_ABS, ft_ts_dev->evbit); set_bit(INPUT_PROP_DIRECT, ft_ts_dev->propbit); input_set_abs_params(ft_ts_dev, ABS_MT_POSITION_X, 0 , FT_SCREEN_WIDTH_NUM, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_POSITION_Y, 0, FT_SCREEN_HEIGHT_NUM, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_TOUCH_MAJOR, 0, 0xff, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_PRESSURE, 0, 0xff, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_TRACKING_ID, 0, 0xff, 0, 0); error = input_mt_init_slots(ft_ts_dev, FT_MAX_TOUCH_POINTS, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); if (error) { return error; } ft_ts_dev->name = "ft"; ft_ts_dev->id.bustype = BUS_I2C; error = input_register_device(ft_ts_dev); if (error) { dev_err(NULL, "failed to register input device: %d\n", error); return error; } /**request_threaded_irq(unsigned int irq,irq_handler_t handler,irq_handler_t thread_fn,unsigned long irqflags,const char * devname,void * dev_id)*/ error = fts_irq_register(); if(error) { dev_err(NULL, "failed to register input device: %d\n", error); return error; } /**Clear INT*/ touch_set_reg(0x045f241C, 0x20); return 0; }
evbit:
事件類型(包括EV_RST,EV_REL,EV_MSC,EV_KEY,EV_ABS,EV_REP等)
propbit:
set_bit(INPUT_PROP_DIRECT,dev->propbit);//代表設備的座標直接和屏幕座標向對應orm
給設備的input_dev結構體初始化,這些input_dev若是想被當成多點屏處理的話,只須要給input_dev額外增長如下幾個參數:事件
input_set_abs_params(ft_ts_dev, ABS_MT_POSITION_X, 0 , FT_SCREEN_WIDTH_NUM, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_POSITION_Y, 0, FT_SCREEN_HEIGHT_NUM, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_TOUCH_MAJOR, 0, 0xff, 0, 0); //至關於單點屏的ABX_PRESSURE input_set_abs_params(ft_ts_dev, ABS_MT_PRESSURE, 0, 0xff, 0, 0); input_set_abs_params(ft_ts_dev, ABS_MT_TRACKING_ID, 0, 0xff, 0, 0); //肯定第幾手指來上報的數據
input_set_abs_params(idev, ABS_X, -64, 64, 4, 0);
對於X軸範圍是-64到+64,數據偏差是-4到+4,中心平滑位置是0input
報告最大支持的點數it
註冊input子系統io
fts_irq_register註冊中斷event
static irqreturn_t ftint_irq(int irq, void *data) { int i; bool act; struct input_dev* input = ft_ts_dev; ts_event event; int ret = touch_event_handler(&event); if(ret) printk( "\n buffer_read failed \n"); if(event.point_num != 0) { for(i = 0; i < event.touch_point; i++) { input_mt_slot(input, i); act = (event.au8_touch_event[i] == FT_EVENT_PRESS_DOWN || event.au8_touch_event[i] == FT_EVENT_CONTACT); input_mt_report_slot_state(input, MT_TOOL_FINGER, act); if (!act) continue; input_report_abs(input, ABS_MT_POSITION_X, event.au16_x[i]); input_report_abs(input, ABS_MT_POSITION_Y, event.au16_y[i]); } } input_mt_sync_frame(input); input_sync(input); return IRQ_HANDLED; }
ret = hi_i2c_read(0x0, buf, FT_MAX_BUFUSED_NUM);
在這裏,使用了hi_i2c_read,在文件i2cdev.c
中,注意i2c_board_info的通常是8位從地址;
通常來講,觸摸屏有固件的,而後每個固件都表明相似的協議,因爲咱們沒有相應的協議,因此按照下面的來看:
for (i = 0; i < FT_MAX_TOUCH_POINTS; i++) { event->touch_point++; /**Notice the array bound !!*/ /* 獲取x座標 */ event->au16_x[i] = (s16) (buf[FT_TOUCH_X_H_POS + 6 * i] & 0x0F) << 8 | (s16) buf[FT_TOUCH_X_L_POS + 6 * i]; /* 獲取y座標 */ event->au16_y[i] = (s16) (buf[FT_TOUCH_Y_H_POS + 6 * i] & 0x0F) << 8 | (s16) buf[FT_TOUCH_Y_L_POS + 6 * i]; /* 按下,鬆開,觸摸 */ event->au8_touch_event[i] = buf[FT_TOUCH_EVENT_POS + 6 * i] >> 6; event->au8_finger_id[i] = (buf[FT_TOUCH_FINGER_POS + 6 * i]) >> 4; /**pressure and area not used !!*/ #if 0 event->area[i] = (buf[FT_TOUCH_AREA_POS + 6 * i]) >> 4; event->pressure[i] = (s16) buf[FTS_TOUCH_PRE_POS + 6 * i]; if (0 == event->area[i]) event->area[i] = 0x09; if (0 == event->pressure[i]) event->pressure[i] = 0x3f; #endif if ((event->au8_touch_event[i]==0 || event->au8_touch_event[i]==2)&&(event->point_num==0)) { printk("abnormal touch data from fw"); return -1; } }
static irqreturn_t ftint_irq(int irq, void *data) { int i; bool act; struct input_dev* input = ft_ts_dev; ts_event event; int ret = touch_event_handler(&event); if(ret) printk( "\n buffer_read failed \n"); if(event.point_num != 0) { for(i = 0; i < event.touch_point; i++) { input_mt_slot(input, i); act = (event.au8_touch_event[i] == FT_EVENT_PRESS_DOWN || event.au8_touch_event[i] == FT_EVENT_CONTACT); input_mt_report_slot_state(input, MT_TOOL_FINGER, act); if (!act) continue; input_report_abs(input, ABS_MT_POSITION_X, event.au16_x[i]); input_report_abs(input, ABS_MT_POSITION_Y, event.au16_y[i]); } } input_mt_sync_frame(input); input_sync(input); return IRQ_HANDLED; }