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