linux/arch/arm/mach-pxa/tosa.c
<<
>>
Prefs
   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