refactor: Move away from deprecated label usages.

* Move away from DT_LABEL.
* Move to DEVICE_DT_GET for non-behavior device access.
* Move various drivers to `gpio_spec_dt` and `DT` related macros.
* Remove mcp23017 while at it, since better upstream driver is
  available.
This commit is contained in:
Peter Johanson 2023-01-17 20:40:44 -05:00 committed by Pete Johanson
parent 062f94d014
commit 09ed79a867
41 changed files with 199 additions and 828 deletions

View file

@ -104,11 +104,10 @@
clock-frequency = <I2C_BITRATE_FAST>; clock-frequency = <I2C_BITRATE_FAST>;
right_io: mcp23017@20 { right_io: mcp23017@20 {
compatible = "microchip,mcp23017"; compatible = "microchip,mcp230xx";
status = "okay"; status = "okay";
gpio-controller; gpio-controller;
reg = <0x20>; reg = <0x20>;
label = "RIGHT_IO";
#gpio-cells = <2>; #gpio-cells = <2>;
ngpios = <16>; ngpios = <16>;
}; };

View file

@ -20,9 +20,6 @@ CONFIG_ZMK_USB=y
CONFIG_ZMK_KSCAN_MATRIX_POLLING=y CONFIG_ZMK_KSCAN_MATRIX_POLLING=y
CONFIG_USB_SELF_POWERED=n CONFIG_USB_SELF_POWERED=n
# Enable IO multiplexer
CONFIG_GPIO_MCP23017=y
# Needed to reduce this to size that will fit on F072 # Needed to reduce this to size that will fit on F072
CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_HEAP_MEM_POOL_SIZE=1024

View file

@ -15,8 +15,8 @@ static int pinmux_mikoto_init(const struct device *port) {
ARG_UNUSED(port); ARG_UNUSED(port);
#if CONFIG_BOARD_MIKOTO_520 #if CONFIG_BOARD_MIKOTO_520
const struct device *p0 = device_get_binding("GPIO_0"); const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0));
const struct device *p1 = device_get_binding("GPIO_1"); const struct device *p1 = DEVICE_DT_GET(DT_NODELABEL(gpio1));
#if CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_40MA #if CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_40MA
gpio_pin_configure(p0, 26, GPIO_INPUT | GPIO_PULL_DOWN); gpio_pin_configure(p0, 26, GPIO_INPUT | GPIO_PULL_DOWN);
gpio_pin_configure(p1, 15, GPIO_INPUT); gpio_pin_configure(p1, 15, GPIO_INPUT);

View file

@ -15,7 +15,7 @@ static int pinmux_nrfmicro_init(const struct device *port) {
ARG_UNUSED(port); ARG_UNUSED(port);
#if (CONFIG_BOARD_NRFMICRO_13 || CONFIG_BOARD_NRFMICRO_13_52833) #if (CONFIG_BOARD_NRFMICRO_13 || CONFIG_BOARD_NRFMICRO_13_52833)
const struct device *p0 = device_get_binding("GPIO_0"); const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0));
#if CONFIG_BOARD_NRFMICRO_CHARGER #if CONFIG_BOARD_NRFMICRO_CHARGER
gpio_pin_configure(p0, 5, GPIO_OUTPUT); gpio_pin_configure(p0, 5, GPIO_OUTPUT);
gpio_pin_set(p0, 5, 0); gpio_pin_set(p0, 5, 0);

View file

@ -15,7 +15,7 @@ static int pinmux_puchi_ble_init(const struct device *port) {
ARG_UNUSED(port); ARG_UNUSED(port);
#if CONFIG_BOARD_PUCHI_BLE_v1 #if CONFIG_BOARD_PUCHI_BLE_v1
const struct device *p0 = device_get_binding("GPIO_0"); const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0));
#if CONFIG_BOARD_PUCHI_BLE_CHARGER #if CONFIG_BOARD_PUCHI_BLE_CHARGER
gpio_pin_configure(p0, 5, GPIO_OUTPUT); gpio_pin_configure(p0, 5, GPIO_OUTPUT);
gpio_pin_set(p0, 5, 0); gpio_pin_set(p0, 5, 0);

View file

