| /* |
| * 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; |
| } |