[ARM] 4590/1: ns9xxx: add gpio handling functions
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / arm / mach-ns9xxx / gpio.c
blob87b872fdca7e9d519bb594dd73ebc3acd8ac0d5a
1 /*
2 * arch/arm/mach-ns9xxx/gpio.c
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 by
9 * the Free Software Foundation.
11 #include <linux/compiler.h>
12 #include <linux/init.h>
13 #include <linux/spinlock.h>
14 #include <linux/module.h>
16 #include <asm/arch-ns9xxx/gpio.h>
17 #include <asm/arch-ns9xxx/processor.h>
18 #include <asm/arch-ns9xxx/regs-bbu.h>
19 #include <asm/bug.h>
20 #include <asm/types.h>
21 #include <asm/bitops.h>
23 #if defined(CONFIG_PROCESSOR_NS9360)
24 #define GPIO_MAX 72
25 #elif defined(CONFIG_PROCESSOR_NS9750)
26 #define GPIO_MAX 49
27 #endif
29 /* protects BBU_GCONFx and BBU_GCTRLx */
30 static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock);
32 /* only access gpiores with atomic ops */
33 static DECLARE_BITMAP(gpiores, GPIO_MAX);
35 static inline int ns9xxx_valid_gpio(unsigned gpio)
37 #if defined(CONFIG_PROCESSOR_NS9360)
38 if (processor_is_ns9360())
39 return gpio <= 72;
40 else
41 #endif
42 #if defined(CONFIG_PROCESSOR_NS9750)
43 if (processor_is_ns9750())
44 return gpio <= 49;
45 else
46 #endif
47 BUG();
50 static inline volatile u32 *ns9xxx_gpio_get_gconfaddr(unsigned gpio)
52 if (gpio < 56)
53 return &BBU_GCONFb1(gpio / 8);
54 else
56 * this could be optimised away on
57 * ns9750 only builds, but it isn't ...
59 return &BBU_GCONFb2((gpio - 56) / 8);
62 static inline volatile u32 *ns9xxx_gpio_get_gctrladdr(unsigned gpio)
64 if (gpio < 32)
65 return &BBU_GCTRL1;
66 else if (gpio < 64)
67 return &BBU_GCTRL2;
68 else
69 /* this could be optimised away on ns9750 only builds */
70 return &BBU_GCTRL3;
73 static inline volatile u32 *ns9xxx_gpio_get_gstataddr(unsigned gpio)
75 if (gpio < 32)
76 return &BBU_GSTAT1;
77 else if (gpio < 64)
78 return &BBU_GSTAT2;
79 else
80 /* this could be optimised away on ns9750 only builds */
81 return &BBU_GSTAT3;
84 int gpio_request(unsigned gpio, const char *label)
86 if (likely(ns9xxx_valid_gpio(gpio)))
87 return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0;
88 else
89 return -EINVAL;
91 EXPORT_SYMBOL(gpio_request);
93 void gpio_free(unsigned gpio)
95 clear_bit(gpio, gpiores);
96 return;
98 EXPORT_SYMBOL(gpio_free);
101 * each gpio can serve for 4 different purposes [0..3]. These are called
102 * "functions" and passed in the parameter func. Functions 0-2 are always some
103 * special things, function 3 is GPIO. If func == 3 dir specifies input or
104 * output, and with inv you can enable an inverter (independent of func).
106 static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func)
108 volatile u32 *conf = ns9xxx_gpio_get_gconfaddr(gpio);
109 u32 confval;
110 unsigned long flags;
112 spin_lock_irqsave(&gpio_lock, flags);
114 confval = *conf;
115 REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir);
116 REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv);
117 REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func);
118 *conf = confval;
120 spin_unlock_irqrestore(&gpio_lock, flags);
122 return 0;
125 int ns9xxx_gpio_configure(unsigned gpio, int inv, int func)
127 if (likely(ns9xxx_valid_gpio(gpio))) {
128 if (func == 3) {
129 printk(KERN_WARNING "use gpio_direction_input "
130 "or gpio_direction_output\n");
131 return -EINVAL;
132 } else
133 return __ns9xxx_gpio_configure(gpio, 0, inv, func);
134 } else
135 return -EINVAL;
137 EXPORT_SYMBOL(ns9xxx_gpio_configure);
139 int gpio_direction_input(unsigned gpio)
141 if (likely(ns9xxx_valid_gpio(gpio))) {
142 return __ns9xxx_gpio_configure(gpio, 0, 0, 3);
143 } else
144 return -EINVAL;
146 EXPORT_SYMBOL(gpio_direction_input);
148 int gpio_direction_output(unsigned gpio, int value)
150 if (likely(ns9xxx_valid_gpio(gpio))) {
151 gpio_set_value(gpio, value);
153 return __ns9xxx_gpio_configure(gpio, 1, 0, 3);
154 } else
155 return -EINVAL;
157 EXPORT_SYMBOL(gpio_direction_output);
159 int gpio_get_value(unsigned gpio)
161 volatile u32 *stat = ns9xxx_gpio_get_gstataddr(gpio);
162 int ret;
164 ret = 1 & (*stat >> (gpio & 31));
166 return ret;
168 EXPORT_SYMBOL(gpio_get_value);
170 void gpio_set_value(unsigned gpio, int value)
172 volatile u32 *ctrl = ns9xxx_gpio_get_gctrladdr(gpio);
173 unsigned long flags;
175 spin_lock_irqsave(&gpio_lock, flags);
177 if (value)
178 *ctrl |= 1 << (gpio & 31);
179 else
180 *ctrl &= ~(1 << (gpio & 31));
182 spin_unlock_irqrestore(&gpio_lock, flags);
184 EXPORT_SYMBOL(gpio_set_value);