@ -24,23 +24,6 @@ LOG_MODULE_REGISTER(il0323, CONFIG_DISPLAY_LOG_LEVEL);
* *
*/ */
#define IL0323_SPI_FREQ DT_INST_PROP(0, spi_max_frequency)
#define IL0323_BUS_NAME DT_INST_BUS_LABEL(0)
#define IL0323_DC_PIN DT_INST_GPIO_PIN(0, dc_gpios)
#define IL0323_DC_FLAGS DT_INST_GPIO_FLAGS(0, dc_gpios)
#define IL0323_DC_CNTRL DT_INST_GPIO_LABEL(0, dc_gpios)
#define IL0323_CS_PIN DT_INST_SPI_DEV_CS_GPIOS_PIN(0)
#define IL0323_CS_FLAGS DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0)
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
#define IL0323_CS_CNTRL DT_INST_SPI_DEV_CS_GPIOS_LABEL(0)
#endif
#define IL0323_BUSY_PIN DT_INST_GPIO_PIN(0, busy_gpios)
#define IL0323_BUSY_CNTRL DT_INST_GPIO_LABEL(0, busy_gpios)
#define IL0323_BUSY_FLAGS DT_INST_GPIO_FLAGS(0, busy_gpios)
#define IL0323_RESET_PIN DT_INST_GPIO_PIN(0, reset_gpios)
#define IL0323_RESET_CNTRL DT_INST_GPIO_LABEL(0, reset_gpios)
#define IL0323_RESET_FLAGS DT_INST_GPIO_FLAGS(0, reset_gpios)
#define EPD_PANEL_WIDTH DT_INST_PROP(0, width) #define EPD_PANEL_WIDTH DT_INST_PROP(0, width)
#define EPD_PANEL_HEIGHT DT_INST_PROP(0, height) #define EPD_PANEL_HEIGHT DT_INST_PROP(0, height)
#define IL0323_PIXELS_PER_BYTE 8U #define IL0323_PIXELS_PER_BYTE 8U
@ -53,15 +36,11 @@ LOG_MODULE_REGISTER(il0323, CONFIG_DISPLAY_LOG_LEVEL);
#define IL0323_PANEL_LAST_PAGE (IL0323_NUMOF_PAGES - 1) #define IL0323_PANEL_LAST_PAGE (IL0323_NUMOF_PAGES - 1)
#define IL0323_BUFFER_SIZE 1280 #define IL0323_BUFFER_SIZE 1280
struct il0323_data { struct il0323_cfg {
const struct device *reset; struct gpio_dt_spec reset;
const struct device *dc; struct gpio_dt_spec dc;
const struct device *busy; struct gpio_dt_spec busy;
const struct device *spi_dev; struct spi_dt_spec spi;
struct spi_config spi_config;
#if defined(IL0323_CS_CNTRL)
struct spi_cs_control cs_ctrl;
#endif
}; };
static uint8_t il0323_pwr[] = DT_INST_PROP(0, pwr); static uint8_t il0323_pwr[] = DT_INST_PROP(0, pwr);
@ -69,21 +48,21 @@ static uint8_t il0323_pwr[] = DT_INST_PROP(0, pwr);
static uint8_t last_buffer[IL0323_BUFFER_SIZE]; static uint8_t last_buffer[IL0323_BUFFER_SIZE];
static bool blanking_on = true; static bool blanking_on = true;
static inline int il0323_write_cmd(struct il0323_data *driver, uint8_t cmd, uint8_t *data, static inline int il0323_write_cmd(const struct il0323_cfg *cfg, uint8_t cmd, uint8_t *data,
size_t len) { size_t len) {
struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)}; struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
struct spi_buf_set buf_set = {.buffers = &buf, .count = 1}; struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};
gpio_pin_set(driver->dc, IL0323_DC_PIN, 1); gpio_pin_set_dt(&cfg->dc, 1);
if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) { if (spi_write_dt(&cfg->spi, &buf_set)) {
return -EIO; return -EIO;
} }
if (data != NULL) { if (data != NULL) {
buf.buf = data; buf.buf = data;
buf.len = len; buf.len = len;
gpio_pin_set(driver->dc, IL0323_DC_PIN, 0); gpio_pin_set_dt(&cfg->dc, 0);
if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) { if (spi_write_dt(&cfg->spi, &buf_set)) {
return -EIO; return -EIO;
} }
} }
@ -91,22 +70,22 @@ static inline int il0323_write_cmd(struct il0323_data *driver, uint8_t cmd, uint
return 0; return 0;
} }
static inline void il0323_busy_wait(struct il0323_data *driver) { static inline void il0323_busy_wait(const struct il0323_cfg *cfg) {
int pin = gpio_pin_get(driver->busy, IL0323_BUSY_PIN); int pin = gpio_pin_get_dt(&cfg->busy);
while (pin > 0) { while (pin > 0) {
__ASSERT(pin >= 0, "Failed to get pin level"); __ASSERT(pin >= 0, "Failed to get pin level");
// LOG_DBG("wait %u", pin); // LOG_DBG("wait %u", pin);
k_msleep(IL0323_BUSY_DELAY); k_msleep(IL0323_BUSY_DELAY);
pin = gpio_pin_get(driver->busy, IL0323_BUSY_PIN); pin = gpio_pin_get_dt(&cfg->busy);
} }
} }
static int il0323_update_display(const struct device *dev) { static int il0323_update_display(const struct device *dev) {
struct il0323_data *driver = dev->data; const struct il0323_cfg *cfg = dev->config;
LOG_DBG("Trigger update sequence"); LOG_DBG("Trigger update sequence");
if (il0323_write_cmd(driver, IL0323_CMD_DRF, NULL, 0)) { if (il0323_write_cmd(cfg, IL0323_CMD_DRF, NULL, 0)) {
return -EIO; return -EIO;
} }
@ -117,7 +96,7 @@ static int il0323_update_display(const struct device *dev) {
static int il0323_write(const struct device *dev, const uint16_t x, const uint16_t y, static int il0323_write(const struct device *dev, const uint16_t x, const uint16_t y,
const struct display_buffer_descriptor *desc, const void *buf) { const struct display_buffer_descriptor *desc, const void *buf) {
struct il0323_data *driver = dev->data; const struct il0323_cfg *cfg = dev->config;
uint16_t x_end_idx = x + desc->width - 1; uint16_t x_end_idx = x + desc->width - 1;
uint16_t y_end_idx = y + desc->height - 1; uint16_t y_end_idx = y + desc->height - 1;
uint8_t ptl[IL0323_PTL_REG_LENGTH] = {0}; uint8_t ptl[IL0323_PTL_REG_LENGTH] = {0};
@ -147,20 +126,20 @@ static int il0323_write(const struct device *dev, const uint16_t x, const uint16
ptl[sizeof(ptl) - 1] = IL0323_PTL_PT_SCAN; ptl[sizeof(ptl) - 1] = IL0323_PTL_PT_SCAN;
LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl"); LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl");
il0323_busy_wait(driver); il0323_busy_wait(cfg);
if (il0323_write_cmd(driver, IL0323_CMD_PIN, NULL, 0)) { if (il0323_write_cmd(cfg, IL0323_CMD_PIN, NULL, 0)) {
return -EIO; return -EIO;
} }
if (il0323_write_cmd(driver, IL0323_CMD_PTL, ptl, sizeof(ptl))) { if (il0323_write_cmd(cfg, IL0323_CMD_PTL, ptl, sizeof(ptl))) {
return -EIO; return -EIO;
} }
if (il0323_write_cmd(driver, IL0323_CMD_DTM1, last_buffer, IL0323_BUFFER_SIZE)) { if (il0323_write_cmd(cfg, IL0323_CMD_DTM1, last_buffer, IL0323_BUFFER_SIZE)) {
return -EIO; return -EIO;
} }
if (il0323_write_cmd(driver, IL0323_CMD_DTM2, (uint8_t *)buf, buf_len)) { if (il0323_write_cmd(cfg, IL0323_CMD_DTM2, (uint8_t *)buf, buf_len)) {
return -EIO; return -EIO;
} }
@ -173,7 +152,7 @@ static int il0323_write(const struct device *dev, const uint16_t x, const uint16
} }
} }
if (il0323_write_cmd(driver, IL0323_CMD_POUT, NULL, 0)) { if (il0323_write_cmd(cfg, IL0323_CMD_POUT, NULL, 0)) {
return -EIO; return -EIO;
} }
@ -217,11 +196,11 @@ static int il0323_clear_and_write_buffer(const struct device *dev, uint8_t patte
} }
static int il0323_blanking_off(const struct device *dev) { static int il0323_blanking_off(const struct device *dev) {
struct il0323_data *driver = dev->data; const struct il0323_cfg *cfg = dev->config;
if (blanking_on) { if (blanking_on) {
/* Update EPD pannel in normal mode */ /* Update EPD panel in normal mode */
il0323_busy_wait(driver); il0323_busy_wait(cfg);
if (il0323_clear_and_write_buffer(dev, 0xff, true)) { if (il0323_clear_and_write_buffer(dev, 0xff, true)) {
return -EIO; return -EIO;
} }
@ -278,30 +257,30 @@ static int il0323_set_pixel_format(const struct device *dev, const enum display_
} }
static int il0323_controller_init(const struct device *dev) { static int il0323_controller_init(const struct device *dev) {
struct il0323_data *driver = dev->data; const struct il0323_cfg *cfg = dev->config;
uint8_t tmp[IL0323_TRES_REG_LENGTH]; uint8_t tmp[IL0323_TRES_REG_LENGTH];
LOG_DBG(""); LOG_DBG("");
gpio_pin_set(driver->reset, IL0323_RESET_PIN, 1); gpio_pin_set_dt(&cfg->reset, 1);
k_msleep(IL0323_RESET_DELAY); k_msleep(IL0323_RESET_DELAY);
gpio_pin_set(driver->reset, IL0323_RESET_PIN, 0); gpio_pin_set_dt(&cfg->reset, 0);
k_msleep(IL0323_RESET_DELAY); k_msleep(IL0323_RESET_DELAY);
il0323_busy_wait(driver); il0323_busy_wait(cfg);
LOG_DBG("Initialize IL0323 controller"); LOG_DBG("Initialize IL0323 controller");
if (il0323_write_cmd(driver, IL0323_CMD_PWR, il0323_pwr, sizeof(il0323_pwr))) { if (il0323_write_cmd(cfg, IL0323_CMD_PWR, il0323_pwr, sizeof(il0323_pwr))) {
return -EIO; return -EIO;
} }
/* Turn on: booster, controller, regulators, and sensor. */ /* Turn on: booster, controller, regulators, and sensor. */
if (il0323_write_cmd(driver, IL0323_CMD_PON, NULL, 0)) { if (il0323_write_cmd(cfg, IL0323_CMD_PON, NULL, 0)) {
return -EIO; return -EIO;
} }
k_msleep(IL0323_PON_DELAY); k_msleep(IL0323_PON_DELAY);
il0323_busy_wait(driver); il0323_busy_wait(cfg);
/* Pannel settings, KW mode */ /* Pannel settings, KW mode */
tmp[0] = IL0323_PSR_UD | IL0323_PSR_SHL | IL0323_PSR_SHD | IL0323_PSR_RST; tmp[0] = IL0323_PSR_UD | IL0323_PSR_SHL | IL0323_PSR_SHD | IL0323_PSR_RST;
@ -321,7 +300,7 @@ static int il0323_controller_init(const struct device *dev) {
#endif /* panel width */ #endif /* panel width */
LOG_HEXDUMP_DBG(tmp, 1, "PSR"); LOG_HEXDUMP_DBG(tmp, 1, "PSR");
if (il0323_write_cmd(driver, IL0323_CMD_PSR, tmp, 1)) { if (il0323_write_cmd(cfg, IL0323_CMD_PSR, tmp, 1)) {
return -EIO; return -EIO;
} }
@ -329,24 +308,24 @@ static int il0323_controller_init(const struct device *dev) {
tmp[IL0323_TRES_HRES_IDX] = EPD_PANEL_WIDTH; tmp[IL0323_TRES_HRES_IDX] = EPD_PANEL_WIDTH;
tmp[IL0323_TRES_VRES_IDX] = EPD_PANEL_HEIGHT; tmp[IL0323_TRES_VRES_IDX] = EPD_PANEL_HEIGHT;
LOG_HEXDUMP_DBG(tmp, IL0323_TRES_REG_LENGTH, "TRES"); LOG_HEXDUMP_DBG(tmp, IL0323_TRES_REG_LENGTH, "TRES");
if (il0323_write_cmd(driver, IL0323_CMD_TRES, tmp, IL0323_TRES_REG_LENGTH)) { if (il0323_write_cmd(cfg, IL0323_CMD_TRES, tmp, IL0323_TRES_REG_LENGTH)) {
return -EIO; return -EIO;
} }
tmp[IL0323_CDI_CDI_IDX] = DT_INST_PROP(0, cdi); tmp[IL0323_CDI_CDI_IDX] = DT_INST_PROP(0, cdi);
LOG_HEXDUMP_DBG(tmp, IL0323_CDI_REG_LENGTH, "CDI"); LOG_HEXDUMP_DBG(tmp, IL0323_CDI_REG_LENGTH, "CDI");
if (il0323_write_cmd(driver, IL0323_CMD_CDI, tmp, IL0323_CDI_REG_LENGTH)) { if (il0323_write_cmd(cfg, IL0323_CMD_CDI, tmp, IL0323_CDI_REG_LENGTH)) {
return -EIO; return -EIO;
} }
tmp[0] = DT_INST_PROP(0, tcon); tmp[0] = DT_INST_PROP(0, tcon);
if (il0323_write_cmd(driver, IL0323_CMD_TCON, tmp, 1)) { if (il0323_write_cmd(cfg, IL0323_CMD_TCON, tmp, 1)) {
return -EIO; return -EIO;
} }
/* Enable Auto Sequence */ /* Enable Auto Sequence */
tmp[0] = IL0323_AUTO_PON_DRF_POF; tmp[0] = IL0323_AUTO_PON_DRF_POF;
if (il0323_write_cmd(driver, IL0323_CMD_AUTO, tmp, 1)) { if (il0323_write_cmd(cfg, IL0323_CMD_AUTO, tmp, 1)) {
return -EIO; return -EIO;
} }
@ -354,62 +333,43 @@ static int il0323_controller_init(const struct device *dev) {
} }
static int il0323_init(const struct device *dev) { static int il0323_init(const struct device *dev) {
struct il0323_data *driver = dev->data; const struct il0323_cfg *cfg = dev->config;
LOG_DBG(""); if (!spi_is_ready(&cfg->spi)) {
LOG_ERR("SPI device not ready for IL0323");
driver->spi_dev = device_get_binding(IL0323_BUS_NAME);
if (driver->spi_dev == NULL) {
LOG_ERR("Could not get SPI device for IL0323");
return -EIO; return -EIO;
} }
driver->spi_config.frequency = IL0323_SPI_FREQ; if (!device_is_ready(cfg->reset.port)) {
driver->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
driver->spi_config.slave = DT_INST_REG_ADDR(0);
driver->spi_config.cs = NULL;
driver->reset = device_get_binding(IL0323_RESET_CNTRL);
if (driver->reset == NULL) {
LOG_ERR("Could not get GPIO port for IL0323 reset"); LOG_ERR("Could not get GPIO port for IL0323 reset");
return -EIO; return -EIO;
} }
gpio_pin_configure(driver->reset, IL0323_RESET_PIN, GPIO_OUTPUT_INACTIVE | IL0323_RESET_FLAGS); gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE);
driver->dc = device_get_binding(IL0323_DC_CNTRL); if (!device_is_ready(cfg->dc.port)) {
if (driver->dc == NULL) {
LOG_ERR("Could not get GPIO port for IL0323 DC signal"); LOG_ERR("Could not get GPIO port for IL0323 DC signal");
return -EIO; return -EIO;
} }
gpio_pin_configure(driver->dc, IL0323_DC_PIN, GPIO_OUTPUT_INACTIVE | IL0323_DC_FLAGS); gpio_pin_configure_dt(&cfg->dc, GPIO_OUTPUT_INACTIVE);
driver->busy = device_get_binding(IL0323_BUSY_CNTRL); if (!device_is_ready(cfg->busy.port)) {
if (driver->busy == NULL) {
LOG_ERR("Could not get GPIO port for IL0323 busy signal"); LOG_ERR("Could not get GPIO port for IL0323 busy signal");
return -EIO; return -EIO;
} }
gpio_pin_configure(driver->busy, IL0323_BUSY_PIN, GPIO_INPUT | IL0323_BUSY_FLAGS); gpio_pin_configure_dt(&cfg->busy, GPIO_INPUT);
#if defined(IL0323_CS_CNTRL)
driver->cs_ctrl.gpio_dev = device_get_binding(IL0323_CS_CNTRL);
if (!driver->cs_ctrl.gpio_dev) {
LOG_ERR("Unable to get SPI GPIO CS device");
return -EIO;
}
driver->cs_ctrl.gpio_pin = IL0323_CS_PIN;
driver->cs_ctrl.gpio_dt_flags = IL0323_CS_FLAGS;
driver->cs_ctrl.delay = 0U;
driver->spi_config.cs = &driver->cs_ctrl;
#endif
return il0323_controller_init(dev); return il0323_controller_init(dev);
} }
static struct il0323_data il0323_driver; static struct il0323_cfg il0323_config = {
.spi = SPI_DT_SPEC_INST_GET(0, SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0),
.reset = GPIO_DT_SPEC_INST_GET(0, reset_gpios),
.busy = GPIO_DT_SPEC_INST_GET(0, busy_gpios),
.dc = GPIO_DT_SPEC_INST_GET(0, dc_gpios),
};
static struct display_driver_api il0323_driver_api = { static struct display_driver_api il0323_driver_api = {
.blanking_on = il0323_blanking_on, .blanking_on = il0323_blanking_on,
@ -424,5 +384,5 @@ static struct display_driver_api il0323_driver_api = {
.set_orientation = il0323_set_orientation, .set_orientation = il0323_set_orientation,
}; };
DEVICE_DT_INST_DEFINE(0, il0323_init, NULL, &il0323_driver, NULL, POST_KERNEL, DEVICE_DT_INST_DEFINE(0, il0323_init, NULL, NULL, &il0323_config, POST_KERNEL,
CONFIG_APPLICATION_INIT_PRIORITY, &il0323_driver_api); CONFIG_APPLICATION_INIT_PRIORITY, &il0323_driver_api);

View file

@ -5,5 +5,4 @@ zephyr_library_named(zmk__drivers__gpio)
zephyr_library_include_directories(${CMAKE_SOURCE_DIR}/include) zephyr_library_include_directories(${CMAKE_SOURCE_DIR}/include)
zephyr_library_sources_ifdef(CONFIG_GPIO_595 gpio_595.c) zephyr_library_sources_ifdef(CONFIG_GPIO_595 gpio_595.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23017 gpio_mcp23017.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_MAX7318 gpio_max7318.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MAX7318 gpio_max7318.c)

View file

@ -1,6 +1,5 @@
menuconfig ZMK_DRIVERS_GPIO menuconfig ZMK_DRIVERS_GPIO
bool "GPIO" bool "GPIO"
rsource "Kconfig.mcp23017"
rsource "Kconfig.max7318" rsource "Kconfig.max7318"
rsource "Kconfig.595" rsource "Kconfig.595"

View file

@ -1,22 +0,0 @@
# MCP23017 GPIO configuration options
# Copyright (c) 2021 Pete Johanson
# SPDX-License-Identifier: Apache-2.0
menuconfig GPIO_MCP23017
bool "MCP23017 I2C-based GPIO chip"
depends on I2C
select HAS_DTS_GPIO
select ZMK_DRIVERS_GPIO
help
Enable driver for MCP23017 I2C-based GPIO chip.
if GPIO_MCP23017
config GPIO_MCP23017_INIT_PRIORITY
int "Init priority"
default 75
help
Device driver initialization priority.
endif #GPIO_MCP23017

View file

@ -1,332 +0,0 @@
/*
* Copyright (c) 2020 Geanix ApS
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT microchip_mcp23017
/**
* @file Driver for MCP23017 SPI-based GPIO driver.
*/
#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <sys/byteorder.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include "gpio_mcp23017.h"
#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(gpio_mcp23017);
/**
* @brief Read both port 0 and port 1 registers of certain register function.
*
* Given the register in reg, read the pair of port 0 and port 1.
*
* @param dev Device struct of the MCP23017.
* @param reg Register to read (the PORTA of the pair of registers).
* @param buf Buffer to read data into.
*
* @return 0 if successful, failed otherwise.
*/
static int read_port_regs(const struct device *dev, uint8_t reg, uint16_t *buf) {
const struct mcp23017_config *const config = dev->config;
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
int ret;
uint16_t port_data;
uint8_t addr = config->slave;
ret = i2c_burst_read(drv_data->i2c, addr, reg, (uint8_t *)&port_data, sizeof(port_data));
if (ret) {
LOG_DBG("i2c_write_read FAIL %d\n", ret);
return ret;
}
*buf = sys_le16_to_cpu(port_data);
LOG_DBG("MCP23017: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", reg, (*buf & 0xFF), (reg + 1),
(*buf >> 8));
return 0;
}
/**
* @brief Write both port 0 and port 1 registers of certain register function.
*
* Given the register in reg, write the pair of port 0 and port 1.
*
* @param dev Device struct of the MCP23017.
* @param reg Register to write into (the PORTA of the pair of registers).
* @param buf Buffer to write data from.
*
* @return 0 if successful, failed otherwise.
*/
static int write_port_regs(const struct device *dev, uint8_t reg, uint16_t value) {
const struct mcp23017_config *const config = dev->config;
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
int ret;
uint16_t port_data;
LOG_DBG("MCP23017: Write: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", reg, (value & 0xFF), (reg + 1),
(value >> 8));
port_data = sys_cpu_to_le16(value);
ret = i2c_burst_write(drv_data->i2c, config->slave, reg, (uint8_t *)&port_data,
sizeof(port_data));
if (ret) {
LOG_DBG("i2c_write FAIL %d\n", ret);
return ret;
}
return 0;
}
/**
* @brief Setup the pin direction (input or output)
*
* @param dev Device struct of the MCP23017
* @param pin The pin number
* @param flags Flags of pin or port
*
* @return 0 if successful, failed otherwise
*/
static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
uint16_t *dir = &drv_data->reg_cache.iodir;
uint16_t *output = &drv_data->reg_cache.gpio;
int ret;
if ((flags & GPIO_OUTPUT) != 0U) {
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
*output |= BIT(pin);
} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
*output &= ~BIT(pin);
}
*dir &= ~BIT(pin);
} else {
*dir |= BIT(pin);
}
ret = write_port_regs(dev, REG_GPIO_PORTA, *output);
if (ret != 0) {
return ret;
}
ret = write_port_regs(dev, REG_IODIR_PORTA, *dir);
return ret;
}
/**
* @brief Setup the pin pull up/pull down status
*
* @param dev Device struct of the MCP23017
* @param pin The pin number
* @param flags Flags of pin or port
*
* @return 0 if successful, failed otherwise
*/
static int setup_pin_pullupdown(const struct device *dev, uint32_t pin, int flags) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
uint16_t port;
int ret;
/* Setup pin pull up or pull down */
port = drv_data->reg_cache.gppu;
/* pull down == 0, pull up == 1 */
if ((flags & GPIO_PULL_DOWN) != 0U) {
return -ENOTSUP;
}
WRITE_BIT(port, pin, (flags & GPIO_PULL_UP) != 0U);
ret = write_port_regs(dev, REG_GPPU_PORTA, port);
if (ret == 0) {
drv_data->reg_cache.gppu = port;
}
return ret;
}
static int mcp23017_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
int ret;
/* Can't do SPI bus operations from an ISR */
if (k_is_in_isr()) {
return -EWOULDBLOCK;
}
k_sem_take(&drv_data->lock, K_FOREVER);
if ((flags & GPIO_OPEN_DRAIN) != 0U) {
ret = -ENOTSUP;
goto done;
};
ret = setup_pin_dir(dev, pin, flags);
if (ret) {
LOG_ERR("MCP23017: error setting pin direction (%d)", ret);
goto done;
}
ret = setup_pin_pullupdown(dev, pin, flags);
if (ret) {
LOG_ERR("MCP23017: error setting pin pull up/down (%d)", ret);
goto done;
}
done:
k_sem_give(&drv_data->lock);
return ret;
}
static int mcp23017_port_get_raw(const struct device *dev, uint32_t *value) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
uint16_t buf;
int ret;
/* Can't do SPI bus operations from an ISR */
if (k_is_in_isr()) {
return -EWOULDBLOCK;
}
k_sem_take(&drv_data->lock, K_FOREVER);
ret = read_port_regs(dev, REG_GPIO_PORTA, &buf);
if (ret != 0) {
goto done;
}
*value = buf;
done:
k_sem_give(&drv_data->lock);
return ret;
}
static int mcp23017_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
uint16_t buf;
int ret;
/* Can't do SPI bus operations from an ISR */
if (k_is_in_isr()) {
return -EWOULDBLOCK;
}
k_sem_take(&drv_data->lock, K_FOREVER);
buf = drv_data->reg_cache.gpio;
buf = (buf & ~mask) | (mask & value);
ret = write_port_regs(dev, REG_GPIO_PORTA, buf);
if (ret == 0) {
drv_data->reg_cache.gpio = buf;
}
k_sem_give(&drv_data->lock);
return ret;
}
static int mcp23017_port_set_bits_raw(const struct device *dev, uint32_t mask) {
return mcp23017_port_set_masked_raw(dev, mask, mask);
}
static int mcp23017_port_clear_bits_raw(const struct device *dev, uint32_t mask) {
return mcp23017_port_set_masked_raw(dev, mask, 0);
}
static int mcp23017_port_toggle_bits(const struct device *dev, uint32_t mask) {
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
uint16_t buf;
int ret;
/* Can't do SPI bus operations from an ISR */
if (k_is_in_isr()) {
return -EWOULDBLOCK;
}
k_sem_take(&drv_data->lock, K_FOREVER);
buf = drv_data->reg_cache.gpio;
buf ^= mask;
ret = write_port_regs(dev, REG_GPIO_PORTA, buf);
if (ret == 0) {
drv_data->reg_cache.gpio = buf;
}
k_sem_give(&drv_data->lock);
return ret;
}
static int mcp23017_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
enum gpio_int_mode mode, enum gpio_int_trig trig) {
return -ENOTSUP;
}
static const struct gpio_driver_api api_table = {
.pin_configure = mcp23017_config,
.port_get_raw = mcp23017_port_get_raw,
.port_set_masked_raw = mcp23017_port_set_masked_raw,
.port_set_bits_raw = mcp23017_port_set_bits_raw,
.port_clear_bits_raw = mcp23017_port_clear_bits_raw,
.port_toggle_bits = mcp23017_port_toggle_bits,
.pin_interrupt_configure = mcp23017_pin_interrupt_configure,
};
/**
* @brief Initialization function of MCP23017
*
* @param dev Device struct
* @return 0 if successful, failed otherwise.
*/
static int mcp23017_init(const struct device *dev) {
const struct mcp23017_config *const config = dev->config;
struct mcp23017_drv_data *const drv_data = (struct mcp23017_drv_data *const)dev->data;
drv_data->i2c = device_get_binding((char *)config->i2c_dev_name);
if (!drv_data->i2c) {
LOG_DBG("Unable to get i2c device");
return -ENODEV;
}
k_sem_init(&drv_data->lock, 1, 1);
return 0;
}
#define MCP23017_INIT(inst) \
static struct mcp23017_config mcp23017_##inst##_config = { \
.i2c_dev_name = DT_INST_BUS_LABEL(inst), \
.slave = DT_INST_REG_ADDR(inst), \
\
}; \
\
static struct mcp23017_drv_data mcp23017_##inst##_drvdata = { \
/* Default for registers according to datasheet */ \
.reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \
.reg_cache.defval = 0x0, .reg_cache.intcon = 0x0, .reg_cache.iocon = 0x0, \
.reg_cache.gppu = 0x0, .reg_cache.intf = 0x0, .reg_cache.intcap = 0x0, \
.reg_cache.gpio = 0x0, .reg_cache.olat = 0x0, \
}; \
\
/* This has to init after SPI master */ \
DEVICE_DT_INST_DEFINE(inst, mcp23017_init, NULL, &mcp23017_##inst##_drvdata, \
&mcp23017_##inst##_config, POST_KERNEL, \
CONFIG_GPIO_MCP23017_INIT_PRIORITY, &api_table);
DT_INST_FOREACH_STATUS_OKAY(MCP23017_INIT)

