diff mbox series

[v5,3/9] mach-snapdragon: switch to PMIC button driver

Message ID 20231130-b4-qcom-dt-compat-v5-3-41500e237ad0@linaro.org
State Superseded
Headers show
Series Qualcomm PMIC fixes | expand

Commit Message

Caleb Connolly Nov. 30, 2023, 8:22 p.m. UTC
The PMIC button driver is a much better representation of the hardware
here, adjust the boards to use upstream DT and the PMIC button driver
instead of exposing the buttons as GPIOs and relying on the GPIO-button
driver.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 arch/arm/dts/dragonboard410c-uboot.dtsi          | 11 ------
 arch/arm/dts/dragonboard410c.dts                 | 22 +++++++++---
 arch/arm/dts/dragonboard820c-uboot.dtsi          | 12 -------
 arch/arm/dts/dragonboard820c.dts                 | 23 ++++++++----
 arch/arm/dts/dragonboard845c-uboot.dtsi          | 11 ------
 arch/arm/dts/dragonboard845c.dts                 |  4 +++
 arch/arm/dts/sdm845.dtsi                         | 23 +++++++++---
 arch/arm/dts/starqltechn-uboot.dtsi              | 10 ------
 arch/arm/dts/starqltechn.dts                     | 20 +++--------
 arch/arm/mach-snapdragon/Kconfig                 |  3 ++
 arch/arm/mach-snapdragon/init_sdm845.c           | 45 +++++-------------------
 board/qualcomm/dragonboard410c/dragonboard410c.c | 31 ++++++----------
 board/qualcomm/dragonboard820c/dragonboard820c.c | 29 +++++----------
 13 files changed, 91 insertions(+), 153 deletions(-)

Comments

