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

feat(boards): M60 keyboard use back button as power switch #1849

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 0 additions & 8 deletions app/boards/arm/nrf52840_m2/nrf52840_m2.dts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
zephyr,code-partition = &code_partition;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zmk,battery = &vbatt;
};

leds {
Expand All @@ -31,13 +30,6 @@
};
};

vbatt: vbatt {
compatible = "zmk,battery-voltage-divider";
io-channels = <&adc 0>;
output-ohms = <1000000>;
full-ohms = <(1000000 + 1000000)>;
};

};

&adc {
Expand Down
3 changes: 3 additions & 0 deletions app/boards/shields/m60/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zephyr_library()
zephyr_library_sources(pinmux.c)
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
8 changes: 8 additions & 0 deletions app/boards/shields/m60/m60.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
chosen {
zmk,kscan = &kscan0;
zmk,physical-layout = &layout_60_ansi;
zmk,battery = &vbatt;
};

kscan0: kscan {
Expand Down Expand Up @@ -58,6 +59,13 @@ RC(6,4) RC(6,3) RC(6,2) RC(6,1) RC(6,0) RC(5,7) RC(5,6) RC(5,5) RC(5,4) RC
RC(6,5) RC(6,6) RC(6,7) RC(7,0) RC(7,1) RC(7,2) RC(7,3) RC(7,4)
>;
};

vbatt: vbatt {
compatible = "zmk,battery-voltage-divider";
io-channels = <&adc 0>;
output-ohms = <1000000>;
full-ohms = <(1000000 + 1000000)>;
};
};

&layout_60_ansi {
Expand Down
66 changes: 66 additions & 0 deletions app/boards/shields/m60/pinmux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/devicetree.h>

/* The PMU(BQ24075) enable pin(LOW active) on M60 is controlled by a NAND gate.
* Partial reverse engineering shows:
* P0.28 affects the NAND gate.
* The button affects P0.27 the NAND gate.
* P0.03 is detection pin for charging state(possibly attached to PMU LED pin).
*/

static const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0));

static inline void power_off(void) {
gpio_pin_set(p0, 28, 0); // turn off the PMU battery path
}

static inline bool is_charging(void) {
// 0: charging
return gpio_pin_get_raw(p0, 3) == 0;
}

static void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
// wait the button stable at 0 so the keyboard won't be powered up accidentally
k_sleep(K_SECONDS(1));

if (!is_charging()) {
power_off();
}
}

static int pinmux_nrf52840_m2_init(void) {
// back button
// NOTE: if used to power off the keyboard, make sure the action is done
// AFTER the button is released.
//
// To wake up the keyboard from sleep with this button, must use interrupt.
// To avoid the callback triggered after keyboard woke up(powering off the
// keyboard), must use GPIO_INT_EDGE_FALLING(trigger on button pressed).
gpio_pin_interrupt_configure(p0, 27, GPIO_INT_EDGE_FALLING);

// GPIO 0.28(LDO control) is already configured by bootloader,
// so configuring it here is just an ensurance.
gpio_pin_configure(p0, 28, GPIO_OUTPUT_ACTIVE | GPIO_PULL_UP | GPIO_OPEN_DRAIN);

// this is the pin for charging detection
gpio_pin_configure(p0, 3, GPIO_INPUT | GPIO_PULL_UP);

// setup the interrupt handler to poweroff the keyboard
static struct gpio_callback button_cb;
gpio_init_callback(&button_cb, button_pressed, BIT(27));
gpio_add_callback(p0, &button_cb);

return 0;
}

SYS_INIT(pinmux_nrf52840_m2_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);