9945dbe000f94d52aa72a40c1ae196bd9733a31a
[openwrt.git] / package / linux / kernel-source / drivers / net / diag / diag_led.c
1 /*
2 * diag_led.c - replacement diag module
3 *
4 * Copyright (C) 2004 Mike Baker,
5 * Imre Kaloz <kaloz@dune.hu>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id$
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 */
31
32 #include <linux/module.h>
33 #include <linux/init.h>
34 #include <linux/kernel.h>
35 #include <linux/sysctl.h>
36 #include <asm/io.h>
37 #include <typedefs.h>
38 #include <bcm4710.h>
39 #include <sbutils.h>
40
41 extern char * nvram_get(const char *name);
42 static void *sbh;
43
44 // v2.x - - - - -
45 #define DIAG_GPIO (1<<1)
46 #define DMZ_GPIO (1<<7)
47
48 static void set_gpio(uint32 mask, uint32 value) {
49 sb_gpiocontrol(sbh,mask,0);
50 sb_gpioouten(sbh,mask,mask);
51 sb_gpioout(sbh,mask,value);
52 }
53
54 static void v2_set_diag(u8 state) {
55 set_gpio(DIAG_GPIO,state);
56 }
57 static void v2_set_dmz(u8 state) {
58 set_gpio(DMZ_GPIO,state);
59 }
60
61 // v1.x - - - - -
62 #define LED_DIAG 0x13
63 #define LED_DMZ 0x12
64
65 static void v1_set_diag(u8 state) {
66 if (!state) {
67 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG)=0xFF;
68 } else {
69 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG);
70 }
71 }
72 static void v1_set_dmz(u8 state) {
73 if (!state) {
74 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ)=0xFF;
75 } else {
76 *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ);
77 }
78 }
79
80 // - - - - -
81 static void ignore(u8 ignored) {};
82
83 // - - - - -
84 #define BIT_DMZ 0x01
85 #define BIT_DIAG 0x04
86
87 void (*set_diag)(u8 state);
88 void (*set_dmz)(u8 state);
89
90 static unsigned int diag = 0;
91
92 static void diag_change()
93 {
94 //printk(KERN_INFO "led -> %02x\n",diag);
95
96 set_diag(0xFF); // off
97 set_dmz(0xFF); // off
98
99 if(diag & BIT_DIAG)
100 set_diag(0x00); // on
101 if(diag & BIT_DMZ)
102 set_dmz(0x00); // on
103 }
104
105 static int proc_diag(ctl_table *table, int write, struct file *filp,
106 void *buffer, size_t *lenp)
107 {
108 int r;
109 r = proc_dointvec(table, write, filp, buffer, lenp);
110 if (write && !r) {
111 diag_change();
112 }
113 return r;
114 }
115
116 // - - - - -
117 static unsigned char reset_gpio = 0;
118 static unsigned char reset_polarity = 0;
119 static unsigned int reset = 0;
120
121 static int proc_reset(ctl_table *table, int write, struct file *filp,
122 void *buffer, size_t *lenp)
123 {
124
125 if (reset_gpio) {
126 sb_gpiocontrol(sbh,reset_gpio,reset_gpio);
127 sb_gpioouten(sbh,reset_gpio,0);
128 reset=!(sb_gpioin(sbh)&reset_gpio);
129
130 if (reset_polarity) reset=!reset;
131 } else {
132 reset=0;
133 }
134
135 return proc_dointvec(table, write, filp, buffer, lenp);
136 }
137
138 // - - - - -
139 static struct ctl_table_header *diag_sysctl_header;
140
141 static ctl_table sys_diag[] = {
142 {
143 ctl_name: 2000,
144 procname: "diag",
145 data: &diag,
146 maxlen: sizeof(diag),
147 mode: 0644,
148 proc_handler: proc_diag
149 },
150 {
151 ctl_name: 2001,
152 procname: "reset",
153 data: &reset,
154 maxlen: sizeof(reset),
155 mode: 0444,
156 proc_handler: proc_reset
157 },
158 { 0 }
159 };
160
161 static int __init diag_init()
162 {
163 char *buf;
164 u32 board_type;
165 sbh = sb_kattach();
166 sb_gpiosetcore(sbh);
167
168 board_type = sb_boardtype(sbh);
169 printk(KERN_INFO "diag boardtype: %08x\n",board_type);
170
171 set_diag=ignore;
172 set_dmz=ignore;
173
174 if ((board_type & 0xf00) == 0x400) {
175 board_type=1;
176 buf=nvram_get("boardtype")?:"";
177 if (!strcmp(buf,"bcm94710dev")) {
178 buf=nvram_get("boardnum")?:"";
179 if (!strcmp(buf,"42")) {
180 // wrt54g v1.x
181 set_diag=v1_set_diag;
182 set_dmz=v1_set_dmz;
183 reset_gpio=(1<<6);
184 reset_polarity=0;
185 } else if (!strcmp(buf,"asusX")) {
186 //asus wl-500g
187 //no leds
188 reset_gpio=(1<<6);
189 reset_polarity=1;
190 }
191 } else if (!strcmp(buf,"bcm94710ap")) {
192 buf=nvram_get("boardnum")?:"";
193 if (!strcmp(buf,"42")) {
194 // buffalo
195 set_dmz=v2_set_dmz;
196 reset_gpio=(1<<4);
197 reset_polarity=1;
198 } else if (!strcmp(buf,"44")) {
199 //dell truemobile
200 set_dmz=v2_set_dmz;
201 reset_gpio=(1<<0);
202 reset_polarity=0;
203 }
204 }
205 } else {
206 board_type=2;
207 set_diag=v2_set_diag;
208 set_dmz=v2_set_dmz;
209 reset_gpio=(1<<6);
210 reset_polarity=0;
211 buf=nvram_get("boardnum")?:"";
212 if (!strcmp(buf,"44")) {
213 //motorola
214 set_diag=ignore;
215 set_dmz=ignore;
216 reset_gpio=(1<<5);
217 reset_polarity=0;
218 }
219 if (!strcmp(buf,"00")) {
220 //buffalo
221 set_diag=ignore;
222 set_dmz=ignore;
223 reset_gpio=(1<<7);
224 reset_polarity=1;
225 }
226 if (!strcmp(buf,"45")) {
227 //wl-500g deluxe
228 set_diag=ignore;
229 set_dmz=ignore;
230 reset_gpio=(1<<6);
231 reset_polarity=1;
232 }
233 }
234 printk(KERN_INFO "using v%d hardware\n",board_type);
235
236 diag_sysctl_header = register_sysctl_table(sys_diag, 0);
237 diag_change();
238
239 return 0;
240 }
241
242 static void __exit diag_exit()
243 {
244 unregister_sysctl_table(diag_sysctl_header);
245 }
246
247 EXPORT_NO_SYMBOLS;
248 MODULE_AUTHOR("openwrt.org");
249 MODULE_LICENSE("GPL");
250
251 module_init(diag_init);
252 module_exit(diag_exit);
This page took 0.068195 seconds and 3 git commands to generate.