Neil Armstrong Dec. 1, 2023, 9:33 a.m. UTC | #1
On 30/11/2023 21:22, Caleb Connolly wrote:
> The PMIC button driver is a much better representation of the hardware
> here, adjust the boards to use upstream DT and the PMIC button driver
> instead of exposing the buttons as GPIOs and relying on the GPIO-button
> driver.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>   arch/arm/dts/dragonboard410c-uboot.dtsi          | 11 ------
>   arch/arm/dts/dragonboard410c.dts                 | 22 +++++++++---
>   arch/arm/dts/dragonboard820c-uboot.dtsi          | 12 -------
>   arch/arm/dts/dragonboard820c.dts                 | 23 ++++++++----
>   arch/arm/dts/dragonboard845c-uboot.dtsi          | 11 ------
>   arch/arm/dts/dragonboard845c.dts                 |  4 +++
>   arch/arm/dts/sdm845.dtsi                         | 23 +++++++++---
>   arch/arm/dts/starqltechn-uboot.dtsi              | 10 ------
>   arch/arm/dts/starqltechn.dts                     | 20 +++--------
>   arch/arm/mach-snapdragon/Kconfig                 |  3 ++
>   arch/arm/mach-snapdragon/init_sdm845.c           | 45 +++++-------------------
>   board/qualcomm/dragonboard410c/dragonboard410c.c | 31 ++++++----------
>   board/qualcomm/dragonboard820c/dragonboard820c.c | 29 +++++----------
>   13 files changed, 91 insertions(+), 153 deletions(-)
> 
> diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi
> index 3b0bd0ed0a1b..cec64bf80f99 100644
> --- a/arch/arm/dts/dragonboard410c-uboot.dtsi
> +++ b/arch/arm/dts/dragonboard410c-uboot.dtsi
> @@ -42,14 +42,3 @@
>   		gpios = <&pm8916_gpios 3 0>;
>   	};
>   };
> -
> -
> -&pm8916_pon {
> -	key_vol_down {
> -		gpios = <&pm8916_pon 1 0>;
> -	};
> -
> -	key_power {
> -		gpios = <&pm8916_pon 0 0>;
> -	};
> -};
> diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
> index 9230dd3fd96c..c41fee977813 100644
> --- a/arch/arm/dts/dragonboard410c.dts
> +++ b/arch/arm/dts/dragonboard410c.dts
> @@ -147,11 +147,23 @@
>   				#address-cells = <0x1>;
>   				#size-cells = <0x1>;
>   
> -				pm8916_pon: pm8916_pon@800 {
> -					compatible = "qcom,pm8916-pwrkey";
> -					reg = <0x800 0x96>;
> -					#gpio-cells = <2>;
> -					gpio-controller;
> +				pon@800 {
> +					compatible = "qcom,pm8916-pon";
> +					reg = <0x800 0x100>;
> +					mode-bootloader = <0x2>;
> +					mode-recovery = <0x1>;
> +
> +					pwrkey {
> +						compatible = "qcom,pm8941-pwrkey";
> +						debounce = <15625>;
> +						bias-pull-up;
> +					};
> +
> +					pm8916_resin: resin {
> +						compatible = "qcom,pm8941-resin";
> +						debounce = <15625>;
> +						bias-pull-up;
> +					};
>   				};
>   
>   				pm8916_gpios: pm8916_gpios@c000 {
> diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
> index 457728a43ecb..d93c7c1fbdee 100644
> --- a/arch/arm/dts/dragonboard820c-uboot.dtsi
> +++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
> @@ -30,15 +30,3 @@
>   		};
>   	};
>   };
> -
> -&pm8994_pon {
> -	key_vol_down {
> -		gpios = <&pm8994_pon 1 0>;
> -		label = "key_vol_down";
> -	};
> -
> -	key_power {
> -		gpios = <&pm8994_pon 0 0>;
> -		label = "key_power";
> -	};
> -};
> diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
> index ad201d48749c..0d9c9f7a4922 100644
> --- a/arch/arm/dts/dragonboard820c.dts
> +++ b/arch/arm/dts/dragonboard820c.dts
> @@ -109,12 +109,23 @@
>   				#address-cells = <0x1>;
>   				#size-cells = <0x1>;
>   
> -				pm8994_pon: pm8994_pon@800 {
> -					compatible = "qcom,pm8994-pwrkey";
> -					reg = <0x800 0x96>;
> -					#gpio-cells = <2>;
> -					gpio-controller;
> -					gpio-bank-name="pm8994_key.";
> +				pm8994_pon: pon@800 {
> +					compatible = "qcom,pm8916-pon";
> +					reg = <0x800 0x100>;
> +					mode-bootloader = <0x2>;
> +					mode-recovery = <0x1>;
> +
> +					pwrkey {
> +						compatible = "qcom,pm8941-pwrkey";
> +						debounce = <15625>;
> +						bias-pull-up;
> +					};
> +
> +					pm8994_resin: resin {
> +						compatible = "qcom,pm8941-resin";
> +						debounce = <15625>;
> +						bias-pull-up;
> +					};
>   				};
>   
>   				pm8994_gpios: pm8994_gpios@c000 {
> diff --git a/arch/arm/dts/dragonboard845c-uboot.dtsi b/arch/arm/dts/dragonboard845c-uboot.dtsi
> index 7728f4f4a3e5..775f45c0149f 100644
> --- a/arch/arm/dts/dragonboard845c-uboot.dtsi
> +++ b/arch/arm/dts/dragonboard845c-uboot.dtsi
> @@ -24,14 +24,3 @@
>   		};
>   	};
>   };
> -
> -&pm8998_pon {
> -	key_vol_down {
> -		gpios = <&pm8998_pon 1 0>;
> -		label = "key_vol_down";
> -	};
> -	key_power {
> -		gpios = <&pm8998_pon 0 0>;
> -		label = "key_power";
> -	};
> -};
> diff --git a/arch/arm/dts/dragonboard845c.dts b/arch/arm/dts/dragonboard845c.dts
> index b4f057ac6537..054f253eb32a 100644
> --- a/arch/arm/dts/dragonboard845c.dts
> +++ b/arch/arm/dts/dragonboard845c.dts
> @@ -41,4 +41,8 @@
>   	};
>   };
>   
> +&pm8998_resin {
> +	status = "okay";
> +};
> +
>   #include "dragonboard845c-uboot.dtsi"
> diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi
> index 4798ace0ff8b..cd5d890e9a45 100644
> --- a/arch/arm/dts/sdm845.dtsi
> +++ b/arch/arm/dts/sdm845.dtsi
> @@ -78,12 +78,25 @@
>   				#address-cells = <0x1>;
>   				#size-cells = <0x1>;
>   
> -				pm8998_pon: pm8998_pon@800 {
> -					compatible = "qcom,pm8998-pwrkey";
> +				pm8998_pon: pon@800 {
> +					compatible = "qcom,pm8998-pon";
> +
>   					reg = <0x800 0x100>;
> -					#gpio-cells = <2>;
> -					gpio-controller;
> -					gpio-bank-name = "pm8998_key.";
> +					mode-bootloader = <0x2>;
> +					mode-recovery = <0x1>;
> +
> +					pm8998_pwrkey: pwrkey {
> +						compatible = "qcom,pm8941-pwrkey";
> +						debounce = <15625>;
> +						bias-pull-up;
> +					};
> +
> +					pm8998_resin: resin {
> +						compatible = "qcom,pm8941-resin";
> +						debounce = <15625>;
> +						bias-pull-up;
> +						status = "disabled";
> +					};
>   				};
>   
>   				pm8998_gpios: pm8998_gpios@c000 {
> diff --git a/arch/arm/dts/starqltechn-uboot.dtsi b/arch/arm/dts/starqltechn-uboot.dtsi
> index 034d5c1c07ed..55c6d18412ba 100644
> --- a/arch/arm/dts/starqltechn-uboot.dtsi
> +++ b/arch/arm/dts/starqltechn-uboot.dtsi
> @@ -25,13 +25,3 @@
>   	};
>   };
>   
> -&pm8998_pon {
> -	key_vol_down {
> -		gpios = <&pm8998_pon 1 0>;
> -		label = "key_vol_down";
> -	};
> -	key_power {
> -		gpios = <&pm8998_pon 0 0>;
> -		label = "key_power";
> -	};
> -};
> diff --git a/arch/arm/dts/starqltechn.dts b/arch/arm/dts/starqltechn.dts
> index 5b6372bee79a..0842e19adb60 100644
> --- a/arch/arm/dts/starqltechn.dts
> +++ b/arch/arm/dts/starqltechn.dts
> @@ -45,22 +45,6 @@
>   		format = "a8r8g8b8";
>   	};
>   
> -	gpio-keys {
> -		compatible = "gpio-keys";
> -
> -		key-pwr {
> -			label = "Power";
> -			linux,code = <KEY_ENTER>;
> -			gpios = <&pm8998_pon 0 GPIO_ACTIVE_LOW>;
> -		};
> -
> -		key-vol-down {
> -			label = "Volume Down";
> -			linux,code = <KEY_DOWN>;
> -			gpios = <&pm8998_pon 1 GPIO_ACTIVE_LOW>;
> -		};
> -	};
> -
>   	soc: soc {
>   		serial@a84000 {
>   			status = "okay";
> @@ -68,6 +52,10 @@
>   	};
>   };
>   
> +&pm8998_resin {
> +	status = "okay";
> +};
> +
>   &tlmm {
>   	muic_i2c: muic-i2c-n {
>   		pins = "GPIO_33", "GPIO_34";
> diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
> index 3c9f3bee3f18..ad6671081910 100644
> --- a/arch/arm/mach-snapdragon/Kconfig
> +++ b/arch/arm/mach-snapdragon/Kconfig
> @@ -17,6 +17,7 @@ config SDM845
>   	select LINUX_KERNEL_IMAGE_HEADER
>   	imply CLK_QCOM_SDM845
>   	imply PINCTRL_QCOM_SDM845
> +	imply BUTTON_QCOM_PMIC
>   
>   config LNX_KRNL_IMG_TEXT_OFFSET_BASE
>   	default 0x80000000
> @@ -30,6 +31,7 @@ config TARGET_DRAGONBOARD410C
>   	select ENABLE_ARM_SOC_BOOT0_HOOK
>   	imply CLK_QCOM_APQ8016
>   	imply PINCTRL_QCOM_APQ8016
> +	imply BUTTON_QCOM_PMIC
>   	help
>   	  Support for 96Boards Dragonboard 410C. This board complies with
>   	  96Board Open Platform Specifications. Features:
> @@ -45,6 +47,7 @@ config TARGET_DRAGONBOARD820C
>   	bool "96Boards Dragonboard 820C"
>   	imply CLK_QCOM_APQ8096
>   	imply PINCTRL_QCOM_APQ8096
> +	imply BUTTON_QCOM_PMIC
>   	help
>   	  Support for 96Boards Dragonboard 820C. This board complies with
>   	  96Board Open Platform Specifications. Features:
> diff --git a/arch/arm/mach-snapdragon/init_sdm845.c b/arch/arm/mach-snapdragon/init_sdm845.c
> index 1f8850239437..067acc9a6f44 100644
> --- a/arch/arm/mach-snapdragon/init_sdm845.c
> +++ b/arch/arm/mach-snapdragon/init_sdm845.c
> @@ -5,6 +5,7 @@
>    * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
>    */
>   
> +#include <button.h>
>   #include <init.h>
>   #include <env.h>
>   #include <common.h>
> @@ -32,46 +33,18 @@ __weak int board_init(void)
>   /* Check for vol- and power buttons */
>   __weak int misc_init_r(void)
>   {
> -	struct udevice *pon;
> -	struct gpio_desc resin;
> -	int node, ret;
> +	struct udevice *btn;
> +	int ret;
> +	enum button_state_t state;
>   
> -	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8998_pon@800", &pon);
> +	ret = button_get_by_label("pwrkey", &btn);
>   	if (ret < 0) {
> -		printf("Failed to find PMIC pon node. Check device tree\n");
> -		return 0;
> +		printf("Couldn't find power button!\n");
> +		return ret;
>   	}
>   
> -	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
> -				  "key_vol_down");
> -	if (node < 0) {
> -		printf("Failed to find key_vol_down node. Check device tree\n");
> -		return 0;
> -	}
> -	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
> -				       &resin, 0)) {
> -		printf("Failed to request key_vol_down button.\n");
> -		return 0;
> -	}
> -	if (dm_gpio_get_value(&resin)) {
> -		env_set("key_vol_down", "1");
> -		printf("Volume down button pressed\n");
> -	} else {
> -		env_set("key_vol_down", "0");
> -	}
> -
> -	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
> -				  "key_power");
> -	if (node < 0) {
> -		printf("Failed to find key_power node. Check device tree\n");
> -		return 0;
> -	}
> -	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
> -				       &resin, 0)) {
> -		printf("Failed to request key_power button.\n");
> -		return 0;
> -	}
> -	if (dm_gpio_get_value(&resin)) {
> +	state = button_get_state(btn);
> +	if (state == BUTTON_ON) {
>   		env_set("key_power", "1");
>   		printf("Power button pressed\n");
>   	} else {
> diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
> index 371b3262f8c5..350e0e9e20aa 100644
> --- a/board/qualcomm/dragonboard410c/dragonboard410c.c
> +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
> @@ -5,6 +5,7 @@
>    * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
>    */
>   
> +#include <button.h>
>   #include <common.h>
>   #include <cpu_func.h>
>   #include <dm.h>
> @@ -108,32 +109,20 @@ int board_usb_init(int index, enum usb_init_type init)
>   /* Check for vol- button - if pressed - stop autoboot */
>   int misc_init_r(void)
>   {
> -	struct udevice *pon;
> -	struct gpio_desc resin;
> -	int node, ret;
> +	struct udevice *btn;
> +	int ret;
> +	enum button_state_t state;
>   
> -	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon);
> +	ret = button_get_by_label("vol_down", &btn);
>   	if (ret < 0) {
> -		printf("Failed to find PMIC pon node. Check device tree\n");
> -		return 0;
> +		printf("Couldn't find power button!\n");
> +		return ret;
>   	}
>   
> -	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
> -				  "key_vol_down");
> -	if (node < 0) {
> -		printf("Failed to find key_vol_down node. Check device tree\n");
> -		return 0;
> -	}
> -
> -	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
> -				       &resin, 0)) {
> -		printf("Failed to request key_vol_down button.\n");
> -		return 0;
> -	}
> -
> -	if (dm_gpio_get_value(&resin)) {
> +	state = button_get_state(btn);
> +	if (state == BUTTON_ON) {
>   		env_set("preboot", "setenv preboot; fastboot 0");
> -		printf("key_vol_down pressed - Starting fastboot.\n");
> +		printf("vol_down pressed - Starting fastboot.\n");
>   	}
>   
>   	return 0;
> diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c
> index 6785bf58e949..2f0db628368b 100644
> --- a/board/qualcomm/dragonboard820c/dragonboard820c.c
> +++ b/board/qualcomm/dragonboard820c/dragonboard820c.c
> @@ -5,6 +5,7 @@
>    * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
>    */
>   
> +#include <button.h>
>   #include <cpu_func.h>
>   #include <init.h>
>   #include <env.h>
> @@ -139,30 +140,18 @@ void reset_cpu(void)
>   /* Check for vol- button - if pressed - stop autoboot */
>   int misc_init_r(void)
>   {
> -	struct udevice *pon;
> -	struct gpio_desc resin;
> -	int node, ret;
> +	struct udevice *btn;
> +	int ret;
> +	enum button_state_t state;
>   
> -	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon);
> +	ret = button_get_by_label("pwrkey", &btn);
>   	if (ret < 0) {
> -		printf("Failed to find PMIC pon node. Check device tree\n");
> -		return 0;
> +		printf("Couldn't find power button!\n");
> +		return ret;
>   	}
>   
> -	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
> -				  "key_vol_down");
> -	if (node < 0) {
> -		printf("Failed to find key_vol_down node. Check device tree\n");
> -		return 0;
> -	}
> -
> -	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
> -				       &resin, 0)) {
> -		printf("Failed to request key_vol_down button.\n");
> -		return 0;
> -	}
> -
> -	if (dm_gpio_get_value(&resin)) {
> +	state = button_get_state(btn);
> +	if (state == BUTTON_ON) {
>   		env_set("bootdelay", "-1");
>   		printf("Power button pressed - dropping to console.\n");
>   	}
> 

Looks good:
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
diff mbox series

Patch

diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi
index 3b0bd0ed0a1b..cec64bf80f99 100644
--- a/arch/arm/dts/dragonboard410c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard410c-uboot.dtsi
@@ -42,14 +42,3 @@ 
 		gpios = <&pm8916_gpios 3 0>;
 	};
 };
