spitz.c 25.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Support for Sharp SL-Cxx00 Series of PDAs
 * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi)
 *
 * Copyright (c) 2005 Richard Purdie
 *
 * Based on Sharp's 2.4 kernel patches/lubbock.c
 *
 * 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.
 *
 */

#include <linux/kernel.h>
16
#include <linux/platform_device.h>
17
#include <linux/delay.h>
18
#include <linux/gpio_keys.h>
19
#include <linux/gpio.h>
20
#include <linux/leds.h>
21
#include <linux/i2c.h>
22
#include <linux/i2c/pxa-i2c.h>
23
#include <linux/platform_data/pca953x.h>
24 25 26
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
27
#include <linux/spi/pxa2xx_spi.h>
28
#include <linux/mtd/sharpsl.h>
29
#include <linux/mtd/physmap.h>
30
#include <linux/input/matrix_keypad.h>
Marek Vasut's avatar
Marek Vasut committed
31
#include <linux/regulator/machine.h>
32
#include <linux/io.h>
33
#include <linux/module.h>
34
#include <linux/reboot.h>
Laura Abbott's avatar
Laura Abbott committed
35
#include <linux/memblock.h>
36 37 38 39

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
40 41 42
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>

43
#include <mach/pxa27x.h>
44
#include <mach/pxa27x-udc.h>
45
#include <mach/reset.h>
46 47 48 49
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/video-pxafb.h>
50
#include <mach/spitz.h>
51
#include <mach/sharpsl_pm.h>
52
#include <mach/smemc.h>
53 54

#include "generic.h"
55
#include "devices.h"
56

Marek Vasut's avatar
Marek Vasut committed
57 58 59
/******************************************************************************
 * Pin configuration
 ******************************************************************************/
60 61 62
static unsigned long spitz_pin_config[] __initdata = {
	/* Chip Selects */
	GPIO78_nCS_2,	/* SCOOP #2 */
63
	GPIO79_nCS_3,	/* NAND */
64 65 66
	GPIO80_nCS_4,	/* SCOOP #1 */

	/* LCD - 16bpp Active TFT */
67
	GPIOxx_LCD_TFT_16BPP,
68 69 70 71 72 73 74 75 76 77 78

	/* PC Card */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO85_nPCE_1,
	GPIO54_nPCE_2,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,
79
	GPIO104_PSKTSEL,
80

81 82 83 84 85 86
	/* I2S */
	GPIO28_I2S_BITCLK_OUT,
	GPIO29_I2S_SDATA_IN,
	GPIO30_I2S_SDATA_OUT,
	GPIO31_I2S_SYNC,

87 88 89 90 91 92 93 94 95 96
	/* MMC */
	GPIO32_MMC_CLK,
	GPIO112_MMC_CMD,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,

	/* GPIOs */
	GPIO9_GPIO,	/* SPITZ_GPIO_nSD_DETECT */
97
	GPIO16_GPIO,	/* SPITZ_GPIO_SYNC */
98 99 100 101 102 103 104 105 106
	GPIO81_GPIO,	/* SPITZ_GPIO_nSD_WP */
	GPIO41_GPIO,	/* SPITZ_GPIO_USB_CONNECT */
	GPIO37_GPIO,	/* SPITZ_GPIO_USB_HOST */
	GPIO35_GPIO,	/* SPITZ_GPIO_USB_DEVICE */
	GPIO22_GPIO,	/* SPITZ_GPIO_HSYNC */
	GPIO94_GPIO,	/* SPITZ_GPIO_CF_CD */
	GPIO105_GPIO,	/* SPITZ_GPIO_CF_IRQ */
	GPIO106_GPIO,	/* SPITZ_GPIO_CF2_IRQ */

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
	/* GPIO matrix keypad */
	GPIO88_GPIO,	/* column 0 */
	GPIO23_GPIO,	/* column 1 */
	GPIO24_GPIO,	/* column 2 */
	GPIO25_GPIO,	/* column 3 */
	GPIO26_GPIO,	/* column 4 */
	GPIO27_GPIO,	/* column 5 */
	GPIO52_GPIO,	/* column 6 */
	GPIO103_GPIO,	/* column 7 */
	GPIO107_GPIO,	/* column 8 */
	GPIO108_GPIO,	/* column 9 */
	GPIO114_GPIO,	/* column 10 */
	GPIO12_GPIO,	/* row 0 */
	GPIO17_GPIO,	/* row 1 */
	GPIO91_GPIO,	/* row 2 */
	GPIO34_GPIO,	/* row 3 */
	GPIO36_GPIO,	/* row 4 */
	GPIO38_GPIO,	/* row 5 */
	GPIO39_GPIO,	/* row 6 */

127 128 129 130
	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

131 132
	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,	/* SPITZ_GPIO_KEY_INT */
	GPIO1_GPIO | WAKEUP_ON_EDGE_FALL,	/* SPITZ_GPIO_RESET */
133 134
};

