aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm47xx/wgt634u.c
blob: f9e309a965763d5027191dfbaff60880b8919a53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
 */

#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
#include <asm/mach-bcm47xx/bcm47xx.h>

/* GPIO definitions for the WGT634U */
#define WGT634U_GPIO_LED	3
#define WGT634U_GPIO_RESET	2
#define WGT634U_GPIO_TP1	7
#define WGT634U_GPIO_TP2	6
#define WGT634U_GPIO_TP3	5
#define WGT634U_GPIO_TP4	4
#define WGT634U_GPIO_TP5	1

static struct gpio_led wgt634u_leds[] = {
	{
		.name = "power",
		.gpio = WGT634U_GPIO_LED,
		.active_low = 1,
		.default_trigger = "heartbeat",
	},
};

static struct gpio_led_platform_data wgt634u_led_data = {
	.num_leds =     ARRAY_SIZE(wgt634u_leds),
	.leds =         wgt634u_leds,
};

static struct platform_device wgt634u_gpio_leds = {
	.name =         "leds-gpio",
	.id =           -1,
	.dev = {
		.platform_data = &wgt634u_led_data,
	}
};


/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
   firmware. */
static struct mtd_partition wgt634u_partitions[] = {
	{
		.name       = "cfe",
		.offset     = 0,
		.size       = 0x60000,		/* 384k */
		.mask_flags = MTD_WRITEABLE 	/* force read-only */
	},
	{
		.name   = "config",
		.offset = 0x60000,
		.size   = 0x20000		/* 128k */
	},
	{
		.name   = "linux",
		.offset = 0x80000,
		.size   = 0x140000 		/* 1280k */
	},
	{
		.name   = "jffs",
		.offset = 0x1c0000,
		.size   = 0x620000 		/* 6272k */
	},
	{
		.name   = "nvram",
		.offset = 0x7e0000,
		.size   = 0x20000		/* 128k */
	},
};

static struct physmap_flash_data wgt634u_flash_data = {
	.parts    = wgt634u_partitions,
	.nr_parts = ARRAY_SIZE(wgt634u_partitions)
};

static struct resource wgt634u_flash_resource = {
	.flags = IORESOURCE_MEM,
};

static struct platform_device wgt634u_flash = {
	.name          = "physmap-flash",
	.id            = 0,
	.dev           = { .platform_data = &wgt634u_flash_data, },
	.resource      = &wgt634u_flash_resource,
	.num_resources = 1,
};

/* Platform devices */
static struct platform_device *wgt634u_devices[] __initdata = {
	&wgt634u_flash,
	&wgt634u_gpio_leds,
};

static int __init wgt634u_init(void)
{
	/* There is no easy way to detect that we are running on a WGT634U
	 * machine. Use the MAC address as an heuristic. Netgear Inc. has
	 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
	 */

	u8 *et0mac = ssb_bcm47xx.sprom.et0mac;

	if (et0mac[0] == 0x00 &&
	    ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
	     (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
		struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;

		printk(KERN_INFO "WGT634U machine detected.\n");

		wgt634u_flash_data.width = mcore->flash_buswidth;
		wgt634u_flash_resource.start = mcore->flash_window;
		wgt634u_flash_resource.end = mcore->flash_window
					   + mcore->flash_window_size
					   - 1;
		return platform_add_devices(wgt634u_devices,
					    ARRAY_SIZE(wgt634u_devices));
	} else
		return -ENODEV;
}

module_init(wgt634u_init);