Root/target/linux/ar71xx/files/arch/mips/ar71xx/gpio.c

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
23static DEFINE_SPINLOCK(ar71xx_gpio_lock);
24
25unsigned long ar71xx_gpio_count;
26EXPORT_SYMBOL(ar71xx_gpio_count);
27
28void __ar71xx_gpio_set_value(unsigned gpio, int value)
29{
30    void __iomem *base = ar71xx_gpio_base;
31
32    if (value)
33        __raw_writel(1 << gpio, base + GPIO_REG_SET);
34    else
35        __raw_writel(1 << gpio, base + GPIO_REG_CLEAR);
36}
37EXPORT_SYMBOL(__ar71xx_gpio_set_value);
38
39int __ar71xx_gpio_get_value(unsigned gpio)
40{
41    return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1;
42}
43EXPORT_SYMBOL(__ar71xx_gpio_get_value);
44
45static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
46{
47    return __ar71xx_gpio_get_value(offset);
48}
49
50static void ar71xx_gpio_set_value(struct gpio_chip *chip,
51                  unsigned offset, int value)
52{
53    __ar71xx_gpio_set_value(offset, value);
54}
55
56static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
57                       unsigned offset)
58{
59    void __iomem *base = ar71xx_gpio_base;
60    unsigned long flags;
61
62    spin_lock_irqsave(&ar71xx_gpio_lock, flags);
63
64    __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset),
65             base + GPIO_REG_OE);
66
67    spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
68
69    return 0;
70}
71
72static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
73                    unsigned offset, int value)
74{
75    void __iomem *base = ar71xx_gpio_base;
76    unsigned long flags;
77
78    spin_lock_irqsave(&ar71xx_gpio_lock, flags);
79
80    if (value)
81        __raw_writel(1 << offset, base + GPIO_REG_SET);
82    else
83        __raw_writel(1 << offset, base + GPIO_REG_CLEAR);
84
85    __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset),
86             base + GPIO_REG_OE);
87
88    spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
89
90    return 0;
91}
92
93static struct gpio_chip ar71xx_gpio_chip = {
94    .label = "ar71xx",
95    .get = ar71xx_gpio_get_value,
96    .set = ar71xx_gpio_set_value,
97    .direction_input = ar71xx_gpio_direction_input,
98    .direction_output = ar71xx_gpio_direction_output,
99    .base = 0,
100    .ngpio = AR71XX_GPIO_COUNT,
101};
102
103void ar71xx_gpio_function_enable(u32 mask)
104{
105    void __iomem *base = ar71xx_gpio_base;
106    unsigned long flags;
107
108    spin_lock_irqsave(&ar71xx_gpio_lock, flags);
109
110    __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask,
111             base + GPIO_REG_FUNC);
112    /* flush write */
113    (void) __raw_readl(base + GPIO_REG_FUNC);
114
115    spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
116}
117
118void ar71xx_gpio_function_disable(u32 mask)
119{
120    void __iomem *base = ar71xx_gpio_base;
121    unsigned long flags;
122
123    spin_lock_irqsave(&ar71xx_gpio_lock, flags);
124
125    __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask,
126             base + GPIO_REG_FUNC);
127    /* flush write */
128    (void) __raw_readl(base + GPIO_REG_FUNC);
129
130    spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
131}
132
133void ar71xx_gpio_function_setup(u32 set, u32 clear)
134{
135    void __iomem *base = ar71xx_gpio_base;
136    unsigned long flags;
137
138    spin_lock_irqsave(&ar71xx_gpio_lock, flags);
139
140    __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set,
141             base + GPIO_REG_FUNC);
142    /* flush write */
143    (void) __raw_readl(base + GPIO_REG_FUNC);
144
145    spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
146}
147EXPORT_SYMBOL(ar71xx_gpio_function_setup);
148
149void __init ar71xx_gpio_init(void)
150{
151    int err;
152
153    if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
154                "AR71xx GPIO controller"))
155        panic("cannot allocate AR71xx GPIO registers page");
156
157    switch (ar71xx_soc) {
158    case AR71XX_SOC_AR7130:
159    case AR71XX_SOC_AR7141:
160    case AR71XX_SOC_AR7161:
161        ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
162        break;
163
164    case AR71XX_SOC_AR7240:
165    case AR71XX_SOC_AR7241:
166    case AR71XX_SOC_AR7242:
167        ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT;
168        break;
169
170    case AR71XX_SOC_AR9130:
171    case AR71XX_SOC_AR9132:
172        ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
173        break;
174
175    case AR71XX_SOC_AR9330:
176    case AR71XX_SOC_AR9331:
177        ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT;
178        break;
179
180    case AR71XX_SOC_AR9341:
181    case AR71XX_SOC_AR9342:
182    case AR71XX_SOC_AR9344:
183        ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT;
184        break;
185
186    default:
187        BUG();
188    }
189
190    err = gpiochip_add(&ar71xx_gpio_chip);
191    if (err)
192        panic("cannot add AR71xx GPIO chip, error=%d", err);
193}
194

Archive Download this file



interactive