blob: 488ca11bb0657055e2ad53f037a5c1907f641b91 [file] [log] [blame]
Mike Frysinger4638b212010-06-02 04:17:26 -04001/*
2 * GPIO Abstraction Layer
3 *
4 * Copyright 2006-2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later
7 */
8
9#include <common.h>
10#include <asm/errno.h>
11#include <asm/gpio.h>
12#include <asm/portmux.h>
13
14#if ANOMALY_05000311 || ANOMALY_05000323
15enum {
16 AWA_data = SYSCR,
17 AWA_data_clear = SYSCR,
18 AWA_data_set = SYSCR,
19 AWA_toggle = SYSCR,
20 AWA_maska = UART_SCR,
21 AWA_maska_clear = UART_SCR,
22 AWA_maska_set = UART_SCR,
23 AWA_maska_toggle = UART_SCR,
24 AWA_maskb = UART_GCTL,
25 AWA_maskb_clear = UART_GCTL,
26 AWA_maskb_set = UART_GCTL,
27 AWA_maskb_toggle = UART_GCTL,
28 AWA_dir = SPORT1_STAT,
29 AWA_polar = SPORT1_STAT,
30 AWA_edge = SPORT1_STAT,
31 AWA_both = SPORT1_STAT,
32#if ANOMALY_05000311
33 AWA_inen = TIMER_ENABLE,
34#elif ANOMALY_05000323
35 AWA_inen = DMA1_1_CONFIG,
36#endif
37};
38 /* Anomaly Workaround */
39#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
40#else
41#define AWA_DUMMY_READ(...) do { } while (0)
42#endif
43
44static struct gpio_port_t * const gpio_array[] = {
45#if defined(BF533_FAMILY)
46 (struct gpio_port_t *) FIO_FLAG_D,
47#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) \
48 || defined(BF538_FAMILY)
49 (struct gpio_port_t *) PORTFIO,
50# if !defined(BF538_FAMILY)
51 (struct gpio_port_t *) PORTGIO,
52 (struct gpio_port_t *) PORTHIO,
53# endif
54#elif defined(BF561_FAMILY)
55 (struct gpio_port_t *) FIO0_FLAG_D,
56 (struct gpio_port_t *) FIO1_FLAG_D,
57 (struct gpio_port_t *) FIO2_FLAG_D,
58#elif defined(CONFIG_BF54x)
59 (struct gpio_port_t *)PORTA_FER,
60 (struct gpio_port_t *)PORTB_FER,
61 (struct gpio_port_t *)PORTC_FER,
62 (struct gpio_port_t *)PORTD_FER,
63 (struct gpio_port_t *)PORTE_FER,
64 (struct gpio_port_t *)PORTF_FER,
65 (struct gpio_port_t *)PORTG_FER,
66 (struct gpio_port_t *)PORTH_FER,
67 (struct gpio_port_t *)PORTI_FER,
68 (struct gpio_port_t *)PORTJ_FER,
69#else
70# error no gpio arrays defined
71#endif
72};
73
74#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
75static unsigned short * const port_fer[] = {
76 (unsigned short *) PORTF_FER,
77 (unsigned short *) PORTG_FER,
78 (unsigned short *) PORTH_FER,
79};
80
81# if !defined(BF537_FAMILY)
82static unsigned short * const port_mux[] = {
83 (unsigned short *) PORTF_MUX,
84 (unsigned short *) PORTG_MUX,
85 (unsigned short *) PORTH_MUX,
86};
87
88static const
89u8 pmux_offset[][16] = {
90# if defined(CONFIG_BF52x)
91 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
92 { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
93 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
94# elif defined(CONFIG_BF51x)
95 { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
96 { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
97 { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
98# endif
99};
100# endif
101
102#elif defined(BF538_FAMILY)
103static unsigned short * const port_fer[] = {
104 (unsigned short *) PORTCIO_FER,
105 (unsigned short *) PORTDIO_FER,
106 (unsigned short *) PORTEIO_FER,
107};
108#endif
109
110#ifdef CONFIG_BFIN_GPIO_TRACK
111#define RESOURCE_LABEL_SIZE 16
112
113static struct str_ident {
114 char name[RESOURCE_LABEL_SIZE];
115} str_ident[MAX_RESOURCES];
116
117static void gpio_error(unsigned gpio)
118{
119 printf("bfin-gpio: GPIO %d wasn't requested!\n", gpio);
120}
121
122static void set_label(unsigned short ident, const char *label)
123{
124 if (label) {
125 strncpy(str_ident[ident].name, label,
126 RESOURCE_LABEL_SIZE);
127 str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
128 }
129}
130
131static char *get_label(unsigned short ident)
132{
133 return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
134}
135
136static int cmp_label(unsigned short ident, const char *label)
137{
138 if (label == NULL)
139 printf("bfin-gpio: please provide none-null label\n");
140
141 if (label)
142 return strcmp(str_ident[ident].name, label);
143 else
144 return -EINVAL;
145}
146
147#define map_entry(m, i) reserved_##m##_map[gpio_bank(i)]
148#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
149#define reserve(m, i) (map_entry(m, i) |= gpio_bit(i))
150#define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i))
151#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c]
152#else
153#define is_reserved(m, i, e) (!(e))
154#define reserve(m, i)
155#define unreserve(m, i)
156#define DECLARE_RESERVED_MAP(m, c)
157#define gpio_error(gpio)
158#define set_label(...)
159#define get_label(...) ""
160#define cmp_label(...) 1
161#endif
162
163DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
164DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
165
166inline int check_gpio(unsigned gpio)
167{
168#if defined(CONFIG_BF54x)
169 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
170 || gpio == GPIO_PH14 || gpio == GPIO_PH15
171 || gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
172 return -EINVAL;
173#endif
174 if (gpio >= MAX_BLACKFIN_GPIOS)
175 return -EINVAL;
176 return 0;
177}
178
179static void port_setup(unsigned gpio, unsigned short usage)
180{
181#if defined(BF538_FAMILY)
182 /*
183 * BF538/9 Port C,D and E are special.
184 * Inverted PORT_FER polarity on CDE and no PORF_FER on F
185 * Regular PORT F GPIOs are handled here, CDE are exclusively
186 * managed by GPIOLIB
187 */
188
189 if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
190 return;
191
192 gpio -= MAX_BLACKFIN_GPIOS;
193
194 if (usage == GPIO_USAGE)
195 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
196 else
197 *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
198 SSYNC();
199 return;
200#endif
201
202 if (check_gpio(gpio))
203 return;
204
205#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
206 if (usage == GPIO_USAGE)
207 *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
208 else
209 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
210 SSYNC();
211#elif defined(CONFIG_BF54x)
212 if (usage == GPIO_USAGE)
213 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
214 else
215 gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
216 SSYNC();
217#endif
218}
219
220#ifdef BF537_FAMILY
221static struct {
222 unsigned short res;
223 unsigned short offset;
224} port_mux_lut[] = {
225 {.res = P_PPI0_D13, .offset = 11},
226 {.res = P_PPI0_D14, .offset = 11},
227 {.res = P_PPI0_D15, .offset = 11},
228 {.res = P_SPORT1_TFS, .offset = 11},
229 {.res = P_SPORT1_TSCLK, .offset = 11},
230 {.res = P_SPORT1_DTPRI, .offset = 11},
231 {.res = P_PPI0_D10, .offset = 10},
232 {.res = P_PPI0_D11, .offset = 10},
233 {.res = P_PPI0_D12, .offset = 10},
234 {.res = P_SPORT1_RSCLK, .offset = 10},
235 {.res = P_SPORT1_RFS, .offset = 10},
236 {.res = P_SPORT1_DRPRI, .offset = 10},
237 {.res = P_PPI0_D8, .offset = 9},
238 {.res = P_PPI0_D9, .offset = 9},
239 {.res = P_SPORT1_DRSEC, .offset = 9},
240 {.res = P_SPORT1_DTSEC, .offset = 9},
241 {.res = P_TMR2, .offset = 8},
242 {.res = P_PPI0_FS3, .offset = 8},
243 {.res = P_TMR3, .offset = 7},
244 {.res = P_SPI0_SSEL4, .offset = 7},
245 {.res = P_TMR4, .offset = 6},
246 {.res = P_SPI0_SSEL5, .offset = 6},
247 {.res = P_TMR5, .offset = 5},
248 {.res = P_SPI0_SSEL6, .offset = 5},
249 {.res = P_UART1_RX, .offset = 4},
250 {.res = P_UART1_TX, .offset = 4},
251 {.res = P_TMR6, .offset = 4},
252 {.res = P_TMR7, .offset = 4},
253 {.res = P_UART0_RX, .offset = 3},
254 {.res = P_UART0_TX, .offset = 3},
255 {.res = P_DMAR0, .offset = 3},
256 {.res = P_DMAR1, .offset = 3},
257 {.res = P_SPORT0_DTSEC, .offset = 1},
258 {.res = P_SPORT0_DRSEC, .offset = 1},
259 {.res = P_CAN0_RX, .offset = 1},
260 {.res = P_CAN0_TX, .offset = 1},
261 {.res = P_SPI0_SSEL7, .offset = 1},
262 {.res = P_SPORT0_TFS, .offset = 0},
263 {.res = P_SPORT0_DTPRI, .offset = 0},
264 {.res = P_SPI0_SSEL2, .offset = 0},
265 {.res = P_SPI0_SSEL3, .offset = 0},
266};
267
268static void portmux_setup(unsigned short per)
269{
270 u16 y, offset, muxreg;
271 u16 function = P_FUNCT2MUX(per);
272
273 for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
274 if (port_mux_lut[y].res == per) {
275
276 /* SET PORTMUX REG */
277
278 offset = port_mux_lut[y].offset;
279 muxreg = bfin_read_PORT_MUX();
280
281 if (offset != 1)
282 muxreg &= ~(1 << offset);
283 else
284 muxreg &= ~(3 << 1);
285
286 muxreg |= (function << offset);
287 bfin_write_PORT_MUX(muxreg);
288 }
289 }
290}
291#elif defined(CONFIG_BF54x)
292inline void portmux_setup(unsigned short per)
293{
294 u32 pmux;
295 u16 ident = P_IDENT(per);
296 u16 function = P_FUNCT2MUX(per);
297
298 pmux = gpio_array[gpio_bank(ident)]->port_mux;
299
300 pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
301 pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
302
303 gpio_array[gpio_bank(ident)]->port_mux = pmux;
304}
305
306inline u16 get_portmux(unsigned short per)
307{
308 u32 pmux;
309 u16 ident = P_IDENT(per);
310
311 pmux = gpio_array[gpio_bank(ident)]->port_mux;
312
313 return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
314}
315#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
316inline void portmux_setup(unsigned short per)
317{
318 u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
319 u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
320
321 pmux = *port_mux[gpio_bank(ident)];
322 pmux &= ~(3 << offset);
323 pmux |= (function & 3) << offset;
324 *port_mux[gpio_bank(ident)] = pmux;
325 SSYNC();
326}
327#else
328# define portmux_setup(...) do { } while (0)
329#endif
330
331#ifndef CONFIG_BF54x
332/***********************************************************
333*
334* FUNCTIONS: Blackfin General Purpose Ports Access Functions
335*
336* INPUTS/OUTPUTS:
337* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
338*
339*
340* DESCRIPTION: These functions abstract direct register access
341* to Blackfin processor General Purpose
342* Ports Regsiters
343*
344* CAUTION: These functions do not belong to the GPIO Driver API
345*************************************************************
346* MODIFICATION HISTORY :
347**************************************************************/
348
349/* Set a specific bit */
350
351#define SET_GPIO(name) \
352void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
353{ \
354 unsigned long flags; \
355 local_irq_save(flags); \
356 if (arg) \
357 gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
358 else \
359 gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
360 AWA_DUMMY_READ(name); \
361 local_irq_restore(flags); \
362}
363
364SET_GPIO(dir) /* set_gpio_dir() */
365SET_GPIO(inen) /* set_gpio_inen() */
366SET_GPIO(polar) /* set_gpio_polar() */
367SET_GPIO(edge) /* set_gpio_edge() */
368SET_GPIO(both) /* set_gpio_both() */
369
370
371#define SET_GPIO_SC(name) \
372void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
373{ \
374 unsigned long flags; \
375 if (ANOMALY_05000311 || ANOMALY_05000323) \
376 local_irq_save(flags); \
377 if (arg) \
378 gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
379 else \
380 gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
381 if (ANOMALY_05000311 || ANOMALY_05000323) { \
382 AWA_DUMMY_READ(name); \
383 local_irq_restore(flags); \
384 } \
385}
386
387SET_GPIO_SC(maska)
388SET_GPIO_SC(maskb)
389SET_GPIO_SC(data)
390
391void set_gpio_toggle(unsigned gpio)
392{
393 unsigned long flags;
394 if (ANOMALY_05000311 || ANOMALY_05000323)
395 local_irq_save(flags);
396 gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
397 if (ANOMALY_05000311 || ANOMALY_05000323) {
398 AWA_DUMMY_READ(toggle);
399 local_irq_restore(flags);
400 }
401}
402
403/* Set current PORT date (16-bit word) */
404
405#define SET_GPIO_P(name) \
406void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
407{ \
408 unsigned long flags; \
409 if (ANOMALY_05000311 || ANOMALY_05000323) \
410 local_irq_save(flags); \
411 gpio_array[gpio_bank(gpio)]->name = arg; \
412 if (ANOMALY_05000311 || ANOMALY_05000323) { \
413 AWA_DUMMY_READ(name); \
414 local_irq_restore(flags); \
415 } \
416}
417
418SET_GPIO_P(data)
419SET_GPIO_P(dir)
420SET_GPIO_P(inen)
421SET_GPIO_P(polar)
422SET_GPIO_P(edge)
423SET_GPIO_P(both)
424SET_GPIO_P(maska)
425SET_GPIO_P(maskb)
426
427/* Get a specific bit */
428#define GET_GPIO(name) \
429unsigned short get_gpio_ ## name(unsigned gpio) \
430{ \
431 unsigned long flags; \
432 unsigned short ret; \
433 if (ANOMALY_05000311 || ANOMALY_05000323) \
434 local_irq_save(flags); \
435 ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
436 if (ANOMALY_05000311 || ANOMALY_05000323) { \
437 AWA_DUMMY_READ(name); \
438 local_irq_restore(flags); \
439 } \
440 return ret; \
441}
442
443GET_GPIO(data)
444GET_GPIO(dir)
445GET_GPIO(inen)
446GET_GPIO(polar)
447GET_GPIO(edge)
448GET_GPIO(both)
449GET_GPIO(maska)
450GET_GPIO(maskb)
451
452/* Get current PORT date (16-bit word) */
453
454#define GET_GPIO_P(name) \
455unsigned short get_gpiop_ ## name(unsigned gpio) \
456{ \
457 unsigned long flags; \
458 unsigned short ret; \
459 if (ANOMALY_05000311 || ANOMALY_05000323) \
460 local_irq_save(flags); \
461 ret = (gpio_array[gpio_bank(gpio)]->name); \
462 if (ANOMALY_05000311 || ANOMALY_05000323) { \
463 AWA_DUMMY_READ(name); \
464 local_irq_restore(flags); \
465 } \
466 return ret; \
467}
468
469GET_GPIO_P(data)
470GET_GPIO_P(dir)
471GET_GPIO_P(inen)
472GET_GPIO_P(polar)
473GET_GPIO_P(edge)
474GET_GPIO_P(both)
475GET_GPIO_P(maska)
476GET_GPIO_P(maskb)
477
478#else /* CONFIG_BF54x */
479
480unsigned short get_gpio_dir(unsigned gpio)
481{
482 return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)));
483}
484
485#endif /* CONFIG_BF54x */
486
487/***********************************************************
488*
489* FUNCTIONS: Blackfin Peripheral Resource Allocation
490* and PortMux Setup
491*
492* INPUTS/OUTPUTS:
493* per Peripheral Identifier
494* label String
495*
496* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
497*
498* CAUTION:
499*************************************************************
500* MODIFICATION HISTORY :
501**************************************************************/
502
503int peripheral_request(unsigned short per, const char *label)
504{
505 unsigned short ident = P_IDENT(per);
506
507 /*
508 * Don't cares are pins with only one dedicated function
509 */
510
511 if (per & P_DONTCARE)
512 return 0;
513
514 if (!(per & P_DEFINED))
515 return -ENODEV;
516
517 BUG_ON(ident >= MAX_RESOURCES);
518
519 /* If a pin can be muxed as either GPIO or peripheral, make
520 * sure it is not already a GPIO pin when we request it.
521 */
522 if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
523 printf("%s: Peripheral %d is already reserved as GPIO by %s !\n",
524 __func__, ident, get_label(ident));
525 return -EBUSY;
526 }
527
528 if (unlikely(is_reserved(peri, ident, 1))) {
529
530 /*
531 * Pin functions like AMC address strobes my
532 * be requested and used by several drivers
533 */
534
535#ifdef CONFIG_BF54x
536 if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
537#else
538 if (!(per & P_MAYSHARE)) {
539#endif
540 /*
541 * Allow that the identical pin function can
542 * be requested from the same driver twice
543 */
544
545 if (cmp_label(ident, label) == 0)
546 goto anyway;
547
548 printf("%s: Peripheral %d function %d is already reserved by %s !\n",
549 __func__, ident, P_FUNCT2MUX(per), get_label(ident));
550 return -EBUSY;
551 }
552 }
553
554 anyway:
555 reserve(peri, ident);
556
557 portmux_setup(per);
558 port_setup(ident, PERIPHERAL_USAGE);
559
560 set_label(ident, label);
561
562 return 0;
563}
564
565int peripheral_request_list(const unsigned short per[], const char *label)
566{
567 u16 cnt;
568 int ret;
569
570 for (cnt = 0; per[cnt] != 0; cnt++) {
571
572 ret = peripheral_request(per[cnt], label);
573
574 if (ret < 0) {
575 for ( ; cnt > 0; cnt--)
576 peripheral_free(per[cnt - 1]);
577
578 return ret;
579 }
580 }
581
582 return 0;
583}
584
585void peripheral_free(unsigned short per)
586{
587 unsigned short ident = P_IDENT(per);
588
589 if (per & P_DONTCARE)
590 return;
591
592 if (!(per & P_DEFINED))
593 return;
594
595 if (unlikely(!is_reserved(peri, ident, 0)))
596 return;
597
598 if (!(per & P_MAYSHARE))
599 port_setup(ident, GPIO_USAGE);
600
601 unreserve(peri, ident);
602
603 set_label(ident, "free");
604}
605
606void peripheral_free_list(const unsigned short per[])
607{
608 u16 cnt;
609 for (cnt = 0; per[cnt] != 0; cnt++)
610 peripheral_free(per[cnt]);
611}
612
613/***********************************************************
614*
615* FUNCTIONS: Blackfin GPIO Driver
616*
617* INPUTS/OUTPUTS:
618* gpio PIO Number between 0 and MAX_BLACKFIN_GPIOS
619* label String
620*
621* DESCRIPTION: Blackfin GPIO Driver API
622*
623* CAUTION:
624*************************************************************
625* MODIFICATION HISTORY :
626**************************************************************/
627
628int bfin_gpio_request(unsigned gpio, const char *label)
629{
630 if (check_gpio(gpio) < 0)
631 return -EINVAL;
632
633 /*
634 * Allow that the identical GPIO can
635 * be requested from the same driver twice
636 * Do nothing and return -
637 */
638
639 if (cmp_label(gpio, label) == 0)
640 return 0;
641
642 if (unlikely(is_reserved(gpio, gpio, 1))) {
643 printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
644 gpio, get_label(gpio));
645 return -EBUSY;
646 }
647 if (unlikely(is_reserved(peri, gpio, 1))) {
648 printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
649 gpio, get_label(gpio));
650 return -EBUSY;
651 }
652#ifndef CONFIG_BF54x
653 else { /* Reset POLAR setting when acquiring a gpio for the first time */
654 set_gpio_polar(gpio, 0);
655 }
656#endif
657
658 reserve(gpio, gpio);
659 set_label(gpio, label);
660
661 port_setup(gpio, GPIO_USAGE);
662
663 return 0;
664}
665
666void bfin_gpio_free(unsigned gpio)
667{
668 if (check_gpio(gpio) < 0)
669 return;
670
671 if (unlikely(!is_reserved(gpio, gpio, 0))) {
672 gpio_error(gpio);
673 return;
674 }
675
676 unreserve(gpio, gpio);
677
678 set_label(gpio, "free");
679}
680
681#ifdef BFIN_SPECIAL_GPIO_BANKS
682DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
683
684int bfin_special_gpio_request(unsigned gpio, const char *label)
685{
686 /*
687 * Allow that the identical GPIO can
688 * be requested from the same driver twice
689 * Do nothing and return -
690 */
691
692 if (cmp_label(gpio, label) == 0)
693 return 0;
694
695 if (unlikely(is_reserved(special_gpio, gpio, 1))) {
696 printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
697 gpio, get_label(gpio));
698 return -EBUSY;
699 }
700 if (unlikely(is_reserved(peri, gpio, 1))) {
701 printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
702 gpio, get_label(gpio));
703
704 return -EBUSY;
705 }
706
707 reserve(special_gpio, gpio);
708 reserve(peri, gpio);
709
710 set_label(gpio, label);
711 port_setup(gpio, GPIO_USAGE);
712
713 return 0;
714}
715
716void bfin_special_gpio_free(unsigned gpio)
717{
718 if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
719 gpio_error(gpio);
720 return;
721 }
722
723 reserve(special_gpio, gpio);
724 reserve(peri, gpio);
725 set_label(gpio, "free");
726}
727#endif
728
729static inline void __bfin_gpio_direction_input(unsigned gpio)
730{
731#ifdef CONFIG_BF54x
732 gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
733#else
734 gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
735#endif
736 gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
737}
738
739int bfin_gpio_direction_input(unsigned gpio)
740{
741 unsigned long flags;
742
743 if (!is_reserved(gpio, gpio, 0)) {
744 gpio_error(gpio);
745 return -EINVAL;
746 }
747
748 local_irq_save(flags);
749 __bfin_gpio_direction_input(gpio);
750 AWA_DUMMY_READ(inen);
751 local_irq_restore(flags);
752
753 return 0;
754}
755
756void bfin_gpio_toggle_value(unsigned gpio)
757{
758#ifdef CONFIG_BF54x
759 gpio_set_value(gpio, !gpio_get_value(gpio));
760#else
761 gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
762#endif
763}
764
765void bfin_gpio_set_value(unsigned gpio, int arg)
766{
767 if (arg)
768 gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
769 else
770 gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
771}
772
773int bfin_gpio_direction_output(unsigned gpio, int value)
774{
775 unsigned long flags;
776
777 if (!is_reserved(gpio, gpio, 0)) {
778 gpio_error(gpio);
779 return -EINVAL;
780 }
781
782 local_irq_save(flags);
783
784 gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
785 gpio_set_value(gpio, value);
786#ifdef CONFIG_BF54x
787 gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
788#else
789 gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
790#endif
791
792 AWA_DUMMY_READ(dir);
793 local_irq_restore(flags);
794
795 return 0;
796}
797
798int bfin_gpio_get_value(unsigned gpio)
799{
800#ifdef CONFIG_BF54x
801 return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
802#else
803 unsigned long flags;
804
805 if (unlikely(get_gpio_edge(gpio))) {
806 int ret;
807 local_irq_save(flags);
808 set_gpio_edge(gpio, 0);
809 ret = get_gpio_data(gpio);
810 set_gpio_edge(gpio, 1);
811 local_irq_restore(flags);
812 return ret;
813 } else
814 return get_gpio_data(gpio);
815#endif
816}
817
818/* If we are booting from SPI and our board lacks a strong enough pull up,
819 * the core can reset and execute the bootrom faster than the resistor can
820 * pull the signal logically high. To work around this (common) error in
821 * board design, we explicitly set the pin back to GPIO mode, force /CS
822 * high, and wait for the electrons to do their thing.
823 *
824 * This function only makes sense to be called from reset code, but it
825 * lives here as we need to force all the GPIO states w/out going through
826 * BUG() checks and such.
827 */
828void bfin_reset_boot_spi_cs(unsigned short pin)
829{
830 unsigned short gpio = P_IDENT(pin);
831 port_setup(gpio, GPIO_USAGE);
832 gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
833 AWA_DUMMY_READ(data_set);
834 udelay(1);
835}
836
837#ifdef CONFIG_BFIN_GPIO_TRACK
838void bfin_gpio_labels(void)
839{
840 int c, gpio;
841
842 for (c = 0; c < MAX_RESOURCES; c++) {
843 gpio = is_reserved(gpio, c, 1);
844 if (!check_gpio(c) && gpio)
845 printf("GPIO_%d:\t%s\tGPIO %s\n", c,
846 get_label(c),
847 get_gpio_dir(c) ? "OUTPUT" : "INPUT");
848 else if (is_reserved(peri, c, 1))
849 printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
850 else
851 continue;
852 }
853}
854#endif