diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig index ebfe5b5eed6..926022b9c1d 100644 --- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig +++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig @@ -11,6 +11,7 @@ CONFIG_RTOS_TIMER=y CONFIG_CLOCK_CONTROL=y CONFIG_GPIO=y +CONFIG_PINMUX=y CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/arm/mec172xevb_assy6906/pinmux.c b/boards/arm/mec172xevb_assy6906/pinmux.c index cfeeedb187a..eba7b952b73 100644 --- a/boards/arm/mec172xevb_assy6906/pinmux.c +++ b/boards/arm/mec172xevb_assy6906/pinmux.c @@ -9,9 +9,105 @@ #include #include -#include "soc.h" +#include -/* - * If PINMUX will be used this is where board_pinmux_init should be implemented - * and added to SYS_INIT. - */ +#define XEC_UART_0_REGS \ + ((struct uart_regs *)DT_REG_ADDR(DT_NODELABEL(uart0))) + +#define XEC_UART_1_REGS \ + ((struct uart_regs *)DT_REG_ADDR(DT_NODELABEL(uart1))) + +struct pinmux_ports_t { +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) + const struct device *porta; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) + const struct device *portb; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) + const struct device *portc; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) + const struct device *portd; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) + const struct device *porte; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) + const struct device *portf; +#endif +}; + +static void brd_init_pinmux_ports(struct pinmux_ports_t *pp) +{ + ARG_UNUSED(pp); + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) + pp->porta = DEVICE_DT_GET(DT_NODELABEL(pinmux_000_036)); + + __ASSERT_NO_MSG(device_is_ready(pp->porta)); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) + pp->portb = DEVICE_DT_GET(DT_NODELABEL(pinmux_040_076)); + + __ASSERT_NO_MSG(device_is_ready(pp->portb)); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) + pp->portc = DEVICE_DT_GET(DT_NODELABEL(pinmux_100_136)); + + __ASSERT_NO_MSG(device_is_ready(pp->portc)); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) + pp->portd = DEVICE_DT_GET(DT_NODELABEL(pinmux_140_176)); + + __ASSERT_NO_MSG(device_is_ready(pp->portd)); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) + pp->porte = DEVICE_DT_GET(DT_NODELABEL(pinmux_200_236)); + + __ASSERT_NO_MSG(device_is_ready(pp->porte)); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) + pp->portf = DEVICE_DT_GET(DT_NODELABEL(pinmux_240_276)); + + __ASSERT_NO_MSG(device_is_ready(pp->portf)); +#endif +} + +static void brd_cfg_uart(struct pinmux_ports_t *pp) +{ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) + struct uart_regs *uart0 = XEC_UART_0_REGS; + + uart0->CFG_SEL = (MCHP_UART_LD_CFG_INTCLK + + MCHP_UART_LD_CFG_RESET_SYS + MCHP_UART_LD_CFG_NO_INVERT); + uart0->ACTV = MCHP_UART_LD_ACTIVATE; + + pinmux_pin_set(pp->portc, MCHP_GPIO_104, MCHP_GPIO_CTRL_MUX_F1); + pinmux_pin_set(pp->portc, MCHP_GPIO_105, MCHP_GPIO_CTRL_MUX_F1); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) + struct uart_regs *uart1 = XEC_UART_1_REGS; + + uart1->CFG_SEL = (MCHP_UART_LD_CFG_INTCLK + + MCHP_UART_LD_CFG_RESET_SYS + MCHP_UART_LD_CFG_NO_INVERT); + uart1->ACTV = MCHP_UART_LD_ACTIVATE; + + pinmux_pin_set(pp->portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F1); + pinmux_pin_set(pp->portd, MCHP_GPIO_171, MCHP_GPIO_CTRL_MUX_F1); +#endif +} + +/* caller passes dev = NULL */ +static int board_pinmux_init(const struct device *dev) +{ + ARG_UNUSED(dev); + struct pinmux_ports_t pp; + + brd_init_pinmux_ports(&pp); + brd_cfg_uart(&pp); + + return 0; +} + +SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/drivers/pinmux/pinmux_mchp_xec.c b/drivers/pinmux/pinmux_mchp_xec.c index c7b8531d787..bf44cd77bd0 100644 --- a/drivers/pinmux/pinmux_mchp_xec.c +++ b/drivers/pinmux/pinmux_mchp_xec.c @@ -6,8 +6,12 @@ #include #include +#include #include #include +#include + +#define DT_DRV_COMPAT microchip_xec_pinmux static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = { (MCHP_GPIO_PORT_A_BITMAP), @@ -19,7 +23,7 @@ static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = { }; struct pinmux_xec_config { - __IO uint32_t *pcr1_base; + uintptr_t pcr1_base; uint32_t port_num; }; @@ -27,9 +31,10 @@ static int pinmux_xec_set(const struct device *dev, uint32_t pin, uint32_t func) { const struct pinmux_xec_config *config = dev->config; - __IO uint32_t *current_pcr1; + uintptr_t current_pcr1; uint32_t pcr1 = 0; uint32_t mask = 0; + uint32_t temp = 0; /* Validate pin number in terms of current port */ if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0) { @@ -70,10 +75,12 @@ static int pinmux_xec_set(const struct device *dev, uint32_t pin, mask |= MCHP_GPIO_CTRL_IDET_MASK; /* Now write contents of pcr1 variable to the PCR1 register that - * corresponds to the pin configured + * corresponds to the pin configured. Each pin control register + * on a 32-bit boundary. */ - current_pcr1 = config->pcr1_base + pin; - *current_pcr1 = (*current_pcr1 & ~mask) | pcr1; + current_pcr1 = config->pcr1_base + pin * 4; + temp = (sys_read32(current_pcr1) & ~mask) | pcr1; + sys_write32(temp, current_pcr1); return 0; } @@ -82,17 +89,17 @@ static int pinmux_xec_get(const struct device *dev, uint32_t pin, uint32_t *func) { const struct pinmux_xec_config *config = dev->config; - __IO uint32_t *current_pcr1; + uintptr_t current_pcr1; /* Validate pin number in terms of current port */ if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0) { return -EINVAL; } - current_pcr1 = config->pcr1_base + pin; - *func = *current_pcr1 & (MCHP_GPIO_CTRL_BUFT_MASK - | MCHP_GPIO_CTRL_MUX_MASK - | MCHP_GPIO_CTRL_PUD_MASK); + current_pcr1 = config->pcr1_base + pin * 4; + *func = sys_read32(current_pcr1) & (MCHP_GPIO_CTRL_BUFT_MASK + | MCHP_GPIO_CTRL_MUX_MASK + | MCHP_GPIO_CTRL_PUD_MASK); return 0; } @@ -122,88 +129,23 @@ static const struct pinmux_driver_api pinmux_xec_driver_api = { .input = pinmux_xec_input, }; -#define PINMUX_ADDR(n) DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(n), ph_reg)) +/* Get ph_reg address given a node-id */ +#define PINMUX_ADDR(n) DT_REG_ADDR(DT_PHANDLE(n, ph_reg)) +/* Get ph_reg address given instance */ +#define PINMUX_INST_ADDR(n) DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(n), ph_reg)) +/* Get port-num property */ +#define PINMUX_PORT_NUM(n) DT_PROP(DT_NODELABEL(n), port_num) -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) -static const struct pinmux_xec_config pinmux_xec_port000_036_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_000_036), - .port_num = MCHP_GPIO_000_036, -}; +/* id is a child node-id */ +#define PINMUX_XEC_DEVICE(id) \ + static const struct pinmux_xec_config pinmux_xec_port_cfg_##id = { \ + .pcr1_base = (uintptr_t)PINMUX_ADDR(id), \ + .port_num = (uint32_t)DT_PROP(id, port_num), \ + }; \ + DEVICE_DT_DEFINE(id, &pinmux_xec_init, NULL, NULL, \ + &pinmux_xec_port_cfg_##id, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &pinmux_xec_driver_api); -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_000_036), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port000_036_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) -static const struct pinmux_xec_config pinmux_xec_port040_076_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_040_076), - .port_num = MCHP_GPIO_040_076, -}; - -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_040_076), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port040_076_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) -static const struct pinmux_xec_config pinmux_xec_port100_136_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_100_136), - .port_num = MCHP_GPIO_100_136, -}; - -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_100_136), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port100_136_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) -static const struct pinmux_xec_config pinmux_xec_port140_176_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_140_176), - .port_num = MCHP_GPIO_140_176, -}; - -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_140_176), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port140_176_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) -static const struct pinmux_xec_config pinmux_xec_port200_236_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_200_236), - .port_num = MCHP_GPIO_200_236, -}; - -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_200_236), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port200_236_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) -static const struct pinmux_xec_config pinmux_xec_port240_276_config = { - .pcr1_base = (uint32_t *) PINMUX_ADDR(pinmux_240_276), - .port_num = MCHP_GPIO_240_276, -}; - -DEVICE_DT_DEFINE(DT_NODELABEL(pinmux_240_276), - &pinmux_xec_init, - NULL, - NULL, &pinmux_xec_port240_276_config, - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &pinmux_xec_driver_api); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) */ +DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(pinmux), PINMUX_XEC_DEVICE) diff --git a/dts/arm/microchip/mec1501hsz.dtsi b/dts/arm/microchip/mec1501hsz.dtsi index e8441b81efc..2a6c4b2dc1a 100644 --- a/dts/arm/microchip/mec1501hsz.dtsi +++ b/dts/arm/microchip/mec1501hsz.dtsi @@ -37,26 +37,32 @@ i2c-smb-4 = &i2c_smb_4; }; - pinmux { + pinmux: pinmux { compatible = "microchip,xec-pinmux"; pinmux_000_036: pinmux-0 { ph-reg = <&gpio_000_036>; + port-num = <0>; }; pinmux_040_076: pinmux-1 { ph-reg = <&gpio_040_076>; + port-num = <1>; }; pinmux_100_136: pinmux-2 { ph-reg = <&gpio_100_136>; + port-num = <2>; }; pinmux_140_176: pinmux-3 { ph-reg = <&gpio_140_176>; + port-num = <3>; }; pinmux_200_236: pinmux-4 { ph-reg = <&gpio_200_236>; + port-num = <4>; }; pinmux_240_276: pinmux-5 { ph-reg = <&gpio_240_276>; + port-num = <5>; }; }; diff --git a/dts/arm/microchip/mec172xnsz.dtsi b/dts/arm/microchip/mec172xnsz.dtsi index a4f102eab7f..82842e93359 100644 --- a/dts/arm/microchip/mec172xnsz.dtsi +++ b/dts/arm/microchip/mec172xnsz.dtsi @@ -32,6 +32,35 @@ reg = <0x00118000 0x10000>; }; + pinmux: pinmux { + compatible = "microchip,xec-pinmux"; + + pinmux_000_036: pinmux-0 { + ph-reg = <&gpio_000_036>; + port-num = <0>; + }; + pinmux_040_076: pinmux-1 { + ph-reg = <&gpio_040_076>; + port-num = <1>; + }; + pinmux_100_136: pinmux-2 { + ph-reg = <&gpio_100_136>; + port-num = <2>; + }; + pinmux_140_176: pinmux-3 { + ph-reg = <&gpio_140_176>; + port-num = <3>; + }; + pinmux_200_236: pinmux-4 { + ph-reg = <&gpio_200_236>; + port-num = <4>; + }; + pinmux_240_276: pinmux-5 { + ph-reg = <&gpio_240_276>; + port-num = <5>; + }; + }; + soc { ecs: ecs@4000fc00 { reg = <0x4000fc00 0x200>; diff --git a/dts/bindings/pinctrl/microchip,xec-pinmux.yaml b/dts/bindings/pinctrl/microchip,xec-pinmux.yaml index 0dc12da3d25..b1c72e48b74 100644 --- a/dts/bindings/pinctrl/microchip,xec-pinmux.yaml +++ b/dts/bindings/pinctrl/microchip,xec-pinmux.yaml @@ -4,9 +4,18 @@ description: Microchip XEC Pinmux node compatible: "microchip,xec-pinmux" +include: base.yaml + child-binding: description: pinmux child node properties: ph-reg: type: phandle required: true + + port-num: + type: int + required: true + description: | + Zero based GPIO port number. Pin group 000 - 036 is port 0, + 040 - 076 is port 1, etc. diff --git a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.mec172xnsz b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.mec172xnsz index 58506b0de2f..d2ee8515790 100644 --- a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.mec172xnsz +++ b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.mec172xnsz @@ -19,4 +19,8 @@ config GPIO_XEC_V2 default y depends on GPIO +config PINMUX_XEC + default y + depends on PINMUX + endif # SOC_MEC172X_NSZ