]> git.sur5r.net Git - u-boot/blob - board/st-ericsson/u8500/gpio.c
nios2: implement get_ticks and get_tbclk
[u-boot] / board / st-ericsson / u8500 / gpio.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2009
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <common.h>
24 #include <asm/arch/gpio.h>
25
26 static struct gpio_register *addr_gpio_register[] = {
27         (void *)U8500_GPIO_0_BASE,
28         (void *)U8500_GPIO_1_BASE,
29         (void *)U8500_GPIO_2_BASE,
30         (void *)U8500_GPIO_3_BASE,
31         (void *)U8500_GPIO_4_BASE,
32         (void *)U8500_GPIO_5_BASE,
33         (void *)U8500_GPIO_6_BASE,
34         (void *)U8500_GPIO_7_BASE,
35         (void *)U8500_GPIO_8_BASE,
36 };
37
38 struct gpio_altfun_data altfun_table[] = {
39         {
40                 .altfun = GPIO_ALT_I2C_0,
41                 .start = 147,
42                 .end = 148,
43                 .cont = 0,
44                 .type = GPIO_ALTF_A,
45         },
46         {
47                 .altfun = GPIO_ALT_I2C_1,
48                 .start = 16,
49                 .end = 17,
50                 .cont = 0,
51                 .type = GPIO_ALTF_B,
52         },
53         {
54                 .altfun = GPIO_ALT_I2C_2,
55                 .start = 10,
56                 .end = 11,
57                 .cont = 0,
58                 .type = GPIO_ALTF_B,
59         },
60         {
61                 .altfun = GPIO_ALT_I2C_3,
62                 .start = 229,
63                 .end = 230,
64                 .cont = 0,
65                 .type = GPIO_ALTF_C,
66         },
67         {
68                 .altfun = GPIO_ALT_UART_0_MODEM,
69                 .start = 0,
70                 .end = 3,
71                 .cont = 1,
72                 .type = GPIO_ALTF_A,
73         },
74         {
75                 .altfun = GPIO_ALT_UART_0_MODEM,
76                 .start = 33,
77                 .end = 36,
78                 .cont = 0,
79                 .type = GPIO_ALTF_C,
80         },
81         {
82                 .altfun = GPIO_ALT_UART_1,
83                 .start = 4,
84                 .end = 7,
85                 .cont = 0,
86                 .type =
87                         GPIO_ALTF_A,
88         },
89         {
90                 .altfun = GPIO_ALT_UART_2,
91                 .start = 18,
92                 .end = 19,
93                 .cont = 1,
94                 .type = GPIO_ALTF_B,
95         },
96         {
97                 .altfun = GPIO_ALT_UART_2,
98                 .start = 29,
99                 .end = 32,
100                 .cont = 0,
101                 .type = GPIO_ALTF_C,
102         },
103         {
104                 .altfun = GPIO_ALT_MSP_0,
105                 .start = 12,
106                 .end = 17,
107                 .cont = 1,
108                 .type = GPIO_ALTF_A,
109         },
110         {
111                 .altfun = GPIO_ALT_MSP_0,
112                 .start = 21,
113                 .end = 21,
114                 .cont = 0,
115                 .type = GPIO_ALTF_B,
116         },
117         {
118                 .altfun = GPIO_ALT_MSP_1,
119                 .start = 33,
120                 .end = 36,
121                 .cont = 0,
122                 .type = GPIO_ALTF_A,
123         },
124         {
125                 .altfun = GPIO_ALT_MSP_2,
126                 .start = 192,
127                 .end = 196,
128                 .cont = 0,
129                 .type = GPIO_ALTF_A,
130         },
131         {
132                 .altfun = GPIO_ALT_LCD_PANEL,
133                 .start = 64,
134                 .end = 93,
135                 .cont = 1,
136                 .type = GPIO_ALTF_A,
137         },
138         {
139                 .altfun = GPIO_ALT_LCD_PANEL,
140                 .start = 150,
141                 .end = 171,
142                 .cont = 0,
143                 .type = GPIO_ALTF_B,
144         },
145         {
146                 .altfun = GPIO_ALT_SD_CARD0,
147                 .start = 18,
148                 .end = 28,
149                 .cont = 0,
150                 .type = GPIO_ALTF_A,
151         },
152         {
153                 .altfun = GPIO_ALT_MM_CARD0,
154                 .start = 18,
155                 .end = 32,
156                 .cont = 0,
157                 .type = GPIO_ALTF_A,
158         },
159         {
160                 .altfun = GPIO_ALT_USB_OTG,
161                 .start = 256,
162                 .end = 267,
163                 .cont = 0,
164                 .type = GPIO_ALTF_A,
165         },
166         {
167                 .altfun = GPIO_ALT_EMMC,
168                 .start = 197,
169                 .end = 207,
170                 .cont = 0,
171                 .type = GPIO_ALTF_A,
172         },
173         {
174                 .altfun = GPIO_ALT_POP_EMMC,
175                 .start = 128,
176                 .end = 138,
177                 .cont = 0,
178                 .type = GPIO_ALTF_A,
179         },
180 };
181
182 /*
183  * Static Function declarations
184  */
185 enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
186 {
187         struct gpio_register *p_gpio_register =
188             addr_gpio_register[GPIO_BLOCK(pin_id)];
189         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
190         enum gpio_error error = GPIO_OK;
191         u32 temp_reg;
192
193         switch (config->mode) {
194         case GPIO_ALTF_A:
195                 temp_reg = readl(&p_gpio_register->gpio_afsa);
196                 temp_reg |= mask;
197                 writel(temp_reg, &p_gpio_register->gpio_afsa);
198                 temp_reg = readl(&p_gpio_register->gpio_afsb);
199                 temp_reg &= ~mask;
200                 writel(temp_reg, &p_gpio_register->gpio_afsb);
201                 break;
202         case GPIO_ALTF_B:
203                 temp_reg = readl(&p_gpio_register->gpio_afsa);
204                 temp_reg &= ~mask;
205                 writel(temp_reg, &p_gpio_register->gpio_afsa);
206                 temp_reg = readl(&p_gpio_register->gpio_afsb);
207                 temp_reg |= mask;
208                 writel(temp_reg, &p_gpio_register->gpio_afsb);
209                 break;
210         case GPIO_ALTF_C:
211                 temp_reg = readl(&p_gpio_register->gpio_afsa);
212                 temp_reg |= mask;
213                 writel(temp_reg, &p_gpio_register->gpio_afsa);
214                 temp_reg = readl(&p_gpio_register->gpio_afsb);
215                 temp_reg |= mask;
216                 writel(temp_reg, &p_gpio_register->gpio_afsb);
217                 break;
218         case GPIO_MODE_SOFTWARE:
219                 temp_reg = readl(&p_gpio_register->gpio_afsa);
220                 temp_reg &= ~mask;
221                 writel(temp_reg, &p_gpio_register->gpio_afsa);
222                 temp_reg = readl(&p_gpio_register->gpio_afsb);
223                 temp_reg &= ~mask;
224                 writel(temp_reg, &p_gpio_register->gpio_afsb);
225
226                 switch (config->direction) {
227                 case GPIO_DIR_INPUT:
228                         writel(mask, &p_gpio_register->gpio_dirc);
229                         break;
230                 case GPIO_DIR_OUTPUT:
231                         writel(mask, &p_gpio_register->gpio_dirs);
232                         break;
233                 case GPIO_DIR_LEAVE_UNCHANGED:
234                         break;
235                 default:
236                         return GPIO_INVALID_PARAMETER;
237                 }
238
239                 break;
240         case GPIO_MODE_LEAVE_UNCHANGED:
241                 break;
242         default:
243                 return GPIO_INVALID_PARAMETER;
244         }
245         return error;
246 }
247
248 enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
249 {
250         struct gpio_register *p_gpio_register =
251             addr_gpio_register[GPIO_BLOCK(pin_id)];
252         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
253         enum gpio_error error = GPIO_OK;
254         u32 temp_reg;
255
256         temp_reg = readl(&p_gpio_register->gpio_afsa);
257         temp_reg &= ~mask;
258         writel(temp_reg, &p_gpio_register->gpio_afsa);
259         temp_reg = readl(&p_gpio_register->gpio_afsb);
260         temp_reg &= ~mask;
261         writel(temp_reg, &p_gpio_register->gpio_afsb);
262         writel(mask, &p_gpio_register->gpio_dirc);
263
264         return error;
265 }
266
267 struct gpio_config altfun_pinconfig;
268 enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
269                             int which_altfunc, char *dev_name)
270 {
271         int i, j, start, end;
272         enum gpio_error error = -1;
273
274         for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
275                 if (altfun_table[i].altfun != alt_func)
276                         continue;
277
278                 start = altfun_table[i].start;
279                 end = altfun_table[i].end;
280                 for (j = start; j <= end; j++) {
281                         if (which_altfunc == GPIO_ALTF_FIND)
282                                 altfun_pinconfig.mode = altfun_table[i].type;
283                         else
284                                 altfun_pinconfig.mode = which_altfunc;
285                         altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
286                         altfun_pinconfig.dev_name = dev_name;
287
288                         if (which_altfunc != GPIO_ALTF_DISABLE)
289                                 error = gpio_setpinconfig(j, &altfun_pinconfig);
290                         else
291                                 error = gpio_resetgpiopin(j, dev_name);
292                         if (!error)
293                                 continue;
294                         printf("GPIO %d configuration failure (nmdk_error:%d)",
295                                 j, error);
296                         error = GPIO_INVALID_PARAMETER;
297                         return error;
298                 }
299
300                 if (!altfun_table[i].cont)
301                         break;
302         }
303         return error;
304 }
305
306 int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
307 {
308         struct gpio_register *p_gpio_register =
309             addr_gpio_register[GPIO_BLOCK(pin_id)];
310         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
311
312         switch (value) {
313         case GPIO_DATA_HIGH:
314                 writel(mask, &p_gpio_register->gpio_dats);
315                 break;
316         case GPIO_DATA_LOW:
317                 writel(mask, &p_gpio_register->gpio_datc);
318                 break;
319         default:
320                 printf("Invalid value passed in %s", __FUNCTION__);
321                 return GPIO_INVALID_PARAMETER;
322         }
323         return GPIO_OK;
324 }
325
326 int gpio_readpin(int pin_id, enum gpio_data *rv)
327 {
328         struct gpio_register *p_gpio_register =
329             addr_gpio_register[GPIO_BLOCK(pin_id)];
330         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
331
332         if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
333                 *rv = GPIO_DATA_HIGH;
334         else
335                 *rv = GPIO_DATA_LOW;
336         return GPIO_OK;
337 }
338
339 int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
340 {
341         return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
342 }
343
344 int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
345 {
346         return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
347 }