MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / char / ledman.c
blob38549288d4f0357ba800755382e2b0ffb8c49dae
1 /****************************************************************************/
2 /* vi:set tabstop=4 cindent shiftwidth=4:
4 * ledman.c -- An LED manager, primarily, but not limited to SnapGear
5 * devices manages up to 32 seperate LED at once.
6 * Copyright (C) Lineo, 2000-2001.
7 * Copyright (C) SnapGear, 2001-2003.
9 * This driver currently supports 4 types of LED modes:
11 * SET - transient LED's that show activity, cleared at next poll
12 * ON - always ON
13 * OFF - always OFF
14 * FLASHING - a blinking LED with the frequency determinbe by the poll func
16 * We have two sets of LED's to support non-standard LED usage without
17 * losing previously/during use set of std values.
19 * Hopefully for most cases, adding new HW with new LED patterns will be
20 * as simple as adding two tables, a small function and an entry in
21 * led_modes. The tables being the map and the defaults while the
22 * function is the XXX_set function.
24 * You can, however, add your own functions for XXX_bits, XXX_tick and
25 * take full control over all aspects of the LED's.
27 /****************************************************************************/
29 #include <linux/config.h>
30 #include <linux/version.h>
31 #include <linux/module.h>
32 #include <linux/utsname.h>
33 #include <linux/kernel.h>
34 #include <linux/major.h>
35 #include <linux/string.h>
36 #include <linux/fcntl.h>
37 #include <linux/timer.h>
38 #include <linux/types.h>
39 #include <linux/fs.h>
40 #include <linux/fcntl.h>
41 #include <linux/ledman.h>
42 #include <linux/interrupt.h>
44 #if LINUX_VERSION_CODE < 0x020300
45 #include <linux/malloc.h>
46 #else
47 #include <linux/slab.h>
48 #endif
50 #if LINUX_VERSION_CODE < 0x020100
51 #define INIT_RET_TYPE int
52 #define Module_init(a)
53 #elif LINUX_VERSION_CODE < 0x020300
54 #include <linux/init.h>
55 #define INIT_RET_TYPE int
56 #define Module_init(a) module_init(a)
57 #else
58 #include <linux/init.h>
59 #define INIT_RET_TYPE static int __init
60 #define Module_init(a) module_init(a)
61 #endif
63 #if LINUX_VERSION_CODE < 0x020100
64 #define Get_user(a,b) a = get_user(b)
65 #else
66 #include <asm/uaccess.h>
67 #define Get_user(a,b) get_user(a,b)
68 #endif
70 #if LINUX_VERSION_CODE < 0x020100
71 static struct symbol_table ledman_syms = {
72 #include <linux/symtab_begin.h>
73 X(ledman_cmd),
74 #include <linux/symtab_end.h>
76 #else
77 EXPORT_SYMBOL(ledman_cmd);
78 #endif
80 /****************************************************************************/
82 static void ledman_poll(unsigned long arg);
83 static int ledman_ioctl(struct inode * inode, struct file * file,
84 unsigned int cmd, unsigned long arg);
85 #if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
86 static int ledman_bits(unsigned long cmd, unsigned long bits);
87 static void ledman_tick(void);
88 #endif
90 /****************************************************************************/
92 static struct timer_list ledman_timerlist;
94 /****************************************************************************/
96 struct file_operations ledman_fops = {
97 ioctl: ledman_ioctl, /* ledman_ioctl */
100 /****************************************************************************/
102 * some types to make adding new LED modes easier
104 * First the elements for def array specifying default LED behaviour
107 #define LEDS_SET 0
108 #define LEDS_ON 1
109 #define LEDS_OFF 2
110 #define LEDS_FLASH 3
111 #define LEDS_MAX 4
113 typedef unsigned long leddef_t[LEDS_MAX];
116 * A LED map is a mapping from numbers in ledman.h to one or more
117 * physical LED bits. Currently the typing limits us to 32 LED's
118 * though this would not be hard to change.
121 typedef unsigned long ledmap_t[LEDMAN_MAX];
124 * A LED mode is a definition of how a set of LED's should behave.
126 * name - a symbolic name for the LED mode, used for changing modes
127 * map - points to a ledmap array, maps ledman.h defines to real LED bits
128 * def - default behaviour for the LED bits (ie, on, flashing ...)
129 * bits - perform command on physical bits, you may use the default or
130 * supply your own for more control.
131 * tick - time based update of LED status, used to clear SET LED's and
132 * also for flashing LED's
133 * set - set the real LED's to match the physical bits
134 * jiffies - how many clock ticks between runs of the tick routine.
138 typedef struct {
139 char name[LEDMAN_MAX_NAME];
140 u_long *map;
141 u_long *def;
142 int (*bits)(unsigned long cmd, unsigned long led);
143 void (*tick)(void);
144 void (*set)(unsigned long led);
145 int jiffies;
146 } ledmode_t;
148 /****************************************************************************/
150 static int current_mode = 0; /* the default LED mode */
151 static int initted = 0;
154 * We have two sets of LED's for transient operations like DHCP and so on
155 * index 0 is the standard LED's and index 1 is the ALTBIT LED's
158 static unsigned long leds_alt, leds_alt_cnt[32];
159 #if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
160 static unsigned long leds_set[2];
161 #endif
162 static unsigned long leds_on[2], leds_off[2], leds_flash[2];
164 static pid_t ledman_resetpid = -1;
166 /****************************************************************************/
169 * Let the system specific defining begin
172 #if defined(CONFIG_M586)
173 #define CONFIG_X86 1
174 #endif
176 #if defined(CONFIG_X86)
177 #if defined(CONFIG_MTD_SNAPGEODE)
178 #define CONFIG_GEODE 1
179 #else
180 #define CONFIG_AMDSC520 1
181 #endif
182 #if defined(CONFIG_SNAPGEAR)
183 extern ledmap_t nettel_old;
184 extern leddef_t nettel_def_old;
185 #endif
186 extern ledmap_t nettel_std;
187 extern leddef_t nettel_def;
188 static void nettel_set(unsigned long bits);
189 static void ledman_initarch(void);
190 #endif /* CONFIG_X86 */
192 #if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
193 #ifdef ENTERASYS
194 extern ledmap_t enterasys_std;
195 extern leddef_t enterasys_def;
196 #endif
197 extern ledmap_t nettel_old;
198 extern ledmap_t nettel_new;
199 extern leddef_t nettel_def;
200 static void nettel_set(unsigned long bits);
201 #endif
203 #if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
204 extern ledmap_t nt5272_std;
205 extern leddef_t nt5272_def;
206 static void nt5272_set(unsigned long bits);
207 #endif
209 #if defined(CONFIG_SE1100)
210 extern ledmap_t se1100_std;
211 extern leddef_t se1100_def;
212 static void se1100_set(unsigned long bits);
213 #endif
215 #if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
216 extern ledmap_t nap5272_std;
217 extern leddef_t nap5272_def;
218 static void nap5272_set(unsigned long bits);
219 #endif
221 #if defined(CONFIG_SH_SECUREEDGE5410)
222 extern ledmap_t se5410_std;
223 extern leddef_t se5410_def;
224 static void se5410_set(unsigned long bits);
225 #endif
227 #if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
228 extern ledmap_t nt1500_std;
229 extern leddef_t nt1500_def;
230 static void nt1500_set(unsigned long bits);
231 #endif
233 #ifdef CONFIG_eLIA
234 extern ledmap_t elia_std;
235 extern leddef_t elia_def;
236 static void elia_set(unsigned long bits);
237 #endif
239 #if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
240 extern ledmap_t keywest_std;
241 extern leddef_t keywest_def;
242 static void keywest_set(unsigned long bits);
243 static void ledman_initkeywest(void);
244 static int keywest_bits(unsigned long cmd, unsigned long bits);
245 static void keywest_tick(void);
246 #endif
248 #ifdef CONFIG_ARCH_IXDP425
249 extern ledmap_t ixdp425_std;
250 extern leddef_t ixdp425_def;
251 static void ledman_initarch(void);
252 static void ixdp425_set(unsigned long bits);
253 #endif
255 #ifdef CONFIG_ARCH_SE4000
256 extern ledmap_t snapgear425_std;
257 extern leddef_t snapgear425_def;
258 static void ledman_initarch(void);
259 static void snapgear425_set(unsigned long bits);
260 #endif
262 /****************************************************************************/
263 /****************************************************************************/
265 #undef LT
266 #define LT (((HZ) + 99) / 100)
268 /****************************************************************************/
270 ledmode_t led_mode[] = {
272 #ifdef ENTERASYS /* first in the list is the default */
273 { "enterasys", enterasys_std, enterasys_def, ledman_bits, ledman_tick, nettel_set, LT },
274 #endif
276 #if defined(CONFIG_X86)
277 { "std", nettel_std, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
278 #if defined(CONFIG_SNAPGEAR)
279 { "old", nettel_old, nettel_def_old, ledman_bits, ledman_tick, nettel_set, LT },
280 #endif
281 #endif
283 #if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
285 * by default the first entry is used. You can select the old-style
286 * LED patterns for acient boards with the command line parameter:
288 * ledman=old
290 { "new", nettel_new, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
291 { "old", nettel_old, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
292 #endif
294 #if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
295 { "std", nt5272_std, nt5272_def, ledman_bits, ledman_tick, nt5272_set, LT },
296 #endif
298 #if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
299 { "std", nt1500_std, nt1500_def, ledman_bits, ledman_tick, nt1500_set, LT },
300 #endif
302 #if defined(CONFIG_SE1100)
303 { "std", se1100_std, se1100_def, ledman_bits, ledman_tick, se1100_set, LT },
304 #endif
306 #if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
307 { "std", nap5272_std, nap5272_def, ledman_bits, ledman_tick, nap5272_set, LT },
308 #endif
310 #if defined(CONFIG_SH_SECUREEDGE5410)
311 { "std", se5410_std, se5410_def, ledman_bits, ledman_tick, se5410_set, LT },
312 #endif
314 #ifdef CONFIG_eLIA
315 { "std", elia_std, elia_def, ledman_bits, ledman_tick, elia_set, LT },
316 #endif
318 #if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
319 { "std",keywest_std,keywest_def,keywest_bits,keywest_tick,keywest_set,HZ/10},
320 #endif
322 #if defined(CONFIG_ARCH_IXDP425)
323 { "std",ixdp425_std,ixdp425_def,ledman_bits,ledman_tick,ixdp425_set,LT},
324 #endif
326 #if defined(CONFIG_ARCH_SE4000)
327 { "std",snapgear425_std,snapgear425_def,ledman_bits,ledman_tick,snapgear425_set,LT},
328 #endif
330 { "", NULL, NULL, 0 }
333 /****************************************************************************/
335 * boot arg processing ledman=mode
339 ledman_setup(char *arg)
341 ledman_cmd(LEDMAN_CMD_MODE, (unsigned long) arg);
342 return(0);
345 #if LINUX_VERSION_CODE >= 0x020100
346 __setup("ledman=", ledman_setup);
347 #endif
349 /****************************************************************************/
350 /****************************************************************************/
352 INIT_RET_TYPE ledman_init(void)
354 printk(KERN_INFO "ledman: Copyright (C) SnapGear, 2000-2003.\n");
356 if (register_chrdev(LEDMAN_MAJOR, "nled", &ledman_fops) < 0) {
357 printk("%s(%d): ledman_init() can't get Major %d\n",
358 __FILE__, __LINE__, LEDMAN_MAJOR);
359 return(-EBUSY);
362 #if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
363 ledman_initkeywest();
364 #endif
366 #if defined(CONFIG_X86) || defined(CONFIG_ARM)
367 ledman_initarch();
368 #endif
371 * set the LEDs up correctly at boot
373 ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
375 * start the timer
377 init_timer(&ledman_timerlist);
378 if (led_mode[current_mode].tick)
379 ledman_timerlist.expires = jiffies + led_mode[current_mode].jiffies;
380 else
381 ledman_timerlist.expires = jiffies + HZ;
382 ledman_timerlist.function = ledman_poll;
383 ledman_timerlist.data = 0;
384 mod_timer(&ledman_timerlist, ledman_timerlist.expires);
386 #if LINUX_VERSION_CODE < 0x020100
387 register_symtab(&ledman_syms);
388 #endif
390 initted = 1;
391 return(0);
394 Module_init(ledman_init);
396 /****************************************************************************/
398 void
399 ledman_killtimer(void)
402 * stop the timer
404 del_timer(&ledman_timerlist);
407 * set the LEDs up correctly at boot
409 ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
412 /****************************************************************************/
414 void
415 ledman_starttimer(void)
418 * start the timer
420 mod_timer(&ledman_timerlist, jiffies + 1);
423 * set the LEDs up correctly at boot
425 ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
428 /****************************************************************************/
430 static void
431 ledman_poll(unsigned long arg)
433 unsigned long expires;
434 if (led_mode[current_mode].tick) {
435 (*led_mode[current_mode].tick)();
436 expires = jiffies + led_mode[current_mode].jiffies;
437 } else
438 expires = jiffies + HZ;
439 mod_timer(&ledman_timerlist, expires);
442 /****************************************************************************/
444 static int
445 ledman_ioctl(
446 struct inode * inode,
447 struct file * file,
448 unsigned int cmd,
449 unsigned long arg)
451 char mode[LEDMAN_MAX_NAME];
452 int i;
454 if (cmd == LEDMAN_CMD_SIGNAL) {
455 ledman_resetpid = current->pid;
456 return(0);
459 if (cmd == LEDMAN_CMD_MODE) {
460 for (i = 0; i < sizeof(mode) - 1; i++) {
461 Get_user(mode[i], (char *) (arg + i));
462 if (!mode[i])
463 break;
465 mode[i] = '\0';
466 arg = (unsigned long) &mode[0];
468 return(ledman_cmd(cmd, arg));
471 /****************************************************************************/
473 * cmd - from ledman.h
474 * led - led code from ledman.h
476 * check parameters and then call
480 ledman_cmd(int cmd, unsigned long led)
482 ledmode_t *lmp;
483 int i;
485 switch (cmd & ~LEDMAN_CMD_ALTBIT) {
486 case LEDMAN_CMD_SET:
487 case LEDMAN_CMD_ON:
488 case LEDMAN_CMD_OFF:
489 case LEDMAN_CMD_FLASH:
490 case LEDMAN_CMD_RESET:
491 case LEDMAN_CMD_ALT_ON:
492 case LEDMAN_CMD_ALT_OFF:
493 break;
494 case LEDMAN_CMD_STARTTIMER:
495 ledman_starttimer();
496 return(0);
497 case LEDMAN_CMD_KILLTIMER:
498 ledman_killtimer();
499 return(0);
500 case LEDMAN_CMD_MODE:
501 for (i = 0; led_mode[i].name[0]; i++)
502 if (strcmp((char *) led, led_mode[i].name) == 0) {
503 current_mode = i;
504 if (initted)
505 ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
506 return(0);
508 return(-EINVAL);
509 default:
510 return(-EINVAL);
513 if (led < 0 || led >= LEDMAN_MAX)
514 return(-EINVAL);
516 lmp = &led_mode[current_mode];
517 (*lmp->bits)(cmd, lmp->map[led]);
518 return(0);
521 /****************************************************************************/
523 * Signal the reset pid, if we have one
526 void
527 ledman_signalreset()
529 static unsigned long firstjiffies = 0;
530 if (ledman_resetpid == -1)
531 return;
532 if (jiffies > (firstjiffies + (HZ / 4))) {
533 firstjiffies = jiffies;
534 printk("LED: reset switch interrupt! (sending signal to pid=%d)\n",
535 ledman_resetpid);
536 kill_proc(ledman_resetpid, SIGUSR2, 1);
540 /****************************************************************************/
541 #if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
542 /****************************************************************************/
544 static int
545 ledman_bits(unsigned long cmd, unsigned long bits)
547 ledmode_t *lmp = &led_mode[current_mode];
548 int alt, i;
549 unsigned long new_alt;
551 alt = (cmd & LEDMAN_CMD_ALTBIT) ? 1 : 0;
553 switch (cmd & ~LEDMAN_CMD_ALTBIT) {
554 case LEDMAN_CMD_SET:
555 leds_set[alt] |= bits;
556 break;
557 case LEDMAN_CMD_ON:
558 leds_on[alt] |= bits;
559 leds_off[alt] &= ~bits;
560 leds_flash[alt] &= ~bits;
561 (*lmp->tick)();
562 break;
563 case LEDMAN_CMD_OFF:
564 leds_on[alt] &= ~bits;
565 leds_off[alt] |= bits;
566 leds_flash[alt] &= ~bits;
567 (*lmp->tick)();
568 break;
569 case LEDMAN_CMD_FLASH:
570 leds_on[alt] &= ~bits;
571 leds_off[alt] &= ~bits;
572 leds_flash[alt] |= bits;
573 break;
574 case LEDMAN_CMD_RESET:
575 leds_set[alt] = (leds_set[alt] &~bits) | (bits&lmp->def[LEDS_SET]);
576 leds_on[alt] = (leds_on[alt] &~bits) | (bits&lmp->def[LEDS_ON]);
577 leds_off[alt] = (leds_off[alt] &~bits) | (bits&lmp->def[LEDS_OFF]);
578 leds_flash[alt] = (leds_flash[alt]&~bits) | (bits&lmp->def[LEDS_FLASH]);
579 break;
580 case LEDMAN_CMD_ALT_ON:
581 new_alt = (bits & ~leds_alt);
582 leds_alt |= bits;
584 * put any newly alt'd bits into a default state
586 (*lmp->bits)(LEDMAN_CMD_RESET | LEDMAN_CMD_ALTBIT, new_alt);
587 for (i = 0; i < 32; i++)
588 if (bits & (1 << i))
589 leds_alt_cnt[i]++;
590 break;
591 case LEDMAN_CMD_ALT_OFF:
592 for (i = 0; i < 32; i++)
593 if ((bits & (1 << i)) && leds_alt_cnt[i]) {
594 leds_alt_cnt[i]--;
595 if (leds_alt_cnt[i] == 0)
596 leds_alt &= ~(1 << i);
598 break;
599 default:
600 return(-EINVAL);
602 return(0);
605 /****************************************************************************/
607 static void
608 ledman_tick(void)
610 ledmode_t *lmp = &led_mode[current_mode];
611 int new_value;
612 static int flash_on = 0;
614 * work out which LED's should be on
616 new_value = 0;
617 new_value |= (((leds_set[0] | leds_on[0]) & ~leds_off[0]) & ~leds_alt);
618 new_value |= (((leds_set[1] | leds_on[1]) & ~leds_off[1]) & leds_alt);
620 * flashing LED's run on their own devices, ie, according to the
621 * value fo flash_on
623 if ((flash_on++ % 60) >= 30)
624 new_value |= ((leds_flash[0]&~leds_alt) | (leds_flash[1]&leds_alt));
625 else
626 new_value &= ~((leds_flash[0]&~leds_alt) | (leds_flash[1]&leds_alt));
628 * set the HW
630 (*lmp->set)(new_value);
631 leds_set[0] = leds_set[1] = 0;
634 /****************************************************************************/
635 #endif /* !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR) */
636 /****************************************************************************/
637 #if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
638 /****************************************************************************/
640 * Here it the definition of the LED's on the NETtel circuit board
641 * as per the labels next to them. The two parallel port LED's steal
642 * some high bits so we can map it more easily onto the HW
644 * LED - D1 D2 D3 D4 D5 D6 D7 D8 D11 D12
645 * HEX - 100 200 004 008 010 020 040 080 002 001
649 #include <asm/coldfire.h>
650 #include <asm/mcfsim.h>
651 #include <asm/nettel.h>
653 static ledmap_t nettel_old = {
654 0x3ff, 0x200, 0x100, 0x008, 0x004, 0x020, 0x010, 0x080, 0x080, 0x080,
655 0x080, 0x040, 0x040, 0x002, 0x002, 0x024, 0x018, 0x001, 0x0ff, 0x0ff,
656 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
657 0x000, 0x000, 0x000
660 #if defined(CONFIG_SNAPGEAR)
663 * all snapgear 5307 based boards have a SW link status on the front
666 static ledmap_t nettel_new = {
667 0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x008, 0x020,
668 0x020, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x0ff, 0x080,
669 0x000, 0x000, 0x080, 0x004, 0x010, 0x000, 0x000, 0x100, 0x200, 0x000,
670 0x000, 0x000, 0x000
673 #else
675 static ledmap_t nettel_new = {
676 0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x004, 0x020,
677 0x010, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x0ff, 0x080,
678 0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
679 0x000, 0x000, 0x000
682 #endif
684 static leddef_t nettel_def = {
685 0x000, 0x200, 0x000, 0x100,
688 #ifdef ENTERASYS
689 static ledmap_t enterasys_std = {
690 0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x004, 0x020,
691 0x010, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x00c, 0x030,
692 0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
693 0x000, 0x000, 0x000
696 static leddef_t enterasys_def = {
697 0x000, 0x200, 0x000, 0x100,
699 #endif
701 static void
702 nettel_set(unsigned long bits)
704 unsigned long flags;
706 local_save_flags(flags); local_irq_disable();
707 * (volatile char *) NETtel_LEDADDR = (~bits & 0xff);
708 mcf_setppdata(0x60, ~(bits >> 3) & 0x60);
709 local_irq_restore(flags);
712 /****************************************************************************/
713 #endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5307) */
714 /****************************************************************************/
715 #if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
716 /****************************************************************************/
719 * For the SecureEdge Firewall (5272), 5 operational LED's.
721 * LED - POWER HEARTBEAT TX RX VPN
722 * HEX - 001 002 004 008 010
725 #include <asm/coldfire.h>
726 #include <asm/mcfsim.h>
727 #include <asm/nettel.h>
729 static ledmap_t nt5272_std = {
730 0x01f, 0x001, 0x002, 0x008, 0x004, 0x008, 0x004, 0x000, 0x000, 0x008,
731 0x004, 0x000, 0x000, 0x000, 0x000, 0x014, 0x008, 0x010, 0x01c, 0x010,
732 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
733 0x000, 0x000, 0x000
736 static leddef_t nt5272_def = {
737 0x000, 0x001, 0x000, 0x002,
740 static void nt5272_set(unsigned long bits)
742 *((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = (~bits & 0x1f);
745 /****************************************************************************/
746 #endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5272) */
747 /****************************************************************************/
748 #if defined(CONFIG_SE1100)
749 /****************************************************************************/
752 * For the SecureEdge SE1100 (5272), 3 operational LED's.
754 * LED - RUNNING INTERNAL1 INTERNAL2
755 * HEX - 001 200 002
758 #include <asm/coldfire.h>
759 #include <asm/mcfsim.h>
760 #include <asm/se1100.h>
762 static ledmap_t se1100_std = {
763 0x203, 0x000, 0x001, 0x200, 0x200, 0x200, 0x200, 0x000, 0x000, 0x000,
764 0x000, 0x002, 0x002, 0x002, 0x002, 0x200, 0x002, 0x000, 0x202, 0x000,
765 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
766 0x000, 0x000, 0x000
769 static leddef_t se1100_def = {
770 0x000, 0x000, 0x000, 0x001
773 static void se1100_set(unsigned long bits)
775 mcf_setpa(0x203, bits & 0x203);
778 /****************************************************************************/
779 #endif /* defined(CONFIG_SE1100) */
780 /****************************************************************************/
781 #if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
782 /****************************************************************************/
785 * For the Gilbarco/NAP (5272), 2 operational LED's.
787 * LED - RUNNING DIAG
788 * HEX - 001 002
791 #include <asm/coldfire.h>
792 #include <asm/mcfsim.h>
793 #include <asm/nap.h>
795 static ledmap_t nap5272_std = {
796 0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
797 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000,
798 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
799 0x000, 0x000, 0x000
802 static leddef_t nap5272_def = {
803 0x000, 0x001, 0x000, 0x002,
806 static void nap5272_set(unsigned long bits)
808 mcf_setpa(0x3, ~bits & 0x3);
811 /****************************************************************************/
812 #endif /* defined(CONFIG_MARCONINAP) && defined(CONFIG_M5272) */
813 /****************************************************************************/
814 #if defined(CONFIG_SH_SECUREEDGE5410)
815 /****************************************************************************/
818 * For the SecureEdge5410 7 (or 8 for eth2/DMZ port) operational LED's.
820 * LED - POWR HBEAT LAN1 LAN2 | LAN3 | COM ONLINE VPN
821 * POS - D2 D3 D4 D5 | ?? | D6 D7 D8 DTR
822 * HEX - 01 02 04 08 |0x2000| 10 20 40 80
825 #include <asm/io.h>
826 #if defined(CONFIG_LEDMAP_TAMS_SOHO)
828 * LED - POWR HBEAT LAN1 LAN2 COM ONLINE VPN
829 * POS - D2 D3 D4 D5 ?? D6 D7 DTR
830 * HEX - 01 02 04 08 0x2000 10 20 80
832 static ledmap_t se5410_std = {
833 0x203f,0x0001,0x0002,0x2000,0x2000,0x2000,0x2000,0x0004,0x0004,0x0008,
834 0x0008,0x0000,0x0000,0x0000,0x0000,0x2024,0x0018,0x0020,0x203c,0x0000,
835 0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,0x0000,0x0001,0x0002,0x0000,
836 0x0000,0x0000,0x0000
838 #else
839 static ledmap_t se5410_std = {
840 0x207f,0x0001,0x0002,0x0010,0x0010,0x0010,0x0010,0x0004,0x0004,0x0008,
841 0x0008,0x0000,0x0000,0x0000,0x0000,0x2054,0x0028,0x0040,0x207c,0x0000,
842 0x0000,0x0000,0x0020,0x0000,0x0000,0x0000,0x0000,0x0001,0x0002,0x2000,
843 0x2000,0x0000,0x0000
845 #endif
847 static leddef_t se5410_def = {
848 0x0000, 0x0001, 0x0000, 0x0002,
851 static void se5410_set(unsigned long bits)
853 int flags;
855 local_irq_save(flags);
856 SECUREEDGE_WRITE_IOPORT(~bits, 0x207f);
857 local_irq_restore(flags);
860 /****************************************************************************/
861 #endif /* defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272) */
862 /****************************************************************************/
863 #if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
864 /****************************************************************************/
866 * For the WebWhale/NETtel1500, 3 LED's (was 2)
868 * LED - HEARTBEAT DCD DATA
869 * HEX - 001 002 004
872 #include <asm/coldfire.h>
873 #include <asm/mcfsim.h>
874 #include <asm/nettel.h>
876 static ledmap_t nt1500_std = {
877 0x007, 0x000, 0x001, 0x004, 0x004, 0x004, 0x004, 0x000, 0x000, 0x000,
878 0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x002, 0x000, 0x007, 0x000,
879 0x002, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
880 0x000, 0x000, 0x000
883 static leddef_t nt1500_def = {
884 0x000, 0x000, 0x000, 0x001,
887 static void
888 nt1500_set(unsigned long bits)
890 * (volatile char *) NETtel_LEDADDR = (~bits & 0x7);
893 /****************************************************************************/
894 #endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5206e) */
895 /****************************************************************************/
896 #ifdef CONFIG_eLIA
897 /****************************************************************************/
899 * For the eLIA, only 2 LED's.
901 * LED - HEARTBEAT USER
902 * HEX - 2 1
905 #ifdef CONFIG_COLDFIRE
906 #include <asm/coldfire.h>
907 #include <asm/mcfsim.h>
908 #endif
909 #include <asm/elia.h>
911 static ledmap_t elia_std = {
912 0x003, 0x000, 0x002, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000,
913 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000,
914 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
915 0x000, 0x000, 0x000
918 static leddef_t elia_def = {
919 0x000, 0x000, 0x000, 0x002,
922 static void
923 elia_set(unsigned long bits)
925 unsigned long flags;
927 local_save_flags(flags); local_irq_disable();
928 mcf_setppdata(0x3000, ~(bits << 12) & 0x3000);
929 local_irq_restore(flags);
932 /****************************************************************************/
933 #endif /* CONFIG_eLIA */
934 /****************************************************************************/
935 /****************************************************************************/
936 #if defined(CONFIG_AMDSC520)
937 /****************************************************************************/
939 #include <linux/smp_lock.h>
940 #include <linux/sched.h>
941 #include <linux/reboot.h>
942 #include <linux/delay.h>
943 #include <asm/io.h>
945 #if defined(CONFIG_CHINOOK)
947 * Here is the definition of the LED's on the 6wind Chinook circuit board
948 * as per the LED order from left to right. These probably don't
949 * correspond to any known enclosure.
951 * LED - D1 D2 D3 D4 D5 D6 D7 D8 D9 D10
952 * HEX - 0001 0400 0008 0010 0800 0020 0040 0080 0100 0200
954 * Sync LEDs - Activity Link
955 * HEX - 04000000 08000000
957 static ledmap_t nettel_std = {
958 0x0c000ff9, 0x00000001, 0x00000400, 0x00000040, 0x00000040,
959 0x04000000, 0x04000000, 0x00000010, 0x00000008, 0x00000020,
960 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
961 0x00000028, 0x00000810, 0x00000200, 0x00000bf8, 0x00000820,
962 0x00000000, 0x08000000, 0x00000100, 0x00000000, 0x00000000,
963 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
964 0x00000000, 0x00000000, 0x00000000
967 static leddef_t nettel_def = {
968 0x0000, 0x0001, 0x0000, 0x0400,
971 #elif defined(CONFIG_SNAPGEAR)
973 * Here is the definition of the LED's on the SnapGear x86 circuit board
974 * as per the labels next to them.
976 * LED - D1 D2 D3 D4 D5 D6 D7 D8 D9 D10
977 * HEX - 001 002 004 008 010 020 040 100 080 200
979 static ledmap_t nettel_std = {
980 0x3ff, 0x001, 0x002, 0x080, 0x080, 0x040, 0x040, 0x010, 0x010, 0x020,
981 0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
982 0x000, 0x000, 0x100, 0x008, 0x004, 0x000, 0x000, 0x001, 0x002, 0x000,
983 0x000, 0x000, 0x000
986 static leddef_t nettel_def = {
987 0x0000, 0x0001, 0x0000, 0x0002,
991 * Here is the definition of the LED's on the SnapGear x86 circuit board
992 * as per the labels next to them. This is for the old enclosure.
994 * LED - D1 D2 D3 D4 D5 D6 D7 D8 D9 D10
995 * HEX - 001 002 004 008 010 020 040 100 080 200
997 static ledmap_t nettel_old = {
998 0x3ff, 0x002, 0x001, 0x080, 0x080, 0x040, 0x040, 0x010, 0x010, 0x020,
999 0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
1000 0x000, 0x000, 0x100, 0x008, 0x004, 0x000, 0x000, 0x001, 0x002, 0x000,
1001 0x000, 0x000, 0x000
1004 static leddef_t nettel_def_old = {
1005 0x0000, 0x0002, 0x0000, 0x0001,
1008 #elif defined(CONFIG_SITECTRLER)
1010 * Here it the definition of the LED's on the SiteController circuit board
1011 * as per the labels next to them. (D9 and D10 are not software controlled)
1013 * LED - D1 D2 D3 D4 D5 D6 D7 D8
1014 * HEX - 0001 0002 0004 0008 0010 0020 0040 0080
1016 static ledmap_t nettel_std = {
1017 0x10fd,0x0001,0x1000,0x0004,0x0004,0x0008,0x0008,0x0040,0x0040,0x0080,
1018 0x0080,0x0000,0x0000,0x0000,0x0000,0x00cc,0x0030,0x0000,0x0000,0x0000,
1019 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,
1020 0x0000,0x0000,0x0000
1023 static leddef_t nettel_def = {
1024 0x0000, 0x0001, 0x0000, 0x1000,
1027 #elif defined(CONFIG_ADTRAN_ADVANTA)
1029 * Here is the definition of the LED's on the Adtran Advanta3110 circuit
1030 * board as per the labels next to them.
1031 * The lower 8 bits are for IO port 0x300.
1032 * The upper 4 bits are for PIO31-28.
1034 * LED - D1 D2 D3 D4 D7 D8 D15green D15red D16green D16red
1035 * HEX - 01 02 04 08 40 80 10000000 40000000 20000000 80000000
1037 static ledmap_t nettel_std = {
1038 0xf00000cf, 0x00000000, 0x20000000, 0x00000000, 0x00000000,
1039 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000008,
1040 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1041 0x00000009, 0x00000006, 0x10000000, 0x100000cf, 0x0000000c,
1042 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1043 0x00000080, 0x00000040, 0x00000001, 0x00000002, 0x00000000,
1044 0x00000000, 0x00000000, 0x00000000
1047 static leddef_t nettel_def = {
1048 0, 0, 0, 0x20000000,
1051 #else
1053 * Here is the definition of the LED's on the x86 NETtel circuit board
1054 * as per the labels next to them.
1056 * LED - D1 D2 D3 D4 D5 D6 D7 D8 D9 D10
1057 * HEX - 001 002 004 008 010 020 040 100 080 200
1059 static ledmap_t nettel_std = {
1060 0x3ff, 0x002, 0x001, 0x100, 0x100, 0x080, 0x080, 0x010, 0x008, 0x040,
1061 0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
1062 0x000, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
1063 0x000, 0x000, 0x000
1066 static leddef_t nettel_def = {
1067 0x0000, 0x0002, 0x0000, 0x0001,
1070 #endif
1072 static volatile unsigned long *ledman_ledp;
1074 static void nettel_set(unsigned long bits)
1076 #ifdef CONFIG_ADTRAN_ADVANTA
1077 outb(~bits, 0x300);
1078 *ledman_ledp = (*ledman_ledp & 0x0fffffff) | (~bits & 0xf0000000);
1079 #else
1080 *ledman_ledp = (*ledman_ledp & ~ nettel_std[LEDMAN_ALL])
1081 | (~bits & nettel_std[LEDMAN_ALL]);
1082 #endif
1085 static irqreturn_t ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1087 ledman_signalreset();
1088 return IRQ_HANDLED;
1091 static void ledman_initarch(void)
1093 volatile unsigned char *mmcrp;
1095 /* Map the CPU MMCR register for access */
1096 mmcrp = (volatile unsigned char *) ioremap(0xfffef000, 4096);
1098 #ifdef CONFIG_ADTRAN_ADVANTA
1099 /* Enable the PIO for the PWR and VPN LEDs */
1100 *(volatile unsigned short *)(mmcrp + 0xc22) &= 0x0fff;
1101 *(volatile unsigned short *)(mmcrp + 0xc2c) |= 0xf000;
1103 /* Enable GPIRQ2, low-to-high transitions, map to IRQ12 */
1104 *(volatile unsigned short *)(mmcrp + 0xc22) |= 0x0020;
1105 *(volatile unsigned long *)(mmcrp + 0xd10) |= 0x0004;
1106 *(mmcrp + 0xd52) = 0x07;
1107 #endif
1109 ledman_ledp = (volatile unsigned long *) (mmcrp + 0xc30);
1111 /* Setup extern "factory default" switch on IRQ12 */
1112 if (request_irq(12, ledman_interrupt, SA_INTERRUPT, "Reset", NULL))
1113 printk("LED: failed to register IRQ12 for Reset witch\n");
1114 else
1115 printk("LED: registered RESET switch on IRQ12\n");
1118 /****************************************************************************/
1119 #endif /* CONFIG_AMDSC520 */
1120 /****************************************************************************/
1121 /****************************************************************************/
1122 #if defined(CONFIG_GEODE)
1123 /****************************************************************************/
1125 #include <asm/io.h>
1128 * Construct a mapping from virtual LED to gpio bit and bank.
1130 struct gpiomap {
1131 unsigned int bank;
1132 unsigned long bit;
1135 #if defined(CONFIG_REEFEDGE)
1137 * Definition of the LED's on the GEODE SC1100 ReefEdfe circuit board,
1138 * as per the labels next to them.
1140 * LED - D20 D19 D18 D16
1141 * GPIO BIT - 38 18 40 37
1142 * VIRTNUM - 0x8 0x4 0x2 0x1
1144 #define GPIO0_OFF 0x00040000
1145 #define GPIO1_OFF 0x00000160
1147 static ledmap_t nettel_std = {
1148 0x00f, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x004,
1149 0x004, 0x008, 0x008, 0x000, 0x000, 0x000, 0x000, 0x004,
1150 0x008, 0x000, 0x00e, 0x000, 0x000, 0x000, 0x000, 0x000,
1151 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
1152 0x000
1155 static struct gpiomap iomap[] = {
1156 /* VIRT 0x1 */ { 1, 0x00000020 },
1157 /* VIRT 0x2 */ { 1, 0x00000100 },
1158 /* VIRT 0x4 */ { 0, 0x00040000 },
1159 /* VIRT 0x8 */ { 1, 0x00000040 },
1162 #else
1164 * Definition of the LED's on the SnapGear GEODE board.
1166 * LED - D11 D12 D13 D14 D15 D16 D17 D18 D19 D20
1167 * GPIO BIT - 32 33 34 35 36 37 39 40 18 38
1168 * VIRTNUM - 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200
1170 #define GPIO0_OFF 0x00040000
1171 #define GPIO1_OFF 0x000001ff
1173 static ledmap_t nettel_std = {
1174 0x3ff, 0x001, 0x002, 0x080, 0x080, 0x080, 0x080, 0x010,
1175 0x008, 0x040, 0x020, 0x200, 0x200, 0x200, 0x200, 0x30c,
1176 0x0f0, 0x000, 0x3fc, 0x004, 0x000, 0x000, 0x004, 0x000,
1177 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
1178 0x000
1181 static struct gpiomap iomap[] = {
1182 /* VIRT 0x1 */ { 1, 0x00000001 },
1183 /* VIRT 0x2 */ { 1, 0x00000002 },
1184 /* VIRT 0x4 */ { 1, 0x00000004 },
1185 /* VIRT 0x8 */ { 1, 0x00000008 },
1186 /* VIRT 0x10 */ { 1, 0x00000010 },
1187 /* VIRT 0x20 */ { 1, 0x00000020 },
1188 /* VIRT 0x40 */ { 1, 0x00000080 },
1189 /* VIRT 0x80 */ { 1, 0x00000100 },
1190 /* VIRT 0x100 */ { 0, 0x00040000 },
1191 /* VIRT 0x200 */ { 1, 0x00000040 },
1194 #endif /* !CONFIG_REEFEDGE */
1196 #define GPIO_SIZE (sizeof(iomap) / sizeof(*iomap))
1198 static leddef_t nettel_def = {
1199 0x0000, 0x0001, 0x0000, 0x0002,
1203 static void nettel_set(unsigned long bits)
1205 unsigned int gpio[2];
1206 unsigned int i, mask;
1208 gpio[0] = GPIO0_OFF;
1209 gpio[1] = GPIO1_OFF;
1211 for (i = 0, mask = 0x1; (i < GPIO_SIZE); i++, mask <<= 1) {
1212 if (bits & mask)
1213 gpio[iomap[i].bank] &= ~iomap[i].bit;
1216 outl(gpio[0], 0x6400);
1217 outl(gpio[1], 0x6410);
1220 static int ledman_button;
1221 static struct timer_list ledman_timer;
1223 static void ledman_buttonpoll(unsigned long arg)
1225 if (inl(0x6404) & 0x0002) {
1226 if (ledman_button == 0) {
1227 printk("LEDMAN: reset button pushed!\n");
1228 ledman_signalreset();
1230 ledman_button = 1;
1231 } else {
1232 ledman_button = 0;
1235 /* Re-arm timer interrupt. */
1236 mod_timer(&ledman_timer, jiffies + HZ/25);
1239 static void ledman_initarch(void)
1241 init_timer(&ledman_timer);
1242 ledman_timer.function = ledman_buttonpoll;
1243 ledman_timer.data = 0;
1244 mod_timer(&ledman_timer, jiffies + HZ/25);
1247 /****************************************************************************/
1248 #endif /* CONFIG_GEODE */
1249 /****************************************************************************/
1250 /****************************************************************************/
1251 #if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
1252 /****************************************************************************/
1254 * Here it the definition of the how we use the 8 segment LED display on
1255 * the Hitachi Keywest
1257 * LED - LD0 LD1 LD2 LD3 LD4 LD5 LD6 LD7
1258 * HEX - 001 002 004 008 010 020 040 080
1259 * HB CNT L1R L1T L2R L2T COM VPN
1263 #include <linux/kernel_stat.h>
1265 #define KEYWEST_NUM_LEDS 8
1267 #if defined(CONFIG_SH_BIGSUR)
1268 #define LED_BASE 0xb1fffe00
1269 #define LED_ADDR(x) (LED_BASE+((x)<<2))
1270 #else
1271 #define LED_BASE 0xb1ffe000
1272 #define LED_ADDR(x) (LED_BASE+(x))
1273 #endif
1275 static ledmap_t keywest_std = {
1276 0x0ff, 0x000, 0x001, 0x040, 0x040, 0x040, 0x040, 0x004, 0x008, 0x010,
1277 0x020, 0x000, 0x000, 0x000, 0x000, 0x054, 0x02a, 0x080, 0x07e, 0x000,
1278 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
1279 0x000, 0x000, 0x000
1282 static leddef_t keywest_def = {
1283 0x000, 0x000, 0x000, 0x001,
1286 static struct keywest_led_value {
1287 int count;
1288 int max;
1289 int prev;
1290 unsigned char disp;
1291 } keywest_led_values[KEYWEST_NUM_LEDS][2];
1294 struct keywest_font_s {
1295 unsigned char row[7];
1296 } keywest_font[] = {
1297 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}, /* bar 0 */
1298 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f }}, /* bar 1 */
1299 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f }}, /* bar 2 */
1300 {{ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f }}, /* bar 3 */
1301 {{ 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 4 */
1302 {{ 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 5 */
1303 {{ 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 6 */
1304 {{ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 7 */
1305 {{ 0x00, 0x0a, 0x1f, 0x1f, 0x0e, 0x04, 0x00 }}, /* heart */
1306 {{ 0x08, 0x14, 0x14, 0x1c, 0x1c, 0x1c, 0x1c }}, /* vpn locked */
1307 {{ 0x02, 0x05, 0x05, 0x1c, 0x1c, 0x1c, 0x1c }}, /* vpn unlocked */
1310 static unsigned int keywest_old_cntx = 0;
1313 * program up some display bars
1316 static void ledman_initkeywest()
1318 int i, j;
1320 for (i = 0; i < sizeof(keywest_font) / sizeof(struct keywest_font_s); i++) {
1321 * (unsigned char *)(LED_ADDR(0x20)) = i;
1322 for (j = 0; j < 7; j++)
1323 * (unsigned char *)(LED_ADDR(0x28+j)) = keywest_font[i].row[j];
1325 keywest_old_cntx = kstat.context_swtch;
1329 * We just rip through and write all LED 'disp' chars each tick.
1332 static void keywest_set(unsigned long bits)
1334 int i, alt;
1335 for (i = 0; i < KEYWEST_NUM_LEDS; i++) {
1336 alt = (leds_alt & (1 << i)) ? 1 : 0;
1337 * (unsigned char *)(LED_ADDR(0x38+i)) = keywest_led_values[i][alt].disp;
1341 static int
1342 keywest_bits(unsigned long cmd, unsigned long bits)
1344 ledmode_t *lmp = &led_mode[current_mode];
1345 int alt, i;
1346 unsigned long new_alt;
1348 alt = (cmd & LEDMAN_CMD_ALTBIT) ? 1 : 0;
1350 switch (cmd & ~LEDMAN_CMD_ALTBIT) {
1351 case LEDMAN_CMD_SET:
1352 bits &= ~(leds_flash[alt]|leds_on[alt]|leds_off[alt]);
1353 for (i = 0; i < KEYWEST_NUM_LEDS; i++)
1354 if (bits & (1 << i))
1355 keywest_led_values[i][alt].count++;
1356 break;
1357 case LEDMAN_CMD_ON:
1358 leds_on[alt] |= bits;
1359 leds_off[alt] &= ~bits;
1360 leds_flash[alt] &= ~bits;
1361 (*lmp->tick)();
1362 break;
1363 case LEDMAN_CMD_OFF:
1364 leds_on[alt] &= ~bits;
1365 leds_off[alt] |= bits;
1366 leds_flash[alt] &= ~bits;
1367 (*lmp->tick)();
1368 break;
1369 case LEDMAN_CMD_FLASH:
1370 leds_on[alt] &= ~bits;
1371 leds_off[alt] &= ~bits;
1372 leds_flash[alt] |= bits;
1373 break;
1374 case LEDMAN_CMD_RESET:
1375 leds_on[alt] = (leds_on[alt] &~bits) | (bits&lmp->def[LEDS_ON]);
1376 leds_off[alt] = (leds_off[alt] &~bits) | (bits&lmp->def[LEDS_OFF]);
1377 leds_flash[alt] = (leds_flash[alt]&~bits) | (bits&lmp->def[LEDS_FLASH]);
1378 memset(keywest_led_values, 0, sizeof(keywest_led_values));
1379 break;
1380 case LEDMAN_CMD_ALT_ON:
1381 new_alt = (bits & ~leds_alt);
1382 leds_alt |= bits;
1384 * put any newly alt'd bits into a default state
1386 (*lmp->bits)(LEDMAN_CMD_RESET | LEDMAN_CMD_ALTBIT, new_alt);
1387 for (i = 0; i < 32; i++)
1388 if (bits & (1 << i))
1389 leds_alt_cnt[i]++;
1390 break;
1391 case LEDMAN_CMD_ALT_OFF:
1392 for (i = 0; i < 32; i++)
1393 if ((bits & (1 << i)) && leds_alt_cnt[i]) {
1394 leds_alt_cnt[i]--;
1395 if (leds_alt_cnt[i] == 0)
1396 leds_alt &= ~(1 << i);
1398 break;
1399 default:
1400 return(-EINVAL);
1402 return(0);
1405 static void
1406 keywest_tick(void)
1408 ledmode_t *lmp = &led_mode[current_mode];
1409 int alt, i;
1410 static int flash_on = 0;
1411 struct keywest_led_value *led_value;
1414 * we take over the second LED as a context switch indicator
1416 keywest_led_values[1][0].count = kstat.context_swtch - keywest_old_cntx;
1417 keywest_old_cntx = kstat.context_swtch;
1419 for (i = 0; i < KEYWEST_NUM_LEDS; i++) {
1420 alt = (leds_alt >> i) & 1;
1421 led_value = &keywest_led_values[i][alt];
1422 if (leds_off[alt] & (1 << i)) {
1423 if ((1 << i) == 0x080) /* VPN unlock */
1424 led_value->disp = 0x8a;
1425 else
1426 led_value->disp = 0x20;
1427 } else if (leds_on[alt] & (1 << i)) {
1428 if ((1 << i) == 0x080) /* VPN lock */
1429 led_value->disp = 0x89;
1430 else
1431 led_value->disp = 0x87;
1432 } else if (leds_flash[alt] & (1 << i)) {
1433 if ((flash_on % 6) >= 3) {
1434 if ((1 << i) == 0x001) /* heart beat */
1435 led_value->disp = 0x88;
1436 else
1437 led_value->disp = 0x87;
1438 } else
1439 led_value->disp = 0x20;
1440 } else {
1441 int val;
1443 if (led_value->count > led_value->max)
1444 led_value->max = led_value->count;
1446 val = (led_value->prev + led_value->count) / 2;
1447 led_value->prev = val;
1449 val = (val * 7) / led_value->max;
1450 if (val == 0 && led_value->count)
1451 val = 1;
1452 led_value->disp = 0x80 + (val & 0x7);
1453 led_value->count = 0;
1454 /* degrade the maximum over time (except load) */
1455 if (i != 1)
1456 led_value->max = (led_value->max * 9)/10;
1459 flash_on++;
1460 (*lmp->set)(0);
1463 /****************************************************************************/
1464 #endif /* CONFIG_SH_KEYWEST */
1465 /****************************************************************************/
1466 /****************************************************************************/
1467 #if defined(CONFIG_ARCH_SE4000)
1468 /****************************************************************************/
1470 #include <linux/interrupt.h>
1471 #include <asm/hardware.h>
1472 #include <asm/io.h>
1475 * Here is the definition of the LED's on the SnapGear/IXP425 circuit board
1476 * as per the labels next to them. LED D7 is not visible on the front panel,
1477 * so not much point using it...
1479 * LED - D1 D3 D4 D5 D6 D7
1480 * HEX - 004 008 010 020 040 080
1482 static ledmap_t snapgear425_std = {
1483 0x0fc, 0x000, 0x004, 0x008, 0x008, 0x008, 0x008, 0x000, 0x000, 0x000,
1484 0x000, 0x000, 0x000, 0x000, 0x000, 0x028, 0x010, 0x020, 0x0fc, 0x010,
1485 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
1486 0x000, 0x000, 0x000
1489 static leddef_t snapgear425_def = {
1490 0x0000, 0x0000, 0x0000, 0x0004,
1493 static volatile struct ixp425_gpio *ledman_gpio;
1495 static irqreturn_t ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1497 ledman_gpio->gpisr |= 0x200;
1498 ledman_signalreset();
1499 return IRQ_HANDLED;
1502 static void snapgear425_set(unsigned long bits)
1504 ledman_gpio->gpoutr = (ledman_gpio->gpoutr & ~0xfc) | (~bits & 0xfc);
1507 static void ledman_initarch(void)
1509 ledman_gpio = (volatile struct ixp425_gpio *) ioremap(IXP425_GPIO_BASE_PHYS, 4096);
1511 /* Enable LED lines as outputs */
1512 ledman_gpio->gpoer &= ~0xfc;
1514 /* Configure GPIO9 as interrupt input (ERASE switch) */
1515 ledman_gpio->gpoer |= 0x200;
1516 ledman_gpio->gpit2r = (ledman_gpio->gpit2r & ~0x38) | 0x18;
1517 ledman_gpio->gpisr |= 0x200;
1519 if (request_irq(26, ledman_interrupt, SA_INTERRUPT, "Reset", NULL))
1520 printk("LED: failed to register IRQ26 for Reset witch\n");
1521 else
1522 printk("LED: registered RESET switch on IRQ26\n");
1525 /****************************************************************************/
1526 #endif /* CONFIG_ARCH_SE4000 */
1527 /****************************************************************************/