1 /*
2  * Soekris board support code
3  *
4  * Copyright (C) 2008-2009 Tower Technologies
5  * Written by Alessandro Zummo <a.zummo@towertech.it>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2
9  * as published by the Free Software Foundation.
10  */
11 
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/io.h>
15 #include <linux/string.h>
16 #include <linux/leds.h>
17 #include <linux/platform_device.h>
18 #include <linux/gpio.h>
19 #include <linux/module.h>
20 
21 #include <asm/geode.h>
22 
23 static const struct gpio_led net5501_leds[] = {
24 	{
25 		.name = "error",
26 		.gpio = 6,
27 		.default_trigger = "default-on",
28 	},
29 };
30 
31 static struct gpio_led_platform_data net5501_leds_data = {
32 	.num_leds = ARRAY_SIZE(net5501_leds),
33 	.leds = net5501_leds,
34 };
35 
36 static struct platform_device net5501_leds_dev = {
37 	.name = "leds-gpio",
38 	.id = -1,
39 	.dev.platform_data = &net5501_leds_data,
40 };
41 
init_net5501(void)42 static void __init init_net5501(void)
43 {
44 	platform_device_register(&net5501_leds_dev);
45 }
46 
47 struct soekris_board {
48 	u16	offset;
49 	char	*sig;
50 	u8	len;
51 	void	(*init)(void);
52 };
53 
54 static struct soekris_board __initdata boards[] = {
55 	{ 0xb7b, "net5501", 7, init_net5501 },	/* net5501 v1.33/1.33c */
56 	{ 0xb1f, "net5501", 7, init_net5501 },	/* net5501 v1.32i */
57 };
58 
soekris_init(void)59 static int __init soekris_init(void)
60 {
61 	int i;
62 	unsigned char *rombase, *bios;
63 
64 	if (!is_geode())
65 		return 0;
66 
67 	rombase = ioremap(0xffff0000, 0xffff);
68 	if (!rombase) {
69 		printk(KERN_INFO "Soekris net5501 LED driver failed to get rombase");
70 		return 0;
71 	}
72 
73 	bios = rombase + 0x20;	/* null terminated */
74 
75 	if (strncmp(bios, "comBIOS", 7))
76 		goto unmap;
77 
78 	for (i = 0; i < ARRAY_SIZE(boards); i++) {
79 		unsigned char *model = rombase + boards[i].offset;
80 
81 		if (strncmp(model, boards[i].sig, boards[i].len) == 0) {
82 			printk(KERN_INFO "Soekris %s: %s\n", model, bios);
83 
84 			if (boards[i].init)
85 				boards[i].init();
86 			break;
87 		}
88 	}
89 
90 unmap:
91 	iounmap(rombase);
92 	return 0;
93 }
94 
95 arch_initcall(soekris_init);
96 
97 MODULE_LICENSE("GPL");
98