source: src/linux/universal/linux-3.2/arch/mips/ar7240/gpio_driver.c @ 18312

Last change on this file since 18312 was 18312, checked in by BrainSlayer, 17 months ago

usb support for hornet devices

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