From e87ded3f03798b2f2f348984f673489542a127cc Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 13 Nov 2023 16:27:01 +0000 Subject: [PATCH] input: it8xxx2: use the generic keyboard code Split the common keyboard scanning code out of the ITE specific driver and use the generic code instead. Note that this changes few timing defaults, the change is not significant though so I suspect there's no difference in practice. Signed-off-by: Fabio Baltieri --- boards/riscv/it82xx2_evb/it82xx2_evb.dts | 2 + boards/riscv/it8xxx2_evb/it8xxx2_evb.dts | 2 + drivers/input/Kconfig.it8xxx2 | 40 +-- drivers/input/input_ite_it8xxx2_kbd.c | 436 ++++------------------- dts/bindings/input/ite,it8xxx2-kbd.yaml | 8 +- 5 files changed, 90 insertions(+), 398 deletions(-) diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.dts b/boards/riscv/it82xx2_evb/it82xx2_evb.dts index 3110363d88a8..1d1bb23eeb68 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb.dts +++ b/boards/riscv/it82xx2_evb/it82xx2_evb.dts @@ -189,6 +189,8 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index 73f7ec1b1def..c111e9092aa1 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -173,6 +173,8 @@ &kso14_default &kso15_default>; pinctrl-names = "default"; + row-size = <8>; + col-size = <16>; kscan_input: kscan-input { compatible = "zephyr,kscan-input"; diff --git a/drivers/input/Kconfig.it8xxx2 b/drivers/input/Kconfig.it8xxx2 index bbd9699decc3..6e729b27c3a9 100644 --- a/drivers/input/Kconfig.it8xxx2 +++ b/drivers/input/Kconfig.it8xxx2 @@ -1,47 +1,11 @@ # Copyright (c) 2021 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -menuconfig INPUT_ITE_IT8XXX2_KBD +config INPUT_ITE_IT8XXX2_KBD bool "ITE keyboard scanning driver" default y depends on DT_HAS_ITE_IT8XXX2_KBD_ENABLED + select INPUT_KBD_MATRIX select MULTITHREADING help This option enables the ITE keyboard scan driver. - -if INPUT_ITE_IT8XXX2_KBD - -config INPUT_ITE_IT8XXX2_COLUMN_SIZE - int "INPUT_ITE_IT8XXX2_COLUMN_SIZE" - range 16 18 - default 16 - help - Adjust the value to your keyboard columns. The maximum - column size for the ITE family is 18. - -config INPUT_ITE_IT8XXX2_ROW_SIZE - int "INPUT_ITE_IT8XXX2_ROW_SIZE" - default 8 - help - Adjust the value to your keyboard rows. The maximum - row size for the ITE family is 8. - -config INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN - int "INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN" - default 9 - help - Determines the time in msecs for debouncing a key press. - -config INPUT_ITE_IT8XXX2_DEBOUNCE_UP - int "INPUT_ITE_IT8XXX2_DEBOUNCE_UP" - default 30 - help - Determines the time in msecs for debouncing a key release. - -config INPUT_ITE_IT8XXX2_POLL_PERIOD - int "INPUT_ITE_IT8XXX2_POLL_PERIOD" - default 3 - help - Defines the poll period in msecs between matrix scans. - -endif diff --git a/drivers/input/input_ite_it8xxx2_kbd.c b/drivers/input/input_ite_it8xxx2_kbd.c index 560f4fdd7d91..6f16fba1d6e7 100644 --- a/drivers/input/input_ite_it8xxx2_kbd.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -14,40 +14,30 @@ #include #include #include +#include #include #include #include LOG_MODULE_REGISTER(input_ite_it8xxx2_kbd); -#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) -#define KEYBOARD_COLUMN_DRIVE_ALL -2 -#define KEYBOARD_COLUMN_DRIVE_NONE -1 -/* Free run timer counts transform to micro-seconds (clock source is 32768Hz) */ -#define CLOCK_32K_HW_CYCLES_TO_US(X) \ - (uint32_t)((((uint64_t)(X) * 1000000U) / \ - sys_clock_hw_cycles_per_sec())) -/* Milli-second transform to micro-second */ -#define MS_TO_US 1000U -/* Number of tracked scan times */ -#define SCAN_OCURRENCES 30U -/* Thread stack size */ -#define TASK_STACK_SIZE 1024 - -struct input_it8xxx2_kbd_wuc_map_cfg { +#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) + +struct it8xxx2_kbd_wuc_map_cfg { /* WUC control device structure */ const struct device *wucs; /* WUC pin mask */ uint8_t mask; }; -struct input_it8xxx2_kbd_config { +struct it8xxx2_kbd_config { + struct input_kbd_matrix_common_config common; /* Keyboard scan controller base address */ struct kscan_it8xxx2_regs *base; /* Keyboard scan input (KSI) wake-up irq */ int irq; /* KSI[7:0] wake-up input source configuration list */ - const struct input_it8xxx2_kbd_wuc_map_cfg *wuc_map_list; + const struct it8xxx2_kbd_wuc_map_cfg *wuc_map_list; /* KSI[7:0]/KSO[17:0] keyboard scan alternate configuration */ const struct pinctrl_dev_config *pcfg; /* KSO16 GPIO cells */ @@ -56,44 +46,26 @@ struct input_it8xxx2_kbd_config { struct gpio_dt_spec kso17_gpios; }; -/* Device data */ -struct input_it8xxx2_kbd_data { - /* Variables in usec units */ - uint32_t deb_time_press; - uint32_t deb_time_rel; - int32_t poll_timeout; - uint32_t poll_period; - uint8_t matrix_stable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_unstable_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - uint8_t matrix_previous_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE]; - /* Index in to the scan_clock_cycle to indicate start of debouncing */ - uint8_t scan_cycle_idx[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] - [CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE]; - /* - * 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; +struct it8xxx2_kbd_data { + struct input_kbd_matrix_common_data common; /* KSI[7:0] wake-up interrupt status mask */ uint8_t ksi_pin_mask; - - K_KERNEL_STACK_MEMBER(thread_stack, TASK_STACK_SIZE); }; -static void drive_keyboard_column(const struct device *dev, int col) +INPUT_KBD_STRUCT_CHECK(struct it8xxx2_kbd_config, struct it8xxx2_kbd_data); + +static void it8xxx2_kbd_drive_column(const struct device *dev, int col) { - const struct input_it8xxx2_kbd_config *const config = dev->config; + const struct it8xxx2_kbd_config *const config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; struct kscan_it8xxx2_regs *const inst = config->base; int mask; /* Tri-state all outputs */ - if (col == KEYBOARD_COLUMN_DRIVE_NONE) { + if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) { mask = 0x3ffff; /* Assert all outputs */ - } else if (col == KEYBOARD_COLUMN_DRIVE_ALL) { + } else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) { mask = 0; /* Assert a single output */ } else { @@ -103,86 +75,24 @@ static void drive_keyboard_column(const struct device *dev, int col) /* Set KSO[17:0] output data */ inst->KBS_KSOL = (uint8_t) (mask & 0xff); inst->KBS_KSOH1 = (uint8_t) ((mask >> 8) & 0xff); -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff); -#endif + if (common->col_size > 16) { + inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff); + } } -static uint8_t read_keyboard_row(const struct device *dev) +static int it8xxx2_kbd_read_row(const struct device *dev) { - const struct input_it8xxx2_kbd_config *const config = dev->config; + const struct it8xxx2_kbd_config *const config = dev->config; struct kscan_it8xxx2_regs *const inst = config->base; /* Bits are active-low, so toggle it (return 1 means key pressed) */ return (inst->KBS_KSI ^ 0xff); } -static bool is_matrix_ghosting(const uint8_t *state) -{ - /* - * 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 < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { - if (!state[c]) - continue; - - for (int c_n = c + 1; c_n < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; 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 < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; col++) { - /* Drive specific column low and others high */ - 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 keyboard_raw_interrupt(const struct device *dev) +static void it8xxx2_kbd_isr(const struct device *dev) { - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + struct it8xxx2_kbd_data *data = dev->data; /* * W/C wakeup interrupt status of KSI[7:0] pins @@ -196,14 +106,13 @@ static void keyboard_raw_interrupt(const struct device *dev) /* W/C interrupt status of KSI[7:0] pins */ ite_intc_isr_clear(config->irq); - /* Release poll lock semaphore */ - k_sem_give(&data->poll_lock); + input_kbd_matrix_poll_start(dev); } -void keyboard_raw_enable_interrupt(const struct device *dev, int enable) +static void it8xxx2_kbd_set_detect_mode(const struct device *dev, bool enable) { - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + struct it8xxx2_kbd_data *data = dev->data; if (enable) { /* @@ -224,217 +133,33 @@ void keyboard_raw_enable_interrupt(const struct device *dev, int enable) } } -static bool check_key_events(const struct device *dev) +static int it8xxx2_kbd_init(const struct device *dev) { - struct input_it8xxx2_kbd_data *data = dev->data; - uint8_t matrix_new_state[CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE] = {0U}; - bool key_pressed = false; - uint32_t cycles_now = k_cycle_get_32(); - uint8_t row_changed = 0U; - uint8_t deb_col; - - 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; - } - - /* - * The intent of this loop is to gather information related to key - * changes - */ - for (int c = 0; c < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; 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 < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; 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 < CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE; c++) { - deb_col = data->matrix_unstable_state[c]; - - if (!deb_col) - continue; - - /* Debouncing for each row key occurs here */ - for (int r = 0; r < CONFIG_INPUT_ITE_IT8XXX2_ROW_SIZE; 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; -} - -/** - * @brief Determine if a timer is expired. - * - * @param start_cycles The starting time of HW cycle. - * @param timeout Pointer to the period time. - * - * @retval true If timer is expired; - * false If timer isn't expired. - */ -static bool poll_expired(uint32_t start_cycles, int32_t *timeout) -{ - uint32_t now_cycles; - uint32_t microsecs_spent; - - now_cycles = k_cycle_get_32(); - microsecs_spent = CLOCK_32K_HW_CYCLES_TO_US(now_cycles - start_cycles); - - /* Update the timeout value */ - *timeout -= microsecs_spent; - - return !(*timeout >= 0); -} - -void polling_task(const struct device *dev, void *dummy2, void *dummy3) -{ - struct input_it8xxx2_kbd_data *data = dev->data; - int32_t local_poll_timeout = data->poll_timeout; - uint32_t current_cycles; - uint32_t cycles_delta; - uint32_t wait_period; - - ARG_UNUSED(dummy2); - ARG_UNUSED(dummy3); - - while (true) { - /* Init all KSO output low */ - drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_ALL); - /* Enable wakeup and interrupt of KSI pins */ - keyboard_raw_enable_interrupt(dev, 1); - /* Wait poll lock semaphore */ - k_sem_take(&data->poll_lock, K_FOREVER); - /* Disable wakeup and interrupt of KSI pins after fired */ - keyboard_raw_enable_interrupt(dev, 0); - - uint32_t start_poll_cycles = k_cycle_get_32(); - - while (true) { - uint32_t start_period_cycles = k_cycle_get_32(); - - if (check_key_events(dev)) { - 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_delta = current_cycles - start_period_cycles; - wait_period = data->poll_period - - CLOCK_32K_HW_CYCLES_TO_US(cycles_delta); - - /* Override wait_period in case it's less than 1000 us */ - if (wait_period < MS_TO_US) { - wait_period = MS_TO_US; - } - - /* - * 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); - } - } -} - -static int input_it8xxx2_kbd_init(const struct device *dev) -{ - const struct input_it8xxx2_kbd_config *const config = dev->config; - struct input_it8xxx2_kbd_data *data = dev->data; + const struct it8xxx2_kbd_config *const config = dev->config; + const struct input_kbd_matrix_common_config *common = &config->common; + struct it8xxx2_kbd_data *data = dev->data; struct kscan_it8xxx2_regs *const inst = config->base; int status; /* Disable wakeup and interrupt of KSI pins before configuring */ - keyboard_raw_enable_interrupt(dev, 0); + it8xxx2_kbd_set_detect_mode(dev, false); -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - /* - * For KSO[16] and KSO[17]: - * 1.GPOTRC: - * Bit[x] = 1b: Enable the open-drain mode of KSO pin - * 2.GPCRCx: - * Bit[7:6] = 00b: Select alternate KSO function - * Bit[2] = 1b: Enable the internal pull-up of KSO pin - * - * NOTE: Set input temporarily for gpio_pin_configure(), after that - * pinctrl_apply_state() set to alternate function immediately. - */ - gpio_pin_configure_dt(&config->kso16_gpios, GPIO_INPUT); - gpio_pin_configure_dt(&config->kso17_gpios, GPIO_INPUT); -#endif + if (common->col_size > 16) { + /* + * For KSO[16] and KSO[17]: + * 1.GPOTRC: + * Bit[x] = 1b: Enable the open-drain mode of KSO pin + * 2.GPCRCx: + * Bit[7:6] = 00b: Select alternate KSO function + * Bit[2] = 1b: Enable the internal pull-up of KSO pin + * + * NOTE: Set input temporarily for gpio_pin_configure(), after + * that pinctrl_apply_state() set to alternate function + * immediately. + */ + gpio_pin_configure_dt(&config->kso16_gpios, GPIO_INPUT); + gpio_pin_configure_dt(&config->kso17_gpios, GPIO_INPUT); + } /* * Enable the internal pull-up and kbs mode of the KSI[7:0] pins. * Enable the internal pull-up and kbs mode of the KSO[15:0] pins. @@ -449,9 +174,9 @@ static int input_it8xxx2_kbd_init(const struct device *dev) /* KSO[17:0] pins output low */ inst->KBS_KSOL = 0x00; inst->KBS_KSOH1 = 0x00; -#if (CONFIG_INPUT_ITE_IT8XXX2_COLUMN_SIZE > 16) - inst->KBS_KSOH2 = 0x00; -#endif + if (common->col_size > 16) { + inst->KBS_KSOH2 = 0x00; + } for (int i = 0; i < KEYBOARD_KSI_PIN_COUNT; i++) { /* Select wakeup interrupt falling-edge triggered of KSI[7:0] pins */ @@ -469,10 +194,8 @@ static int input_it8xxx2_kbd_init(const struct device *dev) * We want to clear KSI[7:0] pins status at a time when wakeup * interrupt fire, so gather the KSI[7:0] pin mask value here. */ - if (IS_ENABLED(CONFIG_LOG)) { - if (config->wuc_map_list[i].wucs != config->wuc_map_list[0].wucs) { - LOG_ERR("KSI%d pin isn't in the same wuc node!", i); - } + if (config->wuc_map_list[i].wucs != config->wuc_map_list[0].wucs) { + LOG_ERR("KSI%d pin isn't in the same wuc node!", i); } data->ksi_pin_mask |= config->wuc_map_list[i].mask; } @@ -480,48 +203,43 @@ static int input_it8xxx2_kbd_init(const struct device *dev) /* W/C interrupt status of KSI[7:0] pins */ ite_intc_isr_clear(config->irq); - /* Kconfig.it8xxx2 time figures are transformed from msec to usec */ - data->deb_time_press = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_DOWN * MS_TO_US); - data->deb_time_rel = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_DEBOUNCE_UP * MS_TO_US); - data->poll_period = - (uint32_t) (CONFIG_INPUT_ITE_IT8XXX2_POLL_PERIOD * MS_TO_US); - data->poll_timeout = 100 * MS_TO_US; - - /* Create poll lock semaphore */ - k_sem_init(&data->poll_lock, 0, 1); - irq_connect_dynamic(DT_INST_IRQN(0), 0, - (void (*)(const void *))keyboard_raw_interrupt, + (void (*)(const void *))it8xxx2_kbd_isr, (const void *)dev, 0); - /* Create keyboard scan task */ - 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); - - return 0; + return input_kbd_matrix_common_init(dev); } -static const struct input_it8xxx2_kbd_wuc_map_cfg - input_it8xxx2_kbd_wuc[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = IT8XXX2_DT_WUC_ITEMS_LIST(0); +static const struct it8xxx2_kbd_wuc_map_cfg + it8xxx2_kbd_wuc[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = IT8XXX2_DT_WUC_ITEMS_LIST(0); PINCTRL_DT_INST_DEFINE(0); -static const struct input_it8xxx2_kbd_config input_it8xxx2_kbd_cfg = { +INPUT_KBD_MATRIX_DT_INST_DEFINE(0); + +static const struct input_kbd_matrix_api it8xxx2_kbd_api = { + .drive_column = it8xxx2_kbd_drive_column, + .read_row = it8xxx2_kbd_read_row, + .set_detect_mode = it8xxx2_kbd_set_detect_mode, +}; + +static const struct it8xxx2_kbd_config it8xxx2_kbd_cfg_0 = { + .common = INPUT_KBD_MATRIX_DT_INST_COMMON_CONFIG_INIT(0, &it8xxx2_kbd_api), .base = (struct kscan_it8xxx2_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0), .irq = DT_INST_IRQN(0), - .wuc_map_list = input_it8xxx2_kbd_wuc, + .wuc_map_list = it8xxx2_kbd_wuc, .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .kso16_gpios = GPIO_DT_SPEC_INST_GET(0, kso16_gpios), .kso17_gpios = GPIO_DT_SPEC_INST_GET(0, kso17_gpios), }; -static struct input_it8xxx2_kbd_data input_it8xxx2_kbd_kbd_data; +static struct it8xxx2_kbd_data it8xxx2_kbd_data_0; -DEVICE_DT_INST_DEFINE(0, &input_it8xxx2_kbd_init, NULL, - &input_it8xxx2_kbd_kbd_data, &input_it8xxx2_kbd_cfg, +DEVICE_DT_INST_DEFINE(0, &it8xxx2_kbd_init, NULL, + &it8xxx2_kbd_data_0, &it8xxx2_kbd_cfg_0, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, + "only one ite,it8xxx2-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), 16, 18), "invalid col-size"); diff --git a/dts/bindings/input/ite,it8xxx2-kbd.yaml b/dts/bindings/input/ite,it8xxx2-kbd.yaml index 1aec1e1e7a9a..d809f41fbbc9 100644 --- a/dts/bindings/input/ite,it8xxx2-kbd.yaml +++ b/dts/bindings/input/ite,it8xxx2-kbd.yaml @@ -5,7 +5,7 @@ description: ITE it8xxx2 keyboard matrix controller compatible: "ite,it8xxx2-kbd" -include: [kscan.yaml, pinctrl-device.yaml] +include: [kbd-matrix-common.yaml, pinctrl-device.yaml] properties: reg: @@ -40,3 +40,9 @@ properties: pinctrl-names: required: true + + row-size: + required: true + + col-size: + required: true