blob: 6d6fdb0b0184d389434f0409201171d4f8201755 [file] [log] [blame]
rev13@wp.plfec465a2015-03-01 12:44:40 +01001/*
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
17DECLARE_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
29static 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
35struct 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
51int 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;
Axel Lin3e59f9e2015-04-26 10:32:36 +080072 clrsetbits_le32(&gpio_regs->afr[dsc->pin >> 3], 0xF << i, ctl->af << i);
rev13@wp.plfec465a2015-03-01 12:44:40 +010073
74 i = dsc->pin * 2;
75
Axel Lin3e59f9e2015-04-26 10:32:36 +080076 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);
rev13@wp.plfec465a2015-03-01 12:44:40 +010080
81 rv = 0;
82out:
83 return rv;
84}
85
86int 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;
104out:
105 return rv;
106}
107
108int 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);
120out:
121 return rv;
122}
123
124/* Common GPIO API */
125
126int gpio_request(unsigned gpio, const char *label)
127{
128 return 0;
129}
130
131int gpio_free(unsigned gpio)
132{
133 return 0;
134}
135
136int 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
151int 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);
169out:
170 return res;
171}
172
173int 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
183int 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}