input: convert kscan_mchp_xec.c driver to input

Convert the XEC keyboard scanning driver from kscan to input, add the
corresponding kscan compatibility node to the current board, build test
only.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
Fabio Baltieri 2023-11-14 11:05:12 +00:00 committed by Anas Nashif
parent 3b50237699
commit ddd2cf1fdc
17 changed files with 146 additions and 158 deletions

View file

@ -3,6 +3,9 @@
if BOARD_MEC1501MODULAR_ASSY6885
config INPUT
default y if KSCAN
#PS/2 driver is compiled in terms of this flag.
config ESPI_PERIPHERAL_8042_KBC
default y

View file

@ -17,7 +17,7 @@
zephyr,sram = &sram0;
zephyr,console = &uart1;
zephyr,flash = &flash0;
zephyr,keyboard-scan = &kscan0;
zephyr,keyboard-scan = &kscan_input;
};
aliases {
@ -26,7 +26,7 @@
i2c0 = &i2c_smb_0;
i2c1 = &i2c_smb_1;
kscan0 = &kscan0;
kscan0 = &kscan_input;
watchdog0 = &wdog;
};
};
@ -100,7 +100,7 @@
pinctrl-names = "default";
};
&kscan0 {
&kbd0 {
status = "okay";
pinctrl-0 = < &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso12_gpio125
@ -118,6 +118,10 @@
&ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep
&ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >;
pinctrl-names = "default", "sleep";
kscan_input: kscan-input {
compatible = "zephyr,kscan-input";
};
};
&peci0 {

View file

@ -3,6 +3,9 @@
if BOARD_MEC15XXEVB_ASSY6853
config INPUT
default y if KSCAN
config ESPI_XEC
default y
depends on ESPI

View file

@ -16,7 +16,7 @@
zephyr,sram = &sram0;
zephyr,console = &uart2;
zephyr,flash = &flash0;
zephyr,keyboard-scan = &kscan0;
zephyr,keyboard-scan = &kscan_input;
};
aliases {
@ -29,7 +29,7 @@
i2c-0 = &i2c_smb_0;
i2c1 = &i2c_smb_1;
i2c7 = &i2c_smb_2;
kscan0 = &kscan0;
kscan0 = &kscan_input;
watchdog0 = &wdog;
};
@ -157,7 +157,7 @@
pinctrl-names = "default";
};
&kscan0 {
&kbd0 {
status = "okay";
pinctrl-0 = < &kso00_gpio040 &kso01_gpio045 &kso02_gpio046 &kso12_gpio125
@ -175,6 +175,10 @@
&ksi2_gpio021_sleep &ksi3_gpio026_sleep &ksi4_gpio027_sleep
&ksi5_gpio030_sleep &ksi6_gpio031_sleep &ksi7_gpio032_sleep >;
pinctrl-names = "default", "sleep";
kscan_input: kscan-input {
compatible = "zephyr,kscan-input";
};
};
&peci0 {

View file

@ -3,6 +3,9 @@
if BOARD_MEC172XEVB_ASSY6906
config INPUT
default y if KSCAN
if RTOS_TIMER
# XEC RTOS timer HW frequency is fixed at 32768 Hz.

View file

@ -213,7 +213,7 @@
pinctrl-names = "default";
};
&kscan0 {
&kbd0 {
status = "okay";
pinctrl-0 = < &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026
@ -231,6 +231,10 @@
&kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep
&kso13_gpio126_sleep >;
pinctrl-names = "default", "sleep";
kscan_input: kscan-input {
compatible = "zephyr,kscan-input";
};
};
&ksi0_gpio017 {

View file

@ -3,6 +3,9 @@
if BOARD_MEC172XMODULAR_ASSY6930
config INPUT
default y if KSCAN
if RTOS_TIMER
# XEC RTOS timer HW frequency is fixed at 32768 Hz.

View file

@ -191,7 +191,7 @@
pinctrl-names = "default";
};
&kscan0 {
&kbd0 {
status = "okay";
pinctrl-0 = < &ksi0_gpio017 &ksi1_gpio020 &ksi2_gpio021 &ksi3_gpio026
@ -209,6 +209,10 @@
&kso10_gpio123_sleep &kso11_gpio124_sleep &kso12_gpio125_sleep
&kso13_gpio126_sleep >;
pinctrl-names = "default", "sleep";
kscan_input: kscan-input {
compatible = "zephyr,kscan-input";
};
};
&ksi0_gpio017 {

View file

@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c)
zephyr_library_sources_ifdef(CONFIG_INPUT_PAT912X input_pat912x.c)
zephyr_library_sources_ifdef(CONFIG_INPUT_PMW3610 input_pmw3610.c)
zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c)
zephyr_library_sources_ifdef(CONFIG_INPUT_XEC_KBD input_xec_kbd.c)
zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c)
# zephyr-keep-sorted-stop

View file

@ -24,6 +24,7 @@ source "drivers/input/Kconfig.pat912x"
source "drivers/input/Kconfig.pmw3610"
source "drivers/input/Kconfig.sdl"
source "drivers/input/Kconfig.stmpe811"
source "drivers/input/Kconfig.xec"
source "drivers/input/Kconfig.xpt2046"
# zephyr-keep-sorted-stop

View file

@ -3,47 +3,47 @@
# Copyright (c) 2019 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
menuconfig KSCAN_XEC
bool "Microchip XEC series KSCAN driver"
menuconfig INPUT_XEC_KBD
bool "Microchip XEC series keyboard matrix driver"
default y
depends on DT_HAS_MICROCHIP_XEC_KSCAN_ENABLED
depends on DT_HAS_MICROCHIP_XEC_KBD_ENABLED
select MULTITHREADING
select PINCTRL
help
Enable the Microchip XEC Kscan IO driver.
if KSCAN_XEC
if INPUT_XEC_KBD
config KSCAN_XEC_COLUMN_SIZE
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 KSCAN_XEC_ROW_SIZE
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 KSCAN_XEC_DEBOUNCE_DOWN
config INPUT_XEC_DEBOUNCE_DOWN
int "Keyscan XEC Debounce Down"
default 10
help
Determines the time in msecs for debouncing a key press.
config KSCAN_XEC_DEBOUNCE_UP
config INPUT_XEC_DEBOUNCE_UP
int "Keyscan XEC Debounce Up"
default 20
help
Determines the time in msecs for debouncing a key release.
config KSCAN_XEC_POLL_PERIOD
config INPUT_XEC_POLL_PERIOD
int "Keyscan XEC Poll Period"
default 5
help
Defines the poll period in msecs between between matrix scans.
endif # KSCAN_XEC
endif # INPUT_XEC

View file

@ -4,30 +4,28 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT microchip_xec_kscan
#define DT_DRV_COMPAT microchip_xec_kbd
#include <cmsis_core.h>
#include <errno.h>
#include <soc.h>
#include <zephyr/device.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/input/input.h>
#include <zephyr/irq.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#ifdef CONFIG_SOC_SERIES_MEC172X
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
#include <zephyr/drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#endif
#include <zephyr/drivers/kscan.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#define LOG_LEVEL CONFIG_KSCAN_LOG_LEVEL
LOG_MODULE_REGISTER(kscan_mchp_xec);
LOG_MODULE_REGISTER(input_xec_kbd, CONFIG_INPUT_LOG_LEVEL);
#define MAX_MATRIX_KEY_COLS CONFIG_KSCAN_XEC_COLUMN_SIZE
#define MAX_MATRIX_KEY_ROWS CONFIG_KSCAN_XEC_ROW_SIZE
#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
@ -42,7 +40,7 @@ LOG_MODULE_REGISTER(kscan_mchp_xec);
/* Thread stack size */
#define TASK_STACK_SIZE 1024
struct kscan_xec_config {
struct xec_kbd_config {
struct kscan_regs *regs;
const struct pinctrl_dev_config *pcfg;
uint8_t rsvd[3];
@ -54,7 +52,7 @@ struct kscan_xec_config {
bool wakeup_source;
};
struct kscan_xec_data {
struct xec_kbd_data {
/* variables in usec units */
uint32_t deb_time_press;
uint32_t deb_time_rel;
@ -71,24 +69,22 @@ struct kscan_xec_data {
uint8_t scan_clk_cycle[SCAN_OCURRENCES];
struct k_sem poll_lock;
uint8_t scan_cycles_idx;
kscan_callback_t callback;
struct k_thread thread;
atomic_t enable_scan;
K_KERNEL_STACK_MEMBER(thread_stack, TASK_STACK_SIZE);
};
#ifdef CONFIG_SOC_SERIES_MEC172X
static void kscan_clear_girq_status(const struct device *dev)
static void xec_kbd_clear_girq_status(const struct device *dev)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
}
static void kscan_configure_girq(const struct device *dev, bool enable)
static void xec_kbd_configure_girq(const struct device *dev, bool enable)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
if (enable) {
mchp_xec_ecia_enable(cfg->girq, cfg->girq_pos);
@ -97,24 +93,24 @@ static void kscan_configure_girq(const struct device *dev, bool enable)
}
}
static void kscan_clr_slp_en(const struct device *dev)
static void xec_kbd_clr_slp_en(const struct device *dev)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
z_mchp_xec_pcr_periph_sleep(cfg->pcr_idx, cfg->pcr_pos, 0);
}
#else
static void kscan_clear_girq_status(const struct device *dev)
static void xec_kbd_clear_girq_status(const struct device *dev)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
MCHP_GIRQ_SRC(cfg->girq) = BIT(cfg->girq_pos);
}
static void kscan_configure_girq(const struct device *dev, bool enable)
static void xec_kbd_configure_girq(const struct device *dev, bool enable)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
if (enable) {
MCHP_GIRQ_ENSET(cfg->girq) = BIT(cfg->girq_pos);
@ -123,7 +119,7 @@ static void kscan_configure_girq(const struct device *dev, bool enable)
}
}
static void kscan_clr_slp_en(const struct device *dev)
static void xec_kbd_clr_slp_en(const struct device *dev)
{
ARG_UNUSED(dev);
@ -131,10 +127,9 @@ static void kscan_clr_slp_en(const struct device *dev)
}
#endif
static void drive_keyboard_column(const struct device *dev, int data)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
struct kscan_regs *regs = cfg->regs;
if (data == KEYBOARD_COLUMN_DRIVE_ALL) {
@ -153,7 +148,7 @@ static void drive_keyboard_column(const struct device *dev, int data)
static uint8_t read_keyboard_row(const struct device *dev)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
struct kscan_regs *regs = cfg->regs;
/* In this implementation a 1 means key pressed */
@ -221,17 +216,17 @@ static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state)
static void scan_matrix_xec_isr(const struct device *dev)
{
struct kscan_xec_data *const data = dev->data;
struct xec_kbd_data *const data = dev->data;
kscan_clear_girq_status(dev);
xec_kbd_clear_girq_status(dev);
irq_disable(DT_INST_IRQN(0));
k_sem_give(&data->poll_lock);
LOG_DBG(" ");
LOG_DBG("");
}
static bool check_key_events(const struct device *dev)
{
struct kscan_xec_data *const data = dev->data;
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();
@ -322,10 +317,10 @@ static bool check_key_events(const struct device *dev)
* application about the keys pressed.
*/
data->matrix_stable_state[c] ^= mask;
if (atomic_get(&data->enable_scan) == 1U) {
data->callback(dev, r, c,
row_bit ? true : false);
}
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);
}
}
@ -351,8 +346,8 @@ static bool poll_expired(uint32_t start_cycles, int64_t *timeout)
void polling_task(const struct device *dev, void *dummy2, void *dummy3)
{
struct kscan_xec_config const *cfg = dev->config;
struct kscan_xec_data *const data = dev->data;
struct xec_kbd_config const *cfg = dev->config;
struct xec_kbd_data *const data = dev->data;
struct kscan_regs *regs = cfg->regs;
uint32_t current_cycles;
uint32_t cycles_diff;
@ -366,7 +361,7 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3)
regs->KSI_STS = MCHP_KSCAN_KSO_SEL_REG_MASK;
/* Ignore isr when releasing a key as we are polling */
kscan_clear_girq_status(dev);
xec_kbd_clear_girq_status(dev);
NVIC_ClearPendingIRQ(DT_INST_IRQN(0));
irq_enable(DT_INST_IRQN(0));
@ -377,7 +372,7 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3)
uint32_t start_poll_cycles = k_cycle_get_32();
while (atomic_get(&data->enable_scan) == 1U) {
while (true) {
uint32_t start_period_cycles = k_cycle_get_32();
if (check_key_events(DEVICE_DT_INST_GET(0))) {
@ -407,7 +402,7 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3)
* whole poll period is used
*/
if (wait_period > data->poll_period) {
LOG_DBG("wait_period : %u", wait_period);
LOG_DBG("wait_period: %u", wait_period);
wait_period = data->poll_period;
}
@ -420,99 +415,63 @@ void polling_task(const struct device *dev, void *dummy2, void *dummy3)
}
}
static int kscan_xec_configure(const struct device *dev,
kscan_callback_t callback)
{
struct kscan_xec_data *const data = dev->data;
if (!callback) {
return -EINVAL;
}
data->callback = callback;
kscan_clear_girq_status(dev);
kscan_configure_girq(dev, 1);
return 0;
}
static int kscan_xec_inhibit_interface(const struct device *dev)
{
struct kscan_xec_data *const data = dev->data;
atomic_set(&data->enable_scan, 0);
return 0;
}
static int kscan_xec_enable_interface(const struct device *dev)
{
struct kscan_xec_data *const data = dev->data;
atomic_set(&data->enable_scan, 1);
return 0;
}
#ifdef CONFIG_PM_DEVICE
static int kscan_xec_pm_action(const struct device *dev, enum pm_device_action action)
static int xec_kbd_pm_action(const struct device *dev, enum pm_device_action action)
{
struct kscan_xec_config const *cfg = dev->config;
struct xec_kbd_config const *cfg = dev->config;
struct kscan_regs *regs = cfg->regs;
int ret = 0;
int ret;
if (cfg->wakeup_source) {
return 0;
}
switch (action) {
case PM_DEVICE_ACTION_RESUME:
if (!(cfg->wakeup_source)) {
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
if (ret != 0) {
LOG_ERR("XEC KSCAN pinctrl init failed (%d)", ret);
return ret;
}
regs->KSO_SEL &= ~BIT(MCHP_KSCAN_KSO_EN_POS);
/* Clea Status register */
/* Clear status register */
regs->KSI_STS = MCHP_KSCAN_KSO_SEL_REG_MASK;
regs->KSI_IEN = MCHP_KSCAN_KSI_IEN_REG_MASK;
}
break;
case PM_DEVICE_ACTION_SUSPEND:
if (!(cfg->wakeup_source)) {
regs->KSO_SEL |= BIT(MCHP_KSCAN_KSO_EN_POS);
regs->KSI_IEN = (~MCHP_KSCAN_KSI_IEN_REG_MASK);
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP);
if (ret == -ENOENT) { /* pinctrl-1 does not exist. */
ret = 0;
}
if (ret != -ENOENT) {
/* pinctrl-1 does not exist */
return ret;
}
break;
default:
ret = -ENOTSUP;
return -ENOTSUP;
}
return ret;
return 0;
}
#endif /* CONFIG_PM_DEVICE */
static const struct kscan_driver_api kscan_xec_driver_api = {
.config = kscan_xec_configure,
.disable_callback = kscan_xec_inhibit_interface,
.enable_callback = kscan_xec_enable_interface,
};
static int kscan_xec_init(const struct device *dev)
static int xec_kbd_init(const struct device *dev)
{
struct kscan_xec_config const *cfg = dev->config;
struct kscan_xec_data *const data = dev->data;
struct xec_kbd_config const *cfg = dev->config;
struct xec_kbd_data *const data = dev->data;
struct kscan_regs *regs = cfg->regs;
int ret;
int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
if (ret != 0) {
LOG_ERR("XEC KSCAN pinctrl init failed (%d)", ret);
return ret;
}
kscan_clr_slp_en(dev);
xec_kbd_clr_slp_en(dev);
/* Enable predrive */
regs->KSO_SEL |= BIT(MCHP_KSCAN_KSO_EN_POS);
@ -522,15 +481,14 @@ static int kscan_xec_init(const struct device *dev)
/* Time figures are transformed from msec to usec */
data->deb_time_press = (uint32_t)
(CONFIG_KSCAN_XEC_DEBOUNCE_DOWN * MSEC_PER_MS);
(CONFIG_INPUT_XEC_DEBOUNCE_DOWN * MSEC_PER_MS);
data->deb_time_rel = (uint32_t)
(CONFIG_KSCAN_XEC_DEBOUNCE_UP * MSEC_PER_MS);
(CONFIG_INPUT_XEC_DEBOUNCE_UP * MSEC_PER_MS);
data->poll_period = (uint32_t)
(CONFIG_KSCAN_XEC_POLL_PERIOD * MSEC_PER_MS);
(CONFIG_INPUT_XEC_POLL_PERIOD * MSEC_PER_MS);
data->poll_timeout = 100 * MSEC_PER_MS;
k_sem_init(&data->poll_lock, 0, 1);
atomic_set(&data->enable_scan, 1);
k_thread_create(&data->thread, data->thread_stack,
TASK_STACK_SIZE,
@ -542,20 +500,20 @@ static int kscan_xec_init(const struct device *dev)
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
scan_matrix_xec_isr, DEVICE_DT_INST_GET(0), 0);
xec_kbd_clear_girq_status(dev);
xec_kbd_configure_girq(dev, true);
return 0;
}
static struct kscan_xec_data kbd_data;
static struct xec_kbd_data kbd_data;
PINCTRL_DT_INST_DEFINE(0);
/* To enable wakeup on the KSCAN, the DTS needs to have entries defined
* in the KSCAN node in the DTS specifying it as a wake source;
* Example as below
*
* wakeup-source;
/* To enable wakeup, set the "wakeup-source" on the keyboard scanning device
* node.
*/
static struct kscan_xec_config kscan_xec_cfg_0 = {
static struct xec_kbd_config xec_kbd_cfg_0 = {
.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)),
@ -565,9 +523,9 @@ static struct kscan_xec_config kscan_xec_cfg_0 = {
.wakeup_source = DT_INST_PROP(0, wakeup_source)
};
PM_DEVICE_DT_INST_DEFINE(0, kscan_xec_pm_action);
PM_DEVICE_DT_INST_DEFINE(0, xec_kbd_pm_action);
DEVICE_DT_INST_DEFINE(0, kscan_xec_init,
PM_DEVICE_DT_INST_GET(0), &kbd_data, &kscan_xec_cfg_0,
POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY,
&kscan_xec_driver_api);
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);

