nslu2-setup.c 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * arch/arm/mach-ixp4xx/nslu2-setup.c
 *
 * NSLU2 board-setup
 *
 * based ixdp425-setup.c:
 *      Copyright (C) 2003-2004 MontaVista Software, Inc.
 *
 * Author: Mark Rakes <mrakes at mac.com>
10
 * Author: Rod Whitby <rod@whitby.id.au>
11 12 13 14 15 16
 * Maintainers: http://www.nslu2-linux.org/
 *
 * Fixed missing init_time in MACHINE_START kas11 10/22/04
 * Changed to conform to new style __init ixdp425 kas11 10/22/04
 */

17
#include <linux/if_ether.h>
18 19 20
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
21
#include <linux/leds.h>
22
#include <linux/i2c.h>
M
Michael-Luke Jones 已提交
23
#include <linux/i2c-gpio.h>
24 25 26 27

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
28
#include <asm/mach/time.h>
29
#include <asm/io.h>
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

static struct flash_platform_data nslu2_flash_data = {
	.map_name		= "cfi_probe",
	.width			= 2,
};

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

static struct platform_device nslu2_flash = {
	.name			= "IXP4XX-Flash",
	.id			= 0,
	.dev.platform_data	= &nslu2_flash_data,
	.num_resources		= 1,
	.resource		= &nslu2_flash_resource,
};

M
Michael-Luke Jones 已提交
48
static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
49 50 51 52
	.sda_pin		= NSLU2_SDA_PIN,
	.scl_pin		= NSLU2_SCL_PIN,
};

53 54 55 56 57 58
static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
	{
		I2C_BOARD_INFO("rtc-x1205", 0x6f),
	},
};

59
static struct gpio_led nslu2_led_pins[] = {
60 61
	{
		.name		= "ready",  /* green led */
62
		.gpio		= NSLU2_LED_GRN_GPIO,
63 64 65
	},
	{
		.name		= "status", /* red led */
66
		.gpio		= NSLU2_LED_RED_GPIO,
67 68 69
	},
	{
		.name		= "disk-1",
70 71
		.gpio		= NSLU2_LED_DISK1_GPIO,
		.active_low	= true,
72 73 74
	},
	{
		.name		= "disk-2",
75 76
		.gpio		= NSLU2_LED_DISK2_GPIO,
		.active_low	= true,
77 78 79
	},
};

80 81 82 83 84
static struct gpio_led_platform_data nslu2_led_data = {
	.num_leds		= ARRAY_SIZE(nslu2_led_pins),
	.leds			= nslu2_led_pins,
};

85
static struct platform_device nslu2_leds = {
86
	.name			= "leds-gpio",
87
	.id			= -1,
88
	.dev.platform_data	= &nslu2_led_data,
89 90
};

M
Michael-Luke Jones 已提交
91 92
static struct platform_device nslu2_i2c_gpio = {
	.name			= "i2c-gpio",
93
	.id			= 0,
M
Michael-Luke Jones 已提交
94 95 96
	.dev	 = {
		.platform_data	= &nslu2_i2c_gpio_data,
	},
97 98
};

99 100 101 102 103 104
static struct platform_device nslu2_beeper = {
	.name			= "ixp4xx-beeper",
	.id			= NSLU2_GPIO_BUZZ,
	.num_resources		= 0,
};

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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
static struct resource nslu2_uart_resources[] = {
	{
		.start		= IXP4XX_UART1_BASE_PHYS,
		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
		.flags		= IORESOURCE_MEM,
	},
	{
		.start		= IXP4XX_UART2_BASE_PHYS,
		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
		.flags		= IORESOURCE_MEM,
	}
};

static struct plat_serial8250_port nslu2_uart_data[] = {
	{
		.mapbase	= IXP4XX_UART1_BASE_PHYS,
		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
		.irq		= IRQ_IXP4XX_UART1,
		.flags		= UPF_BOOT_AUTOCONF,
		.iotype		= UPIO_MEM,
		.regshift	= 2,
		.uartclk	= IXP4XX_UART_XTAL,
	},
	{
		.mapbase	= IXP4XX_UART2_BASE_PHYS,
		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
		.irq		= IRQ_IXP4XX_UART2,
		.flags		= UPF_BOOT_AUTOCONF,
		.iotype		= UPIO_MEM,
		.regshift	= 2,
		.uartclk	= IXP4XX_UART_XTAL,
	},
	{ }
};

static struct platform_device nslu2_uart = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev.platform_data	= nslu2_uart_data,
	.num_resources		= 2,
	.resource		= nslu2_uart_resources,
};

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info nslu2_plat_eth[] = {
	{
		.phy		= 1,
		.rxq		= 3,
		.txreadyq	= 20,
	}
};

static struct platform_device nslu2_eth[] = {
	{
		.name			= "ixp4xx_eth",
		.id			= IXP4XX_ETH_NPEB,
		.dev.platform_data	= nslu2_plat_eth,
	}
};

165
static struct platform_device *nslu2_devices[] __initdata = {
M
Michael-Luke Jones 已提交
166
	&nslu2_i2c_gpio,
167
	&nslu2_flash,
168
	&nslu2_beeper,
169
	&nslu2_leds,
170
	&nslu2_eth[0],
171 172 173 174 175 176 177 178 179 180 181 182 183
};

static void nslu2_power_off(void)
{
	/* This causes the box to drop the power and go dead. */

	/* enable the pwr cntl gpio */
	gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);

	/* do the deed */
	gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
}

184
static void __init nslu2_timer_init(void)
185
{
186 187 188 189 190 191
    /* The xtal on this machine is non-standard. */
    ixp4xx_timer_freq = NSLU2_FREQ;

    /* Call standard timer_init function. */
    ixp4xx_timer_init();
}
192

193 194 195 196 197 198
static struct sys_timer nslu2_timer = {
    .init   = nslu2_timer_init,
};

static void __init nslu2_init(void)
{
199 200 201 202
	DECLARE_MAC_BUF(mac_buf);
	uint8_t __iomem *f;
	int i;

203 204
	ixp4xx_sys_init();

205 206 207 208
	nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
	nslu2_flash_resource.end =
		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;

209 210
	pm_power_off = nslu2_power_off;

211 212 213
	i2c_register_board_info(0, nslu2_i2c_board_info,
				ARRAY_SIZE(nslu2_i2c_board_info));

214 215
	/*
	 * This is only useful on a modified machine, but it is valuable
216 217 218 219 220
	 * to have it first in order to see debug messages, and so that
	 * it does *not* get removed if platform_add_devices fails!
	 */
	(void)platform_device_register(&nslu2_uart);

221
	platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241


	/*
	 * Map in a portion of the flash and read the MAC address.
	 * Since it is stored in BE in the flash itself, we need to
	 * byteswap it if we're in LE mode.
	 */
	f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x40000);
	if (f) {
		for (i = 0; i < 6; i++)
#ifdef __ARMEB__
			nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + i);
#else
			nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + (i^3));
#endif
		iounmap(f);
	}
	printk(KERN_INFO "NSLU2: Using MAC address %s for port 0\n",
	       print_mac(mac_buf, nslu2_plat_eth[0].hwaddr));

242 243 244 245 246 247 248 249 250
}

MACHINE_START(NSLU2, "Linksys NSLU2")
	/* Maintainer: www.nslu2-linux.org */
	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
	.boot_params	= 0x00000100,
	.map_io		= ixp4xx_map_io,
	.init_irq	= ixp4xx_init_irq,
251
	.timer          = &nslu2_timer,
252 253
	.init_machine	= nslu2_init,
MACHINE_END