Marek Vasut's avatar
Marek Vasut committed
135 136 137 138 139

/******************************************************************************
 * Scoop GPIO expander
 ******************************************************************************/
#if defined(CONFIG_SHARP_SCOOP) || defined(CONFIG_SHARP_SCOOP_MODULE)
140 141
/* SCOOP Device #1 */
static struct resource spitz_scoop_1_resources[] = {
142 143 144 145 146 147 148
	[0] = {
		.start		= 0x10800000,
		.end		= 0x10800fff,
		.flags		= IORESOURCE_MEM,
	},
};

149
static struct scoop_config spitz_scoop_1_setup = {
150
	.io_dir		= SPITZ_SCP_IO_DIR,
151
	.io_out		= SPITZ_SCP_IO_OUT,
152 153 154
	.suspend_clr	= SPITZ_SCP_SUS_CLR,
	.suspend_set	= SPITZ_SCP_SUS_SET,
	.gpio_base	= SPITZ_SCP_GPIO_BASE,
155 156
};

157
struct platform_device spitz_scoop_1_device = {
158 159 160
	.name		= "sharp-scoop",
	.id		= 0,
	.dev		= {
161
		.platform_data	= &spitz_scoop_1_setup,
162
	},
163 164
	.num_resources	= ARRAY_SIZE(spitz_scoop_1_resources),
	.resource	= spitz_scoop_1_resources,
165 166
};

167 168
/* SCOOP Device #2 */
static struct resource spitz_scoop_2_resources[] = {
169 170 171 172 173 174 175
	[0] = {
		.start		= 0x08800040,
		.end		= 0x08800fff,
		.flags		= IORESOURCE_MEM,
	},
};

176
static struct scoop_config spitz_scoop_2_setup = {
177
	.io_dir		= SPITZ_SCP2_IO_DIR,
178
	.io_out		= SPITZ_SCP2_IO_OUT,
179 180 181
	.suspend_clr	= SPITZ_SCP2_SUS_CLR,
	.suspend_set	= SPITZ_SCP2_SUS_SET,
	.gpio_base	= SPITZ_SCP2_GPIO_BASE,
182 183
};

184
struct platform_device spitz_scoop_2_device = {
185 186 187
	.name		= "sharp-scoop",
	.id		= 1,
	.dev		= {
188
		.platform_data	= &spitz_scoop_2_setup,
189
	},
190 191
	.num_resources	= ARRAY_SIZE(spitz_scoop_2_resources),
	.resource	= spitz_scoop_2_resources,
192 193
};

Marek Vasut's avatar
Marek Vasut committed
194 195
static void __init spitz_scoop_init(void)
{
196
	platform_device_register(&spitz_scoop_1_device);
Marek Vasut's avatar
Marek Vasut committed
197 198 199

	/* Akita doesn't have the second SCOOP chip */
	if (!machine_is_akita())
200
		platform_device_register(&spitz_scoop_2_device);
Marek Vasut's avatar
Marek Vasut committed
201
}
202 203

/* Power control is shared with between one of the CF slots and SD */
Marek Vasut's avatar
Marek Vasut committed
204
static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr)
205
{
Marek Vasut's avatar
Marek Vasut committed
206 207
	unsigned short cpr;
	unsigned long flags;
208

Marek Vasut's avatar
Marek Vasut committed
209
	if (new_cpr & 0x7) {
210
		gpio_set_value(SPITZ_GPIO_CF_POWER, 1);
Marek Vasut's avatar
Marek Vasut committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
		mdelay(5);
	}

	local_irq_save(flags);

	cpr = read_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR);

	if (enable & new_cpr)
		cpr |= new_cpr;
	else
		cpr &= ~enable;

	write_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR, cpr);

	local_irq_restore(flags);

	if (!(cpr & 0x7)) {
		mdelay(1);
		gpio_set_value(SPITZ_GPIO_CF_POWER, 0);
230 231 232
	}
}

Marek Vasut's avatar
Marek Vasut committed
233 234 235 236 237 238 239 240 241 242
#else
static inline void spitz_scoop_init(void) {}
static inline void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) {}
#endif

/******************************************************************************
 * PCMCIA
 ******************************************************************************/
#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
static void spitz_pcmcia_pwr(struct device *scoop, uint16_t cpr, int nr)
243 244 245
{
	/* Only need to override behaviour for slot 0 */
	if (nr == 0)
Marek Vasut's avatar
Marek Vasut committed
246 247
		spitz_card_pwr_ctrl(
			cpr & (SCOOP_CPR_CF_3V | SCOOP_CPR_CF_XV), cpr);
248 249 250 251
	else
		write_scoop_reg(scoop, SCOOP_CPR, cpr);
}

