22_多点电容触摸屏驱动

本文介绍了Linux系统中电容多点触摸屏(MT)驱动的工作原理,包括TypeA和TypeB两种类型的触摸点信息上报时序,以及涉及的input子系统API如input_mt_init_slots、input_mt_slot等。同时概述了触摸驱动的基本框架,如IIC驱动、中断处理和数据处理函数。
摘要由CSDN通过智能技术生成

一、linux电容触摸屏驱动简介

1、多点触摸屏(MT)简介

​ 电容多点触摸屏驱动由以下几种类型的驱动组成:

  • IIC 设备驱动,电容触摸 IC 基本都是 IIC 接口。

  • 通过中断引脚 (INT) 向内核上报触摸信息,坐标的上报在中断服务函数中完成。

  • 触摸屏的坐标信息、屏幕按下和抬起信息都属于 input 子系统,向内核上报触摸屏坐标信息要使用 input 子系统。

    内核中有一份文档详细的讲解了多点电容触摸屏协议,文档路径为:Documentation/input/multi-touch-protocol.txt

​ 如果使用 2.x 版本的内核可能找不到 MT 协议,MT协议被分为两种类型,TypeA 和 TypeB,两种类型区别如下:

TypeA:适用于触摸点不能被区分或者追踪,此类型的设备上报原始数据。

TypeB:适用于有硬件追踪并能区分触摸点的触摸设备,此类型设备通过 slot 更新某一个触摸点的信息。

1)ABS_MT事件

​ 触摸点的信息通过一系列的 ABS_MT 事件上报给 linux 内核,只有 ABS_MT 事件是用于多点触摸的, ABS_MT 事件定义在文件 linux/input.h 中:

#define ABS_MT_SLOT		0x2f	/* MT slot being modified */
#define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
#define ABS_MT_TOUCH_MINOR	0x31	/* Minor axis (omit if circular) */
#define ABS_MT_WIDTH_MAJOR	0x32	/* Major axis of approaching ellipse */
#define ABS_MT_WIDTH_MINOR	0x33	/* Minor axis (omit if circular) */
#define ABS_MT_ORIENTATION	0x34	/* Ellipse orientation */
#define ABS_MT_POSITION_X	0x35	/* Center X touch position */
#define ABS_MT_POSITION_Y	0x36	/* Center Y touch position */
#define ABS_MT_TOOL_TYPE	0x37	/* Type of touching device */
#define ABS_MT_BLOB_ID		0x38	/* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID	0x39	/* Unique ID of initiated contact */
#define ABS_MT_PRESSURE		0x3a	/* Pressure on contact area */
#define ABS_MT_DISTANCE		0x3b	/* Contact hover distance */
#define ABS_MT_TOOL_X		0x3c	/* Center X tool position */
#define ABS_MT_TOOL_Y		0x3d	/* Center Y tool position */

​ 常用到的有:

ABS_MT_SLOT:用于上报触摸点 ID;

ABS_MT_POSITION_X:用于上报触摸点的 X 坐标;

ABS_MT_POSITION_Y:用于上报触摸点的 Y 坐标;

ABS_MT_TRACKING_ID:对于 TypeB 类型,使用 ABS_MT_TRACKING_ID 来区分触摸点。

2)input_mt_sync函数(用于TypeA)

​ 对于 Type A 类型的设备,通过 input_mt_sync 函数来隔离不同的触摸点数据信息,函数会触发SYN_MT_REPORT 事件,此事件会通知接收者获取当前触摸数据,并且准备接收下一个触摸点数据,函数原型如下:

void input_mt_sync(struct input_dev *dev)

dev:具体的 input_dev 设备。

3)input_mt_slot函数(用于TypeB)

​ 对于 Type A 类型的设备,通过 input_mt_slot 函数来区分不同的触摸点数据信息,input_mt_slot 函数会触发 ABS_MT_SLOT 事件,此事件会告诉接收者当前正在更新的是哪个触摸点 (slot) 的数据。函数原型如下:

void input_mt_slot(struct input_dev *dev, int slot)

dev:具体的 input_dev 设备。

slot:指定当前上报的是哪个触摸点信息。

​ 不管是哪个类型的设备,最终都要调用 input_sync 函数来标识多点触摸信息传输完成。

​ 对于 TypeA 设备,内核驱动需要一次性将触摸屏上所有的触摸点信息全部上报,每个触摸点的信息在本次上报事件流中的顺序不重要,因为事件的过滤和手指(触摸点)跟踪是在内核空间处理的。

​ 对于 TypeB 设备,使用 slot 协议区分具体的触摸点, slot 需要用到 ABS_MT_TRACKING_ID 消息,这个 ID需要硬件提供,或者通过原始数据计算出来。
​ TypeB 设备驱动需要给每个识别出来的触摸点分配一个 slot,后面使用这个 slot 来上报触摸点信息。可以通过 slot 的 ABS_MT_TRACKING_ID 来新增、替换或删除触摸点。一个非负的 ID 表示一个有效的触摸点,-1 这个 ID 表示未使用 slot。一个以前不存在的 ID 表示这是一个新加的触摸点,一个 ID 如果再也不存在了就表示删除了。

​ 如果硬件设备追踪到了比它正在上报的还要多的触摸点,那么驱动程序应该发送 BTN_TOOL_TAP 消息,并且调用input_mt_report_pointer_emulation 函数,将此函数的第二个参数 use_count 设置为 false。

4)TypeA触摸点信息上报时序

​ 对于 TypeA 设备,发送触摸点信息的时序如下:

ABS_MT_POSITION_X x[0]		//上报第一个触摸点的X坐标数据,通过 input_report_abs 函数实现,下面同理
ABS_MT_POSITION_Y y[0]		//上报第一个触摸点的Y坐标数据
SYN_MT_REPORT 				//上报SYN_MT_REPORT事件,通过调用input_mt_sync函数来实现
ABS_MT_POSITION_X x[1] 		//上报第二个触摸点的X坐标数据
ABS_MT_POSITION_Y y[1] 		//上报第二个触摸点的Y坐标数据
SYN_MT_REPORT 				//上报SYN_MT_REPORT事件
SYN_REPORT					//上报SYN_REPORT事件,通过调用input_sync函数实现

​ TypeA 设备上报触摸点示例代码:

static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
{
   
    ret = st1232_ts_read_data(ts); 		//获取所有触摸点信息
    if (ret < 0) 
        goto end;
    
    /* multi touch protocol */ 
    for (i = 0; i < MAX_FINGERS; i++) {
    	//轮流上报触摸点信息
        if (!finger[i].is_valid) 
            continue;
        
        input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t); 
        input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x); 
        input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y); 
        input_mt_sync(input_dev); 		//隔离触摸点
        count++;
    }
    
    /* SYN_REPORT */ 
    input_sync(input_dev);
    
    end: 
    return IRQ_HANDLED; 
}

5)TypeB触摸点信息上报时序

​ 对于 TypeB 设备,发送触摸点信息的时序如下:

ABS_MT_SLOT 0
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值