-
-
-&pm8916_pon {
-	key_vol_down {
-		gpios = <&pm8916_pon 1 0>;
-	};
-
-	key_power {
-		gpios = <&pm8916_pon 0 0>;
-	};
-};
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
index 9230dd3fd96c..c41fee977813 100644
--- a/arch/arm/dts/dragonboard410c.dts
+++ b/arch/arm/dts/dragonboard410c.dts
@@ -147,11 +147,23 @@ 
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8916_pon: pm8916_pon@800 {
-					compatible = "qcom,pm8916-pwrkey";
-					reg = <0x800 0x96>;
-					#gpio-cells = <2>;
-					gpio-controller;
+				pon@800 {
+					compatible = "qcom,pm8916-pon";
+					reg = <0x800 0x100>;
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8916_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+					};
 				};
 
 				pm8916_gpios: pm8916_gpios@c000 {
diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
index 457728a43ecb..d93c7c1fbdee 100644
--- a/arch/arm/dts/dragonboard820c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
@@ -30,15 +30,3 @@ 
 		};
 	};
 };
-
-&pm8994_pon {
-	key_vol_down {
-		gpios = <&pm8994_pon 1 0>;
-		label = "key_vol_down";
-	};
-
-	key_power {
-		gpios = <&pm8994_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
index ad201d48749c..0d9c9f7a4922 100644
--- a/arch/arm/dts/dragonboard820c.dts
+++ b/arch/arm/dts/dragonboard820c.dts
@@ -109,12 +109,23 @@ 
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8994_pon: pm8994_pon@800 {
-					compatible = "qcom,pm8994-pwrkey";
-					reg = <0x800 0x96>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					gpio-bank-name="pm8994_key.";
+				pm8994_pon: pon@800 {
+					compatible = "qcom,pm8916-pon";
+					reg = <0x800 0x100>;
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8994_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+					};
 				};
 
 				pm8994_gpios: pm8994_gpios@c000 {
diff --git a/arch/arm/dts/dragonboard845c-uboot.dtsi b/arch/arm/dts/dragonboard845c-uboot.dtsi
index 7728f4f4a3e5..775f45c0149f 100644
--- a/arch/arm/dts/dragonboard845c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard845c-uboot.dtsi
@@ -24,14 +24,3 @@ 
 		};
 	};
 };
