]>
Commit | Line | Data |
---|---|---|
26bf7dec AL |
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-blackfin/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\n" | |
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 *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", USAGE_LONG); | |
195 | } | |
196 | ||
197 | /* Register information for u-boot to find this command */ | |
198 | U_BOOT_CMD(led, 3, 1, do_bf537led, | |
2fb2604d | 199 | "Control BF537 stamp LEDs", USAGE_LONG); |
26bf7dec AL |
200 | |
201 | #endif |