diff options
Diffstat (limited to 'arch/arm/mach-pxa/spitz.c')
| -rw-r--r-- | arch/arm/mach-pxa/spitz.c | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c new file mode 100644 index 000000000000..568afe3d6e1a --- /dev/null +++ b/arch/arm/mach-pxa/spitz.c | |||
| @@ -0,0 +1,380 @@ | |||
| 1 | /* | ||
| 2 | * Support for Sharp SL-Cxx00 Series of PDAs | ||
| 3 | * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi) | ||
| 4 | * | ||
| 5 | * Copyright (c) 2005 Richard Purdie | ||
| 6 | * | ||
| 7 | * Based on Sharp's 2.4 kernel patches/lubbock.c | ||
| 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/device.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/major.h> | ||
| 20 | #include <linux/fs.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/mmc/host.h> | ||
| 23 | |||
| 24 | #include <asm/setup.h> | ||
| 25 | #include <asm/memory.h> | ||
| 26 | #include <asm/mach-types.h> | ||
| 27 | #include <asm/hardware.h> | ||
| 28 | #include <asm/irq.h> | ||
| 29 | #include <asm/io.h> | ||
| 30 | |||
| 31 | #include <asm/mach/arch.h> | ||
| 32 | #include <asm/mach/map.h> | ||
| 33 | #include <asm/mach/irq.h> | ||
| 34 | |||
| 35 | #include <asm/arch/pxa-regs.h> | ||
| 36 | #include <asm/arch/irq.h> | ||
| 37 | #include <asm/arch/mmc.h> | ||
| 38 | #include <asm/arch/udc.h> | ||
| 39 | #include <asm/arch/ohci.h> | ||
| 40 | #include <asm/arch/pxafb.h> | ||
| 41 | #include <asm/arch/akita.h> | ||
| 42 | #include <asm/arch/spitz.h> | ||
| 43 | #include <asm/arch/sharpsl.h> | ||
| 44 | |||
| 45 | #include <asm/mach/sharpsl_param.h> | ||
| 46 | #include <asm/hardware/scoop.h> | ||
| 47 | |||
| 48 | #include "generic.h" | ||
| 49 | #include "sharpsl.h" | ||
| 50 | |||
| 51 | /* | ||
| 52 | * Spitz SCOOP Device #1 | ||
| 53 | */ | ||
| 54 | static struct resource spitz_scoop_resources[] = { | ||
| 55 | [0] = { | ||
| 56 | .start = 0x10800000, | ||
| 57 | .end = 0x10800fff, | ||
| 58 | .flags = IORESOURCE_MEM, | ||
| 59 | }, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static struct scoop_config spitz_scoop_setup = { | ||
| 63 | .io_dir = SPITZ_SCP_IO_DIR, | ||
| 64 | .io_out = SPITZ_SCP_IO_OUT, | ||
| 65 | .suspend_clr = SPITZ_SCP_SUS_CLR, | ||
| 66 | .suspend_set = SPITZ_SCP_SUS_SET, | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct platform_device spitzscoop_device = { | ||
| 70 | .name = "sharp-scoop", | ||
| 71 | .id = 0, | ||
| 72 | .dev = { | ||
| 73 | .platform_data = &spitz_scoop_setup, | ||
| 74 | }, | ||
| 75 | .num_resources = ARRAY_SIZE(spitz_scoop_resources), | ||
| 76 | .resource = spitz_scoop_resources, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Spitz SCOOP Device #2 | ||
| 81 | */ | ||
| 82 | static struct resource spitz_scoop2_resources[] = { | ||
| 83 | [0] = { | ||
| 84 | .start = 0x08800040, | ||
| 85 | .end = 0x08800fff, | ||
| 86 | .flags = IORESOURCE_MEM, | ||
| 87 | }, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static struct scoop_config spitz_scoop2_setup = { | ||
| 91 | .io_dir = SPITZ_SCP2_IO_DIR, | ||
| 92 | .io_out = SPITZ_SCP2_IO_OUT, | ||
| 93 | .suspend_clr = SPITZ_SCP2_SUS_CLR, | ||
| 94 | .suspend_set = SPITZ_SCP2_SUS_SET, | ||
| 95 | }; | ||
| 96 | |||
| 97 | struct platform_device spitzscoop2_device = { | ||
| 98 | .name = "sharp-scoop", | ||
| 99 | .id = 1, | ||
| 100 | .dev = { | ||
| 101 | .platform_data = &spitz_scoop2_setup, | ||
| 102 | }, | ||
| 103 | .num_resources = ARRAY_SIZE(spitz_scoop2_resources), | ||
| 104 | .resource = spitz_scoop2_resources, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { | ||
| 108 | { | ||
| 109 | .dev = &spitzscoop_device.dev, | ||
| 110 | .irq = SPITZ_IRQ_GPIO_CF_IRQ, | ||
| 111 | .cd_irq = SPITZ_IRQ_GPIO_CF_CD, | ||
| 112 | .cd_irq_str = "PCMCIA0 CD", | ||
| 113 | },{ | ||
| 114 | .dev = &spitzscoop2_device.dev, | ||
| 115 | .irq = SPITZ_IRQ_GPIO_CF2_IRQ, | ||
| 116 | .cd_irq = -1, | ||
| 117 | }, | ||
| 118 | }; | ||
| 119 | |||
| 120 | |||
| 121 | /* | ||
| 122 | * Spitz SSP Device | ||
| 123 | * | ||
| 124 | * Set the parent as the scoop device because a lot of SSP devices | ||
| 125 | * also use scoop functions and this makes the power up/down order | ||
| 126 | * work correctly. | ||
| 127 | */ | ||
| 128 | struct platform_device spitzssp_device = { | ||
| 129 | .name = "corgi-ssp", | ||
| 130 | .dev = { | ||
| 131 | .parent = &spitzscoop_device.dev, | ||
| 132 | }, | ||
| 133 | .id = -1, | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct corgissp_machinfo spitz_ssp_machinfo = { | ||
| 137 | .port = 2, | ||
| 138 | .cs_lcdcon = SPITZ_GPIO_LCDCON_CS, | ||
| 139 | .cs_ads7846 = SPITZ_GPIO_ADS7846_CS, | ||
| 140 | .cs_max1111 = SPITZ_GPIO_MAX1111_CS, | ||
| 141 | .clk_lcdcon = 520, | ||
| 142 | .clk_ads7846 = 14, | ||
| 143 | .clk_max1111 = 56, | ||
| 144 | }; | ||
| 145 | |||
| 146 | |||
| 147 | /* | ||
| 148 | * Spitz Backlight Device | ||
| 149 | */ | ||
| 150 | static struct corgibl_machinfo spitz_bl_machinfo = { | ||
| 151 | .max_intensity = 0x2f, | ||
| 152 | }; | ||
| 153 | |||
| 154 | static struct platform_device spitzbl_device = { | ||
| 155 | .name = "corgi-bl", | ||
| 156 | .dev = { | ||
| 157 | .platform_data = &spitz_bl_machinfo, | ||
| 158 | }, | ||
| 159 | .id = -1, | ||
| 160 | }; | ||
| 161 | |||
| 162 | |||
| 163 | /* | ||
| 164 | * Spitz Keyboard Device | ||
| 165 | */ | ||
| 166 | static struct platform_device spitzkbd_device = { | ||
| 167 | .name = "spitz-keyboard", | ||
| 168 | .id = -1, | ||
| 169 | }; | ||
| 170 | |||
| 171 | |||
| 172 | /* | ||
| 173 | * Spitz Touch Screen Device | ||
| 174 | */ | ||
| 175 | static struct resource spitzts_resources[] = { | ||
| 176 | [0] = { | ||
| 177 | .start = SPITZ_IRQ_GPIO_TP_INT, | ||
| 178 | .end = SPITZ_IRQ_GPIO_TP_INT, | ||
| 179 | .flags = IORESOURCE_IRQ, | ||
| 180 | }, | ||
| 181 | }; | ||
| 182 | |||
| 183 | static struct corgits_machinfo spitz_ts_machinfo = { | ||
| 184 | .get_hsync_len = spitz_get_hsync_len, | ||
| 185 | .put_hsync = spitz_put_hsync, | ||
| 186 | .wait_hsync = spitz_wait_hsync, | ||
| 187 | }; | ||
| 188 | |||
| 189 | static struct platform_device spitzts_device = { | ||
| 190 | .name = "corgi-ts", | ||
| 191 | .dev = { | ||
| 192 | .parent = &spitzssp_device.dev, | ||
| 193 | .platform_data = &spitz_ts_machinfo, | ||
| 194 | }, | ||
| 195 | .id = -1, | ||
| 196 | .num_resources = ARRAY_SIZE(spitzts_resources), | ||
| 197 | .resource = spitzts_resources, | ||
| 198 | }; | ||
| 199 | |||
| 200 | |||
| 201 | /* | ||
| 202 | * MMC/SD Device | ||
| 203 | * | ||
| 204 | * The card detect interrupt isn't debounced so we delay it by 250ms | ||
| 205 | * to give the card a chance to fully insert/eject. | ||
| 206 | */ | ||
| 207 | |||
| 208 | static struct pxamci_platform_data spitz_mci_platform_data; | ||
| 209 | |||
| 210 | static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data) | ||
| 211 | { | ||
| 212 | int err; | ||
| 213 | |||
| 214 | /* setup GPIO for PXA27x MMC controller */ | ||
| 215 | pxa_gpio_mode(GPIO32_MMCCLK_MD); | ||
| 216 | pxa_gpio_mode(GPIO112_MMCCMD_MD); | ||
| 217 | pxa_gpio_mode(GPIO92_MMCDAT0_MD); | ||
| 218 | pxa_gpio_mode(GPIO109_MMCDAT1_MD); | ||
| 219 | pxa_gpio_mode(GPIO110_MMCDAT2_MD); | ||
| 220 | pxa_gpio_mode(GPIO111_MMCDAT3_MD); | ||
| 221 | pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN); | ||
| 222 | pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN); | ||
| 223 | |||
| 224 | spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); | ||
| 225 | |||
| 226 | err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT, | ||
| 227 | "MMC card detect", data); | ||
| 228 | if (err) { | ||
| 229 | printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); | ||
| 230 | return -1; | ||
| 231 | } | ||
| 232 | |||
| 233 | set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* Power control is shared with one of the CF slots so we have a mess */ | ||
| 239 | static void spitz_mci_setpower(struct device *dev, unsigned int vdd) | ||
| 240 | { | ||
| 241 | struct pxamci_platform_data* p_d = dev->platform_data; | ||
| 242 | |||
| 243 | unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); | ||
| 244 | |||
| 245 | if (( 1 << vdd) & p_d->ocr_mask) { | ||
| 246 | /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ | ||
| 247 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 248 | mdelay(2); | ||
| 249 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04); | ||
| 250 | } else { | ||
| 251 | /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */ | ||
| 252 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04); | ||
| 253 | |||
| 254 | if (!(cpr | 0x02)) { | ||
| 255 | mdelay(1); | ||
| 256 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | static int spitz_mci_get_ro(struct device *dev) | ||
| 262 | { | ||
| 263 | return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP); | ||
| 264 | } | ||
| 265 | |||
| 266 | static void spitz_mci_exit(struct device *dev, void *data) | ||
| 267 | { | ||
| 268 | free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data); | ||
| 269 | } | ||
| 270 | |||
| 271 | static struct pxamci_platform_data spitz_mci_platform_data = { | ||
| 272 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
| 273 | .init = spitz_mci_init, | ||
| 274 | .get_ro = spitz_mci_get_ro, | ||
| 275 | .setpower = spitz_mci_setpower, | ||
| 276 | .exit = spitz_mci_exit, | ||
| 277 | }; | ||
| 278 | |||
| 279 | |||
| 280 | /* | ||
| 281 | * Spitz PXA Framebuffer | ||
| 282 | */ | ||
| 283 | static struct pxafb_mach_info spitz_pxafb_info __initdata = { | ||
| 284 | .pixclock = 19231, | ||
| 285 | .xres = 480, | ||
| 286 | .yres = 640, | ||
| 287 | .bpp = 16, | ||
| 288 | .hsync_len = 40, | ||
| 289 | .left_margin = 46, | ||
| 290 | .right_margin = 125, | ||
| 291 | .vsync_len = 3, | ||
| 292 | .upper_margin = 1, | ||
| 293 | .lower_margin = 0, | ||
| 294 | .sync = 0, | ||
| 295 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM, | ||
| 296 | .lccr3 = LCCR3_PixRsEdg | LCCR3_OutEnH, | ||
| 297 | .pxafb_lcd_power = spitz_lcd_power, | ||
| 298 | }; | ||
| 299 | |||
| 300 | |||
| 301 | static struct platform_device *devices[] __initdata = { | ||
| 302 | &spitzscoop_device, | ||
| 303 | &spitzssp_device, | ||
| 304 | &spitzkbd_device, | ||
| 305 | &spitzts_device, | ||
| 306 | &spitzbl_device, | ||
| 307 | &spitzbattery_device, | ||
| 308 | }; | ||
| 309 | |||
| 310 | static void __init common_init(void) | ||
| 311 | { | ||
| 312 | PMCR = 0x00; | ||
| 313 | |||
| 314 | /* setup sleep mode values */ | ||
| 315 | PWER = 0x00000002; | ||
| 316 | PFER = 0x00000000; | ||
| 317 | PRER = 0x00000002; | ||
| 318 | PGSR0 = 0x0158C000; | ||
| 319 | PGSR1 = 0x00FF0080; | ||
| 320 | PGSR2 = 0x0001C004; | ||
| 321 | |||
| 322 | /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ | ||
| 323 | PCFR |= PCFR_OPDE; | ||
| 324 | |||
| 325 | corgi_ssp_set_machinfo(&spitz_ssp_machinfo); | ||
| 326 | |||
| 327 | pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN); | ||
| 328 | |||
| 329 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 330 | pxa_set_mci_info(&spitz_mci_platform_data); | ||
| 331 | pxafb_device.dev.parent = &spitzssp_device.dev; | ||
| 332 | set_pxa_fb_info(&spitz_pxafb_info); | ||
| 333 | } | ||
| 334 | |||
| 335 | static void __init spitz_init(void) | ||
| 336 | { | ||
| 337 | scoop_num = 2; | ||
| 338 | scoop_devs = &spitz_pcmcia_scoop[0]; | ||
| 339 | spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; | ||
| 340 | |||
| 341 | common_init(); | ||
| 342 | |||
| 343 | platform_device_register(&spitzscoop2_device); | ||
| 344 | } | ||
| 345 | |||
| 346 | static void __init fixup_spitz(struct machine_desc *desc, | ||
| 347 | struct tag *tags, char **cmdline, struct meminfo *mi) | ||
| 348 | { | ||
| 349 | sharpsl_save_param(); | ||
| 350 | mi->nr_banks = 1; | ||
| 351 | mi->bank[0].start = 0xa0000000; | ||
| 352 | mi->bank[0].node = 0; | ||
| 353 | mi->bank[0].size = (64*1024*1024); | ||
| 354 | } | ||
| 355 | |||
| 356 | #ifdef CONFIG_MACH_SPITZ | ||
| 357 | MACHINE_START(SPITZ, "SHARP Spitz") | ||
| 358 | .phys_ram = 0xa0000000, | ||
| 359 | .phys_io = 0x40000000, | ||
| 360 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
| 361 | .fixup = fixup_spitz, | ||
| 362 | .map_io = pxa_map_io, | ||
| 363 | .init_irq = pxa_init_irq, | ||
| 364 | .init_machine = spitz_init, | ||
| 365 | .timer = &pxa_timer, | ||
| 366 | MACHINE_END | ||
| 367 | #endif | ||
| 368 | |||
| 369 | #ifdef CONFIG_MACH_BORZOI | ||
| 370 | MACHINE_START(BORZOI, "SHARP Borzoi") | ||
| 371 | .phys_ram = 0xa0000000, | ||
| 372 | .phys_io = 0x40000000, | ||
| 373 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
| 374 | .fixup = fixup_spitz, | ||
| 375 | .map_io = pxa_map_io, | ||
| 376 | .init_irq = pxa_init_irq, | ||
| 377 | .init_machine = spitz_init, | ||
| 378 | .timer = &pxa_timer, | ||
| 379 | MACHINE_END | ||
| 380 | #endif | ||
