1 #include <common.h> 2 #include <asm/arch/gpio.h> 3 #include <dm.h> 4 #include <dm/pinctrl.h> 5 6 DECLARE_GLOBAL_DATA_PTR; 7 8 static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) 9 { 10 gpio_dsc->port = (port_pin & 0xF000) >> 12; 11 gpio_dsc->pin = (port_pin & 0x0F00) >> 8; 12 debug("%s: GPIO:port= %d, pin= %d\n", __func__, gpio_dsc->port, 13 gpio_dsc->pin); 14 15 return 0; 16 } 17 18 static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node) 19 { 20 gpio_fn &= 0x00FF; 21 22 switch (gpio_fn) { 23 case 0: 24 gpio_ctl->mode = STM32_GPIO_MODE_IN; 25 break; 26 case 1 ... 16: 27 gpio_ctl->mode = STM32_GPIO_MODE_AF; 28 gpio_ctl->af = gpio_fn - 1; 29 break; 30 case 17: 31 gpio_ctl->mode = STM32_GPIO_MODE_AN; 32 break; 33 default: 34 gpio_ctl->mode = STM32_GPIO_MODE_OUT; 35 break; 36 } 37 38 gpio_ctl->speed = fdtdec_get_int(gd->fdt_blob, node, "slew-rate", 0); 39 40 if (fdtdec_get_bool(gd->fdt_blob, node, "drive-open-drain")) 41 gpio_ctl->otype = STM32_GPIO_OTYPE_OD; 42 else 43 gpio_ctl->otype = STM32_GPIO_OTYPE_PP; 44 45 if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-up")) 46 gpio_ctl->pupd = STM32_GPIO_PUPD_UP; 47 else if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-down")) 48 gpio_ctl->pupd = STM32_GPIO_PUPD_DOWN; 49 else 50 gpio_ctl->pupd = STM32_GPIO_PUPD_NO; 51 52 debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n", 53 __func__, gpio_fn, gpio_ctl->speed, gpio_ctl->otype, 54 gpio_ctl->pupd); 55 56 return 0; 57 } 58 59 static int stm32_pinctrl_set_state_simple(struct udevice *dev, 60 struct udevice *periph) 61 { 62 u32 pin_mux[50]; 63 struct fdtdec_phandle_args args; 64 int rv, len; 65 66 /* Get node pinctrl-0 */ 67 rv = fdtdec_parse_phandle_with_args(gd->fdt_blob, periph->of_offset, 68 "pinctrl-0", 0, 0, 0, &args); 69 if (rv) 70 return rv; 71 /* 72 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for 73 * usart1) of pin controller phandle "pinctrl-0" 74 * */ 75 fdt_for_each_subnode(args.node, gd->fdt_blob, args.node) { 76 struct stm32_gpio_dsc gpio_dsc; 77 struct stm32_gpio_ctl gpio_ctl; 78 int i; 79 80 len = fdtdec_get_int_array_count(gd->fdt_blob, args.node, 81 "pinmux", pin_mux, 82 ARRAY_SIZE(pin_mux)); 83 debug("%s: periph->name = %s, no of pinmux entries= %d\n", 84 __func__, periph->name, len); 85 if (len < 0) 86 return -EINVAL; 87 for (i = 0; i < len; i++) { 88 debug("%s: pinmux = %x\n", __func__, *(pin_mux + i)); 89 prep_gpio_dsc(&gpio_dsc, *(pin_mux + i)); 90 prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node); 91 92 rv = stm32_gpio_config(&gpio_dsc, &gpio_ctl); 93 debug("%s: rv = %d\n\n", __func__, rv); 94 if (rv) 95 return rv; 96 } 97 } 98 99 return 0; 100 } 101 102 static struct pinctrl_ops stm32_pinctrl_ops = { 103 .set_state_simple = stm32_pinctrl_set_state_simple, 104 }; 105 106 static const struct udevice_id stm32_pinctrl_ids[] = { 107 { .compatible = "st,stm32f746-pinctrl" }, 108 { } 109 }; 110 111 U_BOOT_DRIVER(pinctrl_stm32) = { 112 .name = "pinctrl_stm32", 113 .id = UCLASS_PINCTRL, 114 .of_match = stm32_pinctrl_ids, 115 .ops = &stm32_pinctrl_ops, 116 .bind = dm_scan_fdt_dev, 117 }; 118