source: freewrt/package/broadcom-diag/diag_led.c@ 24d8a15

freewrt_1_0 freewrt_2_0
Last change on this file since 24d8a15 was 24d8a15, checked in by Waldemar Brodkorb <wbx@…>, 19 years ago

fix reset button for asus wl500g premium, no gpl package available, so try and error helped here

git-svn-id: svn://www.freewrt.org/branches/freewrt_1_0@818 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * diag_led.c - led and reset button driver for broadcom routers
3 *
4 * Copyright (C) 2004-2006 Mike Baker,
5 * Imre Kaloz <kaloz@dune.hu>,
6 * Felix Fietkau <nbd@openwrt.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24/*
25 * ChangeLog:
26 * 2004/03/28 initial release
27 * 2004/08/26 asus & buffalo support added
28 * 2005/03/14 asus wl-500g deluxe and buffalo v2 support added
29 * 2005/04/13 added licensing informations
30 * 2005/04/18 base reset polarity off initial readings
31 */
32
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/kernel.h>
36#include <linux/sysctl.h>
37#include <asm/io.h>
38#include <typedefs.h>
39#include <bcmdevs.h>
40#include <sbutils.h>
41
42extern char * nvram_get(const char *name);
43static void *sbh;
44
45// v2.x - - - - -
46#define BITS(n) ((1 << n) - 1)
47#define ISSET(n,b) ((n & (1 << b)) ? 1 : 0)
48#define DIAG_GPIO (1<<1)
49#define AOSS_GPIO (1<<6)
50#define DMZ_GPIO (1<<7)
51#define SES_GPIO ((1 << 2) | (1 << 3) | (1 << 5))
52
53static void set_gpio(uint32 mask, uint32 value) {
54 sb_gpiocontrol(sbh,mask,0);
55 sb_gpioouten(sbh,mask,mask);
56 sb_gpioout(sbh,mask,value);
57}
58
59static void v2_set_diag(u8 state) {
60 set_gpio(DIAG_GPIO,state);
61}
62static void v2_set_dmz(u8 state) {
63 set_gpio(DMZ_GPIO,state);
64}
65static void v2_set_aoss(u8 state) {
66 set_gpio(AOSS_GPIO,state);
67}
68static void v2_set_ses(u8 state) {
69 set_gpio(SES_GPIO, (ISSET(state, 0) << 2) | (ISSET(state, 1) << 3) | (ISSET(state, 2) << 5));
70}
71
72// v1.x - - - - -
73#define LED_DIAG 0x13
74#define LED_DMZ 0x12
75
76static void v1_set_diag(u8 state) {
77 if (!state) {
78 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG)=0xFF;
79 } else {
80 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG);
81 }
82}
83static void v1_set_dmz(u8 state) {
84 if (!state) {
85 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ)=0xFF;
86 } else {
87 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ);
88 }
89}
90
91// - - - - -
92static void ignore(u8 ignored) {};
93
94// - - - - -
95#define BIT_DMZ (1 << 0)
96#define BIT_DIAG (1 << 2)
97#define BIT_SES (BITS(3) << 3)
98
99void (*set_diag)(u8 state);
100void (*set_dmz)(u8 state);
101void (*set_ses)(u8 state);
102
103static unsigned int diag_reverse = 1;
104static unsigned int ses_reverse = 1;
105static unsigned int diag = 0;
106
107static void diag_change()
108{
109 set_diag(diag_reverse ? 0xFF : 0x00); // off
110 set_dmz(diag_reverse ? 0xFF : 0x00); // off
111 set_ses(ses_reverse ? 0xFF : 0x00); // off
112
113 if(diag & BIT_DIAG)
114 set_diag(diag_reverse ? 0x00 : 0xFF); // on
115 if(diag & BIT_DMZ)
116 set_dmz(diag_reverse ? 0x00 : 0xFF); // on
117 if(diag & BIT_SES)
118 set_ses(((ses_reverse ? ~diag : diag) >> 3) & BITS(3));
119}
120
121static int proc_diag(ctl_table *table, int write, struct file *filp,
122 void *buffer, size_t *lenp)
123{
124 int r;
125 r = proc_dointvec(table, write, filp, buffer, lenp);
126 if (write && !r) {
127 diag_change();
128 }
129 return r;
130}
131
132// - - - - -
133static unsigned char reset_gpio = 0;
134static unsigned char reset_polarity = 0;
135static unsigned int reset = 0;
136static unsigned char button_gpio = 0;
137static unsigned char button_polarity = 0;
138static unsigned int button = 0;
139
140
141static int read_gpio(int gpio, int polarity)
142{
143 int res;
144
145 if (gpio) {
146 sb_gpiocontrol(sbh,gpio,gpio);
147 sb_gpioouten(sbh,gpio,0);
148 res=!(sb_gpioin(sbh)&gpio);
149
150 return (polarity ? !res : res);
151 }
152
153 return 0;
154}
155
156static int proc_reset(ctl_table *table, int write, struct file *filp,
157 void *buffer, size_t *lenp)
158{
159 reset = read_gpio(reset_gpio, reset_polarity);
160
161 return proc_dointvec(table, write, filp, buffer, lenp);
162}
163
164static int proc_button(ctl_table *table, int write, struct file *filp,
165 void *buffer, size_t *lenp)
166{
167 button = read_gpio(button_gpio, button_polarity);
168
169 return proc_dointvec(table, write, filp, buffer, lenp);
170}
171
172// - - - - -
173static struct ctl_table_header *diag_sysctl_header;
174
175static ctl_table sys_diag[] = {
176 {
177 ctl_name: 2000,
178 procname: "diag",
179 data: &diag,
180 maxlen: sizeof(diag),
181 mode: 0644,
182 proc_handler: proc_diag
183 },
184 {
185 ctl_name: 2001,
186 procname: "reset",
187 data: &reset,
188 maxlen: sizeof(reset),
189 mode: 0444,
190 proc_handler: proc_reset
191 },
192 {
193 ctl_name: 2002,
194 procname: "button",
195 data: &button,
196 maxlen: sizeof(button),
197 mode: 0444,
198 proc_handler: proc_button
199 },
200 { 0 }
201};
202
203static int __init diag_init()
204{
205 char *buf;
206 u32 board_type;
207 sbh = sb_kattach();
208 sb_gpiosetcore(sbh);
209
210 board_type = sb_boardtype(sbh);
211
212 set_diag=ignore;
213 set_dmz=ignore;
214 set_ses=ignore;
215
216 buf=nvram_get("pmon_ver") ?: "";
217 if (((board_type & 0xf00) == 0x400) && (strncmp(buf, "CFE", 3) != 0)) {
218 buf=nvram_get("boardtype")?:"";
219 if (!strcmp(buf,"bcm94710dev")) {
220 buf=nvram_get("boardnum")?:"";
221 if (!strcmp(buf,"42")) {
222 // wrt54g v1.x
223 set_diag=v1_set_diag;
224 set_dmz=v1_set_dmz;
225 reset_gpio=(1<<6);
226 }
227 if (!strcmp(buf,"asusX")) {
228 //asus wl-500g
229 reset_gpio=(1<<6);
230 }
231 }
232 if (!strcmp(buf,"bcm94710ap")) {
233 buf=nvram_get("boardnum")?:"";
234 if (!strcmp(buf,"42")) {
235 // buffalo
236 set_dmz=v2_set_dmz;
237 reset_gpio=(1<<4);
238 }
239 if (!strcmp(buf,"44")) {
240 //dell truemobile
241 set_dmz=v2_set_dmz;
242 reset_gpio=(1<<0);
243 }
244 }
245 } else {
246 buf=nvram_get("boardnum")?:"";
247 if (!strcmp(buf,"42")) {
248 //linksys
249 set_diag=v2_set_diag;
250 set_dmz=v2_set_dmz;
251 set_ses=v2_set_ses;
252
253 reset_gpio=(1<<6);
254 button_gpio=(1<<4);
255
256 if (!strcmp((nvram_get("boardtype")?:""), "0x0101")) // WRT54G3G
257 ses_reverse = 0;
258 else
259 ses_reverse = 1;
260 }
261 if (!strcmp(buf,"44")) {
262 //motorola
263 reset_gpio=(1<<5);
264 }
265 if (!strcmp(buf,"00")) {
266 //buffalo
267 diag_reverse = 0;
268 set_dmz=v2_set_diag;
269 set_diag=v2_set_aoss;
270 reset_gpio=(1<<7);
271 }
272 if (!strcmp(buf,"45")) {
273 buf=nvram_get("boardtype")?:"";
274 if (!strcmp(buf,"0x042f")) {
275 //wl-500g premium
276 printk("diag: Asus WL500g premium found\n");
277 // special button reset_gpio=(1<<4);
278 reset_gpio=(1<<0);
279 } else {
280 //wl-500g deluxe
281 printk("diag: Asus WL500g deluxe found\n");
282 reset_gpio=(1<<6);
283 }
284 }
285 }
286
287 sb_gpiocontrol(sbh,reset_gpio,reset_gpio);
288 sb_gpioouten(sbh,reset_gpio,0);
289 reset_polarity=!(sb_gpioin(sbh)&reset_gpio);
290
291 if (button_gpio) {
292 sb_gpiocontrol(sbh,button_gpio,button_gpio);
293 sb_gpioouten(sbh,button_gpio,0);
294 button_polarity=!(sb_gpioin(sbh)&button_gpio);
295 } else {
296 // don't create /proc/button
297 sys_diag[2].ctl_name = 0;
298 }
299
300 diag_sysctl_header = register_sysctl_table(sys_diag, 0);
301 diag_change();
302
303 return 0;
304}
305
306static void __exit diag_exit()
307{
308 unregister_sysctl_table(diag_sysctl_header);
309}
310
311EXPORT_NO_SYMBOLS;
312MODULE_AUTHOR("openwrt.org");
313MODULE_LICENSE("GPL");
314
315module_init(diag_init);
316module_exit(diag_exit);
Note: See TracBrowser for help on using the repository browser.