drivers: pinctrl: npcx: add initial pin-controller driver
This CL is the initial version for npcx pinctrl driver and introduces pinctrl nodes for both IO-pads and peripheral devices for each npcx series. Users can set pin configuration via these nodes in the board layout DT file. It also wraps all configurations related to pin-muxing in pinctrl_soc.h. Regarding the other pin properties, we will implement them later. Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
parent
5f5337b9f3
commit
d53d574bf0
14 changed files with 1225 additions and 0 deletions
|
@ -7,6 +7,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_TELINK_B91 pinctrl_b91.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_ITE_IT8XXX2 pinctrl_ite_it8xxx2.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NPCX pinctrl_npcx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c)
|
||||
|
|
|
@ -32,6 +32,7 @@ config PINCTRL_DYNAMIC
|
|||
source "drivers/pinctrl/Kconfig.b91"
|
||||
source "drivers/pinctrl/Kconfig.gd32"
|
||||
source "drivers/pinctrl/Kconfig.it8xxx2"
|
||||
source "drivers/pinctrl/Kconfig.npcx"
|
||||
source "drivers/pinctrl/Kconfig.nrf"
|
||||
source "drivers/pinctrl/Kconfig.rcar"
|
||||
source "drivers/pinctrl/Kconfig.rpi_pico"
|
||||
|
|
15
drivers/pinctrl/Kconfig.npcx
Normal file
15
drivers/pinctrl/Kconfig.npcx
Normal file
|
@ -0,0 +1,15 @@
|
|||
# NPCX Pin Controller configuration options
|
||||
|
||||
# Copyright (c) 2022 Nuvoton Technology Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DT_COMPAT_ST_PINCTRL_NPCX := nuvoton,npcx-pinctrl
|
||||
|
||||
config PINCTRL_NPCX
|
||||
bool "Nuvoton NPCX embedded controller (EC) pin controller driver"
|
||||
depends on SOC_FAMILY_NPCX
|
||||
select PINCTRL_STORE_REG
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_ST_PINCTRL_NPCX))
|
||||
help
|
||||
This option enables the pin controller driver for NPCX family of
|
||||
processors.
|
114
drivers/pinctrl/pinctrl_npcx.c
Normal file
114
drivers/pinctrl/pinctrl_npcx.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Nuvoton Technology Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <soc.h>
|
||||
|
||||
/* Driver config */
|
||||
struct npcx_pinctrl_config {
|
||||
/* scfg device base address */
|
||||
uintptr_t base_scfg;
|
||||
};
|
||||
|
||||
static const struct npcx_pinctrl_config npcx_pinctrl_cfg = {
|
||||
.base_scfg = DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), scfg),
|
||||
};
|
||||
|
||||
/* Pin-control local functions for peripheral devices */
|
||||
static bool npcx_periph_pinmux_has_lock(int group)
|
||||
{
|
||||
#if defined(CONFIG_SOC_SERIES_NPCX7)
|
||||
if (group == 0x00 || (group >= 0x02 && group <= 0x04) || group == 0x06 ||
|
||||
group == 0x0b || group == 0x0f) {
|
||||
return true;
|
||||
}
|
||||
#elif defined(CONFIG_SOC_SERIES_NPCX9)
|
||||
if (group == 0x00 || (group >= 0x02 && group <= 0x06) || group == 0x0b ||
|
||||
group == 0x0d || (group >= 0x0f && group <= 0x12)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static void npcx_periph_pinmux_configure(const struct npcx_periph *alt, bool is_alternate,
|
||||
bool is_locked)
|
||||
{
|
||||
const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;
|
||||
uint8_t alt_mask = BIT(alt->bit);
|
||||
|
||||
/*
|
||||
* is_alternate == 0 means select GPIO, otherwise Alternate Func.
|
||||
* inverted == 0:
|
||||
* Set devalt bit to select Alternate Func.
|
||||
* inverted == 1:
|
||||
* Clear devalt bit to select Alternate Func.
|
||||
*/
|
||||
if (is_alternate != alt->inverted) {
|
||||
NPCX_DEVALT(scfg_base, alt->group) |= alt_mask;
|
||||
} else {
|
||||
NPCX_DEVALT(scfg_base, alt->group) &= ~alt_mask;
|
||||
}
|
||||
|
||||
if (is_locked && npcx_periph_pinmux_has_lock(alt->group)) {
|
||||
NPCX_DEVALT_LK(scfg_base, alt->group) |= alt_mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void npcx_periph_pupd_configure(const struct npcx_periph *pupd,
|
||||
enum npcx_io_bias_type type)
|
||||
{
|
||||
const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;
|
||||
|
||||
if (type == NPCX_BIAS_TYPE_NONE) {
|
||||
NPCX_PUPD_EN(scfg_base, pupd->group) &= ~BIT(pupd->bit);
|
||||
} else {
|
||||
NPCX_PUPD_EN(scfg_base, pupd->group) |= BIT(pupd->bit);
|
||||
}
|
||||
}
|
||||
|
||||
static void npcx_periph_pwm_drive_mode_configure(uintptr_t reg, bool is_od)
|
||||
{
|
||||
struct pwm_reg *const inst = (struct pwm_reg *)(reg);
|
||||
|
||||
if (is_od) {
|
||||
inst->PWMCTLEX |= BIT(NPCX_PWMCTLEX_OD_OUT);
|
||||
} else {
|
||||
inst->PWMCTLEX &= ~BIT(NPCX_PWMCTLEX_OD_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
static void npcx_periph_configure(const pinctrl_soc_pin_t *pin, uintptr_t reg)
|
||||
{
|
||||
if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_PINMUX) {
|
||||
/* Configure peripheral device's pinmux functionality */
|
||||
npcx_periph_pinmux_configure(&pin->cfg.periph,
|
||||
!pin->flags.pinmux_gpio,
|
||||
pin->flags.pinmux_lock);
|
||||
} else if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_PUPD) {
|
||||
/* Configure peripheral device's internal PU/PD */
|
||||
npcx_periph_pupd_configure(&pin->cfg.periph,
|
||||
pin->flags.io_bias_type);
|
||||
} else if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_DRIVE) {
|
||||
/* Configure peripheral device's drive mode. (Only PWM pads support it) */
|
||||
npcx_periph_pwm_drive_mode_configure(reg,
|
||||
pin->flags.io_drive_type == NPCX_DRIVE_TYPE_OPEN_DRAIN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pinctrl API implementation */
|
||||
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
|
||||
uintptr_t reg)
|
||||
{
|
||||
ARG_UNUSED(reg);
|
||||
|
||||
/* Configure all peripheral devices' properties here. */
|
||||
for (uint8_t i = 0; i < pin_cnt; i++) {
|
||||
npcx_periph_configure(&pins[i], reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue