diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb.dts b/boards/riscv/it82xx2_evb/it82xx2_evb.dts index 3110363d88a..1d1bb23eeb6 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 73f7ec1b1de..c111e9092aa 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 bbd9699decc..6e729b27c3a 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 560f4fdd7d9..6f16fba1d6e 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 +#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) -struct input_it8xxx2_kbd_wuc_map_cfg { +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) +static void it8xxx2_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 < 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) -{ - 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 1aec1e1e7a9..d809f41fbbc 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