]> git.sur5r.net Git - u-boot/commitdiff
gpio: generalize for all generic gpio providers
authorMike Frysinger <vapier@gentoo.org>
Sun, 3 Apr 2011 08:40:46 +0000 (04:40 -0400)
committerMike Frysinger <vapier@gentoo.org>
Wed, 13 Apr 2011 19:56:51 +0000 (15:56 -0400)
The Blackfin gpio command isn't terribly Blackfin-specific.  So generalize
the few pieces into two new optional helpers:
name_to_gpio() - turn a string name into a GPIO #
gpio_status() - display current pin bindings (think /proc/gpio)

Once these pieces are pulled out, we can relocate the cmd_gpio.c into the
common directory.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
arch/blackfin/cpu/Makefile
arch/blackfin/cpu/cmd_gpio.c [deleted file]
arch/blackfin/include/asm/gpio.h
common/Makefile
common/cmd_gpio.c [new file with mode: 0644]

index 4a9e577a872ecb516fb77ce3aac9184a0f399b76..df10f1bc653295c64c132df90347e6b76160bc97 100644 (file)
@@ -18,7 +18,6 @@ CEXTRA   := initcode.o
 SEXTRA   := start.o
 SOBJS    := interrupt.o cache.o
 COBJS-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount.o
-COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 COBJS-y  += cpu.o
 COBJS-y  += gpio.o
 COBJS-y  += interrupts.o
diff --git a/arch/blackfin/cpu/cmd_gpio.c b/arch/blackfin/cpu/cmd_gpio.c
deleted file mode 100644 (file)
index e96413b..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Control GPIO pins on the fly
- *
- * Copyright (c) 2008-2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <linux/ctype.h>
-
-#include <asm/blackfin.h>
-#include <asm/gpio.h>
-
-enum {
-       GPIO_INPUT,
-       GPIO_SET,
-       GPIO_CLEAR,
-       GPIO_TOGGLE,
-};
-
-int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       if (argc == 2 && !strcmp(argv[1], "status")) {
-               bfin_gpio_labels();
-               return 0;
-       }
-
-       if (argc != 3)
- show_usage:
-               return cmd_usage(cmdtp);
-
-       /* parse the behavior */
-       ulong sub_cmd;
-       switch (argv[1][0]) {
-               case 'i': sub_cmd = GPIO_INPUT;  break;
-               case 's': sub_cmd = GPIO_SET;    break;
-               case 'c': sub_cmd = GPIO_CLEAR;  break;
-               case 't': sub_cmd = GPIO_TOGGLE; break;
-               default:  goto show_usage;
-       }
-
-       /* parse the pin with format: [p][port]<#> */
-       const char *str_pin = argv[2];
-
-       /* grab the [p]<port> portion */
-       ulong port_base;
-       if (tolower(*str_pin) == 'p') ++str_pin;
-       switch (tolower(*str_pin)) {
-#ifdef GPIO_PA0
-               case 'a': port_base = GPIO_PA0; break;
-#endif
-#ifdef GPIO_PB0
-               case 'b': port_base = GPIO_PB0; break;
-#endif
-#ifdef GPIO_PC0
-               case 'c': port_base = GPIO_PC0; break;
-#endif
-#ifdef GPIO_PD0
-               case 'd': port_base = GPIO_PD0; break;
-#endif
-#ifdef GPIO_PE0
-               case 'e': port_base = GPIO_PE0; break;
-#endif
-#ifdef GPIO_PF0
-               case 'f': port_base = GPIO_PF0; break;
-#endif
-#ifdef GPIO_PG0
-               case 'g': port_base = GPIO_PG0; break;
-#endif
-#ifdef GPIO_PH0
-               case 'h': port_base = GPIO_PH0; break;
-#endif
-#ifdef GPIO_PI0
-               case 'i': port_base = GPIO_PI0; break;
-#endif
-#ifdef GPIO_PJ
-               case 'j': port_base = GPIO_PJ0; break;
-#endif
-               default:  goto show_usage;
-       }
-
-       /* grab the <#> portion */
-       ulong pin = simple_strtoul(str_pin + 1, NULL, 10);
-       if (pin > 15)
-               goto show_usage;
-
-       /* grab the pin before we tweak it */
-       ulong gpio = port_base + pin;
-       gpio_request(gpio, "cmd_gpio");
-
-       /* finally, let's do it: set direction and exec command */
-       ulong value;
-       if (sub_cmd == GPIO_INPUT) {
-               gpio_direction_input(gpio);
-               value = gpio_get_value(gpio);
-       } else {
-               switch (sub_cmd) {
-                       case GPIO_SET:    value = 1; break;
-                       case GPIO_CLEAR:  value = 0; break;
-                       case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
-                       default:          goto show_usage;
-               }
-               gpio_direction_output(gpio, value);
-       }
-       printf("gpio: pin %lu on port %c (gpio %lu) value is %lu\n",
-               pin, *str_pin, gpio, value);
-
-       gpio_free(gpio);
-
-       return value;
-}
-
-U_BOOT_CMD(gpio, 3, 0, do_gpio,
-       "input/set/clear/toggle gpio output pins",
-       "<input|set|clear|toggle> <port><pin>\n"
-       "    - input/set/clear/toggle the specified pin (e.g. PF10)");
index b650ef080000ffbcb169c47a6d37eedf379d4a81..9c0e5d1954d87c7d2961a3732e04ed276fbf6f0d 100644 (file)
@@ -196,6 +196,59 @@ static inline int gpio_is_valid(int number)
        return number >= 0 && number < MAX_BLACKFIN_GPIOS;
 }
 
