diff options
author | Ruibin Chang <Ruibin.Chang@ite.com.tw> | 2021-12-28 18:15:52 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-11 19:24:21 +0000 |
commit | e8f04ef8e0d3ad8f4bd6afa1d54da88f4baf768f (patch) | |
tree | 63d18aa6c8d78e21b38068848edd03a0e2ccceaf | |
parent | ed55b93c6cbf9fb327d9945691dfa86c618eb275 (diff) | |
download | chrome-ec-e8f04ef8e0d3ad8f4bd6afa1d54da88f4baf768f.tar.gz |
zephyr: ITE keyboard driver uses wake up interface for WUC pins
The cros_kb_raw_ite driver uses wake up interface for WUC pins.
BUG=b:188045130
BRANCH=none
TEST=on board krabby, console cmd "ksstate on",
1.press multi-key at a time:
[289.487304 KB state: -- -- -- 14 -- -- -- -- -- -- -- -- --]
[289.579284 KB state: -- -- -- 12 -- -- -- -- -- -- -- -- --]
[289.788635 KB state: -- -- -- 02 -- -- 02 -- -- -- -- -- --]
2.press a key at a time:
check all keyboard key bit field triggered
Signed-off-by: Ruibin Chang <Ruibin.Chang@ite.com.tw>
Change-Id: I4d0a7d88b73938aaf266f51b6982b86b61c11708
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3359166
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
-rw-r--r-- | zephyr/boards/riscv/it8xxx2/it8xxx2.dts | 7 | ||||
-rw-r--r-- | zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c | 90 | ||||
-rw-r--r-- | zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml | 24 | ||||
-rw-r--r-- | zephyr/include/cros/ite/it8xxx2.dtsi | 10 |
4 files changed, 109 insertions, 22 deletions
diff --git a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts index dcc3f4a970..aeeda0a2fe 100644 --- a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts +++ b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts @@ -23,13 +23,6 @@ /* Override keyboard scanning */ soc { /delete-node/ kscan@f01d00; - - cros_kb_raw: cros-kb-raw@f01d00 { - compatible = "ite,it8xxx2-cros-kb-raw"; - reg = <0x00f01d00 0x29>; - interrupt-parent = <&intc>; - interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - }; }; }; diff --git a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c index 61b1adcf3f..29ff8f77aa 100644 --- a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c +++ b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c @@ -9,8 +9,11 @@ #include <drivers/cros_kb_raw.h> #include <drivers/clock_control.h> #include <drivers/gpio.h> +#include <drivers/interrupt_controller/wuc_ite_it8xxx2.h> +#include <dt-bindings/interrupt-controller/it8xxx2-wuc.h> #include <kernel.h> #include <soc.h> +#include <soc_dt.h> #include <soc/ite_it8xxx2/reg_def_cros.h> #include "ec_tasks.h" @@ -20,14 +23,29 @@ #include <logging/log.h> LOG_MODULE_REGISTER(cros_kb_raw, LOG_LEVEL_ERR); +#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0) #define KSOH_PIN_MASK (((1 << (KEYBOARD_COLS_MAX - 8)) - 1) & 0xff) /* Device config */ +struct cros_kb_raw_wuc_map_cfg { + /* WUC control device structure */ + const struct device *wucs; + /* WUC pin mask */ + uint8_t mask; +}; + struct cros_kb_raw_ite_config { /* keyboard scan controller base address */ uintptr_t base; /* Keyboard scan input (KSI) wake-up irq */ int irq; + /* KSI[7:0] wake-up input source configuration list */ + const struct cros_kb_raw_wuc_map_cfg *wuc_map_list; +}; + +struct cros_kb_raw_ite_data { + /* KSI[7:0] wake-up interrupt status mask */ + uint8_t ksi_pin_mask; }; static int kb_raw_ite_init(const struct device *dev) @@ -43,9 +61,17 @@ static int cros_kb_raw_ite_enable_interrupt(const struct device *dev, int enable) { const struct cros_kb_raw_ite_config *config = dev->config; + struct cros_kb_raw_ite_data *data = dev->data; if (enable) { - ECREG(IT8XXX2_WUC_WUESR3) = 0xFF; + /* + * W/C wakeup interrupt status of KSI[7:0] pins + * + * NOTE: We want to clear the status as soon as possible, + * so clear KSI[7:0] pins at a time. + */ + it8xxx2_wuc_clear_status(config->wuc_map_list[0].wucs, + data->ksi_pin_mask); ite_intc_isr_clear(config->irq); irq_enable(config->irq); } else { @@ -105,14 +131,21 @@ static int cros_kb_raw_ite_drive_column(const struct device *dev, int col) static void cros_kb_raw_ite_ksi_isr(const struct device *dev) { - ARG_UNUSED(dev); + const struct cros_kb_raw_ite_config *config = dev->config; + struct cros_kb_raw_ite_data *data = dev->data; /* * We clear IT8XXX2_IRQ_WKINTC irq status in * ite_intc_irq_handler(), after interrupt was fired. */ - /* W/C wakeup interrupt status for KSI[0-7] */ - ECREG(IT8XXX2_WUC_WUESR3) = 0xFF; + /* + * W/C wakeup interrupt status of KSI[7:0] pins + * + * NOTE: We want to clear the status as soon as possible, + * so clear KSI[7:0] pins at a time. + */ + it8xxx2_wuc_clear_status(config->wuc_map_list[0].wucs, + data->ksi_pin_mask); /* Wake-up keyboard scan task */ task_wake(TASK_ID_KEYSCAN); @@ -122,6 +155,7 @@ static int cros_kb_raw_ite_init(const struct device *dev) { unsigned int key; const struct cros_kb_raw_ite_config *config = dev->config; + struct cros_kb_raw_ite_data *data = dev->data; struct kscan_it8xxx2_regs *const inst = (struct kscan_it8xxx2_regs *) config->base; @@ -158,15 +192,38 @@ static int cros_kb_raw_ite_init(const struct device *dev) inst->KBS_KSOH1 &= ~KSOH_PIN_MASK; /* restore interrupts */ irq_unlock(key); - /* Select falling-edge triggered of wakeup interrupt for KSI[0-7] */ - ECREG(IT8XXX2_WUC_WUEMR3) = 0xFF; - /* W/C wakeup interrupt status for KSI[0-7] */ - ECREG(IT8XXX2_WUC_WUESR3) = 0xFF; + + for (int i = 0; i < KEYBOARD_KSI_PIN_COUNT; i++) { + /* Select wakeup interrupt falling-edge triggered of KSI[7:0] */ + it8xxx2_wuc_set_polarity(config->wuc_map_list[i].wucs, + config->wuc_map_list[i].mask, + WUC_TYPE_EDGE_FALLING); + /* W/C wakeup interrupt status of KSI[7:0] pins */ + it8xxx2_wuc_clear_status(config->wuc_map_list[i].wucs, + config->wuc_map_list[i].mask); + /* Enable wakeup interrupt of KSI[7:0] pins */ + it8xxx2_wuc_enable(config->wuc_map_list[i].wucs, + config->wuc_map_list[i].mask); + + /* + * 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 isn't in the same wuc node!", i); + } + } + data->ksi_pin_mask |= config->wuc_map_list[i].mask; + } + + /* W/C interrupt status of KSI[7:0] pins */ ite_intc_isr_clear(config->irq); - /* Enable wakeup interrupt for KSI[0-7] */ - ECREG(IT8XXX2_WUC_WUENR3) = 0xFF; - IRQ_CONNECT(DT_INST_IRQN(0), 0, cros_kb_raw_ite_ksi_isr, NULL, 0); + irq_connect_dynamic(config->irq, 0, + (void (*)(const void *))cros_kb_raw_ite_ksi_isr, + (const void *)dev, 0); return 0; } @@ -177,12 +234,19 @@ static const struct cros_kb_raw_driver_api cros_kb_raw_ite_driver_api = { .read_rows = cros_kb_raw_ite_read_row, .enable_interrupt = cros_kb_raw_ite_enable_interrupt, }; +static const struct cros_kb_raw_wuc_map_cfg + cros_kb_raw_wuc_0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] = + IT8XXX2_DT_WUC_ITEMS_LIST(0); static const struct cros_kb_raw_ite_config cros_kb_raw_cfg = { .base = DT_INST_REG_ADDR(0), .irq = DT_INST_IRQN(0), + .wuc_map_list = cros_kb_raw_wuc_0, }; -DEVICE_DT_INST_DEFINE(0, kb_raw_ite_init, NULL, NULL, &cros_kb_raw_cfg, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, +static struct cros_kb_raw_ite_data cros_kb_raw_data; + +DEVICE_DT_INST_DEFINE(0, kb_raw_ite_init, NULL, &cros_kb_raw_data, + &cros_kb_raw_cfg, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &cros_kb_raw_ite_driver_api); diff --git a/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml new file mode 100644 index 0000000000..9c1d635b61 --- /dev/null +++ b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml @@ -0,0 +1,24 @@ +# Copyright 2022 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: ITE, it8xxx2-cros-kb-raw node + +compatible: "ite,it8xxx2-cros-kb-raw" + +include: cros-kb-raw-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + wucctrl: + type: phandles + description: | + Configure wakeup controller, this controller is used to set that + when the interrupt is triggered in EC low power mode, it can wakeup + EC or not. Via this controller, we set the wakeup trigger edge, + enable, disable, and clear wakeup status for the specific pin which + may be gpio pins or alternate pins. diff --git a/zephyr/include/cros/ite/it8xxx2.dtsi b/zephyr/include/cros/ite/it8xxx2.dtsi index 38224b9fd4..abb3e6bbae 100644 --- a/zephyr/include/cros/ite/it8xxx2.dtsi +++ b/zephyr/include/cros/ite/it8xxx2.dtsi @@ -78,14 +78,20 @@ label = "FLASH"; }; - /delete-node/ kscan@f01d00; - cros_kb_raw: cros-kb-raw@f01d00 { compatible = "ite,it8xxx2-cros-kb-raw"; reg = <0x00f01d00 0x29>; label = "CROS_KB_RAW_0"; interrupt-parent = <&intc>; interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; + wucctrl = <&wuc_wu30 /* KSI[0] */ + &wuc_wu31 /* KSI[1] */ + &wuc_wu32 /* KSI[2] */ + &wuc_wu33 /* KSI[3] */ + &wuc_wu34 /* KSI[4] */ + &wuc_wu35 /* KSI[5] */ + &wuc_wu36 /* KSI[6] */ + &wuc_wu37>; /* KSI[7] */ status = "disabled"; }; }; |