ITE drivers/interrupt_controller: add wuc interface
Add wakeup controller interface for ITE it8xxx2 chip. Signed-off-by: Ruibin Chang <ruibin.chang@ite.com.tw>
This commit is contained in:
parent
d66c1d9b54
commit
4b75cf8f47
11 changed files with 857 additions and 0 deletions
|
@ -14,6 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_GIC_V3_ITS intc_gicv3_its.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_INTEL_VTD_ICTL intc_intel_vtd.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_IOAPIC intc_ioapic.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ITE_IT8XXX2_INTC intc_ite_it8xxx2.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ITE_IT8XXX2_WUC wuc_ite_it8xxx2.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_LEON_IRQMP intc_irqmp.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_LOAPIC intc_loapic.c intc_system_apic.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_LOAPIC_SPURIOUS_VECTOR intc_loapic_spurious.S)
|
||||
|
|
|
@ -51,6 +51,10 @@ config INTC_INIT_PRIORITY
|
|||
help
|
||||
Interrupt controller device initialization priority.
|
||||
|
||||
module = INTC
|
||||
module-str = intc
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
source "drivers/interrupt_controller/Kconfig.multilevel"
|
||||
|
||||
source "drivers/interrupt_controller/Kconfig.loapic"
|
||||
|
|
|
@ -9,3 +9,15 @@ config ITE_IT8XXX2_INTC
|
|||
instance of the shared interrupt driver. To conserve RAM set
|
||||
this value to the lowest practical value.
|
||||
this software interrupt default set on by device tree.
|
||||
|
||||
# Workaround for not being able to have commas in macro arguments
|
||||
DT_COMPAT_ITE_IT8XXX2_WUC := ite,it8xxx2-wuc
|
||||
|
||||
config ITE_IT8XXX2_WUC
|
||||
bool "ITE it8xxx2 Wakeup controller (WUC) interface"
|
||||
depends on SOC_IT8XXX2
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_ITE_IT8XXX2_WUC))
|
||||
help
|
||||
This option enables the wakeup controller interface for IT8XXX2
|
||||
family.
|
||||
This is required for KSCAN, UART, eSPI, GPIO etc., interrupt support.
|
||||
|
|
125
drivers/interrupt_controller/wuc_ite_it8xxx2.c
Normal file
125
drivers/interrupt_controller/wuc_ite_it8xxx2.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2022 ITE Corporation. All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ite_it8xxx2_wuc
|
||||
|
||||
#include <device.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_common.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(wuc_ite_it8xxx2, CONFIG_INTC_LOG_LEVEL);
|
||||
|
||||
/* Driver config */
|
||||
struct it8xxx2_wuc_cfg {
|
||||
/* WUC wakeup edge mode register */
|
||||
uint8_t *reg_wuemr;
|
||||
/* WUC wakeup edge sense register */
|
||||
uint8_t *reg_wuesr;
|
||||
/* WUC wakeup enable register */
|
||||
uint8_t *reg_wuenr;
|
||||
/* WUC wakeup both edge mode register */
|
||||
uint8_t *reg_wubemr;
|
||||
};
|
||||
|
||||
void it8xxx2_wuc_enable(const struct device *dev, uint8_t mask)
|
||||
{
|
||||
const struct it8xxx2_wuc_cfg *config = dev->config;
|
||||
volatile uint8_t *reg_wuenr = config->reg_wuenr;
|
||||
|
||||
/*
|
||||
* WUC group only 1, 3, and 4 have enable/disable register,
|
||||
* others are always enabled.
|
||||
*/
|
||||
if (reg_wuenr == IT8XXX2_WUC_UNUSED_REG) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable wakeup interrupt of the pin */
|
||||
*reg_wuenr |= mask;
|
||||
}
|
||||
|
||||
void it8xxx2_wuc_disable(const struct device *dev, uint8_t mask)
|
||||
{
|
||||
const struct it8xxx2_wuc_cfg *config = dev->config;
|
||||
volatile uint8_t *reg_wuenr = config->reg_wuenr;
|
||||
|
||||
/*
|
||||
* WUC group only 1, 3, and 4 have enable/disable register,
|
||||
* others are always enabled.
|
||||
*/
|
||||
if (reg_wuenr == IT8XXX2_WUC_UNUSED_REG) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable wakeup interrupt of the pin */
|
||||
*reg_wuenr &= ~mask;
|
||||
}
|
||||
|
||||
void it8xxx2_wuc_clear_status(const struct device *dev, uint8_t mask)
|
||||
{
|
||||
const struct it8xxx2_wuc_cfg *config = dev->config;
|
||||
volatile uint8_t *reg_wuesr = config->reg_wuesr;
|
||||
|
||||
if (reg_wuesr == IT8XXX2_WUC_UNUSED_REG) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* W/C wakeup interrupt status of the pin */
|
||||
*reg_wuesr = mask;
|
||||
}
|
||||
|
||||
void it8xxx2_wuc_set_polarity(const struct device *dev, uint8_t mask, uint32_t flags)
|
||||
{
|
||||
const struct it8xxx2_wuc_cfg *config = dev->config;
|
||||
volatile uint8_t *reg_wuemr = config->reg_wuemr;
|
||||
volatile uint8_t *reg_wubemr = config->reg_wubemr;
|
||||
|
||||
if (reg_wuemr == IT8XXX2_WUC_UNUSED_REG) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set wakeup interrupt edge trigger mode of the pin */
|
||||
if ((flags & WUC_TYPE_EDGE_BOTH) == WUC_TYPE_EDGE_RISING) {
|
||||
*reg_wubemr &= ~mask;
|
||||
*reg_wuemr &= ~mask;
|
||||
} else if ((flags & WUC_TYPE_EDGE_BOTH) == WUC_TYPE_EDGE_FALLING) {
|
||||
*reg_wubemr &= ~mask;
|
||||
*reg_wuemr |= mask;
|
||||
} else {
|
||||
/* Both edge trigger mode */
|
||||
*reg_wubemr |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
static int it8xxx2_wuc_init(const struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IT8XXX2_WUC_INIT(inst) \
|
||||
\
|
||||
static const struct it8xxx2_wuc_cfg it8xxx2_wuc_cfg_##inst = { \
|
||||
.reg_wuemr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 0), \
|
||||
.reg_wuesr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 1), \
|
||||
.reg_wuenr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 2), \
|
||||
.reg_wubemr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 3), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, \
|
||||
&it8xxx2_wuc_init, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
&it8xxx2_wuc_cfg_##inst, \
|
||||
PRE_KERNEL_1, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, \
|
||||
NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(IT8XXX2_WUC_INIT)
|
Loading…
Add table
Add a link
Reference in a new issue