5. VIVO-Y927 Linux 内核设备树完善(GPIO按键)
|字数总计:1.5k|阅读时长:8分钟|阅读量:|
第4阶段:完善 GPIO 按键
目标
支持音量键/电源键
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
| #include <dt-bindings/input/input.h>
/ { 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>; }; }; };
&pm8916_resin { linux,code = <KEY_VOLUMEDOWN>; status = "okay"; };
&tlmm { gpio_keys_default: gpio-keys-default-state { pins = "gpio107"; function = "gpio"; drive-strength = <2>; bias-pull-up; }; };
|
最后的 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
|
/dts-v1/;
#include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.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; }; };
&pm8916_resin { linux,code = <KEY_VOLUMEDOWN>; status = "okay"; };
&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>; };
|
编译 Linux 内核
1 2
| cd ~/y927/linux make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image.gz dtbs
|
构建 boot.img 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| cd ~/y927/linux
cat 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-3.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-phase4.img
|
刷入 boot.img 文件
1 2
| fastboot flash boot boot-phase4.img fastboot reboot
|
测试
1
| sudo picocom -b 115200 /dev/ttyACM0
|
2026-06-14 12:32 所有物理按键被成功识别
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
| ~ I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="pm8941_pwrkey" P: Phys=pm8941_pwrkey/input0 S: Sysfs=/devices/platform/soc@0/200f000.spmi/spmi-0/0-00/200f000.spmi:pmic@0:pon@800/200f000.spmi:pmic@0:pon@800:pwrkey/input/input0 U: Uniq= H: Handlers=kbd event0 B: PROP=0 B: EV=3 B: KEY=10000000000000 0
I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="pm8941_resin" P: Phys=pm8941_resin/input0 S: Sysfs=/devices/platform/soc@0/200f000.spmi/spmi-0/0-00/200f000.spmi:pmic@0:pon@800/200f000.spmi:pmic@0:pon@800:resin/input/input1 U: Uniq= H: Handlers=kbd event1 B: PROP=0 B: EV=3 B: KEY=4000000000000 0
I: Bus=0019 Vendor=0001 Product=0001 Version=0100 N: Name="GPIO Buttons" P: Phys=gpio-keys/input0 S: Sysfs=/devices/platform/gpio-keys/input/input2 U: Uniq= H: Handlers=kbd event2 B: PROP=0 B: EV=3 B: KEY=8000000000000 0
|
第4.1阶段:编译evtest打包进initramfs测试
目标
编译一个arm64版本的evtest,并打包到initramfs里用于测试物理按键是否正常工作。
工具准备
1
| sudo apt install -y autoconf automake libtool pkg-config gcc-aarch64-linux-gnu
|
克隆源码
1 2 3
| mkdir -p ~/y927/evtest && cd ~/y927/evtest git clone https://gitlab.freedesktop.org/libevdev/evtest.git src cd src
|
交叉编译
1 2 3 4 5 6 7 8 9 10 11 12
| cd ~/y927/evtest/src ./autogen.sh --host=aarch64-linux-gnu \ CC=aarch64-linux-gnu-gcc \ CFLAGS='-Os -static' \ LDFLAGS='-static' make -j$(nproc)
file evtest
aarch64-linux-gnu-strip evtest
|
制作initramfs
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
| BUSYBOX_BINARY=~/y927/busybox-1.38.0/busybox EVTEST_BINARY=~/y927/evtest/src/evtest cd ~/y927/initramfs rm -rf phase-4 mkdir -p phase-4 && cd phase-4
mkdir -p bin dev proc sys lib/modules
cp $BUSYBOX_BINARY bin/ cp $EVTEST_BINARY bin/
cd bin for cmd in sh mount ls cat sleep exec echo; do ln -sf busybox $cmd done cd ..
cat > init << 'EOF'
mount -t proc proc /proc mount -t sysfs sys /sys mount -t devtmpfs dev /dev echo "===== Phase 1: kernel booted! =====" echo "Serial: $(cat /proc/cmdline)" sleep 5 exec sh </dev/ttyGS0 >/dev/ttyGS0 2>&1 EOF chmod +x init
find . | cpio -o -H newc | gzip > ../initramfs-phase-4.cpio.gz
|
构建 boot.img 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| cd ~/y927/linux
cat 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-phase4.img
|
刷入 boot.img 文件
1 2
| fastboot flash boot boot-phase4.img fastboot reboot
|
测试
1
| sudo picocom -b 115200 /dev/ttyACM0
|
1 2 3
| evtest /dev/input/event0 evtest /dev/input/event1 evtest /dev/input/event2
|
然后按对应的按键,就可以滚动输出对应的按键状态了