252
static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
253 254 255 256 257 258 259 260 261 262
	{
		.dev		= &spitz_scoop_1_device.dev,
		.irq		= SPITZ_IRQ_GPIO_CF_IRQ,
		.cd_irq		= SPITZ_IRQ_GPIO_CF_CD,
		.cd_irq_str	= "PCMCIA0 CD",
	}, {
		.dev		= &spitz_scoop_2_device.dev,
		.irq		= SPITZ_IRQ_GPIO_CF2_IRQ,
		.cd_irq		= -1,
	},
263 264
};

265
static struct scoop_pcmcia_config spitz_pcmcia_config = {
266 267 268
	.devs		= &spitz_pcmcia_scoop[0],
	.num_devs	= 2,
	.power_ctrl	= spitz_pcmcia_pwr,
269 270
};

Marek Vasut's avatar
Marek Vasut committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
static void __init spitz_pcmcia_init(void)
{
	/* Akita has only one PCMCIA slot used */
	if (machine_is_akita())
		spitz_pcmcia_config.num_devs = 1;

	platform_scoop_config = &spitz_pcmcia_config;
}
#else
static inline void spitz_pcmcia_init(void) {}
#endif

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
287

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
#define SPITZ_KEY_CALENDAR	KEY_F1
#define SPITZ_KEY_ADDRESS	KEY_F2
#define SPITZ_KEY_FN		KEY_F3
#define SPITZ_KEY_CANCEL	KEY_F4
#define SPITZ_KEY_EXOK		KEY_F5
#define SPITZ_KEY_EXCANCEL	KEY_F6
#define SPITZ_KEY_EXJOGDOWN	KEY_F7
#define SPITZ_KEY_EXJOGUP	KEY_F8
#define SPITZ_KEY_JAP1		KEY_LEFTALT
#define SPITZ_KEY_JAP2		KEY_RIGHTCTRL
#define SPITZ_KEY_SYNC		KEY_F9
#define SPITZ_KEY_MAIL		KEY_F10
#define SPITZ_KEY_OK		KEY_F11
#define SPITZ_KEY_MENU		KEY_F12

303
static const uint32_t spitz_keymap[] = {
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
	KEY(0, 0, KEY_LEFTCTRL),
	KEY(0, 1, KEY_1),
	KEY(0, 2, KEY_3),
	KEY(0, 3, KEY_5),
	KEY(0, 4, KEY_6),
	KEY(0, 5, KEY_7),
	KEY(0, 6, KEY_9),
	KEY(0, 7, KEY_0),
	KEY(0, 8, KEY_BACKSPACE),
	KEY(0, 9, SPITZ_KEY_EXOK),	/* EXOK */
	KEY(0, 10, SPITZ_KEY_EXCANCEL),	/* EXCANCEL */
	KEY(1, 1, KEY_2),
	KEY(1, 2, KEY_4),
	KEY(1, 3, KEY_R),
	KEY(1, 4, KEY_Y),
	KEY(1, 5, KEY_8),
	KEY(1, 6, KEY_I),
	KEY(1, 7, KEY_O),
	KEY(1, 8, KEY_P),
	KEY(1, 9, SPITZ_KEY_EXJOGDOWN),	/* EXJOGDOWN */
	KEY(1, 10, SPITZ_KEY_EXJOGUP),	/* EXJOGUP */
	KEY(2, 0, KEY_TAB),
	KEY(2, 1, KEY_Q),
	KEY(2, 2, KEY_E),
	KEY(2, 3, KEY_T),
	KEY(2, 4, KEY_G),
	KEY(2, 5, KEY_U),
	KEY(2, 6, KEY_J),
	KEY(2, 7, KEY_K),
	KEY(3, 0, SPITZ_KEY_ADDRESS),	/* ADDRESS */
	KEY(3, 1, KEY_W),
	KEY(3, 2, KEY_S),
	KEY(3, 3, KEY_F),
	KEY(3, 4, KEY_V),
	KEY(3, 5, KEY_H),
	KEY(3, 6, KEY_M),
	KEY(3, 7, KEY_L),
	KEY(3, 9, KEY_RIGHTSHIFT),
	KEY(4, 0, SPITZ_KEY_CALENDAR),	/* CALENDAR */
	KEY(4, 1, KEY_A),
	KEY(4, 2, KEY_D),
	KEY(4, 3, KEY_C),
	KEY(4, 4, KEY_B),
	KEY(4, 5, KEY_N),
	KEY(4, 6, KEY_DOT),
	KEY(4, 8, KEY_ENTER),
	KEY(4, 9, KEY_LEFTSHIFT),
	KEY(5, 0, SPITZ_KEY_MAIL),	/* MAIL */
	KEY(5, 1, KEY_Z),
	KEY(5, 2, KEY_X),
	KEY(5, 3, KEY_MINUS),
	KEY(5, 4, KEY_SPACE),
	KEY(5, 5, KEY_COMMA),
	KEY(5, 7, KEY_UP),
	KEY(5, 10, SPITZ_KEY_FN),	/* FN */
	KEY(6, 0, KEY_SYSRQ),
	KEY(6, 1, SPITZ_KEY_JAP1),	/* JAP1 */
	KEY(6, 2, SPITZ_KEY_JAP2),	/* JAP2 */
	KEY(6, 3, SPITZ_KEY_CANCEL),	/* CANCEL */
	KEY(6, 4, SPITZ_KEY_OK),	/* OK */
	KEY(6, 5, SPITZ_KEY_MENU),	/* MENU */
	KEY(6, 6, KEY_LEFT),
	KEY(6, 7, KEY_DOWN),
	KEY(6, 8, KEY_RIGHT),
};

