source: src/linux/universal/linux-3.3/arch/mips/ar7240/gpio_driver.c @ 18866

Last change on this file since 18866 was 18866, checked in by BrainSlayer, 14 months ago

gpio polarity change for 2.4 ghz wireless

File size: 10.6 KB
Line 
1/*
2 *  Atheros AR7XXX/AR9XXX SoC GPIO API support
3 *
4 *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 *  This program is free software; you can redistribute it and/or modify it
8 *  under the terms of the GNU General Public License version 2 as published
9 *  by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/spinlock.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/gpio.h>
20
21#include <asm/mach-ar71xx/ar71xx.h>
22#include "dev-leds-gpio.h"
23
24static DEFINE_SPINLOCK(ar71xx_gpio_lock);
25
26void set_wl0_gpio(int gpio,int val);
27void set_wl1_gpio(int gpio,int val);
28
29unsigned long ar71xx_gpio_count;
30EXPORT_SYMBOL(ar71xx_gpio_count);
31
32void __ar71xx_gpio_set_value(unsigned gpio, int value)
33{
34        void __iomem *base = ar71xx_gpio_base;
35        if (gpio>=32)
36            {
37            set_wl0_gpio(gpio-32,value);
38            return;
39            }
40        if (value)
41                __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
42        else
43                __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
44}
45EXPORT_SYMBOL(__ar71xx_gpio_set_value);
46
47int __ar71xx_gpio_get_value(unsigned gpio)
48{
49        if (gpio>=32)
50            return 0;
51        return (__raw_readl(ar71xx_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
52}
53EXPORT_SYMBOL(__ar71xx_gpio_get_value);
54
55static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
56{
57        return __ar71xx_gpio_get_value(offset);
58}
59
60static void ar71xx_gpio_set_value(struct gpio_chip *chip,
61                                  unsigned offset, int value)
62{
63        __ar71xx_gpio_set_value(offset, value);
64}
65
66static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
67                                       unsigned offset)
68{
69        void __iomem *base = ar71xx_gpio_base;
70        unsigned long flags;
71        if (offset>=32)
72            return 0;
73
74        spin_lock_irqsave(&ar71xx_gpio_lock, flags);
75
76#ifdef CONFIG_WASP_SUPPORT
77        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
78                     base + AR71XX_GPIO_REG_OE);
79
80#else
81        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
82                     base + AR71XX_GPIO_REG_OE);
83#endif
84        spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
85
86        return 0;
87}
88
89static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
90                                        unsigned offset, int value)
91{
92        void __iomem *base = ar71xx_gpio_base;
93        unsigned long flags;
94        if (offset>=32)
95            {
96            set_wl0_gpio(offset-32,value);
97            return 0;
98            }
99
100        spin_lock_irqsave(&ar71xx_gpio_lock, flags);
101
102        if (value)
103                __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
104        else
105                __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
106#ifdef CONFIG_WASP_SUPPORT
107        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
108                     base + AR71XX_GPIO_REG_OE);
109
110#else
111        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
112                     base + AR71XX_GPIO_REG_OE);
113
114
115#endif
116        spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
117
118        return 0;
119}
120
121static struct gpio_chip ar71xx_gpio_chip = {
122        .label                  = "ar71xx",
123        .get                    = ar71xx_gpio_get_value,
124        .set                    = ar71xx_gpio_set_value,
125        .direction_input        = ar71xx_gpio_direction_input,
126        .direction_output       = ar71xx_gpio_direction_output,
127        .base                   = 0,
128        .ngpio                  = AR71XX_GPIO_COUNT,
129};
130
131void ar71xx_gpio_function_enable(u32 mask)
132{
133        void __iomem *base = ar71xx_gpio_base;
134        unsigned long flags;
135
136        spin_lock_irqsave(&ar71xx_gpio_lock, flags);
137
138        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
139                     base + AR71XX_GPIO_REG_FUNC);
140        /* flush write */
141        (void) __raw_readl(base + AR71XX_GPIO_REG_FUNC);
142
143        spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
144}
145
146void ar71xx_gpio_function_disable(u32 mask)
147{
148        void __iomem *base = ar71xx_gpio_base;
149        unsigned long flags;
150
151        spin_lock_irqsave(&ar71xx_gpio_lock, flags);
152
153        __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
154                     base + AR71XX_GPIO_REG_FUNC);
155        /* flush write */
156        (void) __raw_readl(base + AR71XX_GPIO_REG_FUNC);
157
158        spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
159}
160
161void ar71xx_gpio_function_setup(u32 set, u32 clear)
162{
163        void __iomem *base = ar71xx_gpio_base;
164        unsigned long flags;
165
166        spin_lock_irqsave(&ar71xx_gpio_lock, flags);
167
168        __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
169                     base + AR71XX_GPIO_REG_FUNC);
170        /* flush write */
171        (void) __raw_readl(base + AR71XX_GPIO_REG_FUNC);
172
173        spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
174}
175EXPORT_SYMBOL(ar71xx_gpio_function_setup);
176
177static struct gpio_led generic_leds_gpio[] __initdata = {
178        {
179                .name           = "generic_0",
180                .gpio           = 0,
181                .active_low     = 0,
182        },
183        {
184                .name           = "generic_1",
185                .gpio           = 1,
186                .active_low     = 0,
187        },
188        {
189                .name           = "generic_2",
190                .gpio           = 2,
191                .active_low     = 0,
192        },
193        {
194                .name           = "generic_3",
195                .gpio           = 3,
196                .active_low     = 0,
197        },
198        {
199                .name           = "generic_4",
200                .gpio           = 4,
201                .active_low     = 0,
202        },
203        {
204                .name           = "generic_5",
205                .gpio           = 5,
206                .active_low     = 0,
207        },
208        {
209                .name           = "generic_6",
210                .gpio           = 6,
211                .active_low     = 0,
212        },
213        {
214                .name           = "generic_7",
215                .gpio           = 7,
216                .active_low     = 0,
217        },
218        {
219                .name           = "generic_8",
220                .gpio           = 8,
221                .active_low     = 0,
222        },
223        {
224                .name           = "generic_9",
225                .gpio           = 9,
226                .active_low     = 0,
227        },
228        {
229                .name           = "generic_10",
230                .gpio           = 10,
231                .active_low     = 0,
232        },
233        {
234                .name           = "generic_11",
235                .gpio           = 11,
236                .active_low     = 0,
237        },
238        {
239                .name           = "generic_12",
240                .gpio           = 12,
241                .active_low     = 0,
242        },
243#if defined(CONFIG_DIR825C1)
244        {
245                .name           = "generic_13",
246                .gpio           = 13,
247                .active_low     = 1,
248        },
249#else
250        {
251                .name           = "generic_13",
252                .gpio           = 13,
253                .active_low     = 0,
254        },
255#endif
256        {
257                .name           = "generic_14",
258                .gpio           = 14,
259                .active_low     = 0,
260        },
261        {
262                .name           = "generic_15",
263                .gpio           = 15,
264                .active_low     = 0,
265        },
266        {
267                .name           = "generic_16",
268                .gpio           = 16,
269                .active_low     = 0,
270        },
271#if defined(CONFIG_MACH_HORNET) && defined(CONFIG_WR741)
272        {
273                .name           = "generic_17",
274                .gpio           = 17,
275                .active_low     = 1,
276        },
277#else
278        {
279                .name           = "generic_17",
280                .gpio           = 17,
281                .active_low     = 0,
282        },
283#endif
284        {
285                .name           = "generic_18",
286                .gpio           = 18,
287                .active_low     = 0,
288        },
289        {
290                .name           = "generic_19",
291                .gpio           = 19,
292                .active_low     = 0,
293        },
294        {
295                .name           = "generic_20",
296                .gpio           = 20,
297                .active_low     = 0,
298        },
299        {
300                .name           = "generic_21",
301                .gpio           = 21,
302                .active_low     = 0,
303        },
304        {
305                .name           = "generic_22",
306                .gpio           = 22,
307                .active_low     = 0,
308        },
309        {
310                .name           = "generic_23",
311                .gpio           = 23,
312                .active_low     = 0,
313        },
314        {
315                .name           = "generic_24",
316                .gpio           = 24,
317                .active_low     = 0,
318        },
319        {
320                .name           = "generic_25",
321                .gpio           = 25,
322                .active_low     = 0,
323        },
324        {
325                .name           = "generic_26",
326                .gpio           = 26,
327                .active_low     = 0,
328        },
329        {
330                .name           = "generic_27",
331                .gpio           = 27,
332                .active_low     = 0,
333        },
334        {
335                .name           = "generic_28",
336                .gpio           = 28,
337                .active_low     = 0,
338        },
339        {
340                .name           = "generic_29",
341                .gpio           = 29,
342                .active_low     = 0,
343        },
344        {
345                .name           = "generic_30",
346                .gpio           = 30,
347                .active_low     = 0,
348        },
349        {
350                .name           = "generic_31",
351                .gpio           = 31,
352                .active_low     = 0,
353        },
354
355//wl gpios
356#ifndef CONFIG_MACH_HORNET
357
358        {
359                .name           = "wireless_generic_0",
360                .gpio           = 32,
361                .active_low     = 1,
362        },
363        {
364                .name           = "wireless_generic_1",
365                .gpio           = 33,
366                .active_low     = 1,
367        },
368        {
369                .name           = "wireless_generic_2",
370                .gpio           = 34,
371                .active_low     = 1,
372        },
373        {
374                .name           = "wireless_generic_3",
375                .gpio           = 35,
376                .active_low     = 1,
377        },
378        {
379                .name           = "wireless_generic_4",
380                .gpio           = 36,
381                .active_low     = 1,
382        },
383        {
384                .name           = "wireless_generic_5",
385                .gpio           = 37,
386                .active_low     = 1,
387        },
388        {
389                .name           = "wireless_generic_6",
390                .gpio           = 38,
391                .active_low     = 1,
392        },
393        {
394                .name           = "wireless_generic_7",
395                .gpio           = 39,
396                .active_low     = 1,
397        },
398        {
399                .name           = "wireless_generic_8",
400                .gpio           = 40,
401                .active_low     = 1,
402        },
403        {
404                .name           = "wireless_generic_9",
405                .gpio           = 41,
406                .active_low     = 1,
407        },
408        {
409                .name           = "wireless_generic_10",
410                .gpio           = 42,
411                .active_low     = 1,
412        },
413        {
414                .name           = "wireless_generic_11",
415                .gpio           = 43,
416                .active_low     = 1,
417        },
418        {
419                .name           = "wireless_generic_12",
420                .gpio           = 44,
421                .active_low     = 1,
422        },
423        {
424                .name           = "wireless_generic_13",
425                .gpio           = 45,
426                .active_low     = 1,
427        },
428        {
429                .name           = "wireless_generic_14",
430                .gpio           = 46,
431                .active_low     = 1,
432        },
433        {
434                .name           = "wireless_generic_15",
435                .gpio           = 47,
436                .active_low     = 1,
437        },
438#if 0
439        {
440                .name           = "wireless_generic_16",
441                .gpio           = 48,
442                .active_low     = 0,
443        },
444        {
445                .name           = "wireless_generic_17",
446                .gpio           = 49,
447                .active_low     = 0,
448        },
449        {
450                .name           = "wireless_generic_18",
451                .gpio           = 50,
452                .active_low     = 0,
453        },
454        {
455                .name           = "wireless_generic_19",
456                .gpio           = 51,
457                .active_low     = 0,
458        },
459        {
460                .name           = "wireless_generic_20",
461                .gpio           = 52,
462                .active_low     = 0,
463        },
464        {
465                .name           = "wireless_generic_21",
466                .gpio           = 53,
467                .active_low     = 0,
468        },
469        {
470                .name           = "wireless_generic_22",
471                .gpio           = 54,
472                .active_low     = 0,
473        },
474        {
475                .name           = "wireless_generic_23",
476                .gpio           = 55,
477                .active_low     = 0,
478        },
479        {
480                .name           = "wireless_generic_24",
481                .gpio           = 56,
482                .active_low     = 0,
483        },
484        {
485                .name           = "wireless_generic_25",
486                .gpio           = 57,
487                .active_low     = 0,
488        },
489        {
490                .name           = "wireless_generic_26",
491                .gpio           = 58,
492                .active_low     = 0,
493        },
494        {
495                .name           = "wireless_generic_27",
496                .gpio           = 59,
497                .active_low     = 0,
498        },
499        {
500                .name           = "wireless_generic_28",
501                .gpio           = 60,
502                .active_low     = 0,
503        },
504        {
505                .name           = "wireless_generic_29",
506                .gpio           = 61,
507                .active_low     = 0,
508        },
509        {
510                .name           = "wireless_generic_30",
511                .gpio           = 62,
512                .active_low     = 0,
513        },
514        {
515                .name           = "wireless_generic_31",
516                .gpio           = 63,
517                .active_low     = 0,
518        },
519#endif
520#endif
521};
522
523void serial_print(char *fmt, ...);
524
525void __init ar71xx_gpio_init(void)
526{
527        int err;
528        u32 t;
529
530        if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
531                                "AR71xx GPIO controller"))
532                panic("cannot allocate AR71xx GPIO registers page");
533
534        ar71xx_gpio_chip.ngpio = sizeof(generic_leds_gpio)/sizeof(struct gpio_led);
535
536        err = gpiochip_add(&ar71xx_gpio_chip);
537        if (err)
538                panic("cannot add AR71xx GPIO chip, error=%d", err);
539        int i;
540        for (i=0;i<sizeof(generic_leds_gpio)/sizeof(struct gpio_led);i++) {
541                generic_leds_gpio[i].default_state = LEDS_GPIO_DEFSTATE_KEEP;
542        }
543        ar71xx_add_device_leds_gpio(-1,sizeof(generic_leds_gpio)/sizeof(struct gpio_led),generic_leds_gpio);
544#ifdef CONFIG_WR741
545printk(KERN_INFO "fixup WR741 Switch LED's\n");
546#ifdef CONFIG_MACH_HORNET
547        ar71xx_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
548                                     AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
549                                     AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
550                                     AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
551                                     AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
552#else
553        ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
554                                     AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
555                                     AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
556                                     AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
557                                     AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
558
559#endif
560
561#endif
562
563#ifdef CONFIG_MACH_HORNET
564        t = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
565        t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN;
566        ar71xx_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t);
567//      gpio_request(26, "USB power");
568//      gpio_direction_output(26, 1);
569#endif
570}
Note: See TracBrowser for help on using the repository browser.