collie.c 10.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * linux/arch/arm/mach-sa1100/collie.c
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 *
 * This file contains all Collie-specific tweaks.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * ChangeLog:
P
Pavel Machek 已提交
14
 *  2006 Pavel Machek <pavel@ucw.cz>
15
 *  03-06-2004 John Lenz <lenz@cs.wisc.edu>
L
Linus Torvalds 已提交
16 17 18 19 20 21 22 23
 *  06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
 *  04-16-2001 Lineo Japan,Inc. ...
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
24
#include <linux/platform_data/sa11x0-serial.h>
25
#include <linux/platform_device.h>
26
#include <linux/mfd/ucb1x00.h>
L
Linus Torvalds 已提交
27 28 29
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/timer.h>
30 31
#include <linux/gpio_keys.h>
#include <linux/input.h>
32
#include <linux/gpio.h>
33
#include <linux/power/gpio-charger.h>
L
Linus Torvalds 已提交
34

35 36
#include <video/sa1100fb.h>

37
#include <mach/hardware.h>
L
Linus Torvalds 已提交
38
#include <asm/mach-types.h>
39
#include <asm/page.h>
L
Linus Torvalds 已提交
40
#include <asm/setup.h>
41
#include <mach/collie.h>
L
Linus Torvalds 已提交
42 43 44 45

#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
46
#include <linux/platform_data/irda-sa11x0.h>
L
Linus Torvalds 已提交
47 48 49 50

#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/locomo.h>
51
#include <linux/platform_data/mfd-mcp-sa11x0.h>
52
#include <mach/irqs.h>
L
Linus Torvalds 已提交
53 54 55 56

#include "generic.h"

static struct resource collie_scoop_resources[] = {
57
	[0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
L
Linus Torvalds 已提交
58 59 60 61 62
};

static struct scoop_config collie_scoop_setup = {
	.io_dir 	= COLLIE_SCOOP_IO_DIR,
	.io_out		= COLLIE_SCOOP_IO_OUT,
63
	.gpio_base	= COLLIE_SCOOP_GPIO_BASE,
L
Linus Torvalds 已提交
64 65 66 67 68 69 70 71 72 73 74 75
};

struct platform_device colliescoop_device = {
	.name		= "sharp-scoop",
	.id		= -1,
	.dev		= {
 		.platform_data	= &collie_scoop_setup,
	},
	.num_resources	= ARRAY_SIZE(collie_scoop_resources),
	.resource	= collie_scoop_resources,
};

76
static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = {
77 78 79 80 81 82
	{
	.dev		= &colliescoop_device.dev,
	.irq		= COLLIE_IRQ_GPIO_CF_IRQ,
	.cd_irq		= COLLIE_IRQ_GPIO_CF_CD,
	.cd_irq_str	= "PCMCIA0 CD",
	},
83 84 85
};

static struct scoop_pcmcia_config collie_pcmcia_config = {
86 87
	.devs		= &collie_pcmcia_scoop[0],
	.num_devs	= 1,
88 89
};

90 91 92 93
static struct ucb1x00_plat_data collie_ucb1x00_data = {
	.gpio_base	= COLLIE_TC35143_GPIO_BASE,
};

94
static struct mcp_plat_data collie_mcp_data = {
95 96
	.mccr0		= MCCR0_ADM | MCCR0_ExtClk,
	.sclk_rate	= 9216000,
97
	.codec_pdata	= &collie_ucb1x00_data,
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
static int collie_ir_startup(struct device *dev)
{
	int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
	if (rc)
		return rc;
	rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);

	if (!rc)
		return 0;

