Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Support for Sharp SL-C7xx PDAs
0004  * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky)
0005  *
0006  * Copyright (c) 2004-2005 Richard Purdie
0007  *
0008  * Based on Sharp's 2.4 kernel patches/lubbock.c
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>   /* symbol_get ; symbol_put */
0013 #include <linux/init.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/major.h>
0016 #include <linux/fs.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/leds.h>
0019 #include <linux/mmc/host.h>
0020 #include <linux/mtd/physmap.h>
0021 #include <linux/pm.h>
0022 #include <linux/gpio.h>
0023 #include <linux/gpio/machine.h>
0024 #include <linux/backlight.h>
0025 #include <linux/i2c.h>
0026 #include <linux/platform_data/i2c-pxa.h>
0027 #include <linux/io.h>
0028 #include <linux/regulator/machine.h>
0029 #include <linux/spi/spi.h>
0030 #include <linux/spi/ads7846.h>
0031 #include <linux/spi/corgi_lcd.h>
0032 #include <linux/spi/pxa2xx_spi.h>
0033 #include <linux/mtd/sharpsl.h>
0034 #include <linux/input/matrix_keypad.h>
0035 #include <linux/gpio_keys.h>
0036 #include <linux/memblock.h>
0037 #include <video/w100fb.h>
0038 
0039 #include <asm/setup.h>
0040 #include <asm/memory.h>
0041 #include <asm/mach-types.h>
0042 #include <asm/irq.h>
0043 
0044 #include <asm/mach/arch.h>
0045 #include <asm/mach/map.h>
0046 #include <asm/mach/irq.h>
0047 
0048 #include "pxa25x.h"
0049 #include <linux/platform_data/irda-pxaficp.h>
0050 #include <linux/platform_data/mmc-pxamci.h>
0051 #include "udc.h"
0052 #include "corgi.h"
0053 #include "sharpsl_pm.h"
0054 
0055 #include <asm/mach/sharpsl_param.h>
0056 #include <asm/hardware/scoop.h>
0057 
0058 #include "generic.h"
0059 #include "devices.h"
0060 
0061 static unsigned long corgi_pin_config[] __initdata = {
0062     /* Static Memory I/O */
0063     GPIO78_nCS_2,   /* w100fb */
0064     GPIO80_nCS_4,   /* scoop */
0065 
0066     /* SSP1 */
0067     GPIO23_SSP1_SCLK,
0068     GPIO25_SSP1_TXD,
0069     GPIO26_SSP1_RXD,
0070     GPIO24_GPIO,    /* CORGI_GPIO_ADS7846_CS - SFRM as chip select */
0071 
0072     /* I2S */
0073     GPIO28_I2S_BITCLK_OUT,
0074     GPIO29_I2S_SDATA_IN,
0075     GPIO30_I2S_SDATA_OUT,
0076     GPIO31_I2S_SYNC,
0077     GPIO32_I2S_SYSCLK,
0078 
0079     /* Infra-Red */
0080     GPIO47_FICP_TXD,
0081     GPIO46_FICP_RXD,
0082 
0083     /* FFUART */
0084     GPIO40_FFUART_DTR,
0085     GPIO41_FFUART_RTS,
0086     GPIO39_FFUART_TXD,
0087     GPIO37_FFUART_DSR,
0088     GPIO34_FFUART_RXD,
0089     GPIO35_FFUART_CTS,
0090 
0091     /* PC Card */
0092     GPIO48_nPOE,
0093     GPIO49_nPWE,
0094     GPIO50_nPIOR,
0095     GPIO51_nPIOW,
0096     GPIO52_nPCE_1,
0097     GPIO53_nPCE_2,
0098     GPIO54_nPSKTSEL,
0099     GPIO55_nPREG,
0100     GPIO56_nPWAIT,
0101     GPIO57_nIOIS16,
0102 
0103     /* MMC */
0104     GPIO6_MMC_CLK,
0105     GPIO8_MMC_CS0,
0106 
0107     /* GPIO Matrix Keypad */
0108     GPIO66_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 0 */
0109     GPIO67_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 1 */
0110     GPIO68_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 2 */
0111     GPIO69_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 3 */
0112     GPIO70_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 4 */
0113     GPIO71_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 5 */
0114     GPIO72_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 6 */
0115     GPIO73_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 7 */
0116     GPIO74_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 8 */
0117     GPIO75_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 9 */
0118     GPIO76_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 10 */
0119     GPIO77_GPIO | MFP_LPM_DRIVE_HIGH,   /* column 11 */
0120     GPIO58_GPIO,    /* row 0 */
0121     GPIO59_GPIO,    /* row 1 */
0122     GPIO60_GPIO,    /* row 2 */
0123     GPIO61_GPIO,    /* row 3 */
0124     GPIO62_GPIO,    /* row 4 */
0125     GPIO63_GPIO,    /* row 5 */
0126     GPIO64_GPIO,    /* row 6 */
0127     GPIO65_GPIO,    /* row 7 */
0128 
0129     /* GPIO */
0130     GPIO9_GPIO,             /* CORGI_GPIO_nSD_DETECT */
0131     GPIO7_GPIO,             /* CORGI_GPIO_nSD_WP */
0132     GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,  /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */
0133     GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT,  /* CORGI_GPIO_LED_ORANGE */
0134     GPIO21_GPIO,                /* CORGI_GPIO_ADC_TEMP */
0135     GPIO22_GPIO,                /* CORGI_GPIO_IR_ON */
0136     GPIO33_GPIO,                /* CORGI_GPIO_SD_PWR */
0137     GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT,  /* CORGI_GPIO_CHRG_ON */
0138     GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT,  /* CORGI_GPIO_CHRG_UKN */
0139     GPIO44_GPIO,                /* CORGI_GPIO_HSYNC */
0140 
0141     GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,   /* CORGI_GPIO_KEY_INT */
0142     GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,   /* CORGI_GPIO_AC_IN */
0143     GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,   /* CORGI_GPIO_WAKEUP */
0144 };
0145 
0146 /*
0147  * Corgi SCOOP Device
0148  */
0149 static struct resource corgi_scoop_resources[] = {
0150     [0] = {
0151         .start      = 0x10800000,
0152         .end        = 0x10800fff,
0153         .flags      = IORESOURCE_MEM,
0154     },
0155 };
0156 
0157 static struct scoop_config corgi_scoop_setup = {
0158     .io_dir     = CORGI_SCOOP_IO_DIR,
0159     .io_out     = CORGI_SCOOP_IO_OUT,
0160     .gpio_base  = CORGI_SCOOP_GPIO_BASE,
0161 };
0162 
0163 struct platform_device corgiscoop_device = {
0164     .name       = "sharp-scoop",
0165     .id     = -1,
0166     .dev        = {
0167         .platform_data  = &corgi_scoop_setup,
0168     },
0169     .num_resources  = ARRAY_SIZE(corgi_scoop_resources),
0170     .resource   = corgi_scoop_resources,
0171 };
0172 
0173 static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
0174 {
0175     .dev        = &corgiscoop_device.dev,
0176     .irq        = CORGI_IRQ_GPIO_CF_IRQ,
0177     .cd_irq     = CORGI_IRQ_GPIO_CF_CD,
0178     .cd_irq_str = "PCMCIA0 CD",
0179 },
0180 };
0181 
0182 static struct scoop_pcmcia_config corgi_pcmcia_config = {
0183     .devs         = &corgi_pcmcia_scoop[0],
0184     .num_devs     = 1,
0185 };
0186 
0187 static struct w100_mem_info corgi_fb_mem = {
0188     .ext_cntl          = 0x00040003,
0189     .sdram_mode_reg    = 0x00650021,
0190     .ext_timing_cntl   = 0x10002a4a,
0191     .io_cntl           = 0x7ff87012,
0192     .size              = 0x1fffff,
0193 };
0194 
0195 static struct w100_gen_regs corgi_fb_regs = {
0196     .lcd_format    = 0x00000003,
0197     .lcdd_cntl1    = 0x01CC0000,
0198     .lcdd_cntl2    = 0x0003FFFF,
0199     .genlcd_cntl1  = 0x00FFFF0D,
0200     .genlcd_cntl2  = 0x003F3003,
0201     .genlcd_cntl3  = 0x000102aa,
0202 };
0203 
0204 static struct w100_gpio_regs corgi_fb_gpio = {
0205     .init_data1   = 0x000000bf,
0206     .init_data2   = 0x00000000,
0207     .gpio_dir1    = 0x00000000,
0208     .gpio_oe1     = 0x03c0feff,
0209     .gpio_dir2    = 0x00000000,
0210     .gpio_oe2     = 0x00000000,
0211 };
0212 
0213 static struct w100_mode corgi_fb_modes[] = {
0214 {
0215     .xres            = 480,
0216     .yres            = 640,
0217     .left_margin     = 0x56,
0218     .right_margin    = 0x55,
0219     .upper_margin    = 0x03,
0220     .lower_margin    = 0x00,
0221     .crtc_ss         = 0x82360056,
0222     .crtc_ls         = 0xA0280000,
0223     .crtc_gs         = 0x80280028,
0224     .crtc_vpos_gs    = 0x02830002,
0225     .crtc_rev        = 0x00400008,
0226     .crtc_dclk       = 0xA0000000,
0227     .crtc_gclk       = 0x8015010F,
0228     .crtc_goe        = 0x80100110,
0229     .crtc_ps1_active = 0x41060010,
0230     .pll_freq        = 75,
0231     .fast_pll_freq   = 100,
0232     .sysclk_src      = CLK_SRC_PLL,
0233     .sysclk_divider  = 0,
0234     .pixclk_src      = CLK_SRC_PLL,
0235     .pixclk_divider  = 2,
0236     .pixclk_divider_rotated = 6,
0237 },{
0238     .xres            = 240,
0239     .yres            = 320,
0240     .left_margin     = 0x27,
0241     .right_margin    = 0x2e,
0242     .upper_margin    = 0x01,
0243     .lower_margin    = 0x00,
0244     .crtc_ss         = 0x81170027,
0245     .crtc_ls         = 0xA0140000,
0246     .crtc_gs         = 0xC0140014,
0247     .crtc_vpos_gs    = 0x00010141,
0248     .crtc_rev        = 0x00400008,
0249     .crtc_dclk       = 0xA0000000,
0250     .crtc_gclk       = 0x8015010F,
0251     .crtc_goe        = 0x80100110,
0252     .crtc_ps1_active = 0x41060010,
0253     .pll_freq        = 0,
0254     .fast_pll_freq   = 0,
0255     .sysclk_src      = CLK_SRC_XTAL,
0256     .sysclk_divider  = 0,
0257     .pixclk_src      = CLK_SRC_XTAL,
0258     .pixclk_divider  = 1,
0259     .pixclk_divider_rotated = 1,
0260 },
0261 
0262 };
0263 
0264 static struct w100fb_mach_info corgi_fb_info = {
0265     .init_mode  = INIT_MODE_ROTATED,
0266     .mem        = &corgi_fb_mem,
0267     .regs       = &corgi_fb_regs,
0268     .modelist   = &corgi_fb_modes[0],
0269     .num_modes  = 2,
0270     .gpio       = &corgi_fb_gpio,
0271     .xtal_freq  = 12500000,
0272     .xtal_dbl   = 0,
0273 };
0274 
0275 static struct resource corgi_fb_resources[] = {
0276     [0] = {
0277         .start   = 0x08000000,
0278         .end     = 0x08ffffff,
0279         .flags   = IORESOURCE_MEM,
0280     },
0281 };
0282 
0283 static struct platform_device corgifb_device = {
0284     .name           = "w100fb",
0285     .id             = -1,
0286     .num_resources  = ARRAY_SIZE(corgi_fb_resources),
0287     .resource   = corgi_fb_resources,
0288     .dev            = {
0289         .platform_data = &corgi_fb_info,
0290     },
0291 
0292 };
0293 
0294 /*
0295  * Corgi Keyboard Device
0296  */
0297 #define CORGI_KEY_CALENDER  KEY_F1
0298 #define CORGI_KEY_ADDRESS   KEY_F2
0299 #define CORGI_KEY_FN        KEY_F3
0300 #define CORGI_KEY_CANCEL    KEY_F4
0301 #define CORGI_KEY_OFF       KEY_SUSPEND
0302 #define CORGI_KEY_EXOK      KEY_F5
0303 #define CORGI_KEY_EXCANCEL  KEY_F6
0304 #define CORGI_KEY_EXJOGDOWN KEY_F7
0305 #define CORGI_KEY_EXJOGUP   KEY_F8
0306 #define CORGI_KEY_JAP1      KEY_LEFTCTRL
0307 #define CORGI_KEY_JAP2      KEY_LEFTALT
0308 #define CORGI_KEY_MAIL      KEY_F10
0309 #define CORGI_KEY_OK        KEY_F11
0310 #define CORGI_KEY_MENU      KEY_F12
0311 
0312 static const uint32_t corgikbd_keymap[] = {
0313     KEY(0, 1, KEY_1),
0314     KEY(0, 2, KEY_3),
0315     KEY(0, 3, KEY_5),
0316     KEY(0, 4, KEY_6),
0317     KEY(0, 5, KEY_7),
0318     KEY(0, 6, KEY_9),
0319     KEY(0, 7, KEY_0),
0320     KEY(0, 8, KEY_BACKSPACE),
0321     KEY(1, 1, KEY_2),
0322     KEY(1, 2, KEY_4),
0323     KEY(1, 3, KEY_R),
0324     KEY(1, 4, KEY_Y),
0325     KEY(1, 5, KEY_8),
0326     KEY(1, 6, KEY_I),
0327     KEY(1, 7, KEY_O),
0328     KEY(1, 8, KEY_P),
0329     KEY(2, 0, KEY_TAB),
0330     KEY(2, 1, KEY_Q),
0331     KEY(2, 2, KEY_E),
0332     KEY(2, 3, KEY_T),
0333     KEY(2, 4, KEY_G),
0334     KEY(2, 5, KEY_U),
0335     KEY(2, 6, KEY_J),
0336     KEY(2, 7, KEY_K),
0337     KEY(3, 0, CORGI_KEY_CALENDER),
0338     KEY(3, 1, KEY_W),
0339     KEY(3, 2, KEY_S),
0340     KEY(3, 3, KEY_F),
0341     KEY(3, 4, KEY_V),
0342     KEY(3, 5, KEY_H),
0343     KEY(3, 6, KEY_M),
0344     KEY(3, 7, KEY_L),
0345     KEY(3, 9, KEY_RIGHTSHIFT),
0346     KEY(4, 0, CORGI_KEY_ADDRESS),
0347     KEY(4, 1, KEY_A),
0348     KEY(4, 2, KEY_D),
0349     KEY(4, 3, KEY_C),
0350     KEY(4, 4, KEY_B),
0351     KEY(4, 5, KEY_N),
0352     KEY(4, 6, KEY_DOT),
0353     KEY(4, 8, KEY_ENTER),
0354     KEY(4, 10, KEY_LEFTSHIFT),
0355     KEY(5, 0, CORGI_KEY_MAIL),
0356     KEY(5, 1, KEY_Z),
0357     KEY(5, 2, KEY_X),
0358     KEY(5, 3, KEY_MINUS),
0359     KEY(5, 4, KEY_SPACE),
0360     KEY(5, 5, KEY_COMMA),
0361     KEY(5, 7, KEY_UP),
0362     KEY(5, 11, CORGI_KEY_FN),
0363     KEY(6, 0, KEY_SYSRQ),
0364     KEY(6, 1, CORGI_KEY_JAP1),
0365     KEY(6, 2, CORGI_KEY_JAP2),
0366     KEY(6, 3, CORGI_KEY_CANCEL),
0367     KEY(6, 4, CORGI_KEY_OK),
0368     KEY(6, 5, CORGI_KEY_MENU),
0369     KEY(6, 6, KEY_LEFT),
0370     KEY(6, 7, KEY_DOWN),
0371     KEY(6, 8, KEY_RIGHT),
0372     KEY(7, 0, CORGI_KEY_OFF),
0373     KEY(7, 1, CORGI_KEY_EXOK),
0374     KEY(7, 2, CORGI_KEY_EXCANCEL),
0375     KEY(7, 3, CORGI_KEY_EXJOGDOWN),
0376     KEY(7, 4, CORGI_KEY_EXJOGUP),
0377 };
0378 
0379 static struct matrix_keymap_data corgikbd_keymap_data = {
0380     .keymap     = corgikbd_keymap,
0381     .keymap_size    = ARRAY_SIZE(corgikbd_keymap),
0382 };
0383 
0384 static const int corgikbd_row_gpios[] =
0385         { 58, 59, 60, 61, 62, 63, 64, 65 };
0386 static const int corgikbd_col_gpios[] =
0387         { 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 };
0388 
0389 static struct matrix_keypad_platform_data corgikbd_pdata = {
0390     .keymap_data        = &corgikbd_keymap_data,
0391     .row_gpios      = corgikbd_row_gpios,
0392     .col_gpios      = corgikbd_col_gpios,
0393     .num_row_gpios      = ARRAY_SIZE(corgikbd_row_gpios),
0394     .num_col_gpios      = ARRAY_SIZE(corgikbd_col_gpios),
0395     .col_scan_delay_us  = 10,
0396     .debounce_ms        = 10,
0397     .wakeup         = 1,
0398 };
0399 
0400 static struct platform_device corgikbd_device = {
0401     .name       = "matrix-keypad",
0402     .id     = -1,
0403     .dev        = {
0404         .platform_data = &corgikbd_pdata,
0405     },
0406 };
0407 
0408 static struct gpio_keys_button corgi_gpio_keys[] = {
0409     {
0410         .type   = EV_SW,
0411         .code   = SW_LID,
0412         .gpio   = CORGI_GPIO_SWA,
0413         .desc   = "Lid close switch",
0414         .debounce_interval = 500,
0415     },
0416     {
0417         .type   = EV_SW,
0418         .code   = SW_TABLET_MODE,
0419         .gpio   = CORGI_GPIO_SWB,
0420         .desc   = "Tablet mode switch",
0421         .debounce_interval = 500,
0422     },
0423     {
0424         .type   = EV_SW,
0425         .code   = SW_HEADPHONE_INSERT,
0426         .gpio   = CORGI_GPIO_AK_INT,
0427         .desc   = "HeadPhone insert",
0428         .debounce_interval = 500,
0429     },
0430 };
0431 
0432 static struct gpio_keys_platform_data corgi_gpio_keys_platform_data = {
0433     .buttons    = corgi_gpio_keys,
0434     .nbuttons   = ARRAY_SIZE(corgi_gpio_keys),
0435     .poll_interval  = 250,
0436 };
0437 
0438 static struct platform_device corgi_gpio_keys_device = {
0439     .name   = "gpio-keys-polled",
0440     .id = -1,
0441     .dev    = {
0442         .platform_data  = &corgi_gpio_keys_platform_data,
0443     },
0444 };
0445 
0446 /*
0447  * Corgi LEDs
0448  */
0449 static struct gpio_led corgi_gpio_leds[] = {
0450     {
0451         .name           = "corgi:amber:charge",
0452         .default_trigger    = "sharpsl-charge",
0453         .gpio           = CORGI_GPIO_LED_ORANGE,
0454     },
0455     {
0456         .name           = "corgi:green:mail",
0457         .default_trigger    = "nand-disk",
0458         .gpio           = CORGI_GPIO_LED_GREEN,
0459     },
0460 };
0461 
0462 static struct gpio_led_platform_data corgi_gpio_leds_info = {
0463     .leds       = corgi_gpio_leds,
0464     .num_leds   = ARRAY_SIZE(corgi_gpio_leds),
0465 };
0466 
0467 static struct platform_device corgiled_device = {
0468     .name       = "leds-gpio",
0469     .id     = -1,
0470     .dev        = {
0471         .platform_data = &corgi_gpio_leds_info,
0472     },
0473 };
0474 
0475 static struct gpiod_lookup_table corgi_audio_gpio_table = {
0476     .dev_id = "corgi-audio",
0477     .table = {
0478         GPIO_LOOKUP("sharp-scoop",
0479                 CORGI_GPIO_MUTE_L - CORGI_SCOOP_GPIO_BASE,
0480                 "mute-l", GPIO_ACTIVE_HIGH),
0481         GPIO_LOOKUP("sharp-scoop",
0482                 CORGI_GPIO_MUTE_R - CORGI_SCOOP_GPIO_BASE,
0483                 "mute-r", GPIO_ACTIVE_HIGH),
0484         GPIO_LOOKUP("sharp-scoop",
0485                 CORGI_GPIO_APM_ON - CORGI_SCOOP_GPIO_BASE,
0486                 "apm-on", GPIO_ACTIVE_HIGH),
0487         GPIO_LOOKUP("sharp-scoop",
0488                 CORGI_GPIO_MIC_BIAS - CORGI_SCOOP_GPIO_BASE,
0489                 "mic-bias", GPIO_ACTIVE_HIGH),
0490         { },
0491     },
0492 };
0493 
0494 /*
0495  * Corgi Audio
0496  */
0497 static struct platform_device corgi_audio_device = {
0498     .name   = "corgi-audio",
0499     .id = -1,
0500 };
0501 
0502 /*
0503  * MMC/SD Device
0504  *
0505  * The card detect interrupt isn't debounced so we delay it by 250ms
0506  * to give the card a chance to fully insert/eject.
0507  */
0508 static struct pxamci_platform_data corgi_mci_platform_data = {
0509     .detect_delay_ms    = 250,
0510     .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
0511 };
0512 
0513 static struct gpiod_lookup_table corgi_mci_gpio_table = {
0514     .dev_id = "pxa2xx-mci.0",
0515     .table = {
0516         /* Card detect on GPIO 9 */
0517         GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_DETECT,
0518                 "cd", GPIO_ACTIVE_LOW),
0519         /* Write protect on GPIO 7 */
0520         GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_nSD_WP,
0521                 "wp", GPIO_ACTIVE_LOW),
0522         /* Power on GPIO 33 */
0523         GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_SD_PWR,
0524                 "power", GPIO_ACTIVE_HIGH),
0525         { },
0526     },
0527 };
0528 
0529 /*
0530  * Irda
0531  */
0532 static struct pxaficp_platform_data corgi_ficp_platform_data = {
0533     .gpio_pwdown        = CORGI_GPIO_IR_ON,
0534     .transceiver_cap    = IR_SIRMODE | IR_OFF,
0535 };
0536 
0537 
0538 /*
0539  * USB Device Controller
0540  */
0541 static struct pxa2xx_udc_mach_info udc_info __initdata = {
0542     /* no connect GPIO; corgi can't tell connection status */
0543     .gpio_pullup        = CORGI_GPIO_USB_PULLUP,
0544 };
0545 
0546 #if IS_ENABLED(CONFIG_SPI_PXA2XX)
0547 static struct pxa2xx_spi_controller corgi_spi_info = {
0548     .num_chipselect = 3,
0549 };
0550 
0551 static struct gpiod_lookup_table corgi_spi_gpio_table = {
0552     .dev_id = "spi1",
0553     .table = {
0554         GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
0555         GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
0556         GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
0557         { },
0558     },
0559 };
0560 
0561 static void corgi_wait_for_hsync(void)
0562 {
0563     while (gpio_get_value(CORGI_GPIO_HSYNC))
0564         cpu_relax();
0565 
0566     while (!gpio_get_value(CORGI_GPIO_HSYNC))
0567         cpu_relax();
0568 }
0569 
0570 static struct ads7846_platform_data corgi_ads7846_info = {
0571     .model          = 7846,
0572     .vref_delay_usecs   = 100,
0573     .x_plate_ohms       = 419,
0574     .y_plate_ohms       = 486,
0575     .gpio_pendown       = CORGI_GPIO_TP_INT,
0576     .wait_for_sync      = corgi_wait_for_hsync,
0577 };
0578 
0579 static void corgi_bl_kick_battery(void)
0580 {
0581     void (*kick_batt)(void);
0582 
0583     kick_batt = symbol_get(sharpsl_battery_kick);
0584     if (kick_batt) {
0585         kick_batt();
0586         symbol_put(sharpsl_battery_kick);
0587     }
0588 }
0589 
0590 static struct gpiod_lookup_table corgi_lcdcon_gpio_table = {
0591     .dev_id = "spi1.1",
0592     .table = {
0593         GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_BACKLIGHT_CONT,
0594                 "BL_CONT", GPIO_ACTIVE_HIGH),
0595         { },
0596     },
0597 };
0598 
0599 static struct corgi_lcd_platform_data corgi_lcdcon_info = {
0600     .init_mode      = CORGI_LCD_MODE_VGA,
0601     .max_intensity      = 0x2f,
0602     .default_intensity  = 0x1f,
0603     .limit_mask     = 0x0b,
0604     .kick_battery       = corgi_bl_kick_battery,
0605 };
0606 
0607 static struct spi_board_info corgi_spi_devices[] = {
0608     {
0609         .modalias   = "ads7846",
0610         .max_speed_hz   = 1200000,
0611         .bus_num    = 1,
0612         .chip_select    = 0,
0613         .platform_data  = &corgi_ads7846_info,
0614         .irq        = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
0615     }, {
0616         .modalias   = "corgi-lcd",
0617         .max_speed_hz   = 50000,
0618         .bus_num    = 1,
0619         .chip_select    = 1,
0620         .platform_data  = &corgi_lcdcon_info,
0621     }, {
0622         .modalias   = "max1111",
0623         .max_speed_hz   = 450000,
0624         .bus_num    = 1,
0625         .chip_select    = 2,
0626     },
0627 };
0628 
0629 static void __init corgi_init_spi(void)
0630 {
0631     gpiod_add_lookup_table(&corgi_spi_gpio_table);
0632     pxa2xx_set_spi_info(1, &corgi_spi_info);
0633     gpiod_add_lookup_table(&corgi_lcdcon_gpio_table);
0634     spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
0635 }
0636 #else
0637 static inline void corgi_init_spi(void) {}
0638 #endif
0639 
0640 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
0641 
0642 static struct nand_bbt_descr sharpsl_bbt = {
0643     .options = 0,
0644     .offs = 4,
0645     .len = 2,
0646     .pattern = scan_ff_pattern
0647 };
0648 
0649 static const char * const probes[] = {
0650     "cmdlinepart",
0651     "ofpart",
0652     "sharpslpart",
0653     NULL,
0654 };
0655 
0656 static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
0657     .badblock_pattern   = &sharpsl_bbt,
0658     .part_parsers       = probes,
0659 };
0660 
0661 static struct resource sharpsl_nand_resources[] = {
0662     {
0663         .start  = 0x0C000000,
0664         .end    = 0x0C000FFF,
0665         .flags  = IORESOURCE_MEM,
0666     },
0667 };
0668 
0669 static struct platform_device sharpsl_nand_device = {
0670     .name       = "sharpsl-nand",
0671     .id     = -1,
0672     .resource   = sharpsl_nand_resources,
0673     .num_resources  = ARRAY_SIZE(sharpsl_nand_resources),
0674     .dev.platform_data  = &sharpsl_nand_platform_data,
0675 };
0676 
0677 static struct mtd_partition sharpsl_rom_parts[] = {
0678     {
0679         .name   ="Boot PROM Filesystem",
0680         .offset = 0x00120000,
0681         .size   = MTDPART_SIZ_FULL,
0682     },
0683 };
0684 
0685 static struct physmap_flash_data sharpsl_rom_data = {
0686     .width      = 2,
0687     .nr_parts   = ARRAY_SIZE(sharpsl_rom_parts),
0688     .parts      = sharpsl_rom_parts,
0689 };
0690 
0691 static struct resource sharpsl_rom_resources[] = {
0692     {
0693         .start  = 0x00000000,
0694         .end    = 0x007fffff,
0695         .flags  = IORESOURCE_MEM,
0696     },
0697 };
0698 
0699 static struct platform_device sharpsl_rom_device = {
0700     .name   = "physmap-flash",
0701     .id = -1,
0702     .resource = sharpsl_rom_resources,
0703     .num_resources = ARRAY_SIZE(sharpsl_rom_resources),
0704     .dev.platform_data = &sharpsl_rom_data,
0705 };
0706 
0707 static struct platform_device *devices[] __initdata = {
0708     &corgiscoop_device,
0709     &corgifb_device,
0710     &corgi_gpio_keys_device,
0711     &corgikbd_device,
0712     &corgiled_device,
0713     &corgi_audio_device,
0714     &sharpsl_nand_device,
0715     &sharpsl_rom_device,
0716 };
0717 
0718 static struct i2c_board_info __initdata corgi_i2c_devices[] = {
0719     { I2C_BOARD_INFO("wm8731", 0x1b) },
0720 };
0721 
0722 static void corgi_poweroff(void)
0723 {
0724     if (!machine_is_corgi())
0725         /* Green LED off tells the bootloader to halt */
0726         gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
0727 
0728     pxa_restart(REBOOT_HARD, NULL);
0729 }
0730 
0731 static void corgi_restart(enum reboot_mode mode, const char *cmd)
0732 {
0733     if (!machine_is_corgi())
0734         /* Green LED on tells the bootloader to reboot */
0735         gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
0736 
0737     pxa_restart(REBOOT_HARD, cmd);
0738 }
0739 
0740 static void __init corgi_init(void)
0741 {
0742     pm_power_off = corgi_poweroff;
0743 
0744     /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
0745     PCFR |= PCFR_OPDE;
0746 
0747     pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
0748 
0749     /* allow wakeup from various GPIOs */
0750     gpio_set_wake(CORGI_GPIO_KEY_INT, 1);
0751     gpio_set_wake(CORGI_GPIO_WAKEUP, 1);
0752     gpio_set_wake(CORGI_GPIO_AC_IN, 1);
0753     gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1);
0754 
0755     if (!machine_is_corgi())
0756         gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1);
0757 
0758     pxa_set_ffuart_info(NULL);
0759     pxa_set_btuart_info(NULL);
0760     pxa_set_stuart_info(NULL);
0761 
0762     corgi_init_spi();
0763 
0764     pxa_set_udc_info(&udc_info);
0765     gpiod_add_lookup_table(&corgi_mci_gpio_table);
0766     gpiod_add_lookup_table(&corgi_audio_gpio_table);
0767     pxa_set_mci_info(&corgi_mci_platform_data);
0768     pxa_set_ficp_info(&corgi_ficp_platform_data);
0769     pxa_set_i2c_info(NULL);
0770     i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices));
0771 
0772     platform_scoop_config = &corgi_pcmcia_config;
0773 
0774     platform_add_devices(devices, ARRAY_SIZE(devices));
0775 
0776     regulator_has_full_constraints();
0777 }
0778 
0779 static void __init fixup_corgi(struct tag *tags, char **cmdline)
0780 {
0781     sharpsl_save_param();
0782     if (machine_is_corgi())
0783         memblock_add(0xa0000000, SZ_32M);
0784     else
0785         memblock_add(0xa0000000, SZ_64M);
0786 }
0787 
0788 #ifdef CONFIG_MACH_CORGI
0789 MACHINE_START(CORGI, "SHARP Corgi")
0790     .fixup      = fixup_corgi,
0791     .map_io     = pxa25x_map_io,
0792     .nr_irqs    = PXA_NR_IRQS,
0793     .init_irq   = pxa25x_init_irq,
0794     .handle_irq = pxa25x_handle_irq,
0795     .init_machine   = corgi_init,
0796     .init_time  = pxa_timer_init,
0797     .restart    = corgi_restart,
0798 MACHINE_END
0799 #endif
0800 
0801 #ifdef CONFIG_MACH_SHEPHERD
0802 MACHINE_START(SHEPHERD, "SHARP Shepherd")
0803     .fixup      = fixup_corgi,
0804     .map_io     = pxa25x_map_io,
0805     .nr_irqs    = PXA_NR_IRQS,
0806     .init_irq   = pxa25x_init_irq,
0807     .handle_irq = pxa25x_handle_irq,
0808     .init_machine   = corgi_init,
0809     .init_time  = pxa_timer_init,
0810     .restart    = corgi_restart,
0811 MACHINE_END
0812 #endif
0813 
0814 #ifdef CONFIG_MACH_HUSKY
0815 MACHINE_START(HUSKY, "SHARP Husky")
0816     .fixup      = fixup_corgi,
0817     .map_io     = pxa25x_map_io,
0818     .nr_irqs    = PXA_NR_IRQS,
0819     .init_irq   = pxa25x_init_irq,
0820     .handle_irq = pxa25x_handle_irq,
0821     .init_machine   = corgi_init,
0822     .init_time  = pxa_timer_init,
0823     .restart    = corgi_restart,
0824 MACHINE_END
0825 #endif
0826