diff options
Diffstat (limited to 'arch/arm/mach-pxa/em-x270.c')
-rw-r--r-- | arch/arm/mach-pxa/em-x270.c | 607 |
1 files changed, 556 insertions, 51 deletions
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index f5ed8038ede5..920dfb8d36da 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -11,40 +11,63 @@ | |||
11 | 11 | ||
12 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/delay.h> | ||
14 | 15 | ||
15 | #include <linux/dm9000.h> | 16 | #include <linux/dm9000.h> |
16 | #include <linux/rtc-v3020.h> | 17 | #include <linux/rtc-v3020.h> |
17 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
18 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mtd/physmap.h> | ||
19 | #include <linux/input.h> | 21 | #include <linux/input.h> |
20 | #include <linux/gpio_keys.h> | 22 | #include <linux/gpio_keys.h> |
21 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/mfd/da903x.h> | ||
25 | #include <linux/regulator/machine.h> | ||
26 | #include <linux/spi/spi.h> | ||
27 | #include <linux/spi/tdo24m.h> | ||
28 | #include <linux/power_supply.h> | ||
29 | #include <linux/apm-emulation.h> | ||
30 | |||
31 | #include <media/soc_camera.h> | ||
22 | 32 | ||
23 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 34 | #include <asm/mach/arch.h> |
25 | 35 | ||
26 | #include <mach/mfp-pxa27x.h> | 36 | #include <mach/pxa27x.h> |
27 | #include <mach/pxa-regs.h> | ||
28 | #include <mach/pxa27x-udc.h> | 37 | #include <mach/pxa27x-udc.h> |
29 | #include <mach/audio.h> | 38 | #include <mach/audio.h> |
30 | #include <mach/pxafb.h> | 39 | #include <mach/pxafb.h> |
31 | #include <mach/ohci.h> | 40 | #include <mach/ohci.h> |
32 | #include <mach/mmc.h> | 41 | #include <mach/mmc.h> |
33 | #include <mach/pxa27x_keypad.h> | 42 | #include <mach/pxa27x_keypad.h> |
43 | #include <mach/i2c.h> | ||
44 | #include <mach/camera.h> | ||
45 | #include <mach/pxa2xx_spi.h> | ||
34 | 46 | ||
35 | #include "generic.h" | 47 | #include "generic.h" |
48 | #include "devices.h" | ||
36 | 49 | ||
37 | /* GPIO IRQ usage */ | 50 | /* EM-X270 specific GPIOs */ |
38 | #define GPIO41_ETHIRQ (41) | ||
39 | #define GPIO13_MMC_CD (13) | 51 | #define GPIO13_MMC_CD (13) |
52 | #define GPIO95_MMC_WP (95) | ||
53 | #define GPIO56_NAND_RB (56) | ||
54 | |||
55 | /* eXeda specific GPIOs */ | ||
56 | #define GPIO114_MMC_CD (114) | ||
57 | #define GPIO20_NAND_RB (20) | ||
58 | #define GPIO38_SD_PWEN (38) | ||
59 | |||
60 | /* common GPIOs */ | ||
61 | #define GPIO11_NAND_CS (11) | ||
62 | #define GPIO93_CAM_RESET (93) | ||
63 | #define GPIO41_ETHIRQ (41) | ||
40 | #define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) | 64 | #define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) |
41 | #define EM_X270_MMC_CD IRQ_GPIO(GPIO13_MMC_CD) | ||
42 | 65 | ||
43 | /* NAND control GPIOs */ | 66 | static int mmc_cd; |
44 | #define GPIO11_NAND_CS (11) | 67 | static int nand_rb; |
45 | #define GPIO56_NAND_RB (56) | 68 | static int dm9000_flags; |
46 | 69 | ||
47 | static unsigned long em_x270_pin_config[] = { | 70 | static unsigned long common_pin_config[] = { |
48 | /* AC'97 */ | 71 | /* AC'97 */ |
49 | GPIO28_AC97_BITCLK, | 72 | GPIO28_AC97_BITCLK, |
50 | GPIO29_AC97_SDATA_IN_0, | 73 | GPIO29_AC97_SDATA_IN_0, |
@@ -150,21 +173,32 @@ static unsigned long em_x270_pin_config[] = { | |||
150 | GPIO18_RDY, | 173 | GPIO18_RDY, |
151 | 174 | ||
152 | /* GPIO */ | 175 | /* GPIO */ |
153 | GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, | 176 | GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */ |
154 | 177 | ||
155 | /* power controls */ | 178 | /* power controls */ |
156 | GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ | 179 | GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ |
180 | GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */ | ||
157 | GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ | 181 | GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ |
158 | 182 | ||
159 | /* NAND controls */ | 183 | /* NAND controls */ |
160 | GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ | 184 | GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ |
161 | GPIO56_GPIO, /* NAND Ready/Busy */ | ||
162 | 185 | ||
163 | /* interrupts */ | 186 | /* interrupts */ |
164 | GPIO13_GPIO, /* MMC card detect */ | ||
165 | GPIO41_GPIO, /* DM9000 interrupt */ | 187 | GPIO41_GPIO, /* DM9000 interrupt */ |
166 | }; | 188 | }; |
167 | 189 | ||
190 | static unsigned long em_x270_pin_config[] = { | ||
191 | GPIO13_GPIO, /* MMC card detect */ | ||
192 | GPIO56_GPIO, /* NAND Ready/Busy */ | ||
193 | GPIO95_GPIO, /* MMC Write protect */ | ||
194 | }; | ||
195 | |||
196 | static unsigned long exeda_pin_config[] = { | ||
197 | GPIO20_GPIO, /* NAND Ready/Busy */ | ||
198 | GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */ | ||
199 | GPIO114_GPIO, /* MMC card detect */ | ||
200 | }; | ||
201 | |||
168 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) | 202 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) |
169 | static struct resource em_x270_dm9000_resource[] = { | 203 | static struct resource em_x270_dm9000_resource[] = { |
170 | [0] = { | 204 | [0] = { |
@@ -185,7 +219,7 @@ static struct resource em_x270_dm9000_resource[] = { | |||
185 | }; | 219 | }; |
186 | 220 | ||
187 | static struct dm9000_plat_data em_x270_dm9000_platdata = { | 221 | static struct dm9000_plat_data em_x270_dm9000_platdata = { |
188 | .flags = DM9000_PLATF_32BITONLY, | 222 | .flags = DM9000_PLATF_NO_EEPROM, |
189 | }; | 223 | }; |
190 | 224 | ||
191 | static struct platform_device em_x270_dm9000 = { | 225 | static struct platform_device em_x270_dm9000 = { |
@@ -200,6 +234,7 @@ static struct platform_device em_x270_dm9000 = { | |||
200 | 234 | ||
201 | static void __init em_x270_init_dm9000(void) | 235 | static void __init em_x270_init_dm9000(void) |
202 | { | 236 | { |
237 | em_x270_dm9000_platdata.flags |= dm9000_flags; | ||
203 | platform_device_register(&em_x270_dm9000); | 238 | platform_device_register(&em_x270_dm9000); |
204 | } | 239 | } |
205 | #else | 240 | #else |
@@ -289,7 +324,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd) | |||
289 | { | 324 | { |
290 | dsb(); | 325 | dsb(); |
291 | 326 | ||
292 | return gpio_get_value(GPIO56_NAND_RB); | 327 | return gpio_get_value(nand_rb); |
293 | } | 328 | } |
294 | 329 | ||
295 | static struct mtd_partition em_x270_partition_info[] = { | 330 | static struct mtd_partition em_x270_partition_info[] = { |
@@ -354,14 +389,14 @@ static void __init em_x270_init_nand(void) | |||
354 | 389 | ||
355 | gpio_direction_output(GPIO11_NAND_CS, 1); | 390 | gpio_direction_output(GPIO11_NAND_CS, 1); |
356 | 391 | ||
357 | err = gpio_request(GPIO56_NAND_RB, "NAND R/B"); | 392 | err = gpio_request(nand_rb, "NAND R/B"); |
358 | if (err) { | 393 | if (err) { |
359 | pr_warning("EM-X270: failed to request NAND R/B gpio\n"); | 394 | pr_warning("EM-X270: failed to request NAND R/B gpio\n"); |
360 | gpio_free(GPIO11_NAND_CS); | 395 | gpio_free(GPIO11_NAND_CS); |
361 | return; | 396 | return; |
362 | } | 397 | } |
363 | 398 | ||
364 | gpio_direction_input(GPIO56_NAND_RB); | 399 | gpio_direction_input(nand_rb); |
365 | 400 | ||
366 | platform_device_register(&em_x270_nand); | 401 | platform_device_register(&em_x270_nand); |
367 | } | 402 | } |
@@ -369,6 +404,61 @@ static void __init em_x270_init_nand(void) | |||
369 | static inline void em_x270_init_nand(void) {} | 404 | static inline void em_x270_init_nand(void) {} |
370 | #endif | 405 | #endif |
371 | 406 | ||
407 | #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) | ||
408 | static struct mtd_partition em_x270_nor_parts[] = { | ||
409 | { | ||
410 | .name = "Bootloader", | ||
411 | .offset = 0x00000000, | ||
412 | .size = 0x00050000, | ||
413 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
414 | }, { | ||
415 | .name = "Environment", | ||
416 | .offset = 0x00050000, | ||
417 | .size = 0x00010000, | ||
418 | }, { | ||
419 | .name = "Reserved", | ||
420 | .offset = 0x00060000, | ||
421 | .size = 0x00050000, | ||
422 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
423 | }, { | ||
424 | .name = "Splashscreen", | ||
425 | .offset = 0x000b0000, | ||
426 | .size = 0x00050000, | ||
427 | } | ||
428 | }; | ||
429 | |||
430 | static struct physmap_flash_data em_x270_nor_data[] = { | ||
431 | [0] = { | ||
432 | .width = 2, | ||
433 | .parts = em_x270_nor_parts, | ||
434 | .nr_parts = ARRAY_SIZE(em_x270_nor_parts), | ||
435 | }, | ||
436 | }; | ||
437 | |||
438 | static struct resource em_x270_nor_flash_resource = { | ||
439 | .start = PXA_CS0_PHYS, | ||
440 | .end = PXA_CS0_PHYS + SZ_1M - 1, | ||
441 | .flags = IORESOURCE_MEM, | ||
442 | }; | ||
443 | |||
444 | static struct platform_device em_x270_physmap_flash = { | ||
445 | .name = "physmap-flash", | ||
446 | .id = 0, | ||
447 | .num_resources = 1, | ||
448 | .resource = &em_x270_nor_flash_resource, | ||
449 | .dev = { | ||
450 | .platform_data = &em_x270_nor_data, | ||
451 | }, | ||
452 | }; | ||
453 | |||
454 | static void __init em_x270_init_nor(void) | ||
455 | { | ||
456 | platform_device_register(&em_x270_physmap_flash); | ||
457 | } | ||
458 | #else | ||
459 | static inline void em_x270_init_nor(void) {} | ||
460 | #endif | ||
461 | |||
372 | /* PXA27x OHCI controller setup */ | 462 | /* PXA27x OHCI controller setup */ |
373 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 463 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
374 | static int em_x270_ohci_init(struct device *dev) | 464 | static int em_x270_ohci_init(struct device *dev) |
@@ -395,40 +485,93 @@ static inline void em_x270_init_ohci(void) {} | |||
395 | 485 | ||
396 | /* MCI controller setup */ | 486 | /* MCI controller setup */ |
397 | #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) | 487 | #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) |
488 | static struct regulator *em_x270_sdio_ldo; | ||
489 | |||
398 | static int em_x270_mci_init(struct device *dev, | 490 | static int em_x270_mci_init(struct device *dev, |
399 | irq_handler_t em_x270_detect_int, | 491 | irq_handler_t em_x270_detect_int, |
400 | void *data) | 492 | void *data) |
401 | { | 493 | { |
402 | int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int, | 494 | int err; |
403 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | 495 | |
496 | em_x270_sdio_ldo = regulator_get(dev, "vcc sdio"); | ||
497 | if (IS_ERR(em_x270_sdio_ldo)) { | ||
498 | dev_err(dev, "can't request SDIO power supply: %ld\n", | ||
499 | PTR_ERR(em_x270_sdio_ldo)); | ||
500 | return PTR_ERR(em_x270_sdio_ldo); | ||
501 | } | ||
502 | |||
503 | err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int, | ||
504 | IRQF_DISABLED | IRQF_TRIGGER_RISING | | ||
505 | IRQF_TRIGGER_FALLING, | ||
404 | "MMC card detect", data); | 506 | "MMC card detect", data); |
405 | if (err) { | 507 | if (err) { |
406 | printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", | 508 | dev_err(dev, "can't request MMC card detect IRQ: %d\n", err); |
407 | __func__, err); | 509 | goto err_irq; |
408 | return err; | 510 | } |
511 | |||
512 | if (machine_is_em_x270()) { | ||
513 | err = gpio_request(GPIO95_MMC_WP, "MMC WP"); | ||
514 | if (err) { | ||
515 | dev_err(dev, "can't request MMC write protect: %d\n", | ||
516 | err); | ||
517 | goto err_gpio_wp; | ||
518 | } | ||
519 | gpio_direction_input(GPIO95_MMC_WP); | ||
520 | } else { | ||
521 | err = gpio_request(GPIO38_SD_PWEN, "sdio power"); | ||
522 | if (err) { | ||
523 | dev_err(dev, "can't request MMC power control : %d\n", | ||
524 | err); | ||
525 | goto err_gpio_wp; | ||
526 | } | ||
527 | gpio_direction_output(GPIO38_SD_PWEN, 1); | ||
409 | } | 528 | } |
410 | 529 | ||
411 | return 0; | 530 | return 0; |
531 | |||
532 | err_gpio_wp: | ||
533 | free_irq(gpio_to_irq(mmc_cd), data); | ||
534 | err_irq: | ||
535 | regulator_put(em_x270_sdio_ldo); | ||
536 | |||
537 | return err; | ||
412 | } | 538 | } |
413 | 539 | ||
414 | static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) | 540 | static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) |
415 | { | 541 | { |
416 | /* | 542 | struct pxamci_platform_data* p_d = dev->platform_data; |
417 | FIXME: current hardware implementation does not allow to | 543 | |
418 | enable/disable MMC power. This will be fixed in next HW releases, | 544 | if ((1 << vdd) & p_d->ocr_mask) { |
419 | and we'll need to add implmentation here. | 545 | int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000; |
420 | */ | 546 | |
421 | return; | 547 | regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV); |
548 | regulator_enable(em_x270_sdio_ldo); | ||
549 | } else { | ||
550 | regulator_disable(em_x270_sdio_ldo); | ||
551 | } | ||
422 | } | 552 | } |
423 | 553 | ||
424 | static void em_x270_mci_exit(struct device *dev, void *data) | 554 | static void em_x270_mci_exit(struct device *dev, void *data) |
425 | { | 555 | { |
426 | int irq = gpio_to_irq(GPIO13_MMC_CD); | 556 | free_irq(gpio_to_irq(mmc_cd), data); |
427 | free_irq(irq, data); | 557 | regulator_put(em_x270_sdio_ldo); |
558 | |||
559 | if (machine_is_em_x270()) | ||
560 | gpio_free(GPIO95_MMC_WP); | ||
561 | else | ||
562 | gpio_free(GPIO38_SD_PWEN); | ||
563 | } | ||
564 | |||
565 | static int em_x270_mci_get_ro(struct device *dev) | ||
566 | { | ||
567 | return gpio_get_value(GPIO95_MMC_WP); | ||
428 | } | 568 | } |
429 | 569 | ||
430 | static struct pxamci_platform_data em_x270_mci_platform_data = { | 570 | static struct pxamci_platform_data em_x270_mci_platform_data = { |
431 | .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31, | 571 | .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23| |
572 | MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27| | ||
573 | MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30| | ||
574 | MMC_VDD_30_31|MMC_VDD_31_32, | ||
432 | .init = em_x270_mci_init, | 575 | .init = em_x270_mci_init, |
433 | .setpower = em_x270_mci_setpower, | 576 | .setpower = em_x270_mci_setpower, |
434 | .exit = em_x270_mci_exit, | 577 | .exit = em_x270_mci_exit, |
@@ -436,33 +579,53 @@ static struct pxamci_platform_data em_x270_mci_platform_data = { | |||
436 | 579 | ||
437 | static void __init em_x270_init_mmc(void) | 580 | static void __init em_x270_init_mmc(void) |
438 | { | 581 | { |
582 | if (machine_is_em_x270()) | ||
583 | em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro; | ||
584 | |||
585 | em_x270_mci_platform_data.detect_delay = msecs_to_jiffies(250); | ||
439 | pxa_set_mci_info(&em_x270_mci_platform_data); | 586 | pxa_set_mci_info(&em_x270_mci_platform_data); |
440 | } | 587 | } |
441 | #else | 588 | #else |
442 | static inline void em_x270_init_mmc(void) {} | 589 | static inline void em_x270_init_mmc(void) {} |
443 | #endif | 590 | #endif |
444 | 591 | ||
445 | /* LCD 480x640 */ | 592 | /* LCD */ |
446 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | 593 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
447 | static struct pxafb_mode_info em_x270_lcd_mode = { | 594 | static struct pxafb_mode_info em_x270_lcd_modes[] = { |
448 | .pixclock = 50000, | 595 | [0] = { |
449 | .bpp = 16, | 596 | .pixclock = 38250, |
450 | .xres = 480, | 597 | .bpp = 16, |
451 | .yres = 640, | 598 | .xres = 480, |
452 | .hsync_len = 8, | 599 | .yres = 640, |
453 | .vsync_len = 2, | 600 | .hsync_len = 8, |
454 | .left_margin = 8, | 601 | .vsync_len = 2, |
455 | .upper_margin = 0, | 602 | .left_margin = 8, |
456 | .right_margin = 24, | 603 | .upper_margin = 2, |
457 | .lower_margin = 4, | 604 | .right_margin = 24, |
458 | .cmap_greyscale = 0, | 605 | .lower_margin = 4, |
606 | .sync = 0, | ||
607 | }, | ||
608 | [1] = { | ||
609 | .pixclock = 153800, | ||
610 | .bpp = 16, | ||
611 | .xres = 240, | ||
612 | .yres = 320, | ||
613 | .hsync_len = 8, | ||
614 | .vsync_len = 2, | ||
615 | .left_margin = 8, | ||
616 | .upper_margin = 2, | ||
617 | .right_margin = 88, | ||
618 | .lower_margin = 2, | ||
619 | .sync = 0, | ||
620 | }, | ||
459 | }; | 621 | }; |
460 | 622 | ||
461 | static struct pxafb_mach_info em_x270_lcd = { | 623 | static struct pxafb_mach_info em_x270_lcd = { |
462 | .modes = &em_x270_lcd_mode, | 624 | .modes = em_x270_lcd_modes, |
463 | .num_modes = 1, | 625 | .num_modes = 2, |
464 | .lcd_conn = LCD_COLOR_TFT_16BPP, | 626 | .lcd_conn = LCD_COLOR_TFT_16BPP, |
465 | }; | 627 | }; |
628 | |||
466 | static void __init em_x270_init_lcd(void) | 629 | static void __init em_x270_init_lcd(void) |
467 | { | 630 | { |
468 | set_pxa_fb_info(&em_x270_lcd); | 631 | set_pxa_fb_info(&em_x270_lcd); |
@@ -471,6 +634,40 @@ static void __init em_x270_init_lcd(void) | |||
471 | static inline void em_x270_init_lcd(void) {} | 634 | static inline void em_x270_init_lcd(void) {} |
472 | #endif | 635 | #endif |
473 | 636 | ||
637 | #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) | ||
638 | static struct pxa2xx_spi_master em_x270_spi_info = { | ||
639 | .num_chipselect = 1, | ||
640 | }; | ||
641 | |||
642 | static struct pxa2xx_spi_chip em_x270_tdo24m_chip = { | ||
643 | .rx_threshold = 1, | ||
644 | .tx_threshold = 1, | ||
645 | }; | ||
646 | |||
647 | static struct tdo24m_platform_data em_x270_tdo24m_pdata = { | ||
648 | .model = TDO35S, | ||
649 | }; | ||
650 | |||
651 | static struct spi_board_info em_x270_spi_devices[] __initdata = { | ||
652 | { | ||
653 | .modalias = "tdo24m", | ||
654 | .max_speed_hz = 1000000, | ||
655 | .bus_num = 1, | ||
656 | .chip_select = 0, | ||
657 | .controller_data = &em_x270_tdo24m_chip, | ||
658 | .platform_data = &em_x270_tdo24m_pdata, | ||
659 | }, | ||
660 | }; | ||
661 | |||
662 | static void __init em_x270_init_spi(void) | ||
663 | { | ||
664 | pxa2xx_set_spi_info(1, &em_x270_spi_info); | ||
665 | spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices)); | ||
666 | } | ||
667 | #else | ||
668 | static inline void em_x270_init_spi(void) {} | ||
669 | #endif | ||
670 | |||
474 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) | 671 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) |
475 | static void __init em_x270_init_ac97(void) | 672 | static void __init em_x270_init_ac97(void) |
476 | { | 673 | { |
@@ -481,23 +678,76 @@ static inline void em_x270_init_ac97(void) {} | |||
481 | #endif | 678 | #endif |
482 | 679 | ||
483 | #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) | 680 | #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) |
484 | static unsigned int em_x270_matrix_keys[] = { | 681 | static unsigned int em_x270_module_matrix_keys[] = { |
485 | KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B), | 682 | KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B), |
486 | KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT), | 683 | KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT), |
487 | KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D), | 684 | KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D), |
488 | }; | 685 | }; |
489 | 686 | ||
490 | struct pxa27x_keypad_platform_data em_x270_keypad_info = { | 687 | struct pxa27x_keypad_platform_data em_x270_module_keypad_info = { |
491 | /* code map for the matrix keys */ | 688 | /* code map for the matrix keys */ |
492 | .matrix_key_rows = 3, | 689 | .matrix_key_rows = 3, |
493 | .matrix_key_cols = 3, | 690 | .matrix_key_cols = 3, |
494 | .matrix_key_map = em_x270_matrix_keys, | 691 | .matrix_key_map = em_x270_module_matrix_keys, |
495 | .matrix_key_map_size = ARRAY_SIZE(em_x270_matrix_keys), | 692 | .matrix_key_map_size = ARRAY_SIZE(em_x270_module_matrix_keys), |
693 | }; | ||
694 | |||
695 | static unsigned int em_x270_exeda_matrix_keys[] = { | ||
696 | KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL), | ||
697 | KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE), | ||
698 | KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL), | ||
699 | KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH), | ||
700 | |||
701 | KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M), | ||
702 | KEY(1, 2, KEY_N), KEY(1, 3, KEY_B), | ||
703 | KEY(1, 4, KEY_V), KEY(1, 5, KEY_C), | ||
704 | KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z), | ||
705 | |||
706 | KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON), | ||
707 | KEY(2, 2, KEY_L), KEY(2, 3, KEY_K), | ||
708 | KEY(2, 4, KEY_J), KEY(2, 5, KEY_H), | ||
709 | KEY(2, 6, KEY_G), KEY(2, 7, KEY_F), | ||
710 | |||
711 | KEY(3, 0, KEY_D), KEY(3, 1, KEY_S), | ||
712 | KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB), | ||
713 | KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P), | ||
714 | KEY(3, 6, KEY_O), KEY(3, 7, KEY_I), | ||
715 | |||
716 | KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y), | ||
717 | KEY(4, 2, KEY_T), KEY(4, 3, KEY_R), | ||
718 | KEY(4, 4, KEY_E), KEY(4, 5, KEY_W), | ||
719 | KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS), | ||
720 | |||
721 | KEY(5, 0, KEY_0), KEY(5, 1, KEY_9), | ||
722 | KEY(5, 2, KEY_8), KEY(5, 3, KEY_7), | ||
723 | KEY(5, 4, KEY_6), KEY(5, 5, KEY_5), | ||
724 | KEY(5, 6, KEY_4), KEY(5, 7, KEY_3), | ||
725 | |||
726 | KEY(6, 0, KEY_2), KEY(6, 1, KEY_1), | ||
727 | KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END), | ||
728 | KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP), | ||
729 | KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1), | ||
730 | |||
731 | KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT), | ||
732 | KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME), | ||
733 | KEY(7, 4, 0), KEY(7, 5, 0), | ||
734 | KEY(7, 6, 0), KEY(7, 7, 0), | ||
735 | }; | ||
736 | |||
737 | struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = { | ||
738 | /* code map for the matrix keys */ | ||
739 | .matrix_key_rows = 8, | ||
740 | .matrix_key_cols = 8, | ||
741 | .matrix_key_map = em_x270_exeda_matrix_keys, | ||
742 | .matrix_key_map_size = ARRAY_SIZE(em_x270_exeda_matrix_keys), | ||
496 | }; | 743 | }; |
497 | 744 | ||
498 | static void __init em_x270_init_keypad(void) | 745 | static void __init em_x270_init_keypad(void) |
499 | { | 746 | { |
500 | pxa_set_keypad_info(&em_x270_keypad_info); | 747 | if (machine_is_em_x270()) |
748 | pxa_set_keypad_info(&em_x270_module_keypad_info); | ||
749 | else | ||
750 | pxa_set_keypad_info(&em_x270_exeda_keypad_info); | ||
501 | } | 751 | } |
502 | #else | 752 | #else |
503 | static inline void em_x270_init_keypad(void) {} | 753 | static inline void em_x270_init_keypad(void) {} |
@@ -535,19 +785,264 @@ static void __init em_x270_init_gpio_keys(void) | |||
535 | static inline void em_x270_init_gpio_keys(void) {} | 785 | static inline void em_x270_init_gpio_keys(void) {} |
536 | #endif | 786 | #endif |
537 | 787 | ||
538 | static void __init em_x270_init(void) | 788 | /* Quick Capture Interface and sensor setup */ |
789 | #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) | ||
790 | static struct regulator *em_x270_camera_ldo; | ||
791 | |||
792 | static int em_x270_sensor_init(struct device *dev) | ||
539 | { | 793 | { |
794 | int ret; | ||
795 | |||
796 | ret = gpio_request(GPIO93_CAM_RESET, "camera reset"); | ||
797 | if (ret) | ||
798 | return ret; | ||
799 | |||
800 | gpio_direction_output(GPIO93_CAM_RESET, 0); | ||
801 | |||
802 | em_x270_camera_ldo = regulator_get(NULL, "vcc cam"); | ||
803 | if (em_x270_camera_ldo == NULL) { | ||
804 | gpio_free(GPIO93_CAM_RESET); | ||
805 | return -ENODEV; | ||
806 | } | ||
807 | |||
808 | ret = regulator_enable(em_x270_camera_ldo); | ||
809 | if (ret) { | ||
810 | regulator_put(em_x270_camera_ldo); | ||
811 | gpio_free(GPIO93_CAM_RESET); | ||
812 | return ret; | ||
813 | } | ||
814 | |||
815 | gpio_set_value(GPIO93_CAM_RESET, 1); | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | struct pxacamera_platform_data em_x270_camera_platform_data = { | ||
821 | .init = em_x270_sensor_init, | ||
822 | .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | | ||
823 | PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, | ||
824 | .mclk_10khz = 2600, | ||
825 | }; | ||
826 | |||
827 | static int em_x270_sensor_power(struct device *dev, int on) | ||
828 | { | ||
829 | int ret; | ||
830 | int is_on = regulator_is_enabled(em_x270_camera_ldo); | ||
831 | |||
832 | if (on == is_on) | ||
833 | return 0; | ||
834 | |||
835 | gpio_set_value(GPIO93_CAM_RESET, !on); | ||
836 | |||
837 | if (on) | ||
838 | ret = regulator_enable(em_x270_camera_ldo); | ||
839 | else | ||
840 | ret = regulator_disable(em_x270_camera_ldo); | ||
841 | |||
842 | if (ret) | ||
843 | return ret; | ||
844 | |||
845 | gpio_set_value(GPIO93_CAM_RESET, on); | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static struct soc_camera_link iclink = { | ||
851 | .bus_id = 0, | ||
852 | .power = em_x270_sensor_power, | ||
853 | }; | ||
854 | |||
855 | static struct i2c_board_info em_x270_i2c_cam_info[] = { | ||
856 | { | ||
857 | I2C_BOARD_INFO("mt9m111", 0x48), | ||
858 | .platform_data = &iclink, | ||
859 | }, | ||
860 | }; | ||
861 | |||
862 | static struct i2c_pxa_platform_data em_x270_i2c_info = { | ||
863 | .fast_mode = 1, | ||
864 | }; | ||
865 | |||
866 | static void __init em_x270_init_camera(void) | ||
867 | { | ||
868 | pxa_set_i2c_info(&em_x270_i2c_info); | ||
869 | i2c_register_board_info(0, ARRAY_AND_SIZE(em_x270_i2c_cam_info)); | ||
870 | pxa_set_camera_info(&em_x270_camera_platform_data); | ||
871 | } | ||
872 | #else | ||
873 | static inline void em_x270_init_camera(void) {} | ||
874 | #endif | ||
875 | |||
876 | /* DA9030 related initializations */ | ||
877 | #define REGULATOR_CONSUMER(_name, _dev, _supply) \ | ||
878 | static struct regulator_consumer_supply _name##_consumers[] = { \ | ||
879 | { \ | ||
880 | .dev = _dev, \ | ||
881 | .supply = _supply, \ | ||
882 | }, \ | ||
883 | } | ||
884 | |||
885 | REGULATOR_CONSUMER(ldo3, NULL, "vcc gps"); | ||
886 | REGULATOR_CONSUMER(ldo5, NULL, "vcc cam"); | ||
887 | REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio"); | ||
888 | REGULATOR_CONSUMER(ldo12, NULL, "vcc usb"); | ||
889 | REGULATOR_CONSUMER(ldo19, NULL, "vcc gprs"); | ||
890 | |||
891 | #define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \ | ||
892 | static struct regulator_init_data _ldo##_data = { \ | ||
893 | .constraints = { \ | ||
894 | .min_uV = _min_uV, \ | ||
895 | .max_uV = _max_uV, \ | ||
896 | .state_mem = { \ | ||
897 | .enabled = 0, \ | ||
898 | }, \ | ||
899 | .valid_ops_mask = _ops_mask, \ | ||
900 | }, \ | ||
901 | .num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \ | ||
902 | .consumer_supplies = _ldo##_consumers, \ | ||
903 | }; | ||
904 | |||
905 | REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS); | ||
906 | REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS); | ||
907 | REGULATOR_INIT(ldo10, 2000000, 3200000, | ||
908 | REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE); | ||
909 | REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS); | ||
910 | REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS); | ||
911 | |||
912 | struct led_info em_x270_led_info = { | ||
913 | .name = "em-x270:orange", | ||
914 | .default_trigger = "battery-charging-or-full", | ||
915 | }; | ||
916 | |||
917 | struct power_supply_info em_x270_psy_info = { | ||
918 | .name = "LP555597P6H-FPS", | ||
919 | .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, | ||
920 | .voltage_max_design = 4200000, | ||
921 | .voltage_min_design = 3000000, | ||
922 | .use_for_apm = 1, | ||
923 | }; | ||
924 | |||
925 | static void em_x270_battery_low(void) | ||
926 | { | ||
927 | apm_queue_event(APM_LOW_BATTERY); | ||
928 | } | ||
929 | |||
930 | static void em_x270_battery_critical(void) | ||
931 | { | ||
932 | apm_queue_event(APM_CRITICAL_SUSPEND); | ||
933 | } | ||
934 | |||
935 | struct da9030_battery_info em_x270_batterty_info = { | ||
936 | .battery_info = &em_x270_psy_info, | ||
937 | |||
938 | .charge_milliamp = 1000, | ||
939 | .charge_millivolt = 4200, | ||
940 | |||
941 | .vbat_low = 3600, | ||
942 | .vbat_crit = 3400, | ||
943 | .vbat_charge_start = 4100, | ||
944 | .vbat_charge_stop = 4200, | ||
945 | .vbat_charge_restart = 4000, | ||
946 | |||
947 | .vcharge_min = 3200, | ||
948 | .vcharge_max = 5500, | ||
949 | |||
950 | .tbat_low = 197, | ||
951 | .tbat_high = 78, | ||
952 | .tbat_restart = 100, | ||
953 | |||
954 | .batmon_interval = 0, | ||
955 | |||
956 | .battery_low = em_x270_battery_low, | ||
957 | .battery_critical = em_x270_battery_critical, | ||
958 | }; | ||
959 | |||
960 | #define DA9030_SUBDEV(_name, _id, _pdata) \ | ||
961 | { \ | ||
962 | .name = "da903x-" #_name, \ | ||
963 | .id = DA9030_ID_##_id, \ | ||
964 | .platform_data = _pdata, \ | ||
965 | } | ||
966 | |||
967 | #define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data) | ||
968 | |||
969 | struct da903x_subdev_info em_x270_da9030_subdevs[] = { | ||
970 | DA9030_LDO(3), | ||
971 | DA9030_LDO(5), | ||
972 | DA9030_LDO(10), | ||
973 | DA9030_LDO(12), | ||
974 | DA9030_LDO(19), | ||
975 | |||
976 | DA9030_SUBDEV(led, LED_PC, &em_x270_led_info), | ||
977 | DA9030_SUBDEV(backlight, WLED, &em_x270_led_info), | ||
978 | DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info), | ||
979 | }; | ||
980 | |||
981 | static struct da903x_platform_data em_x270_da9030_info = { | ||
982 | .num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs), | ||
983 | .subdevs = em_x270_da9030_subdevs, | ||
984 | }; | ||
985 | |||
986 | static struct i2c_board_info em_x270_i2c_pmic_info = { | ||
987 | I2C_BOARD_INFO("da9030", 0x49), | ||
988 | .irq = IRQ_GPIO(0), | ||
989 | .platform_data = &em_x270_da9030_info, | ||
990 | }; | ||
991 | |||
992 | static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = { | ||
993 | .use_pio = 1, | ||
994 | }; | ||
995 | |||
996 | static void __init em_x270_init_da9030(void) | ||
997 | { | ||
998 | pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info); | ||
999 | i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1); | ||
1000 | } | ||
1001 | |||
1002 | static void __init em_x270_module_init(void) | ||
1003 | { | ||
1004 | pr_info("%s\n", __func__); | ||
540 | pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); | 1005 | pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); |
541 | 1006 | ||
1007 | mmc_cd = GPIO13_MMC_CD; | ||
1008 | nand_rb = GPIO56_NAND_RB; | ||
1009 | dm9000_flags = DM9000_PLATF_32BITONLY; | ||
1010 | } | ||
1011 | |||
1012 | static void __init em_x270_exeda_init(void) | ||
1013 | { | ||
1014 | pr_info("%s\n", __func__); | ||
1015 | pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config)); | ||
1016 | |||
1017 | mmc_cd = GPIO114_MMC_CD; | ||
1018 | nand_rb = GPIO20_NAND_RB; | ||
1019 | dm9000_flags = DM9000_PLATF_16BITONLY; | ||
1020 | } | ||
1021 | |||
1022 | static void __init em_x270_init(void) | ||
1023 | { | ||
1024 | pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config)); | ||
1025 | |||
1026 | if (machine_is_em_x270()) | ||
1027 | em_x270_module_init(); | ||
1028 | else if (machine_is_exeda()) | ||
1029 | em_x270_exeda_init(); | ||
1030 | else | ||
1031 | panic("Unsupported machine: %d\n", machine_arch_type); | ||
1032 | |||
1033 | em_x270_init_da9030(); | ||
542 | em_x270_init_dm9000(); | 1034 | em_x270_init_dm9000(); |
543 | em_x270_init_rtc(); | 1035 | em_x270_init_rtc(); |
544 | em_x270_init_nand(); | 1036 | em_x270_init_nand(); |
1037 | em_x270_init_nor(); | ||
545 | em_x270_init_lcd(); | 1038 | em_x270_init_lcd(); |
546 | em_x270_init_mmc(); | 1039 | em_x270_init_mmc(); |
547 | em_x270_init_ohci(); | 1040 | em_x270_init_ohci(); |
548 | em_x270_init_keypad(); | 1041 | em_x270_init_keypad(); |
549 | em_x270_init_gpio_keys(); | 1042 | em_x270_init_gpio_keys(); |
550 | em_x270_init_ac97(); | 1043 | em_x270_init_ac97(); |
1044 | em_x270_init_camera(); | ||
1045 | em_x270_init_spi(); | ||
551 | } | 1046 | } |
552 | 1047 | ||
553 | MACHINE_START(EM_X270, "Compulab EM-X270") | 1048 | MACHINE_START(EM_X270, "Compulab EM-X270") |
@@ -559,3 +1054,13 @@ MACHINE_START(EM_X270, "Compulab EM-X270") | |||
559 | .timer = &pxa_timer, | 1054 | .timer = &pxa_timer, |
560 | .init_machine = em_x270_init, | 1055 | .init_machine = em_x270_init, |
561 | MACHINE_END | 1056 | MACHINE_END |
1057 | |||
1058 | MACHINE_START(EXEDA, "Compulab eXeda") | ||
1059 | .boot_params = 0xa0000100, | ||
1060 | .phys_io = 0x40000000, | ||
1061 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
1062 | .map_io = pxa_map_io, | ||
1063 | .init_irq = pxa27x_init_irq, | ||
1064 | .timer = &pxa_timer, | ||
1065 | .init_machine = em_x270_init, | ||
1066 | MACHINE_END | ||