2 * arch/arm/mach-pnx4008/gpio.c
6 * Author: Dmitry Chigirev <source@mvista.com>
8 * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
9 * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
17 #include <linux/config.h>
18 #include <linux/types.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <asm/semaphore.h>
23 #include <asm/arch/platform.h>
24 #include <asm/arch/gpio.h>
26 /* register definitions */
27 #define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
29 #define PIO_INP_STATE (0x00U)
30 #define PIO_OUTP_SET (0x04U)
31 #define PIO_OUTP_CLR (0x08U)
32 #define PIO_OUTP_STATE (0x0CU)
33 #define PIO_DRV_SET (0x10U)
34 #define PIO_DRV_CLR (0x14U)
35 #define PIO_DRV_STATE (0x18U)
36 #define PIO_SDINP_STATE (0x1CU)
37 #define PIO_SDOUTP_SET (0x20U)
38 #define PIO_SDOUTP_CLR (0x24U)
39 #define PIO_MUX_SET (0x28U)
40 #define PIO_MUX_CLR (0x2CU)
41 #define PIO_MUX_STATE (0x30U)
43 static inline void gpio_lock(void)
48 static inline void gpio_unlock(void)
53 /* Inline functions */
54 static inline int gpio_read_bit(u32 reg
, int gpio
)
64 val
= __raw_readl(PIO_VA_BASE
+ reg
);
65 ret
= (val
& bit
) ? 1 : 0;
71 static inline int gpio_set_bit(u32 reg
, int gpio
)
81 val
= __raw_readl(PIO_VA_BASE
+ reg
);
83 __raw_writel(val
, PIO_VA_BASE
+ reg
);
90 /* Very simple access control, bitmap for allocated/free */
91 static unsigned long access_map
[4];
97 /*GPIO to Input Mapping */
98 static short gpio_to_inp_map
[32] = {
99 -1, -1, -1, -1, -1, -1, -1, -1,
100 -1, -1, -1, -1, -1, -1, -1, -1,
101 -1, -1, -1, -1, -1, -1, -1, -1,
102 -1, 10, 11, 12, 13, 14, 24, -1
105 /*GPIO to Mux Mapping */
106 static short gpio_to_mux_map
[32] = {
107 -1, -1, -1, -1, -1, -1, -1, -1,
108 -1, -1, -1, -1, -1, -1, -1, -1,
109 -1, -1, -1, -1, -1, -1, -1, -1,
110 -1, -1, -1, 0, 1, 4, 5, -1
113 /*Output to Mux Mapping */
114 static short outp_to_mux_map
[32] = {
115 -1, -1, -1, 6, -1, -1, -1, -1,
116 -1, -1, -1, -1, -1, -1, -1, -1,
117 -1, -1, -1, -1, -1, 2, -1, -1,
118 -1, -1, -1, -1, -1, -1, -1, -1
121 int pnx4008_gpio_register_pin(unsigned short pin
)
123 unsigned long bit
= GPIO_BIT(pin
);
124 int ret
= -EBUSY
; /* Already in use */
128 if (GPIO_ISBID(pin
)) {
129 if (access_map
[GPIO_INDEX
] & bit
)
131 access_map
[GPIO_INDEX
] |= bit
;
133 } else if (GPIO_ISRAM(pin
)) {
134 if (access_map
[GPIO_INDEX
] & bit
)
136 access_map
[GPIO_INDEX
] |= bit
;
138 } else if (GPIO_ISMUX(pin
)) {
139 if (access_map
[MUX_INDEX
] & bit
)
141 access_map
[MUX_INDEX
] |= bit
;
143 } else if (GPIO_ISOUT(pin
)) {
144 if (access_map
[OUTP_INDEX
] & bit
)
146 access_map
[OUTP_INDEX
] |= bit
;
148 } else if (GPIO_ISIN(pin
)) {
149 if (access_map
[INP_INDEX
] & bit
)
151 access_map
[INP_INDEX
] |= bit
;
161 EXPORT_SYMBOL(pnx4008_gpio_register_pin
);
163 int pnx4008_gpio_unregister_pin(unsigned short pin
)
165 unsigned long bit
= GPIO_BIT(pin
);
166 int ret
= -EFAULT
; /* Not registered */
170 if (GPIO_ISBID(pin
)) {
171 if (~access_map
[GPIO_INDEX
] & bit
)
173 access_map
[GPIO_INDEX
] &= ~bit
;
174 } else if (GPIO_ISRAM(pin
)) {
175 if (~access_map
[GPIO_INDEX
] & bit
)
177 access_map
[GPIO_INDEX
] &= ~bit
;
178 } else if (GPIO_ISMUX(pin
)) {
179 if (~access_map
[MUX_INDEX
] & bit
)
181 access_map
[MUX_INDEX
] &= ~bit
;
182 } else if (GPIO_ISOUT(pin
)) {
183 if (~access_map
[OUTP_INDEX
] & bit
)
185 access_map
[OUTP_INDEX
] &= ~bit
;
186 } else if (GPIO_ISIN(pin
)) {
187 if (~access_map
[INP_INDEX
] & bit
)
189 access_map
[INP_INDEX
] &= ~bit
;
199 EXPORT_SYMBOL(pnx4008_gpio_unregister_pin
);
201 unsigned long pnx4008_gpio_read_pin(unsigned short pin
)
203 unsigned long ret
= -EFAULT
;
204 int gpio
= GPIO_BIT_MASK(pin
);
206 if (GPIO_ISOUT(pin
)) {
207 ret
= gpio_read_bit(PIO_OUTP_STATE
, gpio
);
208 } else if (GPIO_ISRAM(pin
)) {
209 if (gpio_read_bit(PIO_DRV_STATE
, gpio
) == 0) {
210 ret
= gpio_read_bit(PIO_SDINP_STATE
, gpio
);
212 } else if (GPIO_ISBID(pin
)) {
213 ret
= gpio_read_bit(PIO_DRV_STATE
, gpio
);
215 ret
= gpio_read_bit(PIO_OUTP_STATE
, gpio
);
218 gpio_read_bit(PIO_INP_STATE
, gpio_to_inp_map
[gpio
]);
219 } else if (GPIO_ISIN(pin
)) {
220 ret
= gpio_read_bit(PIO_INP_STATE
, gpio
);
226 EXPORT_SYMBOL(pnx4008_gpio_read_pin
);
228 /* Write Value to output */
229 int pnx4008_gpio_write_pin(unsigned short pin
, int output
)
231 int gpio
= GPIO_BIT_MASK(pin
);
235 if (GPIO_ISOUT(pin
)) {
236 printk( "writing '%x' to '%x'\n",
237 gpio
, output
? PIO_OUTP_SET
: PIO_OUTP_CLR
);
238 ret
= gpio_set_bit(output
? PIO_OUTP_SET
: PIO_OUTP_CLR
, gpio
);
239 } else if (GPIO_ISRAM(pin
)) {
240 if (gpio_read_bit(PIO_DRV_STATE
, gpio
) > 0)
241 ret
= gpio_set_bit(output
? PIO_SDOUTP_SET
:
242 PIO_SDOUTP_CLR
, gpio
);
243 } else if (GPIO_ISBID(pin
)) {
244 if (gpio_read_bit(PIO_DRV_STATE
, gpio
) > 0)
245 ret
= gpio_set_bit(output
? PIO_OUTP_SET
:
252 EXPORT_SYMBOL(pnx4008_gpio_write_pin
);
254 /* Value = 1 : Set GPIO pin as output */
255 /* Value = 0 : Set GPIO pin as input */
256 int pnx4008_gpio_set_pin_direction(unsigned short pin
, int output
)
258 int gpio
= GPIO_BIT_MASK(pin
);
262 if (GPIO_ISBID(pin
) || GPIO_ISRAM(pin
)) {
263 ret
= gpio_set_bit(output
? PIO_DRV_SET
: PIO_DRV_CLR
, gpio
);
269 EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction
);
271 /* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
272 int pnx4008_gpio_read_pin_direction(unsigned short pin
)
274 int gpio
= GPIO_BIT_MASK(pin
);
278 if (GPIO_ISBID(pin
) || GPIO_ISRAM(pin
)) {
279 ret
= gpio_read_bit(PIO_DRV_STATE
, gpio
);
285 EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction
);
287 /* Value = 1 : Set pin to muxed function */
288 /* Value = 0 : Set pin as GPIO */
289 int pnx4008_gpio_set_pin_mux(unsigned short pin
, int output
)
291 int gpio
= GPIO_BIT_MASK(pin
);
295 if (GPIO_ISBID(pin
)) {
297 gpio_set_bit(output
? PIO_MUX_SET
: PIO_MUX_CLR
,
298 gpio_to_mux_map
[gpio
]);
299 } else if (GPIO_ISOUT(pin
)) {
301 gpio_set_bit(output
? PIO_MUX_SET
: PIO_MUX_CLR
,
302 outp_to_mux_map
[gpio
]);
303 } else if (GPIO_ISMUX(pin
)) {
304 ret
= gpio_set_bit(output
? PIO_MUX_SET
: PIO_MUX_CLR
, gpio
);
310 EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux
);
312 /* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
313 int pnx4008_gpio_read_pin_mux(unsigned short pin
)
315 int gpio
= GPIO_BIT_MASK(pin
);
319 if (GPIO_ISBID(pin
)) {
320 ret
= gpio_read_bit(PIO_MUX_STATE
, gpio_to_mux_map
[gpio
]);
321 } else if (GPIO_ISOUT(pin
)) {
322 ret
= gpio_read_bit(PIO_MUX_STATE
, outp_to_mux_map
[gpio
]);
323 } else if (GPIO_ISMUX(pin
)) {
324 ret
= gpio_read_bit(PIO_MUX_STATE
, gpio
);
330 EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux
);