1 /* 2 * (C) Copyright 2011 3 * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com 4 * 5 * (C) Copyright 2015 6 * Kamil Lulko, <rev13@wp.pl> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <asm/io.h> 13 #include <asm/errno.h> 14 #include <asm/arch/stm32.h> 15 #include <asm/arch/gpio.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) 20 #define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) 21 #define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) 22 #define STM32_GPIOD_BASE (STM32_AHB1PERIPH_BASE + 0x0C00) 23 #define STM32_GPIOE_BASE (STM32_AHB1PERIPH_BASE + 0x1000) 24 #define STM32_GPIOF_BASE (STM32_AHB1PERIPH_BASE + 0x1400) 25 #define STM32_GPIOG_BASE (STM32_AHB1PERIPH_BASE + 0x1800) 26 #define STM32_GPIOH_BASE (STM32_AHB1PERIPH_BASE + 0x1C00) 27 #define STM32_GPIOI_BASE (STM32_AHB1PERIPH_BASE + 0x2000) 28 29 static const unsigned long io_base[] = { 30 STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, 31 STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, 32 STM32_GPIOG_BASE, STM32_GPIOH_BASE, STM32_GPIOI_BASE 33 }; 34 35 struct stm32_gpio_regs { 36 u32 moder; /* GPIO port mode */ 37 u32 otyper; /* GPIO port output type */ 38 u32 ospeedr; /* GPIO port output speed */ 39 u32 pupdr; /* GPIO port pull-up/pull-down */ 40 u32 idr; /* GPIO port input data */ 41 u32 odr; /* GPIO port output data */ 42 u32 bsrr; /* GPIO port bit set/reset */ 43 u32 lckr; /* GPIO port configuration lock */ 44 u32 afr[2]; /* GPIO alternate function */ 45 }; 46 47 #define CHECK_DSC(x) (!x || x->port > 8 || x->pin > 15) 48 #define CHECK_CTL(x) (!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \ 49 x->pupd > 2 || x->speed > 3) 50 51 int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, 52 const struct stm32_gpio_ctl *ctl) 53 { 54 struct stm32_gpio_regs *gpio_regs; 55 u32 i; 56 int rv; 57 58 if (CHECK_DSC(dsc)) { 59 rv = -EINVAL; 60 goto out; 61 } 62 if (CHECK_CTL(ctl)) { 63 rv = -EINVAL; 64 goto out; 65 } 66 67 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 68 69 setbits_le32(&STM32_RCC->ahb1enr, 1 << dsc->port); 70 71 i = (dsc->pin & 0x07) * 4; 72 clrsetbits_le32(&gpio_regs->afr[dsc->pin >> 3], 0xF << i, ctl->af << i); 73 74 i = dsc->pin * 2; 75 76 clrsetbits_le32(&gpio_regs->moder, 0x3 << i, ctl->mode << i); 77 clrsetbits_le32(&gpio_regs->otyper, 0x3 << i, ctl->otype << i); 78 clrsetbits_le32(&gpio_regs->ospeedr, 0x3 << i, ctl->speed << i); 79 clrsetbits_le32(&gpio_regs->pupdr, 0x3 << i, ctl->pupd << i); 80 81 rv = 0; 82 out: 83 return rv; 84 } 85 86 int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) 87 { 88 struct stm32_gpio_regs *gpio_regs; 89 int rv; 90 91 if (CHECK_DSC(dsc)) { 92 rv = -EINVAL; 93 goto out; 94 } 95 96 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 97 98 if (state) 99 writel(1 << dsc->pin, &gpio_regs->bsrr); 100 else 101 writel(1 << (dsc->pin + 16), &gpio_regs->bsrr); 102 103 rv = 0; 104 out: 105 return rv; 106 } 107 108 int stm32_gpin_get(const struct stm32_gpio_dsc *dsc) 109 { 110 struct stm32_gpio_regs *gpio_regs; 111 int rv; 112 113 if (CHECK_DSC(dsc)) { 114 rv = -EINVAL; 115 goto out; 116 } 117 118 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 119 rv = readl(&gpio_regs->idr) & (1 << dsc->pin); 120 out: 121 return rv; 122 } 123 124 /* Common GPIO API */ 125 126 int gpio_request(unsigned gpio, const char *label) 127 { 128 return 0; 129 } 130 131 int gpio_free(unsigned gpio) 132 { 133 return 0; 134 } 135 136 int gpio_direction_input(unsigned gpio) 137 { 138 struct stm32_gpio_dsc dsc; 139 struct stm32_gpio_ctl ctl; 140 141 dsc.port = stm32_gpio_to_port(gpio); 142 dsc.pin = stm32_gpio_to_pin(gpio); 143 ctl.af = STM32_GPIO_AF0; 144 ctl.mode = STM32_GPIO_MODE_IN; 145 ctl.pupd = STM32_GPIO_PUPD_NO; 146 ctl.speed = STM32_GPIO_SPEED_50M; 147 148 return stm32_gpio_config(&dsc, &ctl); 149 } 150 151 int gpio_direction_output(unsigned gpio, int value) 152 { 153 struct stm32_gpio_dsc dsc; 154 struct stm32_gpio_ctl ctl; 155 int res; 156 157 dsc.port = stm32_gpio_to_port(gpio); 158 dsc.pin = stm32_gpio_to_pin(gpio); 159 ctl.af = STM32_GPIO_AF0; 160 ctl.mode = STM32_GPIO_MODE_OUT; 161 ctl.otype = STM32_GPIO_OTYPE_PP; 162 ctl.pupd = STM32_GPIO_PUPD_NO; 163 ctl.speed = STM32_GPIO_SPEED_50M; 164 165 res = stm32_gpio_config(&dsc, &ctl); 166 if (res < 0) 167 goto out; 168 res = stm32_gpout_set(&dsc, value); 169 out: 170 return res; 171 } 172 173 int gpio_get_value(unsigned gpio) 174 { 175 struct stm32_gpio_dsc dsc; 176 177 dsc.port = stm32_gpio_to_port(gpio); 178 dsc.pin = stm32_gpio_to_pin(gpio); 179 180 return stm32_gpin_get(&dsc); 181 } 182 183 int gpio_set_value(unsigned gpio, int value) 184 { 185 struct stm32_gpio_dsc dsc; 186 187 dsc.port = stm32_gpio_to_port(gpio); 188 dsc.pin = stm32_gpio_to_pin(gpio); 189 190 return stm32_gpout_set(&dsc, value); 191 } 192