IMX93+eGalax触摸

参考

https://rolandma1986.github.io/post/touchscreen/

https://blog.csdn.net/pingis58/article/details/110860271

说明

Linux 输入事件被抽象为设备驱动和事件句柄,设备驱动负责与具体的硬件进行通讯,比如 USB 鼠标键盘,并提供 input 内核模块的 input 事件。事件句柄通过 evdev 事件接口与应用层进行通讯。
其次,在输入设备中,仅包含 keyboard,mousedev,joydev 等基本输入事件接口。并没有区分触屏或触控板。

进一步阅读文档,我们可以看到输入设备可以产生不同的事件类型与事件代码。

以鼠标为例,标左键其产生的事件类型和代码应为 EV_KEY,BTN_LEFT;而移动鼠标则会发送,EV_ABS,ABS_X或ABS_Y。

而触控设备的事件类型与鼠标相同,皆为 EV_KEY,但是触屏设备的事件代码则为 BTN_TOUCH而移动都使用 EV_ABS,ABS_X 或 ABS_Y 事件类型和代码。

工作流程

tslib

原始触摸设备 (/dev/input/event0) -> tslib 进行校正和过滤 -> ts_uinput -> 创建虚拟设备 (/dev/input/ts_uinput) -> 应用程序使用这个虚拟设备

libinput

默认情况下,Weston 通过 libinput backend 来管理所有输入设备(触摸屏、鼠标、键盘)。Libinput 是一个现代、标准的输入设备处理库,它能够直接处理 /dev/input/event* 节点。
Weston 的标准输入路径是:
原始触摸设备 (/dev/input/event0) -> libinput -> Weston

可以结合下,但是没必要

原始触摸设备 (/dev/input/event0) -> tslib 守护进程(使用 ts_uinput) -> 虚拟设备 (/dev/input/ts_uinput) -> libinput -> Weston

修改内核

我是6.6版本的内核,开启对应的内核选项,把USB接口触摸的PID VID放到 struct usb_device_id usbtouch_devices 里面即可。(和4G模块的调试差不多)

# USB触摸的内核配置
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_HIDRAW=y
CONFIG_HID_MULTITOUCH=y

