diff options
author | Ruibin Chang <Ruibin.Chang@ite.com.tw> | 2021-03-23 15:20:18 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-05-18 15:11:54 +0000 |
commit | 70bd26d153cc179aa4f0badef36d04d6e53febb2 (patch) | |
tree | 51fc4b7c4e3277930c759a96ab5590bc32bfc035 /zephyr/drivers | |
parent | 9d6b2fb5d861750b5de933327fe555af29f95ea2 (diff) | |
download | chrome-ec-70bd26d153cc179aa4f0badef36d04d6e53febb2.tar.gz |
zephyr: add support for it8xxx2 cros_kb_row driver
Add support for it8xxx2 cros_kb_row driver.
BUG=b:187192587
BRANCH=none
TEST=on hayato, console cmd "ksstate" then press key:
[115.097839 KB state: -- -- -- 02 -- -- 02 -- -- -- -- -- --]
[116.462371 KB state: -- -- -- -- -- -- 02 -- -- -- -- -- --]
[116.499633 KB state: -- -- -- -- -- -- -- -- -- -- -- -- --]
Cq-Depend: chromium:2902165
Change-Id: I067b95bf2dfe4978e5370ce27382c67db100467b
Signed-off-by: Ruibin Chang <Ruibin.Chang@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2784322
Reviewed-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'zephyr/drivers')
-rw-r--r-- | zephyr/drivers/cros_kb_raw/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c | 188 |
2 files changed, 189 insertions, 0 deletions
diff --git a/zephyr/drivers/cros_kb_raw/CMakeLists.txt b/zephyr/drivers/cros_kb_raw/CMakeLists.txt index 54b8c63b0f..a9ef2b4bb2 100644 --- a/zephyr/drivers/cros_kb_raw/CMakeLists.txt +++ b/zephyr/drivers/cros_kb_raw/CMakeLists.txt @@ -1,3 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_CROS_KB_RAW_NPCX cros_kb_raw_npcx.c) +zephyr_library_sources_ifdef(CONFIG_CROS_KB_RAW_ITE cros_kb_raw_ite.c) diff --git a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c new file mode 100644 index 0000000000..501f8ec309 --- /dev/null +++ b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c @@ -0,0 +1,188 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define DT_DRV_COMPAT ite_it8xxx2_cros_kb_raw + +#include <assert.h> +#include <drivers/cros_kb_raw.h> +#include <drivers/clock_control.h> +#include <drivers/gpio.h> +#include <kernel.h> +#include <soc.h> +#include <soc/ite_it8xxx2/reg_def_cros.h> + +#include "ec_tasks.h" +#include "keyboard_raw.h" +#include "task.h" + +#include <logging/log.h> +LOG_MODULE_REGISTER(cros_kb_raw, LOG_LEVEL_ERR); + +#define KSOH_PIN_MASK (((1 << (KEYBOARD_COLS_MAX - 8)) - 1) & 0xff) + +/* Device config */ +struct cros_kb_raw_ite_config { + /* keyboard scan controller base address */ + uintptr_t base; + /* Keyboard scan input (KSI) wake-up irq */ + int irq; +}; + +/* Driver convenience defines */ +#define DRV_CONFIG(dev) ((const struct cros_kb_raw_ite_config *)(dev)->config) +#define HAL_INSTANCE(dev) (struct kbs_reg *)(DRV_CONFIG(dev)->base) + +static int kb_raw_ite_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* Clock default is on */ + return 0; +} + +/* Cros ec keyboard raw api functions */ +static int cros_kb_raw_ite_enable_interrupt(const struct device *dev, + int enable) +{ + const struct cros_kb_raw_ite_config *const config = DRV_CONFIG(dev); + + if (enable) { + ECREG(IT8XXX2_WUC_WUESR3) = 0xFF; + ite_intc_isr_clear(config->irq); + irq_enable(config->irq); + } else { + irq_disable(config->irq); + } + + return 0; +} + +static int cros_kb_raw_ite_read_row(const struct device *dev) +{ + struct kbs_reg *const inst = HAL_INSTANCE(dev); + + /* Bits are active-low, so invert returned levels */ + return ((inst->KBS_KSI) ^ 0xff); +} + +static int cros_kb_raw_ite_drive_column(const struct device *dev, int col) +{ + int mask; + unsigned int key; + struct kbs_reg *const inst = HAL_INSTANCE(dev); + + /* Tri-state all outputs */ + if (col == KEYBOARD_COLUMN_NONE) + mask = 0xffff; + /* Assert all outputs */ + else if (col == KEYBOARD_COLUMN_ALL) + mask = 0; + /* Assert a single output */ + else + mask = 0xffff ^ BIT(col); +#ifdef CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED + /* KSO[2] is inverted. */ + mask ^= BIT(2); +#endif + inst->KBS_KSOL = mask & 0xff; + /* critical section with interrupts off */ + key = irq_lock(); + /* + * Because IT8XXX2_KBS_KSOH1 register is shared by keyboard scan + * out and GPIO output mode, so we don't drive all KSOH pins + * here (this depends on how many keyboard matrix output pin + * we are using). + */ + inst->KBS_KSOH1 = ((inst->KBS_KSOH1) & ~KSOH_PIN_MASK) | + ((mask >> 8) & KSOH_PIN_MASK); + /* restore interrupts */ + irq_unlock(key); + + return 0; +} + +static void cros_kb_raw_ite_ksi_isr(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* + * 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; + + /* Wake-up keyboard scan task */ + task_wake(TASK_ID_KEYSCAN); +} + +static int cros_kb_raw_ite_init(const struct device *dev) +{ + unsigned int key; + const struct cros_kb_raw_ite_config *const config = DRV_CONFIG(dev); + struct kbs_reg *const inst = HAL_INSTANCE(dev); + + /* Ensure top-level interrupt is disabled */ + cros_kb_raw_ite_enable_interrupt(dev, 0); + + /* + * bit2, Setting 1 enables the internal pull-up of the KSO[15:0] pins. + * To pull up KSO[17:16], set the GPCR registers of their + * corresponding GPIO ports. + * bit0, Setting 1 enables the open-drain mode of the KSO[17:0] pins. + */ + inst->KBS_KSOCTRL = (IT8XXX2_KBS_KSOPU | IT8XXX2_KBS_KSOOD); + /* bit2, 1 enables the internal pull-up of the KSI[7:0] pins. */ + inst->KBS_KSICTRL = IT8XXX2_KBS_KSIPU; +#ifdef CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED + /* KSO[2] output high, others output low. */ + inst->KBS_KSOL = BIT(2); + /* Enable KSO2's push-pull */ + inst->KBS_KSOLGCTRL |= IT8XXX2_KBS_KSO2GCTRL; + inst->KBS_KSOLGOEN |= IT8XXX2_KBS_KSO2GOEN; +#else + /* KSO[7:0] pins output low. */ + inst->KBS_KSOL = 0x00; +#endif + /* critical section with interrupts off */ + key = irq_lock(); + /* + * KSO[COLS_MAX:8] pins low. + * NOTE: KSO[15:8] pins can part be enabled for keyboard function and + * rest be configured as GPIO output mode. In this case that we + * disable the ISR in critical section to avoid race condition. + */ + 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; + 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); + + return 0; +} + +static const struct cros_kb_raw_driver_api cros_kb_raw_ite_driver_api = { + .init = cros_kb_raw_ite_init, + .drive_colum = cros_kb_raw_ite_drive_column, + .read_rows = cros_kb_raw_ite_read_row, + .enable_interrupt = cros_kb_raw_ite_enable_interrupt, +}; + +static const struct cros_kb_raw_ite_config cros_kb_raw_cfg = { + .base = DT_INST_REG_ADDR(0), + .irq = DT_INST_IRQN(0), +}; + +DEVICE_DEFINE(cros_kb_raw_ite_0, DT_INST_LABEL(0), kb_raw_ite_init, NULL, + NULL, &cros_kb_raw_cfg, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &cros_kb_raw_ite_driver_api); |