Microchip: MEC172x: Update pinmux driver
Update the Microchip XEC pinmux driver to use system I/O routine for read/write of registers instead of direct use of volatile and CMSIS defines. Add GPIO port number to bindings instead of using hard coded value from chip headers. Modify SoC DTSI pinmux syntax, requires "pinmux: pinumx {..." or the DT macros will not work. Since pinmux is used by MEC152x we update its chip pinmux DT. Signed-off-by: Scott Worley <scott.worley@microchip.com>
This commit is contained in:
parent
f452a086fb
commit
2070c0997f
7 changed files with 186 additions and 99 deletions
|
@ -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
|
||||
|
|
|
@ -9,9 +9,105 @@
|
|||
#include <kernel.h>
|
||||
#include <drivers/pinmux.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include <soc.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <device.h>
|
||||
#include <devicetree.h>
|
||||
#include <drivers/pinmux.h>
|
||||
#include <soc.h>
|
||||
#include <sys/printk.h>
|
||||
|
||||
#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)
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue