Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental: Automatic power domain handling for displays/RGB #1775

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,16 @@ if ZMK_RGB_UNDERGLOW
config SPI
default y


config ZMK_RGB_UNDERGLOW_DEFAULT_POWER_DOMAIN
bool "Auto-assign the RGB underglow to the default power domain"
default y
depends on ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT

config ZMK_RGB_UNDERGLOW_EXT_POWER
bool "RGB underglow toggling also controls external power"
default y
depends on !ZMK_POWER_DOMAINS
Copy link
Contributor

@lesshonor lesshonor Feb 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
depends on !ZMK_POWER_DOMAINS
depends on ZMK_EXT_POWER

This suggestion builds on my previous one.


config ZMK_RGB_UNDERGLOW_BRT_MIN
int "RGB underglow minimum brightness in percent"
Expand Down Expand Up @@ -338,6 +345,7 @@ config ZMK_RGB_UNDERGLOW_AUTO_OFF_USB
bool "Turn off RGB underglow when USB is disconnected"
depends on USB_DEVICE_STACK


#ZMK_RGB_UNDERGLOW
endif

Expand Down Expand Up @@ -412,23 +420,37 @@ config ZMK_SLEEP
depends on HAS_POWEROFF
select POWEROFF
select ZMK_PM_DEVICE_SUSPEND_RESUME
select PM_DEVICE
imply USB

if ZMK_SLEEP

config PM_DEVICE
default y

config ZMK_IDLE_SLEEP_TIMEOUT
int "Milliseconds of inactivity before entering deep sleep"
depends on ZMK_SLEEP
default 900000

#ZMK_SLEEP
endif
config ZMK_POWER_DOMAINS
bool "Enable automatic power domain handling"
default n
select PM_DEVICE
select PM_DEVICE_POWER_DOMAIN
select PM_DEVICE_RUNTIME
select POWER_DOMAIN
select POWER_DOMAIN_GPIO

config ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
bool "Enable assigning peripherals to the chosen default power domain"
default n
depends on ZMK_POWER_DOMAINS
select PM_DEVICE_POWER_DOMAIN_DYNAMIC
select DEVICE_DEPS_DYNAMIC

# Default this to 2, the most common scenario for this for ZMK is RGB + OLED
config PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
default 2

config ZMK_EXT_POWER
bool "Enable support to control external power output"
default y
default y if !ZMK_POWER_DOMAINS
Copy link
Contributor

@lesshonor lesshonor Feb 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default y if !ZMK_POWER_DOMAINS
default y
depends on !ZMK_POWER_DOMAINS && DT_HAS_ZMK_EXT_POWER_GENERIC_ENABLED

Perhaps you know of some better way to wall this off for boards which don't have an external power cutoff? It's already a bit of a thorn in the side of STM32/RP2040.


config ZMK_PM
bool
Expand Down
4 changes: 4 additions & 0 deletions app/boards/arm/nice_nano/Kconfig.board
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

config BOARD_NICE_NANO
bool "nice!nano"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA

config BOARD_NICE_NANO_V2
bool "nice!nano v2"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA

61 changes: 32 additions & 29 deletions app/boards/arm/nice_nano/arduino_pro_micro_pins.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio0 8 0> /* D0 */
, <1 0 &gpio0 6 0> /* D1 */
, <2 0 &gpio0 17 0> /* D2 */
, <3 0 &gpio0 20 0> /* D3 */
, <4 0 &gpio0 22 0> /* D4/A6 */
, <5 0 &gpio0 24 0> /* D5 */
, <6 0 &gpio1 0 0> /* D6/A7 */
, <7 0 &gpio0 11 0> /* D7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
, <16 0 &gpio0 10 0> /* D16 */
, <14 0 &gpio1 11 0> /* D14 */
, <15 0 &gpio1 13 0> /* D15 */
, <18 0 &gpio1 15 0> /* D18/A0 */
, <19 0 &gpio0 2 0> /* D19/A1 */
, <20 0 &gpio0 29 0> /* D20/A2 */
, <21 0 &gpio0 31 0> /* D21/A3 */
;
= <0 0 &gpio0 8 0> /* D0 */
, <1 0 &gpio0 6 0> /* D1 */
, <2 0 &gpio0 17 0> /* D2 */
, <3 0 &gpio0 20 0> /* D3 */
, <4 0 &gpio0 22 0> /* D4/A6 */
, <5 0 &gpio0 24 0> /* D5 */
, <6 0 &gpio1 0 0> /* D6/A7 */
, <7 0 &gpio0 11 0> /* D7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
, <16 0 &gpio0 10 0> /* D16 */
, <14 0 &gpio1 11 0> /* D14 */
, <15 0 &gpio1 13 0> /* D15 */
, <18 0 &gpio1 15 0> /* D18/A0 */
, <19 0 &gpio0 2 0> /* D19/A1 */
, <20 0 &gpio0 29 0> /* D20/A2 */
, <21 0 &gpio0 31 0> /* D21/A3 */
;
};

pro_micro_a: connector_a {
Expand All @@ -38,20 +38,23 @@
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio1 15 0> /* D18/A0 */
, <1 0 &gpio0 2 0> /* D19/A1 */
, <2 0 &gpio0 29 0> /* D20/A2 */
, <3 0 &gpio0 31 0> /* D21/A3 */
, <6 0 &gpio0 22 0> /* D4/A6 */
, <7 0 &gpio1 0 0> /* D6/A7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
;
= <0 0 &gpio1 15 0> /* D18/A0 */
, <1 0 &gpio0 2 0> /* D19/A1 */
, <2 0 &gpio0 29 0> /* D20/A2 */
, <3 0 &gpio0 31 0> /* D21/A3 */
, <6 0 &gpio0 22 0> /* D4/A6 */
, <7 0 &gpio1 0 0> /* D6/A7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
;
};
};

pro_micro_d: &pro_micro {};
pro_micro_i2c: &i2c0 {};
pro_micro_spi: &spi1 {};
pro_micro_serial: &uart0 {};

pro_micro_power_domain: &core_power_domain {};

13 changes: 9 additions & 4 deletions app/boards/arm/nice_nano/nice_nano.dts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
/ {
chosen {
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

// Node name must match original "EXT_POWER" label to preserve user settings.
EXT_POWER {
compatible = "zmk,ext-power-generic";
control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
Expand All @@ -25,3 +28,5 @@
full-ohms = <(2000000 + 806000)>;
};
};

#include "arduino_pro_micro_pins.dtsi"
1 change: 0 additions & 1 deletion app/boards/arm/nice_nano/nice_nano.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include <nordic/nrf52840_qiaa.dtsi>
#include "nice_nano-pinctrl.dtsi"
#include "arduino_pro_micro_pins.dtsi"

/ {
model = "nice!nano";
Expand Down
14 changes: 9 additions & 5 deletions app/boards/arm/nice_nano/nice_nano_v2.dts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@
/ {
chosen {
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

// Node name must match original "EXT_POWER" label to preserve user settings.
EXT_POWER {
compatible = "zmk,ext-power-generic";
control-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
init-delay-ms = <50>;
core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
compatible = "zmk,battery-nrf-vddh";
};
};

#include "arduino_pro_micro_pins.dtsi"
2 changes: 2 additions & 0 deletions app/boards/arm/puchi_ble/Kconfig.board
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

config BOARD_PUCHI_BLE_v1
bool "puchi_ble_v1"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA
2 changes: 2 additions & 0 deletions app/boards/arm/puchi_ble/arduino_pro_micro_pins.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ pro_micro_d: &pro_micro {};
pro_micro_i2c: &i2c0 {};
pro_micro_spi: &spi0 {};
pro_micro_serial: &uart0 {};

pro_micro_power_domain: &core_power_domain {};
15 changes: 13 additions & 2 deletions app/boards/arm/puchi_ble/puchi_ble_v1.dts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "arduino_pro_micro_pins.dtsi"
#include "puchi_ble_v1-pinctrl.dtsi"

/ {
Expand All @@ -18,6 +17,7 @@
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

leds {
Expand All @@ -33,6 +33,14 @@
control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};

core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
compatible = "zmk,battery-voltage-divider";
io-channels = <&adc 2>;
Expand Down Expand Up @@ -79,7 +87,7 @@ zephyr_udc0: &usbd {
&flash0 {
/*
* For more information, see:
* http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
* http: //docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* http: //docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
* http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html

*/
partitions {
compatible = "fixed-partitions";
Expand Down Expand Up @@ -111,3 +119,6 @@ zephyr_udc0: &usbd {
};
};
};

