资讯详情

嵌入式linux 电容触摸屏驱动框架

事实上,电容触摸屏的驱动程序如下 linux 驱动框架的组合:

1,IIC 由于电容触摸,设备驱动 IC 基本都是 IIC 接口,所以大框架是 IIC 设备驱动。

2,中断引脚(INT)向 linux 内核报告触摸信息,需要使用 linux 中断驱动框架。在中断服务函数中完成坐标报告。

3,触摸屏的坐标信息、屏幕按下和提升信息都属于 linux 的 input 因此,子系统向 linux 内核上报触摸屏坐标信息必须使用 input 子系统。只是,我们必须遵循 linux 报告坐标信息。

我们应该已经明白了IIC还有驱动,中断驱动input子系统,唯一不清楚的可能是input如何在子系统中报告多点电容触摸信息。这与多点触摸协议有关。

老版本的linux内核不支持多点电容触摸(Multi-Touch),简称MT,后面的版本是新加的。MT协议分为两种类型,TypeA和TypeB,两种类型的区别如下:

TypeA:适用于无法区分或跟踪触摸点的原始数据(实际应用中很少)。

TypeB:适用于具有硬件跟踪和区分触摸点的触摸设备。这类设备是通过slot更新触摸点信息,FT5426属于这种类型,一般多点电容触摸IC都有这种能力。

通过一系列的触摸点信息通过触摸点信息ABS_MT事件上报给linux内核,只有ABS_MT事件用于多点触摸,ADS_MT事件如下:

在上面众多AMS_MT在事件中,我们最常用的是AMS_MT_SLOT,AMS_MT_POSITION_X,AMS_MT_POSITION_Y和AMS_MT_TRACKING_ID。其中ABS_MT_POSITION_X 和 ABS_MT_POSITION_Y 用 来 上报 触 摸点 的 (X,Y) 坐 标 信息 , ABS_MT_SLOT 用 来 上 报 触 摸 点 ID ,对于 Type B 类 型 的 设 备 ,需 要 用 到ABS_MT_TRACKING_ID 区分触摸点的事件。

对于TypeA通过类型设备input_mt_sync该函数的原型如下:

这个函数只有一个参数,类型是input_dev,指定具体的input_dev设备,input_mt_sync函数会触发SYN_MT_REPORT该事件将通知接受者获取当前的触摸数据,并准备接收下一个触摸点信息。

对于TypeB类型的设备,报告触摸点信息时需要通过input_mt_slot哪个触摸点区分函数?,函数原型如下:

第二个参数slot指定当前报告的触摸点信息,input_mt_slot函数会触发ABS_MT_SLOT事件将告诉接收者目前更新了哪个触点(slot)的数据。

无论哪种设备,最终都需要调用input_sync识别多点触摸信息传输,告诉接收者处理之前积累的所有信息,并准备下一次接收。Type B 和 Type A 最大的区别是 Type B 触摸点可以区分, 因此可以减少发送到用户空间的数据。Type B 使用 slot 协议区分具体的触摸点,slot需要用到AMS_MT_TRACKING_ID消息,这个ID硬件提供或通过原始数据计算。

Type B 设备驱动需要分配每个被识别的触摸点 slot,以后用这个slot报告触摸点信息。可以通过slot的ABS_MT_TRACKING_ID添加、替换或删除非负值的触摸点ID表示有效的触摸点-1ID表示未使用slot。以前不存在的ID这意味着这是一个新的触摸点,一个ID若不再存在,则表示删除。

一些设备识别或跟踪的触摸点信息比他报告的要多(与相应的设备有关),这些设备驱动器应分配硬件报告的每个触摸点 Type B 的 slot。一旦检测到某个 slot 相关触点 ID 变化,驱动 这个应该改变 slot 的 ABS_MT_TRACKING_ID,使这个 slot 失效。如果硬件设备跟踪的触摸点比他正在报告的更多,则应发送驱动程序 BTN_TOOL_*TAP 消息,并且调用input_mt_report_pointer_emulation函数,该函数的第二个参数 use_count 设置为 false。

对于TypeA以两个触摸点为例:

第 1 行,ABS_MT_POSITION_X 事件报告了第一个触摸点的第一个触摸点 X 坐标数据,通过 input_report_abs 函数实现,下面也是如此。