View file

@ -4,7 +4,6 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/kscan.h)
zephyr_library()
zephyr_library_sources_ifdef(CONFIG_KSCAN_XEC kscan_mchp_xec.c)
zephyr_library_sources_ifdef(CONFIG_KSCAN_HT16K33 kscan_ht16k33.c)
zephyr_library_sources_ifdef(CONFIG_KSCAN_INPUT kscan_input.c)

View file

@ -10,7 +10,6 @@ menuconfig KSCAN
if KSCAN
source "drivers/kscan/Kconfig.xec"
source "drivers/kscan/Kconfig.ht16k33"
source "drivers/kscan/Kconfig.input"

View file

@ -443,8 +443,8 @@
#io-channel-cells = <1>;
clktime = <32>;
};
kscan0: kscan@40009c00 {
compatible = "microchip,xec-kscan";
kbd0: kbd@40009c00 {
compatible = "microchip,xec-kbd";
reg = <0x40009c00 0x18>;
interrupts = <135 0>;
girqs = <21 25>;

View file

@ -651,8 +651,8 @@ adc0: adc@40007c00 {
#io-channel-cells = <1>;
clktime = <32>;
};
kscan0: kscan@40009c00 {
compatible = "microchip,xec-kscan";
kbd0: kbd@40009c00 {
compatible = "microchip,xec-kbd";
reg = <0x40009c00 0x18>;
interrupts = <135 0>;
girqs = <21 25>;

View file

@ -4,17 +4,19 @@
description: Microchip XEC keyboard matrix controller
compatible: "microchip,xec-kscan"
compatible: "microchip,xec-kbd"
include: [kscan.yaml, pinctrl-device.yaml]
include: [base.yaml, pinctrl-device.yaml]
properties:
"#address-cells":
required: true
const: 1
"#size-cells":
type: int
const: 0
reg:
required: true