diff options
author | Mike Rapoport <mike@compulab.co.il> | 2008-12-03 02:38:10 -0500 |
---|---|---|
committer | Eric Miao <eric.miao@marvell.com> | 2009-01-21 02:06:35 -0500 |
commit | 28c88046d0974e50859d80c885f61d67cb083d02 (patch) | |
tree | 9129c792680740f203eb284db899babf96241472 /arch/arm/mach-pxa | |
parent | a645072a608356990b2737a48ecc1bfb66981599 (diff) |
[ARM] pxa/em-x270: updates for 2.6.29
The patch includes the following updates to EM-X270:
- Added DA9030 support
- Added NOR flash support
- Added QCI with mt9m112 sensor support
- Updated LCD support
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/em-x270.c | 371 |
1 files changed, 356 insertions, 15 deletions
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index f5ed8038ede5..1aaae97de7d3 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -16,9 +16,16 @@ | |||
16 | #include <linux/rtc-v3020.h> | 16 | #include <linux/rtc-v3020.h> |
17 | #include <linux/mtd/nand.h> | 17 | #include <linux/mtd/nand.h> |
18 | #include <linux/mtd/partitions.h> | 18 | #include <linux/mtd/partitions.h> |
19 | #include <linux/mtd/physmap.h> | ||
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/gpio_keys.h> | 21 | #include <linux/gpio_keys.h> |
21 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/mfd/da903x.h> | ||
24 | #include <linux/regulator/machine.h> | ||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/spi/tdo24m.h> | ||
27 | |||
28 | #include <media/soc_camera.h> | ||
22 | 29 | ||
23 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
@@ -31,6 +38,9 @@ | |||
31 | #include <mach/ohci.h> | 38 | #include <mach/ohci.h> |
32 | #include <mach/mmc.h> | 39 | #include <mach/mmc.h> |
33 | #include <mach/pxa27x_keypad.h> | 40 | #include <mach/pxa27x_keypad.h> |
41 | #include <mach/i2c.h> | ||
42 | #include <mach/camera.h> | ||
43 | #include <mach/pxa2xx_spi.h> | ||
34 | 44 | ||
35 | #include "generic.h" | 45 | #include "generic.h" |
36 | 46 | ||
@@ -44,6 +54,9 @@ | |||
44 | #define GPIO11_NAND_CS (11) | 54 | #define GPIO11_NAND_CS (11) |
45 | #define GPIO56_NAND_RB (56) | 55 | #define GPIO56_NAND_RB (56) |
46 | 56 | ||
57 | /* Miscelaneous GPIOs */ | ||
58 | #define GPIO93_CAM_RESET (93) | ||
59 | |||
47 | static unsigned long em_x270_pin_config[] = { | 60 | static unsigned long em_x270_pin_config[] = { |
48 | /* AC'97 */ | 61 | /* AC'97 */ |
49 | GPIO28_AC97_BITCLK, | 62 | GPIO28_AC97_BITCLK, |
@@ -154,6 +167,7 @@ static unsigned long em_x270_pin_config[] = { | |||
154 | 167 | ||
155 | /* power controls */ | 168 | /* power controls */ |
156 | GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ | 169 | GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ |
170 | GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */ | ||
157 | GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ | 171 | GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */ |
158 | 172 | ||
159 | /* NAND controls */ | 173 | /* NAND controls */ |
@@ -369,6 +383,61 @@ static void __init em_x270_init_nand(void) | |||
369 | static inline void em_x270_init_nand(void) {} | 383 | static inline void em_x270_init_nand(void) {} |
370 | #endif | 384 | #endif |
371 | 385 | ||
386 | #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) | ||
387 | static struct mtd_partition em_x270_nor_parts[] = { | ||
388 | { | ||
389 | .name = "Bootloader", | ||
390 | .offset = 0x00000000, | ||
391 | .size = 0x00050000, | ||
392 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
393 | }, { | ||
394 | .name = "Environment", | ||
395 | .offset = 0x00050000, | ||
396 | .size = 0x00010000, | ||
397 | }, { | ||
398 | .name = "Reserved", | ||
399 | .offset = 0x00060000, | ||
400 | .size = 0x00050000, | ||
401 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
402 | }, { | ||
403 | .name = "Splashscreen", | ||
404 | .offset = 0x000b0000, | ||
405 | .size = 0x00050000, | ||
406 | } | ||
407 | }; | ||
408 | |||
409 | static struct physmap_flash_data em_x270_nor_data[] = { | ||
410 | [0] = { | ||
411 | .width = 2, | ||
412 | .parts = em_x270_nor_parts, | ||
413 | .nr_parts = ARRAY_SIZE(em_x270_nor_parts), | ||
414 | }, | ||
415 | }; | ||
416 | |||
417 | static struct resource em_x270_nor_flash_resource = { | ||
418 | .start = PXA_CS0_PHYS, | ||
419 | .end = PXA_CS0_PHYS + SZ_1M - 1, | ||
420 | .flags = IORESOURCE_MEM, | ||
421 | }; | ||
422 | |||
423 | static struct platform_device em_x270_physmap_flash = { | ||
424 | .name = "physmap-flash", | ||
425 | .id = 0, | ||
426 | .num_resources = 1, | ||
427 | .resource = &em_x270_nor_flash_resource, | ||
428 | .dev = { | ||
429 | .platform_data = &em_x270_nor_data, | ||
430 | }, | ||
431 | }; | ||
432 | |||
433 | static void __init em_x270_init_nor(void) | ||
434 | { | ||
435 | platform_device_register(&em_x270_physmap_flash); | ||
436 | } | ||
437 | #else | ||
438 | static inline void em_x270_init_nor(void) {} | ||
439 | #endif | ||
440 | |||
372 | /* PXA27x OHCI controller setup */ | 441 | /* PXA27x OHCI controller setup */ |
373 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 442 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
374 | static int em_x270_ohci_init(struct device *dev) | 443 | static int em_x270_ohci_init(struct device *dev) |
@@ -442,27 +511,43 @@ static void __init em_x270_init_mmc(void) | |||
442 | static inline void em_x270_init_mmc(void) {} | 511 | static inline void em_x270_init_mmc(void) {} |
443 | #endif | 512 | #endif |
444 | 513 | ||
445 | /* LCD 480x640 */ | 514 | /* LCD */ |
446 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | 515 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
447 | static struct pxafb_mode_info em_x270_lcd_mode = { | 516 | static struct pxafb_mode_info em_x270_lcd_modes[] = { |
448 | .pixclock = 50000, | 517 | [0] = { |
449 | .bpp = 16, | 518 | .pixclock = 38250, |
450 | .xres = 480, | 519 | .bpp = 16, |
451 | .yres = 640, | 520 | .xres = 480, |
452 | .hsync_len = 8, | 521 | .yres = 640, |
453 | .vsync_len = 2, | 522 | .hsync_len = 8, |
454 | .left_margin = 8, | 523 | .vsync_len = 2, |
455 | .upper_margin = 0, | 524 | .left_margin = 8, |
456 | .right_margin = 24, | 525 | .upper_margin = 2, |
457 | .lower_margin = 4, | 526 | .right_margin = 24, |
458 | .cmap_greyscale = 0, | 527 | .lower_margin = 4, |
528 | .sync = 0, | ||
529 | }, | ||
530 | [1] = { | ||
531 | .pixclock = 153800, | ||
532 | .bpp = 16, | ||
533 | .xres = 240, | ||
534 | .yres = 320, | ||
535 | .hsync_len = 8, | ||
536 | .vsync_len = 2, | ||
537 | .left_margin = 8, | ||
538 | .upper_margin = 2, | ||
539 | .right_margin = 88, | ||
540 | .lower_margin = 2, | ||
541 | .sync = 0, | ||
542 | }, | ||
459 | }; | 543 | }; |
460 | 544 | ||
461 | static struct pxafb_mach_info em_x270_lcd = { | 545 | static struct pxafb_mach_info em_x270_lcd = { |
462 | .modes = &em_x270_lcd_mode, | 546 | .modes = em_x270_lcd_modes, |
463 | .num_modes = 1, | 547 | .num_modes = 2, |
464 | .lcd_conn = LCD_COLOR_TFT_16BPP, | 548 | .lcd_conn = LCD_COLOR_TFT_16BPP, |
465 | }; | 549 | }; |
550 | |||
466 | static void __init em_x270_init_lcd(void) | 551 | static void __init em_x270_init_lcd(void) |
467 | { | 552 | { |
468 | set_pxa_fb_info(&em_x270_lcd); | 553 | set_pxa_fb_info(&em_x270_lcd); |
@@ -471,6 +556,40 @@ static void __init em_x270_init_lcd(void) | |||
471 | static inline void em_x270_init_lcd(void) {} | 556 | static inline void em_x270_init_lcd(void) {} |
472 | #endif | 557 | #endif |
473 | 558 | ||
559 | #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) | ||
560 | static struct pxa2xx_spi_master em_x270_spi_info = { | ||
561 | .num_chipselect = 1, | ||
562 | }; | ||
563 | |||
564 | static struct pxa2xx_spi_chip em_x270_tdo24m_chip = { | ||
565 | .rx_threshold = 1, | ||
566 | .tx_threshold = 1, | ||
567 | }; | ||
568 | |||
569 | static struct tdo24m_platform_data em_x270_tdo24m_pdata = { | ||
570 | .model = TDO35S, | ||
571 | }; | ||
572 | |||
573 | static struct spi_board_info em_x270_spi_devices[] __initdata = { | ||
574 | { | ||
575 | .modalias = "tdo24m", | ||
576 | .max_speed_hz = 1000000, | ||
577 | .bus_num = 1, | ||
578 | .chip_select = 0, | ||
579 | .controller_data = &em_x270_tdo24m_chip, | ||
580 | .platform_data = &em_x270_tdo24m_pdata, | ||
581 | }, | ||
582 | }; | ||
583 | |||
584 | static void __init em_x270_init_spi(void) | ||
585 | { | ||
586 | pxa2xx_set_spi_info(1, &em_x270_spi_info); | ||
587 | spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices)); | ||
588 | } | ||
589 | #else | ||
590 | static inline void em_x270_init_spi(void) {} | ||
591 | #endif | ||
592 | |||
474 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) | 593 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) |
475 | static void __init em_x270_init_ac97(void) | 594 | static void __init em_x270_init_ac97(void) |
476 | { | 595 | { |
@@ -535,19 +654,241 @@ static void __init em_x270_init_gpio_keys(void) | |||
535 | static inline void em_x270_init_gpio_keys(void) {} | 654 | static inline void em_x270_init_gpio_keys(void) {} |
536 | #endif | 655 | #endif |
537 | 656 | ||
657 | /* Quick Capture Interface and sensor setup */ | ||
658 | #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) | ||
659 | static struct regulator *em_x270_camera_ldo; | ||
660 | |||
661 | static int em_x270_sensor_init(struct device *dev) | ||
662 | { | ||
663 | int ret; | ||
664 | |||
665 | ret = gpio_request(GPIO93_CAM_RESET, "camera reset"); | ||
666 | if (ret) | ||
667 | return ret; | ||
668 | |||
669 | gpio_direction_output(GPIO93_CAM_RESET, 0); | ||
670 | |||
671 | em_x270_camera_ldo = regulator_get(NULL, "vcc cam"); | ||
672 | if (em_x270_camera_ldo == NULL) { | ||
673 | gpio_free(GPIO93_CAM_RESET); | ||
674 | return -ENODEV; | ||
675 | } | ||
676 | |||
677 | ret = regulator_enable(em_x270_camera_ldo); | ||
678 | if (ret) { | ||
679 | regulator_put(em_x270_camera_ldo); | ||
680 | gpio_free(GPIO93_CAM_RESET); | ||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | gpio_set_value(GPIO93_CAM_RESET, 1); | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | struct pxacamera_platform_data em_x270_camera_platform_data = { | ||
690 | .init = em_x270_sensor_init, | ||
691 | .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | | ||
692 | PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, | ||
693 | .mclk_10khz = 2600, | ||
694 | }; | ||
695 | |||
696 | static int em_x270_sensor_power(struct device *dev, int on) | ||
697 | { | ||
698 | int ret; | ||
699 | int is_on = regulator_is_enabled(em_x270_camera_ldo); | ||
700 | |||
701 | if (on == is_on) | ||
702 | return 0; | ||
703 | |||
704 | gpio_set_value(GPIO93_CAM_RESET, !on); | ||
705 | |||
706 | if (on) | ||
707 | ret = regulator_enable(em_x270_camera_ldo); | ||
708 | else | ||
709 | ret = regulator_disable(em_x270_camera_ldo); | ||
710 | |||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | gpio_set_value(GPIO93_CAM_RESET, on); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static struct soc_camera_link iclink = { | ||
720 | .bus_id = 0, | ||
721 | .power = em_x270_sensor_power, | ||
722 | }; | ||
723 | |||
724 | static struct i2c_board_info em_x270_i2c_cam_info[] = { | ||
725 | { | ||
726 | I2C_BOARD_INFO("mt9m111", 0x48), | ||
727 | .platform_data = &iclink, | ||
728 | }, | ||
729 | }; | ||
730 | |||
731 | static struct i2c_pxa_platform_data em_x270_i2c_info = { | ||
732 | .fast_mode = 1, | ||
733 | }; | ||
734 | |||
735 | static void __init em_x270_init_camera(void) | ||
736 | { | ||
737 | pxa_set_i2c_info(&em_x270_i2c_info); | ||
738 | i2c_register_board_info(0, ARRAY_AND_SIZE(em_x270_i2c_cam_info)); | ||
739 | pxa_set_camera_info(&em_x270_camera_platform_data); | ||
740 | } | ||
741 | #else | ||
742 | static inline void em_x270_init_camera(void) {} | ||
743 | #endif | ||
744 | |||
745 | /* DA9030 related initializations */ | ||
746 | static struct regulator_consumer_supply ldo3_consumers[] = { | ||
747 | { | ||
748 | .dev = NULL, | ||
749 | .supply = "vcc gps", | ||
750 | }, | ||
751 | }; | ||
752 | |||
753 | static struct regulator_consumer_supply ldo5_consumers[] = { | ||
754 | { | ||
755 | .dev = NULL, | ||
756 | .supply = "vcc cam", | ||
757 | }, | ||
758 | }; | ||
759 | |||
760 | static struct regulator_consumer_supply ldo12_consumers[] = { | ||
761 | { | ||
762 | .dev = NULL, | ||
763 | .supply = "vcc usb", | ||
764 | }, | ||
765 | }; | ||
766 | |||
767 | static struct regulator_consumer_supply ldo19_consumers[] = { | ||
768 | { | ||
769 | .dev = NULL, | ||
770 | .supply = "vcc gprs", | ||
771 | }, | ||
772 | }; | ||
773 | |||
774 | static struct regulator_init_data ldo3_data = { | ||
775 | .constraints = { | ||
776 | .min_uV = 3200000, | ||
777 | .max_uV = 3200000, | ||
778 | .state_mem = { | ||
779 | .enabled = 0, | ||
780 | }, | ||
781 | }, | ||
782 | .num_consumer_supplies = ARRAY_SIZE(ldo3_consumers), | ||
783 | .consumer_supplies = ldo3_consumers, | ||
784 | }; | ||
785 | |||
786 | static struct regulator_init_data ldo5_data = { | ||
787 | .constraints = { | ||
788 | .min_uV = 3000000, | ||
789 | .max_uV = 3000000, | ||
790 | .state_mem = { | ||
791 | .enabled = 0, | ||
792 | }, | ||
793 | }, | ||
794 | .num_consumer_supplies = ARRAY_SIZE(ldo5_consumers), | ||
795 | .consumer_supplies = ldo5_consumers, | ||
796 | }; | ||
797 | |||
798 | static struct regulator_init_data ldo12_data = { | ||
799 | .constraints = { | ||
800 | .min_uV = 3000000, | ||
801 | .max_uV = 3000000, | ||
802 | .state_mem = { | ||
803 | .enabled = 0, | ||
804 | }, | ||
805 | }, | ||
806 | .num_consumer_supplies = ARRAY_SIZE(ldo12_consumers), | ||
807 | .consumer_supplies = ldo12_consumers, | ||
808 | }; | ||
809 | |||
810 | static struct regulator_init_data ldo19_data = { | ||
811 | .constraints = { | ||
812 | .min_uV = 3200000, | ||
813 | .max_uV = 3200000, | ||
814 | .state_mem = { | ||
815 | .enabled = 0, | ||
816 | }, | ||
817 | }, | ||
818 | .num_consumer_supplies = ARRAY_SIZE(ldo19_consumers), | ||
819 | .consumer_supplies = ldo19_consumers, | ||
820 | }; | ||
821 | |||
822 | struct led_info em_x270_led_info = { | ||
823 | .name = "em-x270:orange", | ||
824 | .default_trigger = "battery-charging-or-full", | ||
825 | }; | ||
826 | |||
827 | struct da903x_subdev_info em_x270_da9030_subdevs[] = { | ||
828 | { | ||
829 | .name = "da903x-regulator", | ||
830 | .id = DA9030_ID_LDO3, | ||
831 | .platform_data = &ldo3_data, | ||
832 | }, { | ||
833 | .name = "da903x-regulator", | ||
834 | .id = DA9030_ID_LDO5, | ||
835 | .platform_data = &ldo5_data, | ||
836 | }, { | ||
837 | .name = "da903x-regulator", | ||
838 | .id = DA9030_ID_LDO12, | ||
839 | .platform_data = &ldo12_data, | ||
840 | }, { | ||
841 | .name = "da903x-regulator", | ||
842 | .id = DA9030_ID_LDO19, | ||
843 | .platform_data = &ldo19_data, | ||
844 | }, { | ||
845 | .name = "da903x-led", | ||
846 | .id = DA9030_ID_LED_PC, | ||
847 | .platform_data = &em_x270_led_info, | ||
848 | }, { | ||
849 | .name = "da903x-backlight", | ||
850 | .id = DA9030_ID_WLED, | ||
851 | } | ||
852 | }; | ||
853 | |||
854 | static struct da903x_platform_data em_x270_da9030_info = { | ||
855 | .num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs), | ||
856 | .subdevs = em_x270_da9030_subdevs, | ||
857 | }; | ||
858 | |||
859 | static struct i2c_board_info em_x270_i2c_pmic_info = { | ||
860 | I2C_BOARD_INFO("da9030", 0x49), | ||
861 | .irq = IRQ_GPIO(0), | ||
862 | .platform_data = &em_x270_da9030_info, | ||
863 | }; | ||
864 | |||
865 | static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = { | ||
866 | .use_pio = 1, | ||
867 | }; | ||
868 | |||
869 | static void __init em_x270_init_da9030(void) | ||
870 | { | ||
871 | pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info); | ||
872 | i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1); | ||
873 | } | ||
874 | |||
538 | static void __init em_x270_init(void) | 875 | static void __init em_x270_init(void) |
539 | { | 876 | { |
540 | pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); | 877 | pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config)); |
541 | 878 | ||
879 | em_x270_init_da9030(); | ||
542 | em_x270_init_dm9000(); | 880 | em_x270_init_dm9000(); |
543 | em_x270_init_rtc(); | 881 | em_x270_init_rtc(); |
544 | em_x270_init_nand(); | 882 | em_x270_init_nand(); |
883 | em_x270_init_nor(); | ||
545 | em_x270_init_lcd(); | 884 | em_x270_init_lcd(); |
546 | em_x270_init_mmc(); | 885 | em_x270_init_mmc(); |
547 | em_x270_init_ohci(); | 886 | em_x270_init_ohci(); |
548 | em_x270_init_keypad(); | 887 | em_x270_init_keypad(); |
549 | em_x270_init_gpio_keys(); | 888 | em_x270_init_gpio_keys(); |
550 | em_x270_init_ac97(); | 889 | em_x270_init_ac97(); |
890 | em_x270_init_camera(); | ||
891 | em_x270_init_spi(); | ||
551 | } | 892 | } |
552 | 893 | ||
553 | MACHINE_START(EM_X270, "Compulab EM-X270") | 894 | MACHINE_START(EM_X270, "Compulab EM-X270") |