第 2 ABS_MT_POSITION_Y 事件上报第一个触摸点的 Y 坐标数据。
        第 3 行,上报 SYN_MT_REPORT 事件,通过调用 input_mt_sync 函数来实现。用来隔离不同的触摸点数据信息。
        第 4 行,通过 ABS_MT_POSITION_X 事件上报第二个触摸点的 X 坐标数据。
        第 5 行,通过 ABS_MT_POSITION_Y 事件上报第二个触摸点的 Y 坐标数据。 
        第 6 行,上报 SYN_MT_REPORT 事件,通过调用 input_mt_sync 函数来实现。 

        第 7 行,上报 SYN_REPORT 事件,通过调用 input_sync 函数实现。这个是上报完每一轮触摸点信息就调用一次,比如上报3个触摸点信息,将3个触摸点信息上报完在调用这个就好。也就是发送一个SYN_REPORT事件。

    

        对于Type B 类型的设备,发送触摸点信息的时序如下所示,这里以 2 个触摸点为例:

         第1行,上报ABS_MT_SLOT事件,也就是触摸点对应的SLOT,每次上报一个触摸点坐标之前要先使用input_mt_slot函数上报当前触摸点SLOT,触摸点SLOT其实就是触摸点ID,由硬件提供。

        第2行,根据TypeB的要求,每个SLOT必须关联一个AMS_MT_TRACKING_ID来完成对触摸点的增加,替换,或删除。具体用到的函数就是input_mt_solt_state,如果添加一个新的触摸点,那么此函数的第三个参数active要设置为true,,linux 内核会自动分配一个 ABS_MT_TRACKING_ID 值,不需要用户去指定具体的 ABS_MT_TRACKING_ID 值。

        第 3 行,上报触摸点 0 的 X 轴坐标,使用函数 input_report_abs 来完成。

        第 4 行,上报触摸点 0 的 Y 轴坐标,使用函数 input_report_abs 来完成。
        
        第 5~8 行,和第 1~4 行类似,只是换成了上报触摸点 1   的 (X,Y) 坐标信息  
        第 9 行,当所有的触摸点坐标都上传完毕以后就得发送 SYN_REPORT 事件,使用 input_sync 函数来完成。  

        当一个触摸点移除以后,同样需要通过 SLOT 关联的 ABS_MT_TRACKING_ID 来处理,需要通过ABS_MT_TRACKING_ID事件发送一个-1给内核,方法很简单,同样使用input_mt_report_slot_state函数来完成,只需要将第三个参数active设置为false即可,不需要手动设置为-1,时序如下所示:

