]>
Commit | Line | Data |
---|---|---|
0dd28f1d RP |
1 | /* |
2 | * Support for Sharp SL-Cxx00 Series of PDAs | |
3 | * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi) | |
4 | * | |
5 | * Copyright (c) 2005 Richard Purdie | |
6 | * | |
7 | * Based on Sharp's 2.4 kernel patches/lubbock.c | |
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> | |
d052d1be | 17 | #include <linux/platform_device.h> |
0dd28f1d RP |
18 | #include <linux/delay.h> |
19 | #include <linux/major.h> | |
20 | #include <linux/fs.h> | |
21 | #include <linux/interrupt.h> | |
dd5980d6 | 22 | #include <linux/gpio.h> |
0dd28f1d | 23 | #include <linux/mmc/host.h> |
74617fb6 | 24 | #include <linux/pm.h> |
c3f8f650 | 25 | #include <linux/backlight.h> |
0dd28f1d RP |
26 | |
27 | #include <asm/setup.h> | |
28 | #include <asm/memory.h> | |
29 | #include <asm/mach-types.h> | |
a09e64fb | 30 | #include <mach/hardware.h> |
0dd28f1d RP |
31 | #include <asm/irq.h> |
32 | #include <asm/io.h> | |
74617fb6 | 33 | #include <asm/system.h> |
0dd28f1d RP |
34 | |
35 | #include <asm/mach/arch.h> | |
36 | #include <asm/mach/map.h> | |
37 | #include <asm/mach/irq.h> | |
38 | ||
a09e64fb RK |
39 | #include <mach/pxa-regs.h> |
40 | #include <mach/pxa2xx-regs.h> | |
5e96adec | 41 | #include <mach/mfp-pxa27x.h> |
a09e64fb | 42 | #include <mach/pxa27x-udc.h> |
afd2fc02 | 43 | #include <mach/reset.h> |
f8787fdc | 44 | #include <mach/i2c.h> |
a09e64fb RK |
45 | #include <mach/irda.h> |
46 | #include <mach/mmc.h> | |
47 | #include <mach/ohci.h> | |
48 | #include <mach/udc.h> | |
49 | #include <mach/pxafb.h> | |
50 | #include <mach/akita.h> | |
51 | #include <mach/spitz.h> | |
52 | #include <mach/sharpsl.h> | |
0dd28f1d RP |
53 | |
54 | #include <asm/mach/sharpsl_param.h> | |
55 | #include <asm/hardware/scoop.h> | |
56 | ||
57 | #include "generic.h" | |
46c41e62 | 58 | #include "devices.h" |
0dd28f1d RP |
59 | #include "sharpsl.h" |
60 | ||
5e96adec EM |
61 | static unsigned long spitz_pin_config[] __initdata = { |
62 | /* Chip Selects */ | |
63 | GPIO78_nCS_2, /* SCOOP #2 */ | |
64 | GPIO80_nCS_4, /* SCOOP #1 */ | |
65 | ||
66 | /* LCD - 16bpp Active TFT */ | |
67 | GPIO58_LCD_LDD_0, | |
68 | GPIO59_LCD_LDD_1, | |
69 | GPIO60_LCD_LDD_2, | |
70 | GPIO61_LCD_LDD_3, | |
71 | GPIO62_LCD_LDD_4, | |
72 | GPIO63_LCD_LDD_5, | |
73 | GPIO64_LCD_LDD_6, | |
74 | GPIO65_LCD_LDD_7, | |
75 | GPIO66_LCD_LDD_8, | |
76 | GPIO67_LCD_LDD_9, | |
77 | GPIO68_LCD_LDD_10, | |
78 | GPIO69_LCD_LDD_11, | |
79 | GPIO70_LCD_LDD_12, | |
80 | GPIO71_LCD_LDD_13, | |
81 | GPIO72_LCD_LDD_14, | |
82 | GPIO73_LCD_LDD_15, | |
83 | GPIO74_LCD_FCLK, | |
84 | GPIO75_LCD_LCLK, | |
85 | GPIO76_LCD_PCLK, | |
86 | ||
87 | /* PC Card */ | |
88 | GPIO48_nPOE, | |
89 | GPIO49_nPWE, | |
90 | GPIO50_nPIOR, | |
91 | GPIO51_nPIOW, | |
92 | GPIO85_nPCE_1, | |
93 | GPIO54_nPCE_2, | |
94 | GPIO79_PSKTSEL, | |
95 | GPIO55_nPREG, | |
96 | GPIO56_nPWAIT, | |
97 | GPIO57_nIOIS16, | |
98 | ||
99 | /* MMC */ | |
100 | GPIO32_MMC_CLK, | |
101 | GPIO112_MMC_CMD, | |
102 | GPIO92_MMC_DAT_0, | |
103 | GPIO109_MMC_DAT_1, | |
104 | GPIO110_MMC_DAT_2, | |
105 | GPIO111_MMC_DAT_3, | |
106 | ||
107 | /* GPIOs */ | |
108 | GPIO9_GPIO, /* SPITZ_GPIO_nSD_DETECT */ | |
109 | GPIO81_GPIO, /* SPITZ_GPIO_nSD_WP */ | |
110 | GPIO41_GPIO, /* SPITZ_GPIO_USB_CONNECT */ | |
111 | GPIO37_GPIO, /* SPITZ_GPIO_USB_HOST */ | |
112 | GPIO35_GPIO, /* SPITZ_GPIO_USB_DEVICE */ | |
113 | GPIO22_GPIO, /* SPITZ_GPIO_HSYNC */ | |
114 | GPIO94_GPIO, /* SPITZ_GPIO_CF_CD */ | |
115 | GPIO105_GPIO, /* SPITZ_GPIO_CF_IRQ */ | |
116 | GPIO106_GPIO, /* SPITZ_GPIO_CF2_IRQ */ | |
117 | ||
118 | GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, | |
119 | }; | |
120 | ||
0dd28f1d RP |
121 | /* |
122 | * Spitz SCOOP Device #1 | |
123 | */ | |
124 | static struct resource spitz_scoop_resources[] = { | |
125 | [0] = { | |
126 | .start = 0x10800000, | |
127 | .end = 0x10800fff, | |
128 | .flags = IORESOURCE_MEM, | |
129 | }, | |
130 | }; | |
131 | ||
132 | static struct scoop_config spitz_scoop_setup = { | |
133 | .io_dir = SPITZ_SCP_IO_DIR, | |
134 | .io_out = SPITZ_SCP_IO_OUT, | |
135 | .suspend_clr = SPITZ_SCP_SUS_CLR, | |
136 | .suspend_set = SPITZ_SCP_SUS_SET, | |
137 | }; | |
138 | ||
139 | struct platform_device spitzscoop_device = { | |
140 | .name = "sharp-scoop", | |
141 | .id = 0, | |
142 | .dev = { | |
143 | .platform_data = &spitz_scoop_setup, | |
144 | }, | |
145 | .num_resources = ARRAY_SIZE(spitz_scoop_resources), | |
146 | .resource = spitz_scoop_resources, | |
147 | }; | |
148 | ||
149 | /* | |
150 | * Spitz SCOOP Device #2 | |
151 | */ | |
152 | static struct resource spitz_scoop2_resources[] = { | |
153 | [0] = { | |
154 | .start = 0x08800040, | |
155 | .end = 0x08800fff, | |
156 | .flags = IORESOURCE_MEM, | |
157 | }, | |
158 | }; | |
159 | ||
160 | static struct scoop_config spitz_scoop2_setup = { | |
161 | .io_dir = SPITZ_SCP2_IO_DIR, | |
162 | .io_out = SPITZ_SCP2_IO_OUT, | |
163 | .suspend_clr = SPITZ_SCP2_SUS_CLR, | |
164 | .suspend_set = SPITZ_SCP2_SUS_SET, | |
165 | }; | |
166 | ||
167 | struct platform_device spitzscoop2_device = { | |
168 | .name = "sharp-scoop", | |
169 | .id = 1, | |
170 | .dev = { | |
171 | .platform_data = &spitz_scoop2_setup, | |
172 | }, | |
173 | .num_resources = ARRAY_SIZE(spitz_scoop2_resources), | |
174 | .resource = spitz_scoop2_resources, | |
175 | }; | |
176 | ||
a63ae442 RP |
177 | #define SPITZ_PWR_SD 0x01 |
178 | #define SPITZ_PWR_CF 0x02 | |
179 | ||
180 | /* Power control is shared with between one of the CF slots and SD */ | |
181 | static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) | |
182 | { | |
183 | unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); | |
184 | ||
185 | if (new_cpr & 0x0007) { | |
186 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | |
187 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) | |
188 | mdelay(5); | |
189 | if (device == SPITZ_PWR_CF) | |
190 | cpr |= 0x0002; | |
191 | if (device == SPITZ_PWR_SD) | |
192 | cpr |= 0x0004; | |
193 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | |
194 | } else { | |
195 | if (device == SPITZ_PWR_CF) | |
196 | cpr &= ~0x0002; | |
197 | if (device == SPITZ_PWR_SD) | |
198 | cpr &= ~0x0004; | |
a63ae442 | 199 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) { |
945b9579 | 200 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000); |
a63ae442 RP |
201 | mdelay(1); |
202 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | |
945b9579 RP |
203 | } else { |
204 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | |
a63ae442 RP |
205 | } |
206 | } | |
207 | } | |
208 | ||
a63ae442 RP |
209 | static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr) |
210 | { | |
211 | /* Only need to override behaviour for slot 0 */ | |
212 | if (nr == 0) | |
213 | spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr); | |
214 | else | |
215 | write_scoop_reg(scoop, SCOOP_CPR, cpr); | |
216 | } | |
217 | ||
0dd28f1d RP |
218 | static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { |
219 | { | |
220 | .dev = &spitzscoop_device.dev, | |
221 | .irq = SPITZ_IRQ_GPIO_CF_IRQ, | |
222 | .cd_irq = SPITZ_IRQ_GPIO_CF_CD, | |
223 | .cd_irq_str = "PCMCIA0 CD", | |
224 | },{ | |
225 | .dev = &spitzscoop2_device.dev, | |
226 | .irq = SPITZ_IRQ_GPIO_CF2_IRQ, | |
227 | .cd_irq = -1, | |
228 | }, | |
229 | }; | |
230 | ||
a63ae442 RP |
231 | static struct scoop_pcmcia_config spitz_pcmcia_config = { |
232 | .devs = &spitz_pcmcia_scoop[0], | |
233 | .num_devs = 2, | |
a63ae442 RP |
234 | .power_ctrl = spitz_pcmcia_pwr, |
235 | }; | |
236 | ||
237 | EXPORT_SYMBOL(spitzscoop_device); | |
238 | EXPORT_SYMBOL(spitzscoop2_device); | |
239 | ||
0dd28f1d RP |
240 | |
241 | /* | |
242 | * Spitz SSP Device | |
243 | * | |
244 | * Set the parent as the scoop device because a lot of SSP devices | |
245 | * also use scoop functions and this makes the power up/down order | |
246 | * work correctly. | |
247 | */ | |
248 | struct platform_device spitzssp_device = { | |
249 | .name = "corgi-ssp", | |
250 | .dev = { | |
251 | .parent = &spitzscoop_device.dev, | |
252 | }, | |
253 | .id = -1, | |
254 | }; | |
255 | ||
256 | struct corgissp_machinfo spitz_ssp_machinfo = { | |
257 | .port = 2, | |
258 | .cs_lcdcon = SPITZ_GPIO_LCDCON_CS, | |
259 | .cs_ads7846 = SPITZ_GPIO_ADS7846_CS, | |
260 | .cs_max1111 = SPITZ_GPIO_MAX1111_CS, | |
261 | .clk_lcdcon = 520, | |
262 | .clk_ads7846 = 14, | |
263 | .clk_max1111 = 56, | |
264 | }; | |
265 | ||
266 | ||
267 | /* | |
268 | * Spitz Backlight Device | |
269 | */ | |
c3f8f650 RP |
270 | static void spitz_bl_kick_battery(void) |
271 | { | |
272 | void (*kick_batt)(void); | |
273 | ||
274 | kick_batt = symbol_get(sharpsl_battery_kick); | |
275 | if (kick_batt) { | |
276 | kick_batt(); | |
277 | symbol_put(sharpsl_battery_kick); | |
278 | } | |
279 | } | |
280 | ||
281 | static struct generic_bl_info spitz_bl_machinfo = { | |
282 | .name = "corgi-bl", | |
2c0f5fb0 RP |
283 | .default_intensity = 0x1f, |
284 | .limit_mask = 0x0b, | |
0dd28f1d | 285 | .max_intensity = 0x2f, |
c3f8f650 | 286 | .kick_battery = spitz_bl_kick_battery, |
0dd28f1d RP |
287 | }; |
288 | ||
289 | static struct platform_device spitzbl_device = { | |
c3f8f650 | 290 | .name = "generic-bl", |
0dd28f1d RP |
291 | .dev = { |
292 | .platform_data = &spitz_bl_machinfo, | |
293 | }, | |
294 | .id = -1, | |
295 | }; | |
296 | ||
297 | ||
298 | /* | |
299 | * Spitz Keyboard Device | |
300 | */ | |
301 | static struct platform_device spitzkbd_device = { | |
302 | .name = "spitz-keyboard", | |
303 | .id = -1, | |
304 | }; | |
305 | ||
306 | ||
3179108d RP |
307 | /* |
308 | * Spitz LEDs | |
309 | */ | |
310 | static struct platform_device spitzled_device = { | |
311 | .name = "spitz-led", | |
312 | .id = -1, | |
313 | }; | |
314 | ||
0dd28f1d RP |
315 | /* |
316 | * Spitz Touch Screen Device | |
317 | */ | |
ca4d6cfc RP |
318 | |
319 | static unsigned long (*get_hsync_invperiod)(struct device *dev); | |
320 | ||
321 | static void inline sharpsl_wait_sync(int gpio) | |
322 | { | |
323 | while((GPLR(gpio) & GPIO_bit(gpio)) == 0); | |
324 | while((GPLR(gpio) & GPIO_bit(gpio)) != 0); | |
325 | } | |
326 | ||
327 | static struct device *spitz_pxafb_dev; | |
328 | ||
329 | static int is_pxafb_device(struct device * dev, void * data) | |
330 | { | |
331 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | |
332 | ||
333 | return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0); | |
334 | } | |
335 | ||
336 | static unsigned long spitz_get_hsync_invperiod(void) | |
337 | { | |
338 | #ifdef CONFIG_FB_PXA | |
339 | if (!spitz_pxafb_dev) { | |
340 | spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device); | |
341 | if (!spitz_pxafb_dev) | |
342 | return 0; | |
343 | } | |
344 | if (!get_hsync_invperiod) | |
345 | get_hsync_invperiod = symbol_get(pxafb_get_hsync_time); | |
346 | if (!get_hsync_invperiod) | |
347 | #endif | |
348 | return 0; | |
349 | ||
350 | return get_hsync_invperiod(spitz_pxafb_dev); | |
351 | } | |
352 | ||
353 | static void spitz_put_hsync(void) | |
354 | { | |
355 | put_device(spitz_pxafb_dev); | |
356 | if (get_hsync_invperiod) | |
357 | symbol_put(pxafb_get_hsync_time); | |
358 | spitz_pxafb_dev = NULL; | |
359 | get_hsync_invperiod = NULL; | |
360 | } | |
361 | ||
362 | static void spitz_wait_hsync(void) | |
363 | { | |
364 | sharpsl_wait_sync(SPITZ_GPIO_HSYNC); | |
365 | } | |
366 | ||
0dd28f1d RP |
367 | static struct resource spitzts_resources[] = { |
368 | [0] = { | |
369 | .start = SPITZ_IRQ_GPIO_TP_INT, | |
370 | .end = SPITZ_IRQ_GPIO_TP_INT, | |
371 | .flags = IORESOURCE_IRQ, | |
372 | }, | |
373 | }; | |
374 | ||
375 | static struct corgits_machinfo spitz_ts_machinfo = { | |
ca4d6cfc RP |
376 | .get_hsync_invperiod = spitz_get_hsync_invperiod, |
377 | .put_hsync = spitz_put_hsync, | |
378 | .wait_hsync = spitz_wait_hsync, | |
0dd28f1d RP |
379 | }; |
380 | ||
381 | static struct platform_device spitzts_device = { | |
382 | .name = "corgi-ts", | |
383 | .dev = { | |
384 | .parent = &spitzssp_device.dev, | |
385 | .platform_data = &spitz_ts_machinfo, | |
386 | }, | |
387 | .id = -1, | |
388 | .num_resources = ARRAY_SIZE(spitzts_resources), | |
389 | .resource = spitzts_resources, | |
390 | }; | |
391 | ||
392 | ||
393 | /* | |
394 | * MMC/SD Device | |
395 | * | |
396 | * The card detect interrupt isn't debounced so we delay it by 250ms | |
397 | * to give the card a chance to fully insert/eject. | |
398 | */ | |
399 | ||
400 | static struct pxamci_platform_data spitz_mci_platform_data; | |
401 | ||
40220c1a | 402 | static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, void *data) |
0dd28f1d RP |
403 | { |
404 | int err; | |
405 | ||
dd5980d6 EM |
406 | err = gpio_request(SPITZ_GPIO_nSD_DETECT, "nSD_DETECT"); |
407 | if (err) | |
408 | goto err_out; | |
409 | ||
410 | err = gpio_request(SPITZ_GPIO_nSD_WP, "nSD_WP"); | |
411 | if (err) | |
412 | goto err_free_1; | |
413 | ||
414 | gpio_direction_input(SPITZ_GPIO_nSD_DETECT); | |
415 | gpio_direction_input(SPITZ_GPIO_nSD_WP); | |
0dd28f1d RP |
416 | |
417 | spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); | |
418 | ||
9ded96f2 | 419 | err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, |
dd5980d6 EM |
420 | IRQF_DISABLED | IRQF_TRIGGER_RISING | |
421 | IRQF_TRIGGER_FALLING, | |
9ded96f2 | 422 | "MMC card detect", data); |
dd5980d6 EM |
423 | if (err) { |
424 | pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n", | |
425 | __func__); | |
426 | goto err_free_2; | |
427 | } | |
428 | return 0; | |
0dd28f1d | 429 | |
dd5980d6 EM |
430 | err_free_2: |
431 | gpio_free(SPITZ_GPIO_nSD_WP); | |
432 | err_free_1: | |
433 | gpio_free(SPITZ_GPIO_nSD_DETECT); | |
434 | err_out: | |
2687bd38 | 435 | return err; |
0dd28f1d RP |
436 | } |
437 | ||
0dd28f1d RP |
438 | static void spitz_mci_setpower(struct device *dev, unsigned int vdd) |
439 | { | |
440 | struct pxamci_platform_data* p_d = dev->platform_data; | |
441 | ||
a63ae442 RP |
442 | if (( 1 << vdd) & p_d->ocr_mask) |
443 | spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004); | |
444 | else | |
445 | spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000); | |
0dd28f1d RP |
446 | } |
447 | ||
448 | static int spitz_mci_get_ro(struct device *dev) | |
449 | { | |
dd5980d6 | 450 | return gpio_get_value(SPITZ_GPIO_nSD_WP); |
0dd28f1d RP |
451 | } |
452 | ||
453 | static void spitz_mci_exit(struct device *dev, void *data) | |
454 | { | |
455 | free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data); | |
dd5980d6 EM |
456 | gpio_free(SPITZ_GPIO_nSD_WP); |
457 | gpio_free(SPITZ_GPIO_nSD_DETECT); | |
0dd28f1d RP |
458 | } |
459 | ||
460 | static struct pxamci_platform_data spitz_mci_platform_data = { | |
461 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | |
462 | .init = spitz_mci_init, | |
463 | .get_ro = spitz_mci_get_ro, | |
464 | .setpower = spitz_mci_setpower, | |
465 | .exit = spitz_mci_exit, | |
466 | }; | |
467 | ||
468 | ||
3125c68d RP |
469 | /* |
470 | * USB Host (OHCI) | |
471 | */ | |
472 | static int spitz_ohci_init(struct device *dev) | |
473 | { | |
dd5980d6 EM |
474 | int err; |
475 | ||
476 | err = gpio_request(SPITZ_GPIO_USB_HOST, "USB_HOST"); | |
477 | if (err) | |
478 | return err; | |
479 | ||
5e96adec EM |
480 | /* Only Port 2 is connected |
481 | * Setup USB Port 2 Output Control Register | |
482 | */ | |
3125c68d RP |
483 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; |
484 | ||
dd5980d6 | 485 | gpio_direction_output(SPITZ_GPIO_USB_HOST, 1); |
3125c68d RP |
486 | |
487 | UHCHR = (UHCHR) & | |
488 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | |
489 | ||
490 | UHCRHDA |= UHCRHDA_NOCP; | |
491 | ||
492 | return 0; | |
493 | } | |
494 | ||
495 | static struct pxaohci_platform_data spitz_ohci_platform_data = { | |
496 | .port_mode = PMM_NPS_MODE, | |
497 | .init = spitz_ohci_init, | |
0c27c5d5 | 498 | .power_budget = 150, |
3125c68d RP |
499 | }; |
500 | ||
501 | ||
dc07845d RP |
502 | /* |
503 | * Irda | |
504 | */ | |
505 | static void spitz_irda_transceiver_mode(struct device *dev, int mode) | |
506 | { | |
507 | if (mode & IR_OFF) | |
508 | set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); | |
509 | else | |
510 | reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); | |
0fc3ff31 | 511 | pxa2xx_transceiver_mode(dev, mode); |
dc07845d RP |
512 | } |
513 | ||
94cabd00 RP |
514 | #ifdef CONFIG_MACH_AKITA |
515 | static void akita_irda_transceiver_mode(struct device *dev, int mode) | |
516 | { | |
517 | if (mode & IR_OFF) | |
518 | akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON); | |
519 | else | |
520 | akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON); | |
0fc3ff31 | 521 | pxa2xx_transceiver_mode(dev, mode); |
94cabd00 RP |
522 | } |
523 | #endif | |
524 | ||
dc07845d RP |
525 | static struct pxaficp_platform_data spitz_ficp_platform_data = { |
526 | .transceiver_cap = IR_SIRMODE | IR_OFF, | |
527 | .transceiver_mode = spitz_irda_transceiver_mode, | |
528 | }; | |
529 | ||
530 | ||
0dd28f1d RP |
531 | /* |
532 | * Spitz PXA Framebuffer | |
533 | */ | |
d14b272b | 534 | |
ca4d6cfc RP |
535 | static void spitz_lcd_power(int on, struct fb_var_screeninfo *var) |
536 | { | |
537 | if (on) | |
538 | corgi_lcdtg_hw_init(var->xres); | |
539 | else | |
540 | corgi_lcdtg_suspend(); | |
541 | } | |
542 | ||
d14b272b RP |
543 | static struct pxafb_mode_info spitz_pxafb_modes[] = { |
544 | { | |
545 | .pixclock = 19231, | |
546 | .xres = 480, | |
547 | .yres = 640, | |
548 | .bpp = 16, | |
549 | .hsync_len = 40, | |
550 | .left_margin = 46, | |
551 | .right_margin = 125, | |
552 | .vsync_len = 3, | |
553 | .upper_margin = 1, | |
554 | .lower_margin = 0, | |
555 | .sync = 0, | |
556 | },{ | |
557 | .pixclock = 134617, | |
558 | .xres = 240, | |
559 | .yres = 320, | |
560 | .bpp = 16, | |
561 | .hsync_len = 20, | |
562 | .left_margin = 20, | |
563 | .right_margin = 46, | |
564 | .vsync_len = 2, | |
565 | .upper_margin = 1, | |
566 | .lower_margin = 0, | |
567 | .sync = 0, | |
568 | }, | |
569 | }; | |
570 | ||
571 | static struct pxafb_mach_info spitz_pxafb_info = { | |
572 | .modes = &spitz_pxafb_modes[0], | |
573 | .num_modes = 2, | |
574 | .fixed_modes = 1, | |
575 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM, | |
576 | .lccr3 = LCCR3_PixRsEdg | LCCR3_OutEnH, | |
577 | .pxafb_lcd_power = spitz_lcd_power, | |
0dd28f1d RP |
578 | }; |
579 | ||
580 | ||
581 | static struct platform_device *devices[] __initdata = { | |
582 | &spitzscoop_device, | |
583 | &spitzssp_device, | |
584 | &spitzkbd_device, | |
585 | &spitzts_device, | |
586 | &spitzbl_device, | |
3179108d | 587 | &spitzled_device, |
0dd28f1d RP |
588 | }; |
589 | ||
74617fb6 RP |
590 | static void spitz_poweroff(void) |
591 | { | |
86159a98 | 592 | arm_machine_restart('g'); |
74617fb6 RP |
593 | } |
594 | ||
595 | static void spitz_restart(char mode) | |
596 | { | |
597 | /* Bootloader magic for a reboot */ | |
598 | if((MSC0 & 0xffff0000) == 0x7ff00000) | |
599 | MSC0 = (MSC0 & 0xffff) | 0x7ee00000; | |
600 | ||
601 | spitz_poweroff(); | |
602 | } | |
603 | ||
0dd28f1d RP |
604 | static void __init common_init(void) |
605 | { | |
86159a98 | 606 | init_gpio_reset(SPITZ_GPIO_ON_RESET); |
74617fb6 RP |
607 | pm_power_off = spitz_poweroff; |
608 | arm_pm_restart = spitz_restart; | |
609 | ||
0dd28f1d RP |
610 | PMCR = 0x00; |
611 | ||
0dd28f1d RP |
612 | /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ |
613 | PCFR |= PCFR_OPDE; | |
614 | ||
5e96adec | 615 | pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config)); |
0dd28f1d | 616 | |
5e96adec | 617 | corgi_ssp_set_machinfo(&spitz_ssp_machinfo); |
0dd28f1d RP |
618 | |
619 | platform_add_devices(devices, ARRAY_SIZE(devices)); | |
620 | pxa_set_mci_info(&spitz_mci_platform_data); | |
3125c68d | 621 | pxa_set_ohci_info(&spitz_ohci_platform_data); |
dc07845d | 622 | pxa_set_ficp_info(&spitz_ficp_platform_data); |
cb38c569 | 623 | set_pxa_fb_parent(&spitzssp_device.dev); |
0dd28f1d | 624 | set_pxa_fb_info(&spitz_pxafb_info); |
f8787fdc | 625 | pxa_set_i2c_info(NULL); |
0dd28f1d RP |
626 | } |
627 | ||
ca4d6cfc RP |
628 | #if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI) |
629 | static void spitz_bl_set_intensity(int intensity) | |
630 | { | |
631 | if (intensity > 0x10) | |
632 | intensity += 0x10; | |
633 | ||
634 | /* Bits 0-4 are accessed via the SSP interface */ | |
635 | corgi_ssp_blduty_set(intensity & 0x1f); | |
636 | ||
637 | /* Bit 5 is via SCOOP */ | |
638 | if (intensity & 0x0020) | |
639 | reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); | |
640 | else | |
641 | set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT); | |
642 | ||
643 | if (intensity) | |
644 | set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); | |
645 | else | |
646 | reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON); | |
647 | } | |
648 | ||
0dd28f1d RP |
649 | static void __init spitz_init(void) |
650 | { | |
a63ae442 RP |
651 | platform_scoop_config = &spitz_pcmcia_config; |
652 | ||
0dd28f1d RP |
653 | spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; |
654 | ||
655 | common_init(); | |
656 | ||
657 | platform_device_register(&spitzscoop2_device); | |
658 | } | |
ca4d6cfc | 659 | #endif |
0dd28f1d | 660 | |
94cabd00 RP |
661 | #ifdef CONFIG_MACH_AKITA |
662 | /* | |
663 | * Akita IO Expander | |
664 | */ | |
665 | struct platform_device akitaioexp_device = { | |
666 | .name = "akita-ioexp", | |
667 | .id = -1, | |
668 | }; | |
669 | ||
bd8f103e RP |
670 | EXPORT_SYMBOL_GPL(akitaioexp_device); |
671 | ||
ca4d6cfc RP |
672 | static void akita_bl_set_intensity(int intensity) |
673 | { | |
674 | if (intensity > 0x10) | |
675 | intensity += 0x10; | |
676 | ||
677 | /* Bits 0-4 are accessed via the SSP interface */ | |
678 | corgi_ssp_blduty_set(intensity & 0x1f); | |
679 | ||
680 | /* Bit 5 is via IO-Expander */ | |
681 | if (intensity & 0x0020) | |
682 | akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); | |
683 | else | |
684 | akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT); | |
685 | ||
686 | if (intensity) | |
687 | akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); | |
688 | else | |
689 | akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON); | |
690 | } | |
691 | ||
94cabd00 RP |
692 | static void __init akita_init(void) |
693 | { | |
694 | spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode; | |
695 | ||
696 | /* We just pretend the second element of the array doesn't exist */ | |
697 | spitz_pcmcia_config.num_devs = 1; | |
698 | platform_scoop_config = &spitz_pcmcia_config; | |
699 | spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity; | |
700 | ||
701 | platform_device_register(&akitaioexp_device); | |
702 | ||
703 | spitzscoop_device.dev.parent = &akitaioexp_device.dev; | |
704 | common_init(); | |
705 | } | |
706 | #endif | |
707 | ||
0dd28f1d RP |
708 | static void __init fixup_spitz(struct machine_desc *desc, |
709 | struct tag *tags, char **cmdline, struct meminfo *mi) | |
710 | { | |
711 | sharpsl_save_param(); | |
712 | mi->nr_banks = 1; | |
713 | mi->bank[0].start = 0xa0000000; | |
714 | mi->bank[0].node = 0; | |
715 | mi->bank[0].size = (64*1024*1024); | |
716 | } | |
717 | ||
718 | #ifdef CONFIG_MACH_SPITZ | |
719 | MACHINE_START(SPITZ, "SHARP Spitz") | |
0dd28f1d RP |
720 | .phys_io = 0x40000000, |
721 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | |
722 | .fixup = fixup_spitz, | |
723 | .map_io = pxa_map_io, | |
cd49104d | 724 | .init_irq = pxa27x_init_irq, |
0dd28f1d RP |
725 | .init_machine = spitz_init, |
726 | .timer = &pxa_timer, | |
727 | MACHINE_END | |
728 | #endif | |
729 | ||
730 | #ifdef CONFIG_MACH_BORZOI | |
731 | MACHINE_START(BORZOI, "SHARP Borzoi") | |
0dd28f1d RP |
732 | .phys_io = 0x40000000, |
733 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | |
734 | .fixup = fixup_spitz, | |
735 | .map_io = pxa_map_io, | |
cd49104d | 736 | .init_irq = pxa27x_init_irq, |
0dd28f1d RP |
737 | .init_machine = spitz_init, |
738 | .timer = &pxa_timer, | |
739 | MACHINE_END | |
740 | #endif | |
94cabd00 RP |
741 | |
742 | #ifdef CONFIG_MACH_AKITA | |
743 | MACHINE_START(AKITA, "SHARP Akita") | |
94cabd00 RP |
744 | .phys_io = 0x40000000, |
745 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | |
746 | .fixup = fixup_spitz, | |
747 | .map_io = pxa_map_io, | |
cd49104d | 748 | .init_irq = pxa27x_init_irq, |
94cabd00 RP |
749 | .init_machine = akita_init, |
750 | .timer = &pxa_timer, | |
751 | MACHINE_END | |
752 | #endif |