4 Copyright (C) 2006-2009 Jonathan Zarate
11 #include <sys/types.h>
21 const char *led_names
[] = { "wlan", "diag", "white", "amber", "dmz", "aoss", "bridge", "mystery" };
30 #include <sys/ioctl.h>
31 #include <linux_gpio.h>
35 int f
= open("/dev/gpio", O_RDWR
);
37 _dprintf ("Failed to open /dev/gpio\n");
41 static int _gpio_ioctl(int f
, int gpioreg
, unsigned int mask
, unsigned int val
)
43 struct gpio_ioctl gpio
;
48 if (ioctl(f
, gpioreg
, &gpio
) < 0) {
49 _dprintf("Invalid gpioreg %d\n", gpioreg
);
55 void gpio_write(uint32_t bit
, int en
)
59 if ((f
= gpio_open()) < 0) return;
61 _gpio_ioctl(f
, GPIO_IOC_RESERVE
, bit
, bit
);
62 _gpio_ioctl(f
, GPIO_IOC_OUTEN
, bit
, bit
);
64 _gpio_ioctl(f
, GPIO_IOC_OUT
, bit
, en
? bit
: 0);
68 uint32_t gpio_read(void)
73 if ((f
= gpio_open()) < 0) return ~0;
74 r
= _gpio_ioctl(f
, GPIO_IOC_IN
, 0xffff, 0);
80 uint32_t _gpio_read(int f
)
83 r
= _gpio_ioctl(f
, GPIO_IOC_IN
, 0xffff, 0);
92 int f
= open(DEV_GPIO(in
), O_RDONLY
|O_SYNC
);
94 _dprintf ("Failed to open %s\n", DEV_GPIO(in
));
98 void gpio_write(uint32_t bit
, int en
)
103 if ((f
= open(DEV_GPIO(control
), O_RDWR
)) < 0) return;
104 read(f
, &r
, sizeof(r
));
106 write(f
, &r
, sizeof(r
));
109 if ((f
= open(DEV_GPIO(outen
), O_RDWR
)) < 0) return;
110 read(f
, &r
, sizeof(r
));
112 write(f
, &r
, sizeof(r
));
115 if ((f
= open(DEV_GPIO(out
), O_RDWR
)) < 0) return;
116 read(f
, &r
, sizeof(r
));
119 write(f
, &r
, sizeof(r
));
123 uint32_t gpio_read(void)
128 if ((f
= open(DEV_GPIO(in
), O_RDONLY
)) < 0) return ~0;
129 if (read(f
, &r
, sizeof(r
)) != sizeof(r
)) r
= ~0;
134 uint32_t _gpio_read(int f
)
137 return (read(f
, &v
, sizeof(v
)) == sizeof(v
)) ? v
: ~0;
142 int nvget_gpio(const char *name
, int *gpio
, int *inv
)
147 if (((p
= nvram_get(name
)) != NULL
) && (*p
)) {
148 n
= strtoul(p
, NULL
, 0);
149 if ((n
& 0xFFFFFF70) == 0) {
151 *inv
= ((n
& 0x80) != 0);
160 int led(int which
, int mode
)
162 // WLAN DIAG WHITE AMBER DMZ AOSS BRIDG MYST
163 // ----- ----- ----- ----- ----- ----- ----- -----
164 static int wrt54g
[] = { 0, 1, 2, 3, 7, 255, 255, 255 };
165 static int wrtsl
[] = { 255, 1, 5, 7, 0, 255, 255, 255 };
166 static int whrg54
[] = { 2, 7, 255, 255, 255, 6, 1, 3 };
167 static int wbr2g54
[] = { 255, -1, 255, 255, 255, -6, 255, 255 };
168 static int wzrg54
[] = { 2, 7, 255, 255, 255, 6, 255, 255 };
169 static int wr850g1
[] = { 7, 3, 255, 255, 255, 255, 255, 255 };
170 static int wr850g2
[] = { 0, 1, 255, 255, 255, 255, 255, 255 };
171 static int wtr54gs
[] = { 1, -1, 255, 255, 255, 255, 255, 255 };
172 static int dir320
[] = { -99, 1, 4, 3, 255, 255, 255, -5 };
177 if ((which
< 0) || (which
>= LED_COUNT
)) return 0;
179 switch (nvram_match("led_override", "1") ? MODEL_UNKNOWN
: get_model()) {
181 if (check_hw_type() == HW_BCM4702
) {
183 if ((which
!= LED_DIAG
) && (which
!= LED_DMZ
)) return 0;
184 if (mode
!= LED_PROBE
) {
185 if (f_read_string("/proc/sys/diag", s
, sizeof(s
)) > 0) {
186 b
= (which
== LED_DMZ
) ? 1 : 4;
188 sprintf(s
, "%u", mode
? (n
| b
) : (n
& ~b
));
189 f_write_string("/proc/sys/diag", s
, 0, 0);
197 if (!supports(SUP_WHAM_LED
)) return 0;
205 case MODEL_WRTSL54GS
:
216 case MODEL_WZRRSG54HP
:
218 case MODEL_WHR2A54G54
:
224 case MODEL_WHR2A54G54:
225 if (which != LED_DIAG) return 0;
230 if (which
!= LED_DIAG
) return 0;
244 if (which
!= LED_DIAG
) return 0;
245 b
= -1; // power light
248 if (which
!= LED_DIAG
) return 0;
249 b
= -5; // power light
254 case MODEL_WL500GPv2
:
256 if (which
!= LED_DIAG
) return 0;
257 b
= 0; // Invert power light as diag indicator
258 if (mode
!= LED_PROBE
) mode
= !mode
;
261 if (which
!= LED_DIAG
) return 0;
262 b
= -2; // power light
266 if (which
!= LED_DIAG
) return 0;
267 b
= -1; // power light
274 if (which
!= LED_DIAG
) return 0;
278 if (which
!= LED_DIAG
) return 0;
282 sprintf(s
, "led_%s", led_names
[which
]);
283 if (nvget_gpio(s
, &b
, &n
)) {
284 if ((mode
!= LED_PROBE
) && (n
)) mode
= !mode
;
291 if (b
== -99) b
= 0; // -0 substitute
294 else if (mode
!= LED_PROBE
) {
300 if (mode
!= LED_PROBE
) {
301 gpio_write(1 << b
, mode
);