370 371 372
static const struct matrix_keymap_data spitz_keymap_data = {
	.keymap		= spitz_keymap,
	.keymap_size	= ARRAY_SIZE(spitz_keymap),
373 374
};

375
static const uint32_t spitz_row_gpios[] =
376
		{ 12, 17, 91, 34, 36, 38, 39 };
377
static const uint32_t spitz_col_gpios[] =
378 379
		{ 88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114 };

380 381 382 383 384 385
static struct matrix_keypad_platform_data spitz_mkp_pdata = {
	.keymap_data		= &spitz_keymap_data,
	.row_gpios		= spitz_row_gpios,
	.col_gpios		= spitz_col_gpios,
	.num_row_gpios		= ARRAY_SIZE(spitz_row_gpios),
	.num_col_gpios		= ARRAY_SIZE(spitz_col_gpios),
386 387 388 389 390
	.col_scan_delay_us	= 10,
	.debounce_ms		= 10,
	.wakeup			= 1,
};

391
static struct platform_device spitz_mkp_device = {
392
	.name		= "matrix-keypad",
393
	.id		= -1,
394
	.dev		= {
395
		.platform_data	= &spitz_mkp_pdata,
396
	},
397 398
};

Marek Vasut's avatar
Marek Vasut committed
399 400
static void __init spitz_mkp_init(void)
{
401
	platform_device_register(&spitz_mkp_device);
Marek Vasut's avatar
Marek Vasut committed
402 403 404 405
}
#else
static inline void spitz_mkp_init(void) {}
#endif
406

Marek Vasut's avatar
Marek Vasut committed
407 408 409 410
/******************************************************************************
 * GPIO keys
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
411 412 413 414 415
static struct gpio_keys_button spitz_gpio_keys[] = {
	{
		.type	= EV_PWR,
		.code	= KEY_SUSPEND,
		.gpio	= SPITZ_GPIO_ON_KEY,
416
		.desc	= "On Off",
417 418 419 420 421 422 423
		.wakeup	= 1,
	},
	/* Two buttons detecting the lid state */
	{
		.type	= EV_SW,
		.code	= 0,
		.gpio	= SPITZ_GPIO_SWA,
424
		.desc	= "Display Down",
425 426 427 428 429
	},
	{
		.type	= EV_SW,
		.code	= 1,
		.gpio	= SPITZ_GPIO_SWB,
430
		.desc	= "Lid Closed",
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
	},
};

static struct gpio_keys_platform_data spitz_gpio_keys_platform_data = {
	.buttons	= spitz_gpio_keys,
	.nbuttons	= ARRAY_SIZE(spitz_gpio_keys),
};

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

Marek Vasut's avatar
Marek Vasut committed
447 448 449 450 451 452 453
static void __init spitz_keys_init(void)
{
	platform_device_register(&spitz_gpio_keys_device);
}
#else
static inline void spitz_keys_init(void) {}
#endif
454

Marek Vasut's avatar
Marek Vasut committed
455 456 457 458
/******************************************************************************
 * LEDs
 ******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
459 460 461 462 463 464 465 466 467 468
static struct gpio_led spitz_gpio_leds[] = {
	{
		.name			= "spitz:amber:charge",
		.default_trigger	= "sharpsl-charge",
		.gpio			= SPITZ_GPIO_LED_ORANGE,
	},
	{
		.name			= "spitz:green:hddactivity",
		.default_trigger	= "ide-disk",
		.gpio			= SPITZ_GPIO_LED_GREEN,
469 470 471
	},
};

472 473 474
static struct gpio_led_platform_data spitz_gpio_leds_info = {
	.leds		= spitz_gpio_leds,
	.num_leds	= ARRAY_SIZE(spitz_gpio_leds),
475 476
};

477
static struct platform_device spitz_led_device = {
478
	.name		= "leds-gpio",
479
	.id		= -1,
480
	.dev		= {
481
		.platform_data	= &spitz_gpio_leds_info,
482
	},
483 484
};

Marek Vasut's avatar
Marek Vasut committed
485 486
static void __init spitz_leds_init(void)
{
487
	platform_device_register(&spitz_led_device);
Marek Vasut's avatar
Marek Vasut committed
488 489 490 491
}
#else
static inline void spitz_leds_init(void) {}
#endif
492

Marek Vasut's avatar
Marek Vasut committed
493 494 495 496
/******************************************************************************
 * SSP Devices
 ******************************************************************************/