// Included at the end to ensure the power domain DTS node exists
#include "arduino_pro_micro_pins.dtsi"
11 changes: 11 additions & 0 deletions app/boards/shields/zmk_uno/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

if SHIELD_ZMK_UNO_BASE

config SHIELD_ZMK_UNO_PM
bool "ZMK Uno Automatic Power Management"
default y
select ZMK_POWER_DOMAINS
select ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
select PM_DEVICE
select PM_DEVICE_POWER_DOMAIN
select PM_DEVICE_RUNTIME
select POWER_DOMAIN
select POWER_DOMAIN_GPIO

config ZMK_KEYBOARD_NAME
default "ZMK Uno"

Expand Down
1 change: 1 addition & 0 deletions app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_ZMK_POWER_DOMAINS=y
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ encoder: &qdec0 {

wakeup-sources = <&soft_off_direct_kscan>;
};
};
};
37 changes: 26 additions & 11 deletions app/boards/shields/zmk_uno/zmk_uno.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ nice_view_spi: &arduino_spi {
// on the bus, properly picking up the first `cs-gpios` specifier.
ls0xx@0 {
reg = <0>;

power-domain = <&core_power_domain>;
zephyr,pm-device-runtime-auto;
};

led_strip: ws2812@0 {
compatible = "worldsemi,ws2812-spi";

power-domain = <&rgb_power>;
zephyr,pm-device-runtime-auto;

/* SPI */
reg = <0>; /* ignored, but necessary for SPI bindings */
spi-max-frequency = <4000000>;
Expand All @@ -35,26 +41,35 @@ nice_view_spi: &arduino_spi {
spi-zero-frame = <0x40>;

color-mapping = <LED_COLOR_ID_GREEN LED_COLOR_ID_RED LED_COLOR_ID_BLUE>;

};
};

/ {
chosen {
zmk,backlight = &backlight;
zmk,underglow = &led_strip;
zephyr,display = &oled;
zmk,display-default-power-domain = &core_power_domain;
};

core_power_domain: core_power_domain {
// The "power-domain" compatible is needed for any PDs used for that have dynamic deps,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The "power-domain" compatible is needed for any PDs used for that have dynamic deps,
// The "power-domain" compatible is needed for any PDs which have dynamic deps,

// e.g. for displays or RGB not assigned to the PD in the devicetree statically.
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <2000>;
off-on-delay-us = <2000>;
enable-gpios = <&arduino_header 0 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

// Commented out until we add more powerful power domain support
// external_power {
// compatible = "zmk,ext-power-generic";
// init-delay-ms = <200>;
// control-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
// };

rgb_power {
compatible = "zmk,ext-power-generic";
init-delay-ms = <200>;
control-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
rgb_power: rgb_power {
compatible = "power-domain-gpio";
startup-delay-us = <200>;
off-on-delay-us = <2000>;
enable-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
power-domain = <&core_power_domain>;
zephyr,pm-device-runtime-auto;
};

backlight: gpioleds {
Expand Down
1 change: 1 addition & 0 deletions app/module/drivers/kscan/kscan_gpio_direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/sys/util.h>

#include <zmk/debounce.h>
Expand Down
1 change: 1 addition & 0 deletions app/module/drivers/kscan/kscan_gpio_matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/kscan.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/__assert.h>
Expand Down
Loading
Loading