1 /* 2 * Copyright (c) 2024 Michael Hope 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/drivers/pinctrl.h> 8 #include <zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h> 9 10 #include <ch32fun.h> 11 12 static GPIO_TypeDef *const wch_afio_pinctrl_regs[] = { 13 (GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpioa)), 14 (GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpioc)), 15 (GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpiod)), 16 }; 17 pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)18int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) 19 { 20 int i; 21 22 for (i = 0; i < pin_cnt; i++, pins++) { 23 uint8_t port = (pins->config >> CH32V003_PINCTRL_PORT_SHIFT) & 0x03; 24 uint8_t pin = (pins->config >> CH32V003_PINCTRL_PIN_SHIFT) & 0x0F; 25 uint8_t bit0 = (pins->config >> CH32V003_PINCTRL_RM_BASE_SHIFT) & 0x1F; 26 uint8_t remap = (pins->config >> CH32V003_PINCTRL_RM_SHIFT) & 0x3; 27 GPIO_TypeDef *regs = wch_afio_pinctrl_regs[port]; 28 uint32_t pcfr1 = AFIO->PCFR1; 29 uint8_t cfg = 0; 30 31 if (remap != 0) { 32 RCC->APB2PCENR |= RCC_AFIOEN; 33 } 34 35 if (pins->output_high || pins->output_low) { 36 cfg |= (pins->slew_rate + 1); 37 if (pins->drive_open_drain) { 38 cfg |= BIT(2); 39 } 40 /* Select the alternate function */ 41 cfg |= BIT(3); 42 } else { 43 if (pins->bias_pull_up || pins->bias_pull_down) { 44 cfg |= BIT(3); 45 } 46 } 47 regs->CFGLR = (regs->CFGLR & ~(0x0F << (pin * 4))) | (cfg << (pin * 4)); 48 49 if (pins->output_high) { 50 regs->OUTDR |= BIT(pin); 51 regs->BSHR |= BIT(pin); 52 } else if (pins->output_low) { 53 regs->OUTDR |= BIT(pin); 54 /* Reset the pin. */ 55 regs->BSHR |= BIT(pin + 16); 56 } else { 57 regs->OUTDR &= ~(1 << pin); 58 if (pins->bias_pull_up) { 59 regs->BSHR = BIT(pin); 60 } 61 if (pins->bias_pull_down) { 62 regs->BCR = BIT(pin); 63 } 64 } 65 66 if (bit0 == CH32V003_PINMUX_I2C1_RM) { 67 pcfr1 |= ((remap & 1) << CH32V003_PINMUX_I2C1_RM) | 68 (((remap >> 1) & 1) << CH32V003_PINMUX_I2C1_RM1); 69 } else if (bit0 == CH32V003_PINMUX_USART1_RM) { 70 pcfr1 |= ((remap & 1) << CH32V003_PINMUX_USART1_RM) | 71 (((remap >> 1) & 1) << CH32V003_PINMUX_USART1_RM1); 72 } else { 73 pcfr1 |= remap << bit0; 74 } 75 AFIO->PCFR1 = pcfr1; 76 } 77 78 return 0; 79 } 80