1/* 2 * Support for Sharp SL-C6000x PDAs 3 * Model: (Tosa) 4 * 5 * Copyright (c) 2005 Dirk Opfer 6 * 7 * Based on code written by Sharp/Lineo for 2.4 kernels 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/platform_device.h> 18#include <linux/major.h> 19#include <linux/fs.h> 20#include <linux/interrupt.h> 21#include <linux/mmc/host.h> 22#include <linux/pm.h> 23#include <linux/delay.h> 24 25#include <asm/setup.h> 26#include <asm/memory.h> 27#include <asm/mach-types.h> 28#include <asm/hardware.h> 29#include <asm/irq.h> 30#include <asm/system.h> 31#include <asm/arch/pxa-regs.h> 32#include <asm/arch/irda.h> 33#include <asm/arch/mmc.h> 34#include <asm/arch/udc.h> 35 36#include <asm/mach/arch.h> 37#include <asm/mach/map.h> 38#include <asm/mach/irq.h> 39#include <asm/arch/tosa.h> 40 41#include <asm/hardware/scoop.h> 42#include <asm/mach/sharpsl_param.h> 43 44#include "generic.h" 45 46 47/* 48 * SCOOP Device 49 */ 50static struct resource tosa_scoop_resources[] = { 51 [0] = { 52 .start = TOSA_CF_PHYS, 53 .end = TOSA_CF_PHYS + 0xfff, 54 .flags = IORESOURCE_MEM, 55 }, 56}; 57 58static struct scoop_config tosa_scoop_setup = { 59 .io_dir = TOSA_SCOOP_IO_DIR, 60 .io_out = TOSA_SCOOP_IO_OUT, 61 62}; 63 64struct platform_device tosascoop_device = { 65 .name = "sharp-scoop", 66 .id = 0, 67 .dev = { 68 .platform_data = &tosa_scoop_setup, 69 }, 70 .num_resources = ARRAY_SIZE(tosa_scoop_resources), 71 .resource = tosa_scoop_resources, 72}; 73 74 75/* 76 * SCOOP Device Jacket 77 */ 78static struct resource tosa_scoop_jc_resources[] = { 79 [0] = { 80 .start = TOSA_SCOOP_PHYS + 0x40, 81 .end = TOSA_SCOOP_PHYS + 0xfff, 82 .flags = IORESOURCE_MEM, 83 }, 84}; 85 86static struct scoop_config tosa_scoop_jc_setup = { 87 .io_dir = TOSA_SCOOP_JC_IO_DIR, 88 .io_out = TOSA_SCOOP_JC_IO_OUT, 89}; 90 91struct platform_device tosascoop_jc_device = { 92 .name = "sharp-scoop", 93 .id = 1, 94 .dev = { 95 .platform_data = &tosa_scoop_jc_setup, 96 .parent = &tosascoop_device.dev, 97 }, 98 .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources), 99 .resource = tosa_scoop_jc_resources, 100}; 101 102/* 103 * PCMCIA 104 */ 105static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { 106{ 107 .dev = &tosascoop_device.dev, 108 .irq = TOSA_IRQ_GPIO_CF_IRQ, 109 .cd_irq = TOSA_IRQ_GPIO_CF_CD, 110 .cd_irq_str = "PCMCIA0 CD", 111},{ 112 .dev = &tosascoop_jc_device.dev, 113 .irq = TOSA_IRQ_GPIO_JC_CF_IRQ, 114 .cd_irq = -1, 115}, 116}; 117 118static void tosa_pcmcia_init(void) 119{ 120 /* Setup default state of GPIO outputs 121 before we enable them as outputs. */ 122 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | 123 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | 124 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | 125 GPIO_bit(GPIO53_nPCE_2); 126 127 pxa_gpio_mode(GPIO48_nPOE_MD); 128 pxa_gpio_mode(GPIO49_nPWE_MD); 129 pxa_gpio_mode(GPIO50_nPIOR_MD); 130 pxa_gpio_mode(GPIO51_nPIOW_MD); 131 pxa_gpio_mode(GPIO55_nPREG_MD); 132 pxa_gpio_mode(GPIO56_nPWAIT_MD); 133 pxa_gpio_mode(GPIO57_nIOIS16_MD); 134 pxa_gpio_mode(GPIO52_nPCE_1_MD); 135 pxa_gpio_mode(GPIO53_nPCE_2_MD); 136 pxa_gpio_mode(GPIO54_pSKTSEL_MD); 137} 138 139static struct scoop_pcmcia_config tosa_pcmcia_config = { 140 .devs = &tosa_pcmcia_scoop[0], 141 .num_devs = 2, 142 .pcmcia_init = tosa_pcmcia_init, 143}; 144 145/* 146 * USB Device Controller 147 */ 148static void tosa_udc_command(int cmd) 149{ 150 switch(cmd) { 151 case PXA2XX_UDC_CMD_CONNECT: 152 set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); 153 break; 154 case PXA2XX_UDC_CMD_DISCONNECT: 155 reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); 156 break; 157 } 158} 159 160static int tosa_udc_is_connected(void) 161{ 162 return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0); 163} 164 165 166static struct pxa2xx_udc_mach_info udc_info __initdata = { 167 .udc_command = tosa_udc_command, 168 .udc_is_connected = tosa_udc_is_connected, 169}; 170 171/* 172 * MMC/SD Device 173 */ 174static struct pxamci_platform_data tosa_mci_platform_data; 175 176static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data) 177{ 178 int err; 179 180 /* setup GPIO for PXA25x MMC controller */ 181 pxa_gpio_mode(GPIO6_MMCCLK_MD); 182 pxa_gpio_mode(GPIO8_MMCCS0_MD); 183 pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN); 184 185 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); 186 187 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED, 188 "MMC/SD card detect", data); 189 if (err) { 190 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 191 return -1; 192 } 193 194 set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); 195 196 return 0; 197} 198 199static void tosa_mci_setpower(struct device *dev, unsigned int vdd) 200{ 201 struct pxamci_platform_data* p_d = dev->platform_data; 202 203 if (( 1 << vdd) & p_d->ocr_mask) { 204 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); 205 } else { 206 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); 207 } 208} 209 210static int tosa_mci_get_ro(struct device *dev) 211{ 212 return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP); 213} 214 215static void tosa_mci_exit(struct device *dev, void *data) 216{ 217 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); 218} 219 220static struct pxamci_platform_data tosa_mci_platform_data = { 221 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 222 .init = tosa_mci_init, 223 .get_ro = tosa_mci_get_ro, 224 .setpower = tosa_mci_setpower, 225 .exit = tosa_mci_exit, 226}; 227 228/* 229 * Irda 230 */ 231static void tosa_irda_transceiver_mode(struct device *dev, int mode) 232{ 233 if (mode & IR_OFF) { 234 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); 235 pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW); 236 pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT); 237 } else { 238 pxa_gpio_mode(GPIO47_STTXD_MD); 239 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); 240 } 241} 242 243static struct pxaficp_platform_data tosa_ficp_platform_data = { 244 .transceiver_cap = IR_SIRMODE | IR_OFF, 245 .transceiver_mode = tosa_irda_transceiver_mode, 246}; 247 248/* 249 * Tosa Keyboard 250 */ 251static struct platform_device tosakbd_device = { 252 .name = "tosa-keyboard", 253 .id = -1, 254}; 255 256/* 257 * Tosa LEDs 258 */ 259static struct platform_device tosaled_device = { 260 .name = "tosa-led", 261 .id = -1, 262}; 263 264static struct platform_device *devices[] __initdata = { 265 &tosascoop_device, 266 &tosascoop_jc_device, 267 &tosakbd_device, 268 &tosaled_device, 269}; 270 271static void tosa_poweroff(void) 272{ 273 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 274 275 pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT); 276 GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET); 277 278 mdelay(1000); 279 arm_machine_restart('h'); 280} 281 282static void tosa_restart(char mode) 283{ 284 /* Bootloader magic for a reboot */ 285 if((MSC0 & 0xffff0000) == 0x7ff00000) 286 MSC0 = (MSC0 & 0xffff) | 0x7ee00000; 287 288 tosa_poweroff(); 289} 290 291static void __init tosa_init(void) 292{ 293 pm_power_off = tosa_poweroff; 294 arm_pm_restart = tosa_restart; 295 296 pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); 297 pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); 298 pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); 299 300 /* setup sleep mode values */ 301 PWER = 0x00000002; 302 PFER = 0x00000000; 303 PRER = 0x00000002; 304 PGSR0 = 0x00000000; 305 PGSR1 = 0x00FF0002; 306 PGSR2 = 0x00014000; 307 PCFR |= PCFR_OPDE; 308 309 /* enable batt_fault */ 310 PMCR = 0x01; 311 312 pxa_set_mci_info(&tosa_mci_platform_data); 313 pxa_set_udc_info(&udc_info); 314 pxa_set_ficp_info(&tosa_ficp_platform_data); 315 platform_scoop_config = &tosa_pcmcia_config; 316 317 platform_add_devices(devices, ARRAY_SIZE(devices)); 318} 319 320static void __init fixup_tosa(struct machine_desc *desc, 321 struct tag *tags, char **cmdline, struct meminfo *mi) 322{ 323 sharpsl_save_param(); 324 mi->nr_banks=1; 325 mi->bank[0].start = 0xa0000000; 326 mi->bank[0].node = 0; 327 mi->bank[0].size = (64*1024*1024); 328} 329 330MACHINE_START(TOSA, "SHARP Tosa") 331 .phys_io = 0x40000000, 332 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 333 .fixup = fixup_tosa, 334 .map_io = pxa_map_io, 335 .init_irq = pxa_init_irq, 336 .init_machine = tosa_init, 337 .timer = &pxa_timer, 338MACHINE_END 339