]>
Commit | Line | Data |
---|---|---|
59e4be94 MF |
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 | ||
54841ab5 | 14 | int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
59e4be94 MF |
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"); |