Linux内核驱动--多点触摸接口【附代码】

发布时间:2011-05-30 阅读量:1375 来源: 我爱方案网 作者:

中心议题:
         *  Linux内核驱动--多点触摸接口


为了使用功能强大的多点触控设备,就需要一种方案去上报用户层所需的详细的手指触摸数据。这个文档所描述的多点触控协议可以让内核驱动程序向用户层上报任意多指的数据信息。

单点触摸信息是以ABS承载并按一定顺序发送,如BTN_TOUCH、ABS_X、ABS_Y、SYNC。而多点触摸信息则是以ABS_MT承载并按一定顺序发送,如ABS_MT_POSITION_X、ABS_MT_POSITION_Y,然后通过调用input_mt_sync()产生一个 SYN_MT_REPORT event来标记一个点的结束,告诉接收方接收当前手指的信息并准备接收其它手指的触控信息。最后调用 input_sync()函数上报触摸信息开始动作并告诉接收方开始接收下一系列多点触摸信息。

协议定义了一系列ABS_MT事件,这些事件被分为几大类,充许只应用其中的一部份,多点触摸最小的事件集中应包括 ABS_MT_TOUCH_MAJOR、ABS_MT_POSITION_X和 ABS_MT_POSITION_Y,以此来实现多点触摸。如果设备支持ABS_MT_WIDTH_MAJOR这个事件,那么此事件可以提供手指触摸接触面积大小。触摸方向等信息可以由ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION提供。ABS_MT_TOOL_TYPE提供触摸设备的类别,如手或是笔或是其它。最后有些设备可能会支持 ABS_MT_TRACKING_ID,用来支持硬件跟踪多点信息,即该点属于哪一条线等。

下面是两点触摸支持的最小事件集序列:

ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上报第一个点
ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上报第二个点
SYN_REPORT         //开始动作

Event 原语

“接触”一词用来描述一个物体直接碰到另一个物体的表面。

ABS_MT_TOUCH_MAJOR描述了主接触面的长轴,它和X,Y同一个单位,如果一个面的分辨率为X*Y,则ABS_MT_TOUCH_MAJOR的最大值为sqrt(X^2+Y^2)

ABS_MT_TOUCH_MINOR 描述了接触面的短轴,如果接触面是圆形,它可以不用。

ABS_MT_WIDTH_MAJOR描述了接触工具的长轴

ABS_MT_WIDTH_MINOR 描述了接触工具的短轴

ABS_MT_TOUCH_MAJOR := max(X, Y)
ABS_MT_TOUCH_MINOR := min(X, Y)
ABS_MT_ORIENTATION := bool(X > Y)

以上四个参数可以用来生成额外的触摸信息,如ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR的比率可以用来描述压力。

ABS_MT_ORIENTATION

ABS_MT_POSITION_X 接触面的中心点X坐标

ABS_MT_POSITION_Y接触面的中心点Y坐标

ABS_MT_TOOL_TYPE描述接触工具类型,很多内核驱动无法区分此参数如手指及笔,如果是这样,该参数可以不用,协议目前支持MT_TOOL_FINGER和MT_TOOL_PEN两种类型。

ABS_MT_BLOB_ID形状集ID,集合几个点以描述一个形状,很多驱动没有形状属性,此参数可以不用。

ABS_MT_TRACKING_ID 描述了从接触开始到释放的整个过程的集合,如果设备不支持,此参数可是不用。

触摸轨迹

仅有少数设备可以明触的标识真实的 trackingID,多数情况下 trackingID只能来标识一次触摸动作的过程。

手势

多点触摸指定的应用是创建手势动作, TOUCH和 WIDTH参数经常用来区别手指的压力和手指间的距离,另外 MINOR类的参数可以用来区别设备的接触面的大小(点接触还是面接触),ORIENTATION可以产生旋转事件。
 
参考代码:

(1) 注册多点触摸设备

