diff --git a/drivers/pinctrl/pinctrl_npcx.c b/drivers/pinctrl/pinctrl_npcx.c index 22848b937d1..5759122018f 100644 --- a/drivers/pinctrl/pinctrl_npcx.c +++ b/drivers/pinctrl/pinctrl_npcx.c @@ -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]); diff --git a/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi b/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi index 26baa312a14..e9acb4a0978 100644 --- a/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi @@ -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>; diff --git a/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi b/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi index 51275147558..2fe2b1f75c9 100644 --- a/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi @@ -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>; diff --git a/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml b/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml index 962ecad5fa8..f1ecdc8d891 100644 --- a/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml +++ b/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml @@ -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: | diff --git a/soc/arm/nuvoton_npcx/common/pinctrl_soc.h b/soc/arm/nuvoton_npcx/common/pinctrl_soc.h index cd8af7584ba..8f03faa82b7 100644 --- a/soc/arm/nuvoton_npcx/common/pinctrl_soc.h +++ b/soc/arm/nuvoton_npcx/common/pinctrl_soc.h @@ -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)), ()) diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 31517a0189c..4bed431a457 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -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 + \