]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/omap_gpio.c
sunxi: Add CONFIG_OLD_SUNXI_KERNEL_COMPAT Kconfig option
[karo-tx-uboot.git] / drivers / gpio / omap_gpio.c
1 /*
2  * Copyright (c) 2009 Wind River Systems, Inc.
3  * Tom Rix <Tom.Rix@windriver.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0
6  *
7  * This work is derived from the linux 2.6.27 kernel source
8  * To fetch, use the kernel repository
9  * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
10  * Use the v2.6.27 tag.
11  *
12  * Below is the original's header including its copyright
13  *
14  *  linux/arch/arm/plat-omap/gpio.c
15  *
16  * Support functions for OMAP GPIO
17  *
18  * Copyright (C) 2003-2005 Nokia Corporation
19  * Written by Juha Yrjölä <juha.yrjola@nokia.com>
20  */
21 #include <common.h>
22 #include <asm/gpio.h>
23 #include <asm/io.h>
24 #include <asm/errno.h>
25
26 #define OMAP_GPIO_DIR_OUT       0
27 #define OMAP_GPIO_DIR_IN        1
28
29 static inline const struct gpio_bank *get_gpio_bank(int gpio)
30 {
31         return &omap_gpio_bank[gpio >> 5];
32 }
33
34 static inline int get_gpio_index(int gpio)
35 {
36         return gpio & 0x1f;
37 }
38
39 int gpio_is_valid(int gpio)
40 {
41         return (gpio >= 0) && (gpio < OMAP_MAX_GPIO);
42 }
43
44 static int check_gpio(int gpio)
45 {
46         if (!gpio_is_valid(gpio)) {
47                 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
48                 return -1;
49         }
50         return 0;
51 }
52
53 static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
54                                 int is_input)
55 {
56         void *reg = bank->base;
57         u32 l;
58
59         switch (bank->method) {
60         case METHOD_GPIO_24XX:
61                 reg += OMAP_GPIO_OE;
62                 break;
63         default:
64                 return;
65         }
66         l = __raw_readl(reg);
67         if (is_input)
68                 l |= 1 << gpio;
69         else
70                 l &= ~(1 << gpio);
71         __raw_writel(l, reg);
72 }
73
74 /**
75  * Get the direction of the GPIO by reading the GPIO_OE register
76  * corresponding to the specified bank.
77  */
78 static int _get_gpio_direction(const struct gpio_bank *bank, int gpio)
79 {
80         void *reg = bank->base;
81         u32 v;
82
83         switch (bank->method) {
84         case METHOD_GPIO_24XX:
85                 reg += OMAP_GPIO_OE;
86                 break;
87         default:
88                 return -1;
89         }
90
91         v = __raw_readl(reg);
92
93         if (v & (1 << gpio))
94                 return OMAP_GPIO_DIR_IN;
95         else
96                 return OMAP_GPIO_DIR_OUT;
97 }
98
99 static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
100                                 int enable)
101 {
102         void *reg = bank->base;
103         u32 l = 0;
104
105         switch (bank->method) {
106         case METHOD_GPIO_24XX:
107                 if (enable)
108                         reg += OMAP_GPIO_SETDATAOUT;
109                 else
110                         reg += OMAP_GPIO_CLEARDATAOUT;
111                 l = 1 << gpio;
112                 break;
113         default:
114                 printf("omap3-gpio unknown bank method %s %d\n",
115                        __FILE__, __LINE__);
116                 return;
117         }
118         __raw_writel(l, reg);
119 }
120
121 /**
122  * Set value of the specified gpio
123  */
124 int gpio_set_value(unsigned gpio, int value)
125 {
126         const struct gpio_bank *bank;
127
128         if (check_gpio(gpio) < 0)
129                 return -1;
130         bank = get_gpio_bank(gpio);
131         _set_gpio_dataout(bank, get_gpio_index(gpio), value);
132
133         return 0;
134 }
135
136 /**
137  * Get value of the specified gpio
138  */
139 int gpio_get_value(unsigned gpio)
140 {
141         const struct gpio_bank *bank;
142         void *reg;
143         int input;
144
145         if (check_gpio(gpio) < 0)
146                 return -1;
147         bank = get_gpio_bank(gpio);
148         reg = bank->base;
149         switch (bank->method) {
150         case METHOD_GPIO_24XX:
151                 input = _get_gpio_direction(bank, get_gpio_index(gpio));
152                 switch (input) {
153                 case OMAP_GPIO_DIR_IN:
154                         reg += OMAP_GPIO_DATAIN;
155                         break;
156                 case OMAP_GPIO_DIR_OUT:
157                         reg += OMAP_GPIO_DATAOUT;
158                         break;
159                 default:
160                         return -1;
161                 }
162                 break;
163         default:
164                 return -1;
165         }
166         return (__raw_readl(reg)
167                         & (1 << get_gpio_index(gpio))) != 0;
168 }
169
170 /**
171  * Set gpio direction as input
172  */
173 int gpio_direction_input(unsigned gpio)
174 {
175         const struct gpio_bank *bank;
176
177         if (check_gpio(gpio) < 0)
178                 return -1;
179
180         bank = get_gpio_bank(gpio);
181         _set_gpio_direction(bank, get_gpio_index(gpio), 1);
182
183         return 0;
184 }
185
186 /**
187  * Set gpio direction as output
188  */
189 int gpio_direction_output(unsigned gpio, int value)
190 {
191         const struct gpio_bank *bank;
192
193         if (check_gpio(gpio) < 0)
194                 return -1;
195
196         bank = get_gpio_bank(gpio);
197         _set_gpio_dataout(bank, get_gpio_index(gpio), value);
198         _set_gpio_direction(bank, get_gpio_index(gpio), 0);
199
200         return 0;
201 }
202
203 /**
204  * Request a gpio before using it.
205  *
206  * NOTE: Argument 'label' is unused.
207  */
208 int gpio_request(unsigned gpio, const char *label)
209 {
210         if (check_gpio(gpio) < 0)
211                 return -1;
212
213         return 0;
214 }
215
216 /**
217  * Reset and free the gpio after using it.
218  */
219 int gpio_free(unsigned gpio)
220 {
221         return 0;
222 }