Commit c5530555f82f6fbaf51656e9ba10e295d3c5f195
1 parent
4638b21f2e
Exists in
master
and in
55 other branches
Blackfin: unify custom gpio commands
Now that we have a unified gpio layer, the misc partial gpio commands can be unified and made complete (support all possible gpios). Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Showing 14 changed files with 127 additions and 387 deletions Side-by-side Diff
- arch/blackfin/cpu/Makefile
- arch/blackfin/cpu/cmd_gpio.c
- board/bf537-stamp/Makefile
- board/bf537-stamp/cmd_bf537led.c
- board/cm-bf527/Makefile
- board/cm-bf527/gpio.c
- board/cm-bf537e/Makefile
- board/cm-bf537e/flash.c
- board/cm-bf537u/Makefile
- board/cm-bf537u/flash.c
- board/tcm-bf537/Makefile
- board/tcm-bf537/flash.c
- include/configs/bf537-stamp.h
- include/configs/bfin_adi_common.h
arch/blackfin/cpu/Makefile
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 | + | |
12 | +#include <asm/blackfin.h> | |
13 | +#include <asm/gpio.h> | |
14 | + | |
15 | +enum { | |
16 | + GPIO_INPUT, | |
17 | + GPIO_SET, | |
18 | + GPIO_CLEAR, | |
19 | + GPIO_TOGGLE, | |
20 | +}; | |
21 | + | |
22 | +int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
23 | +{ | |
24 | + if (argc == 2 && !strcmp(argv[1], "status")) { | |
25 | + bfin_gpio_labels(); | |
26 | + return 0; | |
27 | + } | |
28 | + | |
29 | + if (argc != 3) { | |
30 | + show_usage: | |
31 | + printf("Usage:\n%s\n", cmdtp->usage); | |
32 | + return 1; | |
33 | + } | |
34 | + | |
35 | + /* parse the behavior */ | |
36 | + ulong sub_cmd; | |
37 | + switch (argv[1][0]) { | |
38 | + case 'i': sub_cmd = GPIO_INPUT; break; | |
39 | + case 's': sub_cmd = GPIO_SET; break; | |
40 | + case 'c': sub_cmd = GPIO_CLEAR; break; | |
41 | + case 't': sub_cmd = GPIO_TOGGLE; break; | |
42 | + default: goto show_usage; | |
43 | + } | |
44 | + | |
45 | + /* parse the pin with format: [p][port]<#> */ | |
46 | + const char *str_pin = argv[2]; | |
47 | + | |
48 | + /* grab the [p]<port> portion */ | |
49 | + ulong port_base; | |
50 | + if (*str_pin == 'p') ++str_pin; | |
51 | + switch (*str_pin) { | |
52 | +#ifdef GPIO_PA0 | |
53 | + case 'a': port_base = GPIO_PA0; break; | |
54 | +#endif | |
55 | +#ifdef GPIO_PB0 | |
56 | + case 'b': port_base = GPIO_PB0; break; | |
57 | +#endif | |
58 | +#ifdef GPIO_PC0 | |
59 | + case 'c': port_base = GPIO_PC0; break; | |
60 | +#endif | |
61 | +#ifdef GPIO_PD0 | |
62 | + case 'd': port_base = GPIO_PD0; break; | |
63 | +#endif | |
64 | +#ifdef GPIO_PE0 | |
65 | + case 'e': port_base = GPIO_PE0; break; | |
66 | +#endif | |
67 | +#ifdef GPIO_PF0 | |
68 | + case 'f': port_base = GPIO_PF0; break; | |
69 | +#endif | |
70 | +#ifdef GPIO_PG0 | |
71 | + case 'g': port_base = GPIO_PG0; break; | |
72 | +#endif | |
73 | +#ifdef GPIO_PH0 | |
74 | + case 'h': port_base = GPIO_PH0; break; | |
75 | +#endif | |
76 | +#ifdef GPIO_PI0 | |
77 | + case 'i': port_base = GPIO_PI0; break; | |
78 | +#endif | |
79 | +#ifdef GPIO_PJ | |
80 | + case 'j': port_base = GPIO_PJ0; break; | |
81 | +#endif | |
82 | + default: goto show_usage; | |
83 | + } | |
84 | + | |
85 | + /* grab the <#> portion */ | |
86 | + ulong pin = simple_strtoul(str_pin + 1, NULL, 10); | |
87 | + if (pin > 15) | |
88 | + goto show_usage; | |
89 | + | |
90 | + /* grab the pin before we tweak it */ | |
91 | + ulong gpio = port_base + pin; | |
92 | + gpio_request(gpio, "cmd_gpio"); | |
93 | + | |
94 | + /* finally, let's do it: set direction and exec command */ | |
95 | + if (sub_cmd == GPIO_INPUT) { | |
96 | + gpio_direction_input(gpio); | |
97 | + printf("gpio: pin %lu on port %c set to input\n", pin, *str_pin); | |
98 | + return 0; | |
99 | + } | |
100 | + | |
101 | + ulong value; | |
102 | + switch (sub_cmd) { | |
103 | + case GPIO_SET: value = 1; break; | |
104 | + case GPIO_CLEAR: value = 0; break; | |
105 | + case GPIO_TOGGLE: value = !gpio_get_value(gpio); break; | |
106 | + default: goto show_usage; | |
107 | + } | |
108 | + gpio_direction_output(gpio, value); | |
109 | + printf("gpio: pin %lu on port %c (gpio %lu) value is %lu\n", | |
110 | + pin, *str_pin, gpio, value); | |
111 | + | |
112 | + gpio_free(gpio); | |
113 | + | |
114 | + return 0; | |
115 | +} | |
116 | + | |
117 | +U_BOOT_CMD(gpio, 3, 0, do_gpio, | |
118 | + "set/clear/toggle gpio output pins", | |
119 | + "<set|clear|toggle> <port><pin>\n" | |
120 | + " - set/clear/toggle the specified pin (e.g. PF10)"); |
board/bf537-stamp/Makefile
board/bf537-stamp/cmd_bf537led.c
1 | -/* | |
2 | - * U-boot - cmd_bf537led.c | |
3 | - * | |
4 | - * Copyright (C) 2006 Aaron Gage, Ocean Optics Inc. | |
5 | - * | |
6 | - * See file CREDITS for list of people who contributed to this | |
7 | - * project. | |
8 | - * | |
9 | - * This program is free software; you can redistribute it and/or | |
10 | - * modify it under the terms of the GNU General Public License as | |
11 | - * published by the Free Software Foundation; either version 2 of | |
12 | - * the License, or (at your option) any later version. | |
13 | - * | |
14 | - * This program is distributed in the hope that it will be useful, | |
15 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | - * GNU General Public License for more details. | |
18 | - * | |
19 | - * You should have received a copy of the GNU General Public License | |
20 | - * along with this program; if not, write to the Free Software | |
21 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
22 | - * MA 02111-1307 USA | |
23 | - */ | |
24 | -#include <common.h> | |
25 | -#include <config.h> | |
26 | -#include <command.h> | |
27 | -#include <asm/blackfin.h> | |
28 | -#include <asm/string.h> | |
29 | -#ifdef CONFIG_BF537_STAMP_LEDCMD | |
30 | - | |
31 | -/* Define the command usage in a reusable way */ | |
32 | -#define USAGE_LONG \ | |
33 | - "led <number> <action>\n" \ | |
34 | - " <number> - Index (0-5) of LED to change, or \"all\"\n" \ | |
35 | - " <action> - Must be one of:\n" \ | |
36 | - " on off toggle" | |
37 | - | |
38 | -/* Number of LEDs supported by the board */ | |
39 | -#define NUMBER_LEDS 6 | |
40 | -/* The BF537 stamp has 6 LEDs. This mask indicates that all should be lit. */ | |
41 | -#define LED_ALL_MASK 0x003F | |
42 | - | |
43 | -void show_cmd_usage(void); | |
44 | -void set_led_state(int index, int state); | |
45 | -void configure_GPIO_to_output(int index); | |
46 | - | |
47 | -/* Map of LEDs according to their GPIO ports. This can be rearranged or | |
48 | - * otherwise changed to account for different GPIO configurations. | |
49 | - */ | |
50 | -int led_ports[] = { PF6, PF7, PF8, PF9, PF10, PF11 }; | |
51 | - | |
52 | -#define ACTION_TOGGLE -1 | |
53 | -#define ACTION_OFF 0 | |
54 | -#define ACTION_ON 1 | |
55 | - | |
56 | -#define LED_STATE_OFF 0 | |
57 | -#define LED_STATE_ON 1 | |
58 | - | |
59 | -/* This is a trivial atoi implementation since we don't have one available */ | |
60 | -int atoi(char *string) | |
61 | -{ | |
62 | - int length; | |
63 | - int retval = 0; | |
64 | - int i; | |
65 | - int sign = 1; | |
66 | - | |
67 | - length = strlen(string); | |
68 | - for (i = 0; i < length; i++) { | |
69 | - if (0 == i && string[0] == '-') { | |
70 | - sign = -1; | |
71 | - continue; | |
72 | - } | |
73 | - if (string[i] > '9' || string[i] < '0') { | |
74 | - break; | |
75 | - } | |
76 | - retval *= 10; | |
77 | - retval += string[i] - '0'; | |
78 | - } | |
79 | - retval *= sign; | |
80 | - return retval; | |
81 | -} | |
82 | - | |
83 | -int do_bf537led(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) | |
84 | -{ | |
85 | - int led_mask = 0; | |
86 | - int led_current_state = 0; | |
87 | - int action = ACTION_OFF; | |
88 | - int temp; | |
89 | - | |
90 | - if (3 != argc) { | |
91 | - /* Not enough arguments, so just show usage information */ | |
92 | - show_cmd_usage(); | |
93 | - return 1; | |
94 | - } | |
95 | - | |
96 | - if (strcmp(argv[1], "all") == 0) { | |
97 | - led_mask = LED_ALL_MASK; | |
98 | - } else { | |
99 | - temp = atoi(argv[1]); | |
100 | - if (temp < 0 || temp >= NUMBER_LEDS) { | |
101 | - printf("Invalid LED number [%s]\n", argv[1]); | |
102 | - show_cmd_usage(); | |
103 | - return 2; | |
104 | - } | |
105 | - led_mask |= (1 << temp); | |
106 | - } | |
107 | - | |
108 | - if (strcmp(argv[2], "off") == 0) { | |
109 | - action = ACTION_OFF; | |
110 | - } else if (strcmp(argv[2], "on") == 0) { | |
111 | - action = ACTION_ON; | |
112 | - } else if (strcmp(argv[2], "toggle") == 0) { | |
113 | - action = ACTION_TOGGLE; | |
114 | - } else { | |
115 | - printf("Invalid action [%s]\n", argv[2]); | |
116 | - show_cmd_usage(); | |
117 | - return 3; | |
118 | - } | |
119 | - | |
120 | - for (temp = 0; temp < NUMBER_LEDS; temp++) { | |
121 | - if ((led_mask & (1 << temp)) > 0) { | |
122 | - /* | |
123 | - * It is possible that the user has wired one of PF6-PF11 to | |
124 | - * something other than an LED, so this will only change a pin | |
125 | - * to output if the user has indicated a state change. This may | |
126 | - * happen a lot, but this way is safer than just setting all pins | |
127 | - * to output. | |
128 | - */ | |
129 | - configure_GPIO_to_output(temp); | |
130 | - | |
131 | - led_current_state = | |
132 | - ((*pPORTFIO & led_ports[temp]) > | |
133 | - 0) ? LED_STATE_ON : LED_STATE_OFF; | |
134 | - /* | |
135 | - printf("LED state for index %d (%x) is %d\n", temp, led_ports[temp], | |
136 | - led_current_state); | |
137 | - printf("*pPORTFIO is %x\n", *pPORTFIO); | |
138 | - */ | |
139 | - if (ACTION_ON == action | |
140 | - || (ACTION_TOGGLE == action | |
141 | - && 0 == led_current_state)) { | |
142 | - printf("Turning LED %d on\n", temp); | |
143 | - set_led_state(temp, LED_STATE_ON); | |
144 | - } else { | |
145 | - printf("Turning LED %d off\n", temp); | |
146 | - set_led_state(temp, LED_STATE_OFF); | |
147 | - } | |
148 | - } | |
149 | - } | |
150 | - | |
151 | - return 0; | |
152 | -} | |
153 | - | |
154 | -/* | |
155 | - * The GPIO pins that go to the LEDs on the BF537 stamp must be configured | |
156 | - * as output. This function simply configures them that way. This could | |
157 | - * be done to all of the GPIO lines at once, but if a user is using a | |
158 | - * custom board, this will try to be nice and only change the GPIO lines | |
159 | - * that the user specifically names. | |
160 | - */ | |
161 | -void configure_GPIO_to_output(int index) | |
162 | -{ | |
163 | - int port; | |
164 | - | |
165 | - port = led_ports[index]; | |
166 | - | |
167 | - /* Clear the Port F Function Enable Register */ | |
168 | - *pPORTF_FER &= ~port; | |
169 | - /* Set the Port F I/O direction register */ | |
170 | - *pPORTFIO_DIR |= port; | |
171 | - /* Clear the Port F I/O Input Enable Register */ | |
172 | - *pPORTFIO_INEN &= ~port; | |
173 | -} | |
174 | - | |
175 | -/* Enforce the given state on the GPIO line for the indicated LED */ | |
176 | -void set_led_state(int index, int state) | |
177 | -{ | |
178 | - int port; | |
179 | - | |
180 | - port = led_ports[index]; | |
181 | - | |
182 | - if (LED_STATE_OFF == state) { | |
183 | - /* Clear the bit to turn off the LED */ | |
184 | - *pPORTFIO &= ~port; | |
185 | - } else { | |
186 | - /* Set the bit to turn on the LED */ | |
187 | - *pPORTFIO |= port; | |
188 | - } | |
189 | -} | |
190 | - | |
191 | -/* Display usage information */ | |
192 | -void show_cmd_usage() | |
193 | -{ | |
194 | - printf("Usage:\n%s\n", USAGE_LONG); | |
195 | -} | |
196 | - | |
197 | -/* Register information for u-boot to find this command */ | |
198 | -U_BOOT_CMD(led, 3, 1, do_bf537led, | |
199 | - "Control BF537 stamp LEDs", USAGE_LONG); | |
200 | - | |
201 | -#endif |
board/cm-bf527/Makefile
board/cm-bf527/gpio.c
1 | -/* | |
2 | - * Control GPIO pins on the fly | |
3 | - * | |
4 | - * Copyright (c) 2008 Analog Devices Inc. | |
5 | - * | |
6 | - * Licensed under the GPL-2 or later. | |
7 | - */ | |
8 | - | |
9 | -#include <common.h> | |
10 | -#include <command.h> | |
11 | - | |
12 | -#include <asm/blackfin.h> | |
13 | - | |
14 | -int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
15 | -{ | |
16 | - if (argc != 3) { | |
17 | - show_usage: | |
18 | - printf("Usage:\n%s\n", cmdtp->usage); | |
19 | - return 1; | |
20 | - } | |
21 | - | |
22 | - /* parse the behavior */ | |
23 | - ulong port_cmd = 0; | |
24 | - switch (argv[1][0]) { | |
25 | - case 'i': break; | |
26 | - case 's': port_cmd = (PORTFIO_SET - PORTFIO); break; | |
27 | - case 'c': port_cmd = (PORTFIO_CLEAR - PORTFIO); break; | |
28 | - case 't': port_cmd = (PORTFIO_TOGGLE - PORTFIO); break; | |
29 | - default: goto show_usage; | |
30 | - } | |
31 | - | |
32 | - /* parse the pin with format: [p]<fgh><#> */ | |
33 | - const char *str_pin = argv[2]; | |
34 | - | |
35 | - /* grab the [p]<fgh> portion */ | |
36 | - ulong port_base; | |
37 | - if (*str_pin == 'p') ++str_pin; | |
38 | - switch (*str_pin) { | |
39 | - case 'f': port_base = PORTFIO; break; | |
40 | - case 'g': port_base = PORTGIO; break; | |
41 | - case 'h': port_base = PORTHIO; break; | |
42 | - default: goto show_usage; | |
43 | - } | |
44 | - | |
45 | - /* grab the <#> portion */ | |
46 | - ulong pin = simple_strtoul(str_pin+1, NULL, 10); | |
47 | - ulong pin_mask = (1 << pin); | |
48 | - if (pin > 15) | |
49 | - goto show_usage; | |
50 | - | |
51 | - /* finally, let's do it: set direction and exec command */ | |
52 | - switch (*str_pin) { | |
53 | - case 'f': bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~pin_mask); break; | |
54 | - case 'g': bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~pin_mask); break; | |
55 | - case 'h': bfin_write_PORTH_FER(bfin_read_PORTH_FER() & ~pin_mask); break; | |
56 | - } | |
57 | - | |
58 | - ulong port_dir = port_base + (PORTFIO_DIR - PORTFIO); | |
59 | - if (argv[1][0] == 'i') | |
60 | - bfin_write16(port_dir, bfin_read16(port_dir) & ~pin_mask); | |
61 | - else { | |
62 | - bfin_write16(port_dir, bfin_read16(port_dir) | pin_mask); | |
63 | - bfin_write16(port_base + port_cmd, pin_mask); | |
64 | - } | |
65 | - | |
66 | - printf("gpio: pin %li on port %c has been %c\n", pin, *str_pin, argv[1][0]); | |
67 | - | |
68 | - return 0; | |
69 | -} | |
70 | - | |
71 | -U_BOOT_CMD(gpio, 3, 0, do_gpio, | |
72 | - "gpio - set/clear/toggle gpio output pins\n", | |
73 | - "<s|c|t> <port><pin>\n" | |
74 | - " - set/clear/toggle the specified pin\n"); |
board/cm-bf537e/Makefile
board/cm-bf537e/flash.c
1 | -/* | |
2 | - * flash.c - helper commands for working with GPIO-assisted flash | |
3 | - * | |
4 | - * Copyright (c) 2005-2009 Analog Devices Inc. | |
5 | - * | |
6 | - * Licensed under the GPL-2 or later. | |
7 | - */ | |
8 | - | |
9 | -#include <common.h> | |
10 | -#include <command.h> | |
11 | -#include <asm/blackfin.h> | |
12 | -#include "gpio_cfi_flash.h" | |
13 | - | |
14 | -int do_pf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
15 | -{ | |
16 | - ulong faddr = CONFIG_SYS_FLASH_BASE; | |
17 | - ushort data; | |
18 | - ulong dflg; | |
19 | - | |
20 | - if (argc > 1) { | |
21 | - dflg = simple_strtoul(argv[1], NULL, 16); | |
22 | - faddr |= (dflg << 21); | |
23 | - gpio_cfi_flash_swizzle((void *)faddr); | |
24 | - } else { | |
25 | - data = bfin_read_PORTFIO(); | |
26 | - printf("Port F data %04x (PF4:%i)\n", data, !!(data & PF4)); | |
27 | - } | |
28 | - | |
29 | - return 0; | |
30 | -} | |
31 | - | |
32 | -U_BOOT_CMD(pf, 3, 0, do_pf, | |
33 | - "set/clear PF4 GPIO flash bank switch\n", | |
34 | - "<pf4> - set PF4 GPIO pin state\n"); |
board/cm-bf537u/Makefile
board/cm-bf537u/flash.c
1 | -/* | |
2 | - * flash.c - helper commands for working with GPIO-assisted flash | |
3 | - * | |
4 | - * Copyright (c) 2005-2009 Analog Devices Inc. | |
5 | - * | |
6 | - * Licensed under the GPL-2 or later. | |
7 | - */ | |
8 | - | |
9 | -#include <common.h> | |
10 | -#include <command.h> | |
11 | -#include <asm/blackfin.h> | |
12 | -#include "gpio_cfi_flash.h" | |
13 | - | |
14 | -int do_ph(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
15 | -{ | |
16 | - ulong faddr = CONFIG_SYS_FLASH_BASE; | |
17 | - ushort data; | |
18 | - ulong dflg; | |
19 | - | |
20 | - if (argc > 1) { | |
21 | - dflg = simple_strtoul(argv[1], NULL, 16); | |
22 | - faddr |= (dflg << 21); | |
23 | - gpio_cfi_flash_swizzle((void *)faddr); | |
24 | - } else { | |
25 | - data = bfin_read_PORTHIO(); | |
26 | - printf("Port H data %04x (PH0:%i)\n", data, !!(data & PH0)); | |
27 | - } | |
28 | - | |
29 | - return 0; | |
30 | -} | |
31 | - | |
32 | -U_BOOT_CMD(ph, 3, 0, do_ph, | |
33 | - "set/clear PH0 GPIO flash bank switch\n", | |
34 | - "<ph0> - set PH0 GPIO pin state\n"); |
board/tcm-bf537/Makefile
board/tcm-bf537/flash.c
1 | -/* | |
2 | - * flash.c - helper commands for working with GPIO-assisted flash | |
3 | - * | |
4 | - * Copyright (c) 2005-2009 Analog Devices Inc. | |
5 | - * | |
6 | - * Licensed under the GPL-2 or later. | |
7 | - */ | |
8 | - | |
9 | -#include <common.h> | |
10 | -#include <command.h> | |
11 | -#include <asm/blackfin.h> | |
12 | -#include "gpio_cfi_flash.h" | |
13 | - | |
14 | -int do_pf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
15 | -{ | |
16 | - ulong faddr = CONFIG_SYS_FLASH_BASE; | |
17 | - ushort data; | |
18 | - ulong dflg; | |
19 | - | |
20 | - if (argc == 3) { | |
21 | - dflg = simple_strtoul(argv[1], NULL, 16); | |
22 | - faddr |= (dflg << 21); | |
23 | - dflg = simple_strtoul(argv[2], NULL, 16); | |
24 | - faddr |= (dflg << 22); | |
25 | - gpio_cfi_flash_swizzle((void *)faddr); | |
26 | - } else { | |
27 | - data = bfin_read_PORTFIO(); | |
28 | - printf("Port F data %04x (PF4:%i PF5:%i)\n", data, | |
29 | - !!(data & PF4), !!(data & PF5)); | |
30 | - } | |
31 | - | |
32 | - return 0; | |
33 | -} | |
34 | - | |
35 | -U_BOOT_CMD(pf, 3, 0, do_pf, | |
36 | - "set/clear PF4/PF5 GPIO flash bank switch\n", | |
37 | - "<pf4> <pf5> - set PF4/PF5 GPIO pin state\n"); |
include/configs/bf537-stamp.h
include/configs/bfin_adi_common.h