QCM6490 按键调试

前言:

首先我们这个项目有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的键值功能?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
QCM6490启动流程梳理: QCM6490是一种启动流程的处理器芯片,它具有一系列的启动流程。 首先,当电源被打开时,芯片进入到Reset状态,在这个状态下,芯片的所有寄存器、电路和功能都被重置为初始状态。接下来,芯片进入到Boot ROM的阶段,Boot ROM是一个存储器模块,其中包含了初始化引导程序的代码。引导程序的主要功能是加载操作系统和其他应用程序。 引导程序被加载完成后,芯片进入到初始化硬件的阶段。在这个阶段,芯片会对各种硬件组件进行初始化设置,例如外设接口、存储器控制器和时钟模块等。 接着,芯片进入到加载操作系统的阶段。操作系统通常存储在外部存储器中,如闪存或SD卡。在这个阶段,芯片会通过外设接口加载操作系统的代码和数据,并将控制权交给操作系统。 一旦操作系统加载完成,芯片进入到操作系统启动的阶段。在这个阶段,操作系统会初始化各种系统服务和设备驱动程序,为用户程序和应用程序提供运行环境。同时,操作系统也会监控芯片的各种状态和响应用户的指令。 最后,芯片进入到用户程序的运行阶段。在这个阶段,用户程序和应用程序可以与芯片进行交互,执行各种任务和功能。芯片的启动流程到此结束。 总体来说,QCM6490的启动流程包括重置芯片、加载引导程序、初始化硬件、加载操作系统和启动操作系统等几个关键步骤。这个流程确保了芯片在启动时的正常运行,并为用户提供一个良好的使用环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨染天姬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值