//在中断处理函数里面,我们需要将读取到的数据上报,但是需要按照上报时序来完成
//主要看硬件可以是几点触发器,触发就循环多少次
//下面是一个简略的中断处理函数,可以大致看出上报流程
static irqreturn_t ft5x06_handler(int irq, void *dev_id)
{
	/* 读取FT5X06触摸点坐标从0X02寄存器开始,连续读取29个寄存器 */
	ret = ft5x06_read_regs(multidata, FT5X06_TD_STATUS_REG, rdbuf, FT5X06_READLEN);

    /* 上报每一个触摸点坐标 */
	for (i = 0; i < 5; i++) {
		u8 *buf = &rdbuf[i * tplen + offset];

		/* 以第一个触摸点为例,寄存器TOUCH1_XH(地址0X03),各位描述如下:
		 * bit7:6  Event flag  0:按下 1:释放 2:接触 3:没有事件
		 * bit5:4  保留
		 * bit3:0  X轴触摸点的11~8位。
		 */
		type = buf[0] >> 6;     /* 获取触摸类型 */
		if (type == TOUCH_EVENT_RESERVED)
			continue;                    //当硬件得到的信息时没有按下的话就终结本次循环,无需上报
 
		/* 我们所使用的触摸屏和FT5X06是反过来的 */
		x = ((buf[2] << 8) | buf[3]) & 0x0fff;
		y = ((buf[0] << 8) | buf[1]) & 0x0fff;
		
		/* 以第一个触摸点为例,寄存器TOUCH1_YH(地址0X05),各位描述如下:
		 * bit7:4  Touch ID  触摸ID,表示是哪个触摸点
		 * bit3:0  Y轴触摸点的11~8位。
		 */
		id = (buf[2] >> 4) & 0x0f;
		down = type != TOUCH_EVENT_UP;

		input_mt_slot(multidata->input, id);
		input_mt_report_slot_state(multidata->input, MT_TOOL_FINGER, down);

		if (!down)
			continue;

		input_report_abs(multidata->input, ABS_MT_POSITION_X, x);
		input_report_abs(multidata->input, ABS_MT_POSITION_Y, y);
	}
    
    //这个函数就是硬件的追踪的点比上报的多的话就为false,当不是的话就位ture
	input_mt_report_pointer_emulation(multidata->input, true);
    //在5点信息全部上报完的时候,再执行下面的函数,表示本次信息全部上报完成
	input_sync(multidata->input);
}
        1,input_mt_init_slots函数
        
        input_mt_init_slots函数 用于初始化MT的输入slots,编写MT驱动的是个必须先调用此函数初始化slots,通常也就是在probe函数里面就已经执行了。函数原型如下:

        MT设备对应的input_dev,因为MT设备隶属于input_dev

        设备要使用slot数量,也就是触摸点的数量

       其他一些flags信息,可设置如下所示:

         可以采样‘|’运算来同时设置多个flags标识

        0,成功;负值,失败。

         2,input_mt_slot函数

        此函数用于TypeB类型,此函数用于产生ABS_MT_SLOT事件,告诉内核当前上报的是哪个触摸点的坐标数据。

         MT设备对应的input_dev

        当前发送的是哪个slot的坐标信息,也就是那个触摸点,那就是硬件发送过来的信息ID

        3,input_mt_report_slot_state函数

        此函数用于TypeB类型,用于产生ABS_MT_TRACKING_ID 和 ABS_MT_TOOL_TYPE事件给slot关联一个ABS_MT_TRACKING_ID ,ABS_MT_TOOL_TYPE 事 件 指 定 触 摸 类 型 ( 是 笔 还 是 手 指 等 )。函数原型如下:

         MT设备对应的input_dev。

        触摸类型,可以选择MT_TOOL_FINGER(手指)、MT_TOOL_PEN(笔)或MT_TOOL_PALM(手掌),对于多点电容触摸屏来说一般都是手指。

        ture,连续触摸,input子系统内核汇自动分配一个ABS_MT_TRACKING_ID给slot。false,触摸点抬起。表示某个触摸点无效了,input子系统就会给内核分配一个-1给slot,表示触摸点移除。

        4,input_report_abs函数

        TypeA 和 Type B 类型都使用此函数上报触摸点坐标信息,通过ABS_MT_POSITION_X 和ABS_MT_POSITION_Y 事 件 实 现 X 和 Y 轴 坐 标 信 息 上 报 。函数定义如下:

        mt设备对应的input_dev

        要上报的是什么数据,要设置为ABS_MT_POSITION_X或 ABS_MT_POSITION_Y,也就是X轴或者Y轴坐标点数据。

        具体的X轴和Y轴坐标点数值

     5,input_mt_report_pointer_emulation函数

        如果追踪到的触摸点数量多于当前上报的数量,驱动程序使用 BTN_TOOL_TAP 事件来通知用户空间当前追踪到的触摸点总数量,然后调用 input_mt_report_pointer_emulation 函数将 use_count 参数设置为 false。否则的话将 use_count 参数设置为 true,表示当前的触摸点数量(此函数会获取到具体的触摸点数量,不需要用户给出)。 

        MT设备对应的input_dev

        true,有效的触摸点数量;flase,追踪到的触摸点数量多于当前上报的数量

    

        多点电容需要用到那些框架呢?我们需要注意以下几点:

  1. 多点电容触摸芯片的接口,一般都为I2C接口,因此驱动主框架肯定是I2C   
  2. linux里面一般都是通过中断来上报触摸点坐标信息的,因此需要中断框架
  3. 多点电容触摸属于input子系统,因此还要用到input子系统框架
  4. 在中断处理程序中按照linux的MT协议上报坐标信息

标签: 6410电容屏驱动

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司