View file

@ -1,86 +0,0 @@
/*
* Copyright (c) 2020 Geanix ApS, Pete Johanson
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file Header file for the MCP23017 driver.
*/
#ifndef ZEPHYR_DRIVERS_GPIO_GPIO_MCP23017_H_
#define ZEPHYR_DRIVERS_GPIO_GPIO_MCP23017_H_
#include <zephyr/kernel.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Register definitions */
#define REG_IODIR_PORTA 0x00
#define REG_IODIR_PORTB 0x01
#define REG_IPOL_PORTA 0x02
#define REG_IPOL_PORTB 0x03
#define REG_GPINTEN_PORTA 0x04
#define REG_GPINTEN_PORTB 0x05
#define REG_DEFVAL_PORTA 0x06
#define REG_DEFVAL_PORTB 0x07
#define REG_INTCON_PORTA 0x08
#define REG_INTCON_PORTB 0x09
#define REG_GPPU_PORTA 0x0C
#define REG_GPPU_PORTB 0x0D
#define REG_INTF_PORTA 0x0E
#define REG_INTF_PORTB 0x0F
#define REG_INTCAP_PORTA 0x10
#define REG_INTCAP_PORTB 0x11
#define REG_GPIO_PORTA 0x12
#define REG_GPIO_PORTB 0x13
#define REG_OLAT_PORTA 0x14
#define REG_OLAT_PORTB 0x15
#define MCP23017_ADDR 0x40
#define MCP23017_READBIT 0x01
/** Configuration data */
struct mcp23017_config {
/* gpio_driver_data needs to be first */
struct gpio_driver_config common;
const char *const i2c_dev_name;
const uint16_t slave;
};
/** Runtime driver data */
struct mcp23017_drv_data {
/* gpio_driver_data needs to be first */
struct gpio_driver_config data;
/** Master SPI device */
const struct device *i2c;
struct k_sem lock;
struct {
uint16_t iodir;
uint16_t ipol;
uint16_t gpinten;
uint16_t defval;
uint16_t intcon;
uint16_t iocon;
uint16_t gppu;
uint16_t intf;
uint16_t intcap;
uint16_t gpio;
uint16_t olat;
} reg_cache;
};
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_DRIVERS_GPIO_GPIO_MCP23017_H_ */

