当前位置: 首页 > article >正文

RK3568 android11 usb接口TP与电磁笔触点上报优先级问题

一,问题描述

双USB接口,电容触摸跟电磁手写笔触摸会产生误触现象,所以需要在底层实现电磁笔优先级。
电磁屏优先(指当笔和手都放屏上,手不发信息),因为都是USB接口使用,电容触摸跟电磁手写笔触摸会产生误触现象;

rk3568:/ # getevent
add device 1: /dev/input/event5
  name:     "ILITEK ILITEK-TP"
add device 2: /dev/input/event0
  name:     "fdd70030.pwm"
add device 3: /dev/input/event1
  name:     "rk805 pwrkey"
add device 4: /dev/input/event4
  name:     "rk-headset"
add device 5: /dev/input/event3
  name:     "adc-keys"
add device 6: /dev/input/event2
  name:     "HUION Huion Monitor"

cat sys/kernel/debug/usb/devices 查看本地usb设备信息

rk3568:/ # cat sys/kernel/debug/usb/devices
T:  Bus=02 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#=  3 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=222a ProdID=0001 Rev= 0.02
S:  Manufacturer=ILITEK
S:  Product=ILITEK-TP
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=400mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
E:  Ad=02(O) Atr=03(Int.) MxPS=  64 Ivl=1ms


T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=256c ProdID=006d Rev= 1.12
S:  Manufacturer=HUION
S:  Product=Huion Monitor
C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms

dev/input/event5 (触摸 ILITEK ILITEK-TP)
dev/input/event2 (电磁笔 HUION Huion Monitor)


二,驱动代码分析

1. TP上报

源码路径:kernel/drivers/hid/hid-multitouch.c

主要是mt_report函数:

static void mt_report(struct hid_device *hid, struct hid_report *report)  //静态函数mt_report
{
        struct mt_device *td = hid_get_drvdata(hid); //通过 hid_get_drvdata 获取与 HID设备有关的多点触控设备数据结构(mt_device)
        struct hid_field *field = report->field[0];  //获取当前报告的第一个字段 field
        struct mt_report_data *rdata;

        if (!(hid->claimed & HID_CLAIMED_INPUT))  //检查设备状态
                return;

        rdata = mt_find_report_data(td, report); //查找与当前报告相关联的多点触控数据结构 rdata
        if (rdata && rdata->is_mt_collection)   //如果 rdata 存在并且它标记为多点触控集合,则调用 mt_touch_report(hid, rdata) 函数来处理该触控报告
                return mt_touch_report(hid, rdata);

        if (field && field->hidinput && field->hidinput->input)
                input_sync(field->hidinput->input);  //同步输入设备状态
}

这段代码是用于在一个 HID (人机接口设备)驱动中处理多点触控(MT, Multi-Touch)报告的函数。

2. 电磁笔上报

跟踪代码发现电磁笔使用的是hid通用驱动;
源码路径:kernel/drivers/hid/hid-input.c

上报信息主要是以下位置:

if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
        if (value) {   //如果 value 为真(通常表示触控笔或指针当前在数字化仪的感应范围内)
                input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);  //表示正在使用电磁笔
                return;
        }
        input_event(input, usage->type, usage->code, 0);  //表示当前工具不再激活(使用 usage->code 设置为 0)
        input_event(input, usage->type, BTN_TOOL_RUBBER, 0);  //表示电磁笔不在使用
        return;
}

这段代码首先判断 usage 结构的 hid 字段是否等于一个特定值,这个值表明当前事件对应于数字化仪的 “InRange” 事件。


三,功能实现

思路如下:
1.在电磁笔上报信息的地方定义一个全局变量,按下设置为true,松开设置为false;
2.在TP触摸处理多点触控的位置根据变量的状态进行判断
3.电磁笔上报时,屏蔽TP触摸的上报;反之电磁笔停止上报,TP触摸正常;

参考补丁:

diff --git a/kernel/drivers/hid/hid-input.c b/kernel/drivers/hid/hid-input.c
index dd3f4aa052..e644b599c9 100644
--- a/kernel/drivers/hid/hid-input.c
+++ b/kernel/drivers/hid/hid-input.c
@@ -36,6 +36,9 @@
#define unk    KEY_UNKNOWN
+bool touch_blocked;
+EXPORT_SYMBOL(touch_blocked);

