6. VIVO-Y927 Linux 内核设备树完善(触摸屏) | 字数总计: 2.2k | 阅读时长: 11分钟 | 阅读量: |
第5阶段:完善触摸屏
目标
支持 Goodix GT9271 多点电容触摸屏。
DTS 改动分析
Y927 触摸屏挂在 blsp_i2c5,I2C 地址 0x14,中断走 tlmm GPIO13、复位走 tlmm GPIO12,AVDD28(约 2.85V 模拟供电)由 PM8916 LDO16 提供,VDDIO(1.8V 数字 IO 供电)由 PM8916 LDO6 提供。
主线 Goodix 驱动 drivers/input/touchscreen/goodix.c 已经支持 goodix,gt9271 这条 compatible,所以不需要写驱动,只要把 DTS 写对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 &pm8916_rpm_regulators { pm8916_l16: l16 { regulator-min-microvolt = <2850000 > ; regulator-max-microvolt = <2850000 > ; }; }; &blsp_i2c5 { status = "okay" ; touchscreen@14 { compatible = "goodix,gt9271" ; reg = <0x14 > ; interrupt-parent = <&tlmm > ; interrupts = <13 IRQ_TYPE_EDGE_FALLING> ; irq-gpios = <&tlmm 13 GPIO_ACTIVE_HIGH> ; reset-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH> ; AVDD28-supply = <&pm8916_l16 > ; VDDIO-supply = <&pm8916_l6 > ; touchscreen-size-x = <720 > ; touchscreen-size-y = <1280 > ; pinctrl-names = "default" ; pinctrl-0 = <&touchscreen_default > ; }; }; &tlmm { touchscreen_default: touchscreen-default-state { touch-pins { pins = "gpio13" ; function = "gpio" ; drive-strength = <2 > ; bias-pull-up ; }; reset-pins { pins = "gpio12" ; function = "gpio" ; drive-strength = <2 > ; bias-disable ; }; }; };
⚠️ pm8916_l16 在 msm8916-pm8916.dtsi 里默认没声明 。dtsi 只把 ARM/屏幕主链路必需的 LDO(l2/l5/l6/l7/l8/l9/l11/l12/l13)注册到 pm8916_rpm_regulators;l16/l17/l18 这种边缘 LDO 谁用谁声明。漏写直接编译报错:
1 Reference to non-existent node or label "pm8916_l16"
Y927 上 AVDD28 实测 2.85V,min/max 都锁这个值即可。
⚠️ touchscreen_default pinctrl 状态必须显式定义在 &tlmm 。漏写同样报 Reference to non-existent node or label "touchscreen_default"。GT9271 IRQ 引脚需要外部上拉(bias-pull-up),否则中断电平浮动;reset 是单纯输出,bias-disable 即可。
⚠️ 不要执行 i2cdetect -y 0 全总线扫描。Y927 i2c-0 上有些下游设备会卡住串口 shell,要单点测就用 i2cget。
头文件需要新增
DTS 顶部必须有 <dt-bindings/interrupt-controller/irq.h>,才认 IRQ_TYPE_EDGE_FALLING 这个宏:
1 2 3 4 #include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/irq.h> /* 新增 */
内核配置
msm8916_defconfig 默认是 CONFIG_TOUCHSCREEN_GOODIX=m(模块),当前 initramfs 里没有 modprobe 流程,模块永远不会被加载,触摸屏不会出现在 /proc/bus/input/devices。必须把它改成 builtin:
1 2 3 4 5 cd ~/y927/linux./scripts/config --enable TOUCHSCREEN_GOODIX make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig grep TOUCHSCREEN_GOODIX= .config
等价于直接编辑 .config:
1 2 3 CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_GOODIX=y # ← 必须 =y,不是 =m CONFIG_REGULATOR_FIXED_VOLTAGE=y
⚠️ 这跟第 3 阶段 DRM_MSM=m → =y 是同一个坑。msm8916_defconfig 是 postmarketOS 的 distro 默认配置,假定 rootfs 里有完整的 modprobe / udev 链路;最小 initramfs 阶段必须把所有调试要用到的驱动都做成 builtin。
完整 DTS
最终的 arch/arm64/boot/dts/qcom/msm8916-vivo-y927.dts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 /dts-v1/ ; #include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/irq.h> / { model = "vivo Y927 (PD1410V)" ; compatible = "vivo,y927" , "qcom,msm8916" ; chassis-type = "handset" ; aliases { mmc0 = &sdhc_1 ; mmc1 = &sdhc_2 ; }; usb_id: usb-id { compatible = "linux,extcon-usb-gpio" ; id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH> ; pinctrl-names = "default" ; pinctrl-0 = <&usb_id_default > ; }; backlight: backlight { compatible = "gpio-backlight" ; gpios = <&tlmm 8 GPIO_ACTIVE_HIGH> ; default-on ; }; reg_lcd_enp: regulator-lcd-enp { compatible = "regulator-fixed" ; regulator-name = "lcd_enp" ; gpio = <&tlmm 97 GPIO_ACTIVE_HIGH> ; enable-active-high ; regulator-always-on ; regulator-boot-on ; }; reg_lcd_enn: regulator-lcd-enn { compatible = "regulator-fixed" ; regulator-name = "lcd_enn" ; gpio = <&tlmm 98 GPIO_ACTIVE_HIGH> ; enable-active-high ; regulator-always-on ; regulator-boot-on ; }; reserved-memory { cont-splash@83200000 { reg = <0 0x83200000 0 0x800000 > ; no-map ; }; }; gpio-keys { compatible = "gpio-keys" ; pinctrl-names = "default" ; pinctrl-0 = <&gpio_keys_default > ; label = "GPIO Buttons" ; button-volume-up { label = "Volume Up" ; gpios = <&tlmm 107 GPIO_ACTIVE_LOW> ; linux,code = <KEY_VOLUMEUP> ; }; }; }; &usb { dr_mode = "peripheral" ; extcon = <&usb_id > , <&usb_id > ; status = "okay" ; }; &usb_hs_phy { extcon = <&usb_id > ; status = "okay" ; }; &tlmm { usb_id_default: usb-id-default { pins = "gpio110" ; function = "gpio" ; drive-strength = <8 > ; bias-pull-up ; }; mdss_default: mdss-default-state { pins = "gpio25" ; function = "gpio" ; drive-strength = <8 > ; bias-disable ; }; mdss_sleep: mdss-sleep-state { pins = "gpio25" ; function = "gpio" ; drive-strength = <2 > ; bias-pull-down ; }; gpio_keys_default: gpio-keys-default-state { pins = "gpio107" ; function = "gpio" ; drive-strength = <2 > ; bias-pull-up ; }; touchscreen_default: touchscreen-default-state { touch-pins { pins = "gpio13" ; function = "gpio" ; drive-strength = <2 > ; bias-pull-up ; }; reset-pins { pins = "gpio12" ; function = "gpio" ; drive-strength = <2 > ; bias-disable ; }; }; }; &pm8916_resin { linux,code = <KEY_VOLUMEDOWN> ; status = "okay" ; }; &pm8916_rpm_regulators { pm8916_l16: l16 { regulator-min-microvolt = <2850000 > ; regulator-max-microvolt = <2850000 > ; }; }; &sdhc_1 { status = "okay" ; }; &sdhc_2 { status = "okay" ; cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW> ; }; &mdss { status = "okay" ; }; &mdss_dsi0 { pinctrl-names = "default" , "sleep" ; pinctrl-0 = <&mdss_default > ; pinctrl-1 = <&mdss_sleep > ; status = "okay" ; panel@0 { compatible = "vivo,y927-hx8394a" ; reg = <0 > ; reset-gpios = <&tlmm 25 GPIO_ACTIVE_LOW> ; backlight = <&backlight > ; vsp-supply = <®_lcd_enp > ; vsn-supply = <®_lcd_enn > ; port { panel_in: endpoint { remote-endpoint = <&mdss_dsi0_out > ; }; }; }; }; &mdss_dsi0_out { data-lanes = <0 1 2 3 > ; remote-endpoint = <&panel_in > ; }; &blsp_i2c5 { status = "okay" ; touchscreen@14 { compatible = "goodix,gt9271" ; reg = <0x14 > ; interrupt-parent = <&tlmm > ; interrupts = <13 IRQ_TYPE_EDGE_FALLING> ; irq-gpios = <&tlmm 13 GPIO_ACTIVE_HIGH> ; reset-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH> ; AVDD28-supply = <&pm8916_l16 > ; VDDIO-supply = <&pm8916_l6 > ; touchscreen-size-x = <720 > ; touchscreen-size-y = <1280 > ; pinctrl-names = "default" ; pinctrl-0 = <&touchscreen_default > ; }; };
GPIO 对照
GPIO
功能
方向
12
触摸 RESET
输出高有效
13
触摸 IRQ
输入下降沿
编译 Linux 内核
1 2 cd ~/y927/linuxmake ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc ) Image.gz dtbs
构建 boot.img 文件
沿用第 4.1 阶段已经打好的 initramfs-phase-4.cpio.gz(含 evtest),不必重新做 initramfs。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cd ~/y927/linuxcat arch /arm64/boot/Image.gz \ arch /arm64/boot/dts/qcom/msm8916-vivo-y927.dtb \ > vmlinuz-dtb ~/y927/lk2nd/lk2nd/scripts/mkbootimg \ --kernel vmlinuz-dtb \ --ramdisk $HOME /y927/initramfs/initramfs-phase-4.cpio.gz \ --cmdline "console=tty0 console=ttyMSM0,115200 panic=1 initcall_blacklist=simpledrm_platform_driver_init" \ --base 0x80000000 \ --kernel_offset 0x00008000 \ --ramdisk_offset 0x01000000 \ --second_offset 0x00f00000 \ --tags_offset 0x00000100 \ --pagesize 2048 \ --header_version 0 \ --output boot-phase5.img
刷入 boot.img 文件
1 2 fastboot flash boot boot-phase5.img fastboot reboot
测试
1 sudo picocom -b 115200 /dev/ttyACM0
2026-06-14 13:20 触摸屏被成功识别。
1. dmesg 确认驱动 probe 成功
1 2 3 4 5 6 7 8 9 ~ [ 0.228049] i2c_qup 78b9000.i2c: using default clock-frequency 100000 [ 0.232333] input: pm8941_pwrkey as /devices/.../pwrkey/input/input0 [ 0.233669] input: pm8941_resin as /devices/.../resin/input/input1 [ 0.348494] input: GPIO Buttons as /devices/platform/gpio-keys/input/input2 [ 0.367162] l16: Bringing 0uV into 2850000-2850000uV [ 0.459889] Goodix-TS 0-0014: ID 9159, version: 1015 [ 0.460097] Goodix-TS 0-0014: Direct firmware load for goodix_9159_cfg.bin failed with error -2 [ 0.482771] input: Goodix Capacitive TouchScreen as /devices/.../i2c-0/0-0014/input/input3
Y927 实测芯片 ID 是 9159 ,不是 DTS 里写的 gt9271 —— 但 compatible = "goodix,gt9271" 是兼容字符串,主线 Goodix 驱动通过 I2C 通讯握手时会自动读取真实 chip ID 并查内置配置表,所以不影响识别。Direct firmware load for goodix_9159_cfg.bin failed with error -2 表示外部固件配置文件不存在(rootfs 里没放 /lib/firmware/goodix_9159_cfg.bin),驱动会 fallback 到芯片内部 OTP/Flash 里固化的出厂参数,依旧能正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 ~ ... I: Bus=0018 Vendor=0416 Product=23c7 Version=1015 N: Name="Goodix Capacitive TouchScreen" P: Phys=input/ts S: Sysfs=/devices/platform/soc@0/78b9000.i2c/i2c-0/0-0014/input/input3 U: Uniq= H: Handlers=kbd event3 B: PROP=2 B: EV=b B: KEY=400 0 0 0 2000000000000001 f800000000000000 B: ABS=265800000000003
3. 用 evtest 监听触摸事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ~ Input driver version is 1.0.1 Input device ID: bus 0x18 vendor 0x416 product 0x23c7 version 0x1015 Input device name: "Goodix Capacitive TouchScreen" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 330 (BTN_TOUCH) Event type 3 (EV_ABS) Event code 0 (ABS_X) Event code 1 (ABS_Y) Event code 24 (ABS_PRESSURE) Event code 47 (ABS_MT_SLOT) Event code 48 (ABS_MT_TOUCH_MAJOR) Event code 53 (ABS_MT_POSITION_X) Event code 54 (ABS_MT_POSITION_Y) ... Testing ... (interrupt to exit )
按下手指时输出形如:
1 2 3 4 Event: time 12.345, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 360 Event: time 12.345, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 640 Event: time 12.345, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 12.345, -------------- SYN_REPORT ------------
ABS_MT_POSITION_X / ABS_MT_POSITION_Y 跟随手指移动 (0–720, 0–1280),按下/松开时 BTN_TOUCH 翻转 1/0,多点电容触摸链路全通。
提示:evtest 启动后会一直占用串口 stdin,结束时按 Ctrl+C 退出。如果 Ctrl+C 不能恢复 shell(少数情况下 evtest 还在 grab 状态),重启手机即可。