summaryrefslogtreecommitdiff
path: root/app/drivers/zephyr
diff options
context:
space:
mode:
Diffstat (limited to 'app/drivers/zephyr')
-rw-r--r--app/drivers/zephyr/CMakeLists.txt14
-rw-r--r--app/drivers/zephyr/Kconfig79
-rw-r--r--app/drivers/zephyr/battery_voltage_divider.c217
-rw-r--r--app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-demux.yaml (renamed from app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-demux.yaml)0
-rw-r--r--app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml (renamed from app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-direct.yaml)0
-rw-r--r--app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml (renamed from app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-matrix.yaml)0
-rw-r--r--app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml (renamed from app/drivers/zephyr/dts/bindings/alps,ec11.yaml)0
-rw-r--r--app/drivers/zephyr/dts/bindings/sensor/zmk,battery-voltage-divider.yaml (renamed from app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml)0
-rw-r--r--app/drivers/zephyr/ec11.c148
-rw-r--r--app/drivers/zephyr/ec11.h58
-rw-r--r--app/drivers/zephyr/ec11_trigger.c148
-rw-r--r--app/drivers/zephyr/kscan_gpio_demux.c254
-rw-r--r--app/drivers/zephyr/kscan_gpio_direct.c247
-rw-r--r--app/drivers/zephyr/kscan_gpio_matrix.c294
-rw-r--r--app/drivers/zephyr/module.yml4
15 files changed, 2 insertions, 1461 deletions
diff --git a/app/drivers/zephyr/CMakeLists.txt b/app/drivers/zephyr/CMakeLists.txt
deleted file mode 100644
index e3a192d..0000000
--- a/app/drivers/zephyr/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-if(CONFIG_ZMK_KSCAN_GPIO_DRIVER)
- zephyr_include_directories(.)
-
- zephyr_library()
- zephyr_library_sources(
- kscan_gpio_matrix.c
- kscan_gpio_direct.c
- kscan_gpio_demux.c
- )
-
- zephyr_library_sources_ifdef(CONFIG_EC11 ec11.c)
- zephyr_library_sources_ifdef(CONFIG_EC11_TRIGGER ec11_trigger.c)
- zephyr_library_sources_ifdef(CONFIG_ZMK_BATTERY_VOLTAGE_DIVIDER battery_voltage_divider.c)
-endif()
diff --git a/app/drivers/zephyr/Kconfig b/app/drivers/zephyr/Kconfig
deleted file mode 100644
index b8b2b1b..0000000
--- a/app/drivers/zephyr/Kconfig
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (c) 2020 The ZMK Contributors
-# SPDX-License-Identifier: MIT
-
-config ZMK_KSCAN_GPIO_DRIVER
- bool "Enable GPIO kscan driver to simulate key presses"
- default y
- select GPIO
-
-if ZMK_KSCAN_GPIO_DRIVER
-
-config ZMK_KSCAN_MATRIX_POLLING
- bool "Poll for key event triggers instead of using interrupts on matrix boards."
- default n
-
-config ZMK_KSCAN_DIRECT_POLLING
- bool "Poll for key event triggers instead of using interrupts on direct wired boards."
- default n
-
-endif
-
-config ZMK_KSCAN_INIT_PRIORITY
- int "Keyboard scan driver init priority"
- default 40
- help
- Keyboard scan device driver initialization priority.
-
-config ZMK_BATTERY_VOLTAGE_DIVIDER
- bool "ZMK battery voltage divider"
- select ADC
- help
- Enable ZMK battery voltage divider driver for battery monitoring.
-
-menuconfig EC11
- bool "EC11 Incremental Encoder Sensor"
- depends on GPIO
- help
- Enable driver for EC11 incremental encoder sensors.
-
-if EC11
-
-choice
- prompt "Trigger mode"
- default EC11_TRIGGER_NONE
- help
- Specify the type of triggering to be used by the driver.
-
-config EC11_TRIGGER_NONE
- bool "No trigger"
-
-config EC11_TRIGGER_GLOBAL_THREAD
- bool "Use global thread"
- depends on GPIO
- select EC11_TRIGGER
-
-config EC11_TRIGGER_OWN_THREAD
- bool "Use own thread"
- depends on GPIO
- select EC11_TRIGGER
-
-endchoice
-
-config EC11_TRIGGER
- bool
-
-config EC11_THREAD_PRIORITY
- int "Thread priority"
- depends on EC11_TRIGGER_OWN_THREAD
- default 10
- help
- Priority of thread used by the driver to handle interrupts.
-
-config EC11_THREAD_STACK_SIZE
- int "Thread stack size"
- depends on EC11_TRIGGER_OWN_THREAD
- default 1024
- help
- Stack size of thread used by the driver to handle interrupts.
-
-endif # EC11
diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c
deleted file mode 100644
index d634dfd..0000000
--- a/app/drivers/zephyr/battery_voltage_divider.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT zmk_battery_voltage_divider
-
-#include <device.h>
-#include <drivers/gpio.h>
-#include <drivers/adc.h>
-#include <drivers/sensor.h>
-#include <logging/log.h>
-
-LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
-
-struct io_channel_config {
- const char *label;
- uint8_t channel;
-};
-
-struct gpio_channel_config {
- const char *label;
- uint8_t pin;
- uint8_t flags;
-};
-
-struct bvd_config {
- struct io_channel_config io_channel;
- struct gpio_channel_config power_gpios;
- uint32_t output_ohm;
- uint32_t full_ohm;
-};
-
-struct bvd_data {
- struct device *adc;
- struct device *gpio;
- struct adc_channel_cfg acc;
- struct adc_sequence as;
- uint16_t adc_raw;
- uint16_t voltage;
- uint8_t state_of_charge;
-};
-
-static uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) {
- // Simple linear approximation of a battery based off adafruit's discharge graph:
- // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages
-
- if (bat_mv >= 4200) {
- return 100;
- } else if (bat_mv <= 3450) {
- return 0;
- }
-
- return bat_mv * 2 / 15 - 459;
-}
-
-static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) {
- struct bvd_data *drv_data = dev->driver_data;
- const struct bvd_config *drv_cfg = dev->config_info;
- struct adc_sequence *as = &drv_data->as;
-
- // Make sure selected channel is supported
- if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE &&
- chan != SENSOR_CHAN_ALL) {
- LOG_DBG("Selected channel is not supported: %d.", chan);
- return -ENOTSUP;
- }
-
- int rc = 0;
-
- // Enable power GPIO if present
- if (drv_data->gpio) {
- rc = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 1);
-
- if (rc != 0) {
- LOG_DBG("Failed to enable ADC power GPIO: %d", rc);
- return rc;
- }
- }
-
- // Read ADC
- rc = adc_read(drv_data->adc, as);
- as->calibrate = false;
-
- if (rc == 0) {
- int32_t val = drv_data->adc_raw;
-
- adc_raw_to_millivolts(adc_ref_internal(drv_data->adc), drv_data->acc.gain, as->resolution,
- &val);
-
- uint16_t millivolts = val * (uint64_t)drv_cfg->full_ohm / drv_cfg->output_ohm;
- LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", drv_data->adc_raw, val, millivolts);
- uint8_t percent = lithium_ion_mv_to_pct(millivolts);
- LOG_DBG("Percent: %d", percent);
-
- drv_data->voltage = millivolts;
- drv_data->state_of_charge = percent;
- } else {
- LOG_DBG("Failed to read ADC: %d", rc);
- }
-
- // Disable power GPIO if present
- if (drv_data->gpio) {
- int rc2 = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 0);
-
- if (rc2 != 0) {
- LOG_DBG("Failed to disable ADC power GPIO: %d", rc2);
- return rc2;
- }
- }
-
- return rc;
-}
-
-static int bvd_channel_get(struct device *dev, enum sensor_channel chan, struct sensor_value *val) {
- struct bvd_data *drv_data = dev->driver_data;
-
- switch (chan) {
- case SENSOR_CHAN_GAUGE_VOLTAGE:
- val->val1 = drv_data->voltage / 1000;
- val->val2 = (drv_data->voltage % 1000) * 1000U;
- break;
-
- case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE:
- val->val1 = drv_data->state_of_charge;
- val->val2 = 0;
- break;
-
- default:
- return -ENOTSUP;
- }
-
- return 0;
-}
-
-static const struct sensor_driver_api bvd_api = {
- .sample_fetch = bvd_sample_fetch,
- .channel_get = bvd_channel_get,
-};
-
-static int bvd_init(struct device *dev) {
- struct bvd_data *drv_data = dev->driver_data;
- const struct bvd_config *drv_cfg = dev->config_info;
-
- drv_data->adc = device_get_binding(drv_cfg->io_channel.label);
-
- if (drv_data->adc == NULL) {
- LOG_ERR("ADC %s failed to retrieve", drv_cfg->io_channel.label);
- return -ENODEV;
- }
-
- int rc = 0;
-
- if (drv_cfg->power_gpios.label) {
- drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label);
- if (drv_data->gpio == NULL) {
- LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label);
- return -ENODEV;
- }
- rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin,
- GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags);
- if (rc != 0) {
- LOG_ERR("Failed to control feed %s.%u: %d", drv_cfg->power_gpios.label,
- drv_cfg->power_gpios.pin, rc);
- return rc;
- }
- }
-
- drv_data->as = (struct adc_sequence){
- .channels = BIT(0),
- .buffer = &drv_data->adc_raw,
- .buffer_size = sizeof(drv_data->adc_raw),
- .oversampling = 4,
- .calibrate = true,
- };
-
-#ifdef CONFIG_ADC_NRFX_SAADC
- drv_data->acc = (struct adc_channel_cfg){
- .gain = ADC_GAIN_1_5,
- .reference = ADC_REF_INTERNAL,
- .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40),
- .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + drv_cfg->io_channel.channel,
- };
-
- drv_data->as.resolution = 12;
-#else
-#error Unsupported ADC
-#endif
-
- rc = adc_channel_setup(drv_data->adc, &drv_data->acc);
- LOG_DBG("AIN%u setup returned %d", drv_cfg->io_channel.channel, rc);
-
- return rc;
-}
-
-static struct bvd_data bvd_data;
-static const struct bvd_config bvd_cfg = {
- .io_channel =
- {
- DT_INST_IO_CHANNELS_LABEL(0),
- DT_INST_IO_CHANNELS_INPUT(0),
- },
-#if DT_INST_NODE_HAS_PROP(0, power_gpios)
- .power_gpios =
- {
- DT_INST_GPIO_LABEL(0, power_gpios),
- DT_INST_GPIO_PIN(0, power_gpios),
- DT_INST_GPIO_FLAGS(0, power_gpios),
- },
-#endif
- .output_ohm = DT_INST_PROP(0, output_ohms),
- .full_ohm = DT_INST_PROP(0, full_ohms),
-};
-
-DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, &bvd_data, &bvd_cfg, POST_KERNEL,
- CONFIG_SENSOR_INIT_PRIORITY, &bvd_api);
diff --git a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-demux.yaml b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-demux.yaml
index a2d8d24..a2d8d24 100644
--- a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-demux.yaml
+++ b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-demux.yaml
diff --git a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-direct.yaml b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml
index 09a9b6c..09a9b6c 100644
--- a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-direct.yaml
+++ b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml
diff --git a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-matrix.yaml b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml
index 5ebcbdd..5ebcbdd 100644
--- a/app/drivers/zephyr/dts/bindings/zmk,kscan-gpio-matrix.yaml
+++ b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml
diff --git a/app/drivers/zephyr/dts/bindings/alps,ec11.yaml b/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml
index 5cbe77a..5cbe77a 100644
--- a/app/drivers/zephyr/dts/bindings/alps,ec11.yaml
+++ b/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml
diff --git a/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml b/app/drivers/zephyr/dts/bindings/sensor/zmk,battery-voltage-divider.yaml
index 3f391d7..3f391d7 100644
--- a/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml
+++ b/app/drivers/zephyr/dts/bindings/sensor/zmk,battery-voltage-divider.yaml
diff --git a/app/drivers/zephyr/ec11.c b/app/drivers/zephyr/ec11.c
deleted file mode 100644
index 00d0090..0000000
--- a/app/drivers/zephyr/ec11.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT alps_ec11
-
-#include <device.h>
-#include <drivers/gpio.h>
-#include <sys/util.h>
-#include <kernel.h>
-#include <drivers/sensor.h>
-#include <sys/__assert.h>
-#include <logging/log.h>
-
-#include "ec11.h"
-
-LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL);
-
-static int ec11_get_ab_state(struct device *dev) {
- struct ec11_data *drv_data = dev->driver_data;
- const struct ec11_config *drv_cfg = dev->config_info;
-
- return (gpio_pin_get(drv_data->a, drv_cfg->a_pin) << 1) |
- gpio_pin_get(drv_data->b, drv_cfg->b_pin);
-}
-
-static int ec11_sample_fetch(struct device *dev, enum sensor_channel chan) {
- struct ec11_data *drv_data = dev->driver_data;
- const struct ec11_config *drv_cfg = dev->config_info;
- u8_t val;
- s8_t delta;
-
- __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_ROTATION);
-
- val = ec11_get_ab_state(dev);
-
- LOG_DBG("prev: %d, new: %d", drv_data->ab_state, val);
-
- switch (val | (drv_data->ab_state << 2)) {
- case 0b0010:
- case 0b0100:
- case 0b1101:
- case 0b1011:
- delta = -1;
- break;
- case 0b0001:
- case 0b0111:
- case 0b1110:
- case 0b1000:
- delta = 1;
- break;
- default:
- delta = 0;
- break;
- }
-
- LOG_DBG("Delta: %d", delta);
-
- drv_data->pulses += delta;
- drv_data->ab_state = val;
-
- drv_data->ticks = drv_data->pulses / drv_cfg->resolution;
- drv_data->delta = delta;
- drv_data->pulses %= drv_cfg->resolution;
-
- return 0;
-}
-
-static int ec11_channel_get(struct device *dev, enum sensor_channel chan,
- struct sensor_value *val) {
- struct ec11_data *drv_data = dev->driver_data;
-
- if (chan != SENSOR_CHAN_ROTATION) {
- return -ENOTSUP;
- }
-
- val->val1 = drv_data->ticks;
- val->val2 = drv_data->delta;
-
- return 0;
-}
-
-static const struct sensor_driver_api ec11_driver_api = {
-#ifdef CONFIG_EC11_TRIGGER
- .trigger_set = ec11_trigger_set,
-#endif
- .sample_fetch = ec11_sample_fetch,
- .channel_get = ec11_channel_get,
-};
-
-int ec11_init(struct device *dev) {
- struct ec11_data *drv_data = dev->driver_data;
- const struct ec11_config *drv_cfg = dev->config_info;
-
- LOG_DBG("A: %s %d B: %s %d resolution %d", drv_cfg->a_label, drv_cfg->a_pin, drv_cfg->b_label,
- drv_cfg->b_pin, drv_cfg->resolution);
-
- drv_data->a = device_get_binding(drv_cfg->a_label);
- if (drv_data->a == NULL) {
- LOG_ERR("Failed to get pointer to A GPIO device");
- return -EINVAL;
- }
-
- drv_data->b = device_get_binding(drv_cfg->b_label);
- if (drv_data->b == NULL) {
- LOG_ERR("Failed to get pointer to B GPIO device");
- return -EINVAL;
- }
-
- if (gpio_pin_configure(drv_data->a, drv_cfg->a_pin, drv_cfg->a_flags | GPIO_INPUT)) {
- LOG_DBG("Failed to configure A pin");
- return -EIO;
- }
-
- if (gpio_pin_configure(drv_data->b, drv_cfg->b_pin, drv_cfg->b_flags | GPIO_INPUT)) {
- LOG_DBG("Failed to configure B pin");
- return -EIO;
- }
-
-#ifdef CONFIG_EC11_TRIGGER
- if (ec11_init_interrupt(dev) < 0) {
- LOG_DBG("Failed to initialize interrupt!");
- return -EIO;
- }
-#endif
-
- drv_data->ab_state = ec11_get_ab_state(dev);
-
- return 0;
-}
-
-#define EC11_INST(n) \
- struct ec11_data ec11_data_##n; \
- const struct ec11_config ec11_cfg_##n = { \
- .a_label = DT_INST_GPIO_LABEL(n, a_gpios), \
- .a_pin = DT_INST_GPIO_PIN(n, a_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))), \
- }; \
- DEVICE_AND_API_INIT(ec11_##n, DT_INST_LABEL(n), ec11_init, &ec11_data_##n, &ec11_cfg_##n, \
- POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &ec11_driver_api);
-
-DT_INST_FOREACH_STATUS_OKAY(EC11_INST) \ No newline at end of file
diff --git a/app/drivers/zephyr/ec11.h b/app/drivers/zephyr/ec11.h
deleted file mode 100644
index e62e733..0000000
--- a/app/drivers/zephyr/ec11.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#pragma once
-
-#include <device.h>
-#include <drivers/gpio.h>
-#include <sys/util.h>
-
-struct ec11_config {
- const char *a_label;
- const u8_t a_pin;
- const u8_t a_flags;
-
- const char *b_label;
- const u8_t b_pin;
- const u8_t b_flags;
-
- const u8_t resolution;
-};
-
-struct ec11_data {
- struct device *a;
- struct device *b;
- u8_t ab_state;
- s8_t pulses;
- s8_t ticks;
- s8_t delta;
-
-#ifdef CONFIG_EC11_TRIGGER
- struct gpio_callback a_gpio_cb;
- struct gpio_callback b_gpio_cb;
- struct device *dev;
-
- sensor_trigger_handler_t handler;
- const struct sensor_trigger *trigger;
-
-#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
- K_THREAD_STACK_MEMBER(thread_stack, CONFIG_EC11_THREAD_STACK_SIZE);
- struct k_sem gpio_sem;
- struct k_thread thread;
-#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
- struct k_work work;
-#endif
-
-#endif /* CONFIG_EC11_TRIGGER */
-};
-
-#ifdef CONFIG_EC11_TRIGGER
-
-int ec11_trigger_set(struct device *dev, const struct sensor_trigger *trig,
- sensor_trigger_handler_t handler);
-
-int ec11_init_interrupt(struct device *dev);
-#endif
diff --git a/app/drivers/zephyr/ec11_trigger.c b/app/drivers/zephyr/ec11_trigger.c
deleted file mode 100644
index 248ac32..0000000
--- a/app/drivers/zephyr/ec11_trigger.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT alps_ec11
-
-#include <device.h>
-#include <drivers/gpio.h>
-#include <sys/util.h>
-#include <kernel.h>
-#include <drivers/sensor.h>
-
-#include "ec11.h"
-
-extern struct ec11_data ec11_driver;
-
-#include <logging/log.h>
-LOG_MODULE_DECLARE(EC11, CONFIG_SENSOR_LOG_LEVEL);
-
-static inline void setup_int(struct device *dev, bool enable) {
- struct ec11_data *data = dev->driver_data;
- const struct ec11_config *cfg = dev->config_info;
-
- LOG_DBG("enabled %s", (enable ? "true" : "false"));
-
- if (gpio_pin_interrupt_configure(data->a, cfg->a_pin,
- enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
- LOG_WRN("Unable to set A pin GPIO interrupt");
- }
-
- if (gpio_pin_interrupt_configure(data->b, cfg->b_pin,
- enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
- LOG_WRN("Unable to set A pin GPIO interrupt");
- }
-}
-
-static void ec11_a_gpio_callback(struct device *dev, struct gpio_callback *cb, u32_t pins) {
- struct ec11_data *drv_data = CONTAINER_OF(cb, struct ec11_data, a_gpio_cb);
-
- LOG_DBG("");
-
- setup_int(drv_data->dev, false);
-
-#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
- k_sem_give(&drv_data->gpio_sem);
-#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
- k_work_submit(&drv_data->work);
-#endif
-}
-
-static void ec11_b_gpio_callback(struct device *dev, struct gpio_callback *cb, u32_t pins) {
- struct ec11_data *drv_data = CONTAINER_OF(cb, struct ec11_data, b_gpio_cb);
-
- LOG_DBG("");
-
- setup_int(drv_data->dev, false);
-
-#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
- k_sem_give(&drv_data->gpio_sem);
-#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
- k_work_submit(&drv_data->work);
-#endif
-}
-
-static void ec11_thread_cb(void *arg) {
- struct device *dev = arg;
- struct ec11_data *drv_data = dev->driver_data;
-
- drv_data->handler(dev, drv_data->trigger);
-
- setup_int(dev, true);
-}
-
-#ifdef CONFIG_EC11_TRIGGER_OWN_THREAD
-static void ec11_thread(int dev_ptr, int unused) {
- struct device *dev = INT_TO_POINTER(dev_ptr);
- struct ec11_data *drv_data = dev->driver_data;
-
- ARG_UNUSED(unused);
-
- while (1) {
- k_sem_take(&drv_data->gpio_sem, K_FOREVER);
- ec11_thread_cb(dev);
- }
-}
-#endif
-
-#ifdef CONFIG_EC11_TRIGGER_GLOBAL_THREAD
-static void ec11_work_cb(struct k_work *work) {
- struct ec11_data *drv_data = CONTAINER_OF(work, struct ec11_data, work);
-
- LOG_DBG("");
-
- ec11_thread_cb(drv_data->dev);
-}
-#endif
-
-int ec11_trigger_set(struct device *dev, const struct sensor_trigger *trig,
- sensor_trigger_handler_t handler) {
- struct ec11_data *drv_data = dev->driver_data;
-
- setup_int(dev, false);
-
- k_msleep(5);
-
- drv_data->trigger = trig;
- drv_data->handler = handler;
-
- setup_int(dev, true);
-
- return 0;
-}
-
-int ec11_init_interrupt(struct device *dev) {
- struct ec11_data *drv_data = dev->driver_data;
- const struct ec11_config *drv_cfg = dev->config_info;
-
- drv_data->dev = dev;
- /* setup gpio interrupt */
-
- 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) {
- LOG_DBG("Failed to set A callback!");
- return -EIO;
- }
-
- 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) {
- LOG_DBG("Failed to set B callback!");
- return -EIO;
- }
-
-#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
- k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
-
- k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_EC11_THREAD_STACK_SIZE,
- (k_thread_entry_t)ec11_thread, dev, 0, NULL,
- K_PRIO_COOP(CONFIG_EC11_THREAD_PRIORITY), 0, K_NO_WAIT);
-#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
- k_work_init(&drv_data->work, ec11_work_cb);
-#endif
-
- return 0;
-}
diff --git a/app/drivers/zephyr/kscan_gpio_demux.c b/app/drivers/zephyr/kscan_gpio_demux.c
deleted file mode 100644
index 6113d7c..0000000
--- a/app/drivers/zephyr/kscan_gpio_demux.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT zmk_kscan_gpio_demux
-
-#include <device.h>
-#include <drivers/kscan.h>
-#include <drivers/gpio.h>
-#include <logging/log.h>
-
-LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
-
-#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
-
-struct kscan_gpio_item_config {
- char *label;
- gpio_pin_t pin;
- gpio_flags_t flags;
-};
-
-// Helper macro
-#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 _KSCAN_GPIO_INPUT_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, input_gpios, idx)
-#define _KSCAN_GPIO_OUTPUT_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, output_gpios, idx)
-
-// Check debounce config
-#define CHECK_DEBOUNCE_CFG(n, a, b) COND_CODE_0(DT_INST_PROP(n, debounce_period), a, b)
-
-// Define the row and column lengths
-#define INST_MATRIX_INPUTS(n) DT_INST_PROP_LEN(n, input_gpios)
-#define INST_DEMUX_GPIOS(n) DT_INST_PROP_LEN(n, output_gpios)
-#define INST_MATRIX_OUTPUTS(n) PWR_TWO(INST_DEMUX_GPIOS(n))
-#define POLL_INTERVAL(n) DT_INST_PROP(n, polling_interval_msec)
-
-#define GPIO_INST_INIT(n) \
- struct kscan_gpio_irq_callback_##n { \
- struct CHECK_DEBOUNCE_CFG(n, (k_work), (k_delayed_work)) * work; \
- struct gpio_callback callback; \
- struct device *dev; \
- }; \
- \
- struct kscan_gpio_config_##n { \
- struct kscan_gpio_item_config rows[INST_MATRIX_INPUTS(n)]; \
- struct kscan_gpio_item_config cols[INST_DEMUX_GPIOS(n)]; \
- }; \
- \
- struct kscan_gpio_data_##n { \
- kscan_callback_t callback; \
- struct k_timer poll_timer; \
- struct CHECK_DEBOUNCE_CFG(n, (k_work), (k_delayed_work)) work; \
- bool matrix_state[INST_MATRIX_INPUTS(n)][INST_MATRIX_OUTPUTS(n)]; \
- struct device *rows[INST_MATRIX_INPUTS(n)]; \
- struct device *cols[INST_MATRIX_OUTPUTS(n)]; \
- struct device *dev; \
- }; \
- /* IO/GPIO SETUP */ \
- /* gpio_input_devices are PHYSICAL IO devices */ \
- static struct device **kscan_gpio_input_devices_##n(struct device *dev) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- return data->rows; \
- } \
- \
- static const struct kscan_gpio_item_config *kscan_gpio_input_configs_##n(struct device *dev) { \
- const struct kscan_gpio_config_##n *cfg = dev->config_info; \
- return cfg->rows; \
- } \
- \
- /* gpio_output_devices are PHYSICAL IO devices */ \
- static struct device **kscan_gpio_output_devices_##n(struct device *dev) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- return data->cols; \
- } \
- \
- static const struct kscan_gpio_item_config *kscan_gpio_output_configs_##n( \
- struct device *dev) { \
- const struct kscan_gpio_config_##n *cfg = dev->config_info; \
- /* If row2col, rows = outputs & cols = inputs */ \
- return cfg->cols; \
- } \
- /* POLLING SETUP */ \
- static void kscan_gpio_timer_handler(struct k_timer *timer) { \
- struct kscan_gpio_data_##n *data = \
- CONTAINER_OF(timer, struct kscan_gpio_data_##n, poll_timer); \
- k_work_submit(&data->work.work); \
- } \
- \
- /* Read the state of the input GPIOs */ \
- /* This is the core matrix_scan func */ \
- static int kscan_gpio_read_##n(struct device *dev) { \
- bool submit_follow_up_read = false; \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- static bool read_state[INST_MATRIX_INPUTS(n)][INST_MATRIX_OUTPUTS(n)]; \
- for (int o = 0; o < INST_MATRIX_OUTPUTS(n); o++) { \
- /* Iterate over bits and set GPIOs accordingly */ \
- for (u8_t bit = 0; bit < INST_DEMUX_GPIOS(n); bit++) { \
- u8_t state = (o & (0b1 << bit)) >> bit; \
- struct device *out_dev = kscan_gpio_output_devices_##n(dev)[bit]; \
- const struct kscan_gpio_item_config *out_cfg = \
- &kscan_gpio_output_configs_##n(dev)[bit]; \
- gpio_pin_set(out_dev, out_cfg->pin, state); \
- } \
- \
- for (int i = 0; i < INST_MATRIX_INPUTS(n); i++) { \
- /* Get the input device (port) */ \
- struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \
- /* Get the input device config (pin) */ \
- 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 c = 0; c < INST_MATRIX_OUTPUTS(n); c++) { \
- bool pressed = read_state[r][c]; \
- submit_follow_up_read = (submit_follow_up_read || pressed); \
- if (pressed != data->matrix_state[r][c]) { \
- LOG_DBG("Sending event at %d,%d state %s", r, c, (pressed ? "on" : "off")); \
- data->matrix_state[r][c] = pressed; \
- data->callback(dev, r, c, pressed); \
- } \
- } \
- } \
- if (submit_follow_up_read) { \
- CHECK_DEBOUNCE_CFG(n, ({ k_work_submit(&data->work); }), ({ \
- k_delayed_work_cancel(&data->work); \
- k_delayed_work_submit(&data->work, K_MSEC(5)); \
- })) \
- } \
- return 0; \
- } \
- \
- static void kscan_gpio_work_handler_##n(struct k_work *work) { \
- struct kscan_gpio_data_##n *data = CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \
- kscan_gpio_read_##n(data->dev); \
- } \
- \
- 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 */ \
- static int kscan_gpio_configure_##n(struct device *dev, kscan_callback_t callback) { \
- LOG_DBG("KSCAN API configure"); \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- if (!callback) { \
- return -EINVAL; \
- } \
- data->callback = callback; \
- LOG_DBG("Configured GPIO %d", n); \
- return 0; \
- }; \
- \
- /* KSCAN API enable function */ \
- static int kscan_gpio_enable_##n(struct device *dev) { \
- LOG_DBG("KSCAN API enable"); \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- /* TODO: we might want a follow up to hook into the sleep state hooks in Zephyr, */ \
- /* and disable this timer when we enter a sleep state */ \
- k_timer_start(&data->poll_timer, K_MSEC(POLL_INTERVAL(n)), K_MSEC(POLL_INTERVAL(n))); \
- return 0; \
- }; \
- \
- /* KSCAN API disable function */ \
- static int kscan_gpio_disable_##n(struct device *dev) { \
- LOG_DBG("KSCAN API disable"); \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- k_timer_stop(&data->poll_timer); \
- return 0; \
- }; \
- \
- /* GPIO init function*/ \
- static int kscan_gpio_init_##n(struct device *dev) { \
- LOG_DBG("KSCAN GPIO init"); \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- int err; \
- /* configure input devices*/ \
- struct device **input_devices = kscan_gpio_input_devices_##n(dev); \
- 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]; \
- input_devices[i] = device_get_binding(in_cfg->label); \
- if (!input_devices[i]) { \
- LOG_ERR("Unable to find input GPIO device"); \
- return -EINVAL; \
- } \
- err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
- if (err) { \
- LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
- return err; \
- } else { \
- LOG_DBG("Configured pin %d on %s for input", in_cfg->pin, in_cfg->label); \
- } \
- if (err) { \
- LOG_ERR("Error adding the callback to the column device"); \
- return err; \
- } \
- } \
- /* configure output devices*/ \
- struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
- 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]; \
- output_devices[o] = device_get_binding(out_cfg->label); \
- if (!output_devices[o]) { \
- LOG_ERR("Unable to find output GPIO device"); \
- return -EINVAL; \
- } \
- err = gpio_pin_configure(output_devices[o], out_cfg->pin, \
- GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
- if (err) { \
- LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, \
- out_cfg->label); \
- return err; \
- } else { \
- LOG_DBG("Configured pin %d on %s for output", out_cfg->pin, out_cfg->label); \
- } \
- } \
- data->dev = dev; \
- \
- k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL); \
- \
- (CHECK_DEBOUNCE_CFG(n, (k_work_init), (k_delayed_work_init)))( \
- &data->work, kscan_gpio_work_handler_##n); \
- return 0; \
- } \
- \
- static const struct kscan_driver_api gpio_driver_api_##n = { \
- .config = kscan_gpio_configure_##n, \
- .enable_callback = kscan_gpio_enable_##n, \
- .disable_callback = kscan_gpio_disable_##n, \
- }; \
- \
- static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \
- .rows = {UTIL_LISTIFY(INST_MATRIX_INPUTS(n), _KSCAN_GPIO_INPUT_CFG_INIT, n)}, \
- .cols = {UTIL_LISTIFY(INST_DEMUX_GPIOS(n), _KSCAN_GPIO_OUTPUT_CFG_INIT, n)}, \
- }; \
- \
- DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
- &kscan_gpio_data_##n, &kscan_gpio_config_##n, APPLICATION, \
- CONFIG_APPLICATION_INIT_PRIORITY, &gpio_driver_api_##n);
-
-DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
-
-#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/drivers/zephyr/kscan_gpio_direct.c b/app/drivers/zephyr/kscan_gpio_direct.c
deleted file mode 100644
index 8327161..0000000
--- a/app/drivers/zephyr/kscan_gpio_direct.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT zmk_kscan_gpio_direct
-
-#include <device.h>
-#include <drivers/kscan.h>
-#include <drivers/gpio.h>
-#include <logging/log.h>
-
-LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
-
-#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
-
-struct kscan_gpio_item_config {
- char *label;
- gpio_pin_t pin;
- gpio_flags_t flags;
-};
-
-union work_reference {
- struct k_delayed_work delayed;
- struct k_work direct;
-};
-
-struct kscan_gpio_config {
- u8_t num_of_inputs;
- u8_t debounce_period;
- struct kscan_gpio_item_config inputs[];
-};
-
-struct kscan_gpio_data {
-#if defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING)
- struct k_timer poll_timer;
-#endif /* defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING) */
- kscan_callback_t callback;
- union work_reference work;
- struct device *dev;
- u32_t pin_state;
- struct device *inputs[];
-};
-
-static struct device **kscan_gpio_input_devices(struct device *dev) {
- struct kscan_gpio_data *data = dev->driver_data;
- return data->inputs;
-}
-
-static const struct kscan_gpio_item_config *kscan_gpio_input_configs(struct device *dev) {
- const struct kscan_gpio_config *cfg = dev->config_info;
- return cfg->inputs;
-}
-
-static void kscan_gpio_direct_queue_read(union work_reference *work, u8_t debounce_period) {
- if (debounce_period > 0) {
- k_delayed_work_cancel(&work->delayed);
- k_delayed_work_submit(&work->delayed, K_MSEC(debounce_period));
- } else {
- k_work_submit(&work->direct);
- }
-}
-
-#if !defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING)
-
-struct kscan_gpio_irq_callback {
- struct device *dev;
- union work_reference *work;
- u8_t debounce_period;
- struct gpio_callback callback;
-};
-
-static int kscan_gpio_config_interrupts(struct device *dev, gpio_flags_t flags) {
- const struct kscan_gpio_config *cfg = dev->config_info;
- struct device **devices = kscan_gpio_input_devices(dev);
- const struct kscan_gpio_item_config *configs = kscan_gpio_input_configs(dev);
-
- for (int i = 0; i < cfg->num_of_inputs; i++) {
- struct device *dev = devices[i];
- const struct kscan_gpio_item_config *cfg = &configs[i];
-
- int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
-
- if (err) {
- LOG_ERR("Unable to enable matrix GPIO interrupt");
- return err;
- }
- }
-
- return 0;
-}
-
-static int kscan_gpio_direct_enable(struct device *dev) {
- return kscan_gpio_config_interrupts(dev, GPIO_INT_LEVEL_ACTIVE);
-}
-static int kscan_gpio_direct_disable(struct device *dev) {
- return kscan_gpio_config_interrupts(dev, GPIO_INT_DISABLE);
-}
-
-static void kscan_gpio_irq_callback_handler(struct device *dev, struct gpio_callback *cb,
- gpio_port_pins_t pin) {
- struct kscan_gpio_irq_callback *data =
- CONTAINER_OF(cb, struct kscan_gpio_irq_callback, callback);
-
- kscan_gpio_direct_disable(data->dev);
- kscan_gpio_direct_queue_read(data->work, data->debounce_period);
-}
-
-#else /* !defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING) */
-
-static void kscan_gpio_timer_handler(struct k_timer *timer) {
- struct kscan_gpio_data *data = CONTAINER_OF(timer, struct kscan_gpio_data, poll_timer);
-
- kscan_gpio_direct_queue_read(&data->work, 0);
-}
-
-static int kscan_gpio_direct_enable(struct device *dev) {
- struct kscan_gpio_data *data = dev->driver_data;
- k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10));
- return 0;
-}
-static int kscan_gpio_direct_disable(struct device *dev) {
- struct kscan_gpio_data *data = dev->driver_data;
- k_timer_stop(&data->poll_timer);
- return 0;
-}
-
-#endif /* defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING) */
-
-static int kscan_gpio_direct_configure(struct device *dev, kscan_callback_t callback) {
- struct kscan_gpio_data *data = dev->driver_data;
- if (!callback) {
- return -EINVAL;
- }
- data->callback = callback;
- return 0;
-}
-
-static int kscan_gpio_read(struct device *dev) {
- struct kscan_gpio_data *data = dev->driver_data;
- const struct kscan_gpio_config *cfg = dev->config_info;
- u32_t read_state = data->pin_state;
- bool submit_follow_up_read = false;
- for (int i = 0; i < cfg->num_of_inputs; i++) {
- struct device *in_dev = kscan_gpio_input_devices(dev)[i];
- const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i];
- WRITE_BIT(read_state, i, gpio_pin_get(in_dev, in_cfg->pin) > 0);
- }
- for (int i = 0; i < cfg->num_of_inputs; i++) {
- bool prev_pressed = BIT(i) & data->pin_state;
- bool pressed = (BIT(i) & read_state) != 0;
- submit_follow_up_read = (submit_follow_up_read || pressed);
- if (pressed != prev_pressed) {
- LOG_DBG("Sending event at %d,%d state %s", 0, i, (pressed ? "on" : "off"));
- WRITE_BIT(data->pin_state, i, pressed);
- data->callback(dev, 0, i, pressed);
- }
- }
-
-#if !defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING)
- if (submit_follow_up_read) {
- kscan_gpio_direct_queue_read(&data->work, cfg->debounce_period);
- } else {
- kscan_gpio_direct_enable(dev);
- }
-#endif
-
- return 0;
-}
-
-static void kscan_gpio_work_handler(struct k_work *work) {
- struct kscan_gpio_data *data = CONTAINER_OF(work, struct kscan_gpio_data, work);
- kscan_gpio_read(data->dev);
-}
-
-static const struct kscan_driver_api gpio_driver_api = {
- .config = kscan_gpio_direct_configure,
- .enable_callback = kscan_gpio_direct_enable,
- .disable_callback = kscan_gpio_direct_disable,
-};
-
-#define KSCAN_DIRECT_INPUT_ITEM(i, n) \
- { \
- .label = DT_INST_GPIO_LABEL_BY_IDX(n, input_gpios, i), \
- .pin = DT_INST_GPIO_PIN_BY_IDX(n, input_gpios, i), \
- .flags = DT_INST_GPIO_FLAGS_BY_IDX(n, input_gpios, i), \
- },
-
-#define INST_INPUT_LEN(n) DT_INST_PROP_LEN(n, input_gpios)
-
-#define GPIO_INST_INIT(n) \
- COND_CODE_0(IS_ENABLED(CONFIG_ZMK_KSCAN_DIRECT_POLLING), \
- (static struct kscan_gpio_irq_callback irq_callbacks_##n[INST_INPUT_LEN(n)];), ()) \
- static struct kscan_gpio_data kscan_gpio_data_##n = { \
- .inputs = {[INST_INPUT_LEN(n) - 1] = NULL}}; \
- static int kscan_gpio_init_##n(struct device *dev) { \
- struct kscan_gpio_data *data = dev->driver_data; \
- const struct kscan_gpio_config *cfg = dev->config_info; \
- int err; \
- struct device **input_devices = kscan_gpio_input_devices(dev); \
- for (int i = 0; i < cfg->num_of_inputs; i++) { \
- const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i]; \
- input_devices[i] = device_get_binding(in_cfg->label); \
- if (!input_devices[i]) { \
- LOG_ERR("Unable to find input GPIO device"); \
- return -EINVAL; \
- } \
- err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
- if (err) { \
- LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
- return err; \
- } \
- COND_CODE_0( \
- IS_ENABLED(CONFIG_ZMK_KSCAN_DIRECT_POLLING), \
- (irq_callbacks_##n[i].work = &data->work; irq_callbacks_##n[i].dev = dev; \
- irq_callbacks_##n[i].debounce_period = cfg->debounce_period; \
- gpio_init_callback(&irq_callbacks_##n[i].callback, \
- kscan_gpio_irq_callback_handler, BIT(in_cfg->pin)); \
- err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
- if (err) { \
- LOG_ERR("Error adding the callback to the column device"); \
- return err; \
- }), \
- ()) \
- } \
- data->dev = dev; \
- COND_CODE_1(IS_ENABLED(CONFIG_ZMK_KSCAN_DIRECT_POLLING), \
- (k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL);), ()) \
- if (cfg->debounce_period > 0) { \
- k_delayed_work_init(&data->work.delayed, kscan_gpio_work_handler); \
- } else { \
- k_work_init(&data->work.direct, kscan_gpio_work_handler); \
- } \
- return 0; \
- } \
- static const struct kscan_gpio_config kscan_gpio_config_##n = { \
- .inputs = {UTIL_LISTIFY(INST_INPUT_LEN(n), KSCAN_DIRECT_INPUT_ITEM, n)}, \
- .num_of_inputs = INST_INPUT_LEN(n), \
- .debounce_period = DT_INST_PROP(n, debounce_period)}; \
- DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
- &kscan_gpio_data_##n, &kscan_gpio_config_##n, POST_KERNEL, \
- CONFIG_ZMK_KSCAN_INIT_PRIORITY, &gpio_driver_api);
-
-DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
-
-#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/drivers/zephyr/kscan_gpio_matrix.c b/app/drivers/zephyr/kscan_gpio_matrix.c
deleted file mode 100644
index ec4fb39..0000000
--- a/app/drivers/zephyr/kscan_gpio_matrix.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT zmk_kscan_gpio_matrix
-
-#include <device.h>
-#include <drivers/kscan.h>
-#include <drivers/gpio.h>
-#include <logging/log.h>
-
-LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
-
-#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
-
-struct kscan_gpio_item_config {
- char *label;
- gpio_pin_t pin;
- gpio_flags_t flags;
-};
-
-#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 _KSCAN_GPIO_ROW_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, row_gpios, idx)
-#define _KSCAN_GPIO_COL_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, col_gpios, idx)
-
-#if !defined(CONFIG_ZMK_KSCAN_MATRIX_POLLING)
-static int kscan_gpio_config_interrupts(struct device **devices,
- const struct kscan_gpio_item_config *configs, size_t len,
- gpio_flags_t flags) {
- for (int i = 0; i < len; i++) {
- struct device *dev = devices[i];
- const struct kscan_gpio_item_config *cfg = &configs[i];
-
- int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
-
- if (err) {
- LOG_ERR("Unable to enable matrix GPIO interrupt");
- return err;
- }
- }
-
- return 0;
-}
-#endif
-
-#define INST_MATRIX_ROWS(n) DT_INST_PROP_LEN(n, row_gpios)
-#define INST_MATRIX_COLS(n) DT_INST_PROP_LEN(n, col_gpios)
-#define INST_OUTPUT_LEN(n) \
- COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_ROWS(n)), \
- (INST_MATRIX_COLS(n)))
-#define INST_INPUT_LEN(n) \
- COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_COLS(n)), \
- (INST_MATRIX_ROWS(n)))
-
-#define GPIO_INST_INIT(n) \
- struct kscan_gpio_irq_callback_##n { \
- struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) * work; \
- struct gpio_callback callback; \
- struct device *dev; \
- }; \
- static struct kscan_gpio_irq_callback_##n irq_callbacks_##n[INST_INPUT_LEN(n)]; \
- struct kscan_gpio_config_##n { \
- struct kscan_gpio_item_config rows[INST_MATRIX_ROWS(n)]; \
- struct kscan_gpio_item_config cols[INST_MATRIX_COLS(n)]; \
- }; \
- struct kscan_gpio_data_##n { \
- kscan_callback_t callback; \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (struct k_timer poll_timer;), ()) \
- struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) work; \
- bool matrix_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
- struct device *rows[INST_MATRIX_ROWS(n)]; \
- struct device *cols[INST_MATRIX_COLS(n)]; \
- struct device *dev; \
- }; \
- static struct device **kscan_gpio_input_devices_##n(struct device *dev) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->cols), \
- (data->rows))); \
- } \
- static const struct kscan_gpio_item_config *kscan_gpio_input_configs_##n(struct device *dev) { \
- const struct kscan_gpio_config_##n *cfg = dev->config_info; \
- return (( \
- COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->cols), (cfg->rows)))); \
- } \
- static struct device **kscan_gpio_output_devices_##n(struct device *dev) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->rows), \
- (data->cols))); \
- } \
- static const struct kscan_gpio_item_config *kscan_gpio_output_configs_##n( \
- struct device *dev) { \
- const struct kscan_gpio_config_##n *cfg = dev->config_info; \
- return ( \
- COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->rows), (cfg->cols))); \
- } \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
- ( \
- static int kscan_gpio_enable_interrupts_##n(struct device *dev) { \
- return kscan_gpio_config_interrupts( \
- kscan_gpio_input_devices_##n(dev), kscan_gpio_input_configs_##n(dev), \
- INST_INPUT_LEN(n), GPIO_INT_LEVEL_ACTIVE); \
- } static int kscan_gpio_disable_interrupts_##n(struct device *dev) { \
- return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
- kscan_gpio_input_configs_##n(dev), \
- INST_INPUT_LEN(n), GPIO_INT_DISABLE); \
- })) \
- static void kscan_gpio_set_output_state_##n(struct device *dev, int value) { \
- int err; \
- for (int i = 0; i < INST_OUTPUT_LEN(n); i++) { \
- struct device *in_dev = kscan_gpio_output_devices_##n(dev)[i]; \
- const struct kscan_gpio_item_config *cfg = &kscan_gpio_output_configs_##n(dev)[i]; \
- if ((err = gpio_pin_set(in_dev, cfg->pin, value))) { \
- LOG_DBG("FAILED TO SET OUTPUT %d to %d", cfg->pin, err); \
- } \
- } \
- } \
- static void kscan_gpio_set_matrix_state_##n( \
- bool state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)], u32_t input_index, \
- u32_t output_index, bool value) { \
- state[COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (output_index), \
- (input_index))] \
- [COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (input_index), \
- (output_index))] = value; \
- } \
- static int kscan_gpio_read_##n(struct device *dev) { \
- bool submit_follow_up_read = false; \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
- /* Disable our interrupts temporarily while we scan, to avoid */ \
- /* re-entry while we iterate columns and set them active one by one */ \
- /* to get pressed state for each matrix cell. */ \
- kscan_gpio_set_output_state_##n(dev, 0); \
- for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
- struct device *out_dev = kscan_gpio_output_devices_##n(dev)[o]; \
- const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
- gpio_pin_set(out_dev, out_cfg->pin, 1); \
- for (int i = 0; i < INST_INPUT_LEN(n); i++) { \
- struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \
- const struct kscan_gpio_item_config *in_cfg = \
- &kscan_gpio_input_configs_##n(dev)[i]; \
- kscan_gpio_set_matrix_state_##n(read_state, i, o, \
- gpio_pin_get(in_dev, in_cfg->pin) > 0); \
- } \
- gpio_pin_set(out_dev, out_cfg->pin, 0); \
- } \
- /* Set all our outputs as active again. */ \
- kscan_gpio_set_output_state_##n(dev, 1); \
- for (int r = 0; r < INST_MATRIX_ROWS(n); r++) { \
- for (int c = 0; c < INST_MATRIX_COLS(n); c++) { \
- bool pressed = read_state[r][c]; \
- /* Follow up reads needed because further interrupts won't fire on already tripped \
- * input GPIO pins */ \
- submit_follow_up_read = (submit_follow_up_read || pressed); \
- if (pressed != data->matrix_state[r][c]) { \
- LOG_DBG("Sending event at %d,%d state %s", r, c, (pressed ? "on" : "off")); \
- data->matrix_state[r][c] = pressed; \
- data->callback(dev, r, c, pressed); \
- } \
- } \
- } \
- if (submit_follow_up_read) { \
- COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(&data->work); }), ({ \
- k_delayed_work_cancel(&data->work); \
- k_delayed_work_submit(&data->work, K_MSEC(5)); \
- })) \
- } else { \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
- (kscan_gpio_enable_interrupts_##n(dev);)) \
- } \
- return 0; \
- } \
- static void kscan_gpio_work_handler_##n(struct k_work *work) { \
- struct kscan_gpio_data_##n *data = CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \
- kscan_gpio_read_##n(data->dev); \
- } \
- static void kscan_gpio_irq_callback_handler_##n(struct device *dev, struct gpio_callback *cb, \
- gpio_port_pins_t pin) { \
- struct kscan_gpio_irq_callback_##n *data = \
- CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
- (kscan_gpio_disable_interrupts_##n(data->dev);)) \
- COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(data->work); }), ({ \
- k_delayed_work_cancel(data->work); \
- k_delayed_work_submit(data->work, \
- K_MSEC(DT_INST_PROP(n, debounce_period))); \
- })) \
- } \
- \
- static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
- .rows = {[INST_MATRIX_ROWS(n) - 1] = NULL}, .cols = {[INST_MATRIX_COLS(n) - 1] = NULL}}; \
- static int kscan_gpio_configure_##n(struct device *dev, kscan_callback_t callback) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- if (!callback) { \
- return -EINVAL; \
- } \
- data->callback = callback; \
- LOG_DBG("Configured GPIO %d", n); \
- return 0; \
- }; \
- static int kscan_gpio_enable_##n(struct device *dev) { \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
- (struct kscan_gpio_data_##n *data = dev->driver_data; \
- k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10)); return 0;), \
- (int err = kscan_gpio_enable_interrupts_##n(dev); \
- if (err) { return err; } return kscan_gpio_read_##n(dev);)) \
- }; \
- static int kscan_gpio_disable_##n(struct device *dev) { \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
- (struct kscan_gpio_data_##n *data = dev->driver_data; \
- k_timer_stop(&data->poll_timer); return 0;), \
- (return kscan_gpio_disable_interrupts_##n(dev);)) \
- }; \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
- (static void kscan_gpio_timer_handler(struct k_timer *timer) { \
- struct kscan_gpio_data_##n *data = \
- CONTAINER_OF(timer, struct kscan_gpio_data_##n, poll_timer); \
- k_work_submit(&data->work.work); \
- }), \
- ()) \
- static int kscan_gpio_init_##n(struct device *dev) { \
- struct kscan_gpio_data_##n *data = dev->driver_data; \
- int err; \
- struct device **input_devices = kscan_gpio_input_devices_##n(dev); \
- for (int i = 0; i < INST_INPUT_LEN(n); i++) { \
- const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs_##n(dev)[i]; \
- input_devices[i] = device_get_binding(in_cfg->label); \
- if (!input_devices[i]) { \
- LOG_ERR("Unable to find input GPIO device"); \
- return -EINVAL; \
- } \
- err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
- if (err) { \
- LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
- return err; \
- } else { \
- LOG_DBG("Configured pin %d on %s for input", in_cfg->pin, in_cfg->label); \
- } \
- irq_callbacks_##n[i].work = &data->work; \
- irq_callbacks_##n[i].dev = dev; \
- gpio_init_callback(&irq_callbacks_##n[i].callback, \
- kscan_gpio_irq_callback_handler_##n, BIT(in_cfg->pin)); \
- err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
- if (err) { \
- LOG_ERR("Error adding the callback to the column device"); \
- return err; \
- } \
- } \
- struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
- for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
- const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
- output_devices[o] = device_get_binding(out_cfg->label); \
- if (!output_devices[o]) { \
- LOG_ERR("Unable to find output GPIO device"); \
- return -EINVAL; \
- } \
- err = gpio_pin_configure(output_devices[o], out_cfg->pin, \
- GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
- if (err) { \
- LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, \
- out_cfg->label); \
- return err; \
- } \
- } \
- data->dev = dev; \
- COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
- (k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL);), ()) \
- (COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work_init), (k_delayed_work_init)))( \
- &data->work, kscan_gpio_work_handler_##n); \
- return 0; \
- } \
- static const struct kscan_driver_api gpio_driver_api_##n = { \
- .config = kscan_gpio_configure_##n, \
- .enable_callback = kscan_gpio_enable_##n, \
- .disable_callback = kscan_gpio_disable_##n, \
- }; \
- static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \
- .rows = {UTIL_LISTIFY(INST_MATRIX_ROWS(n), _KSCAN_GPIO_ROW_CFG_INIT, n)}, \
- .cols = {UTIL_LISTIFY(INST_MATRIX_COLS(n), _KSCAN_GPIO_COL_CFG_INIT, n)}, \
- }; \
- DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
- &kscan_gpio_data_##n, &kscan_gpio_config_##n, APPLICATION, \
- CONFIG_APPLICATION_INIT_PRIORITY, &gpio_driver_api_##n);
-
-DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
-
-#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/drivers/zephyr/module.yml b/app/drivers/zephyr/module.yml
index cbff6a1..0b66059 100644
--- a/app/drivers/zephyr/module.yml
+++ b/app/drivers/zephyr/module.yml
@@ -1,3 +1,3 @@
build:
- cmake: zephyr
- kconfig: zephyr/Kconfig
+ cmake: .
+ kconfig: Kconfig