aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-bf548/gpio.c
diff options
context:
space:
mode:
authorRoy Huang <roy.huang@analog.com>2007-07-12 10:41:45 -0400
committerBryan Wu <bryan.wu@analog.com>2007-07-12 10:41:45 -0400
commit24a07a124198153540f8f43d9e91d16227aba66e (patch)
tree917b2011e67e224515830833b1151e276b6c6137 /arch/blackfin/mach-bf548/gpio.c
parent088eec1192a0ae60fc218796027e622008af36c0 (diff)
Blackfin arch: initial supporting for BF548-EZKIT
The ADSP-BF54x was specifically designed to meet the needs of convergent multimedia applications where system performance and cost are essential ingredients. The integration of multimedia, human interface, and connectivity peripherals combined with increased system bandwidth and on-chip memory provides customers a platform to design the most demanding applications. Since now, ADSP-BF54x will be supported in the Linux kernel and bunch of related drivers such as USB OTG, ATAPI, NAND flash controller, LCD framebuffer, sound, touch screen will be submitted later. Please enjoy the show. Signed-off-by: Roy Huang <roy.huang@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/mach-bf548/gpio.c')
-rw-r--r--arch/blackfin/mach-bf548/gpio.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/arch/blackfin/mach-bf548/gpio.c b/arch/blackfin/mach-bf548/gpio.c
new file mode 100644
index 000000000000..854896d6ceda
--- /dev/null
+++ b/arch/blackfin/mach-bf548/gpio.c
@@ -0,0 +1,175 @@
1/*
2 * File: arch/blackfin/mach-bf548/gpio.c
3 * Based on:
4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
5 *
6 * Created:
7 * Description: GPIO Abstraction Layer
8 *
9 * Modified:
10 * Copyright 2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/module.h>
31#include <linux/err.h>
32#include <asm/blackfin.h>
33#include <asm/gpio.h>
34#include <linux/irq.h>
35
36static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
37 (struct gpio_port_t *) PORTA_FER,
38 (struct gpio_port_t *) PORTB_FER,
39 (struct gpio_port_t *) PORTC_FER,
40 (struct gpio_port_t *) PORTD_FER,
41 (struct gpio_port_t *) PORTE_FER,
42 (struct gpio_port_t *) PORTF_FER,
43 (struct gpio_port_t *) PORTG_FER,
44 (struct gpio_port_t *) PORTH_FER,
45 (struct gpio_port_t *) PORTI_FER,
46 (struct gpio_port_t *) PORTJ_FER,
47};
48
49static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
50
51inline int check_gpio(unsigned short gpio)
52{
53 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 \
54 || gpio == GPIO_PH14 || gpio == GPIO_PH15 \
55 || gpio > MAX_BLACKFIN_GPIOS)
56 return -EINVAL;
57 return 0;
58}
59
60static void port_setup(unsigned short gpio, unsigned short usage)
61{
62 if (usage == GPIO_USAGE) {
63 if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
64 printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral "
65 "usage and GPIO %d detected!\n", gpio);
66 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
67 } else
68 gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
69 SSYNC();
70}
71
72static int __init bfin_gpio_init(void)
73{
74 int i;
75
76 printk(KERN_INFO "Blackfin GPIO Controller\n");
77
78 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
79 reserved_map[gpio_bank(i)] = 0;
80
81 return 0;
82}
83
84arch_initcall(bfin_gpio_init);
85
86
87/***********************************************************
88*
89* FUNCTIONS: Blackfin GPIO Driver
90*
91* INPUTS/OUTPUTS:
92* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
93*
94*
95* DESCRIPTION: Blackfin GPIO Driver API
96*
97* CAUTION:
98*************************************************************
99* MODIFICATION HISTORY :
100**************************************************************/
101
102int gpio_request(unsigned short gpio, const char *label)
103{
104 unsigned long flags;
105
106 if (check_gpio(gpio) < 0)
107 return -EINVAL;
108
109 local_irq_save(flags);
110
111 if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
112 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
113 dump_stack();
114 local_irq_restore(flags);
115 return -EBUSY;
116 }
117 reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
118
119 local_irq_restore(flags);
120
121 port_setup(gpio, GPIO_USAGE);
122
123 return 0;
124}
125EXPORT_SYMBOL(gpio_request);
126
127
128void gpio_free(unsigned short gpio)
129{
130 unsigned long flags;
131
132 if (check_gpio(gpio) < 0)
133 return;
134
135 local_irq_save(flags);
136
137 if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
138 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
139 dump_stack();
140 local_irq_restore(flags);
141 return;
142 }
143
144 reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
145
146 local_irq_restore(flags);
147}
148EXPORT_SYMBOL(gpio_free);
149
150
151void gpio_direction_input(unsigned short gpio)
152{
153 unsigned long flags;
154
155 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
156
157 local_irq_save(flags);
158 gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
159 gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
160 local_irq_restore(flags);
161}
162EXPORT_SYMBOL(gpio_direction_input);
163
164void gpio_direction_output(unsigned short gpio)
165{
166 unsigned long flags;
167
168 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
169
170 local_irq_save(flags);
171 gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
172 gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
173 local_irq_restore(flags);
174}
175EXPORT_SYMBOL(gpio_direction_output);