1/* 2 * Support for Sharp SL-C6000x PDAs 3 * Model: (Tosa) 4 * 5 * Copyright (c) 2005 Dirk Opfer 6 * 7 * Based on code written by Sharp/Lineo for 2.4 kernels 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/major.h> 19#include <linux/fs.h> 20#include <linux/interrupt.h> 21#include <linux/delay.h> 22#include <linux/fb.h> 23#include <linux/mmc/host.h> 24#include <linux/mfd/tc6393xb.h> 25#include <linux/mfd/tmio.h> 26#include <linux/mtd/nand.h> 27#include <linux/mtd/partitions.h> 28#include <linux/mtd/physmap.h> 29#include <linux/pm.h> 30#include <linux/gpio_keys.h> 31#include <linux/input.h> 32#include <linux/gpio.h> 33#include <linux/power/gpio-charger.h> 34#include <linux/spi/spi.h> 35#include <linux/spi/pxa2xx_spi.h> 36#include <linux/input/matrix_keypad.h> 37#include <linux/i2c/pxa-i2c.h> 38#include <linux/usb/gpio_vbus.h> 39#include <linux/reboot.h> 40#include <linux/memblock.h> 41 42#include <asm/setup.h> 43#include <asm/mach-types.h> 44 45#include <mach/pxa25x.h> 46#include <mach/reset.h> 47#include <linux/platform_data/irda-pxaficp.h> 48#include <linux/platform_data/mmc-pxamci.h> 49#include <mach/udc.h> 50#include <mach/tosa_bt.h> 51#include <mach/audio.h> 52#include <mach/smemc.h> 53 54#include <asm/mach/arch.h> 55#include <mach/tosa.h> 56 57#include <asm/hardware/scoop.h> 58#include <asm/mach/sharpsl_param.h> 59 60#include "generic.h" 61#include "clock.h" 62#include "devices.h" 63 64static unsigned long tosa_pin_config[] = { 65 GPIO78_nCS_2, /* Scoop */ 66 GPIO80_nCS_4, /* tg6393xb */ 67 GPIO33_nCS_5, /* Scoop */ 68 69 // GPIO76 CARD_VCC_ON1 70 71 GPIO19_GPIO, /* Reset out */ 72 GPIO1_RST | WAKEUP_ON_EDGE_FALL, 73 74 GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */ 75 GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */ 76 GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */ 77 GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */ 78 GPIO20_GPIO, /* EAR_IN */ 79 GPIO22_GPIO, /* On */ 80 81 GPIO5_GPIO, /* USB_IN */ 82 GPIO32_GPIO, /* Pen IRQ */ 83 84 GPIO7_GPIO, /* Jacket Detect */ 85 GPIO14_GPIO, /* BAT0_CRG */ 86 GPIO12_GPIO, /* BAT1_CRG */ 87 GPIO17_GPIO, /* BAT0_LOW */ 88 GPIO84_GPIO, /* BAT1_LOW */ 89 GPIO38_GPIO, /* BAT_LOCK */ 90 91 GPIO11_3_6MHz, 92 GPIO15_GPIO, /* TC6393XB IRQ */ 93 GPIO18_RDY, 94 GPIO27_GPIO, /* LCD Sync */ 95 96 /* MMC */ 97 GPIO6_MMC_CLK, 98 GPIO8_MMC_CS0, 99 GPIO9_GPIO, /* Detect */ 100 GPIO10_GPIO, /* nSD_INT */ 101 102 /* CF */ 103 GPIO13_GPIO, /* CD_IRQ */ 104 GPIO21_GPIO, /* Main Slot IRQ */ 105 GPIO36_GPIO, /* Jacket Slot IRQ */ 106 GPIO48_nPOE, 107 GPIO49_nPWE, 108 GPIO50_nPIOR, 109 GPIO51_nPIOW, 110 GPIO52_nPCE_1, 111 GPIO53_nPCE_2, 112 GPIO54_nPSKTSEL, 113 GPIO55_nPREG, 114 GPIO56_nPWAIT, 115 GPIO57_nIOIS16, 116 117 /* AC97 */ 118 GPIO31_AC97_SYNC, 119 GPIO30_AC97_SDATA_OUT, 120 GPIO28_AC97_BITCLK, 121 GPIO29_AC97_SDATA_IN_0, 122 // GPIO79 nAUD_IRQ 123 124 /* FFUART */ 125 GPIO34_FFUART_RXD, 126 GPIO35_FFUART_CTS, 127 GPIO37_FFUART_DSR, 128 GPIO39_FFUART_TXD, 129 GPIO40_FFUART_DTR, 130 GPIO41_FFUART_RTS, 131 132 /* BTUART */ 133 GPIO42_BTUART_RXD, 134 GPIO43_BTUART_TXD, 135 GPIO44_BTUART_CTS, 136 GPIO45_BTUART_RTS, 137 138 /* Keybd */ 139 GPIO58_GPIO | MFP_LPM_DRIVE_LOW, /* Column 0 */ 140 GPIO59_GPIO | MFP_LPM_DRIVE_LOW, /* Column 1 */ 141 GPIO60_GPIO | MFP_LPM_DRIVE_LOW, /* Column 2 */ 142 GPIO61_GPIO | MFP_LPM_DRIVE_LOW, /* Column 3 */ 143 GPIO62_GPIO | MFP_LPM_DRIVE_LOW, /* Column 4 */ 144 GPIO63_GPIO | MFP_LPM_DRIVE_LOW, /* Column 5 */ 145 GPIO64_GPIO | MFP_LPM_DRIVE_LOW, /* Column 6 */ 146 GPIO65_GPIO | MFP_LPM_DRIVE_LOW, /* Column 7 */ 147 GPIO66_GPIO | MFP_LPM_DRIVE_LOW, /* Column 8 */ 148 GPIO67_GPIO | MFP_LPM_DRIVE_LOW, /* Column 9 */ 149 GPIO68_GPIO | MFP_LPM_DRIVE_LOW, /* Column 10 */ 150 GPIO69_GPIO | MFP_LPM_DRIVE_LOW, /* Row 0 */ 151 GPIO70_GPIO | MFP_LPM_DRIVE_LOW, /* Row 1 */ 152 GPIO71_GPIO | MFP_LPM_DRIVE_LOW, /* Row 2 */ 153 GPIO72_GPIO | MFP_LPM_DRIVE_LOW, /* Row 3 */ 154 GPIO73_GPIO | MFP_LPM_DRIVE_LOW, /* Row 4 */ 155 GPIO74_GPIO | MFP_LPM_DRIVE_LOW, /* Row 5 */ 156 GPIO75_GPIO | MFP_LPM_DRIVE_LOW, /* Row 6 */ 157 158 /* SPI */ 159 GPIO81_SSP2_CLK_OUT, 160 GPIO82_SSP2_FRM_OUT, 161 GPIO83_SSP2_TXD, 162 163 /* IrDA is managed in other way */ 164 GPIO46_GPIO, 165 GPIO47_GPIO, 166}; 167 168/* 169 * SCOOP Device 170 */ 171static struct resource tosa_scoop_resources[] = { 172 [0] = { 173 .start = TOSA_CF_PHYS, 174 .end = TOSA_CF_PHYS + 0xfff, 175 .flags = IORESOURCE_MEM, 176 }, 177}; 178 179static struct scoop_config tosa_scoop_setup = { 180 .io_dir = TOSA_SCOOP_IO_DIR, 181 .gpio_base = TOSA_SCOOP_GPIO_BASE, 182}; 183 184static struct platform_device tosascoop_device = { 185 .name = "sharp-scoop", 186 .id = 0, 187 .dev = { 188 .platform_data = &tosa_scoop_setup, 189 }, 190 .num_resources = ARRAY_SIZE(tosa_scoop_resources), 191 .resource = tosa_scoop_resources, 192}; 193 194 195/* 196 * SCOOP Device Jacket 197 */ 198static struct resource tosa_scoop_jc_resources[] = { 199 [0] = { 200 .start = TOSA_SCOOP_PHYS + 0x40, 201 .end = TOSA_SCOOP_PHYS + 0xfff, 202 .flags = IORESOURCE_MEM, 203 }, 204}; 205 206static struct scoop_config tosa_scoop_jc_setup = { 207 .io_dir = TOSA_SCOOP_JC_IO_DIR, 208 .gpio_base = TOSA_SCOOP_JC_GPIO_BASE, 209}; 210 211static struct platform_device tosascoop_jc_device = { 212 .name = "sharp-scoop", 213 .id = 1, 214 .dev = { 215 .platform_data = &tosa_scoop_jc_setup, 216 .parent = &tosascoop_device.dev, 217 }, 218 .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources), 219 .resource = tosa_scoop_jc_resources, 220}; 221 222/* 223 * PCMCIA 224 */ 225static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { 226{ 227 .dev = &tosascoop_device.dev, 228 .irq = TOSA_IRQ_GPIO_CF_IRQ, 229 .cd_irq = TOSA_IRQ_GPIO_CF_CD, 230 .cd_irq_str = "PCMCIA0 CD", 231},{ 232 .dev = &tosascoop_jc_device.dev, 233 .irq = TOSA_IRQ_GPIO_JC_CF_IRQ, 234 .cd_irq = -1, 235}, 236}; 237 238static struct scoop_pcmcia_config tosa_pcmcia_config = { 239 .devs = &tosa_pcmcia_scoop[0], 240 .num_devs = 2, 241}; 242 243/* 244 * USB Device Controller 245 */ 246static struct gpio_vbus_mach_info tosa_udc_info = { 247 .gpio_pullup = TOSA_GPIO_USB_PULLUP, 248 .gpio_vbus = TOSA_GPIO_USB_IN, 249 .gpio_vbus_inverted = 1, 250}; 251 252static struct platform_device tosa_gpio_vbus = { 253 .name = "gpio-vbus", 254 .id = -1, 255 .dev = { 256 .platform_data = &tosa_udc_info, 257 }, 258}; 259 260/* 261 * MMC/SD Device 262 */ 263static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data) 264{ 265 int err; 266 267 err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int"); 268 if (err) { 269 printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); 270 goto err_gpio_int; 271 } 272 err = gpio_direction_input(TOSA_GPIO_nSD_INT); 273 if (err) 274 goto err_gpio_int_dir; 275 276 return 0; 277 278err_gpio_int_dir: 279 gpio_free(TOSA_GPIO_nSD_INT); 280err_gpio_int: 281 return err; 282} 283 284static void tosa_mci_exit(struct device *dev, void *data) 285{ 286 gpio_free(TOSA_GPIO_nSD_INT); 287} 288 289static struct pxamci_platform_data tosa_mci_platform_data = { 290 .detect_delay_ms = 250, 291 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 292 .init = tosa_mci_init, 293 .exit = tosa_mci_exit, 294 .gpio_card_detect = TOSA_GPIO_nSD_DETECT, 295 .gpio_card_ro = TOSA_GPIO_SD_WP, 296 .gpio_power = TOSA_GPIO_PWR_ON, 297}; 298 299/* 300 * Irda 301 */ 302static void tosa_irda_transceiver_mode(struct device *dev, int mode) 303{ 304 if (mode & IR_OFF) { 305 gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); 306 pxa2xx_transceiver_mode(dev, mode); 307 gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); 308 } else { 309 pxa2xx_transceiver_mode(dev, mode); 310 gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); 311 } 312} 313 314static int tosa_irda_startup(struct device *dev) 315{ 316 int ret; 317 318 ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); 319 if (ret) 320 goto err_tx; 321 ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); 322 if (ret) 323 goto err_tx_dir; 324 325 ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); 326 if (ret) 327 goto err_pwr; 328 329 ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); 330 if (ret) 331 goto err_pwr_dir; 332 333 tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); 334 335 return 0; 336 337err_pwr_dir: 338 gpio_free(TOSA_GPIO_IR_POWERDWN); 339err_pwr: 340err_tx_dir: 341 gpio_free(TOSA_GPIO_IRDA_TX); 342err_tx: 343 return ret; 344} 345 346static void tosa_irda_shutdown(struct device *dev) 347{ 348 tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); 349 gpio_free(TOSA_GPIO_IR_POWERDWN); 350 gpio_free(TOSA_GPIO_IRDA_TX); 351} 352 353static struct pxaficp_platform_data tosa_ficp_platform_data = { 354 .gpio_pwdown = -1, 355 .transceiver_cap = IR_SIRMODE | IR_OFF, 356 .transceiver_mode = tosa_irda_transceiver_mode, 357 .startup = tosa_irda_startup, 358 .shutdown = tosa_irda_shutdown, 359}; 360 361/* 362 * Tosa AC IN 363 */ 364static char *tosa_ac_supplied_to[] = { 365 "main-battery", 366 "backup-battery", 367 "jacket-battery", 368}; 369 370static struct gpio_charger_platform_data tosa_power_data = { 371 .name = "charger", 372 .type = POWER_SUPPLY_TYPE_MAINS, 373 .gpio = TOSA_GPIO_AC_IN, 374 .gpio_active_low = 1, 375 .supplied_to = tosa_ac_supplied_to, 376 .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), 377}; 378 379static struct resource tosa_power_resource[] = { 380 { 381 .name = "ac", 382 .start = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), 383 .end = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN), 384 .flags = IORESOURCE_IRQ | 385 IORESOURCE_IRQ_HIGHEDGE | 386 IORESOURCE_IRQ_LOWEDGE, 387 }, 388}; 389 390static struct platform_device tosa_power_device = { 391 .name = "gpio-charger", 392 .id = -1, 393 .dev.platform_data = &tosa_power_data, 394 .resource = tosa_power_resource, 395 .num_resources = ARRAY_SIZE(tosa_power_resource), 396}; 397 398/* 399 * Tosa Keyboard 400 */ 401static const uint32_t tosakbd_keymap[] = { 402 KEY(0, 1, KEY_W), 403 KEY(0, 5, KEY_K), 404 KEY(0, 6, KEY_BACKSPACE), 405 KEY(0, 7, KEY_P), 406 KEY(1, 0, KEY_Q), 407 KEY(1, 1, KEY_E), 408 KEY(1, 2, KEY_T), 409 KEY(1, 3, KEY_Y), 410 KEY(1, 5, KEY_O), 411 KEY(1, 6, KEY_I), 412 KEY(1, 7, KEY_COMMA), 413 KEY(2, 0, KEY_A), 414 KEY(2, 1, KEY_D), 415 KEY(2, 2, KEY_G), 416 KEY(2, 3, KEY_U), 417 KEY(2, 5, KEY_L), 418 KEY(2, 6, KEY_ENTER), 419 KEY(2, 7, KEY_DOT), 420 KEY(3, 0, KEY_Z), 421 KEY(3, 1, KEY_C), 422 KEY(3, 2, KEY_V), 423 KEY(3, 3, KEY_J), 424 KEY(3, 4, TOSA_KEY_ADDRESSBOOK), 425 KEY(3, 5, TOSA_KEY_CANCEL), 426 KEY(3, 6, TOSA_KEY_CENTER), 427 KEY(3, 7, TOSA_KEY_OK), 428 KEY(3, 8, KEY_LEFTSHIFT), 429 KEY(4, 0, KEY_S), 430 KEY(4, 1, KEY_R), 431 KEY(4, 2, KEY_B), 432 KEY(4, 3, KEY_N), 433 KEY(4, 4, TOSA_KEY_CALENDAR), 434 KEY(4, 5, TOSA_KEY_HOMEPAGE), 435 KEY(4, 6, KEY_LEFTCTRL), 436 KEY(4, 7, TOSA_KEY_LIGHT), 437 KEY(4, 9, KEY_RIGHTSHIFT), 438 KEY(5, 0, KEY_TAB), 439 KEY(5, 1, KEY_SLASH), 440 KEY(5, 2, KEY_H), 441 KEY(5, 3, KEY_M), 442 KEY(5, 4, TOSA_KEY_MENU), 443 KEY(5, 6, KEY_UP), 444 KEY(5, 10, TOSA_KEY_FN), 445 KEY(6, 0, KEY_X), 446 KEY(6, 1, KEY_F), 447 KEY(6, 2, KEY_SPACE), 448 KEY(6, 3, KEY_APOSTROPHE), 449 KEY(6, 4, TOSA_KEY_MAIL), 450 KEY(6, 5, KEY_LEFT), 451 KEY(6, 6, KEY_DOWN), 452 KEY(6, 7, KEY_RIGHT), 453}; 454 455static struct matrix_keymap_data tosakbd_keymap_data = { 456 .keymap = tosakbd_keymap, 457 .keymap_size = ARRAY_SIZE(tosakbd_keymap), 458}; 459 460static const int tosakbd_col_gpios[] = 461 { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 }; 462static const int tosakbd_row_gpios[] = 463 { 69, 70, 71, 72, 73, 74, 75 }; 464 465static struct matrix_keypad_platform_data tosakbd_pdata = { 466 .keymap_data = &tosakbd_keymap_data, 467 .row_gpios = tosakbd_row_gpios, 468 .col_gpios = tosakbd_col_gpios, 469 .num_row_gpios = ARRAY_SIZE(tosakbd_row_gpios), 470 .num_col_gpios = ARRAY_SIZE(tosakbd_col_gpios), 471 .col_scan_delay_us = 10, 472 .debounce_ms = 10, 473 .wakeup = 1, 474}; 475 476static struct platform_device tosakbd_device = { 477 .name = "matrix-keypad", 478 .id = -1, 479 .dev = { 480 .platform_data = &tosakbd_pdata, 481 }, 482}; 483 484static struct gpio_keys_button tosa_gpio_keys[] = { 485 /* 486 * Two following keys are directly tied to "ON" button of tosa. Why? 487 * The first one can be used as a wakeup source, the second can't; 488 * also the first one is OR of ac_powered and on_button. 489 */ 490 { 491 .type = EV_PWR, 492 .code = KEY_RESERVED, 493 .gpio = TOSA_GPIO_POWERON, 494 .desc = "Poweron", 495 .wakeup = 1, 496 .active_low = 1, 497 }, 498 { 499 .type = EV_PWR, 500 .code = KEY_SUSPEND, 501 .gpio = TOSA_GPIO_ON_KEY, 502 .desc = "On key", 503 /* 504 * can't be used as wakeup 505 * .wakeup = 1, 506 */ 507 .active_low = 1, 508 }, 509 { 510 .type = EV_KEY, 511 .code = TOSA_KEY_RECORD, 512 .gpio = TOSA_GPIO_RECORD_BTN, 513 .desc = "Record Button", 514 .wakeup = 1, 515 .active_low = 1, 516 }, 517 { 518 .type = EV_KEY, 519 .code = TOSA_KEY_SYNC, 520 .gpio = TOSA_GPIO_SYNC, 521 .desc = "Sync Button", 522 .wakeup = 1, 523 .active_low = 1, 524 }, 525 { 526 .type = EV_SW, 527 .code = SW_HEADPHONE_INSERT, 528 .gpio = TOSA_GPIO_EAR_IN, 529 .desc = "HeadPhone insert", 530 .active_low = 1, 531 .debounce_interval = 300, 532 }, 533}; 534 535static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = { 536 .buttons = tosa_gpio_keys, 537 .nbuttons = ARRAY_SIZE(tosa_gpio_keys), 538}; 539 540static struct platform_device tosa_gpio_keys_device = { 541 .name = "gpio-keys", 542 .id = -1, 543 .dev = { 544 .platform_data = &tosa_gpio_keys_platform_data, 545 }, 546}; 547 548/* 549 * Tosa LEDs 550 */ 551static struct gpio_led tosa_gpio_leds[] = { 552 { 553 .name = "tosa:amber:charge", 554 .default_trigger = "main-battery-charging", 555 .gpio = TOSA_GPIO_CHRG_ERR_LED, 556 }, 557 { 558 .name = "tosa:green:mail", 559 .default_trigger = "nand-disk", 560 .gpio = TOSA_GPIO_NOTE_LED, 561 }, 562 { 563 .name = "tosa:dual:wlan", 564 .default_trigger = "none", 565 .gpio = TOSA_GPIO_WLAN_LED, 566 }, 567 { 568 .name = "tosa:blue:bluetooth", 569 .default_trigger = "tosa-bt", 570 .gpio = TOSA_GPIO_BT_LED, 571 }, 572}; 573 574static struct gpio_led_platform_data tosa_gpio_leds_platform_data = { 575 .leds = tosa_gpio_leds, 576 .num_leds = ARRAY_SIZE(tosa_gpio_leds), 577}; 578 579static struct platform_device tosaled_device = { 580 .name = "leds-gpio", 581 .id = -1, 582 .dev = { 583 .platform_data = &tosa_gpio_leds_platform_data, 584 }, 585}; 586 587/* 588 * Toshiba Mobile IO Controller 589 */ 590static struct resource tc6393xb_resources[] = { 591 [0] = { 592 .start = TOSA_LCDC_PHYS, 593 .end = TOSA_LCDC_PHYS + 0x3ffffff, 594 .flags = IORESOURCE_MEM, 595 }, 596 597 [1] = { 598 .start = TOSA_IRQ_GPIO_TC6393XB_INT, 599 .end = TOSA_IRQ_GPIO_TC6393XB_INT, 600 .flags = IORESOURCE_IRQ, 601 }, 602}; 603 604 605static int tosa_tc6393xb_enable(struct platform_device *dev) 606{ 607 int rc; 608 609 rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); 610 if (rc) 611 goto err_req_pclr; 612 rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); 613 if (rc) 614 goto err_req_suspend; 615 rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v"); 616 if (rc) 617 goto err_req_l3v; 618 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); 619 if (rc) 620 goto err_dir_l3v; 621 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); 622 if (rc) 623 goto err_dir_suspend; 624 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); 625 if (rc) 626 goto err_dir_pclr; 627 628 mdelay(1); 629 630 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); 631 632 mdelay(10); 633 634 gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); 635 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); 636 637 return 0; 638err_dir_pclr: 639err_dir_suspend: 640err_dir_l3v: 641 gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); 642err_req_l3v: 643 gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); 644err_req_suspend: 645 gpio_free(TOSA_GPIO_TC6393XB_REST_IN); 646err_req_pclr: 647 return rc; 648} 649 650static int tosa_tc6393xb_disable(struct platform_device *dev) 651{ 652 gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); 653 gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); 654 gpio_free(TOSA_GPIO_TC6393XB_REST_IN); 655 656 return 0; 657} 658 659static int tosa_tc6393xb_resume(struct platform_device *dev) 660{ 661 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); 662 mdelay(10); 663 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); 664 mdelay(10); 665 666 return 0; 667} 668 669static int tosa_tc6393xb_suspend(struct platform_device *dev) 670{ 671 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); 672 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); 673 return 0; 674} 675 676static struct mtd_partition tosa_nand_partition[] = { 677 { 678 .name = "smf", 679 .offset = 0, 680 .size = 7 * 1024 * 1024, 681 }, 682 { 683 .name = "root", 684 .offset = MTDPART_OFS_APPEND, 685 .size = 28 * 1024 * 1024, 686 }, 687 { 688 .name = "home", 689 .offset = MTDPART_OFS_APPEND, 690 .size = MTDPART_SIZ_FULL, 691 }, 692}; 693 694static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 695 696static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { 697 .options = 0, 698 .offs = 4, 699 .len = 2, 700 .pattern = scan_ff_pattern 701}; 702 703static struct tmio_nand_data tosa_tc6393xb_nand_config = { 704 .num_partitions = ARRAY_SIZE(tosa_nand_partition), 705 .partition = tosa_nand_partition, 706 .badblock_pattern = &tosa_tc6393xb_nand_bbt, 707}; 708 709static int tosa_tc6393xb_setup(struct platform_device *dev) 710{ 711 int rc; 712 713 rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON"); 714 if (rc) 715 goto err_req; 716 717 rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1); 718 if (rc) 719 goto err_dir; 720 721 return rc; 722 723err_dir: 724 gpio_free(TOSA_GPIO_CARD_VCC_ON); 725err_req: 726 return rc; 727} 728 729static void tosa_tc6393xb_teardown(struct platform_device *dev) 730{ 731 gpio_free(TOSA_GPIO_CARD_VCC_ON); 732} 733 734#ifdef CONFIG_MFD_TC6393XB 735static struct fb_videomode tosa_tc6393xb_lcd_mode[] = { 736 { 737 .xres = 480, 738 .yres = 640, 739 .pixclock = 0x002cdf00,/* PLL divisor */ 740 .left_margin = 0x004c, 741 .right_margin = 0x005b, 742 .upper_margin = 0x0001, 743 .lower_margin = 0x000d, 744 .hsync_len = 0x0002, 745 .vsync_len = 0x0001, 746 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 747 .vmode = FB_VMODE_NONINTERLACED, 748 },{ 749 .xres = 240, 750 .yres = 320, 751 .pixclock = 0x00e7f203,/* PLL divisor */ 752 .left_margin = 0x0024, 753 .right_margin = 0x002f, 754 .upper_margin = 0x0001, 755 .lower_margin = 0x000d, 756 .hsync_len = 0x0002, 757 .vsync_len = 0x0001, 758 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 759 .vmode = FB_VMODE_NONINTERLACED, 760 } 761}; 762 763static struct tmio_fb_data tosa_tc6393xb_fb_config = { 764 .lcd_set_power = tc6393xb_lcd_set_power, 765 .lcd_mode = tc6393xb_lcd_mode, 766 .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode), 767 .modes = &tosa_tc6393xb_lcd_mode[0], 768 .height = 82, 769 .width = 60, 770}; 771#endif 772 773static struct tc6393xb_platform_data tosa_tc6393xb_data = { 774 .scr_pll2cr = 0x0cc1, 775 .scr_gper = 0x3300, 776 777 .irq_base = IRQ_BOARD_START, 778 .gpio_base = TOSA_TC6393XB_GPIO_BASE, 779 .setup = tosa_tc6393xb_setup, 780 .teardown = tosa_tc6393xb_teardown, 781 782 .enable = tosa_tc6393xb_enable, 783 .disable = tosa_tc6393xb_disable, 784 .suspend = tosa_tc6393xb_suspend, 785 .resume = tosa_tc6393xb_resume, 786 787 .nand_data = &tosa_tc6393xb_nand_config, 788#ifdef CONFIG_MFD_TC6393XB 789 .fb_data = &tosa_tc6393xb_fb_config, 790#endif 791 792 .resume_restore = 1, 793}; 794 795 796static struct platform_device tc6393xb_device = { 797 .name = "tc6393xb", 798 .id = -1, 799 .dev = { 800 .platform_data = &tosa_tc6393xb_data, 801 }, 802 .num_resources = ARRAY_SIZE(tc6393xb_resources), 803 .resource = tc6393xb_resources, 804}; 805 806static struct tosa_bt_data tosa_bt_data = { 807 .gpio_pwr = TOSA_GPIO_BT_PWR_EN, 808 .gpio_reset = TOSA_GPIO_BT_RESET, 809}; 810 811static struct platform_device tosa_bt_device = { 812 .name = "tosa-bt", 813 .id = -1, 814 .dev.platform_data = &tosa_bt_data, 815}; 816 817static struct pxa2xx_spi_master pxa_ssp_master_info = { 818 .num_chipselect = 1, 819}; 820 821static struct spi_board_info spi_board_info[] __initdata = { 822 { 823 .modalias = "tosa-lcd", 824 // .platform_data 825 .max_speed_hz = 28750, 826 .bus_num = 2, 827 .chip_select = 0, 828 .mode = SPI_MODE_0, 829 }, 830}; 831 832static struct mtd_partition sharpsl_rom_parts[] = { 833 { 834 .name ="Boot PROM Filesystem", 835 .offset = 0x00160000, 836 .size = MTDPART_SIZ_FULL, 837 }, 838}; 839 840static struct physmap_flash_data sharpsl_rom_data = { 841 .width = 2, 842 .nr_parts = ARRAY_SIZE(sharpsl_rom_parts), 843 .parts = sharpsl_rom_parts, 844}; 845 846static struct resource sharpsl_rom_resources[] = { 847 { 848 .start = 0x00000000, 849 .end = 0x007fffff, 850 .flags = IORESOURCE_MEM, 851 }, 852}; 853 854static struct platform_device sharpsl_rom_device = { 855 .name = "physmap-flash", 856 .id = -1, 857 .resource = sharpsl_rom_resources, 858 .num_resources = ARRAY_SIZE(sharpsl_rom_resources), 859 .dev.platform_data = &sharpsl_rom_data, 860}; 861 862static struct platform_device wm9712_device = { 863 .name = "wm9712-codec", 864 .id = -1, 865}; 866 867static struct platform_device tosa_audio_device = { 868 .name = "tosa-audio", 869 .id = -1, 870}; 871 872static struct platform_device *devices[] __initdata = { 873 &tosascoop_device, 874 &tosascoop_jc_device, 875 &tc6393xb_device, 876 &tosa_power_device, 877 &tosakbd_device, 878 &tosa_gpio_keys_device, 879 &tosaled_device, 880 &tosa_bt_device, 881 &sharpsl_rom_device, 882 &wm9712_device, 883 &tosa_gpio_vbus, 884 &tosa_audio_device, 885}; 886 887static void tosa_poweroff(void) 888{ 889 pxa_restart(REBOOT_GPIO, NULL); 890} 891 892static void tosa_restart(enum reboot_mode mode, const char *cmd) 893{ 894 uint32_t msc0 = __raw_readl(MSC0); 895 896 /* Bootloader magic for a reboot */ 897 if((msc0 & 0xffff0000) == 0x7ff00000) 898 __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0); 899 900 tosa_poweroff(); 901} 902 903static void __init tosa_init(void) 904{ 905 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); 906 907 pxa_set_ffuart_info(NULL); 908 pxa_set_btuart_info(NULL); 909 pxa_set_stuart_info(NULL); 910 911 gpio_set_wake(MFP_PIN_GPIO1, 1); 912 /* We can't pass to gpio-keys since it will drop the Reset altfunc */ 913 914 init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0); 915 916 pm_power_off = tosa_poweroff; 917 918 PCFR |= PCFR_OPDE; 919 920 /* enable batt_fault */ 921 PMCR = 0x01; 922 923 pxa_set_mci_info(&tosa_mci_platform_data); 924 pxa_set_ficp_info(&tosa_ficp_platform_data); 925 pxa_set_i2c_info(NULL); 926 pxa_set_ac97_info(NULL); 927 platform_scoop_config = &tosa_pcmcia_config; 928 929 pxa2xx_set_spi_info(2, &pxa_ssp_master_info); 930 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 931 932 clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL); 933 934 platform_add_devices(devices, ARRAY_SIZE(devices)); 935} 936 937static void __init fixup_tosa(struct tag *tags, char **cmdline) 938{ 939 sharpsl_save_param(); 940 memblock_add(0xa0000000, SZ_64M); 941} 942 943MACHINE_START(TOSA, "SHARP Tosa") 944 .fixup = fixup_tosa, 945 .map_io = pxa25x_map_io, 946 .nr_irqs = TOSA_NR_IRQS, 947 .init_irq = pxa25x_init_irq, 948 .handle_irq = pxa25x_handle_irq, 949 .init_machine = tosa_init, 950 .init_time = pxa_timer_init, 951 .restart = tosa_restart, 952MACHINE_END 953