uboot/cmd/gpio.c
<<
>>
Prefs
   1/*
   2 * Control GPIO pins on the fly
   3 *
   4 * Copyright (c) 2008-2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <common.h>
  10#include <command.h>
  11#include <errno.h>
  12#include <dm.h>
  13#include <asm/gpio.h>
  14
  15__weak int name_to_gpio(const char *name)
  16{
  17        return simple_strtoul(name, NULL, 10);
  18}
  19
  20enum gpio_cmd {
  21        GPIO_INPUT,
  22        GPIO_SET,
  23        GPIO_CLEAR,
  24        GPIO_TOGGLE,
  25};
  26
  27#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
  28
  29/* A few flags used by show_gpio() */
  30enum {
  31        FLAG_SHOW_ALL           = 1 << 0,
  32        FLAG_SHOW_BANK          = 1 << 1,
  33        FLAG_SHOW_NEWLINE       = 1 << 2,
  34};
  35
  36static void gpio_get_description(struct udevice *dev, const char *bank_name,
  37                                 int offset, int *flagsp)
  38{
  39        char buf[80];
  40        int ret;
  41
  42        ret = gpio_get_function(dev, offset, NULL);
  43        if (ret < 0)
  44                goto err;
  45        if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
  46                return;
  47        if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
  48                if (*flagsp & FLAG_SHOW_NEWLINE) {
  49                        putc('\n');
  50                        *flagsp &= ~FLAG_SHOW_NEWLINE;
  51                }
  52                printf("Bank %s:\n", bank_name);
  53                *flagsp &= ~FLAG_SHOW_BANK;
  54        }
  55
  56        ret = gpio_get_status(dev, offset, buf, sizeof(buf));
  57        if (ret)
  58                goto err;
  59
  60        printf("%s\n", buf);
  61        return;
  62err:
  63        printf("Error %d\n", ret);
  64}
  65
  66static int do_gpio_status(bool all, const char *gpio_name)
  67{
  68        struct udevice *dev;
  69        int banklen;
  70        int flags;
  71        int ret;
  72
  73        flags = 0;
  74        if (gpio_name && !*gpio_name)
  75                gpio_name = NULL;
  76        for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  77             dev;
  78             ret = uclass_next_device(&dev)) {
  79                const char *bank_name;
  80                int num_bits;
  81
  82                flags |= FLAG_SHOW_BANK;
  83                if (all)
  84                        flags |= FLAG_SHOW_ALL;
  85                bank_name = gpio_get_bank_info(dev, &num_bits);
  86                if (!num_bits) {
  87                        debug("GPIO device %s has no bits\n", dev->name);
  88                        continue;
  89                }
  90                banklen = bank_name ? strlen(bank_name) : 0;
  91
  92                if (!gpio_name || !bank_name ||
  93                    !strncmp(gpio_name, bank_name, banklen)) {
  94                        const char *p = NULL;
  95                        int offset;
  96
  97                        p = gpio_name + banklen;
  98                        if (gpio_name && *p) {
  99                                offset = simple_strtoul(p, NULL, 10);
 100                                gpio_get_description(dev, bank_name, offset,
 101                                                     &flags);
 102                        } else {
 103                                for (offset = 0; offset < num_bits; offset++) {
 104                                        gpio_get_description(dev, bank_name,
 105                                                             offset, &flags);
 106                                }
 107                        }
 108                }
 109                /* Add a newline between bank names */
 110                if (!(flags & FLAG_SHOW_BANK))
 111                        flags |= FLAG_SHOW_NEWLINE;
 112        }
 113
 114        return ret;
 115}
 116#endif
 117
 118static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 119{
 120        unsigned int gpio;
 121        enum gpio_cmd sub_cmd;
 122        int value;
 123        const char *str_cmd, *str_gpio = NULL;
 124        int ret;
 125#ifdef CONFIG_DM_GPIO
 126        bool all = false;
 127#endif
 128
 129        if (argc < 2)
 130 show_usage:
 131                return CMD_RET_USAGE;
 132        str_cmd = argv[1];
 133        argc -= 2;
 134        argv += 2;
 135#ifdef CONFIG_DM_GPIO
 136        if (argc > 0 && !strcmp(*argv, "-a")) {
 137                all = true;
 138                argc--;
 139                argv++;
 140        }
 141#endif
 142        if (argc > 0)
 143                str_gpio = *argv;
 144        if (!strncmp(str_cmd, "status", 2)) {
 145                /* Support deprecated gpio_status() */
 146#ifdef gpio_status
 147                gpio_status();
 148                return 0;
 149#elif defined(CONFIG_DM_GPIO)
 150                return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio));
 151#else
 152                goto show_usage;
 153#endif
 154        }
 155
 156        if (!str_gpio)
 157                goto show_usage;
 158
 159        /* parse the behavior */
 160        switch (*str_cmd) {
 161                case 'i': sub_cmd = GPIO_INPUT;  break;
 162                case 's': sub_cmd = GPIO_SET;    break;
 163                case 'c': sub_cmd = GPIO_CLEAR;  break;
 164                case 't': sub_cmd = GPIO_TOGGLE; break;
 165                default:  goto show_usage;
 166        }
 167
 168#if defined(CONFIG_DM_GPIO)
 169        /*
 170         * TODO(sjg@chromium.org): For now we must fit into the existing GPIO
 171         * framework, so we look up the name here and convert it to a GPIO number.
 172         * Once all GPIO drivers are converted to driver model, we can change the
 173         * code here to use the GPIO uclass interface instead of the numbered
 174         * GPIO compatibility layer.
 175         */
 176        ret = gpio_lookup_name(str_gpio, NULL, NULL, &gpio);
 177        if (ret) {
 178                printf("GPIO: '%s' not found\n", str_gpio);
 179                return cmd_process_error(cmdtp, ret);
 180        }
 181#else
 182        /* turn the gpio name into a gpio number */
 183        gpio = name_to_gpio(str_gpio);
 184        if (gpio < 0)
 185                goto show_usage;
 186#endif
 187        /* grab the pin before we tweak it */
 188        ret = gpio_request(gpio, "cmd_gpio");
 189        if (ret && ret != -EBUSY) {
 190                printf("gpio: requesting pin %u failed\n", gpio);
 191                return -1;
 192        }
 193
 194        /* finally, let's do it: set direction and exec command */
 195        if (sub_cmd == GPIO_INPUT) {
 196                gpio_direction_input(gpio);
 197                value = gpio_get_value(gpio);
 198        } else {
 199                switch (sub_cmd) {
 200                case GPIO_SET:
 201                        value = 1;
 202                        break;
 203                case GPIO_CLEAR:
 204                        value = 0;
 205                        break;
 206                case GPIO_TOGGLE:
 207                        value = gpio_get_value(gpio);
 208                        if (!IS_ERR_VALUE(value))
 209                                value = !value;
 210                        break;
 211                default:
 212                        goto show_usage;
 213                }
 214                gpio_direction_output(gpio, value);
 215        }
 216        printf("gpio: pin %s (gpio %i) value is ", str_gpio, gpio);
 217        if (IS_ERR_VALUE(value))
 218                printf("unknown (ret=%d)\n", value);
 219        else
 220                printf("%d\n", value);
 221        if (sub_cmd != GPIO_INPUT && !IS_ERR_VALUE(value)) {
 222                int nval = gpio_get_value(gpio);
 223
 224                if (IS_ERR_VALUE(nval))
 225                        printf("   Warning: no access to GPIO output value\n");
 226                else if (nval != value)
 227                        printf("   Warning: value of pin is still %d\n", nval);
 228        }
 229
 230        if (ret != -EBUSY)
 231                gpio_free(gpio);
 232
 233        return value;
 234}
 235
 236U_BOOT_CMD(gpio, 4, 0, do_gpio,
 237           "query and control gpio pins",
 238           "<input|set|clear|toggle> <pin>\n"
 239           "    - input/set/clear/toggle the specified pin\n"
 240           "gpio status [-a] [<bank> | <pin>]  - show [all/claimed] GPIOs");
 241