#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
497
static void spitz_ads7846_wait_for_hsync(void)
498 499 500 501 502 503 504 505
{
	while (gpio_get_value(SPITZ_GPIO_HSYNC))
		cpu_relax();

	while (!gpio_get_value(SPITZ_GPIO_HSYNC))
		cpu_relax();
}

506 507 508 509 510
static struct ads7846_platform_data spitz_ads7846_info = {
	.model			= 7846,
	.vref_delay_usecs	= 100,
	.x_plate_ohms		= 419,
	.y_plate_ohms		= 486,
511
	.pressure_max		= 1024,
512
	.gpio_pendown		= SPITZ_GPIO_TP_INT,
513
	.wait_for_sync		= spitz_ads7846_wait_for_hsync,
514
};
515

516
static struct pxa2xx_spi_chip spitz_ads7846_chip = {
517
	.gpio_cs		= SPITZ_GPIO_ADS7846_CS,
518
};
519

520
static void spitz_bl_kick_battery(void)
521
{
522
	void (*kick_batt)(void);
523

524 525 526 527
	kick_batt = symbol_get(sharpsl_battery_kick);
	if (kick_batt) {
		kick_batt();
		symbol_put(sharpsl_battery_kick);
528 529 530
	}
}

531 532 533 534 535
static struct corgi_lcd_platform_data spitz_lcdcon_info = {
	.init_mode		= CORGI_LCD_MODE_VGA,
	.max_intensity		= 0x2f,
	.default_intensity	= 0x1f,
	.limit_mask		= 0x0b,
536 537
	.gpio_backlight_cont	= SPITZ_GPIO_BACKLIGHT_CONT,
	.gpio_backlight_on	= SPITZ_GPIO_BACKLIGHT_ON,
538 539
	.kick_battery		= spitz_bl_kick_battery,
};
540

541
static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
542
	.gpio_cs	= SPITZ_GPIO_LCDCON_CS,
543 544
};

545
static struct pxa2xx_spi_chip spitz_max1111_chip = {
546
	.gpio_cs	= SPITZ_GPIO_MAX1111_CS,
547 548
};

549 550
static struct spi_board_info spitz_spi_devices[] = {
	{
551 552 553 554 555 556
		.modalias		= "ads7846",
		.max_speed_hz		= 1200000,
		.bus_num		= 2,
		.chip_select		= 0,
		.platform_data		= &spitz_ads7846_info,
		.controller_data	= &spitz_ads7846_chip,
557
		.irq			= PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
558
	}, {
559 560 561 562 563 564
		.modalias		= "corgi-lcd",
		.max_speed_hz		= 50000,
		.bus_num		= 2,
		.chip_select		= 1,
		.platform_data		= &spitz_lcdcon_info,
		.controller_data	= &spitz_lcdcon_chip,
565
	}, {
566 567 568 569 570
		.modalias		= "max1111",
		.max_speed_hz		= 450000,
		.bus_num		= 2,
		.chip_select		= 2,
		.controller_data	= &spitz_max1111_chip,
571 572 573
	},
};

Marek Vasut's avatar
Marek Vasut committed
574 575 576 577
static struct pxa2xx_spi_master spitz_spi_info = {
	.num_chipselect	= 3,
};

578
static void __init spitz_spi_init(void)
579
{
Marek Vasut's avatar
Marek Vasut committed
580 581
	struct corgi_lcd_platform_data *lcd_data = &spitz_lcdcon_info;

582
	if (machine_is_akita()) {
Marek Vasut's avatar
Marek Vasut committed
583 584
		lcd_data->gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
		lcd_data->gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
585 586
	}

587 588 589 590
	pxa2xx_set_spi_info(2, &spitz_spi_info);
	spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
}
#else
591
static inline void spitz_spi_init(void) {}
592
#endif
593

Marek Vasut's avatar
Marek Vasut committed
594 595 596 597
/******************************************************************************
 * SD/MMC card controller
 ******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
598
/*
Marek Vasut's avatar
Marek Vasut committed
599 600
 * NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to
 * give the card a chance to fully insert/eject.
601
 */
602
static int spitz_mci_setpower(struct device *dev, unsigned int vdd)
603 604 605
{
	struct pxamci_platform_data* p_d = dev->platform_data;

Marek Vasut's avatar
Marek Vasut committed
606 607
	if ((1 << vdd) & p_d->ocr_mask)
		spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V);
608
	else
Marek Vasut's avatar
Marek Vasut committed
609
		spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0);
610 611

	return 0;
612 613 614
}

static struct pxamci_platform_data spitz_mci_platform_data = {
615
	.detect_delay_ms	= 250,
616
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
617
	.setpower		= spitz_mci_setpower,
618 619 620
	.gpio_card_detect	= SPITZ_GPIO_nSD_DETECT,
	.gpio_card_ro		= SPITZ_GPIO_nSD_WP,
	.gpio_power		= -1,
621 622
};

