From a63b3d1de6915f21db049fa180c4b0ba3757135b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 20 Nov 2023 16:36:14 +0000 Subject: [PATCH] input: xec: use the generic keyboard code Split the common keyboard scanning code out of the XEC specific driver and use the generic code instead. Signed-off-by: Fabio Baltieri --- .../mec1501modular_assy6885.dts | 2 + .../mec15xxevb_assy6853.dts | 2 + .../mec172xevb_assy6906.dts | 2 + .../mec172xmodular_assy6930.dts | 2 + drivers/input/Kconfig.xec | 39 +- drivers/input/input_xec_kbd.c | 416 +++--------------- dts/bindings/input/microchip,xec-kbd.yaml | 8 +- 7 files changed, 84 insertions(+), 387 deletions(-) diff --git a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts index 5101b9d30c..856069de40 100644 --- a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts +++ b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts @@ -118,6 +118,8 @@ &ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep &ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >; pinctrl-names = "default", "sleep"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts index 7402f6e707..11daa0efbe 100644 --- a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts +++ b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts @@ -175,6 +175,8 @@ &ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep &ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >; pinctrl-names = "default", "sleep"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts index 9595fc578e..c0427d03d3 100644 --- a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts +++ b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts @@ -231,6 +231,8 @@ &kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep &kso13_gpio126_sleep >; pinctrl-names = "default", "sleep"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts index dd7db05548..94a08cd03f 100644 --- a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts +++ b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts @@ -209,6 +209,8 @@ &kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep &kso13_gpio126_sleep >; pinctrl-names = "default", "sleep"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/drivers/input/Kconfig.xec b/drivers/input/Kconfig.xec index bd6cc73b9c..b93c47ac5f 100644 --- a/drivers/input/Kconfig.xec +++ b/drivers/input/Kconfig.xec @@ -3,47 +3,12 @@ # Copyright (c) 2019 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -menuconfig INPUT_XEC_KBD +config INPUT_XEC_KBD bool "Microchip XEC series keyboard matrix driver" default y depends on DT_HAS_MICROCHIP_XEC_KBD_ENABLED + select INPUT_KBD_MATRIX select MULTITHREADING select PINCTRL help Enable the Microchip XEC Kscan IO driver. - -if INPUT_XEC_KBD - -config INPUT_XEC_COLUMN_SIZE - int "Keyscan XEC Column Size" - default 16 - help - Adjust the value to your keyboard columns. The maximum - column size for the Microchip XEC family is 18 (from 0 to 17). - -config INPUT_XEC_ROW_SIZE - int "Keyscan XEC Row Size" - default 8 - help - Adjust the value to your keyboard rows. The maximum - column size for the Microchip XEC family is 8 (from 0 to 7). - -config INPUT_XEC_DEBOUNCE_DOWN - int "Keyscan XEC Debounce Down" - default 10 - help - Determines the time in msecs for debouncing a key press. - -config INPUT_XEC_DEBOUNCE_UP - int "Keyscan XEC Debounce Up" - default 20 - help - Determines the time in msecs for debouncing a key release. - -config INPUT_XEC_POLL_PERIOD - int "Keyscan XEC Poll Period" - default 5 - help - Defines the poll period in msecs between between matrix scans. - -endif # INPUT_XEC diff --git a/drivers/input/input_xec_kbd.c b/drivers/input/input_xec_kbd.c index d18b240748..660f902a44 100644 --- a/drivers/input/input_xec_kbd.c +++ b/drivers/input/input_xec_kbd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -24,394 +25,114 @@ LOG_MODULE_REGISTER(input_xec_kbd, CONFIG_INPUT_LOG_LEVEL); -#define MAX_MATRIX_KEY_COLS CONFIG_INPUT_XEC_COLUMN_SIZE -#define MAX_MATRIX_KEY_ROWS CONFIG_INPUT_XEC_ROW_SIZE - -#define KEYBOARD_COLUMN_DRIVE_ALL -2 -#define KEYBOARD_COLUMN_DRIVE_NONE -1 - -/* Poll period/debouncing rely on the 32KHz clock with 30 usec clock cycles */ -#define CLOCK_32K_HW_CYCLES_TO_US(X) \ - (uint32_t)((((uint64_t)(X) * 1000000U) / sys_clock_hw_cycles_per_sec())) -/* Milliseconds in microseconds */ -#define MSEC_PER_MS 1000U -/* Number of tracked scan times */ -#define SCAN_OCURRENCES 30U -/* Thread stack size */ -#define TASK_STACK_SIZE 1024 - struct xec_kbd_config { + struct input_kbd_matrix_common_config common; + struct kscan_regs *regs; const struct pinctrl_dev_config *pcfg; - uint8_t rsvd[3]; uint8_t girq; uint8_t girq_pos; - uint8_t irq_pri; +#ifdef CONFIG_SOC_SERIES_MEC172X uint8_t pcr_idx; uint8_t pcr_pos; +#endif bool wakeup_source; }; struct xec_kbd_data { - /* variables in usec units */ - uint32_t deb_time_press; - uint32_t deb_time_rel; - int64_t poll_timeout; - uint32_t poll_period; - uint8_t matrix_stable_state[MAX_MATRIX_KEY_COLS]; - uint8_t matrix_unstable_state[MAX_MATRIX_KEY_COLS]; - uint8_t matrix_previous_state[MAX_MATRIX_KEY_COLS]; - /* Index in to the scan_clock_cycle to indicate start of debouncing */ - uint8_t scan_cycle_idx[MAX_MATRIX_KEY_COLS][MAX_MATRIX_KEY_ROWS]; - /* Track previous "elapsed clock cycles" per matrix scan. This - * is used to calculate the debouncing time for every key - */ - uint8_t scan_clk_cycle[SCAN_OCURRENCES]; - struct k_sem poll_lock; - uint8_t scan_cycles_idx; - struct k_thread thread; - - K_KERNEL_STACK_MEMBER(thread_stack, TASK_STACK_SIZE); + struct input_kbd_matrix_common_data common; + bool pm_lock_taken; }; -#ifdef CONFIG_SOC_SERIES_MEC172X static void xec_kbd_clear_girq_status(const struct device *dev) { struct xec_kbd_config const *cfg = dev->config; +#ifdef CONFIG_SOC_SERIES_MEC172X mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos); +#else + MCHP_GIRQ_SRC(cfg->girq) = BIT(cfg->girq_pos); +#endif } -static void xec_kbd_configure_girq(const struct device *dev, bool enable) +static void xec_kbd_configure_girq(const struct device *dev) { struct xec_kbd_config const *cfg = dev->config; - if (enable) { - mchp_xec_ecia_enable(cfg->girq, cfg->girq_pos); - } else { - mchp_xec_ecia_disable(cfg->girq, cfg->girq_pos); - } +#ifdef CONFIG_SOC_SERIES_MEC172X + mchp_xec_ecia_enable(cfg->girq, cfg->girq_pos); +#else + MCHP_GIRQ_ENSET(cfg->girq) = BIT(cfg->girq_pos); +#endif } static void xec_kbd_clr_slp_en(const struct device *dev) { +#ifdef CONFIG_SOC_SERIES_MEC172X struct xec_kbd_config const *cfg = dev->config; z_mchp_xec_pcr_periph_sleep(cfg->pcr_idx, cfg->pcr_pos, 0); -} - #else -static void xec_kbd_clear_girq_status(const struct device *dev) -{ - struct xec_kbd_config const *cfg = dev->config; - - MCHP_GIRQ_SRC(cfg->girq) = BIT(cfg->girq_pos); -} - -static void xec_kbd_configure_girq(const struct device *dev, bool enable) -{ - struct xec_kbd_config const *cfg = dev->config; - - if (enable) { - MCHP_GIRQ_ENSET(cfg->girq) = BIT(cfg->girq_pos); - } else { - MCHP_GIRQ_ENCLR(cfg->girq) = BIT(cfg->girq_pos); - } -} - -static void xec_kbd_clr_slp_en(const struct device *dev) -{ ARG_UNUSED(dev); - mchp_pcr_periph_slp_ctrl(PCR_KEYSCAN, 0); -} #endif +} -static void drive_keyboard_column(const struct device *dev, int data) +static void xec_kbd_drive_column(const struct device *dev, int data) { struct xec_kbd_config const *cfg = dev->config; struct kscan_regs *regs = cfg->regs; - if (data == KEYBOARD_COLUMN_DRIVE_ALL) { + if (data == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) { /* KSO output controlled by the KSO_SELECT field */ regs->KSO_SEL = MCHP_KSCAN_KSO_ALL; - } else if (data == KEYBOARD_COLUMN_DRIVE_NONE) { + } else if (data == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { /* Keyboard scan disabled. All KSO output buffers disabled */ regs->KSO_SEL = MCHP_KSCAN_KSO_EN; } else { - /* It is assumed, KEYBOARD_COLUMN_DRIVE_ALL was - * previously set - */ + /* Assume, ALL was previously set */ regs->KSO_SEL = data; } } -static uint8_t read_keyboard_row(const struct device *dev) +static kbd_row_t xec_kbd_read_row(const struct device *dev) { struct xec_kbd_config const *cfg = dev->config; struct kscan_regs *regs = cfg->regs; /* In this implementation a 1 means key pressed */ - return ~(regs->KSI_IN & 0xFF); + return ~(regs->KSI_IN & 0xff); } -static bool is_matrix_ghosting(const uint8_t *state) +static void xec_kbd_isr(const struct device *dev) { - /* matrix keyboard designs are susceptible to ghosting. - * An extra key appears to be pressed when 3 keys - * belonging to the same block are pressed. - * for example, in the following block - * - * . . w . q . - * . . . . . . - * . . . . . . - * . . m . a . - * - * the key m would look as pressed if the user pressed keys - * w, q and a simultaneously. A block can also be formed, - * with not adjacent columns. - */ - for (int c = 0; c < MAX_MATRIX_KEY_COLS; c++) { - if (!state[c]) - continue; - - for (int c_n = c + 1; c_n < MAX_MATRIX_KEY_COLS; c_n++) { - /* we and the columns to detect a "block". - * this is an indication of ghosting, due to current - * flowing from a key which was never pressed. in our - * case, current flowing is a bit set to 1 as we - * flipped the bits when the matrix was scanned. - * now we or the columns using z&(z-1) which is - * non-zero only if z has more than one bit set. - */ - uint8_t common_row_bits = state[c] & state[c_n]; - - if (common_row_bits & (common_row_bits - 1)) - return true; - } - } - - return false; -} - -static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state) -{ - uint8_t row; - uint8_t key_event = 0U; - - for (int col = 0; col < MAX_MATRIX_KEY_COLS; col++) { - drive_keyboard_column(dev, col); - - /* Allow the matrix to stabilize before reading it */ - k_busy_wait(50U); - row = read_keyboard_row(dev); - new_state[col] = row; - key_event |= row; - } - - drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_NONE); - - return key_event != 0U ? true : false; -} - -static void scan_matrix_xec_isr(const struct device *dev) -{ - struct xec_kbd_data *const data = dev->data; - xec_kbd_clear_girq_status(dev); irq_disable(DT_INST_IRQN(0)); - k_sem_give(&data->poll_lock); - LOG_DBG(""); + + input_kbd_matrix_poll_start(dev); } -static bool check_key_events(const struct device *dev) -{ - struct xec_kbd_data *const data = dev->data; - uint8_t matrix_new_state[MAX_MATRIX_KEY_COLS] = {0U}; - bool key_pressed = false; - uint32_t cycles_now = k_cycle_get_32(); - - if (++data->scan_cycles_idx >= SCAN_OCURRENCES) { - data->scan_cycles_idx = 0U; - } - - data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now; - - /* Scan the matrix */ - key_pressed = read_keyboard_matrix(dev, matrix_new_state); - - /* Abort if ghosting is detected */ - if (is_matrix_ghosting(matrix_new_state)) { - return false; - } - - uint8_t row_changed = 0U; - uint8_t deb_col; - - /* The intent of this loop is to gather information related to key - * changes. - */ - for (int c = 0; c < MAX_MATRIX_KEY_COLS; c++) { - /* Check if there was an update from the previous scan */ - row_changed = matrix_new_state[c] ^ - data->matrix_previous_state[c]; - - if (!row_changed) { - continue; - } - - for (int r = 0; r < MAX_MATRIX_KEY_ROWS; r++) { - /* Index all they keys that changed for each row - * in order to debounce each key in terms of it - */ - if (row_changed & BIT(r)) { - data->scan_cycle_idx[c][r] = - data->scan_cycles_idx; - } - } - - data->matrix_unstable_state[c] |= row_changed; - data->matrix_previous_state[c] = matrix_new_state[c]; - } - - for (int c = 0; c < MAX_MATRIX_KEY_COLS; c++) { - deb_col = data->matrix_unstable_state[c]; - - if (!deb_col) { - continue; - } - - /* Debouncing for each row key occurs here */ - for (int r = 0; r < MAX_MATRIX_KEY_ROWS; r++) { - uint8_t mask = BIT(r); - uint8_t row_bit = matrix_new_state[c] & mask; - - /* Continue if we already debounce a key */ - if (!(deb_col & mask)) { - continue; - } - - /* Convert the clock cycle differences to usec */ - uint32_t debt = CLOCK_32K_HW_CYCLES_TO_US(cycles_now - - data->scan_clk_cycle[data->scan_cycle_idx[c][r]]); - - /* Does the key requires more time to be debounced? */ - if (debt < (row_bit ? data->deb_time_press : - data->deb_time_rel)) { - /* Need more time to debounce */ - continue; - } - - data->matrix_unstable_state[c] &= ~row_bit; - - /* Check if there was a change in the stable state */ - if ((data->matrix_stable_state[c] & mask) - == row_bit) { - /* Key state did not change */ - continue; - - } - - /* The current row has been debounced, therefore update - * the stable state. Then, proceed to notify the - * application about the keys pressed. - */ - data->matrix_stable_state[c] ^= mask; - - input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER); - input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER); - input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER); - } - } - - return key_pressed; -} - -static bool poll_expired(uint32_t start_cycles, int64_t *timeout) -{ - uint32_t stop_cycles; - uint32_t cycles_spent; - uint32_t microsecs_spent; - - stop_cycles = k_cycle_get_32(); - cycles_spent = stop_cycles - start_cycles; - microsecs_spent = CLOCK_32K_HW_CYCLES_TO_US(cycles_spent); - - /* Update the timeout value */ - *timeout -= microsecs_spent; - - return *timeout >= 0; - -} - -void polling_task(const struct device *dev, void *dummy2, void *dummy3) +static void xec_kbd_set_detect_mode(const struct device *dev, bool enabled) { struct xec_kbd_config const *cfg = dev->config; - struct xec_kbd_data *const data = dev->data; + struct xec_kbd_data *data = dev->data; struct kscan_regs *regs = cfg->regs; - uint32_t current_cycles; - uint32_t cycles_diff; - uint32_t wait_period; - int64_t local_poll_timeout = data->poll_timeout; - ARG_UNUSED(dummy2); - ARG_UNUSED(dummy3); + if (enabled) { + if (data->pm_lock_taken) { + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, + PM_ALL_SUBSTATES); + } - while (true) { regs->KSI_STS = MCHP_KSCAN_KSO_SEL_REG_MASK; - /* Ignore isr when releasing a key as we are polling */ xec_kbd_clear_girq_status(dev); NVIC_ClearPendingIRQ(DT_INST_IRQN(0)); irq_enable(DT_INST_IRQN(0)); - - drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_ALL); - - k_sem_take(&data->poll_lock, K_FOREVER); - pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); - - uint32_t start_poll_cycles = k_cycle_get_32(); - - while (true) { - uint32_t start_period_cycles = k_cycle_get_32(); - - if (check_key_events(DEVICE_DT_INST_GET(0))) { - local_poll_timeout = data->poll_timeout; - start_poll_cycles = k_cycle_get_32(); - } else if (!poll_expired(start_poll_cycles, - &local_poll_timeout)) { - break; - } - - /* Subtract the time invested from the sleep period - * in order to compensate for the time invested - * in debouncing a key - */ - current_cycles = k_cycle_get_32(); - cycles_diff = current_cycles - start_period_cycles; - wait_period = data->poll_period - - CLOCK_32K_HW_CYCLES_TO_US(cycles_diff); - - /* Override wait_period in case it is less than 1 ms */ - if (wait_period < MSEC_PER_MS) { - wait_period = MSEC_PER_MS; - } - - /* wait period results in a larger number when - * current cycles counter wrap. In this case, the - * whole poll period is used - */ - if (wait_period > data->poll_period) { - LOG_DBG("wait_period: %u", wait_period); - - wait_period = data->poll_period; - } - - /* Allow other threads to run while we sleep */ - k_usleep(wait_period); - } - - pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + } else { + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, + PM_ALL_SUBSTATES); + data->pm_lock_taken = true; } } @@ -461,7 +182,6 @@ static int xec_kbd_pm_action(const struct device *dev, enum pm_device_action act static int xec_kbd_init(const struct device *dev) { struct xec_kbd_config const *cfg = dev->config; - struct xec_kbd_data *const data = dev->data; struct kscan_regs *regs = cfg->regs; int ret; @@ -479,53 +199,51 @@ static int xec_kbd_init(const struct device *dev) regs->KSO_SEL &= ~BIT(MCHP_KSCAN_KSO_EN_POS); regs->KSI_IEN = MCHP_KSCAN_KSI_IEN_REG_MASK; - /* Time figures are transformed from msec to usec */ - data->deb_time_press = (uint32_t) - (CONFIG_INPUT_XEC_DEBOUNCE_DOWN * MSEC_PER_MS); - data->deb_time_rel = (uint32_t) - (CONFIG_INPUT_XEC_DEBOUNCE_UP * MSEC_PER_MS); - data->poll_period = (uint32_t) - (CONFIG_INPUT_XEC_POLL_PERIOD * MSEC_PER_MS); - data->poll_timeout = 100 * MSEC_PER_MS; - - k_sem_init(&data->poll_lock, 0, 1); - - k_thread_create(&data->thread, data->thread_stack, - TASK_STACK_SIZE, - (void (*)(void *, void *, void *))polling_task, - (void *)dev, NULL, NULL, - K_PRIO_COOP(4), 0, K_NO_WAIT); - /* Interrupts are enabled in the thread function */ IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), - scan_matrix_xec_isr, DEVICE_DT_INST_GET(0), 0); + xec_kbd_isr, DEVICE_DT_INST_GET(0), 0); xec_kbd_clear_girq_status(dev); - xec_kbd_configure_girq(dev, true); + xec_kbd_configure_girq(dev); - return 0; + return input_kbd_matrix_common_init(dev); } -static struct xec_kbd_data kbd_data; - PINCTRL_DT_INST_DEFINE(0); +PM_DEVICE_DT_INST_DEFINE(0, xec_kbd_pm_action); + +INPUT_KBD_MATRIX_DT_INST_DEFINE(0); + +static const struct input_kbd_matrix_api xec_kbd_api = { + .drive_column = xec_kbd_drive_column, + .read_row = xec_kbd_read_row, + .set_detect_mode = xec_kbd_set_detect_mode, +}; + /* To enable wakeup, set the "wakeup-source" on the keyboard scanning device * node. */ static struct xec_kbd_config xec_kbd_cfg_0 = { + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, &xec_kbd_api), .regs = (struct kscan_regs *)(DT_INST_REG_ADDR(0)), - .girq = (uint8_t)(DT_INST_PROP_BY_IDX(0, girqs, 0)), - .girq_pos = (uint8_t)(DT_INST_PROP_BY_IDX(0, girqs, 1)), - .pcr_idx = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 0)), - .pcr_pos = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 1)), + .girq = DT_INST_PROP_BY_IDX(0, girqs, 0), + .girq_pos = DT_INST_PROP_BY_IDX(0, girqs, 1), +#ifdef CONFIG_SOC_SERIES_MEC172X + .pcr_idx = DT_INST_PROP_BY_IDX(0, pcrs, 0), + .pcr_pos = DT_INST_PROP_BY_IDX(0, pcrs, 1), +#endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .wakeup_source = DT_INST_PROP(0, wakeup_source) }; -PM_DEVICE_DT_INST_DEFINE(0, xec_kbd_pm_action); +static struct xec_kbd_data kbd_data_0; DEVICE_DT_INST_DEFINE(0, xec_kbd_init, - PM_DEVICE_DT_INST_GET(0), &kbd_data, &xec_kbd_cfg_0, - POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, - NULL); + PM_DEVICE_DT_INST_GET(0), &kbd_data_0, &xec_kbd_cfg_0, + POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, + "only one microchip,xec-kbd compatible node can be supported"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, row_size), 1, 8), "invalid row-size"); +BUILD_ASSERT(IN_RANGE(DT_INST_PROP(0, col_size), 1, 18), "invalid col-size"); diff --git a/dts/bindings/input/microchip,xec-kbd.yaml b/dts/bindings/input/microchip,xec-kbd.yaml index f5f2250ec6..2c28c49ec4 100644 --- a/dts/bindings/input/microchip,xec-kbd.yaml +++ b/dts/bindings/input/microchip,xec-kbd.yaml @@ -6,7 +6,7 @@ description: Microchip XEC keyboard matrix controller compatible: "microchip,xec-kbd" -include: [base.yaml, pinctrl-device.yaml] +include: [kbd-matrix-common.yaml, pinctrl-device.yaml] properties: "#address-cells": @@ -32,3 +32,9 @@ properties: type: array required: true description: ADC PCR register index and bit position + + row-size: + required: true + + col-size: + required: true