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>
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_OUT
, bit
, en
? bit
: 0);
87 uint32_t _gpio_read(int f
)
90 // r = _gpio_ioctl(f, GPIO_IOC_IN, 0xFFFF, 0);
91 r
= _gpio_ioctl(f
, GPIO_IOC_IN
, 0x07FF, 0);
96 uint32_t gpio_read(void)
101 if ((f
= gpio_open(0)) < 0) return ~0;
109 int gpio_open(uint32_t mask
)
111 int f
= open(DEV_GPIO(in
), O_RDONLY
|O_SYNC
);
113 _dprintf ("Failed to open %s\n", DEV_GPIO(in
));
117 void gpio_write(uint32_t bit
, int en
)
122 if ((f
= open(DEV_GPIO(control
), O_RDWR
)) < 0) return;
123 read(f
, &r
, sizeof(r
));
125 write(f
, &r
, sizeof(r
));
128 if ((f
= open(DEV_GPIO(outen
), O_RDWR
)) < 0) return;
129 read(f
, &r
, sizeof(r
));
131 write(f
, &r
, sizeof(r
));
134 if ((f
= open(DEV_GPIO(out
), O_RDWR
)) < 0) return;
135 read(f
, &r
, sizeof(r
));
138 write(f
, &r
, sizeof(r
));
142 uint32_t _gpio_read(int f
)
145 return (read(f
, &v
, sizeof(v
)) == sizeof(v
)) ? v
: ~0;
148 uint32_t gpio_read(void)
153 if ((f
= open(DEV_GPIO(in
), O_RDONLY
)) < 0) return ~0;
161 int nvget_gpio(const char *name
, int *gpio
, int *inv
)
166 if (((p
= nvram_get(name
)) != NULL
) && (*p
)) {
167 n
= strtoul(p
, NULL
, 0);
168 if ((n
& 0xFFFFFF70) == 0) {
170 *inv
= ((n
& 0x80) != 0);
179 int led(int which
, int mode
)
181 // WLAN DIAG WHITE AMBER DMZ AOSS BRIDG MYST
182 // ----- ----- ----- ----- ----- ----- ----- -----
183 static int wrt54g
[] = { 0, 1, 2, 3, 7, 255, 255, 255 };
184 static int wrtsl
[] = { 255, 1, 5, 7, 0, 255, 255, 255 };
185 static int whrg54
[] = { 2, 7, 255, 255, 255, 6, 1, 3 };
186 static int wbr2g54
[] = { 255, -1, 255, 255, 255, -6, 255, 255 };
187 static int wzrg54
[] = { 2, 7, 255, 255, 255, 6, 255, 255 };
188 static int wr850g1
[] = { 7, 3, 255, 255, 255, 255, 255, 255 };
189 static int wr850g2
[] = { 0, 1, 255, 255, 255, 255, 255, 255 };
190 static int wtr54gs
[] = { 1, -1, 255, 255, 255, 255, 255, 255 };
191 static int dir320
[] = { -99, 1, 4, 3, 255, 255, 255, -5 };
192 static int wnr3500
[] = { 255, 255, 2, 255, 255, -1, 255, 255 };
193 static int wrt160nv3
[] = { 255, 1, 4, 2, 255, 255, 255, 255 };
197 int b
= 255, c
= 255;
199 if ((which
< 0) || (which
>= LED_COUNT
)) return 0;
201 switch (nvram_match("led_override", "1") ? MODEL_UNKNOWN
: get_model()) {
203 if (check_hw_type() == HW_BCM4702
) {
205 if ((which
!= LED_DIAG
) && (which
!= LED_DMZ
)) return 0;
206 if (mode
!= LED_PROBE
) {
207 if (f_read_string("/proc/sys/diag", s
, sizeof(s
)) > 0) {
208 b
= (which
== LED_DMZ
) ? 1 : 4;
210 sprintf(s
, "%u", mode
? (n
| b
) : (n
& ~b
));
211 f_write_string("/proc/sys/diag", s
, 0, 0);
219 if (!supports(SUP_WHAM_LED
)) return 0;
227 case MODEL_WRTSL54GS
:
238 case MODEL_WZRRSG54HP
:
240 case MODEL_WHR2A54G54
:
246 case MODEL_WHR2A54G54:
247 if (which != LED_DIAG) return 0;
252 if (which
!= LED_DIAG
) return 0;
266 if (which
!= LED_DIAG
) return 0;
267 b
= -1; // power light
270 if (which
!= LED_DIAG
) return 0;
271 b
= -5; // power light
276 case MODEL_WL500GPv2
:
278 if (which
!= LED_DIAG
) return 0;
279 b
= -99; // Invert power light as diag indicator
282 if (which
!= LED_DIAG
) return 0;
283 b
= -2; // power light
287 if (which
!= LED_DIAG
) return 0;
288 b
= -1; // power light
291 if (which
== LED_DIAG
) {
292 // power led gpio: 0x03 - green, 0x07 - amber
298 case MODEL_WRT160Nv3
:
299 b
= wrt160nv3
[which
];
306 if (which
!= LED_DIAG
) return 0;
310 if (which
!= LED_DIAG
) return 0;
314 sprintf(s
, "led_%s", led_names
[which
]);
315 if (nvget_gpio(s
, &b
, &n
)) {
316 if ((mode
!= LED_PROBE
) && (n
)) mode
= !mode
;
323 if (b
== -99) b
= 0; // -0 substitute
326 else if (mode
!= LED_PROBE
) {
332 if (mode
!= LED_PROBE
) {
333 gpio_write(1 << b
, mode
);
340 if (c
< 16) gpio_write(1 << c
, mode
);