2 * Copyright (c) 2009 Wind River Systems, Inc.
5 * SPDX-License-Identifier: GPL-2.0
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.
12 * Below is the original's header including its copyright
14 * linux/arch/arm/plat-omap/gpio.c
16 * Support functions for OMAP GPIO
18 * Copyright (C) 2003-2005 Nokia Corporation
25 #include <asm/errno.h>
27 #define OMAP_GPIO_DIR_OUT 0
28 #define OMAP_GPIO_DIR_IN 1
32 #define GPIO_NAME_SIZE 20
33 #define GPIO_PER_BANK 32
36 char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
38 void *base; /* address of registers in physical memory */
39 enum gpio_method method;
44 static inline int get_gpio_index(int gpio)
49 int gpio_is_valid(int gpio)
51 return (gpio >= 0) && (gpio < OMAP_MAX_GPIO);
54 static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
57 void *reg = bank->base;
60 switch (bank->method) {
61 case METHOD_GPIO_24XX:
76 * Get the direction of the GPIO by reading the GPIO_OE register
77 * corresponding to the specified bank.
79 static int _get_gpio_direction(const struct gpio_bank *bank, int gpio)
81 void *reg = bank->base;
84 switch (bank->method) {
85 case METHOD_GPIO_24XX:
95 return OMAP_GPIO_DIR_IN;
97 return OMAP_GPIO_DIR_OUT;
100 static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
103 void *reg = bank->base;
106 switch (bank->method) {
107 case METHOD_GPIO_24XX:
109 reg += OMAP_GPIO_SETDATAOUT;
111 reg += OMAP_GPIO_CLEARDATAOUT;
115 printf("omap3-gpio unknown bank method %s %d\n",
119 __raw_writel(l, reg);
122 static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
124 void *reg = bank->base;
127 switch (bank->method) {
128 case METHOD_GPIO_24XX:
129 input = _get_gpio_direction(bank, gpio);
131 case OMAP_GPIO_DIR_IN:
132 reg += OMAP_GPIO_DATAIN;
134 case OMAP_GPIO_DIR_OUT:
135 reg += OMAP_GPIO_DATAOUT;
145 return (__raw_readl(reg) & (1 << gpio)) != 0;
148 #ifndef CONFIG_DM_GPIO
150 static inline const struct gpio_bank *get_gpio_bank(int gpio)
152 return &omap_gpio_bank[gpio >> 5];
155 static int check_gpio(int gpio)
157 if (!gpio_is_valid(gpio)) {
158 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
165 * Set value of the specified gpio
167 int gpio_set_value(unsigned gpio, int value)
169 const struct gpio_bank *bank;
171 if (check_gpio(gpio) < 0)
173 bank = get_gpio_bank(gpio);
174 _set_gpio_dataout(bank, get_gpio_index(gpio), value);
180 * Get value of the specified gpio
182 int gpio_get_value(unsigned gpio)
184 const struct gpio_bank *bank;
186 if (check_gpio(gpio) < 0)
188 bank = get_gpio_bank(gpio);
190 return _get_gpio_value(bank, get_gpio_index(gpio));
194 * Set gpio direction as input
196 int gpio_direction_input(unsigned gpio)
198 const struct gpio_bank *bank;
200 if (check_gpio(gpio) < 0)
203 bank = get_gpio_bank(gpio);
204 _set_gpio_direction(bank, get_gpio_index(gpio), 1);
210 * Set gpio direction as output
212 int gpio_direction_output(unsigned gpio, int value)
214 const struct gpio_bank *bank;
216 if (check_gpio(gpio) < 0)
219 bank = get_gpio_bank(gpio);
220 _set_gpio_dataout(bank, get_gpio_index(gpio), value);
221 _set_gpio_direction(bank, get_gpio_index(gpio), 0);
227 * Request a gpio before using it.
229 * NOTE: Argument 'label' is unused.
231 int gpio_request(unsigned gpio, const char *label)
233 if (check_gpio(gpio) < 0)
240 * Reset and free the gpio after using it.
242 int gpio_free(unsigned gpio)
247 #else /* new driver model interface CONFIG_DM_GPIO */
250 * gpio_is_requested() - check if a GPIO has been requested
252 * @bank: Bank to check
253 * @offset: GPIO offset within bank to check
254 * @return true if marked as requested, false if not
256 static inline bool gpio_is_requested(struct gpio_bank *bank, int offset)
258 return *bank->label[offset] != '\0';
261 static int omap_gpio_is_output(struct gpio_bank *bank, int offset)
263 return _get_gpio_direction(bank, offset) == OMAP_GPIO_DIR_OUT;
266 static int check_requested(struct udevice *dev, unsigned offset,
269 struct gpio_bank *bank = dev_get_priv(dev);
270 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
272 if (!gpio_is_requested(bank, offset)) {
273 printf("omap_gpio: %s: error: gpio %s%d not requested\n",
274 func, uc_priv->bank_name, offset);
281 /* set GPIO pin 'gpio' as an input */
282 static int omap_gpio_direction_input(struct udevice *dev, unsigned offset)
284 struct gpio_bank *bank = dev_get_priv(dev);
287 ret = check_requested(dev, offset, __func__);
291 /* Configure GPIO direction as input. */
292 _set_gpio_direction(bank, offset, 1);
297 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
298 static int omap_gpio_direction_output(struct udevice *dev, unsigned offset,
301 struct gpio_bank *bank = dev_get_priv(dev);
304 ret = check_requested(dev, offset, __func__);
308 _set_gpio_dataout(bank, offset, value);
309 _set_gpio_direction(bank, offset, 0);
314 /* read GPIO IN value of pin 'gpio' */
315 static int omap_gpio_get_value(struct udevice *dev, unsigned offset)
317 struct gpio_bank *bank = dev_get_priv(dev);
320 ret = check_requested(dev, offset, __func__);
324 return _get_gpio_value(bank, offset);
327 /* write GPIO OUT value to pin 'gpio' */
328 static int omap_gpio_set_value(struct udevice *dev, unsigned offset,
331 struct gpio_bank *bank = dev_get_priv(dev);
334 ret = check_requested(dev, offset, __func__);
338 _set_gpio_dataout(bank, offset, value);
343 static int omap_gpio_get_state(struct udevice *dev, unsigned int offset,
344 char *buf, int bufsize)
346 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
347 struct gpio_bank *bank = dev_get_priv(dev);
353 label = bank->label[offset];
354 is_output = omap_gpio_is_output(bank->base, offset);
355 size = snprintf(buf, bufsize, "%s%d: ",
356 uc_priv->bank_name ? uc_priv->bank_name : "", offset);
359 requested = gpio_is_requested(bank, offset);
360 snprintf(buf, bufsize, "%s: %d [%c]%s%s",
361 is_output ? "out" : " in",
362 _get_gpio_value(bank, offset),
363 requested ? 'x' : ' ',
364 requested ? " " : "",
370 static int omap_gpio_request(struct udevice *dev, unsigned offset,
373 struct gpio_bank *bank = dev_get_priv(dev);
375 if (gpio_is_requested(bank, offset))
378 strncpy(bank->label[offset], label, GPIO_NAME_SIZE);
379 bank->label[offset][GPIO_NAME_SIZE - 1] = '\0';
384 static int omap_gpio_free(struct udevice *dev, unsigned offset)
386 struct gpio_bank *bank = dev_get_priv(dev);
389 ret = check_requested(dev, offset, __func__);
392 bank->label[offset][0] = '\0';
397 static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
399 struct gpio_bank *bank = dev_get_priv(dev);
401 if (!gpio_is_requested(bank, offset))
404 /* GPIOF_FUNC is not implemented yet */
405 if (_get_gpio_direction(bank->base, offset))
411 static const struct dm_gpio_ops gpio_omap_ops = {
412 .request = omap_gpio_request,
413 .free = omap_gpio_free,
414 .direction_input = omap_gpio_direction_input,
415 .direction_output = omap_gpio_direction_output,
416 .get_value = omap_gpio_get_value,
417 .set_value = omap_gpio_set_value,
418 .get_function = omap_gpio_get_function,
419 .get_state = omap_gpio_get_state,
422 static int omap_gpio_probe(struct udevice *dev)
424 struct gpio_bank *bank = dev_get_priv(dev);
425 struct omap_gpio_platdata *plat = dev_get_platdata(dev);
426 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
429 sprintf(name, "GPIO%d_", plat->bank_index);
433 uc_priv->bank_name = str;
434 uc_priv->gpio_count = GPIO_PER_BANK;
435 bank->base = (void *)plat->base;
436 bank->method = plat->method;
441 U_BOOT_DRIVER(gpio_omap) = {
444 .ops = &gpio_omap_ops,
445 .probe = omap_gpio_probe,
446 .priv_auto_alloc_size = sizeof(struct gpio_bank),
449 #endif /* CONFIG_DM_GPIO */