1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * ADI GPIO2 Abstraction Layer
3*4882a593Smuzhiyun * Support BF54x, BF60x and future processors.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2008-2013 Analog Devices Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Licensed under the GPL-2 or later
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <asm/gpio.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define RESOURCE_LABEL_SIZE 16
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun static struct str_ident {
17*4882a593Smuzhiyun char name[RESOURCE_LABEL_SIZE];
18*4882a593Smuzhiyun } str_ident[MAX_RESOURCES];
19*4882a593Smuzhiyun
gpio_error(unsigned gpio)20*4882a593Smuzhiyun static void gpio_error(unsigned gpio)
21*4882a593Smuzhiyun {
22*4882a593Smuzhiyun printf("adi_gpio2: GPIO %d wasn't requested!\n", gpio);
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun
set_label(unsigned short ident,const char * label)25*4882a593Smuzhiyun static void set_label(unsigned short ident, const char *label)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun if (label) {
28*4882a593Smuzhiyun strncpy(str_ident[ident].name, label,
29*4882a593Smuzhiyun RESOURCE_LABEL_SIZE);
30*4882a593Smuzhiyun str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun
get_label(unsigned short ident)34*4882a593Smuzhiyun static char *get_label(unsigned short ident)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun return *str_ident[ident].name ? str_ident[ident].name : "UNKNOWN";
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun
cmp_label(unsigned short ident,const char * label)39*4882a593Smuzhiyun static int cmp_label(unsigned short ident, const char *label)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun if (label == NULL)
42*4882a593Smuzhiyun printf("adi_gpio2: please provide none-null label\n");
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun if (label)
45*4882a593Smuzhiyun return strcmp(str_ident[ident].name, label);
46*4882a593Smuzhiyun else
47*4882a593Smuzhiyun return -EINVAL;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun #define map_entry(m, i) reserved_##m##_map[gpio_bank(i)]
51*4882a593Smuzhiyun #define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
52*4882a593Smuzhiyun #define reserve(m, i) (map_entry(m, i) |= gpio_bit(i))
53*4882a593Smuzhiyun #define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i))
54*4882a593Smuzhiyun #define DECLARE_RESERVED_MAP(m, c) unsigned short reserved_##m##_map[c]
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun static DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
57*4882a593Smuzhiyun static DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
58*4882a593Smuzhiyun
check_gpio(unsigned gpio)59*4882a593Smuzhiyun inline int check_gpio(unsigned gpio)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun #if defined(CONFIG_BF54x)
62*4882a593Smuzhiyun if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 ||
63*4882a593Smuzhiyun gpio == GPIO_PH14 || gpio == GPIO_PH15 ||
64*4882a593Smuzhiyun gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
65*4882a593Smuzhiyun return -EINVAL;
66*4882a593Smuzhiyun #endif
67*4882a593Smuzhiyun if (gpio >= MAX_GPIOS)
68*4882a593Smuzhiyun return -EINVAL;
69*4882a593Smuzhiyun return 0;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
port_setup(unsigned gpio,unsigned short usage)72*4882a593Smuzhiyun static void port_setup(unsigned gpio, unsigned short usage)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun #if defined(CONFIG_BF54x)
75*4882a593Smuzhiyun if (usage == GPIO_USAGE)
76*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
77*4882a593Smuzhiyun else
78*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
79*4882a593Smuzhiyun #else
80*4882a593Smuzhiyun if (usage == GPIO_USAGE)
81*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio);
82*4882a593Smuzhiyun else
83*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio);
84*4882a593Smuzhiyun #endif
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
portmux_setup(unsigned short per)87*4882a593Smuzhiyun inline void portmux_setup(unsigned short per)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun u32 pmux;
90*4882a593Smuzhiyun u16 ident = P_IDENT(per);
91*4882a593Smuzhiyun u16 function = P_FUNCT2MUX(per);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun pmux = gpio_array[gpio_bank(ident)]->port_mux;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
96*4882a593Smuzhiyun pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun gpio_array[gpio_bank(ident)]->port_mux = pmux;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
get_portmux(unsigned short per)101*4882a593Smuzhiyun inline u16 get_portmux(unsigned short per)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun u32 pmux;
104*4882a593Smuzhiyun u16 ident = P_IDENT(per);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun pmux = gpio_array[gpio_bank(ident)]->port_mux;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun return pmux >> (2 * gpio_sub_n(ident)) & 0x3;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
get_gpio_dir(unsigned gpio)111*4882a593Smuzhiyun unsigned short get_gpio_dir(unsigned gpio)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun return 0x01 &
114*4882a593Smuzhiyun (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio));
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /***********************************************************
118*4882a593Smuzhiyun *
119*4882a593Smuzhiyun * FUNCTIONS: Peripheral Resource Allocation
120*4882a593Smuzhiyun * and PortMux Setup
121*4882a593Smuzhiyun *
122*4882a593Smuzhiyun * INPUTS/OUTPUTS:
123*4882a593Smuzhiyun * per Peripheral Identifier
124*4882a593Smuzhiyun * label String
125*4882a593Smuzhiyun *
126*4882a593Smuzhiyun * DESCRIPTION: Peripheral Resource Allocation and Setup API
127*4882a593Smuzhiyun **************************************************************/
128*4882a593Smuzhiyun
peripheral_request(unsigned short per,const char * label)129*4882a593Smuzhiyun int peripheral_request(unsigned short per, const char *label)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun unsigned short ident = P_IDENT(per);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /*
134*4882a593Smuzhiyun * Don't cares are pins with only one dedicated function
135*4882a593Smuzhiyun */
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (per & P_DONTCARE)
138*4882a593Smuzhiyun return 0;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun if (!(per & P_DEFINED))
141*4882a593Smuzhiyun return -EINVAL;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun BUG_ON(ident >= MAX_RESOURCES);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /* If a pin can be muxed as either GPIO or peripheral, make
146*4882a593Smuzhiyun * sure it is not already a GPIO pin when we request it.
147*4882a593Smuzhiyun */
148*4882a593Smuzhiyun if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
149*4882a593Smuzhiyun printf("%s: Peripheral %d is already reserved as GPIO by %s!\n",
150*4882a593Smuzhiyun __func__, ident, get_label(ident));
151*4882a593Smuzhiyun return -EBUSY;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun if (unlikely(is_reserved(peri, ident, 1))) {
155*4882a593Smuzhiyun /*
156*4882a593Smuzhiyun * Pin functions like AMC address strobes my
157*4882a593Smuzhiyun * be requested and used by several drivers
158*4882a593Smuzhiyun */
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if (!((per & P_MAYSHARE) &&
161*4882a593Smuzhiyun get_portmux(per) == P_FUNCT2MUX(per))) {
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun * Allow that the identical pin function can
164*4882a593Smuzhiyun * be requested from the same driver twice
165*4882a593Smuzhiyun */
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun if (cmp_label(ident, label) == 0)
168*4882a593Smuzhiyun goto anyway;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun printf("%s: Peripheral %d function %d is already "
171*4882a593Smuzhiyun "reserved by %s!\n", __func__, ident,
172*4882a593Smuzhiyun P_FUNCT2MUX(per), get_label(ident));
173*4882a593Smuzhiyun return -EBUSY;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun anyway:
178*4882a593Smuzhiyun reserve(peri, ident);
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun portmux_setup(per);
181*4882a593Smuzhiyun port_setup(ident, PERIPHERAL_USAGE);
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun set_label(ident, label);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun return 0;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
peripheral_request_list(const unsigned short per[],const char * label)188*4882a593Smuzhiyun int peripheral_request_list(const unsigned short per[], const char *label)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun u16 cnt;
191*4882a593Smuzhiyun int ret;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun for (cnt = 0; per[cnt] != 0; cnt++) {
194*4882a593Smuzhiyun ret = peripheral_request(per[cnt], label);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun if (ret < 0) {
197*4882a593Smuzhiyun for (; cnt > 0; cnt--)
198*4882a593Smuzhiyun peripheral_free(per[cnt - 1]);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun return ret;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun return 0;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
peripheral_free(unsigned short per)207*4882a593Smuzhiyun void peripheral_free(unsigned short per)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun unsigned short ident = P_IDENT(per);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (per & P_DONTCARE)
212*4882a593Smuzhiyun return;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun if (!(per & P_DEFINED))
215*4882a593Smuzhiyun return;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if (unlikely(!is_reserved(peri, ident, 0)))
218*4882a593Smuzhiyun return;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun if (!(per & P_MAYSHARE))
221*4882a593Smuzhiyun port_setup(ident, GPIO_USAGE);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun unreserve(peri, ident);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun set_label(ident, "free");
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
peripheral_free_list(const unsigned short per[])228*4882a593Smuzhiyun void peripheral_free_list(const unsigned short per[])
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun u16 cnt;
231*4882a593Smuzhiyun for (cnt = 0; per[cnt] != 0; cnt++)
232*4882a593Smuzhiyun peripheral_free(per[cnt]);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /***********************************************************
236*4882a593Smuzhiyun *
237*4882a593Smuzhiyun * FUNCTIONS: GPIO Driver
238*4882a593Smuzhiyun *
239*4882a593Smuzhiyun * INPUTS/OUTPUTS:
240*4882a593Smuzhiyun * gpio PIO Number between 0 and MAX_GPIOS
241*4882a593Smuzhiyun * label String
242*4882a593Smuzhiyun *
243*4882a593Smuzhiyun * DESCRIPTION: GPIO Driver API
244*4882a593Smuzhiyun **************************************************************/
245*4882a593Smuzhiyun
gpio_request(unsigned gpio,const char * label)246*4882a593Smuzhiyun int gpio_request(unsigned gpio, const char *label)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun if (check_gpio(gpio) < 0)
249*4882a593Smuzhiyun return -EINVAL;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun * Allow that the identical GPIO can
253*4882a593Smuzhiyun * be requested from the same driver twice
254*4882a593Smuzhiyun * Do nothing and return -
255*4882a593Smuzhiyun */
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun if (cmp_label(gpio, label) == 0)
258*4882a593Smuzhiyun return 0;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun if (unlikely(is_reserved(gpio, gpio, 1))) {
261*4882a593Smuzhiyun printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
262*4882a593Smuzhiyun gpio, get_label(gpio));
263*4882a593Smuzhiyun return -EBUSY;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun if (unlikely(is_reserved(peri, gpio, 1))) {
266*4882a593Smuzhiyun printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
267*4882a593Smuzhiyun "by %s!\n", gpio, get_label(gpio));
268*4882a593Smuzhiyun return -EBUSY;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun reserve(gpio, gpio);
272*4882a593Smuzhiyun set_label(gpio, label);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun port_setup(gpio, GPIO_USAGE);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun return 0;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
gpio_free(unsigned gpio)279*4882a593Smuzhiyun int gpio_free(unsigned gpio)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun if (check_gpio(gpio) < 0)
282*4882a593Smuzhiyun return -1;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (unlikely(!is_reserved(gpio, gpio, 0))) {
285*4882a593Smuzhiyun gpio_error(gpio);
286*4882a593Smuzhiyun return -1;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun unreserve(gpio, gpio);
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun set_label(gpio, "free");
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun return 0;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun #ifdef ADI_SPECIAL_GPIO_BANKS
297*4882a593Smuzhiyun static DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
298*4882a593Smuzhiyun
special_gpio_request(unsigned gpio,const char * label)299*4882a593Smuzhiyun int special_gpio_request(unsigned gpio, const char *label)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun /*
302*4882a593Smuzhiyun * Allow that the identical GPIO can
303*4882a593Smuzhiyun * be requested from the same driver twice
304*4882a593Smuzhiyun * Do nothing and return -
305*4882a593Smuzhiyun */
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (cmp_label(gpio, label) == 0)
308*4882a593Smuzhiyun return 0;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (unlikely(is_reserved(special_gpio, gpio, 1))) {
311*4882a593Smuzhiyun printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
312*4882a593Smuzhiyun gpio, get_label(gpio));
313*4882a593Smuzhiyun return -EBUSY;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun if (unlikely(is_reserved(peri, gpio, 1))) {
316*4882a593Smuzhiyun printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
317*4882a593Smuzhiyun "by %s!\n", gpio, get_label(gpio));
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun return -EBUSY;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun reserve(special_gpio, gpio);
323*4882a593Smuzhiyun reserve(peri, gpio);
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun set_label(gpio, label);
326*4882a593Smuzhiyun port_setup(gpio, GPIO_USAGE);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun return 0;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
special_gpio_free(unsigned gpio)331*4882a593Smuzhiyun void special_gpio_free(unsigned gpio)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
334*4882a593Smuzhiyun gpio_error(gpio);
335*4882a593Smuzhiyun return;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun unreserve(special_gpio, gpio);
339*4882a593Smuzhiyun unreserve(peri, gpio);
340*4882a593Smuzhiyun set_label(gpio, "free");
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun #endif
343*4882a593Smuzhiyun
__gpio_direction_input(unsigned gpio)344*4882a593Smuzhiyun static inline void __gpio_direction_input(unsigned gpio)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
347*4882a593Smuzhiyun #if defined(CONFIG_BF54x)
348*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
349*4882a593Smuzhiyun #else
350*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio);
351*4882a593Smuzhiyun #endif
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
gpio_direction_input(unsigned gpio)354*4882a593Smuzhiyun int gpio_direction_input(unsigned gpio)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun unsigned long flags;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (!is_reserved(gpio, gpio, 0)) {
359*4882a593Smuzhiyun gpio_error(gpio);
360*4882a593Smuzhiyun return -EINVAL;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun local_irq_save(flags);
364*4882a593Smuzhiyun __gpio_direction_input(gpio);
365*4882a593Smuzhiyun local_irq_restore(flags);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
gpio_set_value(unsigned gpio,int arg)370*4882a593Smuzhiyun int gpio_set_value(unsigned gpio, int arg)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun if (arg)
373*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
374*4882a593Smuzhiyun else
375*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun return 0;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
gpio_direction_output(unsigned gpio,int value)380*4882a593Smuzhiyun int gpio_direction_output(unsigned gpio, int value)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun unsigned long flags;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun if (!is_reserved(gpio, gpio, 0)) {
385*4882a593Smuzhiyun gpio_error(gpio);
386*4882a593Smuzhiyun return -EINVAL;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun local_irq_save(flags);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun #if defined(CONFIG_BF54x)
392*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
393*4882a593Smuzhiyun #else
394*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio);
395*4882a593Smuzhiyun #endif
396*4882a593Smuzhiyun gpio_set_value(gpio, value);
397*4882a593Smuzhiyun gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun local_irq_restore(flags);
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun return 0;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
gpio_get_value(unsigned gpio)404*4882a593Smuzhiyun int gpio_get_value(unsigned gpio)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun return 1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
gpio_labels(void)409*4882a593Smuzhiyun void gpio_labels(void)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun int c, gpio;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun for (c = 0; c < MAX_RESOURCES; c++) {
414*4882a593Smuzhiyun gpio = is_reserved(gpio, c, 1);
415*4882a593Smuzhiyun if (!check_gpio(c) && gpio)
416*4882a593Smuzhiyun printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c),
417*4882a593Smuzhiyun get_gpio_dir(c) ? "OUTPUT" : "INPUT");
418*4882a593Smuzhiyun else if (is_reserved(peri, c, 1))
419*4882a593Smuzhiyun printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
420*4882a593Smuzhiyun else
421*4882a593Smuzhiyun continue;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun }
424