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