static const unsigned char hid_keyboard[256] = {
       0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
      50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
@@ -1268,12 +1271,17 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
     }
     if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
+    printk(KERN_ERR "[fy-1]:value = %d,quirks = %x, BTN_TOOL_RUBBER = %d, usage->code = %d,usage->type = %u\n",value,(*quirks & HID_QUIRK_INVERT), BTN_TOOL_RUBBER, usage->code, usage->type);
         if (value) {
             input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
+            touch_blocked = true;
+            printk(KERN_ERR "[fy-2]:value = %d,usage->code = %d,usage->type = %u,BTN_TOOL_RUBBER = %d\n",value,usage->code, usage->type, BTN_TOOL_RUBBER);
             return;
         }
         input_event(input, usage->type, usage->code, 0);
         input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
+        touch_blocked = false;
+        printk(KERN_ERR "[fy-3]:value = %d,usage->code = %d,usage->type = %u,BTN_TOOL_RUBBER = %d\n",value,usage->code, usage->type, BTN_TOOL_RUBBER);
         return;
     }
diff --git a/kernel/drivers/hid/hid-multitouch.c b/kernel/drivers/hid/hid-multitouch.c
index 0c72702fc1..ffb9a4820b 100644
--- a/kernel/drivers/hid/hid-multitouch.c
+++ b/kernel/drivers/hid/hid-multitouch.c
@@ -1366,18 +1366,28 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
     return 0;
}
+extern bool touch_blocked;
static void mt_report(struct hid_device *hid, struct hid_report *report)
{
     struct mt_device *td = hid_get_drvdata(hid);
     struct hid_field *field = report->field[0];
     struct mt_report_data *rdata;
+    printk(KERN_INFO "[FY-1]------mt_report: Entered mt_report for HID device: %p\n", hid);
     if (!(hid->claimed & HID_CLAIMED_INPUT))
         return;
     rdata = mt_find_report_data(td, report);
-    if (rdata && rdata->is_mt_collection)
-        return mt_touch_report(hid, rdata);
+    if (rdata && rdata->is_mt_collection){
+        printk(KERN_INFO "[FY-2]------mt_report: Found MT collection, processing touch report\n");
+        if(touch_blocked){
+           printk(KERN_INFO "[FY-3]------mt_report: Touch events are blocked.\n");
+           return;
+        }else{
+           printk(KERN_INFO "[FY-4]------mt_report: Touch events are open.\n");
+           return mt_touch_report(hid, rdata);
+        }
+    }
     if (field && field->hidinput && field->hidinput->input)
         input_sync(field->hidinput->input);

编译烧录后,验证功能正常(电磁笔使用时TP不上报);


http://www.kler.cn/a/369510.html

相关文章:

  • 数据仓库建设 : 主题域简介
  • Sentinel详解
  • 01.04、回文排序
  • Ajax:跨域 JSONP
  • spring final修饰
  • 海通证券万一免五操作合规吗,怎样实现低佣金?
  • HCIP-HarmonyOS Application Developer 习题(十八)
  • Unity URP ShaderGraph 基本设置
  • [论文阅读]Detecting Pretraining Data from Large Language Models
  • Windows服务器如何远程登录 #服务器远程教程#
  • 大数据-192 DataX - 异构数据源的同步工具 核心模块 Reader Writer
  • 【微服务】Nacos 注册中心
  • 实时面部情绪识别技术解析
  • 大券商和小券商开户,哪个更划算?
  • 算法:利用前序序列和中序序列构造二叉树
  • Spring常见面试题总结
  • java程序,生成mysql测试数据
  • 高并发-负载均衡
  • 《Python游戏编程入门》注-第4章1
  • DevOps --- Pipeline和Yaml文件
  • 有人问我:过去一年用 AI 写了多少代码
  • 力扣 —— 加油站
  • 开源实时数仓的构建
  • NYSQL期中小结
  • Redis 命令集 (超级详细)
  • 一些MySQL的知识