blob: 871fff36497b9a99e6f62f043ee9f034e8d1d84b [file] [log] [blame]
/*
* Copyright (c) 2021 Microchip Technology Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <init.h>
#include <kernel.h>
#include <drivers/clock_control/mchp_xec_clock_control.h>
#include <drivers/pinmux.h>
#include <soc.h>
enum gpio_ports {
port_000_036 = 0,
port_040_076,
port_100_136,
port_140_176,
port_200_236,
port_240_276,
port_max,
};
struct pin_info {
enum gpio_ports port_num;
uint8_t pin;
uint32_t flags;
};
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
};
const struct pin_info uart_pin_table[] = {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay)
{ port_100_136, MCHP_GPIO_104, MCHP_GPIO_CTRL_MUX_F1 },
{ port_100_136, MCHP_GPIO_105, MCHP_GPIO_CTRL_MUX_F1 },
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay)
{ port_140_176, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F1 },
{ port_140_176, MCHP_GPIO_171, MCHP_GPIO_CTRL_MUX_F1 },
#endif
};
/* eSPI: Reset#, Alert#, CS#, CLK, IO0 - IO4 */
const struct pin_info espi_pin_table[] = {
#if defined(CONFIG_ESPI_XEC_V2) && DT_NODE_HAS_STATUS(DT_NODELABEL(espi0), okay)
{ port_040_076, MCHP_GPIO_061, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_063, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_066, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_065, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_070, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_071, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_072, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1 },
#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
}
const struct device *get_port_device(struct pinmux_ports_t *pp,
uint8_t port_num)
{
switch (port_num) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay)
case port_000_036:
return pp->porta;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay)
case port_040_076:
return pp->portb;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay)
case port_100_136:
return pp->portc;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay)
case port_140_176:
return pp->portd;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay)
case port_200_236:
return pp->porte;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay)
case port_240_276:
return pp->portf;
#endif
default:
return NULL;
}
}
static void brd_pin_table_init(struct pinmux_ports_t *pp,
const struct pin_info *table, size_t nentries)
{
for (size_t n = 0; n < nentries; n++) {
const struct device *dev =
get_port_device(pp, table[n].port_num);
if (!dev) {
continue;
}
pinmux_pin_set(dev, table[n].pin, table[n].flags);
}
}
/* 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_pin_table_init(&pp, uart_pin_table, ARRAY_SIZE(uart_pin_table));
brd_pin_table_init(&pp, espi_pin_table, ARRAY_SIZE(espi_pin_table));
return 0;
}
SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY);