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