Minor led fix
[tomato.git] / release / src / router / shared / led.c
blob5a487cd6aa42a019c4abbf7c8e0f3eca2b894746
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <bcmnvram.h>
16 #include "utils.h"
17 #include "shared.h"
20 const char *led_names[] = { "wlan", "diag", "white", "amber", "dmz", "aoss", "bridge", "mystery" };
23 // --- move begin ---
24 #if TOMATO_N
26 #else
28 void gpio_write(uint32_t bit, int en)
30 int f;
31 uint32_t r;
33 if ((f = open("/dev/gpio/control", O_RDWR)) < 0) return;
34 read(f, &r, sizeof(r));
35 r &= ~bit;
36 write(f, &r, sizeof(r));
37 close(f);
39 if ((f = open("/dev/gpio/outen", O_RDWR)) < 0) return;
40 read(f, &r, sizeof(r));
41 r |= bit;
42 write(f, &r, sizeof(r));
43 close(f);
45 if ((f = open("/dev/gpio/out", O_RDWR)) < 0) return;
46 read(f, &r, sizeof(r));
47 if (en) r |= bit;
48 else r &= ~bit;
49 write(f, &r, sizeof(r));
50 close(f);
53 uint32_t gpio_read(void)
55 int f;
56 uint32_t r;
58 if ((f = open("/dev/gpio/in", O_RDONLY)) < 0) return ~0;
59 if (read(f, &r, sizeof(r)) != sizeof(r)) r = ~0;
60 close(f);
61 return r;
64 #endif
66 int nvget_gpio(const char *name, int *gpio, int *inv)
68 char *p;
69 uint32_t n;
71 if (((p = nvram_get(name)) != NULL) && (*p)) {
72 n = strtoul(p, NULL, 0);
73 if ((n & 0xFFFFFF70) == 0) {
74 *gpio = (n & 15);
75 *inv = ((n & 0x80) != 0);
76 return 1;
79 return 0;
81 // --- move end ---
84 int led(int which, int mode)
86 // WLAN DIAG WHITE AMBER DMZ AOSS BRIDG MYST
87 // ----- ----- ----- ----- ----- ----- ----- -----
88 static int wrt54g[] = { 0, 1, 2, 3, 7, 255, 255, 255 };
89 static int wrtsl[] = { 255, 1, 5, 7, 0, 255, 255, 255 };
90 static int whrg54[] = { 2, 7, 255, 255, 255, 6, 1, 3 };
91 static int wbr2g54[] = { 255, -1, 255, 255, 255, -6, 255, 255 };
92 static int wzrg54[] = { 2, 7, 255, 255, 255, 6, 255, 255 };
93 static int wr850g1[] = { 7, 3, 255, 255, 255, 255, 255, 255 };
94 static int wr850g2[] = { 0, 1, 255, 255, 255, 255, 255, 255 };
95 static int wtr54gs[] = { 1, -1, 255, 255, 255, 255, 255, 255 };
96 char s[16];
97 int n;
98 int b;
100 if ((which < 0) || (which >= LED_COUNT)) return 0;
102 switch (nvram_match("led_override", "1") ? MODEL_UNKNOWN : get_model()) {
103 case MODEL_WRT54G:
104 if (check_hw_type() == HW_BCM4702) {
105 // G v1.x
106 if ((which != LED_DIAG) && (which != LED_DMZ)) return 0;
107 if (mode != LED_PROBE) {
108 if (f_read_string("/proc/sys/diag", s, sizeof(s)) > 0) {
109 b = (which == LED_DMZ) ? 1 : 4;
110 n = atoi(s);
111 sprintf(s, "%u", mode ? (n | b) : (n & ~b));
112 f_write_string("/proc/sys/diag", s, 0, 0);
115 return 1;
117 switch (which) {
118 case LED_AMBER:
119 case LED_WHITE:
120 if (!supports(SUP_WHAM_LED)) return 0;
121 break;
123 b = wrt54g[which];
124 break;
125 case MODEL_WTR54GS:
126 b = wtr54gs[which];
127 break;
128 case MODEL_WRTSL54GS:
129 b = wrtsl[which];
130 break;
131 case MODEL_WHRG54S:
132 case MODEL_WHRHPG54:
133 case MODEL_WHRG125:
134 b = whrg54[which];
135 break;
136 case MODEL_WZRG54:
137 case MODEL_WZRHPG54:
138 case MODEL_WZRRSG54:
139 case MODEL_WZRRSG54HP:
140 case MODEL_WVRG54NF:
141 case MODEL_WHR2A54G54:
142 case MODEL_WHR3AG54:
143 case MODEL_WZRG108:
144 b = wzrg54[which];
145 break;
147 case MODEL_WHR2A54G54:
148 if (which != LED_DIAG) return 0;
149 b = 7;
150 break;
152 case MODEL_WBRG54:
153 if (which != LED_DIAG) return 0;
154 b = 7;
155 break;
156 case MODEL_WBR2G54:
157 b = wbr2g54[which];
158 break;
159 case MODEL_WR850GV1:
160 b = wr850g1[which];
161 break;
162 case MODEL_WR850GV2:
163 case MODEL_WR100:
164 b = wr850g2[which];
165 break;
166 case MODEL_WL500GP:
167 if (which != LED_DIAG) return 0;
168 b = -1; // power light
169 break;
170 case MODEL_WL500W:
171 if (which != LED_DIAG) return 0;
172 b = -5; // power light
173 break;
174 case MODEL_WL520GU:
175 if (which != LED_DIAG) return 0;
176 b = 0; // Invert power light as diag indicator
177 if (mode != LED_PROBE) mode = !mode;
178 break;
180 case MODEL_RT390W:
181 break;
183 case MODEL_MN700:
184 if (which != LED_DIAG) return 0;
185 b = 6;
186 break;
187 case MODEL_WLA2G54L:
188 if (which != LED_DIAG) return 0;
189 b = 1;
190 break;
191 default:
192 sprintf(s, "led_%s", led_names[which]);
193 if (nvget_gpio(s, &b, &n)) {
194 if ((mode != LED_PROBE) && (n)) mode = !mode;
195 goto SET;
197 return 0;
200 if (b < 0) {
201 if (b == -99) b = 1; // -0 substitute
202 else b = -b;
204 else if (mode != LED_PROBE) {
205 mode = !mode;
208 SET:
209 if (b < 16) {
210 if (mode != LED_PROBE) {
211 gpio_write(1 << b, mode);
213 return 1;
216 return 0;