zephyr/drivers/pinctrl/pinctrl_emsdp.c

298 lines
7.1 KiB
C

/*
* Copyright (c) 2023 Synopsys
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT snps_emsdp_pinctrl
#include <zephyr/arch/cpu.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/dt-bindings/pinctrl/emsdp-pinctrl.h>
/**
* Mux Control Register Index
*/
#define PMOD_MUX_CTRL 0 /*!< 32-bits, offset 0x0 */
#define ARDUINO_MUX_CTRL 4 /*!< 32-bits, offset 0x4 */
#define EMSDP_CREG_BASE DT_INST_REG_ADDR(0)
#define EMSDP_CREG_PMOD_MUX_OFFSET (0x0030)
#define MUX_SEL0_OFFSET (0)
#define MUX_SEL1_OFFSET (4)
#define MUX_SEL2_OFFSET (8)
#define MUX_SEL3_OFFSET (12)
#define MUX_SEL4_OFFSET (16)
#define MUX_SEL5_OFFSET (20)
#define MUX_SEL6_OFFSET (24)
#define MUX_SEL7_OFFSET (28)
#define MUX_SEL0_MASK (0xf << MUX_SEL0_OFFSET)
#define MUX_SEL1_MASK (0xf << MUX_SEL1_OFFSET)
#define MUX_SEL2_MASK (0xf << MUX_SEL2_OFFSET)
#define MUX_SEL3_MASK (0xf << MUX_SEL3_OFFSET)
#define MUX_SEL4_MASK (0xf << MUX_SEL4_OFFSET)
#define MUX_SEL5_MASK (0xf << MUX_SEL5_OFFSET)
#define MUX_SEL6_MASK (0xf << MUX_SEL6_OFFSET)
#define MUX_SEL7_MASK (0xf << MUX_SEL7_OFFSET)
/**
* PMOD A Multiplexor
*/
#define PM_A_CFG0_GPIO ((0) << MUX_SEL0_OFFSET)
#define PM_A_CFG0_I2C ((1) << MUX_SEL0_OFFSET) /* io_i2c_mst2 */
#define PM_A_CFG0_SPI ((2) << MUX_SEL0_OFFSET) /* io_spi_mst1, cs_0 */
#define PM_A_CFG0_UART1a ((3) << MUX_SEL0_OFFSET) /* io_uart1 */
#define PM_A_CFG0_UART1b ((4) << MUX_SEL0_OFFSET) /* io_uart1 */
#define PM_A_CFG0_PWM1 ((5) << MUX_SEL0_OFFSET)
#define PM_A_CFG0_PWM2 ((6) << MUX_SEL0_OFFSET)
#define PM_A_CFG1_GPIO ((0) << MUX_SEL1_OFFSET)
/**
* PMOD B Multiplexor
*/
#define PM_B_CFG0_GPIO ((0) << MUX_SEL2_OFFSET)
#define PM_B_CFG0_I2C ((1) << MUX_SEL2_OFFSET) /* io_i2c_mst2 */
#define PM_B_CFG0_SPI ((2) << MUX_SEL2_OFFSET) /* io_spi_mst1, cs_1 */
#define PM_B_CFG0_UART2a ((3) << MUX_SEL2_OFFSET) /* io_uart2 */
#define PM_B_CFG0_UART2b ((4) << MUX_SEL2_OFFSET) /* io_uart2 */
#define PM_B_CFG0_PWM1 ((5) << MUX_SEL2_OFFSET)
#define PM_B_CFG0_PWM2 ((6) << MUX_SEL2_OFFSET)
#define PM_B_CFG1_GPIO ((0) << MUX_SEL3_OFFSET)
/**
* PMOD C Multiplexor
*/
#define PM_C_CFG0_GPIO ((0) << MUX_SEL4_OFFSET)
#define PM_C_CFG0_I2C ((1) << MUX_SEL4_OFFSET) /* io_i2c_mst2 */
#define PM_C_CFG0_SPI ((2) << MUX_SEL4_OFFSET) /* io_spi_mst1, cs_2 */
#define PM_C_CFG0_UART3a ((3) << MUX_SEL4_OFFSET) /* io_uart3 */
#define PM_C_CFG0_UART3b ((4) << MUX_SEL4_OFFSET) /* io_uart3 */
#define PM_C_CFG0_PWM1 ((5) << MUX_SEL4_OFFSET)
#define PM_C_CFG0_PWM2 ((6) << MUX_SEL4_OFFSET)
#define PM_C_CFG1_GPIO ((0) << MUX_SEL5_OFFSET)
/**
* Arduino Multiplexor
*/
#define ARDUINO_CFG0_GPIO ((0) << MUX_SEL0_OFFSET)
#define ARDUINO_CFG0_UART ((1) << MUX_SEL0_OFFSET) /* io_uart0 */
#define ARDUINO_CFG1_GPIO ((0) << MUX_SEL1_OFFSET)
#define ARDUINO_CFG1_PWM ((1) << MUX_SEL1_OFFSET)
#define ARDUINO_CFG2_GPIO ((0) << MUX_SEL2_OFFSET)
#define ARDUINO_CFG2_PWM ((1) << MUX_SEL2_OFFSET)
#define ARDUINO_CFG3_GPIO ((0) << MUX_SEL3_OFFSET)
#define ARDUINO_CFG3_PWM ((1) << MUX_SEL3_OFFSET)
#define ARDUINO_CFG4_GPIO ((0) << MUX_SEL4_OFFSET)
#define ARDUINO_CFG4_PWM ((1) << MUX_SEL4_OFFSET)
#define ARDUINO_CFG5_GPIO ((0) << MUX_SEL5_OFFSET)
#define ARDUINO_CFG5_SPI ((1) << MUX_SEL5_OFFSET) /* io_spi_mst0, cs_0 */
#define ARDUINO_CFG5_PWM1 ((2) << MUX_SEL5_OFFSET)
#define ARDUINO_CFG5_PWM2 ((3) << MUX_SEL5_OFFSET)
#define ARDUINO_CFG5_PWM3 ((4) << MUX_SEL5_OFFSET)
#define ARDUINO_CFG6_GPIO ((0) << MUX_SEL6_OFFSET)
#define ARDUINO_CFG6_I2C ((1) << MUX_SEL6_OFFSET) /* io_i2c_mst1 */
static int pinctrl_emsdp_set(uint32_t pin, uint32_t type)
{
const uint32_t mux_regs = (EMSDP_CREG_BASE + EMSDP_CREG_PMOD_MUX_OFFSET);
uint32_t reg;
if (pin == UNMUXED_PIN) {
return 0;
}
if (pin <= PMOD_C) {
reg = sys_read32(mux_regs + PMOD_MUX_CTRL);
} else {
reg = sys_read32(mux_regs + ARDUINO_MUX_CTRL);
}
switch (pin) {
case PMOD_A:
reg &= ~(MUX_SEL0_MASK);
switch (type) {
case PMOD_GPIO:
reg |= PM_A_CFG0_GPIO;
break;
case PMOD_UARTA:
reg |= PM_A_CFG0_UART1a;
break;
case PMOD_UARTB:
reg |= PM_A_CFG0_UART1b;
break;
case PMOD_SPI:
reg |= PM_A_CFG0_SPI;
break;
case PMOD_I2C:
reg |= PM_A_CFG0_I2C;
break;
case PMOD_PWM_MODE1:
reg |= PM_A_CFG0_PWM1;
break;
case PMOD_PWM_MODE2:
reg |= PM_A_CFG0_PWM2;
break;
default:
break;
}
break;
case PMOD_B:
reg &= ~(MUX_SEL2_MASK);
switch (type) {
case PMOD_GPIO:
reg |= PM_B_CFG0_GPIO;
break;
case PMOD_UARTA:
reg |= PM_B_CFG0_UART2a;
break;
case PMOD_UARTB:
reg |= PM_A_CFG0_UART1b;
break;
case PMOD_SPI:
reg |= PM_B_CFG0_SPI;
break;
case PMOD_I2C:
reg |= PM_B_CFG0_I2C;
break;
case PMOD_PWM_MODE1:
reg |= PM_B_CFG0_PWM1;
break;
case PMOD_PWM_MODE2:
reg |= PM_B_CFG0_PWM2;
break;
default:
break;
}
break;
case PMOD_C:
reg &= ~(MUX_SEL4_MASK);
switch (type) {
case PMOD_GPIO:
reg |= PM_C_CFG0_GPIO;
break;
case PMOD_UARTA:
reg |= PM_C_CFG0_UART3a;
break;
case PMOD_UARTB:
reg |= PM_C_CFG0_UART3b;
break;
case PMOD_SPI:
reg |= PM_C_CFG0_SPI;
break;
case PMOD_I2C:
reg |= PM_C_CFG0_I2C;
break;
case PMOD_PWM_MODE1:
reg |= PM_C_CFG0_PWM1;
break;
case PMOD_PWM_MODE2:
reg |= PM_C_CFG0_PWM2;
break;
default:
break;
}
break;
case ARDUINO_PIN_0:
case ARDUINO_PIN_1:
reg &= ~MUX_SEL0_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG0_GPIO;
} else if (type == ARDUINO_UART) {
reg |= ARDUINO_CFG0_UART;
}
break;
case ARDUINO_PIN_2:
case ARDUINO_PIN_3:
reg &= ~MUX_SEL1_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG1_GPIO;
} else if (type == ARDUINO_PWM) {
reg |= ARDUINO_CFG1_PWM;
}
break;
case ARDUINO_PIN_4:
case ARDUINO_PIN_5:
reg &= ~MUX_SEL2_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG2_GPIO;
} else if (type == ARDUINO_PWM) {
reg |= ARDUINO_CFG2_PWM;
}
break;
case ARDUINO_PIN_6:
case ARDUINO_PIN_7:
reg &= ~MUX_SEL3_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG3_GPIO;
} else if (type == ARDUINO_PWM) {
reg |= ARDUINO_CFG3_PWM;
}
break;
case ARDUINO_PIN_8:
case ARDUINO_PIN_9:
reg &= ~MUX_SEL4_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG4_GPIO;
} else if (type == ARDUINO_PWM) {
reg |= ARDUINO_CFG4_PWM;
}
break;
case ARDUINO_PIN_10:
case ARDUINO_PIN_11:
case ARDUINO_PIN_12:
case ARDUINO_PIN_13:
reg &= ~MUX_SEL5_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG5_GPIO;
} else if (type == ARDUINO_SPI) {
reg |= ARDUINO_CFG5_SPI;
} else if (type == ARDUINO_PWM) {
reg |= ARDUINO_CFG5_PWM1;
}
break;
case ARDUINO_PIN_AD4:
case ARDUINO_PIN_AD5:
reg &= ~MUX_SEL6_MASK;
if (type == ARDUINO_GPIO) {
reg |= ARDUINO_CFG6_GPIO;
} else if (type == ARDUINO_I2C) {
reg |= ARDUINO_CFG6_I2C;
}
break;
default:
break;
}
if (pin <= PMOD_C) {
sys_write32(reg, mux_regs + PMOD_MUX_CTRL);
} else {
sys_write32(reg, mux_regs + ARDUINO_MUX_CTRL);
}
return 0;
}
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
{
ARG_UNUSED(reg);
int i;
for (i = 0; i < pin_cnt; i++) {
pinctrl_emsdp_set(pins[i].pin, pins[i].type);
}
return 0;
}