1 /* 2 * (C) Copyright 2011 3 * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com 4 * 5 * (C) Copyright 2015 6 * Kamil Lulko, <kamil.lulko@gmail.com> 7 * 8 * Copyright 2015 ATS Advanced Telematics Systems GmbH 9 * Copyright 2015 Konsulko Group, Matt Porter <mporter@konsulko.com> 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 #include <common.h> 15 #include <asm/io.h> 16 #include <asm/errno.h> 17 #include <asm/arch/stm32.h> 18 #include <asm/arch/gpio.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #if defined(CONFIG_STM32F4) 23 #define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) 24 #define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) 25 #define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) 26 #define STM32_GPIOD_BASE (STM32_AHB1PERIPH_BASE + 0x0C00) 27 #define STM32_GPIOE_BASE (STM32_AHB1PERIPH_BASE + 0x1000) 28 #define STM32_GPIOF_BASE (STM32_AHB1PERIPH_BASE + 0x1400) 29 #define STM32_GPIOG_BASE (STM32_AHB1PERIPH_BASE + 0x1800) 30 #define STM32_GPIOH_BASE (STM32_AHB1PERIPH_BASE + 0x1C00) 31 #define STM32_GPIOI_BASE (STM32_AHB1PERIPH_BASE + 0x2000) 32 33 static const unsigned long io_base[] = { 34 STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, 35 STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, 36 STM32_GPIOG_BASE, STM32_GPIOH_BASE, STM32_GPIOI_BASE 37 }; 38 39 struct stm32_gpio_regs { 40 u32 moder; /* GPIO port mode */ 41 u32 otyper; /* GPIO port output type */ 42 u32 ospeedr; /* GPIO port output speed */ 43 u32 pupdr; /* GPIO port pull-up/pull-down */ 44 u32 idr; /* GPIO port input data */ 45 u32 odr; /* GPIO port output data */ 46 u32 bsrr; /* GPIO port bit set/reset */ 47 u32 lckr; /* GPIO port configuration lock */ 48 u32 afr[2]; /* GPIO alternate function */ 49 }; 50 51 #define CHECK_DSC(x) (!x || x->port > 8 || x->pin > 15) 52 #define CHECK_CTL(x) (!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \ 53 x->pupd > 2 || x->speed > 3) 54 55 int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, 56 const struct stm32_gpio_ctl *ctl) 57 { 58 struct stm32_gpio_regs *gpio_regs; 59 u32 i; 60 int rv; 61 62 if (CHECK_DSC(dsc)) { 63 rv = -EINVAL; 64 goto out; 65 } 66 if (CHECK_CTL(ctl)) { 67 rv = -EINVAL; 68 goto out; 69 } 70 71 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 72 73 i = (dsc->pin & 0x07) * 4; 74 clrsetbits_le32(&gpio_regs->afr[dsc->pin >> 3], 0xF << i, ctl->af << i); 75 76 i = dsc->pin * 2; 77 78 clrsetbits_le32(&gpio_regs->moder, 0x3 << i, ctl->mode << i); 79 clrsetbits_le32(&gpio_regs->otyper, 0x3 << i, ctl->otype << i); 80 clrsetbits_le32(&gpio_regs->ospeedr, 0x3 << i, ctl->speed << i); 81 clrsetbits_le32(&gpio_regs->pupdr, 0x3 << i, ctl->pupd << i); 82 83 rv = 0; 84 out: 85 return rv; 86 } 87 #elif defined(CONFIG_STM32F1) 88 #define STM32_GPIOA_BASE (STM32_APB2PERIPH_BASE + 0x0800) 89 #define STM32_GPIOB_BASE (STM32_APB2PERIPH_BASE + 0x0C00) 90 #define STM32_GPIOC_BASE (STM32_APB2PERIPH_BASE + 0x1000) 91 #define STM32_GPIOD_BASE (STM32_APB2PERIPH_BASE + 0x1400) 92 #define STM32_GPIOE_BASE (STM32_APB2PERIPH_BASE + 0x1800) 93 #define STM32_GPIOF_BASE (STM32_APB2PERIPH_BASE + 0x1C00) 94 #define STM32_GPIOG_BASE (STM32_APB2PERIPH_BASE + 0x2000) 95 96 static const unsigned long io_base[] = { 97 STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, 98 STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, 99 STM32_GPIOG_BASE 100 }; 101 102 #define STM32_GPIO_CR_MODE_MASK 0x3 103 #define STM32_GPIO_CR_MODE_SHIFT(p) (p * 4) 104 #define STM32_GPIO_CR_CNF_MASK 0x3 105 #define STM32_GPIO_CR_CNF_SHIFT(p) (p * 4 + 2) 106 107 struct stm32_gpio_regs { 108 u32 crl; /* GPIO port configuration low */ 109 u32 crh; /* GPIO port configuration high */ 110 u32 idr; /* GPIO port input data */ 111 u32 odr; /* GPIO port output data */ 112 u32 bsrr; /* GPIO port bit set/reset */ 113 u32 brr; /* GPIO port bit reset */ 114 u32 lckr; /* GPIO port configuration lock */ 115 }; 116 117 #define CHECK_DSC(x) (!x || x->port > 6 || x->pin > 15) 118 #define CHECK_CTL(x) (!x || x->mode > 3 || x->icnf > 3 || x->ocnf > 3 || \ 119 x->pupd > 1) 120 121 int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, 122 const struct stm32_gpio_ctl *ctl) 123 { 124 struct stm32_gpio_regs *gpio_regs; 125 u32 *cr; 126 int p, crp; 127 int rv; 128 129 if (CHECK_DSC(dsc)) { 130 rv = -EINVAL; 131 goto out; 132 } 133 if (CHECK_CTL(ctl)) { 134 rv = -EINVAL; 135 goto out; 136 } 137 138 p = dsc->pin; 139 140 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 141 142 if (p < 8) { 143 cr = &gpio_regs->crl; 144 crp = p; 145 } else { 146 cr = &gpio_regs->crh; 147 crp = p - 8; 148 } 149 150 clrbits_le32(cr, 0x3 << STM32_GPIO_CR_MODE_SHIFT(crp)); 151 setbits_le32(cr, ctl->mode << STM32_GPIO_CR_MODE_SHIFT(crp)); 152 153 clrbits_le32(cr, 0x3 << STM32_GPIO_CR_CNF_SHIFT(crp)); 154 /* Inputs set the optional pull up / pull down */ 155 if (ctl->mode == STM32_GPIO_MODE_IN) { 156 setbits_le32(cr, ctl->icnf << STM32_GPIO_CR_CNF_SHIFT(crp)); 157 clrbits_le32(&gpio_regs->odr, 0x1 << p); 158 setbits_le32(&gpio_regs->odr, ctl->pupd << p); 159 } else { 160 setbits_le32(cr, ctl->ocnf << STM32_GPIO_CR_CNF_SHIFT(crp)); 161 } 162 163 rv = 0; 164 out: 165 return rv; 166 } 167 #else 168 #error STM32 family not supported 169 #endif 170 171 int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) 172 { 173 struct stm32_gpio_regs *gpio_regs; 174 int rv; 175 176 if (CHECK_DSC(dsc)) { 177 rv = -EINVAL; 178 goto out; 179 } 180 181 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 182 183 if (state) 184 writel(1 << dsc->pin, &gpio_regs->bsrr); 185 else 186 writel(1 << (dsc->pin + 16), &gpio_regs->bsrr); 187 188 rv = 0; 189 out: 190 return rv; 191 } 192 193 int stm32_gpin_get(const struct stm32_gpio_dsc *dsc) 194 { 195 struct stm32_gpio_regs *gpio_regs; 196 int rv; 197 198 if (CHECK_DSC(dsc)) { 199 rv = -EINVAL; 200 goto out; 201 } 202 203 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 204 rv = readl(&gpio_regs->idr) & (1 << dsc->pin); 205 out: 206 return rv; 207 } 208 209 /* Common GPIO API */ 210 211 int gpio_request(unsigned gpio, const char *label) 212 { 213 return 0; 214 } 215 216 int gpio_free(unsigned gpio) 217 { 218 return 0; 219 } 220 221 int gpio_direction_input(unsigned gpio) 222 { 223 struct stm32_gpio_dsc dsc; 224 struct stm32_gpio_ctl ctl; 225 226 dsc.port = stm32_gpio_to_port(gpio); 227 dsc.pin = stm32_gpio_to_pin(gpio); 228 #if defined(CONFIG_STM32F4) 229 ctl.af = STM32_GPIO_AF0; 230 ctl.mode = STM32_GPIO_MODE_IN; 231 ctl.otype = STM32_GPIO_OTYPE_PP; 232 ctl.pupd = STM32_GPIO_PUPD_NO; 233 ctl.speed = STM32_GPIO_SPEED_50M; 234 #elif defined(CONFIG_STM32F1) 235 ctl.mode = STM32_GPIO_MODE_IN; 236 ctl.icnf = STM32_GPIO_ICNF_IN_FLT; 237 ctl.ocnf = STM32_GPIO_OCNF_GP_PP; /* ignored for input */ 238 ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for floating */ 239 #else 240 #error STM32 family not supported 241 #endif 242 243 return stm32_gpio_config(&dsc, &ctl); 244 } 245 246 int gpio_direction_output(unsigned gpio, int value) 247 { 248 struct stm32_gpio_dsc dsc; 249 struct stm32_gpio_ctl ctl; 250 int res; 251 252 dsc.port = stm32_gpio_to_port(gpio); 253 dsc.pin = stm32_gpio_to_pin(gpio); 254 #if defined(CONFIG_STM32F4) 255 ctl.af = STM32_GPIO_AF0; 256 ctl.mode = STM32_GPIO_MODE_OUT; 257 ctl.pupd = STM32_GPIO_PUPD_NO; 258 ctl.speed = STM32_GPIO_SPEED_50M; 259 #elif defined(CONFIG_STM32F1) 260 ctl.mode = STM32_GPIO_MODE_OUT_50M; 261 ctl.ocnf = STM32_GPIO_OCNF_GP_PP; 262 ctl.icnf = STM32_GPIO_ICNF_IN_FLT; /* ignored for output */ 263 ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for output */ 264 #else 265 #error STM32 family not supported 266 #endif 267 268 res = stm32_gpio_config(&dsc, &ctl); 269 if (res < 0) 270 goto out; 271 res = stm32_gpout_set(&dsc, value); 272 out: 273 return res; 274 } 275 276 int gpio_get_value(unsigned gpio) 277 { 278 struct stm32_gpio_dsc dsc; 279 280 dsc.port = stm32_gpio_to_port(gpio); 281 dsc.pin = stm32_gpio_to_pin(gpio); 282 283 return stm32_gpin_get(&dsc); 284 } 285 286 int gpio_set_value(unsigned gpio, int value) 287 { 288 struct stm32_gpio_dsc dsc; 289 290 dsc.port = stm32_gpio_to_port(gpio); 291 dsc.pin = stm32_gpio_to_pin(gpio); 292 293 return stm32_gpout_set(&dsc, value); 294 } 295