You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
7.1 KiB
297 lines
7.1 KiB
/* |
|
* 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; |
|
}
|
|
|