1/* 2 * linux/arch/arm/mach-pxa/poodle.c 3 * 4 * Support for the SHARP Poodle Board. 5 * 6 * Based on: 7 * linux/arch/arm/mach-pxa/lubbock.c Author: Nicolas Pitre 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 * Change Log 14 * 12-Dec-2002 Sharp Corporation for Poodle 15 * John Lenz <lenz@cs.wisc.edu> updates to 2.6 16 */ 17#include <linux/kernel.h> 18#include <linux/init.h> 19#include <linux/platform_device.h> 20#include <linux/fb.h> 21#include <linux/pm.h> 22#include <linux/delay.h> 23 24#include <asm/hardware.h> 25#include <asm/mach-types.h> 26#include <asm/irq.h> 27#include <asm/setup.h> 28#include <asm/system.h> 29 30#include <asm/mach/arch.h> 31#include <asm/mach/map.h> 32#include <asm/mach/irq.h> 33 34#include <asm/arch/pxa-regs.h> 35#include <asm/arch/mmc.h> 36#include <asm/arch/udc.h> 37#include <asm/arch/irda.h> 38#include <asm/arch/poodle.h> 39#include <asm/arch/pxafb.h> 40#include <asm/arch/sharpsl.h> 41#include <asm/arch/ssp.h> 42 43#include <asm/hardware/scoop.h> 44#include <asm/hardware/locomo.h> 45#include <asm/mach/sharpsl_param.h> 46 47#include "generic.h" 48#include "sharpsl.h" 49 50static struct resource poodle_scoop_resources[] = { 51 [0] = { 52 .start = 0x10800000, 53 .end = 0x10800fff, 54 .flags = IORESOURCE_MEM, 55 }, 56}; 57 58static struct scoop_config poodle_scoop_setup = { 59 .io_dir = POODLE_SCOOP_IO_DIR, 60 .io_out = POODLE_SCOOP_IO_OUT, 61}; 62 63struct platform_device poodle_scoop_device = { 64 .name = "sharp-scoop", 65 .id = -1, 66 .dev = { 67 .platform_data = &poodle_scoop_setup, 68 }, 69 .num_resources = ARRAY_SIZE(poodle_scoop_resources), 70 .resource = poodle_scoop_resources, 71}; 72 73static void poodle_pcmcia_init(void) 74{ 75 /* Setup default state of GPIO outputs 76 before we enable them as outputs. */ 77 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | 78 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | 79 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | 80 GPIO_bit(GPIO53_nPCE_2); 81 82 pxa_gpio_mode(GPIO48_nPOE_MD); 83 pxa_gpio_mode(GPIO49_nPWE_MD); 84 pxa_gpio_mode(GPIO50_nPIOR_MD); 85 pxa_gpio_mode(GPIO51_nPIOW_MD); 86 pxa_gpio_mode(GPIO55_nPREG_MD); 87 pxa_gpio_mode(GPIO56_nPWAIT_MD); 88 pxa_gpio_mode(GPIO57_nIOIS16_MD); 89 pxa_gpio_mode(GPIO52_nPCE_1_MD); 90 pxa_gpio_mode(GPIO53_nPCE_2_MD); 91 pxa_gpio_mode(GPIO54_pSKTSEL_MD); 92} 93 94static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { 95{ 96 .dev = &poodle_scoop_device.dev, 97 .irq = POODLE_IRQ_GPIO_CF_IRQ, 98 .cd_irq = POODLE_IRQ_GPIO_CF_CD, 99 .cd_irq_str = "PCMCIA0 CD", 100}, 101}; 102 103static struct scoop_pcmcia_config poodle_pcmcia_config = { 104 .devs = &poodle_pcmcia_scoop[0], 105 .num_devs = 1, 106 .pcmcia_init = poodle_pcmcia_init, 107}; 108 109EXPORT_SYMBOL(poodle_scoop_device); 110 111 112/* LoCoMo device */ 113static struct resource locomo_resources[] = { 114 [0] = { 115 .start = 0x10000000, 116 .end = 0x10001fff, 117 .flags = IORESOURCE_MEM, 118 }, 119 [1] = { 120 .start = IRQ_GPIO(10), 121 .end = IRQ_GPIO(10), 122 .flags = IORESOURCE_IRQ, 123 }, 124}; 125 126struct platform_device poodle_locomo_device = { 127 .name = "locomo", 128 .id = 0, 129 .num_resources = ARRAY_SIZE(locomo_resources), 130 .resource = locomo_resources, 131}; 132 133EXPORT_SYMBOL(poodle_locomo_device); 134 135/* 136 * Poodle SSP Device 137 */ 138 139struct platform_device poodle_ssp_device = { 140 .name = "corgi-ssp", 141 .id = -1, 142}; 143 144struct corgissp_machinfo poodle_ssp_machinfo = { 145 .port = 1, 146 .cs_lcdcon = -1, 147 .cs_ads7846 = -1, 148 .cs_max1111 = -1, 149 .clk_lcdcon = 2, 150 .clk_ads7846 = 36, 151 .clk_max1111 = 2, 152}; 153 154 155/* 156 * Poodle Touch Screen Device 157 */ 158static struct resource poodlets_resources[] = { 159 [0] = { 160 .start = POODLE_IRQ_GPIO_TP_INT, 161 .end = POODLE_IRQ_GPIO_TP_INT, 162 .flags = IORESOURCE_IRQ, 163 }, 164}; 165 166static unsigned long poodle_get_hsync_len(void) 167{ 168 return 0; 169} 170 171static void poodle_null_hsync(void) 172{ 173} 174 175static struct corgits_machinfo poodle_ts_machinfo = { 176 .get_hsync_len = poodle_get_hsync_len, 177 .put_hsync = poodle_null_hsync, 178 .wait_hsync = poodle_null_hsync, 179}; 180 181static struct platform_device poodle_ts_device = { 182 .name = "corgi-ts", 183 .dev = { 184 .platform_data = &poodle_ts_machinfo, 185 }, 186 .id = -1, 187 .num_resources = ARRAY_SIZE(poodlets_resources), 188 .resource = poodlets_resources, 189}; 190 191 192/* 193 * MMC/SD Device 194 * 195 * The card detect interrupt isn't debounced so we delay it by 250ms 196 * to give the card a chance to fully insert/eject. 197 */ 198static struct pxamci_platform_data poodle_mci_platform_data; 199 200static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data) 201{ 202 int err; 203 204 /* setup GPIO for PXA25x MMC controller */ 205 pxa_gpio_mode(GPIO6_MMCCLK_MD); 206 pxa_gpio_mode(GPIO8_MMCCS0_MD); 207 pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN); 208 pxa_gpio_mode(POODLE_GPIO_nSD_WP | GPIO_IN); 209 pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT); 210 pxa_gpio_mode(POODLE_GPIO_SD_PWR1 | GPIO_OUT); 211 212 poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250); 213 214 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, 215 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 216 "MMC card detect", data); 217 if (err) { 218 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 219 return -1; 220 } 221 222 return 0; 223} 224 225static void poodle_mci_setpower(struct device *dev, unsigned int vdd) 226{ 227 struct pxamci_platform_data* p_d = dev->platform_data; 228 229 if (( 1 << vdd) & p_d->ocr_mask) { 230 GPSR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR); 231 mdelay(2); 232 GPSR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1); 233 } else { 234 GPCR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1); 235 GPCR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR); 236 } 237} 238 239static int poodle_mci_get_ro(struct device *dev) 240{ 241 return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP); 242} 243 244 245static void poodle_mci_exit(struct device *dev, void *data) 246{ 247 free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data); 248} 249 250static struct pxamci_platform_data poodle_mci_platform_data = { 251 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 252 .init = poodle_mci_init, 253 .get_ro = poodle_mci_get_ro, 254 .setpower = poodle_mci_setpower, 255 .exit = poodle_mci_exit, 256}; 257 258 259/* 260 * Irda 261 */ 262static void poodle_irda_transceiver_mode(struct device *dev, int mode) 263{ 264 if (mode & IR_OFF) { 265 GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON); 266 } else { 267 GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON); 268 } 269} 270 271static struct pxaficp_platform_data poodle_ficp_platform_data = { 272 .transceiver_cap = IR_SIRMODE | IR_OFF, 273 .transceiver_mode = poodle_irda_transceiver_mode, 274}; 275 276 277/* 278 * USB Device Controller 279 */ 280static void poodle_udc_command(int cmd) 281{ 282 switch(cmd) { 283 case PXA2XX_UDC_CMD_CONNECT: 284 GPSR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP); 285 break; 286 case PXA2XX_UDC_CMD_DISCONNECT: 287 GPCR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP); 288 break; 289 } 290} 291 292static struct pxa2xx_udc_mach_info udc_info __initdata = { 293 /* no connect GPIO; poodle can't tell connection status */ 294 .udc_command = poodle_udc_command, 295}; 296 297 298/* PXAFB device */ 299static struct pxafb_mode_info poodle_fb_mode = { 300 .pixclock = 144700, 301 .xres = 320, 302 .yres = 240, 303 .bpp = 16, 304 .hsync_len = 7, 305 .left_margin = 11, 306 .right_margin = 30, 307 .vsync_len = 2, 308 .upper_margin = 2, 309 .lower_margin = 0, 310 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 311}; 312 313static struct pxafb_mach_info poodle_fb_info = { 314 .modes = &poodle_fb_mode, 315 .num_modes = 1, 316 .lccr0 = LCCR0_Act | LCCR0_Sngl | LCCR0_Color, 317 .lccr3 = 0, 318}; 319 320static struct platform_device *devices[] __initdata = { 321 &poodle_locomo_device, 322 &poodle_scoop_device, 323 &poodle_ssp_device, 324 &poodle_ts_device, 325}; 326 327static void poodle_poweroff(void) 328{ 329 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 330 arm_machine_restart('h'); 331} 332 333static void poodle_restart(char mode) 334{ 335 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 336 arm_machine_restart('h'); 337} 338 339static void __init poodle_init(void) 340{ 341 int ret = 0; 342 343 pm_power_off = poodle_poweroff; 344 arm_pm_restart = poodle_restart; 345 346 /* setup sleep mode values */ 347 PWER = 0x00000002; 348 PFER = 0x00000000; 349 PRER = 0x00000002; 350 PGSR0 = 0x00008000; 351 PGSR1 = 0x003F0202; 352 PGSR2 = 0x0001C000; 353 PCFR |= PCFR_OPDE; 354 355 /* cpu initialize */ 356 /* Pgsr Register */ 357 PGSR0 = 0x0146dd80; 358 PGSR1 = 0x03bf0890; 359 PGSR2 = 0x0001c000; 360 361 /* Alternate Register */ 362 GAFR0_L = 0x01001000; 363 GAFR0_U = 0x591a8010; 364 GAFR1_L = 0x900a8451; 365 GAFR1_U = 0xaaa5aaaa; 366 GAFR2_L = 0x8aaaaaaa; 367 GAFR2_U = 0x00000002; 368 369 /* Direction Register */ 370 GPDR0 = 0xd3f0904c; 371 GPDR1 = 0xfcffb7d3; 372 GPDR2 = 0x0001ffff; 373 374 /* Output Register */ 375 GPCR0 = 0x00000000; 376 GPCR1 = 0x00000000; 377 GPCR2 = 0x00000000; 378 379 GPSR0 = 0x00400000; 380 GPSR1 = 0x00000000; 381 GPSR2 = 0x00000000; 382 383 set_pxa_fb_parent(&poodle_locomo_device.dev); 384 set_pxa_fb_info(&poodle_fb_info); 385 pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT); 386 pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT); 387 pxa_set_udc_info(&udc_info); 388 pxa_set_mci_info(&poodle_mci_platform_data); 389 pxa_set_ficp_info(&poodle_ficp_platform_data); 390 391 platform_scoop_config = &poodle_pcmcia_config; 392 393 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 394 if (ret) { 395 printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n"); 396 } 397 corgi_ssp_set_machinfo(&poodle_ssp_machinfo); 398} 399 400static void __init fixup_poodle(struct machine_desc *desc, 401 struct tag *tags, char **cmdline, struct meminfo *mi) 402{ 403 sharpsl_save_param(); 404 mi->nr_banks=1; 405 mi->bank[0].start = 0xa0000000; 406 mi->bank[0].node = 0; 407 mi->bank[0].size = (32*1024*1024); 408} 409 410MACHINE_START(POODLE, "SHARP Poodle") 411 .phys_io = 0x40000000, 412 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 413 .fixup = fixup_poodle, 414 .map_io = pxa_map_io, 415 .init_irq = pxa_init_irq, 416 .timer = &pxa_timer, 417 .init_machine = poodle_init, 418MACHINE_END 419