ts->input_dev = input_allocate_device();
        if (ts->input_dev == NULL) {
                ret = -ENOMEM;
                printk(KERN_ERR "Failed to allocate input device\n");
                goto err_input_dev_alloc_failed;
        }
        ts->input_dev->name = "MT-touchscreen";

        set_bit(EV_SYN, ts->input_dev->evbit);
        set_bit(EV_KEY, ts->input_dev->evbit);
        set_bit(EV_ABS, ts->input_dev->evbit);
        set_bit(BTN_TOUCH, ts->input_dev->keybit);
      
        max_x=0x77b;
        max_y=0xb38;

        input_set_abs_params(ts->input_dev, ABS_X, 0, max_x, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_Y, 0, max_y, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
        ret = input_register_device(ts->input_dev);
        if (ret) {
                printk(KERN_ERR "Unable to register %s input device\n", ts->input_dev->name);
                goto err_input_register_device_failed;
        }

(2) 报点

if(finger==2)
{
        input_report_key(ts->input_dev,ABS_MT_TRACKING_ID,0);
        input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, f1R);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_X, f1x);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, f1y);
        input_mt_sync(ts->input_dev);
        input_report_key(ts->input_dev,ABS_MT_TRACKING_ID,1);
        input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, f2z);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_X, f2x);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, f2y);
        input_mt_sync(ts->input_dev)
        input_sync(ts->input_dev);
}
else if(finger==1)
{
        input_report_key(ts->input_dev,ABS_MT_TRACKING_ID,0);
        input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, f1R);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_X, f1x);
        input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, f1y);
        input_mt_sync(ts->input_dev);
        input_sync(ts->input_dev);
}
相关资讯
全球芯链共融:新质生产力驱动工业数字化转型新格局

2025年5月14日,全球半导体分销巨头大联大控股在深圳成功举办以「新质工业·引领未来」为主题的峰会,汇聚英飞凌、意法半导体、瑞芯微等16家顶尖原厂及逾500名行业精英。面对全球制造业智能化、低碳化转型浪潮,此次峰会聚焦人工智能、边缘计算、电力电子等新质生产力的技术融合,通过主论坛、分论坛及技术展区三大板块,全方位展示从芯片设计到系统集成的全产业链创新方案。中国工业增加值连续三年稳步增长(2023年4.6%、2024年5.7%、2025年一季度6.5%),印证了“新质工业时代”的全面开启。大联大中国区总裁沈维中在开幕致辞中强调,中国制造业正以技术韧性重构全球供应链,而半导体技术的全链路赋能将成为驱动产业升级的核心引擎。

体积缩小37.7%!看LM-R2S系列如何重塑工业电源格局

根据金升阳官方技术白皮书数据显示,其最新发布的LM-R2S系列机壳开关电源通过8项核心技术创新,实现了工业供电设备在功率密度、环境耐受性及能效表现的三维突破。作为LM-R2系列的迭代产品,该系列解决了传统工业电源在设备小型化与复杂工况适配性之间的矛盾,为智能制造升级提供了高可靠性的供电保障。

存储器市场回暖驱动威刚科技2025年第一季业绩显著增长

2025年第一季度,全球存储器市场迎来关键转折点。DRAM与NAND Flash现货价自2月止跌回升,带动行业库存去化加速,需求端逐步回温。威刚科技董事长陈立白指出,存储器原厂自2024年末起减产调控供给,叠加AI服务器、智能终端等新兴应用需求增长,推动市场价格走出低谷。根据TrendForce数据,尽管此前预测Q1合约价可能下跌,但实际现货市场受备货动能及库存策略影响,价格反弹超预期,成为威刚业绩增长的直接推力。

全大核架构革新旗舰体验 天玑9400e芯片深度解析

MediaTek于5月14日正式推出天玑9400e旗舰移动平台。作为天玑系列的全新力作,该芯片凭借全大核架构设计、第三代4nm制程工艺及多项创新技术,在计算性能、能效管理和AI应用领域实现突破性进展,为智能手机用户提供更卓越的游戏、影像与通信体验。

韩国半导体出口突破116亿美元:存储芯片涨价与HBM需求推高增长

根据韩国产业通商资源部5月14日发布的《2025年4月ICT进出口趋势》报告,韩国4月信息通信技术(ICT)出口额达189.2亿美元,同比增长10.8%,创下有记录以来4月份的最高值。同期贸易顺差为76.1亿美元,主要得益于半导体等高附加值产品的强劲表现。然而,对华、对美两大核心市场的出口增速显著放缓,反映出全球贸易政策不确定性的深远影响。