Marek Vasut's avatar
Marek Vasut committed
623 624 625 626 627 628 629
static void __init spitz_mmc_init(void)
{
	pxa_set_mci_info(&spitz_mci_platform_data);
}
#else
static inline void spitz_mmc_init(void) {}
#endif
630

Marek Vasut's avatar
Marek Vasut committed
631 632 633 634
/******************************************************************************
 * USB Host
 ******************************************************************************/
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
635 636
static int spitz_ohci_init(struct device *dev)
{
637
	int err;
638

639 640 641
	err = gpio_request(SPITZ_GPIO_USB_HOST, "USB_HOST");
	if (err)
		return err;
642

Marek Vasut's avatar
Marek Vasut committed
643
	/* Only Port 2 is connected, setup USB Port 2 Output Control Register */
644 645
	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;

646
	return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
647 648
}

649 650 651 652 653
static void spitz_ohci_exit(struct device *dev)
{
	gpio_free(SPITZ_GPIO_USB_HOST);
}

654 655 656
static struct pxaohci_platform_data spitz_ohci_platform_data = {
	.port_mode	= PMM_NPS_MODE,
	.init		= spitz_ohci_init,
657
	.exit		= spitz_ohci_exit,
658
	.flags		= ENABLE_PORT_ALL | NO_OC_PROTECTION,
659
	.power_budget	= 150,
660 661
};

Marek Vasut's avatar
Marek Vasut committed
662 663 664 665 666 667 668
static void __init spitz_uhc_init(void)
{
	pxa_set_ohci_info(&spitz_ohci_platform_data);
}
#else
static inline void spitz_uhc_init(void) {}
#endif
669

Marek Vasut's avatar
Marek Vasut committed
670 671 672 673
/******************************************************************************
 * IrDA
 ******************************************************************************/
#if defined(CONFIG_PXA_FICP) || defined(CONFIG_PXA_FICP_MODULE)
674
static struct pxaficp_platform_data spitz_ficp_platform_data = {
675
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
676 677
};

Marek Vasut's avatar
Marek Vasut committed
678 679 680 681 682 683
static void __init spitz_irda_init(void)
{
	if (machine_is_akita())
		spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON;
	else
		spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
684

Marek Vasut's avatar
Marek Vasut committed
685 686 687 688 689
	pxa_set_ficp_info(&spitz_ficp_platform_data);
}
#else
static inline void spitz_irda_init(void) {}
#endif
690

Marek Vasut's avatar
Marek Vasut committed
691 692 693 694
/******************************************************************************
 * Framebuffer
 ******************************************************************************/
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
695
static struct pxafb_mode_info spitz_pxafb_modes[] = {
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
	{
		.pixclock       = 19231,
		.xres           = 480,
		.yres           = 640,
		.bpp            = 16,
		.hsync_len      = 40,
		.left_margin    = 46,
		.right_margin   = 125,
		.vsync_len      = 3,
		.upper_margin   = 1,
		.lower_margin   = 0,
		.sync           = 0,
	}, {
		.pixclock       = 134617,
		.xres           = 240,
		.yres           = 320,
		.bpp            = 16,
		.hsync_len      = 20,
		.left_margin    = 20,
		.right_margin   = 46,
		.vsync_len      = 2,
		.upper_margin   = 1,
		.lower_margin   = 0,
		.sync           = 0,
	},
721 722 723
};

static struct pxafb_mach_info spitz_pxafb_info = {
Marek Vasut's avatar
Marek Vasut committed
724 725
	.modes          = spitz_pxafb_modes,
	.num_modes      = ARRAY_SIZE(spitz_pxafb_modes),
726
	.fixed_modes    = 1,
727
	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_ALTERNATE_MAPPING,
728 729
};

Marek Vasut's avatar
Marek Vasut committed
730 731
static void __init spitz_lcd_init(void)
{
732
	pxa_set_fb_info(NULL, &spitz_pxafb_info);
Marek Vasut's avatar
Marek Vasut committed
733 734 735 736 737 738
}
#else
static inline void spitz_lcd_init(void) {}
#endif

/******************************************************************************
739
 * NAND Flash
Marek Vasut's avatar
Marek Vasut committed
740 741
 ******************************************************************************/
#if defined(CONFIG_MTD_NAND_SHARPSL) || defined(CONFIG_MTD_NAND_SHARPSL_MODULE)
742
static struct mtd_partition spitz_nand_partitions[] = {
743 744 745 746
	{
		.name = "System Area",
		.offset = 0,
		.size = 7 * 1024 * 1024,
747
	}, {
748 749
		.name = "Root Filesystem",
		.offset = 7 * 1024 * 1024,
750
	}, {
751 752 753 754 755 756 757 758
		.name = "Home Filesystem",
		.offset = MTDPART_OFS_APPEND,
		.size = MTDPART_SIZ_FULL,
	},
};

