pinctrl: npcx: add DEV_CTLx configuration support

Add a new pinctrl type to control peripheral modules' specific IO
characteristics such as tri-state, the power supply type selection (3.3V
or 1.8V), and so on. In NPCX series, the corresponding registers/fields
are irregular. This CL wraps these definitions to dt nodes and put them
in pinctrl property if needed.

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2023-05-24 02:46:50 -07:00 committed by Carles Cufí
commit 7411fbcb5b
6 changed files with 119 additions and 0 deletions

View file

@ -153,6 +153,16 @@ static void npcx_psl_input_detection_configure(const pinctrl_soc_pin_t *pin)
}
}
static void npcx_device_control_configure(const pinctrl_soc_pin_t *pin)
{
const struct npcx_dev_ctl *ctrl = (const struct npcx_dev_ctl *)&pin->cfg.dev_ctl;
const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;
SET_FIELD(NPCX_DEV_CTL(scfg_base, ctrl->offest),
FIELD(ctrl->field_offset, ctrl->field_size),
ctrl->field_value);
}
/* Pinctrl API implementation */
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
uintptr_t reg)
@ -164,6 +174,9 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
if (pins[i].flags.type == NPCX_PINCTRL_TYPE_PERIPH) {
/* Configure peripheral device's pinmux functionality */
npcx_periph_configure(&pins[i], reg);
} else if (pins[i].flags.type == NPCX_PINCTRL_TYPE_DEVICE_CTRL) {
/* Configure device's io characteristics */
npcx_device_control_configure(&pins[i]);
} else if (pins[i].flags.type == NPCX_PINCTRL_TYPE_PSL_IN) {
/* Configure SPL input's detection mode */
npcx_psl_input_detection_configure(&pins[i]);

View file

@ -5,7 +5,35 @@
*/
&pinctrl {
/* Prebuild nodes for peripheral device's characteristics (Optional) */
/omit-if-no-ref/ vhif_lpc_sl: devctl-vhif-3p3v-lpc {
dev-ctl = <0x0 2 2 0x01>;
};
/omit-if-no-ref/ vhif_espi_shi_sl: devctl-vhif-1p8v-espi-shi {
dev-ctl = <0x0 2 2 0x02>;
};
/omit-if-no-ref/ ext_flash_tris_off: devctl-fiu-ext-tris-off {
dev-ctl = <0x0 6 1 0x00>;
};
/omit-if-no-ref/ ext_flash_tris_on: devctl-fiu-ext-tris-on {
dev-ctl = <0x0 6 1 0x01>;
};
/* Prebuild nodes for peripheral device's pin-muxing and pad properties */
/* Flash Interface Unit (FIU) */
/omit-if-no-ref/ fiu_ext_io0_io1_clk_cs_gpa4_96_a2_a0: periph-fiu-ext {
dev-ctl = <0x6 1 1 0x00>; /* Select to external flash */
pinmux = <&alt0_gpio_no_fpip>;
};
/omit-if-no-ref/ int_flash_sl: periph-fiu-int {
dev-ctl = <0x6 1 1 0x01>; /* Select to internal flash */
/* No need for pin-muxing */
};
/* Host peripheral interfaces */
/omit-if-no-ref/ espi_lpc_gp46_47_51_52_53_54_55_57: periph-lpc-espi {
pinmux = <&alt1_no_lpc_espi>;

View file

@ -5,7 +5,44 @@
*/
&pinctrl {
/* Prebuild nodes for peripheral device's characteristics (Optional) */
/omit-if-no-ref/ vhif_lpc_sl: devctl-vhif-3p3v-lpc {
dev-ctl = <0x0 2 2 0x01>;
};
/omit-if-no-ref/ vhif_espi_shi_sl: devctl-vhif-1p8v-espi-shi {
dev-ctl = <0x0 2 2 0x02>;
};
/omit-if-no-ref/ ext_flash_tris_off: devctl-fiu-ext-tris-off {
dev-ctl = <0x0 6 1 0x00>;
};
/omit-if-no-ref/ ext_flash_tris_on: devctl-fiu-ext-tris-on {
dev-ctl = <0x0 6 1 0x01>;
};
/* Prebuild nodes for peripheral device's pin-muxing and pad properties */
/* Flash Interface Unit (FIU) */
/omit-if-no-ref/ fiu_ext_io0_io1_clk_cs_gpa4_96_a2_a0: periph-fiu-ext {
dev-ctl = <0x6 1 1 0x00>; /* Select to external flash */
pinmux = <&alt0_gpio_no_fpip>;
};
/omit-if-no-ref/ ext_flash_cs1_gpa6: periph-ext-spi-flash-cs1 {
pinmux = <&alt0_f_spi_cs1>;
};
/omit-if-no-ref/ int_flash_sl: periph-fiu-int {
dev-ctl = <0x6 1 1 0x01>; /* Select to internal flash */
/* No need for pin-muxing */
};
/omit-if-no-ref/ fiu_ext_quad_io2_io3_gp93_a7: periph-fiu-ext-quad {
pinmux = <&alt0_f_spi_quad>;
};
/* Host peripheral interfaces */
/omit-if-no-ref/ espi_lpc_gp46_47_51_52_53_54_55_57: periph-lpc-espi {
pinmux = <&alt1_no_lpc_espi>;

View file

@ -57,6 +57,9 @@ child-binding:
pinmux:
type: phandle
description: Configurations of pinmux selection
dev-ctl:
type: array
description: Configurations of device control such as tri-state, io type and so on.
periph-pupd:
type: array
description: |

View file

@ -16,6 +16,7 @@
*/
enum npcx_pinctrl_type {
NPCX_PINCTRL_TYPE_PERIPH,
NPCX_PINCTRL_TYPE_DEVICE_CTRL,
NPCX_PINCTRL_TYPE_PSL_IN,
NPCX_PINCTRL_TYPE_RESERVED,
};
@ -81,6 +82,23 @@ struct npcx_periph {
uint16_t reserved: 2;
} __packed;
/**
* @brief NPCX device control structure
*
* Used to indicate the device's corresponding register/field for its io
* characteristics such as tri-state, power supply type selection, and so on.
*/
struct npcx_dev_ctl {
/** Related register offset for device configuration. */
uint16_t offest: 5;
/** Related register field offset for device control. */
uint16_t field_offset: 3;
/** Related register field size for device control. */
uint16_t field_size: 3;
/** field value */
uint16_t field_value: 5;
} __packed;
/**
* @brief NPCX Power Switch Logic (PSL) input pad configuration structure
*
@ -103,6 +121,7 @@ struct npcx_psl_input {
struct npcx_pinctrl {
union {
struct npcx_periph periph;
struct npcx_dev_ctl dev_ctl;
struct npcx_psl_input psl_in;
uint16_t cfg_word;
} cfg;
@ -163,6 +182,21 @@ typedef struct npcx_pinctrl pinctrl_soc_pin_t;
.cfg.periph.inverted = DT_PHA(DT_PROP(node_id, prop), alts, inv), \
},
/**
* @brief Utility macro to initialize a periphral pinmux configuration.
*
* @param node_id Node identifier.
* @param prop Property name for pinmux configuration. (i.e. 'pinmux')
*/
#define Z_PINCTRL_NPCX_DEVICE_CONTROL_INIT(node_id, prop) \
{ \
.flags.type = NPCX_PINCTRL_TYPE_DEVICE_CTRL, \
.cfg.dev_ctl.offest = DT_PROP_BY_IDX(node_id, prop, 0), \
.cfg.dev_ctl.field_offset = DT_PROP_BY_IDX(node_id, prop, 1), \
.cfg.dev_ctl.field_size = DT_PROP_BY_IDX(node_id, prop, 2), \
.cfg.dev_ctl.field_value = DT_PROP_BY_IDX(node_id, prop, 3), \
},
/**
* @brief Utility macro to initialize a periphral pull-up/down configuration.
*
@ -227,6 +261,9 @@ typedef struct npcx_pinctrl pinctrl_soc_pin_t;
COND_CODE_1(Z_PINCTRL_NPCX_HAS_PSL_IN_PROP(DT_PROP_BY_IDX(node_id, prop, idx)), \
(Z_PINCTRL_NPCX_PSL_IN_DETECT_CONF_INIT( \
DT_PROP_BY_IDX(node_id, prop, idx), psl_polarity)), ()) \
COND_CODE_1(DT_NODE_HAS_PROP(DT_PROP_BY_IDX(node_id, prop, idx), dev_ctl), \
(Z_PINCTRL_NPCX_DEVICE_CONTROL_INIT( \
DT_PROP_BY_IDX(node_id, prop, idx), dev_ctl)), ()) \
COND_CODE_1(DT_NODE_HAS_PROP(DT_PROP_BY_IDX(node_id, prop, idx), pinmux), \
(Z_PINCTRL_NPCX_PERIPH_PINMUX_INIT( \
DT_PROP_BY_IDX(node_id, prop, idx), pinmux)), ())

View file

@ -254,6 +254,7 @@ static inline uint32_t npcx_lv_gpio_ctl_offset(uint32_t ctl_no)
}
/* Macro functions for SCFG multi-registers */
#define NPCX_DEV_CTL(base, n) (*(volatile uint8_t *)(base + n))
#define NPCX_DEVALT(base, n) (*(volatile uint8_t *)(base + \
npcx_devalt_offset(n)))
#define NPCX_DEVALT_LK(base, n) (*(volatile uint8_t *)(base + \