-
-&pm8998_pon {
-	key_vol_down {
-		gpios = <&pm8998_pon 1 0>;
-		label = "key_vol_down";
-	};
-	key_power {
-		gpios = <&pm8998_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/dragonboard845c.dts b/arch/arm/dts/dragonboard845c.dts
index b4f057ac6537..054f253eb32a 100644
--- a/arch/arm/dts/dragonboard845c.dts
+++ b/arch/arm/dts/dragonboard845c.dts
@@ -41,4 +41,8 @@ 
 	};
 };
 
+&pm8998_resin {
+	status = "okay";
+};
+
 #include "dragonboard845c-uboot.dtsi"
diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi
index 4798ace0ff8b..cd5d890e9a45 100644
--- a/arch/arm/dts/sdm845.dtsi
+++ b/arch/arm/dts/sdm845.dtsi
@@ -78,12 +78,25 @@ 
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8998_pon: pm8998_pon@800 {
-					compatible = "qcom,pm8998-pwrkey";
+				pm8998_pon: pon@800 {
+					compatible = "qcom,pm8998-pon";
+
 					reg = <0x800 0x100>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					gpio-bank-name = "pm8998_key.";
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pm8998_pwrkey: pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8998_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+						status = "disabled";
+					};
 				};
 
 				pm8998_gpios: pm8998_gpios@c000 {
diff --git a/arch/arm/dts/starqltechn-uboot.dtsi b/arch/arm/dts/starqltechn-uboot.dtsi
index 034d5c1c07ed..55c6d18412ba 100644
--- a/arch/arm/dts/starqltechn-uboot.dtsi
+++ b/arch/arm/dts/starqltechn-uboot.dtsi
@@ -25,13 +25,3 @@ 
 	};
 };
 
-&pm8998_pon {
-	key_vol_down {
-		gpios = <&pm8998_pon 1 0>;
-		label = "key_vol_down";
-	};
-	key_power {
-		gpios = <&pm8998_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/starqltechn.dts b/arch/arm/dts/starqltechn.dts
index 5b6372bee79a..0842e19adb60 100644
--- a/arch/arm/dts/starqltechn.dts
+++ b/arch/arm/dts/starqltechn.dts
@@ -45,22 +45,6 @@ 
 		format = "a8r8g8b8";
 	};
 
-	gpio-keys {
-		compatible = "gpio-keys";
-
-		key-pwr {
-			label = "Power";
-			linux,code = <KEY_ENTER>;
-			gpios = <&pm8998_pon 0 GPIO_ACTIVE_LOW>;
-		};
-
-		key-vol-down {
-			label = "Volume Down";
-			linux,code = <KEY_DOWN>;
-			gpios = <&pm8998_pon 1 GPIO_ACTIVE_LOW>;
-		};
-	};
-
 	soc: soc {
 		serial@a84000 {
 			status = "okay";
@@ -68,6 +52,10 @@ 
 	};
 };
 
+&pm8998_resin {
+	status = "okay";
+};
+
 &tlmm {
 	muic_i2c: muic-i2c-n {
 		pins = "GPIO_33", "GPIO_34";
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index 3c9f3bee3f18..ad6671081910 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -17,6 +17,7 @@  config SDM845
 	select LINUX_KERNEL_IMAGE_HEADER
 	imply CLK_QCOM_SDM845
 	imply PINCTRL_QCOM_SDM845
+	imply BUTTON_QCOM_PMIC
 
 config LNX_KRNL_IMG_TEXT_OFFSET_BASE
 	default 0x80000000
@@ -30,6 +31,7 @@  config TARGET_DRAGONBOARD410C
 	select ENABLE_ARM_SOC_BOOT0_HOOK
 	imply CLK_QCOM_APQ8016
 	imply PINCTRL_QCOM_APQ8016
+	imply BUTTON_QCOM_PMIC
 	help
 	  Support for 96Boards Dragonboard 410C. This board complies with
 	  96Board Open Platform Specifications. Features:
@@ -45,6 +47,7 @@  config TARGET_DRAGONBOARD820C
 	bool "96Boards Dragonboard 820C"
 	imply CLK_QCOM_APQ8096
 	imply PINCTRL_QCOM_APQ8096
+	imply BUTTON_QCOM_PMIC
 	help
 	  Support for 96Boards Dragonboard 820C. This board complies with
 	  96Board Open Platform Specifications. Features:
diff --git a/arch/arm/mach-snapdragon/init_sdm845.c b/arch/arm/mach-snapdragon/init_sdm845.c
index 1f8850239437..067acc9a6f44 100644
--- a/arch/arm/mach-snapdragon/init_sdm845.c
+++ b/arch/arm/mach-snapdragon/init_sdm845.c
@@ -5,6 +5,7 @@ 
  * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
  */
 
+#include <button.h>
 #include <init.h>
 #include <env.h>
 #include <common.h>
@@ -32,46 +33,18 @@  __weak int board_init(void)
 /* Check for vol- and power buttons */
 __weak int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8998_pon@800", &pon);
+	ret = button_get_by_label("pwrkey", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
-	}
-	if (dm_gpio_get_value(&resin)) {
-		env_set("key_vol_down", "1");
-		printf("Volume down button pressed\n");
-	} else {
-		env_set("key_vol_down", "0");
-	}
-
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_power");
-	if (node < 0) {
-		printf("Failed to find key_power node. Check device tree\n");
-		return 0;
-	}
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_power button.\n");
-		return 0;
-	}
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("key_power", "1");
 		printf("Power button pressed\n");
 	} else {
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 371b3262f8c5..350e0e9e20aa 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -5,6 +5,7 @@ 
  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
  */
 
+#include <button.h>
 #include <common.h>
 #include <cpu_func.h>
 #include <dm.h>
@@ -108,32 +109,20 @@  int board_usb_init(int index, enum usb_init_type init)
 /* Check for vol- button - if pressed - stop autoboot */
 int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon);
+	ret = button_get_by_label("vol_down", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
-	}
-
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("preboot", "setenv preboot; fastboot 0");
-		printf("key_vol_down pressed - Starting fastboot.\n");
+		printf("vol_down pressed - Starting fastboot.\n");
 	}
 
 	return 0;
diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c
index 6785bf58e949..2f0db628368b 100644
--- a/board/qualcomm/dragonboard820c/dragonboard820c.c
+++ b/board/qualcomm/dragonboard820c/dragonboard820c.c
@@ -5,6 +5,7 @@ 
  * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
  */
 
+#include <button.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <env.h>
@@ -139,30 +140,18 @@  void reset_cpu(void)
 /* Check for vol- button - if pressed - stop autoboot */
 int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon);
+	ret = button_get_by_label("pwrkey", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
-	}
-
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("bootdelay", "-1");
 		printf("Power button pressed - dropping to console.\n");
 	}