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);