blob: 2fe0998ac3fbb101da4a5dfd1ccaefbb7990324a [file] [log] [blame]
Dirk Opfer8459c152005-11-06 14:27:52 +00001/*
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>
Dirk Opfer067c9042005-11-21 15:17:06 +000017#include <linux/platform_device.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000018#include <linux/major.h>
19#include <linux/fs.h>
20#include <linux/interrupt.h>
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +010021#include <linux/delay.h>
22#include <linux/fb.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000023#include <linux/mmc/host.h>
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +010024#include <linux/mfd/tc6393xb.h>
Richard Purdie74617fb2006-06-19 19:57:12 +010025#include <linux/pm.h>
Russell King905f1462006-06-20 23:27:37 +010026#include <linux/delay.h>
Dmitry Baryshkov93e9012f2008-01-21 01:04:20 -050027#include <linux/gpio_keys.h>
28#include <linux/input.h>
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +010029#include <linux/gpio.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000030
31#include <asm/setup.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000032#include <asm/mach-types.h>
eric miaobb548dd2008-01-30 09:39:48 +010033#include <asm/arch/pxa2xx-regs.h>
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +010034#include <asm/arch/mfp-pxa25x.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000035#include <asm/arch/irda.h>
Dmitry Baryshkov481ea5a2008-04-10 15:43:18 +010036#include <asm/arch/i2c.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000037#include <asm/arch/mmc.h>
38#include <asm/arch/udc.h>
39
40#include <asm/mach/arch.h>
Dirk Opfer8459c152005-11-06 14:27:52 +000041#include <asm/arch/tosa.h>
42
43#include <asm/hardware/scoop.h>
44#include <asm/mach/sharpsl_param.h>
45
46#include "generic.h"
Russell King46c41e62007-05-15 15:39:36 +010047#include "devices.h"
Dirk Opfer8459c152005-11-06 14:27:52 +000048
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +010049static unsigned long tosa_pin_config[] = {
50 GPIO78_nCS_2, /* Scoop */
51 GPIO80_nCS_4, /* tg6393xb */
52 GPIO33_nCS_5, /* Scoop */
53
54 // GPIO76 CARD_VCC_ON1
55
56 GPIO19_GPIO, /* Reset out */
57 GPIO1_RST | WAKEUP_ON_EDGE_FALL,
58
59 GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */
60 GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */
61 GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */
62 GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */
63 GPIO20_GPIO, /* EAR_IN */
64 GPIO22_GPIO, /* On */
65
66 GPIO5_GPIO, /* USB_IN */
67 GPIO32_GPIO, /* Pen IRQ */
68
69 GPIO7_GPIO, /* Jacket Detect */
70 GPIO14_GPIO, /* BAT0_CRG */
71 GPIO12_GPIO, /* BAT1_CRG */
72 GPIO17_GPIO, /* BAT0_LOW */
73 GPIO84_GPIO, /* BAT1_LOW */
74 GPIO38_GPIO, /* BAT_LOCK */
75
76 GPIO11_3_6MHz,
77 GPIO15_GPIO, /* TC6393XB IRQ */
78 GPIO18_RDY,
79 GPIO27_GPIO, /* LCD Sync */
80
81 /* MMC */
82 GPIO6_MMC_CLK,
83 GPIO8_MMC_CS0,
84 GPIO9_GPIO, /* Detect */
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +010085 GPIO10_GPIO, /* nSD_INT */
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +010086
87 /* CF */
88 GPIO13_GPIO, /* CD_IRQ */
89 GPIO21_GPIO, /* Main Slot IRQ */
90 GPIO36_GPIO, /* Jacket Slot IRQ */
91 GPIO48_nPOE,
92 GPIO49_nPWE,
93 GPIO50_nPIOR,
94 GPIO51_nPIOW,
95 GPIO52_nPCE_1,
96 GPIO53_nPCE_2,
97 GPIO54_nPSKTSEL,
98 GPIO55_nPREG,
99 GPIO56_nPWAIT,
100 GPIO57_nIOIS16,
101
102 /* AC97 */
103 GPIO31_AC97_SYNC,
104 GPIO30_AC97_SDATA_OUT,
105 GPIO28_AC97_BITCLK,
106 GPIO29_AC97_SDATA_IN_0,
107 // GPIO79 nAUD_IRQ
108
109 /* FFUART */
110 GPIO34_FFUART_RXD,
111 GPIO35_FFUART_CTS,
112 GPIO37_FFUART_DSR,
113 GPIO39_FFUART_TXD,
114 GPIO40_FFUART_DTR,
115 GPIO41_FFUART_RTS,
116
117 /* BTUART */
118 GPIO42_BTUART_RXD,
119 GPIO43_BTUART_TXD,
120 GPIO44_BTUART_CTS,
121 GPIO45_BTUART_RTS,
122
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +0100123 /* Keybd */
eric miaoc8671552008-05-26 03:28:50 +0100124 GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
125 GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
126 GPIO60_GPIO | MFP_LPM_DRIVE_LOW,
127 GPIO61_GPIO | MFP_LPM_DRIVE_LOW,
128 GPIO62_GPIO | MFP_LPM_DRIVE_LOW,
129 GPIO63_GPIO | MFP_LPM_DRIVE_LOW,
130 GPIO64_GPIO | MFP_LPM_DRIVE_LOW,
131 GPIO65_GPIO | MFP_LPM_DRIVE_LOW,
132 GPIO66_GPIO | MFP_LPM_DRIVE_LOW,
133 GPIO67_GPIO | MFP_LPM_DRIVE_LOW,
134 GPIO68_GPIO | MFP_LPM_DRIVE_LOW,
135 GPIO69_GPIO | MFP_LPM_DRIVE_LOW,
136 GPIO70_GPIO | MFP_LPM_DRIVE_LOW,
137 GPIO71_GPIO | MFP_LPM_DRIVE_LOW,
138 GPIO72_GPIO | MFP_LPM_DRIVE_LOW,
139 GPIO73_GPIO | MFP_LPM_DRIVE_LOW,
140 GPIO74_GPIO | MFP_LPM_DRIVE_LOW,
141 GPIO75_GPIO | MFP_LPM_DRIVE_LOW,
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +0100142
143 /* SPI */
144 GPIO81_SSP2_CLK_OUT,
145 GPIO82_SSP2_FRM_OUT,
146 GPIO83_SSP2_TXD,
147};
148
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100149static unsigned long tosa_pin_irda_off[] = {
150 GPIO46_STUART_RXD,
151 GPIO47_GPIO | MFP_LPM_DRIVE_LOW,
152};
153
154static unsigned long tosa_pin_irda_on[] = {
155 GPIO46_STUART_RXD,
156 GPIO47_STUART_TXD,
157};
158
159
Dirk Opfer8459c152005-11-06 14:27:52 +0000160/*
161 * SCOOP Device
162 */
163static struct resource tosa_scoop_resources[] = {
164 [0] = {
165 .start = TOSA_CF_PHYS,
166 .end = TOSA_CF_PHYS + 0xfff,
167 .flags = IORESOURCE_MEM,
168 },
169};
170
171static struct scoop_config tosa_scoop_setup = {
172 .io_dir = TOSA_SCOOP_IO_DIR,
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100173 .gpio_base = TOSA_SCOOP_GPIO_BASE,
Dirk Opfer8459c152005-11-06 14:27:52 +0000174};
175
Dmitry Baryshkovba4eb7e2008-04-19 10:42:25 +0100176static struct platform_device tosascoop_device = {
Dirk Opfer8459c152005-11-06 14:27:52 +0000177 .name = "sharp-scoop",
178 .id = 0,
179 .dev = {
180 .platform_data = &tosa_scoop_setup,
181 },
182 .num_resources = ARRAY_SIZE(tosa_scoop_resources),
183 .resource = tosa_scoop_resources,
184};
185
186
187/*
188 * SCOOP Device Jacket
189 */
190static struct resource tosa_scoop_jc_resources[] = {
191 [0] = {
192 .start = TOSA_SCOOP_PHYS + 0x40,
193 .end = TOSA_SCOOP_PHYS + 0xfff,
194 .flags = IORESOURCE_MEM,
195 },
196};
197
198static struct scoop_config tosa_scoop_jc_setup = {
199 .io_dir = TOSA_SCOOP_JC_IO_DIR,
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100200 .gpio_base = TOSA_SCOOP_JC_GPIO_BASE,
Dirk Opfer8459c152005-11-06 14:27:52 +0000201};
202
Dmitry Baryshkovba4eb7e2008-04-19 10:42:25 +0100203static struct platform_device tosascoop_jc_device = {
Dirk Opfer8459c152005-11-06 14:27:52 +0000204 .name = "sharp-scoop",
205 .id = 1,
206 .dev = {
207 .platform_data = &tosa_scoop_jc_setup,
208 .parent = &tosascoop_device.dev,
209 },
210 .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources),
211 .resource = tosa_scoop_jc_resources,
212};
213
Dirk Opfer4c18ad22005-11-08 19:15:50 +0000214/*
215 * PCMCIA
216 */
Dirk Opfer8459c152005-11-06 14:27:52 +0000217static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
218{
219 .dev = &tosascoop_device.dev,
220 .irq = TOSA_IRQ_GPIO_CF_IRQ,
221 .cd_irq = TOSA_IRQ_GPIO_CF_CD,
222 .cd_irq_str = "PCMCIA0 CD",
223},{
224 .dev = &tosascoop_jc_device.dev,
225 .irq = TOSA_IRQ_GPIO_JC_CF_IRQ,
226 .cd_irq = -1,
227},
228};
229
Dirk Opfer4c18ad22005-11-08 19:15:50 +0000230static struct scoop_pcmcia_config tosa_pcmcia_config = {
231 .devs = &tosa_pcmcia_scoop[0],
232 .num_devs = 2,
Dirk Opfer4c18ad22005-11-08 19:15:50 +0000233};
234
Dirk Opfera93876c2005-11-08 19:15:30 +0000235/*
236 * USB Device Controller
237 */
Dirk Opfera93876c2005-11-08 19:15:30 +0000238static struct pxa2xx_udc_mach_info udc_info __initdata = {
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100239 .gpio_pullup = TOSA_GPIO_USB_PULLUP,
Dmitry Baryshkov487dc922007-12-21 12:18:01 +0300240 .gpio_vbus = TOSA_GPIO_USB_IN,
241 .gpio_vbus_inverted = 1,
Dirk Opfera93876c2005-11-08 19:15:30 +0000242};
243
244/*
245 * MMC/SD Device
246 */
247static struct pxamci_platform_data tosa_mci_platform_data;
248
David Howells40220c12006-10-09 12:19:47 +0100249static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
Dirk Opfera93876c2005-11-08 19:15:30 +0000250{
251 int err;
252
Dirk Opfera93876c2005-11-08 19:15:30 +0000253 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
254
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100255 err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect");
256 if (err) {
257 printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n");
258 goto err_gpio_detect;
259 }
260 err = gpio_direction_input(TOSA_GPIO_nSD_DETECT);
261 if (err)
262 goto err_gpio_detect_dir;
263
Russell King2687bd32008-01-23 14:05:58 +0000264 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
265 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
Dirk Opfera93876c2005-11-08 19:15:30 +0000266 "MMC/SD card detect", data);
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100267 if (err) {
Dirk Opfera93876c2005-11-08 19:15:30 +0000268 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100269 goto err_irq;
270 }
Dirk Opfera93876c2005-11-08 19:15:30 +0000271
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100272 err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect");
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100273 if (err) {
274 printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n");
275 goto err_gpio_wp;
276 }
277 err = gpio_direction_input(TOSA_GPIO_SD_WP);
278 if (err)
279 goto err_gpio_wp_dir;
280
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100281 err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power");
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100282 if (err) {
283 printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
284 goto err_gpio_pwr;
285 }
286 err = gpio_direction_output(TOSA_GPIO_PWR_ON, 0);
287 if (err)
288 goto err_gpio_pwr_dir;
289
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100290 err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int");
291 if (err) {
292 printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
293 goto err_gpio_int;
294 }
295 err = gpio_direction_input(TOSA_GPIO_nSD_INT);
296 if (err)
297 goto err_gpio_int_dir;
298
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100299 return 0;
300
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100301err_gpio_int_dir:
302 gpio_free(TOSA_GPIO_nSD_INT);
303err_gpio_int:
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100304err_gpio_pwr_dir:
305 gpio_free(TOSA_GPIO_PWR_ON);
306err_gpio_pwr:
307err_gpio_wp_dir:
308 gpio_free(TOSA_GPIO_SD_WP);
309err_gpio_wp:
310 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
311err_irq:
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100312err_gpio_detect_dir:
313 gpio_free(TOSA_GPIO_nSD_DETECT);
314err_gpio_detect:
Russell King2687bd32008-01-23 14:05:58 +0000315 return err;
Dirk Opfera93876c2005-11-08 19:15:30 +0000316}
317
318static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
319{
320 struct pxamci_platform_data* p_d = dev->platform_data;
321
322 if (( 1 << vdd) & p_d->ocr_mask) {
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100323 gpio_set_value(TOSA_GPIO_PWR_ON, 1);
Dirk Opfera93876c2005-11-08 19:15:30 +0000324 } else {
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100325 gpio_set_value(TOSA_GPIO_PWR_ON, 0);
Dirk Opfera93876c2005-11-08 19:15:30 +0000326 }
327}
328
329static int tosa_mci_get_ro(struct device *dev)
330{
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100331 return gpio_get_value(TOSA_GPIO_SD_WP);
Dirk Opfera93876c2005-11-08 19:15:30 +0000332}
333
334static void tosa_mci_exit(struct device *dev, void *data)
335{
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100336 gpio_free(TOSA_GPIO_nSD_INT);
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100337 gpio_free(TOSA_GPIO_PWR_ON);
338 gpio_free(TOSA_GPIO_SD_WP);
Dirk Opfera93876c2005-11-08 19:15:30 +0000339 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
Dmitry Baryshkovc4d5f8d2008-06-09 13:23:50 +0100340 gpio_free(TOSA_GPIO_nSD_DETECT);
Dirk Opfera93876c2005-11-08 19:15:30 +0000341}
342
343static struct pxamci_platform_data tosa_mci_platform_data = {
344 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
345 .init = tosa_mci_init,
346 .get_ro = tosa_mci_get_ro,
347 .setpower = tosa_mci_setpower,
348 .exit = tosa_mci_exit,
349};
350
351/*
352 * Irda
353 */
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100354static void tosa_irda_transceiver_mode(struct device *dev, int mode)
355{
356 if (mode & IR_OFF) {
357 gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0);
358 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off));
359 gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
360 } else {
361 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on));
362 gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1);
363 }
364}
365
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100366static int tosa_irda_startup(struct device *dev)
367{
368 int ret;
369
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100370 ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX");
371 if (ret)
372 goto err_tx;
373 ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
374 if (ret)
375 goto err_tx_dir;
376
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100377 ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
378 if (ret)
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100379 goto err_pwr;
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100380
381 ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
382 if (ret)
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100383 goto err_pwr_dir;
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100384
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100385 tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
386
387 return 0;
388
389err_pwr_dir:
390 gpio_free(TOSA_GPIO_IR_POWERDWN);
391err_pwr:
392err_tx_dir:
393 gpio_free(TOSA_GPIO_IRDA_TX);
394err_tx:
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100395 return ret;
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100396}
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100397
398static void tosa_irda_shutdown(struct device *dev)
399{
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100400 tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100401 gpio_free(TOSA_GPIO_IR_POWERDWN);
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100402 gpio_free(TOSA_GPIO_IRDA_TX);
Dirk Opfera93876c2005-11-08 19:15:30 +0000403}
404
405static struct pxaficp_platform_data tosa_ficp_platform_data = {
406 .transceiver_cap = IR_SIRMODE | IR_OFF,
407 .transceiver_mode = tosa_irda_transceiver_mode,
Dmitry Baryshkovd4e7d092008-04-12 20:16:16 +0100408 .startup = tosa_irda_startup,
409 .shutdown = tosa_irda_shutdown,
Dirk Opfera93876c2005-11-08 19:15:30 +0000410};
411
412/*
413 * Tosa Keyboard
414 */
415static struct platform_device tosakbd_device = {
416 .name = "tosa-keyboard",
417 .id = -1,
418};
Dirk Opfer8459c152005-11-06 14:27:52 +0000419
Dmitry Baryshkov93e9012f2008-01-21 01:04:20 -0500420static struct gpio_keys_button tosa_gpio_keys[] = {
Dmitry Baryshkov0aa975612008-04-12 20:02:50 +0100421 /*
422 * Two following keys are directly tied to "ON" button of tosa. Why?
423 * The first one can be used as a wakeup source, the second can't;
424 * also the first one is OR of ac_powered and on_button.
425 */
426 {
427 .type = EV_PWR,
428 .code = KEY_RESERVED,
429 .gpio = TOSA_GPIO_POWERON,
430 .desc = "Poweron",
431 .wakeup = 1,
432 .active_low = 1,
433 },
Dmitry Baryshkov93e9012f2008-01-21 01:04:20 -0500434 {
435 .type = EV_PWR,
436 .code = KEY_SUSPEND,
437 .gpio = TOSA_GPIO_ON_KEY,
438 .desc = "On key",
Dmitry Baryshkov0aa975612008-04-12 20:02:50 +0100439 /*
440 * can't be used as wakeup
441 * .wakeup = 1,
442 */
Dmitry Baryshkov93e9012f2008-01-21 01:04:20 -0500443 .active_low = 1,
444 },
445 {
446 .type = EV_KEY,
447 .code = TOSA_KEY_RECORD,
448 .gpio = TOSA_GPIO_RECORD_BTN,
449 .desc = "Record Button",
450 .wakeup = 1,
451 .active_low = 1,
452 },
453 {
454 .type = EV_KEY,
455 .code = TOSA_KEY_SYNC,
456 .gpio = TOSA_GPIO_SYNC,
457 .desc = "Sync Button",
458 .wakeup = 1,
459 .active_low = 1,
460 },
461};
462
463static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
464 .buttons = tosa_gpio_keys,
465 .nbuttons = ARRAY_SIZE(tosa_gpio_keys),
466};
467
468static struct platform_device tosa_gpio_keys_device = {
469 .name = "gpio-keys",
470 .id = -1,
471 .dev = {
472 .platform_data = &tosa_gpio_keys_platform_data,
473 },
474};
475
Dirk Opfer6d0cf3e2006-03-31 02:31:12 -0800476/*
477 * Tosa LEDs
478 */
Dmitry Baryshkovba4eb7e2008-04-19 10:42:25 +0100479static struct gpio_led tosa_gpio_leds[] = {
Dmitry Baryshkov311c7362008-04-12 20:17:02 +0100480 {
481 .name = "tosa:amber:charge",
482 .default_trigger = "main-battery-charging",
483 .gpio = TOSA_GPIO_CHRG_ERR_LED,
484 },
485 {
486 .name = "tosa:green:mail",
487 .default_trigger = "nand-disk",
488 .gpio = TOSA_GPIO_NOTE_LED,
489 },
Dmitry Baryshkovc5461062008-04-19 10:42:06 +0100490 {
491 .name = "tosa:dual:wlan",
492 .default_trigger = "none",
493 .gpio = TOSA_GPIO_WLAN_LED,
494 },
495 {
496 .name = "tosa:blue:bluetooth",
497 .default_trigger = "none",
498 .gpio = TOSA_GPIO_BT_LED,
499 },
Dmitry Baryshkov311c7362008-04-12 20:17:02 +0100500};
501
Dmitry Baryshkovba4eb7e2008-04-19 10:42:25 +0100502static struct gpio_led_platform_data tosa_gpio_leds_platform_data = {
Dmitry Baryshkov311c7362008-04-12 20:17:02 +0100503 .leds = tosa_gpio_leds,
504 .num_leds = ARRAY_SIZE(tosa_gpio_leds),
505};
506
Dirk Opfer6d0cf3e2006-03-31 02:31:12 -0800507static struct platform_device tosaled_device = {
Dmitry Baryshkov311c7362008-04-12 20:17:02 +0100508 .name = "leds-gpio",
509 .id = -1,
510 .dev = {
511 .platform_data = &tosa_gpio_leds_platform_data,
512 },
Dirk Opfer6d0cf3e2006-03-31 02:31:12 -0800513};
514
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +0100515/*
516 * Toshiba Mobile IO Controller
517 */
518static struct resource tc6393xb_resources[] = {
519 [0] = {
520 .start = TOSA_LCDC_PHYS,
521 .end = TOSA_LCDC_PHYS + 0x3ffffff,
522 .flags = IORESOURCE_MEM,
523 },
524
525 [1] = {
526 .start = TOSA_IRQ_GPIO_TC6393XB_INT,
527 .end = TOSA_IRQ_GPIO_TC6393XB_INT,
528 .flags = IORESOURCE_IRQ,
529 },
530};
531
532
533static int tosa_tc6393xb_enable(struct platform_device *dev)
534{
535 int rc;
536
537 rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr");
538 if (rc)
539 goto err_req_pclr;
540 rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
541 if (rc)
542 goto err_req_suspend;
543 rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v");
544 if (rc)
545 goto err_req_l3v;
546 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
547 if (rc)
548 goto err_dir_l3v;
549 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0);
550 if (rc)
551 goto err_dir_suspend;
552 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0);
553 if (rc)
554 goto err_dir_pclr;
555
556 mdelay(1);
557
558 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
559
560 mdelay(10);
561
562 gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1);
563 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
564
565 return 0;
566err_dir_pclr:
567err_dir_suspend:
568err_dir_l3v:
569 gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
570err_req_l3v:
571 gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
572err_req_suspend:
573 gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
574err_req_pclr:
575 return rc;
576}
577
578static int tosa_tc6393xb_disable(struct platform_device *dev)
579{
580 gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
581 gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
582 gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
583
584 return 0;
585}
586
587static int tosa_tc6393xb_resume(struct platform_device *dev)
588{
589 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
590 mdelay(10);
591 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
592 mdelay(10);
593
594 return 0;
595}
596
597static int tosa_tc6393xb_suspend(struct platform_device *dev)
598{
599 gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0);
600 gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0);
601 return 0;
602}
603
604static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
605 .scr_pll2cr = 0x0cc1,
606 .scr_gper = 0x3300,
607 .scr_gpo_dsr =
608 TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
609 .scr_gpo_doecr =
610 TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
611
612 .irq_base = IRQ_BOARD_START,
613 .gpio_base = TOSA_TC6393XB_GPIO_BASE,
614
615 .enable = tosa_tc6393xb_enable,
616 .disable = tosa_tc6393xb_disable,
617 .suspend = tosa_tc6393xb_suspend,
618 .resume = tosa_tc6393xb_resume,
619};
620
621
622static struct platform_device tc6393xb_device = {
623 .name = "tc6393xb",
624 .id = -1,
625 .dev = {
626 .platform_data = &tosa_tc6393xb_setup,
627 },
628 .num_resources = ARRAY_SIZE(tc6393xb_resources),
629 .resource = tc6393xb_resources,
630};
631
Dirk Opfer8459c152005-11-06 14:27:52 +0000632static struct platform_device *devices[] __initdata = {
633 &tosascoop_device,
634 &tosascoop_jc_device,
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +0100635 &tc6393xb_device,
Dirk Opfera93876c2005-11-08 19:15:30 +0000636 &tosakbd_device,
Dmitry Baryshkov93e9012f2008-01-21 01:04:20 -0500637 &tosa_gpio_keys_device,
Dirk Opfer6d0cf3e2006-03-31 02:31:12 -0800638 &tosaled_device,
Dirk Opfer8459c152005-11-06 14:27:52 +0000639};
640
Richard Purdie74617fb2006-06-19 19:57:12 +0100641static void tosa_poweroff(void)
642{
Dmitry Baryshkov86159a92008-05-22 16:21:48 +0100643 arm_machine_restart('g');
Richard Purdie74617fb2006-06-19 19:57:12 +0100644}
645
646static void tosa_restart(char mode)
647{
648 /* Bootloader magic for a reboot */
649 if((MSC0 & 0xffff0000) == 0x7ff00000)
650 MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
651
652 tosa_poweroff();
653}
654
Dirk Opfer8459c152005-11-06 14:27:52 +0000655static void __init tosa_init(void)
656{
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +0100657 int dummy;
658
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +0100659 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
Dmitry Baryshkovb032fcc2008-06-12 11:42:07 +0100660 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off));
Dmitry Baryshkov2cb47342008-04-10 11:00:32 +0100661 gpio_set_wake(MFP_PIN_GPIO1, 1);
662 /* We can't pass to gpio-keys since it will drop the Reset altfunc */
663
Dmitry Baryshkov86159a92008-05-22 16:21:48 +0100664 init_gpio_reset(TOSA_GPIO_ON_RESET);
665
Richard Purdie74617fb2006-06-19 19:57:12 +0100666 pm_power_off = tosa_poweroff;
667 arm_pm_restart = tosa_restart;
668
Dirk Opfer8459c152005-11-06 14:27:52 +0000669 PCFR |= PCFR_OPDE;
670
Dirk Opfera93876c2005-11-08 19:15:30 +0000671 /* enable batt_fault */
Dirk Opfer8459c152005-11-06 14:27:52 +0000672 PMCR = 0x01;
673
Dmitry Baryshkovbf0116e2008-06-14 11:42:02 +0100674 dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12);
675 dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
676 dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
677
Dirk Opfera93876c2005-11-08 19:15:30 +0000678 pxa_set_mci_info(&tosa_mci_platform_data);
679 pxa_set_udc_info(&udc_info);
680 pxa_set_ficp_info(&tosa_ficp_platform_data);
Dmitry Baryshkov481ea5a2008-04-10 15:43:18 +0100681 pxa_set_i2c_info(NULL);
Dirk Opfer4c18ad22005-11-08 19:15:50 +0000682 platform_scoop_config = &tosa_pcmcia_config;
Dirk Opfer8459c152005-11-06 14:27:52 +0000683
Dirk Opfer4c18ad22005-11-08 19:15:50 +0000684 platform_add_devices(devices, ARRAY_SIZE(devices));
Dirk Opfer8459c152005-11-06 14:27:52 +0000685}
686
687static void __init fixup_tosa(struct machine_desc *desc,
688 struct tag *tags, char **cmdline, struct meminfo *mi)
689{
690 sharpsl_save_param();
691 mi->nr_banks=1;
692 mi->bank[0].start = 0xa0000000;
693 mi->bank[0].node = 0;
694 mi->bank[0].size = (64*1024*1024);
695}
696
697MACHINE_START(TOSA, "SHARP Tosa")
Dirk Opfer8459c152005-11-06 14:27:52 +0000698 .phys_io = 0x40000000,
699 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
700 .fixup = fixup_tosa,
701 .map_io = pxa_map_io,
Eric Miaocd491042007-06-22 04:14:09 +0100702 .init_irq = pxa25x_init_irq,
Dirk Opfer8459c152005-11-06 14:27:52 +0000703 .init_machine = tosa_init,
704 .timer = &pxa_timer,
705MACHINE_END