/* --------- gpio_chip related code --------- */ static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val) { struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); if (val) gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); else gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); }
/* --------- pinconf related code --------- */ static int xway_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config); int port = PORT(pin); u32 reg; switch (param) { case LTQ_PINCONF_PARAM_OPEN_DRAIN: if (port == PORT3) reg = GPIO3_OD; else reg = GPIO_OD(pin); *config = LTQ_PINCONF_PACK(param, !gpio_getbit(info->membase[0], reg, PORT_PIN(pin))); break; case LTQ_PINCONF_PARAM_PULL: if (port == PORT3) reg = GPIO3_PUDEN; else reg = GPIO_PUDEN(pin); if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin))) { *config = LTQ_PINCONF_PACK(param, 0); break; } if (port == PORT3) reg = GPIO3_PUDSEL; else reg = GPIO_PUDSEL(pin); if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin))) *config = LTQ_PINCONF_PACK(param, 2); else *config = LTQ_PINCONF_PACK(param, 1); break; case LTQ_PINCONF_PARAM_OUTPUT: reg = GPIO_DIR(pin); *config = LTQ_PINCONF_PACK(param, gpio_getbit(info->membase[0], reg, PORT_PIN(pin))); break; default: dev_err(pctldev->dev, "Invalid config param %04x\n", param); return -ENOTSUPP; } return 0; }
static inline void xmc4_gpio_pdisc(uintptr_t portbase, unsigned int pin, bool enable) { uint32_t regval; uint32_t mask; /* Read the PDISC register */ regval = xmc4_gpio_getreg(portbase, XMC4_PORT_PDISC_OFFSET); /* Set or clear the pin field in the PDISC register. * * Disable = set * Analog = set * Enable = clear */ mask = PORT_PIN(pin); if (enable) { regval &= ~mask; } else { regval |= mask; } xmc4_gpio_putreg(portbase, XMC4_PORT_PDISC_OFFSET, regval); }
static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) { struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); return 0; }
static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val) { struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); xway_gpio_set(chip, pin, val); return 0; }
static inline int xway_mux_apply(struct pinctrl_dev *pctrldev, int pin, int mux) { struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); int port = PORT(pin); u32 alt1_reg = GPIO_ALT1(pin); if (port == PORT3) alt1_reg = GPIO3_ALT1; if (mux & MUX_ALT0) gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); else gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); if (mux & MUX_ALT1) gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin)); else gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin)); return 0; }
bool xmc4_gpio_read(gpioconfig_t pinconfig) { uintptr_t portbase = xmc4_gpio_portbase(pinconfig); unsigned int pin = xmc4_gpio_pin(pinconfig); uint32_t regval; /* Read the OUT register. This is an atomoc operation so no critical * section is needed. */ regval = xmc4_gpio_getreg(portbase, XMC4_PORT_IN_OFFSET); /* Return in the input state for this pin at the time is was read */ return ((regval & PORT_PIN(pin)) != 0); }
static inline void xmc4_gpio_pps(uintptr_t portbase, unsigned int pin, bool powersave) { uint32_t regval; uint32_t mask; /* Read the PPS register */ regval = xmc4_gpio_getreg(portbase, XMC4_PORT_PPS_OFFSET); /* Set/clear the enable/disable power save value for this field */ mask = PORT_PIN(pin); if (powersave) { regval |= mask; } else { regval &= ~mask; } xmc4_gpio_putreg(portbase, XMC4_PORT_PPS_OFFSET, regval); }
void __section("SectionForBootstrapOperations") BootstrapCode_GPIO() { /* GPIO pins connected to NOR Flash and SRAM on the MCBSTM32F400 board */ const uint8_t PortD_PinList[] = {0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13, 14, 15}; #ifdef DEBUG // PE2,3,4,5 are used for TRACECLK and TRACEDATA0-3 so don't enable them as address pins in debug builds // This limits external FLASH and SRAM to 1MB addressable space each. const uint8_t PortE_PinList[] = {0, 1, /*2, 3, 4, 5,*/ 7, 8, 9, 10, 11, 12, 13, 14, 15}; #else const uint8_t PortE_PinList[] = {0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15}; #endif const uint8_t PortF_PinList[] = {0, 1, 2, 3, 4, 5, 12, 13, 14, 15}; const uint8_t PortG_PinList[] = {0, 1, 2, 3, 4, 5, 10}; const uint32_t pinConfig = 0x3C2; // Speed 100Mhz, AF12 FSMC, Alternate Mode const uint32_t pinMode = pinConfig & 0xF; const GPIO_ALT_MODE alternateMode = (GPIO_ALT_MODE) pinConfig; const GPIO_RESISTOR resistorConfig = RESISTOR_PULLUP; uint32_t i; /* Enable GPIO clocks */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN | RCC_AHB1ENR_GPIOIEN; CPU_GPIO_EnableOutputPin(LED1, FALSE); CPU_GPIO_EnableOutputPin(LED2, FALSE); CPU_GPIO_EnableOutputPin(LED3, FALSE); CPU_GPIO_EnableOutputPin(LED4, FALSE); CPU_GPIO_EnableOutputPin(LED5, FALSE); CPU_GPIO_EnableOutputPin(LED6, FALSE); CPU_GPIO_EnableOutputPin(LED7, FALSE); CPU_GPIO_EnableOutputPin(LED8, FALSE); /*Initialize SRAM and NOR GPIOs */ for(i = 0; i < ARRAY_LENGTH(PortD_PinList); i++) /* Port D */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortE_PinList); i++) /* Port E */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortF_PinList); i++) /* Port F */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortG_PinList); i++) /* Port G */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } /* Initialize NOR and SRAM */ InitNorFlash(); InitSram(); }
static int xway_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *configs, unsigned num_configs) { struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); enum ltq_pinconf_param param; int arg; int port = PORT(pin); u32 reg; int i; for (i = 0; i < num_configs; i++) { param = LTQ_PINCONF_UNPACK_PARAM(configs[i]); arg = LTQ_PINCONF_UNPACK_ARG(configs[i]); switch (param) { case LTQ_PINCONF_PARAM_OPEN_DRAIN: if (port == PORT3) reg = GPIO3_OD; else reg = GPIO_OD(pin); if (arg == 0) gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); else gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); break; case LTQ_PINCONF_PARAM_PULL: if (port == PORT3) reg = GPIO3_PUDEN; else reg = GPIO_PUDEN(pin); if (arg == 0) { gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); break; } gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); if (port == PORT3) reg = GPIO3_PUDSEL; else reg = GPIO_PUDSEL(pin); if (arg == 1) gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); else if (arg == 2) gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); else dev_err(pctldev->dev, "Invalid pull value %d\n", arg); break; case LTQ_PINCONF_PARAM_OUTPUT: reg = GPIO_DIR(pin); if (arg == 0) gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); else gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); break; default: dev_err(pctldev->dev, "Invalid config param %04x\n", param); return -ENOTSUPP; } } /* for each config */ return 0; }
// ============================================================================= // 功能: 设置对应UART的IO口,包括时钟和IO配置 // 参数: SerialNo,串口号 // 返回: 无 // ============================================================================= static void __UART_GpioConfig(u8 SerialNo) { GPIO_PowerOn(1); switch(SerialNo) { case CN_UART0: SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; PORT_MuxConfig(PORT_PORT_A,PORT_PIN(1),PORT_PINMUX_ALT2); PORT_MuxConfig(PORT_PORT_A,PORT_PIN(2),PORT_PINMUX_ALT2); break; case CN_UART1: SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; PORT_MuxConfig(PORT_PORT_E,PORT_PIN(0),PORT_PINMUX_ALT3); PORT_MuxConfig(PORT_PORT_E,PORT_PIN(1),PORT_PINMUX_ALT3); break; case CN_UART2: SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; PORT_MuxConfig(PORT_PORT_E,PORT_PIN(16),PORT_PINMUX_ALT3); PORT_MuxConfig(PORT_PORT_E,PORT_PIN(17),PORT_PINMUX_ALT3); break; case CN_UART3: SIM->SCGC4 |= SIM_SCGC4_UART3_MASK; PORT_MuxConfig(PORT_PORT_E,PORT_PIN(4),PORT_PINMUX_ALT3); PORT_MuxConfig(PORT_PORT_E,PORT_PIN(5),PORT_PINMUX_ALT3); break; case CN_UART4: SIM->SCGC1 |= SIM_SCGC1_UART4_MASK; PORT_MuxConfig(PORT_PORT_E,PORT_PIN(24),PORT_PINMUX_ALT3); PORT_MuxConfig(PORT_PORT_E,PORT_PIN(25),PORT_PINMUX_ALT3); break; case CN_UART5: SIM->SCGC1 |= SIM_SCGC1_UART5_MASK; PORT_MuxConfig(PORT_PORT_E,PORT_PIN(8),PORT_PINMUX_ALT3); PORT_MuxConfig(PORT_PORT_E,PORT_PIN(9),PORT_PINMUX_ALT3); break; default: break; } }