1 /* 2 * (C) Copyright 2017 3 * Vikas Manocha, <vikas.manocha@st.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <fdtdec.h> 12 #include <asm/arch/gpio.h> 13 #include <asm/arch/stm32.h> 14 #include <asm/gpio.h> 15 #include <asm/io.h> 16 #include <linux/errno.h> 17 #include <linux/io.h> 18 19 #define MAX_SIZE_BANK_NAME 5 20 #define STM32_GPIOS_PER_BANK 16 21 #define MODE_BITS(gpio_pin) (gpio_pin * 2) 22 #define MODE_BITS_MASK 3 23 #define IN_OUT_BIT_INDEX(gpio_pin) (1UL << (gpio_pin)) 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) 28 { 29 struct stm32_gpio_priv *priv = dev_get_priv(dev); 30 struct stm32_gpio_regs *regs = priv->regs; 31 int bits_index = MODE_BITS(offset); 32 int mask = MODE_BITS_MASK << bits_index; 33 34 clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); 35 36 return 0; 37 } 38 39 static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, 40 int value) 41 { 42 struct stm32_gpio_priv *priv = dev_get_priv(dev); 43 struct stm32_gpio_regs *regs = priv->regs; 44 int bits_index = MODE_BITS(offset); 45 int mask = MODE_BITS_MASK << bits_index; 46 47 clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); 48 mask = IN_OUT_BIT_INDEX(offset); 49 clrsetbits_le32(®s->odr, mask, value ? mask : 0); 50 51 return 0; 52 } 53 54 static int stm32_gpio_get_value(struct udevice *dev, unsigned offset) 55 { 56 struct stm32_gpio_priv *priv = dev_get_priv(dev); 57 struct stm32_gpio_regs *regs = priv->regs; 58 59 return readl(®s->idr) & IN_OUT_BIT_INDEX(offset) ? 1 : 0; 60 } 61 62 static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value) 63 { 64 struct stm32_gpio_priv *priv = dev_get_priv(dev); 65 struct stm32_gpio_regs *regs = priv->regs; 66 int mask = IN_OUT_BIT_INDEX(offset); 67 68 clrsetbits_le32(®s->odr, mask, value ? mask : 0); 69 70 return 0; 71 } 72 73 static const struct dm_gpio_ops gpio_stm32_ops = { 74 .direction_input = stm32_gpio_direction_input, 75 .direction_output = stm32_gpio_direction_output, 76 .get_value = stm32_gpio_get_value, 77 .set_value = stm32_gpio_set_value, 78 }; 79 80 static int gpio_stm32_probe(struct udevice *dev) 81 { 82 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 83 struct stm32_gpio_priv *priv = dev_get_priv(dev); 84 fdt_addr_t addr; 85 char *name; 86 87 addr = devfdt_get_addr(dev); 88 if (addr == FDT_ADDR_T_NONE) 89 return -EINVAL; 90 91 priv->regs = (struct stm32_gpio_regs *)addr; 92 name = (char *)fdtdec_locate_byte_array(gd->fdt_blob, 93 dev_of_offset(dev), 94 "st,bank-name", 95 MAX_SIZE_BANK_NAME); 96 if (!name) 97 return -EINVAL; 98 uc_priv->bank_name = name; 99 uc_priv->gpio_count = STM32_GPIOS_PER_BANK; 100 debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs, 101 uc_priv->bank_name); 102 103 #ifdef CONFIG_CLK 104 struct clk clk; 105 int ret; 106 ret = clk_get_by_index(dev, 0, &clk); 107 if (ret < 0) 108 return ret; 109 110 ret = clk_enable(&clk); 111 112 if (ret) { 113 dev_err(dev, "failed to enable clock\n"); 114 return ret; 115 } 116 debug("clock enabled for device %s\n", dev->name); 117 #endif 118 119 return 0; 120 } 121 122 static const struct udevice_id stm32_gpio_ids[] = { 123 { .compatible = "st,stm32-gpio" }, 124 { } 125 }; 126 127 U_BOOT_DRIVER(gpio_stm32) = { 128 .name = "gpio_stm32", 129 .id = UCLASS_GPIO, 130 .of_match = stm32_gpio_ids, 131 .probe = gpio_stm32_probe, 132 .ops = &gpio_stm32_ops, 133 .flags = DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS, 134 .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), 135 }; 136