4 Copyright (C) 2006-2009 Jonathan Zarate
11 #include <sys/types.h>
21 const char *led_names
[] = { "wlan", "diag", "white", "amber", "dmz", "aoss", "bridge", "usb", "usb3", "5g"};
30 #include <sys/ioctl.h>
31 #include <linux_gpio.h>
33 static int _gpio_ioctl(int f
, int gpioreg
, unsigned int mask
, unsigned int val
)
35 struct gpio_ioctl gpio
;
40 if (ioctl(f
, gpioreg
, &gpio
) < 0) {
41 _dprintf("Invalid gpioreg %d\n", gpioreg
);
47 static int _gpio_open()
49 int f
= open("/dev/gpio", O_RDWR
);
51 _dprintf ("Failed to open /dev/gpio\n");
55 int gpio_open(uint32_t mask
)
61 if ((f
>= 0) && mask
) {
62 for (i
= 0; i
<= 15; i
++) {
64 if ((mask
& bit
) == bit
) {
65 _gpio_ioctl(f
, GPIO_IOC_RESERVE
, bit
, bit
);
66 _gpio_ioctl(f
, GPIO_IOC_OUTEN
, bit
, 0);
76 void gpio_write(uint32_t bit
, int en
)
80 if ((f
= gpio_open(0)) < 0) return;
82 _gpio_ioctl(f
, GPIO_IOC_RESERVE
, bit
, bit
);
83 _gpio_ioctl(f
, GPIO_IOC_OUTEN
, bit
, bit
);
84 _gpio_ioctl(f
, GPIO_IOC_OUT
, bit
, en
? bit
: 0);
88 uint32_t _gpio_read(int f
)
91 // r = _gpio_ioctl(f, GPIO_IOC_IN, 0xFFFF, 0);
92 r
= _gpio_ioctl(f
, GPIO_IOC_IN
, 0x07FF, 0);
97 uint32_t gpio_read(void)
102 if ((f
= gpio_open(0)) < 0) return ~0;
110 int gpio_open(uint32_t mask
)
112 int f
= open(DEV_GPIO(in
), O_RDONLY
|O_SYNC
);
114 _dprintf ("Failed to open %s\n", DEV_GPIO(in
));
118 void gpio_write(uint32_t bit
, int en
)
123 if ((f
= open(DEV_GPIO(control
), O_RDWR
)) < 0) return;
124 read(f
, &r
, sizeof(r
));
126 write(f
, &r
, sizeof(r
));
129 if ((f
= open(DEV_GPIO(outen
), O_RDWR
)) < 0) return;
130 read(f
, &r
, sizeof(r
));
132 write(f
, &r
, sizeof(r
));
135 if ((f
= open(DEV_GPIO(out
), O_RDWR
)) < 0) return;
136 read(f
, &r
, sizeof(r
));
139 write(f
, &r
, sizeof(r
));
143 uint32_t _gpio_read(int f
)
146 return (read(f
, &v
, sizeof(v
)) == sizeof(v
)) ? v
: ~0;
149 uint32_t gpio_read(void)
154 if ((f
= open(DEV_GPIO(in
), O_RDONLY
)) < 0) return ~0;
162 int nvget_gpio(const char *name
, int *gpio
, int *inv
)
167 if (((p
= nvram_get(name
)) != NULL
) && (*p
)) {
168 n
= strtoul(p
, NULL
, 0);
169 if ((n
& 0xFFFFFF70) == 0) {
171 *inv
= ((n
& 0x80) != 0);
180 int do_led(int which
, int mode
)
182 // WLAN DIAG WHITE AMBER DMZ AOSS BRIDG USB2 USB3 5G
183 // ----- ----- ----- ----- --- ---- ----- ---- ---- --
184 static int wrt54g
[] = { 255, 1, 2, 3, 7, 255, 255, 255, 255, 255};
185 static int wrtsl
[] = { 255, 1, 5, 7, 0, 255, 255, 255, 255, 255};
186 static int whrg54
[] = { 2, 7, 255, 255, 255, 6, 1, 3, 255, 255};
187 static int wbr2g54
[] = { 255, -1, 255, 255, 255, -6, 255, 255, 255, 255};
188 static int wzrg54
[] = { 2, 7, 255, 255, 255, 6, 255, 255, 255, 255};
189 static int wr850g1
[] = { 7, 3, 255, 255, 255, 255, 255, 255, 255, 255};
190 static int wr850g2
[] = { 0, 1, 255, 255, 255, 255, 255, 255, 255, 255};
191 static int wtr54gs
[] = { 1, -1, 255, 255, 255, 255, 255, 255, 255, 255};
192 static int dir320
[] = { -99, 1, 4, 3, 255, 255, 255, -5, 255, 255};
193 static int h618b
[] = { 255, -1, 255, 255, 255, -5, -3, -4, 255, 255};
194 static int wl1600gl
[] = { 1, -5, 0, 255, 255, 2, 255, 255, 255, 255};
195 static int wrt310nv1
[] = { 255, 1, 9, 3, 255, 255, 255, 255, 255, 255};
196 static int wrt160nv1
[] = { 255, 1, 5, 3, 255, 255, 255, 255, 255, 255};
198 static int wnr3500
[] = { 255, 255, 2, 255, 255, -1, 255, 255, 255, 255};
199 static int wnr2000v2
[] = { 255, 255, 255, 255, 255, -7, 255, 255, 255, 255};
200 static int f7d
[] = { 255, 255, 255, 255, 12, 13, 255, 14, 255, 255};
201 static int wrt160nv3
[] = { 255, 1, 4, 2, 255, 255, 255, 255, 255, 255};
202 static int e900
[] = { 255, -6, 8, 255, 255, 255, 255, 255, 255, 255};
203 static int e1000v2
[] = { 255, -6, 8, 7, 255, 255, 255, 255, 255, 255};
204 static int e3200
[] = { 255, -3, 255, 255, 255, 255, 255, 255, 255, 255};
205 static int wrt320n
[] = { 255, 2, 3, 4, 255, 255, 255, 255, 255, 255};
206 static int wrt610nv2
[] = { 255, 5, 3, 0, 255, 255, 255, -7, 255, 255};
207 static int e4200
[] = { 255, 5, -3, 255, 255, 255, 255, 255, 255, 255};
208 static int rtn10u
[] = { 255, 255, 255, 255, 255, -7, 255, -8, 255, 255};
209 static int rtn10p
[] = { 255, -6, 255, 255, 255, -7, 255, 255, 255, 255};
210 static int rtn12b1
[] = { -5, 255, 255, 255, 255, 255, 255, 225, 255, 255};
211 static int rtn15u
[] = { 1, 255, 3, 255, 255, 255, 255, -9, 255, 255};
212 static int rtn53
[] = { 0, -17, 255, 255, 255, 255, 255, 255, 255, 255};
213 static int l600n
[] = { 255, 255, 255, 255, 255, -7, 255, -8, 255, 255};
214 static int dir620c1
[] = { -6, -8, 255, 255, 255, -7, 255, 255, 255, 255};
215 static int rtn66u
[] = { 255, -12, 255, 255, 255, 255, 255, 15, 255, 13};
216 static int w1800r
[] = { 255, -13, 255, 255, 255, 255, 255, -12, 255, -5};
217 static int d1800h
[] = { -12, -13, 8, 255, 255, -10, 255, 15, 255, 11};
218 static int tdn6
[] = { 255, -6, 8, 255, 255, 255, 255, 255, 255, 255};
220 #ifdef CONFIG_BCMWL6A
221 static int ac68u
[] = { 255, 255, 255, 255, 255, -4, 255, -0, -14, 255};
222 static int ac56u
[] = { 255, 255, 255, 255, 255, -3, 255, -0, -14, 255};
223 static int n18u
[] = { 255, 255, 6, 255, 255, 255, 255, 3, 14, 255};
224 static int r6250
[] = { 11, 255, 15, 255, 255, 1, 255, 8, 8, 255};
225 static int r6300v2
[] = { 11, 255, 10, 255, 255, 1, 255, 8, 8, 255};
226 static int r6400
[] = { 9, -2, 255, 255, 255, -11, 255, 12, 13, 8};
227 static int r7000
[] = { 13, 255, 255, 255, 255, -15, 255, -17, -18, 12};
228 static int dir868
[] = { 255, 255, 3, 255, 255, -0, 255, 255, 255, 255};
229 static int ea6700
[] = { 255, 255, -6, -6, 255, 255, 255, 255, 255, 255};
230 static int ea6900
[] = { 255, 255, 8, 255, 255, 6, 255, 255, 255, 255};
231 static int ws880
[] = { 0, 255, -12, 255, 255, 6, 1, 14, 14, 6};
232 static int r1d
[] = { 255, 255, 255, 255, 255, 1, -8, 255, 255, 255};
233 static int wzr1750
[] = { 255, 255, 255, 255, 255, -5, 255, 255, 255, 255};
236 // WLAN DIAG WHITE AMBER DMZ AOSS BRIDG USB2 USB3 5G
241 int b
= 255, c
= 255;
244 if ((which
< 0) || (which
>= LED_COUNT
)) return ret
;
246 switch (nvram_match("led_override", "1") ? MODEL_UNKNOWN
: get_model()) {
248 if (check_hw_type() == HW_BCM4702
) {
250 if ((which
!= LED_DIAG
) && (which
!= LED_DMZ
)) return ret
;
251 b
= (which
== LED_DMZ
) ? 1 : 4;
252 if (mode
!= LED_PROBE
) {
253 if (f_read_string("/proc/sys/diag", s
, sizeof(s
)) > 0) {
255 sprintf(s
, "%u", mode
? (n
| b
) : (n
& ~b
));
256 f_write_string("/proc/sys/diag", s
, 0, 0);
264 if (!supports(SUP_WHAM_LED
)) return ret
;
272 case MODEL_WRTSL54GS
:
283 case MODEL_WZRRSG54HP
:
285 case MODEL_WHR2A54G54
:
291 case MODEL_WHR2A54G54:
292 if (which != LED_DIAG) return ret;
297 if (which
!= LED_DIAG
) return ret
;
311 if (which
!= LED_DIAG
) return ret
;
312 b
= -1; // power light
315 if (which
!= LED_DIAG
) return ret
;
316 b
= -5; // power light
327 case MODEL_WL500GPv2
:
331 if (which
!= LED_DIAG
) return ret
;
332 b
= -99; // Invert power light as diag indicator
336 if (which
!= LED_DIAG
) return ret
;
337 b
= -2; // power light
341 if (which
!= LED_DIAG
) return ret
;
342 b
= -1; // power light
358 if (which
== LED_DIAG
) {
359 // power led gpio: 0x02 - white, 0x13 - red
366 case MODEL_WNR3500LV2
:
367 if (which
== LED_DIAG
) {
368 // power led gpio: 0x03 - green, 0x07 - amber
374 case MODEL_WNR2000v2
:
375 if (which
== LED_DIAG
) {
376 // power led gpio: 0x01 - green, 0x02 - amber
380 b
= wnr2000v2
[which
];
386 case MODEL_F5D8235v3
:
387 if (which
== LED_DIAG
) {
388 // power led gpio: 10 - green, 11 - red
389 b
= (mode
) ? 11 : -10;
390 c
= (mode
) ? -10 : 11;
406 case MODEL_WRT160Nv3
:
407 b
= wrt160nv3
[which
];
412 case MODEL_WRT610Nv2
:
413 b
= wrt610nv2
[which
];
432 case MODEL_TDN60
: //bwq518
437 #ifdef CONFIG_BCMWL6A
448 if (which
== LED_DIAG
) {
449 // power led gpio: -3 - orange, -2 - green
456 if (which
== LED_DIAG
) {
457 // power led gpio: -3 - orange, -2 - green
464 if (which
== LED_DIAG
) {
465 // power led gpio: -2 - orange, -1 - white
472 if (which
== LED_DIAG
) {
473 // power led gpio: -3 - orange, -2 - white
480 if (which
== LED_DIAG
) {
481 // power led gpio: -0 - orange, -2 - white
491 if (which
== LED_DIAG
) {
492 // power led gpio: -2 - orange, -3 - blue
499 case MODEL_EA6900
: //need to be verified
512 if (which
!= LED_DIAG
) return ret
;
516 if (which
!= LED_DIAG
) return ret
;
520 if (which
!= LED_DIAG
) return ret
;
523 case MODEL_WRT310Nv1
:
524 b
= wrt310nv1
[which
];
526 case MODEL_WRT160Nv1
:
527 b
= wrt160nv1
[which
];
530 sprintf(s
, "led_%s", led_names
[which
]);
531 if (nvget_gpio(s
, &b
, &n
)) {
532 if ((mode
!= LED_PROBE
) && (n
)) mode
= !mode
;
533 ret
= (n
) ? b
: ((b
) ? -b
: -99);
541 if (b
== -99) b
= 0; // -0 substitute
544 else if (mode
!= LED_PROBE
) {
550 if (mode
!= LED_PROBE
) {
551 gpio_write(1 << b
, mode
);
558 if (c
< 16) gpio_write(1 << c
, mode
);