	gpio_free(COLLIE_GPIO_IR_ON);
	return rc;
}

static void collie_ir_shutdown(struct device *dev)
{
	gpio_free(COLLIE_GPIO_IR_ON);
}

static int collie_ir_set_power(struct device *dev, unsigned int state)
{
	gpio_set_value(COLLIE_GPIO_IR_ON, !state);
	return 0;
}

static struct irda_platform_data collie_ir_data = {
	.startup = collie_ir_startup,
	.shutdown = collie_ir_shutdown,
	.set_power = collie_ir_set_power,
};

T
Thomas Kunze 已提交
131 132 133 134 135 136 137 138
/*
 * Collie AC IN
 */
static char *collie_ac_supplied_to[] = {
	"main-battery",
	"backup-battery",
};

139 140 141 142 143

static struct gpio_charger_platform_data collie_power_data = {
	.name			= "charger",
	.type			= POWER_SUPPLY_TYPE_MAINS,
	.gpio			= COLLIE_GPIO_AC_IN,
T
Thomas Kunze 已提交
144 145 146 147 148
	.supplied_to		= collie_ac_supplied_to,
	.num_supplicants	= ARRAY_SIZE(collie_ac_supplied_to),
};

static struct platform_device collie_power_device = {
149
	.name			= "gpio-charger",
T
Thomas Kunze 已提交
150 151
	.id			= -1,
	.dev.platform_data	= &collie_power_data,
152 153
};

154 155 156 157
#ifdef CONFIG_SHARP_LOCOMO
/*
 * low-level UART features.
 */
158
struct platform_device collie_locomo_device;
159 160 161

static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
{
162
	if (mctrl & TIOCM_RTS)
163
		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
164
	else
165
		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
166

167
	if (mctrl & TIOCM_DTR)
168
		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
169
	else
170
		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
171 172 173 174 175 176 177
}

static u_int collie_uart_get_mctrl(struct uart_port *port)
{
	int ret = TIOCM_CD;
	unsigned int r;

178 179 180
	r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
	if (r == -ENODEV)
		return ret;
181 182 183 184 185 186 187
	if (r & LOCOMO_GPIO_CTS)
		ret |= TIOCM_CTS;
	if (r & LOCOMO_GPIO_DSR)
		ret |= TIOCM_DSR;

	return ret;
}
188 189 190 191 192 193

static struct sa1100_port_fns collie_port_fns __initdata = {
	.set_mctrl	= collie_uart_set_mctrl,
	.get_mctrl	= collie_uart_get_mctrl,
};

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
static int collie_uart_probe(struct locomo_dev *dev)
{
	return 0;
}

static int collie_uart_remove(struct locomo_dev *dev)
{
	return 0;
}

static struct locomo_driver collie_uart_driver = {
	.drv = {
		.name = "collie_uart",
	},
	.devid	= LOCOMO_DEVID_UART,
	.probe	= collie_uart_probe,
	.remove	= collie_uart_remove,
};

213 214
static int __init collie_uart_init(void)
{
215 216 217 218 219 220
	return locomo_driver_register(&collie_uart_driver);
}
device_initcall(collie_uart_init);

#endif

L
Linus Torvalds 已提交
221 222

static struct resource locomo_resources[] = {
223 224
	[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
	[1] = DEFINE_RES_IRQ(IRQ_GPIO25),
L
Linus Torvalds 已提交
225 226
};

227 228 229 230
static struct locomo_platform_data locomo_info = {
	.irq_base	= IRQ_BOARD_START,
};

231
struct platform_device collie_locomo_device = {
L
Linus Torvalds 已提交
232 233
	.name		= "locomo",
	.id		= 0,
234 235 236
	.dev		= {
		.platform_data	= &locomo_info,
	},
L
Linus Torvalds 已提交
237 238 239 240
	.num_resources	= ARRAY_SIZE(locomo_resources),
	.resource	= locomo_resources,
};

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
static struct gpio_keys_button collie_gpio_keys[] = {
	{
		.type	= EV_PWR,
		.code	= KEY_RESERVED,
		.gpio	= COLLIE_GPIO_ON_KEY,
		.desc	= "On key",
		.wakeup	= 1,
		.active_low = 1,
	},
	{
		.type	= EV_PWR,
		.code	= KEY_WAKEUP,
		.gpio	= COLLIE_GPIO_WAKEUP,
		.desc	= "Sync",
		.wakeup = 1,
		.active_low = 1,
	},
};

static struct gpio_keys_platform_data collie_gpio_keys_data = {
	.buttons	= collie_gpio_keys,
	.nbuttons	= ARRAY_SIZE(collie_gpio_keys),
};

static struct platform_device collie_gpio_keys_device = {
	.name	= "gpio-keys",
	.id	= -1,
	.dev	= {
		.platform_data = &collie_gpio_keys_data,
	},
};

L
Linus Torvalds 已提交
273
static struct platform_device *devices[] __initdata = {
274
	&collie_locomo_device,
L
Linus Torvalds 已提交
275
	&colliescoop_device,
T
Thomas Kunze 已提交
276
	&collie_power_device,
277
	&collie_gpio_keys_device,
L
Linus Torvalds 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
};

static struct mtd_partition collie_partitions[] = {
	{
		.name		= "bootloader",
		.offset 	= 0,
		.size		= 0x000C0000,
		.mask_flags	= MTD_WRITEABLE
	}, {
		.name		= "kernel",
		.offset 	= MTDPART_OFS_APPEND,
		.size		= 0x00100000,
	}, {
		.name		= "rootfs",
		.offset 	= MTDPART_OFS_APPEND,
		.size		= 0x00e20000,
294 295 296 297 298
	}, {
		.name		= "bootblock",
		.offset		= MTDPART_OFS_APPEND,
		.size		= 0x00020000,
		.mask_flags	= MTD_WRITEABLE
L
Linus Torvalds 已提交
299 300 301
	}
};

302 303
static int collie_flash_init(void)
{
304
	int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
305 306 307 308 309 310 311 312 313 314
	if (rc)
		return rc;

	rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
	if (rc)
		gpio_free(COLLIE_GPIO_VPEN);

	return rc;
}

L
Linus Torvalds 已提交
315 316
static void collie_set_vpp(int vpp)
{
317
	gpio_set_value(COLLIE_GPIO_VPEN, vpp);
L
Linus Torvalds 已提交
318 319
}

320 321 322 323
static void collie_flash_exit(void)
{
	gpio_free(COLLIE_GPIO_VPEN);
}
324

L
Linus Torvalds 已提交
325
static struct flash_platform_data collie_flash_data = {
326
	.map_name	= "cfi_probe",
327
	.init		= collie_flash_init,
L
Linus Torvalds 已提交
328
	.set_vpp	= collie_set_vpp,
329
	.exit		= collie_flash_exit,
L
Linus Torvalds 已提交
330 331 332 333 334
	.parts		= collie_partitions,
	.nr_parts	= ARRAY_SIZE(collie_partitions),
};

static struct resource collie_flash_resources[] = {
335
	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
L
Linus Torvalds 已提交
336 337
};

338 339 340 341 342 343 344 345 346 347 348 349
static struct sa1100fb_mach_info collie_lcd_info = {
	.pixclock	= 171521,	.bpp		= 16,
	.xres		= 320,		.yres		= 240,

