pinctrl: npcx: add pinctrl support for psl pads

This CL introduces how to configure PSL (Power Switch Logic) pads
properties such as input detection mode/polarity, pin-muxing and so
on via pinctrl mechanism. It includes:

1. Add two pinctrl properties and their enums for PSL input
   detection configuration.
    psl-in-mode:
      - "level"
      - "mode"
    psl-in-pole:
      - "low-falling"
      - "high-rising"

2. Add macro functions to get PSL input detection and pin-muxing
   configurations from 'pinmux', 'psl-offset' abd 'psl-polarity'
   properties.

Here is an example to configure PSL_IN2 as the PSL detection input and
its mode and polarity.

/* A falling edge detection type for PSL_IN2 */
&psl_in2_gp00 {
	psl-in-mode = "edge";
	psl-in-pol = "low-falling";
};

A device will be introduced later which uses this pinctrl node to
configure PSL input detection settings and how to turn off VCC1 power
rail by PSL_OUT.

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2022-04-06 20:20:17 -07:00 committed by Fabio Baltieri
commit 851e357aa4
8 changed files with 166 additions and 9 deletions

View file

@ -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++) {
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;

View file

@ -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 */

View file

@ -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 {

View file

@ -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"

View file

@ -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)), ())

View file

@ -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
*/

View file

@ -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)
{

View file

@ -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_ */