diff --git a/drivers/pinctrl/pinctrl_npcx.c b/drivers/pinctrl/pinctrl_npcx.c index 616af8af467..22848b937d1 100644 --- a/drivers/pinctrl/pinctrl_npcx.c +++ b/drivers/pinctrl/pinctrl_npcx.c @@ -9,12 +9,14 @@ /* Driver config */ struct npcx_pinctrl_config { - /* scfg device base address */ + /* Device base address used for pinctrl driver */ uintptr_t base_scfg; + uintptr_t base_glue; }; static const struct npcx_pinctrl_config npcx_pinctrl_cfg = { - .base_scfg = DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), scfg), + .base_scfg = NPCX_SCFG_REG_ADDR, + .base_glue = NPCX_GLUE_REG_ADDR, }; /* PWM pinctrl config */ @@ -130,6 +132,27 @@ static void npcx_periph_configure(const pinctrl_soc_pin_t *pin, uintptr_t reg) } } +static void npcx_psl_input_detection_configure(const pinctrl_soc_pin_t *pin) +{ + struct glue_reg *inst_glue = (struct glue_reg *)(npcx_pinctrl_cfg.base_glue); + const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg; + const struct npcx_psl_input *psl_in = (const struct npcx_psl_input *)&pin->cfg.psl_in; + + /* Configure detection polarity of PSL input pads */ + if (pin->flags.psl_in_polarity == NPCX_PSL_IN_POL_HIGH) { + NPCX_DEVALT(scfg_base, psl_in->pol_group) |= BIT(psl_in->pol_bit); + } else { + NPCX_DEVALT(scfg_base, psl_in->pol_group) &= ~BIT(psl_in->pol_bit); + } + + /* Configure detection mode of PSL input pads */ + if (pin->flags.psl_in_mode == NPCX_PSL_IN_MODE_EDGE) { + inst_glue->PSL_CTS |= NPCX_PSL_CTS_MODE_BIT(psl_in->port); + } else { + inst_glue->PSL_CTS &= ~NPCX_PSL_CTS_MODE_BIT(psl_in->port); + } +} + /* Pinctrl API implementation */ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) @@ -138,7 +161,15 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, /* Configure all peripheral devices' properties here. */ for (uint8_t i = 0; i < pin_cnt; i++) { - npcx_periph_configure(&pins[i], reg); + 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_PSL_IN) { + /* Configure SPL input's detection mode */ + npcx_psl_input_detection_configure(&pins[i]); + } else { + return -ENOTSUP; + } } return 0; diff --git a/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi b/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi index 2788723f564..26baa312a14 100644 --- a/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7/npcx7-pinctrl.dtsi @@ -342,18 +342,26 @@ /* PSL peripheral interfaces. */ /omit-if-no-ref/ psl_in1_gpd2: periph-psl-in1 { pinmux = <&altd_npsl_in1_sl>; + psl-offset = <0>; + psl-polarity = <&altd_psl_in1_ahi>; }; /omit-if-no-ref/ psl_in2_gp00: periph-psl-in2 { pinmux = <&altd_npsl_in2_sl>; + psl-offset = <1>; + psl-polarity = <&altd_psl_in2_ahi>; }; /omit-if-no-ref/ psl_in3_gp01: periph-psl-in3 { pinmux = <&altd_psl_in3_sl>; + psl-offset = <2>; + psl-polarity = <&altd_psl_in3_ahi>; }; /omit-if-no-ref/ psl_in4_gp02: periph-psl-in4 { pinmux = <&altd_psl_in4_sl>; + psl-offset = <3>; + psl-polarity = <&altd_psl_in4_ahi>; }; /* UART peripheral interfaces */ diff --git a/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi b/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi index 0b3551f0518..51275147558 100644 --- a/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9/npcx9-pinctrl.dtsi @@ -350,18 +350,26 @@ /* PSL peripheral interfaces */ /omit-if-no-ref/ psl_in1_gpd2: periph-psl-in1 { pinmux = <&altd_npsl_in1_sl>; + psl-offset = <0>; + psl-polarity = <&altd_psl_in1_ahi>; }; /omit-if-no-ref/ psl_in2_gp00: periph-psl-in2 { pinmux = <&altd_npsl_in2_sl>; + psl-offset = <1>; + psl-polarity = <&altd_psl_in2_ahi>; }; /omit-if-no-ref/ psl_in3_gp01: periph-psl-in3 { pinmux = <&altd_psl_in3_sl>; + psl-offset = <2>; + psl-polarity = <&altd_psl_in3_ahi>; }; /omit-if-no-ref/ psl_in4_gp02: periph-psl-in4 { pinmux = <&altd_psl_in4_sl>; + psl-offset = <3>; + psl-polarity = <&altd_psl_in4_ahi>; }; /omit-if-no-ref/ psl_gpo_gpd7: periph-psl-gpo { diff --git a/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml b/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml index 04d6e9af0d6..907487c4ad1 100644 --- a/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml +++ b/dts/bindings/pinctrl/nuvoton,npcx-pinctrl.yaml @@ -14,6 +14,8 @@ description: | Custom pin properties for npcx series are available also: - pinmux-locked: Lock pinmux configuration for peripheral device - pinmux-gpio: Inverse pinmux back to gpio + - psl-in-mode: Select the assertion detection mode of PSL input + - psl-in-pol: Select the assertion detection polarity of PSL input An example for NPCX7 family, include the chip level pinctrl DTSI file in the board level DTS: @@ -61,6 +63,17 @@ child-binding: description: | A map to PUPD_ENn register/bit that enable pull-up/down of NPCX peripheral devices. Please don't overwrite this property in the board-level DT driver. + psl-offset: + type: int + description: | + Offset to PSL_CTS register that is used for PSL input's status and detection mode. + Please don't overwrite this property in the board-level DT driver. + psl-polarity: + type: phandle + required: false + description: | + A map to DEVALTn that configures detection polarity of PSL input pads. + Please don't overwrite this property in the board-level DT driver. pinmux-locked: required: false type: boolean @@ -69,3 +82,23 @@ child-binding: required: false type: boolean description: Inverse pinmux selection to GPIO + psl-in-mode: + type: string + required: false + description: | + The assertion detection mode of PSL input selection + - "level": Select the detection mode to level detection + - "edge": Select the detection mode to edge detection + enum: + - "level" + - "edge" + psl-in-pol: + type: string + required: false + description: | + The assertion detection polarity of PSL input selection + - "low-falling": Select the detection polarity to low/falling + - "high-rising": Select the detection polarity to high/rising + enum: + - "low-falling" + - "high-rising" diff --git a/soc/arm/nuvoton_npcx/common/pinctrl_soc.h b/soc/arm/nuvoton_npcx/common/pinctrl_soc.h index befef6e84f8..cd8af7584ba 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_PSL_IN, NPCX_PINCTRL_TYPE_RESERVED, }; @@ -45,6 +46,22 @@ enum npcx_io_drive_type { NPCX_DRIVE_TYPE_OPEN_DRAIN, }; +/** + * @brief Suppoerted PSL input detection mode in NPCX series + */ +enum npcx_psl_in_mode { + NPCX_PSL_IN_MODE_LEVEL, + NPCX_PSL_IN_MODE_EDGE, +}; + +/** + * @brief Suppoerted PSL input detection polarity in NPCX series + */ +enum npcx_psl_in_pol { + NPCX_PSL_IN_POL_LOW, + NPCX_PSL_IN_POL_HIGH, +}; + /** * @brief NPCX peripheral device configuration structure * @@ -64,6 +81,21 @@ struct npcx_periph { uint16_t reserved: 2; } __packed; +/** + * @brief NPCX Power Switch Logic (PSL) input pad configuration structure + * + * Used to indicate a Power Switch Logic (PSL) input detection configuration + * such as detection polarity, port number, and so on. + */ +struct npcx_psl_input { + /** Indicate a PSL input port number. */ + uint16_t port: 5; + /** Related register group for detection polarity of PSL input. */ + uint16_t pol_group: 8; + /** Related register bit for detection polarity of PSL input. */ + uint16_t pol_bit: 3; +} __packed; + /** * @brief Type for NPCX pin configuration. Please make sure the size of this * structure is 4 bytes in case the impact of ROM usage. @@ -71,6 +103,7 @@ struct npcx_periph { struct npcx_pinctrl { union { struct npcx_periph periph; + struct npcx_psl_input psl_in; uint16_t cfg_word; } cfg; struct { @@ -82,7 +115,10 @@ struct npcx_pinctrl { /** Properties used for io-pad. */ enum npcx_io_bias_type io_bias_type :2; enum npcx_io_drive_type io_drive_type :1; - uint16_t reserved :1; + /** Properties used for PSL input. */ + enum npcx_psl_in_mode psl_in_mode :1; + enum npcx_psl_in_pol psl_in_polarity :1; + uint16_t reserved :7; } flags; } __packed; @@ -106,6 +142,10 @@ typedef struct npcx_pinctrl pinctrl_soc_pin_t; UTIL_AND(DT_PROP(node_id, drive_open_drain), \ DT_NODE_HAS_PROP(node_periph, pwm_channel)) +#define Z_PINCTRL_NPCX_HAS_PSL_IN_PROP(node_id) \ + UTIL_AND(DT_NODE_HAS_PROP(node_id, psl_in_pol), \ + DT_NODE_HAS_PROP(node_id, psl_in_mode)) + /** * @brief Utility macro to initialize a periphral pinmux configuration. * @@ -152,6 +192,23 @@ typedef struct npcx_pinctrl pinctrl_soc_pin_t; .cfg.periph.group = DT_PROP(node_periph, pwm_channel), \ }, +/* + * @brief Utility macro to initialize a Power Switch Logic (PSL) input detection + * configurations. + * + * @param node_id Node identifier. + * @param prop Property name for pull-up/down configuration. (i.e. 'polarity') + */ +#define Z_PINCTRL_NPCX_PSL_IN_DETECT_CONF_INIT(node_id, prop) \ + { \ + .flags.type = NPCX_PINCTRL_TYPE_PSL_IN, \ + .flags.psl_in_mode = DT_ENUM_IDX(node_id, psl_in_mode), \ + .flags.psl_in_polarity = DT_ENUM_IDX(node_id, psl_in_pol), \ + .cfg.psl_in.port = DT_PROP(node_id, psl_offset), \ + .cfg.psl_in.pol_group = DT_PHA(DT_PROP(node_id, prop), alts, group), \ + .cfg.psl_in.pol_bit = DT_PHA(DT_PROP(node_id, prop), alts, bit), \ + }, + /** * @brief Utility macro to initialize all peripheral confiurations for each pin. * @@ -167,6 +224,9 @@ typedef struct npcx_pinctrl pinctrl_soc_pin_t; COND_CODE_1(Z_PINCTRL_NPCX_HAS_PUPD_PROP(DT_PROP_BY_IDX(node_id, prop, idx)), \ (Z_PINCTRL_NPCX_PERIPH_PUPD_INIT( \ DT_PROP_BY_IDX(node_id, prop, idx), periph_pupd)), ()) \ + 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), 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 ba795eee23b..1933aef830e 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -280,6 +280,12 @@ struct glue_reg { volatile uint8_t PSL_CTS; }; +/* GLUE register fields */ +/* PSL input detection mode is configured by bits 7:4 of PSL_CTS */ +#define NPCX_PSL_CTS_MODE_BIT(bit) BIT(bit + 4) +/* PSL input assertion events are reported by bits 3:0 of PSL_CTS */ +#define NPCX_PSL_CTS_EVENT_BIT(bit) BIT(bit) + /* * Universal Asynchronous Receiver-Transmitter (UART) device registers */ diff --git a/soc/arm/nuvoton_npcx/common/scfg.c b/soc/arm/nuvoton_npcx/common/scfg.c index f446170a0e0..d7736c4eac7 100644 --- a/soc/arm/nuvoton_npcx/common/scfg.c +++ b/soc/arm/nuvoton_npcx/common/scfg.c @@ -52,11 +52,6 @@ static const struct npcx_scfg_config npcx_scfg_cfg = { #define HAL_GLUE_INST() (struct glue_reg *)(npcx_scfg_cfg.base_glue) -/* PSL input detection mode is configured by bits 7:4 of PSL_CTS */ -#define NPCX_PSL_CTS_MODE_BIT(bit) BIT(bit + 4) -/* PSL input assertion events are reported by bits 3:0 of PSL_CTS */ -#define NPCX_PSL_CTS_EVENT_BIT(bit) BIT(bit) - /* Pin-control local functions */ static void npcx_pinctrl_alt_sel(const struct npcx_alt *alt, int alt_func) { diff --git a/soc/arm/nuvoton_npcx/common/soc_dt.h b/soc/arm/nuvoton_npcx/common/soc_dt.h index 8cfc1ed18e5..d50692a2513 100644 --- a/soc/arm/nuvoton_npcx/common/soc_dt.h +++ b/soc/arm/nuvoton_npcx/common/soc_dt.h @@ -700,4 +700,20 @@ #define NPCX_BOOTER_IS_HIF_TYPE_SET() \ DT_PROP(DT_PATH(booter_variant), hif_type_auto) +/** + * @brief Helper macro to get address of system configuration module which is + * used by serval peripheral device drivers in npcx series. + * + * @return base address of system configuration module. + */ +#define NPCX_SCFG_REG_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), scfg) + +/** + * @brief Helper macro to get address of system glue module which is + * used by serval peripheral device drivers in npcx series. + * + * @return base address of system glue module. + */ +#define NPCX_GLUE_REG_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), glue) + #endif /* _NUVOTON_NPCX_SOC_DT_H_ */