cpuidle: remove unused exports
[pandora-kernel.git] / arch / blackfin / mach-bf548 / gpio.c
1 /*
2  * File:         arch/blackfin/mach-bf548/gpio.c
3  * Based on:
4  * Author:       Michael Hennerich (hennerich@blackfin.uclinux.org)
5  *
6  * Created:
7  * Description:  GPIO Abstraction Layer
8  *
9  * Modified:
10  *               Copyright 2007 Analog Devices Inc.
11  *
12  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, see the file COPYING, or write
26  * to the Free Software Foundation, Inc.,
27  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
29
30 #include <linux/module.h>
31 #include <linux/err.h>
32 #include <asm/blackfin.h>
33 #include <asm/gpio.h>
34 #include <asm/portmux.h>
35 #include <linux/irq.h>
36
37 static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
38         (struct gpio_port_t *)PORTA_FER,
39         (struct gpio_port_t *)PORTB_FER,
40         (struct gpio_port_t *)PORTC_FER,
41         (struct gpio_port_t *)PORTD_FER,
42         (struct gpio_port_t *)PORTE_FER,
43         (struct gpio_port_t *)PORTF_FER,
44         (struct gpio_port_t *)PORTG_FER,
45         (struct gpio_port_t *)PORTH_FER,
46         (struct gpio_port_t *)PORTI_FER,
47         (struct gpio_port_t *)PORTJ_FER,
48 };
49
50 static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
51 static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
52
53 inline int check_gpio(unsigned short gpio)
54 {
55         if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
56             || gpio == GPIO_PH14 || gpio == GPIO_PH15
57             || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
58             || gpio > MAX_BLACKFIN_GPIOS)
59                 return -EINVAL;
60         return 0;
61 }
62
63 inline void portmux_setup(unsigned short portno, unsigned short function)
64 {
65         u32 pmux;
66
67         pmux = gpio_array[gpio_bank(portno)]->port_mux;
68
69         pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
70         pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
71
72         gpio_array[gpio_bank(portno)]->port_mux = pmux;
73
74 }
75
76 inline u16 get_portmux(unsigned short portno)
77 {
78         u32 pmux;
79
80         pmux = gpio_array[gpio_bank(portno)]->port_mux;
81
82         return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
83
84 }
85
86 static void port_setup(unsigned short gpio, unsigned short usage)
87 {
88         if (usage == GPIO_USAGE) {
89                 if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
90                         printk(KERN_WARNING
91                                "bfin-gpio: Possible Conflict with Peripheral "
92                                "usage and GPIO %d detected!\n", gpio);
93                 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
94         } else
95                 gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
96         SSYNC();
97 }
98
99 static int __init bfin_gpio_init(void)
100 {
101         printk(KERN_INFO "Blackfin GPIO Controller\n");
102
103         return 0;
104 }
105
106 arch_initcall(bfin_gpio_init);
107
108 int peripheral_request(unsigned short per, const char *label)
109 {
110         unsigned long flags;
111         unsigned short ident = P_IDENT(per);
112
113         if (!(per & P_DEFINED))
114                 return -ENODEV;
115
116         if (check_gpio(ident) < 0)
117                 return -EINVAL;
118
119         local_irq_save(flags);
120
121         if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
122                 printk(KERN_ERR
123                        "%s: Peripheral %d is already reserved as GPIO!\n",
124                        __FUNCTION__, per);
125                 dump_stack();
126                 local_irq_restore(flags);
127                 return -EBUSY;
128         }
129
130         if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
131
132                 u16 funct = get_portmux(ident);
133
134                 if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
135                         printk(KERN_ERR
136                                "%s: Peripheral %d is already reserved!\n",
137                                __FUNCTION__, per);
138                         dump_stack();
139                         local_irq_restore(flags);
140                         return -EBUSY;
141                 }
142         }
143
144         reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
145
146         portmux_setup(ident, P_FUNCT2MUX(per));
147         port_setup(ident, PERIPHERAL_USAGE);
148
149         local_irq_restore(flags);
150
151         return 0;
152 }
153 EXPORT_SYMBOL(peripheral_request);
154
155 int peripheral_request_list(unsigned short per[], const char *label)
156 {
157
158         u16 cnt;
159         int ret;
160
161         for (cnt = 0; per[cnt] != 0; cnt++) {
162                 ret = peripheral_request(per[cnt], label);
163                 if (ret < 0)
164                         return ret;
165         }
166
167         return 0;
168 }
169 EXPORT_SYMBOL(peripheral_request_list);
170
171 void peripheral_free(unsigned short per)
172 {
173         unsigned long flags;
174         unsigned short ident = P_IDENT(per);
175
176         if (!(per & P_DEFINED))
177                 return;
178
179         if (check_gpio(ident) < 0)
180                 return;
181
182         local_irq_save(flags);
183
184         if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
185                 printk(KERN_ERR "bfin-gpio: Peripheral %d wasn't reserved!\n", per);
186                 dump_stack();
187                 local_irq_restore(flags);
188                 return;
189         }
190
191         if (!(per & P_MAYSHARE)) {
192                 port_setup(ident, GPIO_USAGE);
193         }
194
195         reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
196
197         local_irq_restore(flags);
198 }
199 EXPORT_SYMBOL(peripheral_free);
200
201 void peripheral_free_list(unsigned short per[])
202 {
203         u16 cnt;
204
205         for (cnt = 0; per[cnt] != 0; cnt++) {
206                 peripheral_free(per[cnt]);
207         }
208
209 }
210 EXPORT_SYMBOL(peripheral_free_list);
211
212 /***********************************************************
213 *
214 * FUNCTIONS: Blackfin GPIO Driver
215 *
216 * INPUTS/OUTPUTS:
217 * gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
218 *
219 *
220 * DESCRIPTION: Blackfin GPIO Driver API
221 *
222 * CAUTION:
223 *************************************************************
224 * MODIFICATION HISTORY :
225 **************************************************************/
226
227 int gpio_request(unsigned short gpio, const char *label)
228 {
229         unsigned long flags;
230
231         if (check_gpio(gpio) < 0)
232                 return -EINVAL;
233
234         local_irq_save(flags);
235
236         if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
237                 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
238                 dump_stack();
239                 local_irq_restore(flags);
240                 return -EBUSY;
241         }
242
243         if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
244                 printk(KERN_ERR
245                        "bfin-gpio: GPIO %d is already reserved as Peripheral!\n", gpio);
246                 dump_stack();
247                 local_irq_restore(flags);
248                 return -EBUSY;
249         }
250
251         reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
252
253         local_irq_restore(flags);
254
255         port_setup(gpio, GPIO_USAGE);
256
257         return 0;
258 }
259 EXPORT_SYMBOL(gpio_request);
260
261 void gpio_free(unsigned short gpio)
262 {
263         unsigned long flags;
264
265         if (check_gpio(gpio) < 0)
266                 return;
267
268         local_irq_save(flags);
269
270         if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
271                 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
272                 dump_stack();
273                 local_irq_restore(flags);
274                 return;
275         }
276
277         reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
278
279         local_irq_restore(flags);
280 }
281 EXPORT_SYMBOL(gpio_free);
282
283 void gpio_direction_input(unsigned short gpio)
284 {
285         unsigned long flags;
286
287         BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
288
289         local_irq_save(flags);
290         gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
291         gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
292         local_irq_restore(flags);
293 }
294 EXPORT_SYMBOL(gpio_direction_input);
295
296 void gpio_direction_output(unsigned short gpio)
297 {
298         unsigned long flags;
299
300         BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
301
302         local_irq_save(flags);
303         gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
304         gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
305         local_irq_restore(flags);
306 }
307 EXPORT_SYMBOL(gpio_direction_output);
308
309 void gpio_set_value(unsigned short gpio, unsigned short arg)
310 {
311         if (arg)
312                 gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
313         else
314                 gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
315
316 }
317 EXPORT_SYMBOL(gpio_set_value);
318
319 unsigned short gpio_get_value(unsigned short gpio)
320 {
321         return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
322 }
323 EXPORT_SYMBOL(gpio_get_value);