diff --git a/CODEOWNERS b/CODEOWNERS index 1d113fa8349..1e3d0b38c19 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -219,7 +219,6 @@ /drivers/flash/ @nashif @nvlsianpu /drivers/flash/*nrf* @nvlsianpu /drivers/gpio/ @mnkp -/drivers/gpio/*ht16k33* @henrikbrixandersen /drivers/gpio/*lmp90xxx* @henrikbrixandersen /drivers/gpio/*stm32* @erwango /drivers/gpio/*eos_s3* @wtatarski @kowalewskijan @kgugala @@ -250,6 +249,7 @@ /drivers/ipm/ipm_nrfx_ipc.h @masz-nordic @ioannisg /drivers/ipm/ipm_stm32_ipcc.c @arnopo /drivers/kscan/ @albertofloyd @franciscomunoz @scottwcpg +/drivers/kscan/*ht16k33* @henrikbrixandersen /drivers/led/ @Mani-Sadhasivam /drivers/led_strip/ @mbolivar-nordic /drivers/lora/ @Mani-Sadhasivam diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 31a5c63cfad..26eb35825ab 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -27,7 +27,6 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SX1509B gpio_sx1509b.c) zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL gpio_intel.c) zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_HT16K33 gpio_ht16k33.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LITEX gpio_litex.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index cb51450bb05..8b71fff389a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -69,8 +69,6 @@ source "drivers/gpio/Kconfig.stellaris" source "drivers/gpio/Kconfig.rv32m1" -source "drivers/gpio/Kconfig.ht16k33" - source "drivers/gpio/Kconfig.lmp90xxx" source "drivers/gpio/Kconfig.litex" diff --git a/drivers/gpio/Kconfig.ht16k33 b/drivers/gpio/Kconfig.ht16k33 deleted file mode 100644 index baa306b9e27..00000000000 --- a/drivers/gpio/Kconfig.ht16k33 +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2019 Henrik Brix Andersen -# SPDX-License-Identifier: Apache-2.0 - -menuconfig GPIO_HT16K33 - bool "HT16K33 keyscan driver" - depends on HT16K33_KEYSCAN - help - Enable keyscan driver for HT16K33. - - The HT16K33 is a memory mapping, multifunction LED - controller driver. The controller supports matrix key scan - circuit of up to 13x3 keys. - - The keyscan functionality is exposed as up to 3 GPIO - controller drivers, each supporting GPIO callbacks for - keyscan event notifications. - -config GPIO_HT16K33_INIT_PRIORITY - int "Driver init priority" - default 99 - depends on GPIO_HT16K33 - help - Device driver initialization priority. This driver must be - initialized after the HT16K33 LED driver. diff --git a/drivers/gpio/gpio_ht16k33.c b/drivers/gpio/gpio_ht16k33.c deleted file mode 100644 index 1f7dedba707..00000000000 --- a/drivers/gpio/gpio_ht16k33.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2019 Henrik Brix Andersen - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT holtek_ht16k33_keyscan - -/** - * @file - * @brief GPIO driver for the HT16K33 I2C LED driver with keyscan - */ - -#include -#include - -#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL -#include -LOG_MODULE_REGISTER(gpio_ht16k33); - -#include - -#include "gpio_utils.h" - -/* HT16K33 size definitions */ -#define HT16K33_KEYSCAN_ROWS 3 - -struct gpio_ht16k33_cfg { - /* gpio_driver_config needs to be first */ - struct gpio_driver_config common; - char *parent_dev_name; - uint8_t keyscan_idx; -}; - -struct gpio_ht16k33_data { - /* gpio_driver_data needs to be first */ - struct gpio_driver_data common; - const struct device *parent; - sys_slist_t callbacks; -}; - -static int gpio_ht16k33_cfg(const struct device *dev, - gpio_pin_t pin, - gpio_flags_t flags) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pin); - - /* Keyscan is input-only */ - if (((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) - || ((flags & GPIO_OUTPUT) != 0)) { - return -ENOTSUP; - } - - return 0; -} - -static int gpio_ht16k33_port_get_raw(const struct device *port, - gpio_port_value_t *value) -{ - ARG_UNUSED(port); - ARG_UNUSED(value); - - /* Keyscan only supports interrupt mode */ - return -ENOTSUP; -} - -static int gpio_ht16k33_port_set_masked_raw(const struct device *port, - gpio_port_pins_t mask, - gpio_port_value_t value) -{ - ARG_UNUSED(port); - ARG_UNUSED(mask); - ARG_UNUSED(value); - - /* Keyscan is input-only */ - return -ENOTSUP; -} - -static int gpio_ht16k33_port_set_bits_raw(const struct device *port, - gpio_port_pins_t pins) -{ - ARG_UNUSED(port); - ARG_UNUSED(pins); - - /* Keyscan is input-only */ - return -ENOTSUP; -} - -static int gpio_ht16k33_port_clear_bits_raw(const struct device *port, - gpio_port_pins_t pins) -{ - ARG_UNUSED(port); - ARG_UNUSED(pins); - - /* Keyscan is input-only */ - return -ENOTSUP; -} - -static int gpio_ht16k33_port_toggle_bits(const struct device *port, - gpio_port_pins_t pins) -{ - ARG_UNUSED(port); - ARG_UNUSED(pins); - - /* Keyscan is input-only */ - return -ENOTSUP; -} - -static int gpio_ht16k33_pin_interrupt_configure(const struct device *port, - gpio_pin_t pin, - enum gpio_int_mode int_mode, - enum gpio_int_trig int_trig) -{ - ARG_UNUSED(port); - ARG_UNUSED(pin); - ARG_UNUSED(int_mode); - ARG_UNUSED(int_trig); - - /* Interrupts are always enabled */ - return 0; -} - -void ht16k33_process_keyscan_row_data(const struct device *dev, - uint32_t keys) -{ - struct gpio_ht16k33_data *data = dev->data; - - gpio_fire_callbacks(&data->callbacks, dev, keys); -} - -static int gpio_ht16k33_manage_callback(const struct device *dev, - struct gpio_callback *callback, - bool set) -{ - struct gpio_ht16k33_data *data = dev->data; - - return gpio_manage_callback(&data->callbacks, callback, set); -} - -static uint32_t gpio_ht16k33_get_pending_int(const struct device *dev) -{ - struct gpio_ht16k33_data *data = dev->data; - - return ht16k33_get_pending_int(data->parent); -} - -static int gpio_ht16k33_init(const struct device *dev) -{ - const struct gpio_ht16k33_cfg *config = dev->config; - struct gpio_ht16k33_data *data = dev->data; - - if (config->keyscan_idx >= HT16K33_KEYSCAN_ROWS) { - LOG_ERR("HT16K33 keyscan index out of bounds (%d)", - config->keyscan_idx); - return -EINVAL; - } - - /* Establish reference to parent and vice versa */ - data->parent = device_get_binding(config->parent_dev_name); - if (!data->parent) { - LOG_ERR("HT16K33 parent device '%s' not found", - config->parent_dev_name); - return -EINVAL; - } - - return ht16k33_register_keyscan_device(data->parent, dev, - config->keyscan_idx); -} - -static const struct gpio_driver_api gpio_ht16k33_api = { - .pin_configure = gpio_ht16k33_cfg, - .port_get_raw = gpio_ht16k33_port_get_raw, - .port_set_masked_raw = gpio_ht16k33_port_set_masked_raw, - .port_set_bits_raw = gpio_ht16k33_port_set_bits_raw, - .port_clear_bits_raw = gpio_ht16k33_port_clear_bits_raw, - .port_toggle_bits = gpio_ht16k33_port_toggle_bits, - .pin_interrupt_configure = gpio_ht16k33_pin_interrupt_configure, - .manage_callback = gpio_ht16k33_manage_callback, - .get_pending_int = gpio_ht16k33_get_pending_int, -}; - -#define GPIO_HT16K33_DEVICE(id) \ - static const struct gpio_ht16k33_cfg gpio_ht16k33_##id##_cfg = {\ - .common = { \ - .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_NGPIOS(13), \ - }, \ - .parent_dev_name = \ - DT_INST_BUS_LABEL(id), \ - .keyscan_idx = \ - DT_INST_REG_ADDR(id), \ - }; \ - \ - static struct gpio_ht16k33_data gpio_ht16k33_##id##_data; \ - \ - DEVICE_DT_INST_DEFINE(id, \ - &gpio_ht16k33_init, \ - NULL, \ - &gpio_ht16k33_##id##_data, \ - &gpio_ht16k33_##id##_cfg, POST_KERNEL, \ - CONFIG_GPIO_HT16K33_INIT_PRIORITY, \ - &gpio_ht16k33_api); - -DT_INST_FOREACH_STATUS_OKAY(GPIO_HT16K33_DEVICE) diff --git a/drivers/kscan/CMakeLists.txt b/drivers/kscan/CMakeLists.txt index 8e1271076d2..10571e991c5 100644 --- a/drivers/kscan/CMakeLists.txt +++ b/drivers/kscan/CMakeLists.txt @@ -5,5 +5,6 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_KSCAN_FT5336 kscan_ft5336.c) zephyr_library_sources_ifdef(CONFIG_KSCAN_XEC kscan_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_KSCAN_SDL kscan_sdl.c) +zephyr_library_sources_ifdef(CONFIG_KSCAN_HT16K33 kscan_ht16k33.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE kscan_handlers.c) diff --git a/drivers/kscan/Kconfig b/drivers/kscan/Kconfig index 1998f83c1c0..04592219f1d 100644 --- a/drivers/kscan/Kconfig +++ b/drivers/kscan/Kconfig @@ -13,6 +13,7 @@ if KSCAN source "drivers/kscan/Kconfig.ft5336" source "drivers/kscan/Kconfig.xec" source "drivers/kscan/Kconfig.sdl" +source "drivers/kscan/Kconfig.ht16k33" module = KSCAN module-str = kscan diff --git a/drivers/kscan/Kconfig.ht16k33 b/drivers/kscan/Kconfig.ht16k33 new file mode 100644 index 00000000000..117f8b1b703 --- /dev/null +++ b/drivers/kscan/Kconfig.ht16k33 @@ -0,0 +1,12 @@ +# Copyright (c) 2019 - 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config KSCAN_HT16K33 + bool "HT16K33 keyscan driver" + depends on HT16K33_KEYSCAN + help + Enable keyscan driver for HT16K33. + + The HT16K33 is a memory mapping, multifunction LED + controller driver. The controller supports matrix key scan + circuit of up to 13x3 keys. diff --git a/drivers/kscan/kscan_ht16k33.c b/drivers/kscan/kscan_ht16k33.c new file mode 100644 index 00000000000..7434211f52e --- /dev/null +++ b/drivers/kscan/kscan_ht16k33.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 - 2021 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT holtek_ht16k33_keyscan + +/** + * @file + * @brief Keyscan driver for the HT16K33 I2C LED driver + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(kscan_ht16k33, CONFIG_KSCAN_LOG_LEVEL); + +BUILD_ASSERT(CONFIG_KSCAN_INIT_PRIORITY > CONFIG_LED_INIT_PRIORITY, + "HT16K33 keyscan driver must be initialized after HT16K33 LED driver"); + +struct kscan_ht16k33_cfg { + const struct device *parent; +}; + +static int kscan_ht16k33_config(const struct device *dev, + kscan_callback_t callback) +{ + const struct kscan_ht16k33_cfg *config = dev->config; + + return ht16k33_register_keyscan_callback(config->parent, dev, callback); +} + +static int kscan_ht16k33_init(const struct device *dev) +{ + const struct kscan_ht16k33_cfg *config = dev->config; + + if (!device_is_ready(config->parent)) { + LOG_ERR("HT16K33 parent device not ready"); + return -EINVAL; + } + + return 0; +} + +static const struct kscan_driver_api kscan_ht16k33_api = { + .config = kscan_ht16k33_config, +}; + +#define KSCAN_HT16K33_DEVICE(id) \ + static const struct kscan_ht16k33_cfg kscan_ht16k33_##id##_cfg = { \ + .parent = DEVICE_DT_GET(DT_INST_BUS(id)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(id, &kscan_ht16k33_init, \ + NULL, NULL, \ + &kscan_ht16k33_##id##_cfg, POST_KERNEL, \ + CONFIG_KSCAN_INIT_PRIORITY, \ + &kscan_ht16k33_api); + +DT_INST_FOREACH_STATUS_OKAY(KSCAN_HT16K33_DEVICE) diff --git a/drivers/led/Kconfig.ht16k33 b/drivers/led/Kconfig.ht16k33 index fb13424059f..43cff73241e 100644 --- a/drivers/led/Kconfig.ht16k33 +++ b/drivers/led/Kconfig.ht16k33 @@ -13,14 +13,14 @@ menuconfig HT16K33 config HT16K33_KEYSCAN bool "Enable keyscan support" - depends on (HT16K33 && GPIO) - select GPIO_HT16K33 + depends on (HT16K33 && KSCAN) + select KSCAN_HT16K33 help Enable keyscan child device support in the HT16K33 LED driver. The keyscan functionality itself is handled by the - HT16K33 GPIO driver. + HT16K33 keyscan driver. if HT16K33_KEYSCAN diff --git a/drivers/led/ht16k33.c b/drivers/led/ht16k33.c index 79a16ff1880..a72bc4cd594 100644 --- a/drivers/led/ht16k33.c +++ b/drivers/led/ht16k33.c @@ -15,14 +15,11 @@ #include #include #include -#include -#include - -#define LOG_LEVEL CONFIG_LED_LOG_LEVEL -#include -LOG_MODULE_REGISTER(ht16k33); - #include +#include +#include + +LOG_MODULE_REGISTER(ht16k33, CONFIG_LED_LOG_LEVEL); #include "led_context.h" @@ -83,7 +80,8 @@ struct ht16k33_data { uint8_t buffer[HT16K33_DISP_DATA_SIZE]; #ifdef CONFIG_HT16K33_KEYSCAN struct k_mutex lock; - const struct device *children[HT16K33_KEYSCAN_ROWS]; + const struct device *child; + kscan_callback_t kscan_cb; struct gpio_callback irq_cb; struct k_thread irq_thread; struct k_sem irq_sem; @@ -123,7 +121,7 @@ static int ht16k33_led_blink(const struct device *dev, uint32_t led, cmd |= HT16K33_OPT_BLINK_2HZ; } - if (i2c_write(data->i2c, &cmd, 1, config->i2c_addr)) { + if (i2c_write(data->i2c, &cmd, sizeof(cmd), config->i2c_addr)) { LOG_ERR("Setting HT16K33 blink frequency failed"); return -EIO; } @@ -150,7 +148,7 @@ static int ht16k33_led_set_brightness(const struct device *dev, uint32_t led, dim = (value * (HT16K33_DIMMING_LEVELS - 1)) / dev_data->max_brightness; cmd = HT16K33_CMD_DIMMING_SET | dim; - if (i2c_write(data->i2c, &cmd, 1, config->i2c_addr)) { + if (i2c_write(data->i2c, &cmd, sizeof(cmd), config->i2c_addr)) { LOG_ERR("Setting HT16K33 brightness failed"); return -EIO; } @@ -206,35 +204,17 @@ static int ht16k33_led_off(const struct device *dev, uint32_t led) } #ifdef CONFIG_HT16K33_KEYSCAN -uint32_t ht16k33_get_pending_int(const struct device *dev) -{ - const struct ht16k33_cfg *config = dev->config; - struct ht16k33_data *data = dev->data; - uint8_t cmd; - uint8_t flag; - int err; - - cmd = HT16K33_CMD_INT_FLAG_ADDR; - err = i2c_write_read(data->i2c, config->i2c_addr, &cmd, sizeof(cmd), - &flag, sizeof(flag)); - if (err) { - LOG_ERR("Failed to read HT16K33 IRQ flag"); - return 0; - } - - return (flag ? 1 : 0); -} - static bool ht16k33_process_keyscan_data(const struct device *dev) { const struct ht16k33_cfg *config = dev->config; struct ht16k33_data *data = dev->data; uint8_t keys[HT16K33_KEYSCAN_DATA_SIZE]; bool pressed = false; - uint16_t row; - uint16_t new; + uint16_t state; + uint16_t changed; + int row; + int col; int err; - int i; err = i2c_burst_read(data->i2c, config->i2c_addr, HT16K33_CMD_KEY_DATA_ADDR, keys, @@ -245,19 +225,28 @@ static bool ht16k33_process_keyscan_data(const struct device *dev) } k_mutex_lock(&data->lock, K_FOREVER); - for (i = 0; i < HT16K33_KEYSCAN_ROWS; i++) { - row = sys_get_le16(&keys[i * 2]); - if (row) { + + for (row = 0; row < HT16K33_KEYSCAN_ROWS; row++) { + state = sys_get_le16(&keys[row * 2]); + changed = data->key_state[row] ^ state; + data->key_state[row] = state; + + if (state) { pressed = true; - new = data->key_state[i] ^ row; - new &= row; - if (data->children[i] && new) { - ht16k33_process_keyscan_row_data( - data->children[i], new); + } + + if (data->kscan_cb == NULL) { + continue; + } + + for (col = 0; col < HT16K33_KEYSCAN_COLS; col++) { + if (changed & BIT(col)) { + data->kscan_cb(data->child, row, col, + state & BIT(col)); } } - data->key_state[i] = row; } + k_mutex_unlock(&data->lock); return pressed; @@ -298,22 +287,15 @@ static void ht16k33_timer_callback(struct k_timer *timer) k_sem_give(&data->irq_sem); } -int ht16k33_register_keyscan_device(const struct device *parent, - const struct device *child, - uint8_t keyscan_idx) +int ht16k33_register_keyscan_callback(const struct device *parent, + const struct device *child, + kscan_callback_t callback) { struct ht16k33_data *data = parent->data; k_mutex_lock(&data->lock, K_FOREVER); - - if (data->children[keyscan_idx]) { - k_mutex_unlock(&data->lock); - LOG_ERR("HT16K33 keyscan device %d already registered", - keyscan_idx); - return -EINVAL; - } - - data->children[keyscan_idx] = child; + data->child = child; + data->kscan_cb = callback; k_mutex_unlock(&data->lock); return 0; @@ -379,7 +361,6 @@ static int ht16k33_init(const struct device *dev) } #ifdef CONFIG_HT16K33_KEYSCAN - memset(&data->children, 0, sizeof(data->children)); k_mutex_init(&data->lock); k_sem_init(&data->irq_sem, 0, 1); diff --git a/dts/bindings/gpio/holtek,ht16k33-keyscan.yaml b/dts/bindings/kscan/holtek,ht16k33-keyscan.yaml similarity index 51% rename from dts/bindings/gpio/holtek,ht16k33-keyscan.yaml rename to dts/bindings/kscan/holtek,ht16k33-keyscan.yaml index 8028db8ff79..5ab63b1b0e1 100644 --- a/dts/bindings/gpio/holtek,ht16k33-keyscan.yaml +++ b/dts/bindings/kscan/holtek,ht16k33-keyscan.yaml @@ -1,4 +1,4 @@ -description: Holtek HT16K33 LED driver with keyscan +description: Holtek HT16K33 keyscan compatible: "holtek,ht16k33-keyscan" @@ -7,11 +7,5 @@ include: base.yaml on-bus: ht16k33 properties: - reg: - required: true label: required: true - -gpio-cells: - - pin - - flags diff --git a/dts/bindings/led/holtek,ht16k33.yaml b/dts/bindings/led/holtek,ht16k33.yaml index 65680a8e1af..4c373a1fc58 100644 --- a/dts/bindings/led/holtek,ht16k33.yaml +++ b/dts/bindings/led/holtek,ht16k33.yaml @@ -7,12 +7,6 @@ include: i2c-device.yaml bus: ht16k33 properties: - "#address-cells": - required: true - const: 1 - "#size-cells": - required: true - const: 0 label: required: true irq-gpios: diff --git a/include/drivers/led/ht16k33.h b/include/drivers/led/ht16k33.h index c73c62e003d..7352121561e 100644 --- a/include/drivers/led/ht16k33.h +++ b/include/drivers/led/ht16k33.h @@ -8,40 +8,20 @@ #ifndef ZEPHYR_INCLUDE_DRIVERS_LED_HT16K33_H_ #define ZEPHYR_INCLUDE_DRIVERS_LED_HT16K33_H_ -#include -#include +#include /** * Register a HT16K33 keyscan device to be notified of relevant * keyscan events by the keyscan interrupt thread in the HT16K33 * parent driver. * - * @param parent HT16K33 parent device. - * @param child HT16K33 keyscan child device. - * @param keyscan_idx Index of the keyscan line handled by the keyscan - * child device (0, 1, or 2). + * @param parent HT16K33 parent device. + * @param child HT16K33 child device. + * @param callback Keyscan callback function. * @return 0 if successful, negative errno code on failure. */ -int ht16k33_register_keyscan_device(const struct device *parent, - const struct device *child, - uint8_t keyscan_idx); - -/** - * Check if a HT16K33 keyscan interrupt is pending. - * - * @param parent HT16K33 parent device. - * @return status != 0 if an interrupt is pending. - */ -uint32_t ht16k33_get_pending_int(const struct device *parent); - -/** - * Dispatch keyscan row data from a keyscan event to be handled by a - * HT16K33 keyscan GPIO child device. - * - * @param child HT16K33 keyscan child device. - * @param keys Bitmask of key state for the row. - */ -void ht16k33_process_keyscan_row_data(const struct device *child, - uint32_t keys); +int ht16k33_register_keyscan_callback(const struct device *parent, + const struct device *child, + kscan_callback_t callback); #endif /* ZEPHYR_INCLUDE_DRIVERS_LED_HT16K33_H_ */ diff --git a/samples/drivers/ht16k33/boards/nrf52840dk_nrf52840.overlay b/samples/drivers/ht16k33/boards/nrf52840dk_nrf52840.overlay index 98650dd2d45..6e005a707d3 100644 --- a/samples/drivers/ht16k33/boards/nrf52840dk_nrf52840.overlay +++ b/samples/drivers/ht16k33/boards/nrf52840dk_nrf52840.overlay @@ -13,23 +13,10 @@ label = "HT16K33"; /* Uncomment to use IRQ instead of polling: */ /* irq-gpios = <&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; */ - #address-cells = <1>; - #size-cells = <0>; - ks@0 { + keyscan { compatible = "holtek,ht16k33-keyscan"; - reg = <0x0>; - label = "KS0"; - }; - ks@1 { - compatible = "holtek,ht16k33-keyscan"; - reg = <0x1>; - label = "KS1"; - }; - ks@2 { - compatible = "holtek,ht16k33-keyscan"; - reg = <0x2>; - label = "KS2"; + label = "KEYSCAN"; }; }; }; diff --git a/samples/drivers/ht16k33/prj.conf b/samples/drivers/ht16k33/prj.conf index ff3d92b65c3..16b235a3398 100644 --- a/samples/drivers/ht16k33/prj.conf +++ b/samples/drivers/ht16k33/prj.conf @@ -1,6 +1,7 @@ CONFIG_LOG=y CONFIG_I2C=y -CONFIG_GPIO=y CONFIG_LED=y +CONFIG_KSCAN=y +CONFIG_KSCAN_INIT_PRIORITY=95 CONFIG_HT16K33=y CONFIG_HT16K33_KEYSCAN=y diff --git a/samples/drivers/ht16k33/src/main.c b/samples/drivers/ht16k33/src/main.c index 162a857a564..21e7c8156d3 100644 --- a/samples/drivers/ht16k33/src/main.c +++ b/samples/drivers/ht16k33/src/main.c @@ -4,90 +4,69 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include -#include - -#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#include #include -LOG_MODULE_REGISTER(main); -#define LED_DEV_NAME DT_LABEL(DT_INST(0, holtek_ht16k33)) -#define KS0_DEV_NAME DT_LABEL(DT_INST(0, holtek_ht16k33_keyscan)) -#define KS1_DEV_NAME DT_LABEL(DT_INST(1, holtek_ht16k33_keyscan)) -#define KS2_DEV_NAME DT_LABEL(DT_INST(2, holtek_ht16k33_keyscan)) +LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL); -#define KEYSCAN_DEVICES 3 +#define LED_NODE DT_INST(0, holtek_ht16k33) +#define KEY_NODE DT_INST(0, holtek_ht16k33_keyscan) -const struct device *led_dev; -const struct device *ks_dev[KEYSCAN_DEVICES]; -static struct gpio_callback ks_cb[KEYSCAN_DEVICES]; - -static void keyscan_callback(const struct device *gpiob, - struct gpio_callback *cb, uint32_t pins) +static void keyscan_callback(const struct device *dev, uint32_t row, + uint32_t column, bool pressed) { - LOG_INF("%s: 0x%08x", gpiob->name, pins); + LOG_INF("Row %d, column %d %s", row, column, + pressed ? "pressed" : "released"); } void main(void) { + const struct device *led = DEVICE_DT_GET(LED_NODE); + const struct device *key = DEVICE_DT_GET(KEY_NODE); int err; int i; - /* LED device binding */ - led_dev = device_get_binding(LED_DEV_NAME); - if (!led_dev) { - LOG_ERR("LED device %s not found", LED_DEV_NAME); + if (!device_is_ready(led)) { + LOG_ERR("LED device not ready"); return; } - /* Keyscan device bindings */ - ks_dev[0] = device_get_binding(KS0_DEV_NAME); - ks_dev[1] = device_get_binding(KS1_DEV_NAME); - ks_dev[2] = device_get_binding(KS2_DEV_NAME); - for (i = 0; i < ARRAY_SIZE(ks_dev); i++) { - if (!ks_dev[i]) { - LOG_ERR("KS%d device not found", i); - return; - } + if (!device_is_ready(key)) { + LOG_ERR("Keyscan device not ready"); + return; + } - gpio_init_callback(&ks_cb[i], &keyscan_callback, - GENMASK(12, 0)); - - err = gpio_add_callback(ks_dev[i], &ks_cb[i]); - if (err) { - LOG_ERR("Failed to add KS%d GPIO callback (err %d)", i, - err); - return; - } + err = kscan_config(key, keyscan_callback); + if (err) { + LOG_ERR("Failed to add keyscan callback (err %d)", err); } while (1) { LOG_INF("Iterating through all LEDs, turning them on " "one-by-one"); for (i = 0; i < 128; i++) { - led_on(led_dev, i); + led_on(led, i); k_sleep(K_MSEC(100)); } for (i = 500; i <= 2000; i *= 2) { LOG_INF("Blinking LEDs with a period of %d ms", i); - led_blink(led_dev, 0, i / 2, i / 2); + led_blink(led, 0, i / 2, i / 2); k_msleep(10 * i); } - led_blink(led_dev, 0, 0, 0); + led_blink(led, 0, 0, 0); for (i = 100; i >= 0; i -= 10) { LOG_INF("Setting LED brightness to %d%%", i); - led_set_brightness(led_dev, 0, i); + led_set_brightness(led, 0, i); k_sleep(K_MSEC(1000)); } LOG_INF("Turning all LEDs off and restoring 100%% brightness"); for (i = 0; i < 128; i++) { - led_off(led_dev, i); + led_off(led, i); } - led_set_brightness(led_dev, 0, 100); + led_set_brightness(led, 0, 100); } }