static uint8_t scan_ff_pattern[] = { 0xff, 0xff };

759 760 761 762 763
static struct nand_bbt_descr spitz_nand_bbt = {
	.options	= 0,
	.offs		= 4,
	.len		= 2,
	.pattern	= scan_ff_pattern
764 765
};

766
static struct nand_ecclayout akita_oobinfo = {
Marek Vasut's avatar
Marek Vasut committed
767 768 769 770 771 772 773
	.oobfree	= { {0x08, 0x09} },
	.eccbytes	= 24,
	.eccpos		= {
			0x05, 0x01, 0x02, 0x03, 0x06, 0x07, 0x15, 0x11,
			0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
			0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37,
	},
774 775
};

776 777 778 779
static struct sharpsl_nand_platform_data spitz_nand_pdata = {
	.badblock_pattern	= &spitz_nand_bbt,
	.partitions		= spitz_nand_partitions,
	.nr_partitions		= ARRAY_SIZE(spitz_nand_partitions),
780 781
};

782
static struct resource spitz_nand_resources[] = {
783
	{
Marek Vasut's avatar
Marek Vasut committed
784 785
		.start	= PXA_CS3_PHYS,
		.end	= PXA_CS3_PHYS + SZ_4K - 1,
786 787 788 789
		.flags	= IORESOURCE_MEM,
	},
};

790
static struct platform_device spitz_nand_device = {
791 792
	.name		= "sharpsl-nand",
	.id		= -1,
793 794
	.resource	= spitz_nand_resources,
	.num_resources	= ARRAY_SIZE(spitz_nand_resources),
Marek Vasut's avatar
Marek Vasut committed
795
	.dev		= {
796
		.platform_data	= &spitz_nand_pdata,
Marek Vasut's avatar
Marek Vasut committed
797
	}
798 799
};

Marek Vasut's avatar
Marek Vasut committed
800 801 802
static void __init spitz_nand_init(void)
{
	if (machine_is_spitz()) {
803
		spitz_nand_partitions[1].size = 5 * 1024 * 1024;
Marek Vasut's avatar
Marek Vasut committed
804
	} else if (machine_is_akita()) {
805 806 807
		spitz_nand_partitions[1].size = 58 * 1024 * 1024;
		spitz_nand_bbt.len = 1;
		spitz_nand_pdata.ecc_layout = &akita_oobinfo;
Marek Vasut's avatar
Marek Vasut committed
808
	} else if (machine_is_borzoi()) {
809 810 811
		spitz_nand_partitions[1].size = 32 * 1024 * 1024;
		spitz_nand_bbt.len = 1;
		spitz_nand_pdata.ecc_layout = &akita_oobinfo;
Marek Vasut's avatar
Marek Vasut committed
812 813
	}

814
	platform_device_register(&spitz_nand_device);
Marek Vasut's avatar
Marek Vasut committed
815 816 817 818
}
#else
static inline void spitz_nand_init(void) {}
#endif
819

Marek Vasut's avatar
Marek Vasut committed
820 821 822 823
/******************************************************************************
 * NOR Flash
 ******************************************************************************/
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
824
static struct mtd_partition spitz_rom_parts[] = {
825 826 827 828 829 830 831
	{
		.name	="Boot PROM Filesystem",
		.offset	= 0x00140000,
		.size	= MTDPART_SIZ_FULL,
	},
};

832
static struct physmap_flash_data spitz_rom_data = {
833
	.width		= 2,
834 835
	.nr_parts	= ARRAY_SIZE(spitz_rom_parts),
	.parts		= spitz_rom_parts,
836 837
};

838
static struct resource spitz_rom_resources[] = {
839
	{
Marek Vasut's avatar
Marek Vasut committed
840 841
		.start	= PXA_CS0_PHYS,
		.end	= PXA_CS0_PHYS + SZ_8M - 1,
842 843 844 845
		.flags	= IORESOURCE_MEM,
	},
};

846 847 848 849 850
static struct platform_device spitz_rom_device = {
	.name		= "physmap-flash",
	.id		= -1,
	.resource	= spitz_rom_resources,
	.num_resources	= ARRAY_SIZE(spitz_rom_resources),
Marek Vasut's avatar
Marek Vasut committed
851
	.dev		= {
852
		.platform_data	= &spitz_rom_data,
Marek Vasut's avatar
Marek Vasut committed
853
	},
854 855
};

Marek Vasut's avatar
Marek Vasut committed
856 857
static void __init spitz_nor_init(void)
{
858
	platform_device_register(&spitz_rom_device);
Marek Vasut's avatar
Marek Vasut committed
859 860 861 862 863 864
}
#else
static inline void spitz_nor_init(void) {}
#endif