+#include <linux/ctype.h>
+
+static inline int name_to_gpio(const char *name)
+{
+       int port_base;
+
+       if (tolower(*name) == 'p') {
+               ++name;
+
+               switch (tolower(*name)) {
+#ifdef GPIO_PA0
+               case 'a': port_base = GPIO_PA0; break;
+#endif
+#ifdef GPIO_PB0
+               case 'b': port_base = GPIO_PB0; break;
+#endif
+#ifdef GPIO_PC0
+               case 'c': port_base = GPIO_PC0; break;
+#endif
+#ifdef GPIO_PD0
+               case 'd': port_base = GPIO_PD0; break;
+#endif
+#ifdef GPIO_PE0
+               case 'e': port_base = GPIO_PE0; break;
+#endif
+#ifdef GPIO_PF0
+               case 'f': port_base = GPIO_PF0; break;
+#endif
+#ifdef GPIO_PG0
+               case 'g': port_base = GPIO_PG0; break;
+#endif
+#ifdef GPIO_PH0
+               case 'h': port_base = GPIO_PH0; break;
+#endif
+#ifdef GPIO_PI0
+               case 'i': port_base = GPIO_PI0; break;
+#endif
+#ifdef GPIO_PJ
+               case 'j': port_base = GPIO_PJ0; break;
+#endif
+               default:  return -1;
+               }
+
+               ++name;
+       } else
+               port_base = 0;
+
+       return port_base + simple_strtoul(name, NULL, 10);
+}
+#define name_to_gpio(n) name_to_gpio(n)
+
+#define gpio_status() bfin_gpio_labels()
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ARCH_BLACKFIN_GPIO_H__ */
index 26380c6d8afc890dd35a37843b88c0dcda2edb6f..432a9de42d18a298a45e0854dd5c0ce2afb334e3 100644 (file)
@@ -98,6 +98,7 @@ COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o
 ifdef CONFIG_FPGA
 COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
 endif
+COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
 COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
 COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o
diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c
new file mode 100644 (file)
index 0000000..9c9de28
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Control GPIO pins on the fly
+ *
+ * Copyright (c) 2008-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include <asm/gpio.h>
+
+#ifndef name_to_gpio
+#define name_to_gpio(name) simple_strtoul(name, NULL, 10)
+#endif
+
+enum gpio_cmd {
+       GPIO_INPUT,
+       GPIO_SET,
+       GPIO_CLEAR,
+       GPIO_TOGGLE,
+};
+
+static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int gpio;
+       enum gpio_cmd sub_cmd;
+       ulong value;
+       const char *str_cmd, *str_gpio;
+
+#ifdef gpio_status
+       if (argc == 2 && !strcmp(argv[1], "status")) {
+               gpio_status();
+               return 0;
+       }
+#endif
+
+       if (argc != 3)
+ show_usage:
+               return cmd_usage(cmdtp);
+       str_cmd = argv[1];
+       str_gpio = argv[2];
+
+       /* parse the behavior */
+       switch (*str_cmd) {
+               case 'i': sub_cmd = GPIO_INPUT;  break;
+               case 's': sub_cmd = GPIO_SET;    break;
+               case 'c': sub_cmd = GPIO_CLEAR;  break;
+               case 't': sub_cmd = GPIO_TOGGLE; break;
+               default:  goto show_usage;
+       }
+
+       /* turn the gpio name into a gpio number */
+       gpio = name_to_gpio(str_gpio);
+       if (gpio < 0)
+               goto show_usage;
+
+       /* grab the pin before we tweak it */
+       gpio_request(gpio, "cmd_gpio");
+
+       /* finally, let's do it: set direction and exec command */
+       if (sub_cmd == GPIO_INPUT) {
+               gpio_direction_input(gpio);
+               value = gpio_get_value(gpio);
+       } else {
+               switch (sub_cmd) {
+                       case GPIO_SET:    value = 1; break;
+                       case GPIO_CLEAR:  value = 0; break;
+                       case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
+                       default:          goto show_usage;
+               }
+               gpio_direction_output(gpio, value);
+       }
+       printf("gpio: pin %s (gpio %i) value is %lu\n",
+               str_gpio, gpio, value);
+
+       gpio_free(gpio);
+
+       return value;
+}
+
+U_BOOT_CMD(gpio, 3, 0, do_gpio,
+       "input/set/clear/toggle gpio pins",
+       "<input|set|clear|toggle> <pin>\n"
+       "    - input/set/clear/toggle the specified pin");