Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gpio.c
Go to the documentation of this file.
1 /*
2  * Atheros AR71XX/AR724X/AR913X GPIO API support
3  *
4  * Copyright (C) 2010-2011 Jaiganesh Narayanan <[email protected]>
5  * Copyright (C) 2008-2011 Gabor Juhos <[email protected]>
6  * Copyright (C) 2008 Imre Kaloz <[email protected]>
7  *
8  * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published
12  * by the Free Software Foundation.
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/spinlock.h>
20 #include <linux/io.h>
21 #include <linux/ioport.h>
22 #include <linux/gpio.h>
23 
25 #include <asm/mach-ath79/ath79.h>
26 #include "common.h"
27 
28 static void __iomem *ath79_gpio_base;
29 static unsigned long ath79_gpio_count;
30 static DEFINE_SPINLOCK(ath79_gpio_lock);
31 
32 static void __ath79_gpio_set_value(unsigned gpio, int value)
33 {
34  void __iomem *base = ath79_gpio_base;
35 
36  if (value)
37  __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
38  else
39  __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
40 }
41 
42 static int __ath79_gpio_get_value(unsigned gpio)
43 {
44  return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
45 }
46 
47 static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
48 {
49  return __ath79_gpio_get_value(offset);
50 }
51 
52 static void ath79_gpio_set_value(struct gpio_chip *chip,
53  unsigned offset, int value)
54 {
55  __ath79_gpio_set_value(offset, value);
56 }
57 
58 static int ath79_gpio_direction_input(struct gpio_chip *chip,
59  unsigned offset)
60 {
61  void __iomem *base = ath79_gpio_base;
62  unsigned long flags;
63 
64  spin_lock_irqsave(&ath79_gpio_lock, flags);
65 
66  __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
67  base + AR71XX_GPIO_REG_OE);
68 
69  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
70 
71  return 0;
72 }
73 
74 static int ath79_gpio_direction_output(struct gpio_chip *chip,
75  unsigned offset, int value)
76 {
77  void __iomem *base = ath79_gpio_base;
78  unsigned long flags;
79 
80  spin_lock_irqsave(&ath79_gpio_lock, flags);
81 
82  if (value)
83  __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
84  else
85  __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
86 
87  __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
88  base + AR71XX_GPIO_REG_OE);
89 
90  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
91 
92  return 0;
93 }
94 
95 static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
96 {
97  void __iomem *base = ath79_gpio_base;
98  unsigned long flags;
99 
100  spin_lock_irqsave(&ath79_gpio_lock, flags);
101 
102  __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
103  base + AR71XX_GPIO_REG_OE);
104 
105  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
106 
107  return 0;
108 }
109 
110 static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
111  int value)
112 {
113  void __iomem *base = ath79_gpio_base;
114  unsigned long flags;
115 
116  spin_lock_irqsave(&ath79_gpio_lock, flags);
117 
118  if (value)
119  __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
120  else
121  __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
122 
123  __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
124  base + AR71XX_GPIO_REG_OE);
125 
126  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
127 
128  return 0;
129 }
130 
131 static struct gpio_chip ath79_gpio_chip = {
132  .label = "ath79",
133  .get = ath79_gpio_get_value,
134  .set = ath79_gpio_set_value,
135  .direction_input = ath79_gpio_direction_input,
136  .direction_output = ath79_gpio_direction_output,
137  .base = 0,
138 };
139 
141 {
142  void __iomem *base = ath79_gpio_base;
143  unsigned long flags;
144 
145  spin_lock_irqsave(&ath79_gpio_lock, flags);
146 
148  base + AR71XX_GPIO_REG_FUNC);
149  /* flush write */
151 
152  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
153 }
154 
156 {
157  void __iomem *base = ath79_gpio_base;
158  unsigned long flags;
159 
160  spin_lock_irqsave(&ath79_gpio_lock, flags);
161 
163  base + AR71XX_GPIO_REG_FUNC);
164  /* flush write */
166 
167  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
168 }
169 
171 {
172  void __iomem *base = ath79_gpio_base;
173  unsigned long flags;
174 
175  spin_lock_irqsave(&ath79_gpio_lock, flags);
176 
177  __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
178  base + AR71XX_GPIO_REG_FUNC);
179  /* flush write */
181 
182  spin_unlock_irqrestore(&ath79_gpio_lock, flags);
183 }
184 
186 {
187  int err;
188 
189  if (soc_is_ar71xx())
190  ath79_gpio_count = AR71XX_GPIO_COUNT;
191  else if (soc_is_ar7240())
192  ath79_gpio_count = AR7240_GPIO_COUNT;
193  else if (soc_is_ar7241() || soc_is_ar7242())
194  ath79_gpio_count = AR7241_GPIO_COUNT;
195  else if (soc_is_ar913x())
196  ath79_gpio_count = AR913X_GPIO_COUNT;
197  else if (soc_is_ar933x())
198  ath79_gpio_count = AR933X_GPIO_COUNT;
199  else if (soc_is_ar934x())
200  ath79_gpio_count = AR934X_GPIO_COUNT;
201  else
202  BUG();
203 
205  ath79_gpio_chip.ngpio = ath79_gpio_count;
206  if (soc_is_ar934x()) {
207  ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
208  ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
209  }
210 
211  err = gpiochip_add(&ath79_gpio_chip);
212  if (err)
213  panic("cannot add AR71xx GPIO chip, error=%d", err);
214 }
215 
216 int gpio_get_value(unsigned gpio)
217 {
218  if (gpio < ath79_gpio_count)
219  return __ath79_gpio_get_value(gpio);
220 
221  return __gpio_get_value(gpio);
222 }
224 
225 void gpio_set_value(unsigned gpio, int value)
226 {
227  if (gpio < ath79_gpio_count)
228  __ath79_gpio_set_value(gpio, value);
229  else
230  __gpio_set_value(gpio, value);
231 }
233 
234 int gpio_to_irq(unsigned gpio)
235 {
236  /* FIXME */
237  return -EINVAL;
238 }
240 
241 int irq_to_gpio(unsigned irq)
242 {
243  /* FIXME */
244  return -EINVAL;
245 }