]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/blackfin/cpu/cmd_gpio.c
Merge branch 'master' of git://git.denx.de/u-boot-blackfin
[karo-tx-uboot.git] / arch / blackfin / cpu / cmd_gpio.c
1 /*
2  * Control GPIO pins on the fly
3  *
4  * Copyright (c) 2008-2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <common.h>
10 #include <command.h>
11 #include <linux/ctype.h>
12
13 #include <asm/blackfin.h>
14 #include <asm/gpio.h>
15
16 enum {
17         GPIO_INPUT,
18         GPIO_SET,
19         GPIO_CLEAR,
20         GPIO_TOGGLE,
21 };
22
23 int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
24 {
25         if (argc == 2 && !strcmp(argv[1], "status")) {
26                 bfin_gpio_labels();
27                 return 0;
28         }
29
30         if (argc != 3)
31  show_usage:
32                 return cmd_usage(cmdtp);
33
34         /* parse the behavior */
35         ulong sub_cmd;
36         switch (argv[1][0]) {
37                 case 'i': sub_cmd = GPIO_INPUT;  break;
38                 case 's': sub_cmd = GPIO_SET;    break;
39                 case 'c': sub_cmd = GPIO_CLEAR;  break;
40                 case 't': sub_cmd = GPIO_TOGGLE; break;
41                 default:  goto show_usage;
42         }
43
44         /* parse the pin with format: [p][port]<#> */
45         const char *str_pin = argv[2];
46
47         /* grab the [p]<port> portion */
48         ulong port_base;
49         if (tolower(*str_pin) == 'p') ++str_pin;
50         switch (tolower(*str_pin)) {
51 #ifdef GPIO_PA0
52                 case 'a': port_base = GPIO_PA0; break;
53 #endif
54 #ifdef GPIO_PB0
55                 case 'b': port_base = GPIO_PB0; break;
56 #endif
57 #ifdef GPIO_PC0
58                 case 'c': port_base = GPIO_PC0; break;
59 #endif
60 #ifdef GPIO_PD0
61                 case 'd': port_base = GPIO_PD0; break;
62 #endif
63 #ifdef GPIO_PE0
64                 case 'e': port_base = GPIO_PE0; break;
65 #endif
66 #ifdef GPIO_PF0
67                 case 'f': port_base = GPIO_PF0; break;
68 #endif
69 #ifdef GPIO_PG0
70                 case 'g': port_base = GPIO_PG0; break;
71 #endif
72 #ifdef GPIO_PH0
73                 case 'h': port_base = GPIO_PH0; break;
74 #endif
75 #ifdef GPIO_PI0
76                 case 'i': port_base = GPIO_PI0; break;
77 #endif
78 #ifdef GPIO_PJ
79                 case 'j': port_base = GPIO_PJ0; break;
80 #endif
81                 default:  goto show_usage;
82         }
83
84         /* grab the <#> portion */
85         ulong pin = simple_strtoul(str_pin + 1, NULL, 10);
86         if (pin > 15)
87                 goto show_usage;
88
89         /* grab the pin before we tweak it */
90         ulong gpio = port_base + pin;
91         gpio_request(gpio, "cmd_gpio");
92
93         /* finally, let's do it: set direction and exec command */
94         ulong value;
95         if (sub_cmd == GPIO_INPUT) {
96                 gpio_direction_input(gpio);
97                 value = gpio_get_value(gpio);
98         } else {
99                 switch (sub_cmd) {
100                         case GPIO_SET:    value = 1; break;
101                         case GPIO_CLEAR:  value = 0; break;
102                         case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
103                         default:          goto show_usage;
104                 }
105                 gpio_direction_output(gpio, value);
106         }
107         printf("gpio: pin %lu on port %c (gpio %lu) value is %lu\n",
108                 pin, *str_pin, gpio, value);
109
110         gpio_free(gpio);
111
112         return value;
113 }
114
115 U_BOOT_CMD(gpio, 3, 0, do_gpio,
116         "input/set/clear/toggle gpio output pins",
117         "<input|set|clear|toggle> <port><pin>\n"
118         "    - input/set/clear/toggle the specified pin (e.g. PF10)");