From 4e4c535fc399d8ae28d758a97a08e5fbf88930b3 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 31 Oct 2024 12:39:59 +0000 Subject: [PATCH] input: it8xxx2_kbd: add a kso-ignore-mask property The it8xxx2_kbd KSO pins can be used as both keyboard scan and GPIO. By default the keyboard scanning driver controls the output level of all the KSO signals from 0 to (col-size - 1), meaning that any line in between used as GPIO is going to have its output value overridden. Add a kso-ignore-mask property to the keyboard scan driver to allow specifiying extra pins that should not be controlled by the driver. Signed-off-by: Fabio Baltieri --- drivers/input/input_ite_it8xxx2_kbd.c | 16 ++++++++-------- dts/bindings/input/ite,it8xxx2-kbd.yaml | 8 ++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/input/input_ite_it8xxx2_kbd.c b/drivers/input/input_ite_it8xxx2_kbd.c index ba5b03afa0a1f1..c7ff590f3c9eee 100644 --- a/drivers/input/input_ite_it8xxx2_kbd.c +++ b/drivers/input/input_ite_it8xxx2_kbd.c @@ -44,6 +44,8 @@ struct it8xxx2_kbd_config { struct gpio_dt_spec kso16_gpios; /* KSO17 GPIO cells */ struct gpio_dt_spec kso17_gpios; + /* Mask of signals to ignore */ + uint32_t kso_ignore_mask; }; struct it8xxx2_kbd_data { @@ -59,7 +61,7 @@ static void it8xxx2_kbd_drive_column(const struct device *dev, int col) 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; - const uint32_t kso_mask = BIT_MASK(common->col_size); + const uint32_t kso_mask = BIT_MASK(common->col_size) & ~config->kso_ignore_mask; const uint8_t ksol_mask = kso_mask & 0xff; const uint8_t ksoh1_mask = (kso_mask >> 8) & 0xff; uint32_t kso_val; @@ -76,17 +78,14 @@ static void it8xxx2_kbd_drive_column(const struct device *dev, int col) kso_val = kso_mask ^ BIT(col); } - /* Set KSO[17:0] output data */ - inst->KBS_KSOL = (inst->KBS_KSOL & ~ksol_mask) | (kso_val & ksol_mask); - /* - * Disable global interrupts for critical section - * The KBS_KSOH1 register contains both keyboard and GPIO output settings. + /* Set KSO[17:0] output data, disable global interrupts for critical section. + * The KBS_KSO* registers contains both keyboard and GPIO output settings. * Not all bits are for the keyboard will be driven, so a critical section * is needed to avoid race conditions. */ key = irq_lock(); + inst->KBS_KSOL = (inst->KBS_KSOL & ~ksol_mask) | (kso_val & ksol_mask); inst->KBS_KSOH1 = (inst->KBS_KSOH1 & ~ksoh1_mask) | ((kso_val >> 8) & ksoh1_mask); - /* Restore interrupts */ irq_unlock(key); if (common->col_size > 16) { @@ -153,7 +152,7 @@ static int it8xxx2_kbd_init(const struct device *dev) 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; - const uint32_t kso_mask = BIT_MASK(common->col_size); + const uint32_t kso_mask = BIT_MASK(common->col_size) & ~config->kso_ignore_mask; const uint8_t ksol_mask = kso_mask & 0xff; const uint8_t ksoh1_mask = (kso_mask >> 8) & 0xff; int status; @@ -248,6 +247,7 @@ static const struct it8xxx2_kbd_config it8xxx2_kbd_cfg_0 = { .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), + .kso_ignore_mask = DT_INST_PROP(0, kso_ignore_mask), }; static struct it8xxx2_kbd_data it8xxx2_kbd_data_0; diff --git a/dts/bindings/input/ite,it8xxx2-kbd.yaml b/dts/bindings/input/ite,it8xxx2-kbd.yaml index d809f41fbbc971..896a50295bb695 100644 --- a/dts/bindings/input/ite,it8xxx2-kbd.yaml +++ b/dts/bindings/input/ite,it8xxx2-kbd.yaml @@ -35,6 +35,14 @@ properties: description: | The KSO17 pin for the selected port. + kso-ignore-mask: + type: int + default: 0 + description: | + Bitmask of KSO signals to ignore, this can be used to instruct the driver + to skip KSO signals between 0 and (col-size - 1) that are used as GPIOs. + Default to 0 (no signals masked). + pinctrl-0: required: true