2 * arch/arm/mach-ns9xxx/gpio.c
4 * Copyright (C) 2006 by Digi International Inc.
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>
20 #include <asm/types.h>
21 #include <asm/bitops.h>
23 #if defined(CONFIG_PROCESSOR_NS9360)
25 #elif defined(CONFIG_PROCESSOR_NS9750)
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())
42 #if defined(CONFIG_PROCESSOR_NS9750)
43 if (processor_is_ns9750())
50 static inline volatile u32
*ns9xxx_gpio_get_gconfaddr(unsigned gpio
)
53 return &BBU_GCONFb1(gpio
/ 8);
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
)
69 /* this could be optimised away on ns9750 only builds */
73 static inline volatile u32
*ns9xxx_gpio_get_gstataddr(unsigned gpio
)
80 /* this could be optimised away on ns9750 only builds */
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;
91 EXPORT_SYMBOL(gpio_request
);
93 void gpio_free(unsigned gpio
)
95 clear_bit(gpio
, gpiores
);
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
);
112 spin_lock_irqsave(&gpio_lock
, flags
);
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
);
120 spin_unlock_irqrestore(&gpio_lock
, flags
);
125 int ns9xxx_gpio_configure(unsigned gpio
, int inv
, int func
)
127 if (likely(ns9xxx_valid_gpio(gpio
))) {
129 printk(KERN_WARNING
"use gpio_direction_input "
130 "or gpio_direction_output\n");
133 return __ns9xxx_gpio_configure(gpio
, 0, inv
, func
);
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);
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);
157 EXPORT_SYMBOL(gpio_direction_output
);
159 int gpio_get_value(unsigned gpio
)
161 volatile u32
*stat
= ns9xxx_gpio_get_gstataddr(gpio
);
164 ret
= 1 & (*stat
>> (gpio
& 31));
168 EXPORT_SYMBOL(gpio_get_value
);
170 void gpio_set_value(unsigned gpio
, int value
)
172 volatile u32
*ctrl
= ns9xxx_gpio_get_gctrladdr(gpio
);
175 spin_lock_irqsave(&gpio_lock
, flags
);
178 *ctrl
|= 1 << (gpio
& 31);
180 *ctrl
&= ~(1 << (gpio
& 31));
182 spin_unlock_irqrestore(&gpio_lock
, flags
);
184 EXPORT_SYMBOL(gpio_set_value
);