input: it8xxx2_kbd: mask out KSOL and KSOH1 register access
KSOL and KSOH1 registers are used not only by the kbd driver, but potentially by other GPIOs attached to the keyboard scanning pins. Mask write access to those registers to ensure drivers don't step over each other. Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
parent
2e36c898c9
commit
d8476170bf
1 changed files with 16 additions and 9 deletions
|
|
@ -16,6 +16,7 @@
|
|||
#include <zephyr/input/input.h>
|
||||
#include <zephyr/input/input_kbd_matrix.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(input_ite_it8xxx2_kbd);
|
||||
|
|
@ -58,24 +59,27 @@ 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;
|
||||
int mask;
|
||||
const uint32_t kso_mask = BIT_MASK(common->col_size);
|
||||
const uint8_t ksol_mask = kso_mask & 0xff;
|
||||
const uint8_t ksoh1_mask = (kso_mask >> 8) & 0xff;
|
||||
uint32_t kso_val;
|
||||
|
||||
/* Tri-state all outputs */
|
||||
if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) {
|
||||
mask = 0x3ffff;
|
||||
kso_val = kso_mask;
|
||||
/* Assert all outputs */
|
||||
} else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) {
|
||||
mask = 0;
|
||||
kso_val = 0;
|
||||
/* Assert a single output */
|
||||
} else {
|
||||
mask = 0x3ffff ^ BIT(col);
|
||||
kso_val = kso_mask ^ BIT(col);
|
||||
}
|
||||
|
||||
/* Set KSO[17:0] output data */
|
||||
inst->KBS_KSOL = (uint8_t) (mask & 0xff);
|
||||
inst->KBS_KSOH1 = (uint8_t) ((mask >> 8) & 0xff);
|
||||
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);
|
||||
if (common->col_size > 16) {
|
||||
inst->KBS_KSOH2 = (uint8_t) ((mask >> 16) & 0xff);
|
||||
inst->KBS_KSOH2 = (kso_val >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +142,9 @@ 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 uint8_t ksol_mask = kso_mask & 0xff;
|
||||
const uint8_t ksoh1_mask = (kso_mask >> 8) & 0xff;
|
||||
int status;
|
||||
|
||||
/* Disable wakeup and interrupt of KSI pins before configuring */
|
||||
|
|
@ -171,8 +178,8 @@ static int it8xxx2_kbd_init(const struct device *dev)
|
|||
}
|
||||
|
||||
/* KSO[17:0] pins output low */
|
||||
inst->KBS_KSOL = 0x00;
|
||||
inst->KBS_KSOH1 = 0x00;
|
||||
inst->KBS_KSOL = inst->KBS_KSOL & ~ksol_mask;
|
||||
inst->KBS_KSOH1 = inst->KBS_KSOH1 & ~ksoh1_mask;
|
||||
if (common->col_size > 16) {
|
||||
inst->KBS_KSOH2 = 0x00;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue