9f5ca5497bb9277844f72cb032ff0151e48a2c37
[deliverable/linux.git] / arch / arm / mach-pxa / tosa.c
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 #include <linux/gpio_keys.h>
25 #include <linux/input.h>
26
27 #include <asm/setup.h>
28 #include <asm/memory.h>
29 #include <asm/mach-types.h>
30 #include <asm/hardware.h>
31 #include <asm/irq.h>
32 #include <asm/system.h>
33 #include <asm/arch/pxa-regs.h>
34 #include <asm/arch/pxa2xx-regs.h>
35 #include <asm/arch/mfp-pxa25x.h>
36 #include <asm/arch/irda.h>
37 #include <asm/arch/i2c.h>
38 #include <asm/arch/mmc.h>
39 #include <asm/arch/udc.h>
40
41 #include <asm/mach/arch.h>
42 #include <asm/mach/map.h>
43 #include <asm/mach/irq.h>
44 #include <asm/arch/tosa.h>
45
46 #include <asm/hardware/scoop.h>
47 #include <asm/mach/sharpsl_param.h>
48
49 #include "generic.h"
50 #include "devices.h"
51
52 static unsigned long tosa_pin_config[] = {
53 GPIO78_nCS_2, /* Scoop */
54 GPIO80_nCS_4, /* tg6393xb */
55 GPIO33_nCS_5, /* Scoop */
56
57 // GPIO76 CARD_VCC_ON1
58
59 GPIO19_GPIO, /* Reset out */
60 GPIO1_RST | WAKEUP_ON_EDGE_FALL,
61
62 GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */
63 GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */
64 GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */
65 GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */
66 GPIO20_GPIO, /* EAR_IN */
67 GPIO22_GPIO, /* On */
68
69 GPIO5_GPIO, /* USB_IN */
70 GPIO32_GPIO, /* Pen IRQ */
71
72 GPIO7_GPIO, /* Jacket Detect */
73 GPIO14_GPIO, /* BAT0_CRG */
74 GPIO12_GPIO, /* BAT1_CRG */
75 GPIO17_GPIO, /* BAT0_LOW */
76 GPIO84_GPIO, /* BAT1_LOW */
77 GPIO38_GPIO, /* BAT_LOCK */
78
79 GPIO11_3_6MHz,
80 GPIO15_GPIO, /* TC6393XB IRQ */
81 GPIO18_RDY,
82 GPIO27_GPIO, /* LCD Sync */
83
84 /* MMC */
85 GPIO6_MMC_CLK,
86 GPIO8_MMC_CS0,
87 GPIO9_GPIO, /* Detect */
88 // GPIO10 nSD_INT
89
90 /* CF */
91 GPIO13_GPIO, /* CD_IRQ */
92 GPIO21_GPIO, /* Main Slot IRQ */
93 GPIO36_GPIO, /* Jacket Slot IRQ */
94 GPIO48_nPOE,
95 GPIO49_nPWE,
96 GPIO50_nPIOR,
97 GPIO51_nPIOW,
98 GPIO52_nPCE_1,
99 GPIO53_nPCE_2,
100 GPIO54_nPSKTSEL,
101 GPIO55_nPREG,
102 GPIO56_nPWAIT,
103 GPIO57_nIOIS16,
104
105 /* AC97 */
106 GPIO31_AC97_SYNC,
107 GPIO30_AC97_SDATA_OUT,
108 GPIO28_AC97_BITCLK,
109 GPIO29_AC97_SDATA_IN_0,
110 // GPIO79 nAUD_IRQ
111
112 /* FFUART */
113 GPIO34_FFUART_RXD,
114 GPIO35_FFUART_CTS,
115 GPIO37_FFUART_DSR,
116 GPIO39_FFUART_TXD,
117 GPIO40_FFUART_DTR,
118 GPIO41_FFUART_RTS,
119
120 /* BTUART */
121 GPIO42_BTUART_RXD,
122 GPIO43_BTUART_TXD,
123 GPIO44_BTUART_CTS,
124 GPIO45_BTUART_RTS,
125
126 /* IrDA */
127 GPIO46_STUART_RXD,
128 GPIO47_STUART_TXD,
129
130 /* Keybd */
131 GPIO58_GPIO,
132 GPIO59_GPIO,
133 GPIO60_GPIO,
134 GPIO61_GPIO,
135 GPIO62_GPIO,
136 GPIO63_GPIO,
137 GPIO64_GPIO,
138 GPIO65_GPIO,
139 GPIO66_GPIO,
140 GPIO67_GPIO,
141 GPIO68_GPIO,
142 GPIO69_GPIO,
143 GPIO70_GPIO,
144 GPIO71_GPIO,
145 GPIO72_GPIO,
146 GPIO73_GPIO,
147 GPIO74_GPIO,
148 GPIO75_GPIO,
149
150 /* SPI */
151 GPIO81_SSP2_CLK_OUT,
152 GPIO82_SSP2_FRM_OUT,
153 GPIO83_SSP2_TXD,
154 };
155
156 /*
157 * SCOOP Device
158 */
159 static struct resource tosa_scoop_resources[] = {
160 [0] = {
161 .start = TOSA_CF_PHYS,
162 .end = TOSA_CF_PHYS + 0xfff,
163 .flags = IORESOURCE_MEM,
164 },
165 };
166
167 static struct scoop_config tosa_scoop_setup = {
168 .io_dir = TOSA_SCOOP_IO_DIR,
169 .io_out = TOSA_SCOOP_IO_OUT,
170
171 };
172
173 struct platform_device tosascoop_device = {
174 .name = "sharp-scoop",
175 .id = 0,
176 .dev = {
177 .platform_data = &tosa_scoop_setup,
178 },
179 .num_resources = ARRAY_SIZE(tosa_scoop_resources),
180 .resource = tosa_scoop_resources,
181 };
182
183
184 /*
185 * SCOOP Device Jacket
186 */
187 static struct resource tosa_scoop_jc_resources[] = {
188 [0] = {
189 .start = TOSA_SCOOP_PHYS + 0x40,
190 .end = TOSA_SCOOP_PHYS + 0xfff,
191 .flags = IORESOURCE_MEM,
192 },
193 };
194
195 static struct scoop_config tosa_scoop_jc_setup = {
196 .io_dir = TOSA_SCOOP_JC_IO_DIR,
197 .io_out = TOSA_SCOOP_JC_IO_OUT,
198 };
199
200 struct platform_device tosascoop_jc_device = {
201 .name = "sharp-scoop",
202 .id = 1,
203 .dev = {
204 .platform_data = &tosa_scoop_jc_setup,
205 .parent = &tosascoop_device.dev,
206 },
207 .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources),
208 .resource = tosa_scoop_jc_resources,
209 };
210
211 /*
212 * PCMCIA
213 */
214 static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
215 {
216 .dev = &tosascoop_device.dev,
217 .irq = TOSA_IRQ_GPIO_CF_IRQ,
218 .cd_irq = TOSA_IRQ_GPIO_CF_CD,
219 .cd_irq_str = "PCMCIA0 CD",
220 },{
221 .dev = &tosascoop_jc_device.dev,
222 .irq = TOSA_IRQ_GPIO_JC_CF_IRQ,
223 .cd_irq = -1,
224 },
225 };
226
227 static struct scoop_pcmcia_config tosa_pcmcia_config = {
228 .devs = &tosa_pcmcia_scoop[0],
229 .num_devs = 2,
230 };
231
232 /*
233 * USB Device Controller
234 */
235 static void tosa_udc_command(int cmd)
236 {
237 switch(cmd) {
238 case PXA2XX_UDC_CMD_CONNECT:
239 set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
240 break;
241 case PXA2XX_UDC_CMD_DISCONNECT:
242 reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
243 break;
244 }
245 }
246
247 static struct pxa2xx_udc_mach_info udc_info __initdata = {
248 .udc_command = tosa_udc_command,
249 .gpio_vbus = TOSA_GPIO_USB_IN,
250 .gpio_vbus_inverted = 1,
251 };
252
253 /*
254 * MMC/SD Device
255 */
256 static struct pxamci_platform_data tosa_mci_platform_data;
257
258 static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
259 {
260 int err;
261
262 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
263
264 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
265 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
266 "MMC/SD card detect", data);
267 if (err)
268 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
269
270 return err;
271 }
272
273 static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
274 {
275 struct pxamci_platform_data* p_d = dev->platform_data;
276
277 if (( 1 << vdd) & p_d->ocr_mask) {
278 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
279 } else {
280 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
281 }
282 }
283
284 static int tosa_mci_get_ro(struct device *dev)
285 {
286 return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP);
287 }
288
289 static void tosa_mci_exit(struct device *dev, void *data)
290 {
291 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
292 }
293
294 static struct pxamci_platform_data tosa_mci_platform_data = {
295 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
296 .init = tosa_mci_init,
297 .get_ro = tosa_mci_get_ro,
298 .setpower = tosa_mci_setpower,
299 .exit = tosa_mci_exit,
300 };
301
302 /*
303 * Irda
304 */
305 static void tosa_irda_transceiver_mode(struct device *dev, int mode)
306 {
307 if (mode & IR_OFF) {
308 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
309 } else {
310 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
311 }
312 }
313
314 static struct pxaficp_platform_data tosa_ficp_platform_data = {
315 .transceiver_cap = IR_SIRMODE | IR_OFF,
316 .transceiver_mode = tosa_irda_transceiver_mode,
317 };
318
319 /*
320 * Tosa Keyboard
321 */
322 static struct platform_device tosakbd_device = {
323 .name = "tosa-keyboard",
324 .id = -1,
325 };
326
327 static struct gpio_keys_button tosa_gpio_keys[] = {
328 /*
329 * Two following keys are directly tied to "ON" button of tosa. Why?
330 * The first one can be used as a wakeup source, the second can't;
331 * also the first one is OR of ac_powered and on_button.
332 */
333 {
334 .type = EV_PWR,
335 .code = KEY_RESERVED,
336 .gpio = TOSA_GPIO_POWERON,
337 .desc = "Poweron",
338 .wakeup = 1,
339 .active_low = 1,
340 },
341 {
342 .type = EV_PWR,
343 .code = KEY_SUSPEND,
344 .gpio = TOSA_GPIO_ON_KEY,
345 .desc = "On key",
346 /*
347 * can't be used as wakeup
348 * .wakeup = 1,
349 */
350 .active_low = 1,
351 },
352 {
353 .type = EV_KEY,
354 .code = TOSA_KEY_RECORD,
355 .gpio = TOSA_GPIO_RECORD_BTN,
356 .desc = "Record Button",
357 .wakeup = 1,
358 .active_low = 1,
359 },
360 {
361 .type = EV_KEY,
362 .code = TOSA_KEY_SYNC,
363 .gpio = TOSA_GPIO_SYNC,
364 .desc = "Sync Button",
365 .wakeup = 1,
366 .active_low = 1,
367 },
368 };
369
370 static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
371 .buttons = tosa_gpio_keys,
372 .nbuttons = ARRAY_SIZE(tosa_gpio_keys),
373 };
374
375 static struct platform_device tosa_gpio_keys_device = {
376 .name = "gpio-keys",
377 .id = -1,
378 .dev = {
379 .platform_data = &tosa_gpio_keys_platform_data,
380 },
381 };
382
383 /*
384 * Tosa LEDs
385 */
386 static struct platform_device tosaled_device = {
387 .name = "tosa-led",
388 .id = -1,
389 };
390
391 static struct platform_device *devices[] __initdata = {
392 &tosascoop_device,
393 &tosascoop_jc_device,
394 &tosakbd_device,
395 &tosa_gpio_keys_device,
396 &tosaled_device,
397 };
398
399 static void tosa_poweroff(void)
400 {
401 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
402
403 pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
404 GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
405
406 mdelay(1000);
407 arm_machine_restart('h');
408 }
409
410 static void tosa_restart(char mode)
411 {
412 /* Bootloader magic for a reboot */
413 if((MSC0 & 0xffff0000) == 0x7ff00000)
414 MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
415
416 tosa_poweroff();
417 }
418
419 static void __init tosa_init(void)
420 {
421 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
422 gpio_set_wake(MFP_PIN_GPIO1, 1);
423 /* We can't pass to gpio-keys since it will drop the Reset altfunc */
424
425 pm_power_off = tosa_poweroff;
426 arm_pm_restart = tosa_restart;
427
428 PCFR |= PCFR_OPDE;
429
430 /* enable batt_fault */
431 PMCR = 0x01;
432
433 pxa_set_mci_info(&tosa_mci_platform_data);
434 pxa_set_udc_info(&udc_info);
435 pxa_set_ficp_info(&tosa_ficp_platform_data);
436 pxa_set_i2c_info(NULL);
437 platform_scoop_config = &tosa_pcmcia_config;
438
439 platform_add_devices(devices, ARRAY_SIZE(devices));
440 }
441
442 static void __init fixup_tosa(struct machine_desc *desc,
443 struct tag *tags, char **cmdline, struct meminfo *mi)
444 {
445 sharpsl_save_param();
446 mi->nr_banks=1;
447 mi->bank[0].start = 0xa0000000;
448 mi->bank[0].node = 0;
449 mi->bank[0].size = (64*1024*1024);
450 }
451
452 MACHINE_START(TOSA, "SHARP Tosa")
453 .phys_io = 0x40000000,
454 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
455 .fixup = fixup_tosa,
456 .map_io = pxa_map_io,
457 .init_irq = pxa25x_init_irq,
458 .init_machine = tosa_init,
459 .timer = &pxa_timer,
460 MACHINE_END
This page took 0.221569 seconds and 4 git commands to generate.