# 这里面PID VID本来就有的,但是被忽略成HID设备 DEVTYPE_IGNORE ,注释掉即可。 之前就是卡在这一步了,因为event设备也出来了还是出来了3个,正常的话就只会出来一个event设备的。
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index d6d04b9f04fc..e187d9465704 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -140,8 +140,8 @@ enum {
 static const struct usb_device_id usbtouch_devices[] = {
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
        /* ignore the HID capable devices, handled by usbhid */
-       {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
-       {USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE},
+       // {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
+       // {USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE},

        /* normal device IDs */
        {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
@@ -305,7 +305,7 @@ static int egalax_init(struct usbtouch_usb *usbtouch)

# tslib的内核配置  出u_input节点
CONFIG_INPUT_UINPUT=y

安装

官网:https://www.gtouch.com/

alt text

执行安装官网下载的eGTouch_v2.5.13219.L-ma里面的setup.sh,会有服务生成。

/etc/systemd/system/multi-user.target.wants/eGTouchD.service
cat /etc/eGTouchL.ini
# 改上报事件 BtnType 1   ????? 这个文件驱动没有调用 不知道什么情况 没用
BtnType                         [0] BTN_LEFT    [1] ABS_PRESSURE        [2] BTN_TOUCH

调试

cat /proc/bus/input/devices

alt text

systemctl status eGTouchD.service

systemctl resart eGTouchD.service

hexdump -d /dev/input/event0

校准

IMX93文件系统是yocto,自带的是weston的桌面,使用其自带的校准工具,校准原生的节点。 发现不行,一直是大叉号。 后来发现是是驱动问题,就可以正常使用了。 后面的就当成记录吧。

weston-touch-calibrator /sys/devices/platform/soc@0/4c200000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input4/event3 --debug

使用虚拟的输出节点校准:

weston-touch-calibrator /sys/devices/virtual/input/input5/event4

输入就会自动把可用设备都输出

root@imx93evk:~# weston-touch-calibrator
could not load cursor 'dnd-move'
could not load cursor 'dnd-copy'
could not load cursor 'dnd-none'
device "/sys/devices/platform/soc@0/4c200000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input4/event3" - head "LVDS-1"
device "/sys/devices/virtual/input/input5/event4" - head "LVDS-1"

tslib

用ts_lib校准,是个开源的项目,可以自己编译,但是安装setup.sh的时候有这个选项,选上即可。
开源地址:https://github.com/libts/tslib

编译和使用参考:https://www.jianshu.com/p/8ff1d603d1f7

# 内核需要开启 CONFIG_INPUT_UINPUT=y 来生成节点
/dev/uinput
# 校准 会生成一个文件
ts_calibrate
# 这个命令可以绘图,查看校准的怎么样
ts_test
# 可以一开始就是用着命令,看看触摸有反应没
ts_print

需要配置参数

export TSLIB_TSDEVICE=/dev/input/ts0         
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
ts_uinput -d -v

也有自带的服务去运行ts_uinput。

systemctl status ts_uinput.service
# 输出
root@imx93evk:~# systemctl status ts_uinput.service
* ts_uinput.service - touchscreen input
     Loaded: loaded (/lib/systemd/system/ts_uinput.service; static)
     Active: inactive (dead)

Oct 17 15:45:43 imx93evk systemd[1]: Dependency failed for touchscreen input.
Oct 17 15:45:43 imx93evk systemd[1]: ts_uinput.service: Job ts_uinput.service/start failed with result 'dependency'.

服务配置:

root@imx93evk:~# cat /lib/systemd/system/ts_uinput.service
[Unit]
Description=touchscreen input
BindsTo=dev-input-ts.device
After=dev-input-ts.device
RequiresMountsFor=/etc/ts.env

[Service]
Type=forking
EnvironmentFile=/etc/ts.env
ExecStart=/usr/bin/ts_uinput -d

配置文件:

root@imx93evk:~# cat /etc/ts.env
LIBFILE=/etc/pointercal
TSLIB_CONFFILE=/etc/ts.conf
TSLIB_PLUGINDIR=/usr/lib/ts

libinput

yocto,自带的是weston的桌面就是使用的这个。

# 查看设备列表
libinput list-devices

libinput debug-events --device /dev/input/event3

libinput debug-events

配置udev

只让 ts_uinput 作为唯一触摸设备,原始设备必须被屏蔽。???? 错误的,屏蔽后会整个触摸都不好用。

# /etc/udev/rules.d 路径  设置为 SYMLINK+="input/ts0" 更好看点
root@imx93evk:/etc/udev/rules.d# cat 98-touchscreen.rules
SUBSYSTEMS=="input", KERNEL=="event[0-9]*", ATTRS{name}=="eGalax Inc. USB TouchController", SYMLINK+="input/ts0", TAG+="systemd" ENV{SYSTEMD_WANTS}="ts_uinput.service"
SUBSYSTEMS=="input", KERNEL=="event[0-9]*", ATTRS{name}=="ts_uinput", SYMLINK+="input/ts_uinput"
udevadm info /dev/input/event3
# 输出
P: /devices/platform/soc@0/4c200000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input4/event3
M: event3
R: 3
U: input
D: c 13:67
N: input/event3
L: 0
S: input/by-id/usb-eGalax_Inc._USB_TouchController-event-if00
S: input/by-path/platform-ci_hdrc.1-usb-0:1.3:1.0-event
S: input/ts0
E: DEVPATH=/devices/platform/soc@0/4c200000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input4/event3
E: DEVNAME=/dev/input/event3
E: MAJOR=13
E: MINOR=67
E: SUBSYSTEM=input
E: USEC_INITIALIZED=8444568
E: ID_INPUT=1
E: ID_INPUT_TOUCHSCREEN=1
E: ID_BUS=usb
E: ID_MODEL=USB_TouchController
E: ID_MODEL_ENC=USB\x20TouchController
E: ID_MODEL_ID=0001
E: ID_SERIAL=eGalax_Inc._USB_TouchController
E: ID_VENDOR=eGalax_Inc.
E: ID_VENDOR_ENC=eGalax\x20Inc.
E: ID_VENDOR_ID=0eef
E: ID_REVISION=0100
E: ID_TYPE=hid
E: ID_USB_MODEL=USB_TouchController
E: ID_USB_MODEL_ENC=USB\x20TouchController
E: ID_USB_MODEL_ID=0001
E: ID_USB_SERIAL=eGalax_Inc._USB_TouchController
E: ID_USB_VENDOR=eGalax_Inc.
E: ID_USB_VENDOR_ENC=eGalax\x20Inc.
E: ID_USB_VENDOR_ID=0eef
E: ID_USB_REVISION=0100
E: ID_USB_TYPE=hid
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=platform-ci_hdrc.1-usb-0:1.3:1.0
E: ID_PATH_TAG=platform-ci_hdrc_1-usb-0_1_3_1_0
E: LIBINPUT_DEVICE_GROUP=3/eef/1:usb-ci_hdrc.1-1
E: SYSTEMD_WANTS=ts_uinput.service
E: DEVLINKS=/dev/input/by-id/usb-eGalax_Inc._USB_TouchController-event-if00 /dev/input/by-path/platform-ci_hdrc.1-usb-0:1.3:1.0-event /dev/input/ts0
E: TAGS=:systemd:
E: CURRENT_TAGS=:systemd:

其中的ID_INPUT_TOUCHSCREEN是输出触摸屏的属性。有这个属性就表示可以被桌面作为输出设备使用。

udevadm control --reload-rules
udevadm trigger
# 查看name
udevadm info -a -p $(udevadm info -q path -n /dev/input/event3)

桌面设置

# 关闭桌面
pkill weston
# 桌面服务
systemctl status weston
# 桌面配置
/etc/xdg/weston/weston.ini

内容:

[core]
use-g2d=true
repaint-window=16
idle-time=0
#gbm-format=argb8888
#enable-overlay-view=1

#[shell]
#size=1920x1080

[libinput]
touchscreen_calibrator=true
calibration_helper=/etc/udev/scripts/save-calibration.sh

#[output]
#name=HDMI-A-1
#mode=1920x1080@60
#transform=rotate-90

#[output]
#name=HDMI-A-2
#mode=off
#       WIDTHxHEIGHT    Resolution size width and height in pixels
#       off             Disables the output
#       preferred       Uses the preferred mode
#       current         Uses the current crt controller mode
#transform=rotate-90

[screen-share]
command=/usr/bin/weston --backend=rdp-backend.so --shell=fullscreen-shell.so --no-clients-resize
#start-on-startup=true

[launcher]
icon=/home/root/.nxp-demo-experience/icon/icon_demo_launcher.png
path=/usr/bin/weston-terminal --shell=/home/root/.nxp-demo-experience/scripts/run_tui.sh

[launcher]
icon=/usr/share/weston/terminal.png
path=/usr/bin/weston-terminal

可以看到:

[libinput]
touchscreen_calibrator=true
calibration_helper=/etc/udev/scripts/save-calibration.sh

cat /etc/udev/scripts/save-calibration.sh

root@imx93evk:/etc/udev/rules.d# cat /etc/udev/scripts/save-calibration.sh
#!/bin/bash
echo 'SUBSYSTEM=="input", KERNEL=="event[0-9]*", ENV{ID_INPUT_TOUCHSCREEN}=="1", ENV{LIBINPUT_CALIBRATION_MATRIX}="'$2 $3 $4 $5 $6 $7'"'  > /etc/udev/rules.d/tsc2007.rules

ID_INPUT_TOUCHSCREEN 属性

USB相关

加上这一段之后,内核就不认这个USB设备了。

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 95f90699d2b1..c53b22f5a052 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -285,6 +285,15 @@ static void evdev_pass_values(struct evdev_client *client,
                        EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM);
 }

+static bool evdev_match(struct input_handler *handler, struct input_dev *dev)
+{
+       /* Avoid EETI USB touchscreens */
+       #define VID_EETI 0x0EEF
+       if ((BUS_USB == dev->id.bustype) && (VID_EETI == dev->id.vendor))
+               return false;
+       return true;
+}
+
 /*
  * Pass incoming events to all connected clients.
  */
@@ -1420,6 +1429,7 @@ MODULE_DEVICE_TABLE(input, evdev_ids);
 static struct input_handler evdev_handler = {
        .event          = evdev_event,
        .events         = evdev_events,
+       .match      =   evdev_match,/* added by EETI*/
        .connect        = evdev_connect,
        .disconnect     = evdev_disconnect,
        .legacy_minors  = true,
posted @ 2025-10-17 14:26  潇汀  阅读(11)  评论(0)    收藏  举报