1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Support for Sharp SL-C7xx PDAs 4 * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky) 5 * 6 * Copyright (c) 2004-2005 Richard Purdie 7 * 8 * Based on Sharp's 2.4 kernel patches/lubbock.c 9 */ 10 11#include <linux/kernel.h> 12#include <linux/module.h> /* symbol_get ; symbol_put */ 13#include <linux/init.h> 14#include <linux/platform_device.h> 15#include <linux/major.h> 16#include <linux/fs.h> 17#include <linux/interrupt.h> 18#include <linux/leds.h> 19#include <linux/mmc/host.h> 20#include <linux/mtd/physmap.h> 21#include <linux/pm.h> 22#include <linux/gpio.h> 23#include <linux/gpio/machine.h> 24#include <linux/backlight.h> 25#include <linux/i2c.h> 26#include <linux/platform_data/i2c-pxa.h> 27#include <linux/io.h> 28#include <linux/regulator/machine.h> 29#include <linux/spi/spi.h> 30#include <linux/spi/ads7846.h> 31#include <linux/spi/corgi_lcd.h> 32#include <linux/spi/pxa2xx_spi.h> 33#include <linux/mtd/sharpsl.h> 34#include <linux/input/matrix_keypad.h> 35#include <linux/gpio_keys.h> 36#include <linux/memblock.h> 37#include <video/w100fb.h> 38 39#include <asm/setup.h> 40#include <asm/memory.h> 41#include <asm/mach-types.h> 42#include <mach/hardware.h> 43#include <asm/irq.h> 44 45#include <asm/mach/arch.h> 46#include <asm/mach/map.h> 47#include <asm/mach/irq.h> 48 49#include "pxa25x.h" 50#include <linux/platform_data/irda-pxaficp.h> 51#include <linux/platform_data/mmc-pxamci.h> 52#include "udc.h" 53#include <mach/corgi.h> 54#include "sharpsl_pm.h" 55 56#include <asm/mach/sharpsl_param.h> 57#include <asm/hardware/scoop.h> 58 59#include "generic.h" 60#include "devices.h" 61 62static unsigned long corgi_pin_config[] __initdata = { 63 /* Static Memory I/O */ 64 GPIO78_nCS_2, /* w100fb */ 65 GPIO80_nCS_4, /* scoop */ 66 67 /* SSP1 */ 68 GPIO23_SSP1_SCLK, 69 GPIO25_SSP1_TXD, 70 GPIO26_SSP1_RXD, 71 GPIO24_GPIO, /* CORGI_GPIO_ADS7846_CS - SFRM as chip select */ 72 73 /* I2S */ 74 GPIO28_I2S_BITCLK_OUT, 75 GPIO29_I2S_SDATA_IN, 76 GPIO30_I2S_SDATA_OUT, 77 GPIO31_I2S_SYNC, 78 GPIO32_I2S_SYSCLK, 79 80 /* Infra-Red */ 81 GPIO47_FICP_TXD, 82 GPIO46_FICP_RXD, 83 84 /* FFUART */ 85 GPIO40_FFUART_DTR, 86 GPIO41_FFUART_RTS, 87 GPIO39_FFUART_TXD, 88 GPIO37_FFUART_DSR, 89 GPIO34_FFUART_RXD, 90 GPIO35_FFUART_CTS, 91 92 /* PC Card */ 93 GPIO48_nPOE, 94 GPIO49_nPWE, 95 GPIO50_nPIOR, 96 GPIO51_nPIOW, 97 GPIO52_nPCE_1, 98 GPIO53_nPCE_2, 99 GPIO54_nPSKTSEL, 100 GPIO55_nPREG, 101 GPIO56_nPWAIT, 102 GPIO57_nIOIS16, 103 104 /* MMC */ 105 GPIO6_MMC_CLK, 106 GPIO8_MMC_CS0, 107 108 /* GPIO Matrix Keypad */ 109 GPIO66_GPIO | MFP_LPM_DRIVE_HIGH, /* column 0 */ 110 GPIO67_GPIO | MFP_LPM_DRIVE_HIGH, /* column 1 */ 111 GPIO68_GPIO | MFP_LPM_DRIVE_HIGH, /* column 2 */ 112 GPIO69_GPIO | MFP_LPM_DRIVE_HIGH, /* column 3 */ 113 GPIO70_GPIO | MFP_LPM_DRIVE_HIGH, /* column 4 */ 114 GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* column 5 */ 115 GPIO72_GPIO | MFP_LPM_DRIVE_HIGH, /* column 6 */ 116 GPIO73_GPIO | MFP_LPM_DRIVE_HIGH, /* column 7 */ 117 GPIO74_GPIO | MFP_LPM_DRIVE_HIGH, /* column 8 */ 118 GPIO75_GPIO | MFP_LPM_DRIVE_HIGH, /* column 9 */ 119 GPIO76_GPIO | MFP_LPM_DRIVE_HIGH, /* column 10 */ 120 GPIO77_GPIO | MFP_LPM_DRIVE_HIGH, /* column 11 */ 121 GPIO58_GPIO, /* row 0 */ 122 GPIO59_GPIO, /* row 1 */ 123 GPIO60_GPIO, /* row 2 */ 124 GPIO61_GPIO, /* row 3 */ 125 GPIO62_GPIO, /* row 4 */ 126 GPIO63_GPIO, /* row 5 */ 127 GPIO64_GPIO, /* row 6 */ 128 GPIO65_GPIO, /* row 7 */ 129 130 /* GPIO */ 131 GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */ 132 GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */ 133 GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */ 134 GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_LED_ORANGE */ 135 GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */ 136 GPIO22_GPIO, /* CORGI_GPIO_IR_ON */ 137 GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ 138 GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_ON */ 139 GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_UKN */ 140 GPIO44_GPIO, /* CORGI_GPIO_HSYNC */ 141 142 GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_KEY_INT */ 143 GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* CORGI_GPIO_AC_IN */ 144 GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_WAKEUP */ 145}; 146 147/* 148 * Corgi SCOOP Device 149 */ 150static struct resource corgi_scoop_resources[] = { 151 [0] = { 152 .start = 0x10800000, 153 .end = 0x10800fff, 154 .flags = IORESOURCE_MEM, 155 }, 156}; 157 158static struct scoop_config corgi_scoop_setup = { 159 .io_dir = CORGI_SCOOP_IO_DIR, 160 .io_out = CORGI_SCOOP_IO_OUT, 161 .gpio_base = CORGI_SCOOP_GPIO_BASE, 162}; 163 164struct platform_device corgiscoop_device = { 165 .name = "sharp-scoop", 166 .id = -1, 167 .dev = { 168 .platform_data = &corgi_scoop_setup, 169 }, 170 .num_resources = ARRAY_SIZE(corgi_scoop_resources), 171 .resource = corgi_scoop_resources, 172}; 173 174static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { 175{ 176 .dev = &corgiscoop_device.dev, 177 .irq = CORGI_IRQ_GPIO_CF_IRQ, 178 .cd_irq = CORGI_IRQ_GPIO_CF_CD, 179 .cd_irq_str = "PCMCIA0 CD", 180}, 181}; 182 183static struct scoop_pcmcia_config corgi_pcmcia_config = { 184 .devs = &corgi_pcmcia_scoop[0], 185 .num_devs = 1, 186}; 187 188static struct w100_mem_info corgi_fb_mem = { 189 .ext_cntl = 0x00040003, 190 .sdram_mode_reg = 0x00650021, 191 .ext_timing_cntl = 0x10002a4a, 192 .io_cntl = 0x7ff87012, 193 .size = 0x1fffff, 194}; 195 196static struct w100_gen_regs corgi_fb_regs = { 197 .lcd_format = 0x00000003, 198 .lcdd_cntl1 = 0x01CC0000, 199 .lcdd_cntl2 = 0x0003FFFF, 200 .genlcd_cntl1 = 0x00FFFF0D, 201 .genlcd_cntl2 = 0x003F3003, 202 .genlcd_cntl3 = 0x000102aa, 203}; 204 205static struct w100_gpio_regs corgi_fb_gpio = { 206 .init_data1 = 0x000000bf, 207 .init_data2 = 0x00000000, 208 .gpio_dir1 = 0x00000000, 209 .gpio_oe1 = 0x03c0feff, 210 .gpio_dir2 = 0x00000000, 211 .gpio_oe2 = 0x00000000, 212}; 213 214static struct w100_mode corgi_fb_modes[] = { 215{ 216 .xres = 480, 217 .yres = 640, 218 .left_margin = 0x56, 219 .right_margin = 0x55, 220 .upper_margin = 0x03, 221 .lower_margin = 0x00, 222 .crtc_ss = 0x82360056, 223 .crtc_ls = 0xA0280000, 224 .crtc_gs = 0x80280028, 225 .crtc_vpos_gs = 0x02830002, 226 .crtc_rev = 0x00400008, 227 .crtc_dclk = 0xA0000000, 228 .crtc_gclk = 0x8015010F, 229 .crtc_goe = 0x80100110, 230 .crtc_ps1_active = 0x41060010, 231 .pll_freq = 75, 232 .fast_pll_freq = 100, 233 .sysclk_src = CLK_SRC_PLL, 234 .sysclk_divider = 0, 235 .pixclk_src = CLK_SRC_PLL, 236 .pixclk_divider = 2, 237 .pixclk_divider_rotated = 6, 238},{ 239 .xres = 240, 240 .yres = 320, 241 .left_margin = 0x27, 242 .right_margin = 0x2e, 243 .upper_margin = 0x01, 244 .lower_margin = 0x00, 245 .crtc_ss = 0x81170027, 246 .crtc_ls = 0xA0140000, 247 .crtc_gs = 0xC0140014, 248 .crtc_vpos_gs = 0x00010141, 249 .crtc_rev = 0x00400008, 250 .crtc_dclk = 0xA0000000, 251 .crtc_gclk = 0x8015010F, 252 .crtc_goe = 0x80100110, 253 .crtc_ps1_active = 0x41060010, 254 .pll_freq = 0, 255 .fast_pll_freq = 0, 256 .sysclk_src = CLK_SRC_XTAL, 257 .sysclk_divider = 0, 258 .pixclk_src = CLK_SRC_XTAL, 259 .pixclk_divider = 1, 260 .pixclk_divider_rotated = 1, 261}, 262 263}; 264 265static struct w100fb_mach_info corgi_fb_info = { 266 .init_mode = INIT_MODE_ROTATED, 267 .mem = &corgi_fb_mem, 268 .regs = &corgi_fb_regs, 269 .modelist = &corgi_fb_modes[0], 270 .num_modes = 2, 271 .gpio = &corgi_fb_gpio, 272 .xtal_freq = 12500000, 273 .xtal_dbl = 0, 274}; 275 276static struct resource corgi_fb_resources[] = { 277 [0] = { 278 .start = 0x08000000, 279 .end = 0x08ffffff, 280 .flags = IORESOURCE_MEM, 281 }, 282}; 283 284static struct platform_device corgifb_device = { 285 .name = "w100fb", 286 .id = -1, 287 .num_resources = ARRAY_SIZE(corgi_fb_resources), 288 .resource = corgi_fb_resources, 289 .dev = { 290 .platform_data = &corgi_fb_info, 291 }, 292 293}; 294 295/* 296 * Corgi Keyboard Device 297 */ 298#define CORGI_KEY_CALENDER KEY_F1 299#define CORGI_KEY_ADDRESS KEY_F2 300#define CORGI_KEY_FN KEY_F3 301#define CORGI_KEY_CANCEL KEY_F4 302#define CORGI_KEY_OFF KEY_SUSPEND 303#define CORGI_KEY_EXOK KEY_F5 304#define CORGI_KEY_EXCANCEL KEY_F6 305#define CORGI_KEY_EXJOGDOWN KEY_F7 306#define CORGI_KEY_EXJOGUP KEY_F8 307#define CORGI_KEY_JAP1 KEY_LEFTCTRL 308#define CORGI_KEY_JAP2 KEY_LEFTALT 309#define CORGI_KEY_MAIL KEY_F10 310#define CORGI_KEY_OK KEY_F11 311#define CORGI_KEY_MENU KEY_F12 312 313static const uint32_t corgikbd_keymap[] = { 314 KEY(0, 1, KEY_1), 315 KEY(0, 2, KEY_3), 316 KEY(0, 3, KEY_5), 317 KEY(0, 4, KEY_6), 318 KEY(0, 5, KEY_7), 319 KEY(0, 6, KEY_9), 320 KEY(0, 7, KEY_0), 321 KEY(0, 8, KEY_BACKSPACE), 322 KEY(1, 1, KEY_2), 323 KEY(1, 2, KEY_4), 324 KEY(1, 3, KEY_R), 325 KEY(1, 4, KEY_Y), 326 KEY(1, 5, KEY_8), 327 KEY(1, 6, KEY_I), 328 KEY(1, 7, KEY_O), 329 KEY(1, 8, KEY_P), 330 KEY(2, 0, KEY_TAB), 331 KEY(2, 1, KEY_Q), 332 KEY(2, 2, KEY_E), 333 KEY(2, 3, KEY_T), 334 KEY(2, 4, KEY_G), 335 KEY(2, 5, KEY_U), 336 KEY(2, 6, KEY_J), 337 KEY(2, 7, KEY_K), 338 KEY(3, 0, CORGI_KEY_CALENDER), 339 KEY(3, 1, KEY_W), 340 KEY(3, 2, KEY_S), 341 KEY(3, 3, KEY_F), 342 KEY(3, 4, KEY_V), 343 KEY(3, 5, KEY_H), 344 KEY(3, 6, KEY_M), 345 KEY(3, 7, KEY_L), 346 KEY(3, 9, KEY_RIGHTSHIFT), 347 KEY(4, 0, CORGI_KEY_ADDRESS), 348 KEY(4, 1, KEY_A), 349 KEY(4, 2, KEY_D), 350 KEY(4, 3, KEY_C), 351 KEY(4, 4, KEY_B), 352 KEY(4, 5, KEY_N), 353 KEY(4, 6, KEY_DOT), 354 KEY(4, 8, KEY_ENTER), 355 KEY(4, 10, KEY_LEFTSHIFT), 356 KEY(5, 0, CORGI_KEY_MAIL), 357 KEY(5, 1, KEY_Z), 358 KEY(5, 2, KEY_X), 359 KEY(5, 3, KEY_MINUS), 360 KEY(5, 4, KEY_SPACE), 361 KEY(5, 5, KEY_COMMA), 362 KEY(5, 7, KEY_UP), 363 KEY(5, 11, CORGI_KEY_FN), 364 KEY(6, 0, KEY_SYSRQ), 365 KEY(6, 1, CORGI_KEY_JAP1), 366 KEY(6, 2, CORGI_KEY_JAP2), 367 KEY(6, 3, CORGI_KEY_CANCEL), 368 KEY(6, 4, CORGI_KEY_OK), 369 KEY(6, 5, CORGI_KEY_MENU), 370 KEY(6, 6, KEY_LEFT), 371 KEY(6, 7, KEY_DOWN), 372 KEY(6, 8, KEY_RIGHT), 373 KEY(7, 0, CORGI_KEY_OFF), 374 KEY(7, 1, CORGI_KEY_EXOK), 375 KEY(7, 2, CORGI_KEY_EXCANCEL), 376 KEY(7, 3, CORGI_KEY_EXJOGDOWN), 377 KEY(7, 4, CORGI_KEY_EXJOGUP), 378}; 379 380static struct matrix_keymap_data corgikbd_keymap_data = { 381 .keymap = corgikbd_keymap, 382 .keymap_size = ARRAY_SIZE(corgikbd_keymap), 383}; 384 385static const int corgikbd_row_gpios[] = 386 { 58, 59, 60, 61, 62, 63, 64, 65 }; 387static const int corgikbd_col_gpios[] = 388 { 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 }; 389 390static struct matrix_keypad_platform_data corgikbd_pdata = { 391 .keymap_data = &corgikbd_keymap_data, 392 .row_gpios = corgikbd_row_gpios, 393 .col_gpios = corgikbd_col_gpios, 394 .num_row_gpios = ARRAY_SIZE(corgikbd_row_gpios), 395 .num_col_gpios = ARRAY_SIZE(corgikbd_col_gpios), 396 .col_scan_delay_us = 10, 397 .debounce_ms = 10, 398 .wakeup = 1, 399}; 400 401static struct platform_device corgikbd_device = { 402 .name = "matrix-keypad", 403 .id = -1, 404 .dev = { 405 .platform_data = &corgikbd_pdata, 406 }, 407}; 408 409static struct gpio_keys_button corgi_gpio_keys[] = { 410 { 411 .type = EV_SW, 412 .code = SW_LID, 413 .gpio = CORGI_GPIO_SWA, 414 .desc = "Lid close switch", 415 .debounce_interval = 500, 416 }, 417 { 418 .type = EV_SW, 419 .code = SW_TABLET_MODE, 420 .gpio = CORGI_GPIO_SWB, 421 .desc = "Tablet mode switch", 422 .debounce_interval = 500, 423 }, 424 { 425 .type = EV_SW, 426 .code = SW_HEADPHONE_INSERT, 427 .gpio = CORGI_GPIO_AK_INT, 428 .desc = "HeadPhone insert", 429 .debounce_interval = 500, 430 }, 431}; 432 433static struct gpio_keys_platform_data corgi_gpio_keys_platform_data = { 434 .buttons = corgi_gpio_keys, 435 .nbuttons = ARRAY_SIZE(corgi_gpio_keys), 436 .poll_interval = 250, 437}; 438 439static struct platform_device corgi_gpio_keys_device = { 440 .name = "gpio-keys-polled", 441 .id = -1, 442 .dev = { 443 .platform_data = &corgi_gpio_keys_platform_data, 444 }, 445}; 446 447/* 448 * Corgi LEDs 449 */ 450static struct gpio_led corgi_gpio_leds[] = { 451 { 452 .name = "corgi:amber:charge", 453 .default_trigger = "sharpsl-charge", 454 .gpio = CORGI_GPIO_LED_ORANGE, 455 }, 456 { 457 .name = "corgi:green:mail", 458 .default_trigger = "nand-disk", 459 .gpio = CORGI_GPIO_LED_GREEN, 460 }, 461}; 462 463static struct gpio_led_platform_data corgi_gpio_leds_info = { 464 .leds = corgi_gpio_leds, 465 .num_leds = ARRAY_SIZE(corgi_gpio_leds), 466}; 467 468static struct platform_device corgiled_device = { 469 .name = "leds-gpio", 470 .id = -1, 471 .dev = { 472 .platform_data = &corgi_gpio_leds_info, 473 }, 474}; 475 476/* 477 * Corgi Audio 478 */ 479static struct platform_device corgi_audio_device = { 480 .name = "corgi-audio", 481 .id = -1, 482}; 483 484/* 485 * MMC/SD Device 486 * 487 * The card detect interrupt isn't debounced so we delay it by 250ms 488 * to give the card a chance to fully insert/eject. 489 */ 490static struct pxamci_platform_data corgi_mci_platform_data = { 491 .detect_delay_ms = 250, 492 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 493}; 494 495static struct gpiod_lookup_table corgi_mci_gpio_table = { 496 .dev_id = "pxa2xx-mci.0", 497 .table = { 498 /* Card detect on GPIO 9 */ 499 GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_DETECT, 500 "cd", GPIO_ACTIVE_LOW), 501 /* Write protect on GPIO 7 */ 502 GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_WP, 503 "wp", GPIO_ACTIVE_LOW), 504 /* Power on GPIO 33 */ 505 GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_SD_PWR, 506 "power", GPIO_ACTIVE_HIGH), 507 { }, 508 }, 509}; 510 511/* 512 * Irda 513 */ 514static struct pxaficp_platform_data corgi_ficp_platform_data = { 515 .gpio_pwdown = CORGI_GPIO_IR_ON, 516 .transceiver_cap = IR_SIRMODE | IR_OFF, 517}; 518 519 520/* 521 * USB Device Controller 522 */ 523static struct pxa2xx_udc_mach_info udc_info __initdata = { 524 /* no connect GPIO; corgi can't tell connection status */ 525 .gpio_pullup = CORGI_GPIO_USB_PULLUP, 526}; 527 528#if IS_ENABLED(CONFIG_SPI_PXA2XX) 529static struct pxa2xx_spi_controller corgi_spi_info = { 530 .num_chipselect = 3, 531}; 532 533static void corgi_wait_for_hsync(void) 534{ 535 while (gpio_get_value(CORGI_GPIO_HSYNC)) 536 cpu_relax(); 537 538 while (!gpio_get_value(CORGI_GPIO_HSYNC)) 539 cpu_relax(); 540} 541 542static struct ads7846_platform_data corgi_ads7846_info = { 543 .model = 7846, 544 .vref_delay_usecs = 100, 545 .x_plate_ohms = 419, 546 .y_plate_ohms = 486, 547 .gpio_pendown = CORGI_GPIO_TP_INT, 548 .wait_for_sync = corgi_wait_for_hsync, 549}; 550 551static struct pxa2xx_spi_chip corgi_ads7846_chip = { 552 .gpio_cs = CORGI_GPIO_ADS7846_CS, 553}; 554 555static void corgi_bl_kick_battery(void) 556{ 557 void (*kick_batt)(void); 558 559 kick_batt = symbol_get(sharpsl_battery_kick); 560 if (kick_batt) { 561 kick_batt(); 562 symbol_put(sharpsl_battery_kick); 563 } 564} 565 566static struct gpiod_lookup_table corgi_lcdcon_gpio_table = { 567 .dev_id = "spi1.1", 568 .table = { 569 GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_BACKLIGHT_CONT, 570 "BL_CONT", GPIO_ACTIVE_HIGH), 571 { }, 572 }, 573}; 574 575static struct corgi_lcd_platform_data corgi_lcdcon_info = { 576 .init_mode = CORGI_LCD_MODE_VGA, 577 .max_intensity = 0x2f, 578 .default_intensity = 0x1f, 579 .limit_mask = 0x0b, 580 .kick_battery = corgi_bl_kick_battery, 581}; 582 583static struct pxa2xx_spi_chip corgi_lcdcon_chip = { 584 .gpio_cs = CORGI_GPIO_LCDCON_CS, 585}; 586 587static struct pxa2xx_spi_chip corgi_max1111_chip = { 588 .gpio_cs = CORGI_GPIO_MAX1111_CS, 589}; 590 591static struct spi_board_info corgi_spi_devices[] = { 592 { 593 .modalias = "ads7846", 594 .max_speed_hz = 1200000, 595 .bus_num = 1, 596 .chip_select = 0, 597 .platform_data = &corgi_ads7846_info, 598 .controller_data= &corgi_ads7846_chip, 599 .irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT), 600 }, { 601 .modalias = "corgi-lcd", 602 .max_speed_hz = 50000, 603 .bus_num = 1, 604 .chip_select = 1, 605 .platform_data = &corgi_lcdcon_info, 606 .controller_data= &corgi_lcdcon_chip, 607 }, { 608 .modalias = "max1111", 609 .max_speed_hz = 450000, 610 .bus_num = 1, 611 .chip_select = 2, 612 .controller_data= &corgi_max1111_chip, 613 }, 614}; 615 616static void __init corgi_init_spi(void) 617{ 618 pxa2xx_set_spi_info(1, &corgi_spi_info); 619 gpiod_add_lookup_table(&corgi_lcdcon_gpio_table); 620 spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices)); 621} 622#else 623static inline void corgi_init_spi(void) {} 624#endif 625 626static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 627 628static struct nand_bbt_descr sharpsl_bbt = { 629 .options = 0, 630 .offs = 4, 631 .len = 2, 632 .pattern = scan_ff_pattern 633}; 634 635static const char * const probes[] = { 636 "cmdlinepart", 637 "ofpart", 638 "sharpslpart", 639 NULL, 640}; 641 642static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = { 643 .badblock_pattern = &sharpsl_bbt, 644 .part_parsers = probes, 645}; 646 647static struct resource sharpsl_nand_resources[] = { 648 { 649 .start = 0x0C000000, 650 .end = 0x0C000FFF, 651 .flags = IORESOURCE_MEM, 652 }, 653}; 654 655static struct platform_device sharpsl_nand_device = { 656 .name = "sharpsl-nand", 657 .id = -1, 658 .resource = sharpsl_nand_resources, 659 .num_resources = ARRAY_SIZE(sharpsl_nand_resources), 660 .dev.platform_data = &sharpsl_nand_platform_data, 661}; 662 663static struct mtd_partition sharpsl_rom_parts[] = { 664 { 665 .name ="Boot PROM Filesystem", 666 .offset = 0x00120000, 667 .size = MTDPART_SIZ_FULL, 668 }, 669}; 670 671static struct physmap_flash_data sharpsl_rom_data = { 672 .width = 2, 673 .nr_parts = ARRAY_SIZE(sharpsl_rom_parts), 674 .parts = sharpsl_rom_parts, 675}; 676 677static struct resource sharpsl_rom_resources[] = { 678 { 679 .start = 0x00000000, 680 .end = 0x007fffff, 681 .flags = IORESOURCE_MEM, 682 }, 683}; 684 685static struct platform_device sharpsl_rom_device = { 686 .name = "physmap-flash", 687 .id = -1, 688 .resource = sharpsl_rom_resources, 689 .num_resources = ARRAY_SIZE(sharpsl_rom_resources), 690 .dev.platform_data = &sharpsl_rom_data, 691}; 692 693static struct platform_device *devices[] __initdata = { 694 &corgiscoop_device, 695 &corgifb_device, 696 &corgi_gpio_keys_device, 697 &corgikbd_device, 698 &corgiled_device, 699 &corgi_audio_device, 700 &sharpsl_nand_device, 701 &sharpsl_rom_device, 702}; 703 704static struct i2c_board_info __initdata corgi_i2c_devices[] = { 705 { I2C_BOARD_INFO("wm8731", 0x1b) }, 706}; 707 708static void corgi_poweroff(void) 709{ 710 if (!machine_is_corgi()) 711 /* Green LED off tells the bootloader to halt */ 712 gpio_set_value(CORGI_GPIO_LED_GREEN, 0); 713 714 pxa_restart(REBOOT_HARD, NULL); 715} 716 717static void corgi_restart(enum reboot_mode mode, const char *cmd) 718{ 719 if (!machine_is_corgi()) 720 /* Green LED on tells the bootloader to reboot */ 721 gpio_set_value(CORGI_GPIO_LED_GREEN, 1); 722 723 pxa_restart(REBOOT_HARD, cmd); 724} 725 726static void __init corgi_init(void) 727{ 728 pm_power_off = corgi_poweroff; 729 730 /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ 731 PCFR |= PCFR_OPDE; 732 733 pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); 734 735 /* allow wakeup from various GPIOs */ 736 gpio_set_wake(CORGI_GPIO_KEY_INT, 1); 737 gpio_set_wake(CORGI_GPIO_WAKEUP, 1); 738 gpio_set_wake(CORGI_GPIO_AC_IN, 1); 739 gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1); 740 741 if (!machine_is_corgi()) 742 gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1); 743 744 pxa_set_ffuart_info(NULL); 745 pxa_set_btuart_info(NULL); 746 pxa_set_stuart_info(NULL); 747 748 corgi_init_spi(); 749 750 pxa_set_udc_info(&udc_info); 751 gpiod_add_lookup_table(&corgi_mci_gpio_table); 752 pxa_set_mci_info(&corgi_mci_platform_data); 753 pxa_set_ficp_info(&corgi_ficp_platform_data); 754 pxa_set_i2c_info(NULL); 755 i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices)); 756 757 platform_scoop_config = &corgi_pcmcia_config; 758 759 platform_add_devices(devices, ARRAY_SIZE(devices)); 760 761 regulator_has_full_constraints(); 762} 763 764static void __init fixup_corgi(struct tag *tags, char **cmdline) 765{ 766 sharpsl_save_param(); 767 if (machine_is_corgi()) 768 memblock_add(0xa0000000, SZ_32M); 769 else 770 memblock_add(0xa0000000, SZ_64M); 771} 772 773#ifdef CONFIG_MACH_CORGI 774MACHINE_START(CORGI, "SHARP Corgi") 775 .fixup = fixup_corgi, 776 .map_io = pxa25x_map_io, 777 .nr_irqs = PXA_NR_IRQS, 778 .init_irq = pxa25x_init_irq, 779 .handle_irq = pxa25x_handle_irq, 780 .init_machine = corgi_init, 781 .init_time = pxa_timer_init, 782 .restart = corgi_restart, 783MACHINE_END 784#endif 785 786#ifdef CONFIG_MACH_SHEPHERD 787MACHINE_START(SHEPHERD, "SHARP Shepherd") 788 .fixup = fixup_corgi, 789 .map_io = pxa25x_map_io, 790 .nr_irqs = PXA_NR_IRQS, 791 .init_irq = pxa25x_init_irq, 792 .handle_irq = pxa25x_handle_irq, 793 .init_machine = corgi_init, 794 .init_time = pxa_timer_init, 795 .restart = corgi_restart, 796MACHINE_END 797#endif 798 799#ifdef CONFIG_MACH_HUSKY 800MACHINE_START(HUSKY, "SHARP Husky") 801 .fixup = fixup_corgi, 802 .map_io = pxa25x_map_io, 803 .nr_irqs = PXA_NR_IRQS, 804 .init_irq = pxa25x_init_irq, 805 .handle_irq = pxa25x_handle_irq, 806 .init_machine = corgi_init, 807 .init_time = pxa_timer_init, 808 .restart = corgi_restart, 809MACHINE_END 810#endif 811 812