View file

@ -7,7 +7,7 @@
#define DT_DRV_COMPAT zmk_kscan_composite #define DT_DRV_COMPAT zmk_kscan_composite
#include <zephyr/device.h> #include <zephyr/device.h>
#include <drivers/kscan.h> #include <zephyr/drivers/kscan.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
@ -16,13 +16,13 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#define MATRIX_COLS DT_PROP(MATRIX_NODE_ID, columns) #define MATRIX_COLS DT_PROP(MATRIX_NODE_ID, columns)
struct kscan_composite_child_config { struct kscan_composite_child_config {
char *label; const struct device *child;
uint8_t row_offset; uint8_t row_offset;
uint8_t column_offset; uint8_t column_offset;
}; };
#define CHILD_CONFIG(inst) \ #define CHILD_CONFIG(inst) \
{.label = DT_LABEL(DT_PHANDLE(inst, kscan)), \ {.child = DEVICE_DT_GET(DT_PHANDLE(inst, kscan)), \
.row_offset = DT_PROP(inst, row_offset), \ .row_offset = DT_PROP(inst, row_offset), \
.column_offset = DT_PROP(inst, column_offset)}, .column_offset = DT_PROP(inst, column_offset)},
@ -41,12 +41,7 @@ static int kscan_composite_enable_callback(const struct device *dev) {
for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
const struct device *dev = device_get_binding(cfg->label); kscan_enable_callback(cfg->child);
if (!dev) {
LOG_WRN("Failed to load child kscan device %s", cfg->label);
continue;
}
kscan_enable_callback(dev);
} }
return 0; return 0;
} }
@ -55,12 +50,7 @@ static int kscan_composite_disable_callback(const struct device *dev) {
for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
const struct device *dev = device_get_binding(cfg->label); kscan_disable_callback(cfg->child);
if (!dev) {
LOG_WRN("Failed to load child kscan device %s", cfg->label);
continue;
}
kscan_disable_callback(dev);
} }
return 0; return 0;
} }
@ -68,13 +58,13 @@ static int kscan_composite_disable_callback(const struct device *dev) {
static void kscan_composite_child_callback(const struct device *child_dev, uint32_t row, static void kscan_composite_child_callback(const struct device *child_dev, uint32_t row,
uint32_t column, bool pressed) { uint32_t column, bool pressed) {
// TODO: Ideally we can get this passed into our callback! // TODO: Ideally we can get this passed into our callback!
const struct device *dev = device_get_binding(DT_INST_LABEL(0)); const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
struct kscan_composite_data *data = dev->data; struct kscan_composite_data *data = dev->data;
for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
if (device_get_binding(cfg->label) != child_dev) { if (cfg->child != child_dev) {
continue; continue;
} }
@ -92,7 +82,7 @@ static int kscan_composite_configure(const struct device *dev, kscan_callback_t
for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
kscan_config(device_get_binding(cfg->label), &kscan_composite_child_callback); kscan_config(cfg->child, &kscan_composite_child_callback);
} }
data->callback = callback; data->callback = callback;

View file

@ -13,26 +13,11 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct kscan_gpio_item_config {
char *label;
gpio_pin_t pin;
gpio_flags_t flags;
};
// Helper macro // Helper macro
#define PWR_TWO(x) (1 << (x)) #define PWR_TWO(x) (1 << (x))
// Define GPIO cfg
#define _KSCAN_GPIO_ITEM_CFG_INIT(n, prop, idx) \
{ \
.label = DT_INST_GPIO_LABEL_BY_IDX(n, prop, idx), \
.pin = DT_INST_GPIO_PIN_BY_IDX(n, prop, idx), \
.flags = DT_INST_GPIO_FLAGS_BY_IDX(n, prop, idx), \
}
// Define row and col cfg // Define row and col cfg
#define _KSCAN_GPIO_INPUT_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, input_gpios, idx) #define _KSCAN_GPIO_CFG_INIT(n, prop, idx) GPIO_DT_SPEC_GET_BY_IDX(n, prop, idx),
#define _KSCAN_GPIO_OUTPUT_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, output_gpios, idx)
// Check debounce config // Check debounce config
#define CHECK_DEBOUNCE_CFG(n, a, b) COND_CODE_0(DT_INST_PROP(n, debounce_period), a, b) #define CHECK_DEBOUNCE_CFG(n, a, b) COND_CODE_0(DT_INST_PROP(n, debounce_period), a, b)
@ -51,8 +36,8 @@ struct kscan_gpio_item_config {
}; \ }; \
\ \
struct kscan_gpio_config_##n { \ struct kscan_gpio_config_##n { \
struct kscan_gpio_item_config rows[INST_MATRIX_INPUTS(n)]; \ const struct gpio_dt_spec rows[INST_MATRIX_INPUTS(n)]; \
struct kscan_gpio_item_config cols[INST_DEMUX_GPIOS(n)]; \ const struct gpio_dt_spec cols[INST_DEMUX_GPIOS(n)]; \
}; \ }; \
\ \
struct kscan_gpio_data_##n { \ struct kscan_gpio_data_##n { \
@ -60,33 +45,16 @@ struct kscan_gpio_item_config {
struct k_timer poll_timer; \ struct k_timer poll_timer; \
struct CHECK_DEBOUNCE_CFG(n, (k_work), (k_work_delayable)) work; \ struct CHECK_DEBOUNCE_CFG(n, (k_work), (k_work_delayable)) work; \
bool matrix_state[INST_MATRIX_INPUTS(n)][INST_MATRIX_OUTPUTS(n)]; \ bool matrix_state[INST_MATRIX_INPUTS(n)][INST_MATRIX_OUTPUTS(n)]; \
const struct device *rows[INST_MATRIX_INPUTS(n)]; \
const struct device *cols[INST_MATRIX_OUTPUTS(n)]; \
const struct device *dev; \ const struct device *dev; \
}; \ }; \
/* IO/GPIO SETUP */ \ /* IO/GPIO SETUP */ \
/* gpio_input_devices are PHYSICAL IO devices */ \ static const struct gpio_dt_spec *kscan_gpio_input_specs_##n(const struct device *dev) { \
static const struct device **kscan_gpio_input_devices_##n(const struct device *dev) { \
struct kscan_gpio_data_##n *data = dev->data; \
return data->rows; \
} \
\
static const struct kscan_gpio_item_config *kscan_gpio_input_configs_##n( \
const struct device *dev) { \
const struct kscan_gpio_config_##n *cfg = dev->config; \ const struct kscan_gpio_config_##n *cfg = dev->config; \
return cfg->rows; \ return cfg->rows; \
} \ } \
\ \
/* gpio_output_devices are PHYSICAL IO devices */ \ static const struct gpio_dt_spec *kscan_gpio_output_specs_##n(const struct device *dev) { \
static const struct device **kscan_gpio_output_devices_##n(const struct device *dev) { \
struct kscan_gpio_data_##n *data = dev->data; \
return data->cols; \
} \
\
static const struct kscan_gpio_item_config *kscan_gpio_output_configs_##n( \
const struct device *dev) { \
const struct kscan_gpio_config_##n *cfg = dev->config; \ const struct kscan_gpio_config_##n *cfg = dev->config; \
/* If row2col, rows = outputs & cols = inputs */ \
return cfg->cols; \ return cfg->cols; \
} \ } \
/* POLLING SETUP */ \ /* POLLING SETUP */ \
@ -106,21 +74,16 @@ struct kscan_gpio_item_config {
/* Iterate over bits and set GPIOs accordingly */ \ /* Iterate over bits and set GPIOs accordingly */ \
for (uint8_t bit = 0; bit < INST_DEMUX_GPIOS(n); bit++) { \ for (uint8_t bit = 0; bit < INST_DEMUX_GPIOS(n); bit++) { \
uint8_t state = (o & (0b1 << bit)) >> bit; \ uint8_t state = (o & (0b1 << bit)) >> bit; \
const struct device *out_dev = kscan_gpio_output_devices_##n(dev)[bit]; \ const struct gpio_dt_spec *out_spec = &kscan_gpio_output_specs_##n(dev)[bit]; \
const struct kscan_gpio_item_config *out_cfg = \ gpio_pin_set_dt(out_spec, state); \
&kscan_gpio_output_configs_##n(dev)[bit]; \
gpio_pin_set(out_dev, out_cfg->pin, state); \
} \ } \
/* Let the col settle before reading the rows */ \ /* Let the col settle before reading the rows */ \
k_usleep(1); \ k_usleep(1); \
\ \
for (int i = 0; i < INST_MATRIX_INPUTS(n); i++) { \ for (int i = 0; i < INST_MATRIX_INPUTS(n); i++) { \
/* Get the input device (port) */ \ /* Get the input spec */ \
const struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \ const struct gpio_dt_spec *in_spec = &kscan_gpio_input_specs_##n(dev)[i]; \
/* Get the input device config (pin) */ \ read_state[i][o] = gpio_pin_get_dt(in_spec) > 0; \
const struct kscan_gpio_item_config *in_cfg = \
&kscan_gpio_input_configs_##n(dev)[i]; \
read_state[i][o] = gpio_pin_get(in_dev, in_cfg->pin) > 0; \
} \ } \
} \ } \
for (int r = 0; r < INST_MATRIX_INPUTS(n); r++) { \ for (int r = 0; r < INST_MATRIX_INPUTS(n); r++) { \
@ -146,8 +109,7 @@ struct kscan_gpio_item_config {
kscan_gpio_read_##n(data->dev); \ kscan_gpio_read_##n(data->dev); \
} \ } \
\ \
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \ static struct kscan_gpio_data_##n kscan_gpio_data_##n = {}; \
.rows = {[INST_MATRIX_INPUTS(n) - 1] = NULL}, .cols = {[INST_DEMUX_GPIOS(n) - 1] = NULL}}; \
\ \
/* KSCAN API configure function */ \ /* KSCAN API configure function */ \
static int kscan_gpio_configure_##n(const struct device *dev, kscan_callback_t callback) { \ static int kscan_gpio_configure_##n(const struct device *dev, kscan_callback_t callback) { \
@ -185,20 +147,18 @@ struct kscan_gpio_item_config {
struct kscan_gpio_data_##n *data = dev->data; \ struct kscan_gpio_data_##n *data = dev->data; \
int err; \ int err; \
/* configure input devices*/ \ /* configure input devices*/ \
const struct device **input_devices = kscan_gpio_input_devices_##n(dev); \
for (int i = 0; i < INST_MATRIX_INPUTS(n); i++) { \ for (int i = 0; i < INST_MATRIX_INPUTS(n); i++) { \
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs_##n(dev)[i]; \ const struct gpio_dt_spec *in_spec = &kscan_gpio_input_specs_##n(dev)[i]; \
input_devices[i] = device_get_binding(in_cfg->label); \ if (!device_is_ready(in_spec->port)) { \
if (!input_devices[i]) { \
LOG_ERR("Unable to find input GPIO device"); \ LOG_ERR("Unable to find input GPIO device"); \
return -EINVAL; \ return -EINVAL; \
} \ } \
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \ err = gpio_pin_configure_dt(in_spec, GPIO_INPUT); \
if (err) { \ if (err) { \
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \ LOG_ERR("Unable to configure pin %d for input", in_spec->pin); \
return err; \ return err; \
} else { \ } else { \
LOG_DBG("Configured pin %d on %s for input", in_cfg->pin, in_cfg->label); \ LOG_DBG("Configured pin %d for input", in_spec->pin); \
} \ } \
if (err) { \ if (err) { \
LOG_ERR("Error adding the callback to the column device"); \ LOG_ERR("Error adding the callback to the column device"); \
@ -206,22 +166,18 @@ struct kscan_gpio_item_config {
} \ } \
} \ } \
/* configure output devices*/ \ /* configure output devices*/ \
const struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
for (int o = 0; o < INST_DEMUX_GPIOS(n); o++) { \ for (int o = 0; o < INST_DEMUX_GPIOS(n); o++) { \
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \ const struct gpio_dt_spec *out_spec = &kscan_gpio_output_specs_##n(dev)[o]; \
output_devices[o] = device_get_binding(out_cfg->label); \ if (!device_is_ready(out_spec->port)) { \
if (!output_devices[o]) { \
LOG_ERR("Unable to find output GPIO device"); \ LOG_ERR("Unable to find output GPIO device"); \
return -EINVAL; \ return -EINVAL; \
} \ } \
err = gpio_pin_configure(output_devices[o], out_cfg->pin, \ err = gpio_pin_configure_dt(out_spec, GPIO_OUTPUT_ACTIVE); \
GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
if (err) { \ if (err) { \
LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, \ LOG_ERR("Unable to configure pin %d for output", out_spec->pin); \
out_cfg->label); \
return err; \ return err; \
} else { \ } else { \
LOG_DBG("Configured pin %d on %s for output", out_cfg->pin, out_cfg->label); \ LOG_DBG("Configured pin %d for output", out_spec->pin); \
} \ } \
} \ } \
data->dev = dev; \ data->dev = dev; \
@ -240,8 +196,8 @@ struct kscan_gpio_item_config {
}; \ }; \
\ \
static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \ static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \
.rows = {LISTIFY(INST_MATRIX_INPUTS(n), _KSCAN_GPIO_INPUT_CFG_INIT, (, ), n)}, \ .rows = {DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), input_gpios, _KSCAN_GPIO_CFG_INIT)}, \
.cols = {LISTIFY(INST_DEMUX_GPIOS(n), _KSCAN_GPIO_OUTPUT_CFG_INIT, (, ), n)}, \ .cols = {DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), output_gpios, _KSCAN_GPIO_CFG_INIT)}, \
}; \ }; \
\ \
DEVICE_DT_INST_DEFINE(n, kscan_gpio_init_##n, NULL, &kscan_gpio_data_##n, \ DEVICE_DT_INST_DEFINE(n, kscan_gpio_init_##n, NULL, &kscan_gpio_data_##n, \

View file

@ -8,9 +8,9 @@
#include <zephyr/device.h> #include <zephyr/device.h>
#include <zephyr/devicetree.h> #include <zephyr/devicetree.h>
#include <drivers/gpio.h> #include <zephyr/drivers/gpio.h>
#include <drivers/adc.h> #include <zephyr/drivers/adc.h>
#include <drivers/sensor.h> #include <zephyr/drivers/sensor.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include "battery_common.h" #include "battery_common.h"
@ -21,22 +21,15 @@ struct io_channel_config {
uint8_t channel; uint8_t channel;
}; };
struct gpio_channel_config {
const char *label;
uint8_t pin;
uint8_t flags;
};
struct bvd_config { struct bvd_config {
struct io_channel_config io_channel; struct io_channel_config io_channel;
struct gpio_channel_config power_gpios; struct gpio_dt_spec power;
uint32_t output_ohm; uint32_t output_ohm;
uint32_t full_ohm; uint32_t full_ohm;
}; };
struct bvd_data { struct bvd_data {
const struct device *adc; const struct device *adc;
const struct device *gpio;
struct adc_channel_cfg acc; struct adc_channel_cfg acc;
struct adc_sequence as; struct adc_sequence as;
struct battery_value value; struct battery_value value;
@ -56,9 +49,9 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
int rc = 0; int rc = 0;
// Enable power GPIO if present #if DT_INST_NODE_HAS_PROP(0, power_gpios)
if (drv_data->gpio) { // Enable power before sampling
rc = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 1); rc = gpio_pin_set_dt(&drv_cfg->power, 1);
if (rc != 0) { if (rc != 0) {
LOG_DBG("Failed to enable ADC power GPIO: %d", rc); LOG_DBG("Failed to enable ADC power GPIO: %d", rc);
@ -67,7 +60,7 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
// wait for any capacitance to charge up // wait for any capacitance to charge up
k_sleep(K_MSEC(10)); k_sleep(K_MSEC(10));
} #endif // DT_INST_NODE_HAS_PROP(0, power_gpios)
// Read ADC // Read ADC
rc = adc_read(drv_data->adc, as); rc = adc_read(drv_data->adc, as);
@ -90,15 +83,15 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
LOG_DBG("Failed to read ADC: %d", rc); LOG_DBG("Failed to read ADC: %d", rc);
} }
#if DT_INST_NODE_HAS_PROP(0, power_gpios)
// Disable power GPIO if present // Disable power GPIO if present
if (drv_data->gpio) { int rc2 = gpio_pin_set_dt(&drv_cfg->power, 0);
int rc2 = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 0);
if (rc2 != 0) { if (rc2 != 0) {
LOG_DBG("Failed to disable ADC power GPIO: %d", rc2); LOG_DBG("Failed to disable ADC power GPIO: %d", rc2);
return rc2; return rc2;
} }
} #endif // DT_INST_NODE_HAS_PROP(0, power_gpios)
return rc; return rc;
} }
@ -125,20 +118,17 @@ static int bvd_init(const struct device *dev) {
int rc = 0; int rc = 0;
if (drv_cfg->power_gpios.label) { #if DT_INST_NODE_HAS_PROP(0, power_gpios)
drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label); if (!device_is_ready(drv_cfg->power.port)) {
if (drv_data->gpio == NULL) { LOG_ERR("GPIO port for power control is not ready");
LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label);
return -ENODEV; return -ENODEV;
} }
rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin, rc = gpio_pin_configure_dt(&drv_cfg->power, GPIO_OUTPUT_INACTIVE);
GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags);
if (rc != 0) { if (rc != 0) {
LOG_ERR("Failed to control feed %s.%u: %d", drv_cfg->power_gpios.label, LOG_ERR("Failed to control feed %u: %d", drv_cfg->power.pin, rc);
drv_cfg->power_gpios.pin, rc);
return rc; return rc;
} }
} #endif // DT_INST_NODE_HAS_PROP(0, power_gpios)
drv_data->as = (struct adc_sequence){ drv_data->as = (struct adc_sequence){
.channels = BIT(0), .channels = BIT(0),
@ -175,12 +165,7 @@ static const struct bvd_config bvd_cfg = {
DT_IO_CHANNELS_INPUT(DT_DRV_INST(0)), DT_IO_CHANNELS_INPUT(DT_DRV_INST(0)),
}, },
#if DT_INST_NODE_HAS_PROP(0, power_gpios) #if DT_INST_NODE_HAS_PROP(0, power_gpios)
.power_gpios = .power = GPIO_DT_SPEC_INST_GET(0, power_gpios),
{
DT_INST_GPIO_LABEL(0, power_gpios),
DT_INST_GPIO_PIN(0, power_gpios),
DT_INST_GPIO_FLAGS(0, power_gpios),
},
#endif #endif
.output_ohm = DT_INST_PROP(0, output_ohms), .output_ohm = DT_INST_PROP(0, output_ohms),
.full_ohm = DT_INST_PROP(0, full_ohms), .full_ohm = DT_INST_PROP(0, full_ohms),

View file

@ -19,11 +19,9 @@
LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL); LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL);
static int ec11_get_ab_state(const struct device *dev) { static int ec11_get_ab_state(const struct device *dev) {
struct ec11_data *drv_data = dev->data;
const struct ec11_config *drv_cfg = dev->config; const struct ec11_config *drv_cfg = dev->config;
return (gpio_pin_get(drv_data->a, drv_cfg->a_pin) << 1) | return (gpio_pin_get_dt(&drv_cfg->a) << 1) | gpio_pin_get_dt(&drv_cfg->b);
gpio_pin_get(drv_data->b, drv_cfg->b_pin);
} }
static int ec11_sample_fetch(const struct device *dev, enum sensor_channel chan) { static int ec11_sample_fetch(const struct device *dev, enum sensor_channel chan) {
@ -94,27 +92,25 @@ int ec11_init(const struct device *dev) {
struct ec11_data *drv_data = dev->data; struct ec11_data *drv_data = dev->data;
const struct ec11_config *drv_cfg = dev->config; const struct ec11_config *drv_cfg = dev->config;
LOG_DBG("A: %s %d B: %s %d resolution %d", drv_cfg->a_label, drv_cfg->a_pin, drv_cfg->b_label, LOG_DBG("A: %s %d B: %s %d resolution %d", drv_cfg->a.port->name, drv_cfg->a.pin,
drv_cfg->b_pin, drv_cfg->resolution); drv_cfg->b.port->name, drv_cfg->b.pin, drv_cfg->resolution);
drv_data->a = device_get_binding(drv_cfg->a_label); if (!device_is_ready(drv_cfg->a.port)) {
if (drv_data->a == NULL) { LOG_ERR("A GPIO device is not ready");
LOG_ERR("Failed to get pointer to A GPIO device");
return -EINVAL; return -EINVAL;
} }
drv_data->b = device_get_binding(drv_cfg->b_label); if (!device_is_ready(drv_cfg->b.port)) {
if (drv_data->b == NULL) { LOG_ERR("B GPIO device is not ready");
LOG_ERR("Failed to get pointer to B GPIO device");
return -EINVAL; return -EINVAL;
} }
if (gpio_pin_configure(drv_data->a, drv_cfg->a_pin, drv_cfg->a_flags | GPIO_INPUT)) { if (gpio_pin_configure_dt(&drv_cfg->a, GPIO_INPUT)) {
LOG_DBG("Failed to configure A pin"); LOG_DBG("Failed to configure A pin");
return -EIO; return -EIO;
} }
if (gpio_pin_configure(drv_data->b, drv_cfg->b_pin, drv_cfg->b_flags | GPIO_INPUT)) { if (gpio_pin_configure_dt(&drv_cfg->b, GPIO_INPUT)) {
LOG_DBG("Failed to configure B pin"); LOG_DBG("Failed to configure B pin");
return -EIO; return -EIO;
} }
@ -134,12 +130,8 @@ int ec11_init(const struct device *dev) {
#define EC11_INST(n) \ #define EC11_INST(n) \
struct ec11_data ec11_data_##n; \ struct ec11_data ec11_data_##n; \
const struct ec11_config ec11_cfg_##n = { \ const struct ec11_config ec11_cfg_##n = { \
.a_label = DT_INST_GPIO_LABEL(n, a_gpios), \ .a = GPIO_DT_SPEC_INST_GET(n, a_gpios), \
.a_pin = DT_INST_GPIO_PIN(n, a_gpios), \ .b = GPIO_DT_SPEC_INST_GET(n, b_gpios), \
.a_flags = DT_INST_GPIO_FLAGS(n, a_gpios), \
.b_label = DT_INST_GPIO_LABEL(n, b_gpios), \
.b_pin = DT_INST_GPIO_PIN(n, b_gpios), \
.b_flags = DT_INST_GPIO_FLAGS(n, b_gpios), \
COND_CODE_0(DT_INST_NODE_HAS_PROP(n, resolution), (1), (DT_INST_PROP(n, resolution))), \ COND_CODE_0(DT_INST_NODE_HAS_PROP(n, resolution), (1), (DT_INST_PROP(n, resolution))), \
}; \ }; \
DEVICE_DT_INST_DEFINE(n, ec11_init, NULL, &ec11_data_##n, &ec11_cfg_##n, POST_KERNEL, \ DEVICE_DT_INST_DEFINE(n, ec11_init, NULL, &ec11_data_##n, &ec11_cfg_##n, POST_KERNEL, \

View file

@ -11,20 +11,13 @@
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
struct ec11_config { struct ec11_config {
const char *a_label; const struct gpio_dt_spec a;
const uint8_t a_pin; const struct gpio_dt_spec b;
const uint8_t a_flags;
const char *b_label;
const uint8_t b_pin;
const uint8_t b_flags;
const uint8_t resolution; const uint8_t resolution;
}; };
struct ec11_data { struct ec11_data {
const struct device *a;
const struct device *b;
uint8_t ab_state; uint8_t ab_state;
int8_t pulses; int8_t pulses;
int8_t ticks; int8_t ticks;

View file

@ -20,18 +20,15 @@ extern struct ec11_data ec11_driver;
LOG_MODULE_DECLARE(EC11, CONFIG_SENSOR_LOG_LEVEL); LOG_MODULE_DECLARE(EC11, CONFIG_SENSOR_LOG_LEVEL);
static inline void setup_int(const struct device *dev, bool enable) { static inline void setup_int(const struct device *dev, bool enable) {
struct ec11_data *data = dev->data;
const struct ec11_config *cfg = dev->config; const struct ec11_config *cfg = dev->config;
LOG_DBG("enabled %s", (enable ? "true" : "false")); LOG_DBG("enabled %s", (enable ? "true" : "false"));
if (gpio_pin_interrupt_configure(data->a, cfg->a_pin, if (gpio_pin_interrupt_configure_dt(&cfg->a, enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
LOG_WRN("Unable to set A pin GPIO interrupt"); LOG_WRN("Unable to set A pin GPIO interrupt");
} }
if (gpio_pin_interrupt_configure(data->b, cfg->b_pin, if (gpio_pin_interrupt_configure_dt(&cfg->b, enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
LOG_WRN("Unable to set A pin GPIO interrupt"); LOG_WRN("Unable to set A pin GPIO interrupt");
} }
} }
@ -121,16 +118,16 @@ int ec11_init_interrupt(const struct device *dev) {
drv_data->dev = dev; drv_data->dev = dev;
/* setup gpio interrupt */ /* setup gpio interrupt */
gpio_init_callback(&drv_data->a_gpio_cb, ec11_a_gpio_callback, BIT(drv_cfg->a_pin)); gpio_init_callback(&drv_data->a_gpio_cb, ec11_a_gpio_callback, BIT(drv_cfg->a.pin));
if (gpio_add_callback(drv_data->a, &drv_data->a_gpio_cb) < 0) { if (gpio_add_callback(drv_cfg->a.port, &drv_data->a_gpio_cb) < 0) {
LOG_DBG("Failed to set A callback!"); LOG_DBG("Failed to set A callback!");
return -EIO; return -EIO;
} }
gpio_init_callback(&drv_data->b_gpio_cb, ec11_b_gpio_callback, BIT(drv_cfg->b_pin)); gpio_init_callback(&drv_data->b_gpio_cb, ec11_b_gpio_callback, BIT(drv_cfg->b.pin));
if (gpio_add_callback(drv_data->b, &drv_data->b_gpio_cb) < 0) { if (gpio_add_callback(drv_cfg->b.port, &drv_data->b_gpio_cb) < 0) {
LOG_DBG("Failed to set B callback!"); LOG_DBG("Failed to set B callback!");
return -EIO; return -EIO;
} }

View file

@ -1,29 +0,0 @@
#
# Copyright (c) 2020 Geanix ApS
#
# SPDX-License-Identifier: Apache-2.0
#
description: >
This is a representation of the Microchip MCP23017 I2C Gpio Expander.
compatible: "microchip,mcp23017"
include: [gpio-controller.yaml, i2c-device.yaml]
properties:
label:
required: true
"#gpio-cells":
const: 2
ngpios:
type: int
required: true
const: 16
description: Number of gpios supported
gpio-cells:
- pin
- flags

View file

@ -12,9 +12,6 @@ compatible: "zmk,gpio-595"
include: [gpio-controller.yaml, spi-device.yaml] include: [gpio-controller.yaml, spi-device.yaml]
properties: properties:
label:
required: true
"#gpio-cells": "#gpio-cells":
const: 2 const: 2

View file

@ -4,8 +4,3 @@
description: Battery SoC monitoring using nRF VDDH description: Battery SoC monitoring using nRF VDDH
compatible: "zmk,battery-nrf-vddh" compatible: "zmk,battery-nrf-vddh"
properties:
label:
required: true
type: string

View file

@ -6,8 +6,3 @@ description: Battery SoC monitoring using voltage divider
compatible: "zmk,battery-voltage-divider" compatible: "zmk,battery-voltage-divider"
include: voltage-divider.yaml include: voltage-divider.yaml
properties:
label:
required: true
type: string

View file

@ -25,7 +25,7 @@ int zmk_keymap_position_state_changed(uint8_t source, uint32_t position, bool pr
#define ZMK_KEYMAP_EXTRACT_BINDING(idx, drv_inst) \ #define ZMK_KEYMAP_EXTRACT_BINDING(idx, drv_inst) \
{ \ { \
.behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(drv_inst, bindings, idx)), \ .behavior_dev = DT_PROP(DT_PHANDLE_BY_IDX(drv_inst, bindings, idx), label), \
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param1), (0), \ .param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param1), (0), \
(DT_PHA_BY_IDX(drv_inst, bindings, idx, param1))), \ (DT_PHA_BY_IDX(drv_inst, bindings, idx, param1))), \
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param2), (0), \ .param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param2), (0), \

View file

@ -6,4 +6,6 @@
#pragma once #pragma once
int zmk_kscan_init(char *name); #include <zephyr/device.h>
int zmk_kscan_init(const struct device *dev);

View file

@ -28,8 +28,8 @@ static void behavior_queue_process_next(struct k_work *work) {
struct q_item item = {.wait = 0}; struct q_item item = {.wait = 0};
while (k_msgq_get(&zmk_behavior_queue_msgq, &item, K_NO_WAIT) == 0) { while (k_msgq_get(&zmk_behavior_queue_msgq, &item, K_NO_WAIT) == 0) {
LOG_DBG("Invoking %s: 0x%02x 0x%02x", item.binding.behavior_dev, LOG_DBG("Invoking %s: 0x%02x 0x%02x", item.binding.behavior_dev, item.binding.param1,
item.binding.param1, item.binding.param2); item.binding.param2);
struct zmk_behavior_binding_event event = {.position = item.position, struct zmk_behavior_binding_event event = {.position = item.position,
.timestamp = k_uptime_get()}; .timestamp = k_uptime_get()};

View file

@ -16,7 +16,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <dt-bindings/zmk/bt.h> #include <dt-bindings/zmk/bt.h>
#include <zmk/behavior.h> #include <zmk/behavior.h>
#include <zmk/ble.h> #include <zmk/ble.h>
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)

View file

@ -166,9 +166,10 @@ static int behavior_caps_word_init(const struct device *dev) {
#define CAPS_WORD_LABEL(i, _n) DT_INST_LABEL(i) #define CAPS_WORD_LABEL(i, _n) DT_INST_LABEL(i)
#define PARSE_BREAK(i) \ #define PARSE_BREAK(i) \
{.page = ZMK_HID_USAGE_PAGE(i), \ { \
.id = ZMK_HID_USAGE_ID(i), \ .page = ZMK_HID_USAGE_PAGE(i), .id = ZMK_HID_USAGE_ID(i), \
.implicit_modifiers = SELECT_MODS(i)} .implicit_modifiers = SELECT_MODS(i) \
}
#define BREAK_ITEM(i, n) PARSE_BREAK(DT_INST_PROP_BY_IDX(n, continue_list, i)) #define BREAK_ITEM(i, n) PARSE_BREAK(DT_INST_PROP_BY_IDX(n, continue_list, i))
@ -177,7 +178,7 @@ static int behavior_caps_word_init(const struct device *dev) {
static struct behavior_caps_word_config behavior_caps_word_config_##n = { \ static struct behavior_caps_word_config behavior_caps_word_config_##n = { \
.index = n, \ .index = n, \
.mods = DT_INST_PROP_OR(n, mods, MOD_LSFT), \ .mods = DT_INST_PROP_OR(n, mods, MOD_LSFT), \
.continuations = {LISTIFY(DT_INST_PROP_LEN(n, continue_list), BREAK_ITEM, (,), n)}, \ .continuations = {LISTIFY(DT_INST_PROP_LEN(n, continue_list), BREAK_ITEM, (, ), n)}, \
.continuations_count = DT_INST_PROP_LEN(n, continue_list), \ .continuations_count = DT_INST_PROP_LEN(n, continue_list), \
}; \ }; \
DEVICE_DT_INST_DEFINE(n, behavior_caps_word_init, NULL, &behavior_caps_word_data_##n, \ DEVICE_DT_INST_DEFINE(n, behavior_caps_word_init, NULL, &behavior_caps_word_data_##n, \

View file

@ -700,8 +700,8 @@ static int behavior_hold_tap_init(const struct device *dev) {
#define KP_INST(n) \ #define KP_INST(n) \
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \ static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
.tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \ .tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \
.hold_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 0)), \ .hold_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 0), label), \
.tap_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 1)), \ .tap_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 1), label), \
.quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \ .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \
.global_quick_tap = DT_INST_PROP(n, global_quick_tap), \ .global_quick_tap = DT_INST_PROP(n, global_quick_tap), \
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \

View file

@ -44,13 +44,13 @@ struct behavior_macro_config {
struct zmk_behavior_binding bindings[]; struct zmk_behavior_binding bindings[];
}; };
#define TAP_MODE DT_LABEL(DT_INST(0, zmk_macro_control_mode_tap)) #define TAP_MODE DT_PROP(DT_INST(0, zmk_macro_control_mode_tap), label)
#define PRESS_MODE DT_LABEL(DT_INST(0, zmk_macro_control_mode_press)) #define PRESS_MODE DT_PROP(DT_INST(0, zmk_macro_control_mode_press), label)
#define REL_MODE DT_LABEL(DT_INST(0, zmk_macro_control_mode_release)) #define REL_MODE DT_PROP(DT_INST(0, zmk_macro_control_mode_release), label)
#define TAP_TIME DT_LABEL(DT_INST(0, zmk_macro_control_tap_time)) #define TAP_TIME DT_PROP(DT_INST(0, zmk_macro_control_tap_time), label)
#define WAIT_TIME DT_LABEL(DT_INST(0, zmk_macro_control_wait_time)) #define WAIT_TIME DT_PROP(DT_INST(0, zmk_macro_control_wait_time), label)
#define WAIT_REL DT_LABEL(DT_INST(0, zmk_macro_pause_for_release)) #define WAIT_REL DT_PROP(DT_INST(0, zmk_macro_pause_for_release), label)
#define ZM_IS_NODE_MATCH(a, b) (strcmp(a, b) == 0) #define ZM_IS_NODE_MATCH(a, b) (strcmp(a, b) == 0)
#define IS_TAP_MODE(dev) ZM_IS_NODE_MATCH(dev, TAP_MODE) #define IS_TAP_MODE(dev) ZM_IS_NODE_MATCH(dev, TAP_MODE)
@ -169,7 +169,7 @@ static const struct behavior_driver_api behavior_macro_driver_api = {
#define BINDING_WITH_COMMA(idx, drv_inst) ZMK_KEYMAP_EXTRACT_BINDING(idx, DT_DRV_INST(drv_inst)) #define BINDING_WITH_COMMA(idx, drv_inst) ZMK_KEYMAP_EXTRACT_BINDING(idx, DT_DRV_INST(drv_inst))
#define TRANSFORMED_BEHAVIORS(n) \ #define TRANSFORMED_BEHAVIORS(n) \
{LISTIFY(DT_PROP_LEN(DT_DRV_INST(n), bindings), BINDING_WITH_COMMA, (,), n)}, {LISTIFY(DT_PROP_LEN(DT_DRV_INST(n), bindings), BINDING_WITH_COMMA, (, ), n)},
#define MACRO_INST(n) \ #define MACRO_INST(n) \
static struct behavior_macro_state behavior_macro_state_##n = {}; \ static struct behavior_macro_state behavior_macro_state_##n = {}; \

View file

@ -81,7 +81,7 @@ static int behavior_mod_morph_init(const struct device *dev) { return 0; }
#define _TRANSFORM_ENTRY(idx, node) \ #define _TRANSFORM_ENTRY(idx, node) \
{ \ { \
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ .behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(node, bindings, idx), label), \
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \ .param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
(DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \ (DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \ .param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \

View file

@ -240,7 +240,7 @@ static int behavior_tap_dance_init(const struct device *dev) {
#define _TRANSFORM_ENTRY(idx, node) ZMK_KEYMAP_EXTRACT_BINDING(idx, node) #define _TRANSFORM_ENTRY(idx, node) ZMK_KEYMAP_EXTRACT_BINDING(idx, node)
#define TRANSFORMED_BINDINGS(node) \ #define TRANSFORMED_BINDINGS(node) \
{ LISTIFY(DT_INST_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, (,), DT_DRV_INST(node)) } { LISTIFY(DT_INST_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, (, ), DT_DRV_INST(node)) }
#define KP_INST(n) \ #define KP_INST(n) \
static struct zmk_behavior_binding \ static struct zmk_behavior_binding \

View file

@ -12,7 +12,7 @@
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <drivers/display.h> #include <zephyr/drivers/display.h>
#include <lvgl.h> #include <lvgl.h>
#include "theme.h" #include "theme.h"
@ -21,9 +21,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/events/activity_state_changed.h> #include <zmk/events/activity_state_changed.h>
#include <zmk/display/status_screen.h> #include <zmk/display/status_screen.h>
#define ZMK_DISPLAY_NAME CONFIG_LV_Z_DISPLAY_DEV_NAME static const struct device *display = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
static const struct device *display;
static bool initialized = false; static bool initialized = false;
static lv_obj_t *screen; static lv_obj_t *screen;
@ -103,8 +101,7 @@ static void initialize_theme() {
void initialize_display(struct k_work *work) { void initialize_display(struct k_work *work) {
LOG_DBG(""); LOG_DBG("");
display = device_get_binding(ZMK_DISPLAY_NAME); if (!device_is_ready(display)) {
if (display == NULL) {
LOG_ERR("Failed to find display device"); LOG_ERR("Failed to find display device");
return; return;
} }

View file

@ -22,14 +22,11 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct ext_power_generic_config { struct ext_power_generic_config {
const char *label; const struct gpio_dt_spec control;
const uint8_t pin;
const uint8_t flags;
const uint16_t init_delay_ms; const uint16_t init_delay_ms;
}; };
struct ext_power_generic_data { struct ext_power_generic_data {
const struct device *gpio;
bool status; bool status;
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
bool settings_init; bool settings_init;
@ -39,10 +36,10 @@ struct ext_power_generic_data {
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
static void ext_power_save_state_work(struct k_work *work) { static void ext_power_save_state_work(struct k_work *work) {
char setting_path[40]; char setting_path[40];
const struct device *ext_power = device_get_binding(DT_INST_LABEL(0)); const struct device *ext_power = DEVICE_DT_GET(DT_DRV_INST(0));
struct ext_power_generic_data *data = ext_power->data; struct ext_power_generic_data *data = ext_power->data;
snprintf(setting_path, 40, "ext_power/state/%s", DT_INST_LABEL(0)); snprintf(setting_path, 40, "ext_power/state/%s", DT_INST_PROP(0, label));
settings_save_one(setting_path, &data->status, sizeof(data->status)); settings_save_one(setting_path, &data->status, sizeof(data->status));
} }
@ -62,7 +59,7 @@ static int ext_power_generic_enable(const struct device *dev) {
struct ext_power_generic_data *data = dev->data; struct ext_power_generic_data *data = dev->data;
const struct ext_power_generic_config *config = dev->config; const struct ext_power_generic_config *config = dev->config;
if (gpio_pin_set(data->gpio, config->pin, 1)) { if (gpio_pin_set_dt(&config->control, 1)) {
LOG_WRN("Failed to set ext-power control pin"); LOG_WRN("Failed to set ext-power control pin");
return -EIO; return -EIO;
} }
@ -74,7 +71,8 @@ static int ext_power_generic_disable(const struct device *dev) {
struct ext_power_generic_data *data = dev->data; struct ext_power_generic_data *data = dev->data;
const struct ext_power_generic_config *config = dev->config; const struct ext_power_generic_config *config = dev->config;
if (gpio_pin_set(data->gpio, config->pin, 0)) { if (gpio_pin_set_dt(&config->control, 0)) {
LOG_WRN("Failed to set ext-power control pin");
LOG_WRN("Failed to clear ext-power control pin"); LOG_WRN("Failed to clear ext-power control pin");
return -EIO; return -EIO;
} }
@ -93,7 +91,7 @@ static int ext_power_settings_set(const char *name, size_t len, settings_read_cb
const char *next; const char *next;
int rc; int rc;
if (settings_name_steq(name, DT_INST_LABEL(0), &next) && !next) { if (settings_name_steq(name, DT_INST_PROP(0, label), &next) && !next) {
const struct device *ext_power = DEVICE_DT_GET(DT_DRV_INST(0)); const struct device *ext_power = DEVICE_DT_GET(DT_DRV_INST(0));
struct ext_power_generic_data *data = ext_power->data; struct ext_power_generic_data *data = ext_power->data;
@ -106,7 +104,7 @@ static int ext_power_settings_set(const char *name, size_t len, settings_read_cb
data->settings_init = true; data->settings_init = true;
if (ext_power == NULL) { if (ext_power == NULL) {
LOG_ERR("Unable to retrieve ext_power device: %s", DT_INST_LABEL(0)); LOG_ERR("Unable to retrieve ext_power device: %s", DT_INST_PROP(0, label));
return -EIO; return -EIO;
} }
@ -131,13 +129,7 @@ static int ext_power_generic_init(const struct device *dev) {
struct ext_power_generic_data *data = dev->data; struct ext_power_generic_data *data = dev->data;
const struct ext_power_generic_config *config = dev->config; const struct ext_power_generic_config *config = dev->config;
data->gpio = device_get_binding(config->label); if (gpio_pin_configure_dt(&config->control, GPIO_OUTPUT_INACTIVE)) {
if (data->gpio == NULL) {
LOG_ERR("Failed to get ext-power control device");
return -EINVAL;
}
if (gpio_pin_configure(data->gpio, config->pin, config->flags | GPIO_OUTPUT)) {
LOG_ERR("Failed to configure ext-power control pin"); LOG_ERR("Failed to configure ext-power control pin");
return -EIO; return -EIO;
} }
@ -190,9 +182,7 @@ static int ext_power_generic_pm_action(const struct device *dev, enum pm_device_
#endif /* CONFIG_PM_DEVICE */ #endif /* CONFIG_PM_DEVICE */
static const struct ext_power_generic_config config = { static const struct ext_power_generic_config config = {
.label = DT_INST_GPIO_LABEL(0, control_gpios), .control = GPIO_DT_SPEC_INST_GET(0, control_gpios),
.pin = DT_INST_GPIO_PIN(0, control_gpios),
.flags = DT_INST_GPIO_FLAGS(0, control_gpios),
.init_delay_ms = DT_INST_PROP_OR(0, init_delay_ms, 0)}; .init_delay_ms = DT_INST_PROP_OR(0, init_delay_ms, 0)};
static struct ext_power_generic_data data = { static struct ext_power_generic_data data = {

View file

@ -42,7 +42,7 @@ static uint8_t _zmk_keymap_layer_default = 0;
#if ZMK_KEYMAP_HAS_SENSORS #if ZMK_KEYMAP_HAS_SENSORS
#define _TRANSFORM_SENSOR_ENTRY(idx, layer) \ #define _TRANSFORM_SENSOR_ENTRY(idx, layer) \
{ \ { \
.behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(layer, sensor_bindings, idx)), \ .behavior_dev = DT_PROP(DT_PHANDLE_BY_IDX(layer, sensor_bindings, idx), label), \
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param1), (0), \ .param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param1), (0), \
(DT_PHA_BY_IDX(layer, sensor_bindings, idx, param1))), \ (DT_PHA_BY_IDX(layer, sensor_bindings, idx, param1))), \
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param2), (0), \ .param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param2), (0), \
@ -57,7 +57,8 @@ static uint8_t _zmk_keymap_layer_default = 0;
#endif /* ZMK_KEYMAP_HAS_SENSORS */ #endif /* ZMK_KEYMAP_HAS_SENSORS */
#define LAYER_LABEL(node) COND_CODE_0(DT_NODE_HAS_PROP(node, label), (NULL), (DT_LABEL(node))), #define LAYER_LABEL(node) \
COND_CODE_0(DT_NODE_HAS_PROP(node, label), (NULL), (DT_PROP(node, label))),
// State // State

View file

@ -58,8 +58,7 @@ void zmk_kscan_process_msgq(struct k_work *item) {
} }
} }
int zmk_kscan_init(char *name) { int zmk_kscan_init(const struct device *dev) {
const struct device *dev = device_get_binding(name);
if (dev == NULL) { if (dev == NULL) {
LOG_ERR("Failed to get the KSCAN device"); LOG_ERR("Failed to get the KSCAN device");
return -EINVAL; return -EINVAL;

View file

@ -17,12 +17,10 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/display.h> #include <zmk/display.h>
#include <drivers/ext_power.h> #include <drivers/ext_power.h>
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
void main(void) { void main(void) {
LOG_INF("Welcome to ZMK!\n"); LOG_INF("Welcome to ZMK!\n");
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) { if (zmk_kscan_init(DEVICE_DT_GET(ZMK_MATRIX_NODE_ID)) != 0) {
return; return;
} }

View file

@ -27,8 +27,14 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#define STRIP_LABEL DT_LABEL(DT_CHOSEN(zmk_underglow)) #if !DT_CHOSEN(zmk_underglow)
#define STRIP_NUM_PIXELS DT_PROP(DT_CHOSEN(zmk_underglow), chain_length)
#error "A zmk,underglow chosen node must be declared"
#endif
#define STRIP_CHOSEN DT_CHOSEN(zmk_underglow)
#define STRIP_NUM_PIXELS DT_PROP(STRIP_CHOSEN, chain_length)
#define HUE_MAX 360 #define HUE_MAX 360
#define SAT_MAX 100 #define SAT_MAX 100
@ -230,13 +236,7 @@ static struct k_work_delayable underglow_save_work;
#endif #endif
static int zmk_rgb_underglow_init(const struct device *_arg) { static int zmk_rgb_underglow_init(const struct device *_arg) {
led_strip = device_get_binding(STRIP_LABEL); led_strip = DEVICE_DT_GET(STRIP_CHOSEN);
if (led_strip) {
LOG_INF("Found LED strip device %s", STRIP_LABEL);
} else {
LOG_ERR("LED strip device %s not found", STRIP_LABEL);
return -EINVAL;
}
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER)
ext_power = device_get_binding("EXT_POWER"); ext_power = device_get_binding("EXT_POWER");

View file

@ -65,7 +65,8 @@ static void zmk_sensors_init_item(const char *node, uint8_t i, uint8_t abs_i) {
sensor_trigger_set(sensors[i].dev, &sensors[i].trigger, zmk_sensors_trigger_handler); sensor_trigger_set(sensors[i].dev, &sensors[i].trigger, zmk_sensors_trigger_handler);
} }
#define _SENSOR_INIT(node) zmk_sensors_init_item(DT_LABEL(node), local_index++, absolute_index++); #define _SENSOR_INIT(node) \
zmk_sensors_init_item(DT_PROP(node, label), local_index++, absolute_index++);
#define SENSOR_INIT(idx, _i) \ #define SENSOR_INIT(idx, _i) \
COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx), okay), \ COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx), okay), \
(_SENSOR_INIT(ZMK_KEYMAP_SENSORS_BY_IDX(idx))), (absolute_index++;)) (_SENSOR_INIT(ZMK_KEYMAP_SENSORS_BY_IDX(idx))), (absolute_index++;))

View file

@ -377,8 +377,7 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data) {
bt_uuid_to_str(&uuid.uuid, uuid_str, sizeof(uuid_str)); bt_uuid_to_str(&uuid.uuid, uuid_str, sizeof(uuid_str));
bt_uuid_to_str(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID), service_uuid_str, bt_uuid_to_str(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID), service_uuid_str,
sizeof(service_uuid_str)); sizeof(service_uuid_str));
LOG_DBG("UUID %s does not match split UUID: %s", uuid_str, LOG_DBG("UUID %s does not match split UUID: %s", uuid_str, service_uuid_str);
service_uuid_str);
continue; continue;
} }
@ -433,8 +432,7 @@ static void split_central_device_found(const bt_addr_le_t *addr, int8_t rssi, ui
char dev[BT_ADDR_LE_STR_LEN]; char dev[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(addr, dev, sizeof(dev)); bt_addr_le_to_str(addr, dev, sizeof(dev));
LOG_DBG("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i", dev, type, ad->len, LOG_DBG("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i", dev, type, ad->len, rssi);
rssi);
/* We're only interested in connectable events */ /* We're only interested in connectable events */
if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {

View file

@ -60,8 +60,8 @@ static ssize_t split_svc_run_behavior(struct bt_conn *conn, const struct bt_gatt
.param2 = payload->data.param2, .param2 = payload->data.param2,
.behavior_dev = payload->behavior_dev, .behavior_dev = payload->behavior_dev,
}; };
LOG_DBG("%s with params %d %d: pressed? %d", binding.behavior_dev, LOG_DBG("%s with params %d %d: pressed? %d", binding.behavior_dev, binding.param1,
binding.param1, binding.param2, payload->data.state); binding.param2, payload->data.state);
struct zmk_behavior_binding_event event = {.position = payload->data.position, struct zmk_behavior_binding_event event = {.position = payload->data.position,
.timestamp = k_uptime_get()}; .timestamp = k_uptime_get()};
int err; int err;

View file

@ -258,8 +258,8 @@ An example of this can be seen below, taking the `#define KP_INST(n)` from the h
#define KP_INST(n) \ #define KP_INST(n) \
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \ static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
.tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \ .tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \
.hold_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 0)), \ .hold_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 0), label), \
.tap_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 1)), \ .tap_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 1), label), \
.quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \ .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
.retro_tap = DT_INST_PROP(n, retro_tap), \ .retro_tap = DT_INST_PROP(n, retro_tap), \