summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuibin Chang <Ruibin.Chang@ite.com.tw>2021-12-28 18:15:52 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-04-11 19:24:21 +0000
commite8f04ef8e0d3ad8f4bd6afa1d54da88f4baf768f (patch)
tree63d18aa6c8d78e21b38068848edd03a0e2ccceaf
parented55b93c6cbf9fb327d9945691dfa86c618eb275 (diff)
downloadchrome-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.dts7
-rw-r--r--zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c90
-rw-r--r--zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml24
-rw-r--r--zephyr/include/cros/ite/it8xxx2.dtsi10
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";
};
};