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