/******************************************************************************
865
 * I2C devices
Marek Vasut's avatar
Marek Vasut committed
866 867 868 869
 ******************************************************************************/
#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
static struct pca953x_platform_data akita_pca953x_pdata = {
	.gpio_base		= AKITA_IOEXP_GPIO_BASE,
870 871
};

Marek Vasut's avatar
Marek Vasut committed
872 873 874 875 876 877 878 879 880 881 882 883
static struct i2c_board_info spitz_i2c_devs[] = {
	{
		.type		= "wm8750",
		.addr		= 0x1b,
	}, {
		.type		= "max7310",
		.addr		= 0x18,
		.platform_data	= &akita_pca953x_pdata,
	},
};

static struct regulator_consumer_supply isl6271a_consumers[] = {
884
	REGULATOR_SUPPLY("vcc_core", NULL),
885 886
};

Marek Vasut's avatar
Marek Vasut committed
887 888 889 890 891 892 893 894 895 896 897 898
static struct regulator_init_data isl6271a_info[] = {
	{
		.constraints = {
			.name		= "vcc_core range",
			.min_uV		= 850000,
			.max_uV		= 1600000,
			.always_on	= 1,
			.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
		},
	.consumer_supplies	= isl6271a_consumers,
	.num_consumer_supplies	= ARRAY_SIZE(isl6271a_consumers),
	}
899 900
};

Marek Vasut's avatar
Marek Vasut committed
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
static struct i2c_board_info spitz_pi2c_devs[] = {
	{
		.type		= "isl6271a",
		.addr		= 0x0c,
		.platform_data	= &isl6271a_info,
	},
};

static void __init spitz_i2c_init(void)
{
	int size = ARRAY_SIZE(spitz_i2c_devs);

	/* Only Akita has the max7310 chip */
	if (!machine_is_akita())
		size--;

	pxa_set_i2c_info(NULL);
	pxa27x_set_i2c_power_info(NULL);
	i2c_register_board_info(0, spitz_i2c_devs, size);
	i2c_register_board_info(1, ARRAY_AND_SIZE(spitz_pi2c_devs));
}
#else
static inline void spitz_i2c_init(void) {}
#endif

/******************************************************************************
 * Machine init
 ******************************************************************************/
929 930
static void spitz_poweroff(void)
{
931
	pxa_restart(REBOOT_GPIO, NULL);
932 933
}

934
static void spitz_restart(enum reboot_mode mode, const char *cmd)
935
{
936
	uint32_t msc0 = __raw_readl(MSC0);
937
	/* Bootloader magic for a reboot */
938 939
	if ((msc0 & 0xffff0000) == 0x7ff00000)
		__raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);
940 941 942 943

	spitz_poweroff();
}

Marek Vasut's avatar
Marek Vasut committed
944
static void __init spitz_init(void)
945
{
946
	init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
947 948
	pm_power_off = spitz_poweroff;

949 950 951 952 953
	PMCR = 0x00;

	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
	PCFR |= PCFR_OPDE;

954
	pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config));
955

956 957 958 959
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

960
	spitz_spi_init();
Marek Vasut's avatar
Marek Vasut committed
961 962 963 964 965 966 967 968 969 970 971 972
	spitz_scoop_init();
	spitz_mkp_init();
	spitz_keys_init();
	spitz_leds_init();
	spitz_mmc_init();
	spitz_pcmcia_init();
	spitz_irda_init();
	spitz_uhc_init();
	spitz_lcd_init();
	spitz_nor_init();
	spitz_nand_init();
	spitz_i2c_init();
973 974
}

Laura Abbott's avatar
Laura Abbott committed
975
static void __init spitz_fixup(struct tag *tags, char **cmdline)
976 977
{
	sharpsl_save_param();
Laura Abbott's avatar
Laura Abbott committed
978
	memblock_add(0xa0000000, SZ_64M);
979 980 981 982
}

#ifdef CONFIG_MACH_SPITZ
MACHINE_START(SPITZ, "SHARP Spitz")
983
	.fixup		= spitz_fixup,
984
	.map_io		= pxa27x_map_io,
Rob Herring's avatar
Rob Herring committed
985
	.nr_irqs	= PXA_NR_IRQS,
986
	.init_irq	= pxa27x_init_irq,
987
	.handle_irq	= pxa27x_handle_irq,
988
	.init_machine	= spitz_init,
Stephen Warren's avatar
Stephen Warren committed
989
	.init_time	= pxa_timer_init,
990
	.restart	= spitz_restart,
991 992 993 994 995
MACHINE_END
#endif

#ifdef CONFIG_MACH_BORZOI
MACHINE_START(BORZOI, "SHARP Borzoi")
996
	.fixup		= spitz_fixup,
997
	.map_io		= pxa27x_map_io,
Rob Herring's avatar
Rob Herring committed
998
	.nr_irqs	= PXA_NR_IRQS,
999
	.init_irq	= pxa27x_init_irq