前言:
首先我们这个项目有5个按键 音量+ 音量- 开机键 RST键 HOME键
我们需要分两块看这个按键:
1.开机之前需要进行组合按键,比如组合按键进fastboot ,组合按键强制下载
衍生:USB的D+接地进强制下载?代码逻辑?
2.开机之后的按键功能
首先根据原理图我们可以知道:
音量+ 对应:pm7325 GPIO6
音量 - 对应:GPIO25
home 对应:GPIO24
PWR 对应:pmk7325 上的PWR
RESET 对应:pmk7325 上的RESIN
原理图:
代码移植:
一、组合按键移植 关于组合按键,同时按下:① PWR键 音量+ :recovery模式
② PWR键 音量- :Fastboot模式
③ PWR键 音量+ 音量- :下载模式
AP侧看到这样一段代码:
LA.UM.9.14.1\bootable\bootloader\edk2\QcomModulePkg\Application\LinuxLoader\LinuxLoader.c
EFI_STATUS EFIAPI __attribute__ ( (no_sanitize ("safe-stack")))
LinuxLoaderEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{
...
Status = GetKeyPress (&KeyPressed);
if (Status == EFI_SUCCESS) {
if (KeyPressed == SCAN_DOWN)
BootIntoFastboot = TRUE;
if (KeyPressed == SCAN_UP)
BootIntoRecovery = TRUE;
if (KeyPressed == SCAN_ESC)
RebootDevice (EMERGENCY_DLOAD);
} else if (Status == EFI_DEVICE_ERROR) {
DEBUG ((EFI_D_ERROR, "Error reading key status: %r\n", Status));
goto stack_guard_update_default;
}
// check for reboot mode
Status = GetRebootReason (&BootReason);
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR, "Failed to get Reboot reason: %r\n", Status));
goto stack_guard_update_default;
}
switch (BootReason) {
case FASTBOOT_MODE:
BootIntoFastboot = TRUE;
break;
case RECOVERY_MODE:
BootIntoRecovery = TRUE;
break;
case ALARM_BOOT:
BootReasonAlarm = TRUE;
break;
case DM_VERITY_ENFORCING:
// write to device info
Status = EnableEnforcingMode (TRUE);
if (Status != EFI_SUCCESS)
goto stack_guard_update_default;
break;
case DM_VERITY_LOGGING:
/* Disable MDTP if it's Enabled through Local Deactivation */
Status = MdtpDisable ();
if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
DEBUG ((EFI_D_ERROR, "MdtpDisable Returned error: %r\n", Status));
goto stack_guard_update_default;
}
// write to device info
Status = EnableEnforcingMode (FALSE);
if (Status != EFI_SUCCESS)
goto stack_guard_update_default;
break;
case DM_VERITY_KEYSCLEAR:
Status = ResetDeviceState ();
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR, "VB Reset Device State error: %r\n", Status));
goto stack_guard_update_default;
}
break;
default:
if (BootReason != NORMAL_MODE) {
DEBUG ((EFI_D_ERROR,
"Boot reason: 0x%x not handled, defaulting to Normal Boot\n",
BootReason));
}
break;
}
Status = RecoveryInit (&BootIntoRecovery);
if (Status != EFI_SUCCESS)
DEBUG ((EFI_D_VERBOSE, "RecoveryInit failed ignore: %r\n", Status));
/* Populate board data required for fastboot, dtb selection and cmd line */
Status = BoardInit ();
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR, "Error finding board information: %r\n", Status));
return Status;
}
DEBUG ((EFI_D_ERROR, "KeyPress:%u, BootReason:%u\n", KeyPressed, BootReason));
DEBUG ((EFI_D_ERROR, "Fastboot=%d, Recovery:%d\n",
BootIntoFastboot, BootIntoRecovery));
...
}
首先根据log:
PWR键 音量+
KeyPress:5, BootReason:0
Fastboot=0, Recovery:0
PWR键 音量-
HLOS SubType : 0x0
KeyPress:258, BootReason:0
Fastboot=0, Recovery:0
WR键 音量+ 音量-:
HLOS SubType : 0x0
KeyPress:5, BootReason:0
Fastboot=0, Recovery:0
Booting from slot (_a)
看KeyPress值,情况1和情况3的值一样没办法区分,这个时候我们需要查一下BP的代码了,这个值是从BP传过来的。通过关键词“SCAN_DOWN”搜索BP侧代码来切入。
然后我们找到几个关键性的文件:
boot_images\boot\QcomPkg\SocPkg\Kodiak\Library\ButtonsTargetLib
这个目录下的文件配置了gpio-key;但是具体的都是pm-gpio -key,没有CPU gpio-key;这个时候怎么办呢?
我们又看到在这个文件中调用的上述配置:
boot_images\boot\QcomPkg\Library\ButtonsLib\ButtonsLib.c
@@ -40,6 +40,7 @@ when who what, where, why
#include <Protocol/EFIPlatformInfo.h>
#include <Protocol/EFIPmicGpio.h>
#include <Protocol/EFIPmicPwrOn.h>
+#include <Protocol/EFITlmm.h>
EFI_PLATFORMINFO_PLATFORM_TYPE PlatformType ;
@@ -51,12 +52,19 @@ EFI_QCOM_PMIC_PWRON_PROTOCOL *PmicPONProtocol;
BOOLEAN isEfiKeyDetected = FALSE;
BOOLEAN isHomeKeyDetected = FALSE;
extern EFI_GUID gQcomTokenSpaceGuid;
+//add by zh
+EFI_TLMM_PROTOCOL *TLMMProtocol;
#define NUMBER_OF_KEYS 5
// Button Index
#define VOLUME_UP_BUTTON_IDX 1
#define HOME_BUTTON_IDX 2
#define CAMERA_SNAPSHOT_BUTTON_IDX 3
+#define VOLUME_DOWN_BUTTON_IDX 4
+
+#define VOLUME_DOWN_BUTTON_GPIO 25
+#define NOT_SUPPORTED 0
+
/*** Define the Key Map for all Platforms ***/
struct StructPlatformKeyMap {
@@ -71,6 +79,54 @@ EFI_STATUS ConfigureButtonGPIOs ( VOID );
EFI_STATUS ReadGpioStatus( UINT16 KeyIndex, BOOLEAN *pGpioButtonPressed );
+//add by zh
+EFI_STATUS EnableInput_Meig ( UINT16 GpioNumber )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(TLMMProtocol)
+ {
+ Status = TLMMProtocol->ConfigGpio(
+ EFI_GPIO_CFG(GpioNumber, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA),
+ TLMM_GPIO_ENABLE);
+
+ if ( EFI_ERROR (Status) )
+ {
+ DEBUG(( EFI_D_ERROR, "EnableInput: ConfigDigitalInput failed Status = (0x%x)\r\n", Status));
+ goto ErrorExit;
+ }
+ }
+
+ErrorExit:
+ return Status;
+}
+
+
+EFI_STATUS ReadGpioStatus_Meig( UINT16 GpioNumber, BOOLEAN *pGpioButtonPressed )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 GpioStatus = FALSE;
+ Status = TLMMProtocol->GpioIn(EFI_GPIO_CFG( GpioNumber, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA ),
+ &GpioStatus);
+
+ if ( EFI_ERROR (Status) )
+ {
+ DEBUG(( EFI_D_ERROR, "ReadGpioStatus: IrqStatus failed Status = (0x%x)\r\n", Status));
+ }
+ else
+ {
+ //
+ // this is because we initially have pull-ups on the GPIOs
+ //
+ *pGpioButtonPressed = ( GpioStatus == TRUE ) ? FALSE : TRUE;
+ }
+
+
+ return Status;
+}
+//add by zh end
+
+
/**
Find a local key to an array.
@@ -335,6 +391,16 @@ EFI_STATUS ButtonsInit (
)
{
EFI_STATUS Status;
+
+ // get tlmm Gpio protocol handle
+ Status = gBS->LocateProtocol(&gEfiTLMMProtocolGuid, NULL, (void**)&TLMMProtocol);
+ if ( EFI_ERROR (Status) )
+ {
+ DEBUG(( EFI_D_ERROR, "ButtonsInit: failed to locate TLMMProtocol, Status = (0x%x)\r\n", Status));
+ goto ErrorExit;
+ }
+
+ ASSERT(TLMMProtocol != NULL);
// get Pmic Gpio protocol handle
Status = gBS->LocateProtocol(&gQcomPmicGpioProtocolGuid, NULL, (VOID **) &PmicGpioProtocol);
@@ -361,6 +427,18 @@ EFI_STATUS ButtonsInit (
DEBUG(( EFI_D_ERROR, "ButtonsInit: InitializeKeyMap() failed, Status = (0x%x)\r\n", Status ));
goto ErrorExit;
}
+
+ // volume down add by zh
+ if (VOLUME_DOWN_BUTTON_GPIO != NOT_SUPPORTED)
+ {
+ Status = EnableInput_Meig(VOLUME_DOWN_BUTTON_GPIO);
+ if ( EFI_ERROR (Status) )
+ {
+ DEBUG(( EFI_D_ERROR, "ConfigureButtonGPIOs: EnableInput failed for VOL- button, Status = (0x%x)\r\n", Status));
+ goto ErrorExit;
+ }
+ }
+
// Configure button GPIOs
Status = ConfigureButtonGPIOs();
@@ -437,12 +515,18 @@ EFI_STATUS PollButtonArray( UINT8 *pButtonArray )
//for volume down
ButtonPressed = FALSE;
- Status = ReadRealTimeIRQStatus( EFI_PM_PON_IRQ_RESIN_ON, &ButtonPressed );
+ Status = ReadGpioStatus_Meig( VOLUME_DOWN_BUTTON_GPIO, &ButtonPressed );
if ( EFI_ERROR (Status) )
{
- DEBUG(( EFI_D_ERROR, "PollButtonArray: ReadRealTimeIRQStatus failed for VOL-, Status = (0x%x)\r\n", Status));
- goto ErrorExit;
+ DEBUG(( EFI_D_ERROR, "PollButtonArray: ReadGpioStatus failed for VOL-, Status = (0x%x)\r\n", Status));
+ goto ErrorExit;
}
+ // Status = ReadRealTimeIRQStatus( EFI_PM_PON_IRQ_RESIN_ON, &ButtonPressed );
+ // if ( EFI_ERROR (Status) )
+ // {
+ // DEBUG(( EFI_D_ERROR, "PollButtonArray: ReadRealTimeIRQStatus failed for VOL-, Status = (0x%x)\r\n", Status));
+ // goto ErrorExit;
+ // }
*(pButtonArray + 2) = ButtonPressed;
//for home
boot_images/boot/QcomPkg/SocPkg/Kodiak/Library/ButtonsTargetLib/ButtonsLib.inf
@@ -54,6 +54,7 @@
gEfiPlatformInfoProtocolGuid
gQcomPmicGpioProtocolGuid
gQcomPmicPwrOnProtocolGuid
+ gEfiTLMMProtocolGuid
[Pcd]
修改之后:
PWR键 音量+
HLOS SubType : 0x0
KeyPress:5, BootReason:0
Fastboot=0, Recovery:0
Booting from slot (_a)
//#define SCAN_HOME 0x0005
PWR键 音量-
KeyPress:8, BootReason:0
Fastboot=0, Recovery:0
//#define SCAN_DELETE 0x0008
WR键 音量+ 音量-:直接xbl 就进edl了?AP侧有这样一段代码决定的:
LA.UM.9.14.1\bootable\bootloader\edk2\QcomModulePkg\Application\LinuxLoader\LinuxLoader.c
//具体逻辑?log中没看出来
Status = GetKeyPress (&KeyPressed);
if (Status == EFI_SUCCESS) {
if (KeyPressed == SCAN_DOWN)
BootIntoFastboot = TRUE;
if (KeyPressed == SCAN_UP)
BootIntoRecovery = TRUE;
if (KeyPressed == SCAN_ESC)
RebootDevice (EMERGENCY_DLOAD);//进下载模式
接着看这些宏定义
55 #define SCAN_NULL 0x0000
56 #define SCAN_UP 0x0001
57 #define SCAN_DOWN 0x0002
58 #define SCAN_RIGHT 0x0003
59 #define SCAN_LEFT 0x0004
60 #define SCAN_HOME 0x0005
61 #define SCAN_END 0x0006
62 #define SCAN_INSERT 0x0007
63 #define SCAN_DELETE 0x0008
64 #define SCAN_PAGE_UP 0x0009
65 #define SCAN_PAGE_DOWN 0x000A
因此AP侧修改如下:
LA.UM.9.14.1\bootable\bootloader\edk2\QcomModulePkg\Application\LinuxLoader\LinuxLoader.c
Status = GetKeyPress (&KeyPressed);
if (Status == EFI_SUCCESS) {
//if (KeyPressed == SCAN_DOWN)
if (KeyPressed == SCAN_DELETE)
BootIntoFastboot = TRUE;
//if (KeyPressed == SCAN_UP)
if (KeyPressed == SCAN_HOME)
BootIntoRecovery = TRUE;
if (KeyPressed == SCAN_ESC)
RebootDevice (EMERGENCY_DLOAD);
} else if (Status == EFI_DEVICE_ERROR) {
DEBUG ((EFI_D_ERROR, "Error reading key status: %r\n", Status));
goto stack_guard_update_default;
}
所以问题又来了,AP侧是怎么调用的?具体逻辑?
LA.UM.9.14.1\bootable\bootloader\edk2\QcomModulePkg\Library\BootLib\KeyPad.c
gEfiSimpleTextInputExProtocolGuid 对应的处理函数集 KeypadSimpleInputExProtocolImplementation
跟随这个看下BP侧代码:
boot_images/boot/QcomPkg/Drivers/ButtonsDxe/ButtonsDxe.c +1048
boot_images/boot/QcomPkg/Drivers/KeypadDxe/KeypadDxe.c +920
回到AP侧代码,最终还是这里获取key 值:ReadKeyStrokeEx 被安装到gEfiSimpleTextInputExProtocolGuid 。
理论上应该调用KeysDxeReadKeyStrokeEx 才对,总共有三个ReadKeyStrokeEx,上面两个不会被调用,走的是下面的。
PollButtonArray–》PollForKey—》KeysDxeReadKeyStroke
对应BP:
boot_images/boot/QcomPkg/Drivers/SimpleTextInOutSerialDxe/SimpleTextInOut.c
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mSimpleTextInEx = {
TextInResetEx,
ReadKeyStrokeEx,
NULL, // WaitForKeyEx
SetState,
RegisterKeyNotify,
UnregisterKeyNotify,
};
//函数定义的地方,ReadKeyStroke 有具体的函数映射
EFI_STATUS
EFIAPI
ReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
{
KeyData->KeyState.KeyShiftState = 0;
KeyData->KeyState.KeyToggleState = 0;
return ReadKeyStroke (NULL, &KeyData->Key);
}
EFI_STATUS
EFIAPI
SimpleTextInOutEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT WaitKeyEvt;
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_CALLBACK,
WaitForKeyEvent,
NULL,
&WaitKeyEvt
);
ASSERT_EFI_ERROR (Status);
mSimpleTextIn.WaitForKey = WaitKeyEvt;
mSimpleTextInEx.WaitForKeyEx = WaitKeyEvt;
Status = gBS->InstallMultipleProtocolInterfaces(
&mInstallHandle,
&gEfiSimpleTextInProtocolGuid, &mSimpleTextIn,
&gEfiSimpleTextInputExProtocolGuid, &mSimpleTextInEx,
&gEfiSimpleTextOutProtocolGuid, &mSimpleTextOut,
&gEfiDevicePathProtocolGuid, &mDevicePath,
NULL
);
if (!EFI_ERROR (Status)) {
gST->ConOut = &mSimpleTextOut;
gST->ConIn = &mSimpleTextIn;
}
return Status;
}
boot_images/boot/QcomPkg/Library/ButtonsLib/ButtonsLib.c
EFI_STATUS PollPowerKey(BOOLEAN *pPowerKey)
{
EFI_STATUS Status = EFI_INVALID_PARAMETER;
Status = ReadRealTimeIRQStatus( EFI_PM_PON_IRQ_KPDPWR_ON, pPowerKey );
if ( EFI_ERROR (Status) )
{
DEBUG(( EFI_D_ERROR, "PollPowerKey: ReadRealTimeIRQStatus failed for Power Button, Status = (0x%x)\r\n", Status));
goto ErrorExit;
}
ErrorExit:
return Status;
}
键值映射:
ConvertEfiKeyCode函数
boot_images\boot\QcomPkg\Library\ButtonsLib\ButtonsLib.c
if( bVolUpKeyIsPressed && bVolDownKeyIsPressed )
{
// combo key found
EfiKey.ScanCode = SCAN_ESC;
}
else if( bCameraKeyIsPressed && bVolUpKeyIsPressed )
{
// combo key found
EfiKey.ScanCode = SCAN_HOME;
}
else if( bCameraKeyIsPressed && bVolDownKeyIsPressed )
{
// combo key found
EfiKey.ScanCode = SCAN_DELETE;
}
else if( bVolUpKeyIsPressed )
{
if( bPwrKeyPressed )
{
// combo key found
EfiKey.ScanCode = SCAN_HOME;
}
else
{
// single key found
EfiKey.ScanCode = SCAN_UP;
}
}
二、功能键调试
vendor/qcom/proprietary/devicetree/qcom/pmk8350.dtsi
pon_hlos@1300 {
compatible = "qcom,qpnp-power-on";
reg = <0x1300>, <0x800>;
reg-names = "pon_hlos", "pon_pbs";
interrupts = <0x0 0x13 0x7 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x13 0x6 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "kpdpwr", "resin";
qcom,kpdpwr-sw-debounce;
qcom,pon_1 {
qcom,pon-type = <PON_POWER_ON_TYPE_KPDPWR>;
qcom,pull-up = <1>;
linux,code = <KEY_POWER>;//具体键值 116 对应16进制0x74
qcom,support-reset = <1>;
qcom,s1-timer = <10256>;
qcom,s2-timer = <1000>;//debounce time = s1+s2=11s左右
qcom,s2-type = <7>;
};
qcom,pon_2 {
qcom,pon-type = <PON_POWER_ON_TYPE_RESIN>;
qcom,pull-up;
linux,code = <0x198>;//KEY_RESTART //具体键值 0x198就是16进制
qcom,support-reset = <1>;
qcom,s1-timer = <10256>;
qcom,s2-timer = <1000>;//debounce time = s1+s2=按11s左右重启
qcom,s2-type = <7>;
};
};
/*
qcom,support-reset:
0 表示不支持按power键进重启功能
1 表示支持
qcom,s1-timer:
qcom,s2-timer:
qcom,s2-type:
1 = WARM_RESET
4 = SHUTDOWN
5 = DVDD_SHUTDOWN
7 = HARD_RESET
8 = DVDD_HARD_RESET
The debounce timer for the BARK interrupt for that reset source. Value is specified in ms. Supported values are: 0, 32, 56, 80, 128, 184, 272, 408, 608, 904, 1352, 2048, 3072, 4480, 6720, 10256
qcom,s2-timer
The debounce timer for the S2 reset specified in ms. On the expiry of this timer, the PMIC executes the reset sequence. Supported values are: 0, 10, 50, 100, 250, 500, 1000, 2000
qcom,s2-type
The type of reset associated with this source. The supported resets are: SOFT(0), WARM(1), SHUTDOWN(4), HARD(7)
*/
kernel/msm-5.4/include/dt-bindings/input/qcom,qpnp-power-on.h
#define PON_POWER_ON_TYPE_KPDPWR 0
#define PON_POWER_ON_TYPE_RESIN 1
#define PON_POWER_ON_TYPE_CBLPWR 2
#define PON_POWER_ON_TYPE_KPDPWR_RESIN 3
/* PMIC PON peripheral physical power off types: */
#define PON_POWER_OFF_TYPE_WARM_RESET 0x01
#define PON_POWER_OFF_TYPE_SHUTDOWN 0x04
#define PON_POWER_OFF_TYPE_DVDD_SHUTDOWN 0x05
#define PON_POWER_OFF_TYPE_HARD_RESET 0x07
#define PON_POWER_OFF_TYPE_DVDD_HARD_RESET 0x08
\LA.UM.9.14.1\vendor\qcom\proprietary\devicetree\qcom\yupik-qrd.dtsi
gpio_keys {
compatible = "gpio-keys";
label = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&key_vol_up_default>,<&gpio_keys_active>;
home {
label = "home";
gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
linux,code = <KEY_HOME>;//102
linux,can-disable;
debounce-interval = <15>;
gpio-key,wakeup;
};
vol_up {
label = "volume_up";
gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
linux,code = <KEY_VOLUMEUP>;//键值
gpio-key,wakeup;
debounce-interval = <15>;
linux,can-disable;
};
vol_down {
label = "volume_down";
gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
linux,code = <KEY_VOLUMEDOWN>;
linux,can-disable;
debounce-interval = <15>;
gpio-key,wakeup;
};
};
vendor/qcom/proprietary/devicetree/qcom/yupik-pinctrl.dtsi
+ gpio_keys_active {
+ gpio_keys_active: gpio_keys_active {
+ mux {
+ pins = "gpio45", "gpio47";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio45", "gpio47";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+ };
+ gpio_keys_suspend {
+ gpio_keys_suspend: gpio_keys_suspend {
+ mux {
+ pins = "gpio45", "gpio47";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio45", "gpio47";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
如何DEBUG:
1.代码逻辑分析: 通过如下属性找到源码位置:compatible = "gpio-keys";
//kernel/msm-5.4/drivers/input/keyboard/gpio_keys.c
compatible = "qcom,qpnp-power-on";
//kernel/msm-5.4/drivers/input/misc/qpnp-power-on.c
//device/qcom/qssi/gpio-keys.kl
//frameworks/base/data/keyboards/Generic.kl
在老平台上修改dtsi后键值无功能,新平台未找到qpnp_pon.kl,gpio-key走的就是gpio-keys.kl,pon key 走的是?
device/google/atv/Generic.kl ---- 应该是它
device/amlogic/yukawa/Generic.kl—三方客制化的:
注:对于新加一个gpio-key的按键,在device/google/atv/Generic.kl 里有按键定义 也要在device/qcom/qssi/gpio-keys.kl 从新写一下,不然按键不起作用 getevent -l 里可以其作用 但是用的时候不起作用。
那么底层dtsi的键值怎么一步步映射到kl的呢?
kernel/msm-5.4/include/uapi/linux/input-event-codes.h
#define KEY_VOLUMEDOWN 114
//PON_POWER_ON_TYPE_KPDPWR 键参考上面的qcom,qpnp-power-on.h
device/qcom/qssi/gpio-keys.kl
key 115 VOLUME_UP
key 114 VOLUME_DOWN
key 102 HOME
key 528 FOCUS
key 766 CAMERA
device/google/atv/Generic.kl
key 116 POWER
frameworks/base/data/keyboards/Generic.kl
key 113 VOLUME_MUTE
key 114 VOLUME_DOWN
key 115 VOLUME_UP
key 116 POWER
2.DEBUG手法 以PWR键为例
C:\Users\Admin>adb shell
lahaina:/ # getevent
add device 1: /dev/input/event5
name: "lahaina-yupikidp-snd-card Button Jack"
add device 2: /dev/input/event4
name: "lahaina-yupikidp-snd-card Headset Jack"
add device 3: /dev/input/event3
name: "goodix-ts"
add device 4: /dev/input/event0
name: "qpnp_pon"
add device 5: /dev/input/event2
name: "gpio-keys"
add device 6: /dev/input/event1
name: "Typec_Headphone"
/dev/input/event0: 0001 0074 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0074 00000000
/dev/input/event0: 0000 0000 00000000
^C
130|lahaina:/ # getevent -l
add device 1: /dev/input/event5
name: "lahaina-yupikidp-snd-card Button Jack"
add device 2: /dev/input/event4
name: "lahaina-yupikidp-snd-card Headset Jack"
add device 3: /dev/input/event3
name: "goodix-ts"
add device 4: /dev/input/event0
name: "qpnp_pon"
add device 5: /dev/input/event2
name: "gpio-keys"
add device 6: /dev/input/event1
name: "Typec_Headphone"
/dev/input/event0: EV_KEY KEY_POWER DOWN
/dev/input/event0: EV_SYN SYN_REPORT 00000000
/dev/input/event0: EV_KEY KEY_POWER UP
/dev/input/event0: EV_SYN SYN_REPORT 00000000
130|lahaina:/ # ^C
130|lahaina:/ #
比如新加一个指纹,怎么看指纹的中断有没有加好,查看中断号:
cat /proc/interrupts ------- |grep finger、fpsensor、chipone、goodix
我们如何通过命令来input 按键呢?
input keyevent 26 (PWR键功能,底层咋是116呢?)
在下面的代码这里映射的:
frameworks/base/core/java/android/view/KeyEvent.java
public static final int KEYCODE_POWER = 26;
SM6125 平台关机短按power键就开机,改为长按开机:
+++ b/boot_images/QcomPkg/Library/PmicLib/app/pon/src/pm_app_key_press.c
@@ -67,6 +67,9 @@ pm_app_pwrkey_long_press_check(pm_pon_pwrkey_dbnc_chk_at_type dbnc_chk_at)
}
pmic_index = dbnc_chk->pmic_index;
+ /*yjc add for bug25957 start */
+ dbnc_chk->dbnc_time_msec = 2000;
+ /*yjc add for bug25957 end */
如何新建一个按键:
待更新:
底层逻辑
键值映射
定时器的应用
TP的键值功能?