diff options
Diffstat (limited to 'arch/arm/mach-imx/generic.c')
-rw-r--r-- | arch/arm/mach-imx/generic.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 1c474cf709ca..a58b678006df 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c | |||
@@ -28,12 +28,16 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | 30 | ||
31 | #include <asm/errno.h> | ||
31 | #include <asm/arch/imxfb.h> | 32 | #include <asm/arch/imxfb.h> |
32 | #include <asm/hardware.h> | 33 | #include <asm/hardware.h> |
33 | #include <asm/arch/imx-regs.h> | 34 | #include <asm/arch/imx-regs.h> |
34 | 35 | ||
35 | #include <asm/mach/map.h> | 36 | #include <asm/mach/map.h> |
36 | #include <asm/arch/mmc.h> | 37 | #include <asm/arch/mmc.h> |
38 | #include <asm/arch/gpio.h> | ||
39 | |||
40 | unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG]; | ||
37 | 41 | ||
38 | void imx_gpio_mode(int gpio_mode) | 42 | void imx_gpio_mode(int gpio_mode) |
39 | { | 43 | { |
@@ -95,6 +99,120 @@ void imx_gpio_mode(int gpio_mode) | |||
95 | 99 | ||
96 | EXPORT_SYMBOL(imx_gpio_mode); | 100 | EXPORT_SYMBOL(imx_gpio_mode); |
97 | 101 | ||
102 | int imx_gpio_request(unsigned gpio, const char *label) | ||
103 | { | ||
104 | if(gpio >= (GPIO_PORT_MAX + 1) * 32) | ||
105 | printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n", | ||
106 | gpio, label ? label : "?"); | ||
107 | return -EINVAL; | ||
108 | |||
109 | if(test_and_set_bit(gpio, imx_gpio_alloc_map)) { | ||
110 | printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n", | ||
111 | gpio, label ? label : "?"); | ||
112 | return -EBUSY; | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | EXPORT_SYMBOL(imx_gpio_request); | ||
119 | |||
120 | void imx_gpio_free(unsigned gpio) | ||
121 | { | ||
122 | if(gpio >= (GPIO_PORT_MAX + 1) * 32) | ||
123 | return; | ||
124 | |||
125 | clear_bit(gpio, imx_gpio_alloc_map); | ||
126 | } | ||
127 | |||
128 | EXPORT_SYMBOL(imx_gpio_free); | ||
129 | |||
130 | int imx_gpio_direction_input(unsigned gpio) | ||
131 | { | ||
132 | imx_gpio_mode(gpio| GPIO_IN); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | EXPORT_SYMBOL(imx_gpio_direction_input); | ||
137 | |||
138 | int imx_gpio_direction_output(unsigned gpio, int value) | ||
139 | { | ||
140 | imx_gpio_set_value(gpio, value); | ||
141 | imx_gpio_mode(gpio| GPIO_OUT); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | EXPORT_SYMBOL(imx_gpio_direction_output); | ||
146 | |||
147 | int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count, | ||
148 | int alloc_mode, const char *label) | ||
149 | { | ||
150 | const int *p = pin_list; | ||
151 | int i; | ||
152 | unsigned gpio; | ||
153 | unsigned mode; | ||
154 | |||
155 | for (i = 0; i < count; i++) { | ||
156 | gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); | ||
157 | mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK); | ||
158 | |||
159 | if (gpio >= (GPIO_PORT_MAX + 1) * 32) | ||
160 | goto setup_error; | ||
161 | |||
162 | if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE) | ||
163 | imx_gpio_free(gpio); | ||
164 | else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC)) | ||
165 | if (imx_gpio_request(gpio, label)) | ||
166 | if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC)) | ||
167 | goto setup_error; | ||
168 | |||
169 | if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY | | ||
170 | IMX_GPIO_ALLOC_MODE_RELEASE))) | ||
171 | imx_gpio_mode(gpio | mode); | ||
172 | |||
173 | p++; | ||
174 | } | ||
175 | return 0; | ||
176 | |||
177 | setup_error: | ||
178 | if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC | | ||
179 | IMX_GPIO_ALLOC_MODE_TRY_ALLOC)) | ||
180 | return -EINVAL; | ||
181 | |||
182 | while (p != pin_list) { | ||
183 | p--; | ||
184 | gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); | ||
185 | imx_gpio_free(gpio); | ||
186 | } | ||
187 | |||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | EXPORT_SYMBOL(imx_gpio_setup_multiple_pins); | ||
192 | |||
193 | void __imx_gpio_set_value(unsigned gpio, int value) | ||
194 | { | ||
195 | imx_gpio_set_value_inline(gpio, value); | ||
196 | } | ||
197 | |||
198 | EXPORT_SYMBOL(__imx_gpio_set_value); | ||
199 | |||
200 | int imx_gpio_to_irq(unsigned gpio) | ||
201 | { | ||
202 | return IRQ_GPIOA(0) + gpio; | ||
203 | } | ||
204 | |||
205 | EXPORT_SYMBOL(imx_gpio_to_irq); | ||
206 | |||
207 | int imx_irq_to_gpio(unsigned irq) | ||
208 | { | ||
209 | if (irq < IRQ_GPIOA(0)) | ||
210 | return -EINVAL; | ||
211 | return irq - IRQ_GPIOA(0); | ||
212 | } | ||
213 | |||
214 | EXPORT_SYMBOL(imx_irq_to_gpio); | ||
215 | |||
98 | /* | 216 | /* |
99 | * get the system pll clock in Hz | 217 | * get the system pll clock in Hz |
100 | * | 218 | * |