	.hsync_len	= 5,		.vsync_len	= 1,
	.left_margin	= 11,		.upper_margin	= 2,
	.right_margin	= 30,		.lower_margin	= 0,

	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,

	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
350 351 352 353

#ifdef CONFIG_BACKLIGHT_LOCOMO
	.lcd_power	= locomolcd_power
#endif
354 355
};

L
Linus Torvalds 已提交
356 357 358 359 360
static void __init collie_init(void)
{
	int ret = 0;

	/* cpu initialize */
361 362 363 364 365 366
	GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
		GPIO_MCP_CLK | GPIO_32_768kHz;

	GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
		GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
		GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
T
Thomas Kunze 已提交
367 368
		_COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
		_COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
369 370 371 372 373

	PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
		PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
		PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;

T
Thomas Kunze 已提交
374 375
	PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY |
		_COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
376

T
Thomas Kunze 已提交
377
	PGSR = _COLLIE_GPIO_nREMOCON_ON;
378 379 380 381 382

	PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;

	PCFR = PCFR_OPDE;

T
Thomas Kunze 已提交
383 384
	GPSR |= _COLLIE_GPIO_UCB1x00_RESET;

385 386
	sa11x0_ppc_configure_mcp();

L
Linus Torvalds 已提交
387

388 389
	platform_scoop_config = &collie_pcmcia_config;

L
Linus Torvalds 已提交
390 391 392 393 394
	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	if (ret) {
		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
	}

395
	sa11x0_register_lcd(&collie_lcd_info);
396 397 398
	sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
			    ARRAY_SIZE(collie_flash_resources));
	sa11x0_register_mcp(&collie_mcp_data);
399
	sa11x0_register_irda(&collie_ir_data);
L
Linus Torvalds 已提交
400 401 402 403 404

	sharpsl_save_param();
}

static struct map_desc collie_io_desc[] __initdata = {
405 406 407 408 409 410 411 412 413 414 415
	{	/* 32M main flash (cs0) */
		.virtual	= 0xe8000000,
		.pfn		= __phys_to_pfn(0x00000000),
		.length		= 0x02000000,
		.type		= MT_DEVICE
	}, {	/* 32M boot flash (cs1) */
		.virtual	= 0xea000000,
		.pfn		= __phys_to_pfn(0x08000000),
		.length		= 0x02000000,
		.type		= MT_DEVICE
	}
L
Linus Torvalds 已提交
416 417 418 419 420 421
};

static void __init collie_map_io(void)
{
	sa1100_map_io();
	iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
422 423 424 425 426 427

#ifdef CONFIG_SHARP_LOCOMO
	sa1100_register_uart_fns(&collie_port_fns);
#endif
	sa1100_register_uart(0, 3);
	sa1100_register_uart(1, 1);
L
Linus Torvalds 已提交
428 429 430
}

MACHINE_START(COLLIE, "Sharp-Collie")
431
	.map_io		= collie_map_io,
432
	.nr_irqs	= SA1100_NR_IRQS,
433
	.init_irq	= sa1100_init_irq,
S
Stephen Warren 已提交
434
	.init_time	= sa1100_timer_init,
L
Linus Torvalds 已提交
435
	.init_machine	= collie_init,
436
	.init_late	= sa11x0_init_late,
437
	.restart	= sa11x0_restart,
L
Linus Torvalds 已提交
438
MACHINE_END