diff options
author | Antonio Ospite <ospite@studenti.unina.it> | 2009-11-12 09:47:04 -0500 |
---|---|---|
committer | Eric Miao <eric.y.miao@gmail.com> | 2009-11-30 20:03:02 -0500 |
commit | 405ac4015a92904b6366db7c6ef21491bdb7e771 (patch) | |
tree | 6347e1367702a9f04f03707ec1541a8d71f207da /arch/arm/mach-pxa/ezx.c | |
parent | 0ba01ebcb39aeb27c5a861c80e0b38634d0cb457 (diff) |
[ARM] pxa/ezx: add camera support for A780 and A910 EZX phones
Signed-off-by: Bart Visscher <bartv@thisnet.nl>
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch/arm/mach-pxa/ezx.c')
-rw-r--r-- | arch/arm/mach-pxa/ezx.c | 174 |
1 files changed, 170 insertions, 4 deletions
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 48c17372bc1c..320e2f8c599e 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c | |||
@@ -17,8 +17,11 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/pwm_backlight.h> | 18 | #include <linux/pwm_backlight.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/gpio.h> | ||
20 | #include <linux/gpio_keys.h> | 21 | #include <linux/gpio_keys.h> |
21 | 22 | ||
23 | #include <media/soc_camera.h> | ||
24 | |||
22 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
23 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 27 | #include <asm/mach/arch.h> |
@@ -29,6 +32,7 @@ | |||
29 | #include <plat/i2c.h> | 32 | #include <plat/i2c.h> |
30 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
31 | #include <mach/pxa27x_keypad.h> | 34 | #include <mach/pxa27x_keypad.h> |
35 | #include <mach/camera.h> | ||
32 | 36 | ||
33 | #include "devices.h" | 37 | #include "devices.h" |
34 | #include "generic.h" | 38 | #include "generic.h" |
@@ -38,6 +42,9 @@ | |||
38 | #define GPIO15_A910_FLIP_LID 15 | 42 | #define GPIO15_A910_FLIP_LID 15 |
39 | #define GPIO12_E680_LOCK_SWITCH 12 | 43 | #define GPIO12_E680_LOCK_SWITCH 12 |
40 | #define GPIO15_E6_LOCK_SWITCH 15 | 44 | #define GPIO15_E6_LOCK_SWITCH 15 |
45 | #define GPIO50_nCAM_EN 50 | ||
46 | #define GPIO19_GEN1_CAM_RST 19 | ||
47 | #define GPIO28_GEN2_CAM_RST 28 | ||
41 | 48 | ||
42 | static struct platform_pwm_backlight_data ezx_backlight_data = { | 49 | static struct platform_pwm_backlight_data ezx_backlight_data = { |
43 | .pwm_id = 0, | 50 | .pwm_id = 0, |
@@ -191,8 +198,8 @@ static unsigned long gen1_pin_config[] __initdata = { | |||
191 | GPIO94_CIF_DD_5, | 198 | GPIO94_CIF_DD_5, |
192 | GPIO17_CIF_DD_6, | 199 | GPIO17_CIF_DD_6, |
193 | GPIO108_CIF_DD_7, | 200 | GPIO108_CIF_DD_7, |
194 | GPIO50_GPIO, /* CAM_EN */ | 201 | GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */ |
195 | GPIO19_GPIO, /* CAM_RST */ | 202 | GPIO19_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */ |
196 | 203 | ||
197 | /* EMU */ | 204 | /* EMU */ |
198 | GPIO120_GPIO, /* EMU_MUX1 */ | 205 | GPIO120_GPIO, /* EMU_MUX1 */ |
@@ -248,8 +255,8 @@ static unsigned long gen2_pin_config[] __initdata = { | |||
248 | GPIO48_CIF_DD_5, | 255 | GPIO48_CIF_DD_5, |
249 | GPIO93_CIF_DD_6, | 256 | GPIO93_CIF_DD_6, |
250 | GPIO12_CIF_DD_7, | 257 | GPIO12_CIF_DD_7, |
251 | GPIO50_GPIO, /* CAM_EN */ | 258 | GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */ |
252 | GPIO28_GPIO, /* CAM_RST */ | 259 | GPIO28_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */ |
253 | GPIO17_GPIO, /* CAM_FLASH */ | 260 | GPIO17_GPIO, /* CAM_FLASH */ |
254 | }; | 261 | }; |
255 | #endif | 262 | #endif |
@@ -683,6 +690,81 @@ static struct platform_device a780_gpio_keys = { | |||
683 | }, | 690 | }, |
684 | }; | 691 | }; |
685 | 692 | ||
693 | /* camera */ | ||
694 | static int a780_camera_init(void) | ||
695 | { | ||
696 | int err; | ||
697 | |||
698 | /* | ||
699 | * GPIO50_nCAM_EN is active low | ||
700 | * GPIO19_GEN1_CAM_RST is active on rising edge | ||
701 | */ | ||
702 | err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN"); | ||
703 | if (err) { | ||
704 | pr_err("%s: Failed to request nCAM_EN\n", __func__); | ||
705 | goto fail; | ||
706 | } | ||
707 | |||
708 | err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST"); | ||
709 | if (err) { | ||
710 | pr_err("%s: Failed to request CAM_RST\n", __func__); | ||
711 | goto fail_gpio_cam_rst; | ||
712 | } | ||
713 | |||
714 | gpio_direction_output(GPIO50_nCAM_EN, 1); | ||
715 | gpio_direction_output(GPIO19_GEN1_CAM_RST, 0); | ||
716 | |||
717 | return 0; | ||
718 | |||
719 | fail_gpio_cam_rst: | ||
720 | gpio_free(GPIO50_nCAM_EN); | ||
721 | fail: | ||
722 | return err; | ||
723 | } | ||
724 | |||
725 | static int a780_camera_power(struct device *dev, int on) | ||
726 | { | ||
727 | gpio_set_value(GPIO50_nCAM_EN, !on); | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static int a780_camera_reset(struct device *dev) | ||
732 | { | ||
733 | gpio_set_value(GPIO19_GEN1_CAM_RST, 0); | ||
734 | msleep(10); | ||
735 | gpio_set_value(GPIO19_GEN1_CAM_RST, 1); | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | struct pxacamera_platform_data a780_pxacamera_platform_data = { | ||
741 | .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | | ||
742 | PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, | ||
743 | .mclk_10khz = 5000, | ||
744 | }; | ||
745 | |||
746 | static struct i2c_board_info a780_camera_i2c_board_info = { | ||
747 | I2C_BOARD_INFO("mt9m111", 0x5d), | ||
748 | }; | ||
749 | |||
750 | static struct soc_camera_link a780_iclink = { | ||
751 | .bus_id = 0, | ||
752 | .flags = SOCAM_SENSOR_INVERT_PCLK, | ||
753 | .i2c_adapter_id = 0, | ||
754 | .board_info = &a780_camera_i2c_board_info, | ||
755 | .module_name = "mt9m111", | ||
756 | .power = a780_camera_power, | ||
757 | .reset = a780_camera_reset, | ||
758 | }; | ||
759 | |||
760 | static struct platform_device a780_camera = { | ||
761 | .name = "soc-camera-pdrv", | ||
762 | .id = 0, | ||
763 | .dev = { | ||
764 | .platform_data = &a780_iclink, | ||
765 | }, | ||
766 | }; | ||
767 | |||
686 | static struct platform_device *a780_devices[] __initdata = { | 768 | static struct platform_device *a780_devices[] __initdata = { |
687 | &a780_gpio_keys, | 769 | &a780_gpio_keys, |
688 | }; | 770 | }; |
@@ -703,6 +785,11 @@ static void __init a780_init(void) | |||
703 | 785 | ||
704 | pxa_set_keypad_info(&a780_keypad_platform_data); | 786 | pxa_set_keypad_info(&a780_keypad_platform_data); |
705 | 787 | ||
788 | if (a780_camera_init() == 0) { | ||
789 | pxa_set_camera_info(&a780_pxacamera_platform_data); | ||
790 | platform_device_register(&a780_camera); | ||
791 | } | ||
792 | |||
706 | platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); | 793 | platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); |
707 | platform_add_devices(ARRAY_AND_SIZE(a780_devices)); | 794 | platform_add_devices(ARRAY_AND_SIZE(a780_devices)); |
708 | } | 795 | } |
@@ -876,6 +963,80 @@ static struct platform_device a910_gpio_keys = { | |||
876 | }, | 963 | }, |
877 | }; | 964 | }; |
878 | 965 | ||
966 | /* camera */ | ||
967 | static int a910_camera_init(void) | ||
968 | { | ||
969 | int err; | ||
970 | |||
971 | /* | ||
972 | * GPIO50_nCAM_EN is active low | ||
973 | * GPIO28_GEN2_CAM_RST is active on rising edge | ||
974 | */ | ||
975 | err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN"); | ||
976 | if (err) { | ||
977 | pr_err("%s: Failed to request nCAM_EN\n", __func__); | ||
978 | goto fail; | ||
979 | } | ||
980 | |||
981 | err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST"); | ||
982 | if (err) { | ||
983 | pr_err("%s: Failed to request CAM_RST\n", __func__); | ||
984 | goto fail_gpio_cam_rst; | ||
985 | } | ||
986 | |||
987 | gpio_direction_output(GPIO50_nCAM_EN, 1); | ||
988 | gpio_direction_output(GPIO28_GEN2_CAM_RST, 0); | ||
989 | |||
990 | return 0; | ||
991 | |||
992 | fail_gpio_cam_rst: | ||
993 | gpio_free(GPIO50_nCAM_EN); | ||
994 | fail: | ||
995 | return err; | ||
996 | } | ||
997 | |||
998 | static int a910_camera_power(struct device *dev, int on) | ||
999 | { | ||
1000 | gpio_set_value(GPIO50_nCAM_EN, !on); | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static int a910_camera_reset(struct device *dev) | ||
1005 | { | ||
1006 | gpio_set_value(GPIO28_GEN2_CAM_RST, 0); | ||
1007 | msleep(10); | ||
1008 | gpio_set_value(GPIO28_GEN2_CAM_RST, 1); | ||
1009 | |||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | struct pxacamera_platform_data a910_pxacamera_platform_data = { | ||
1014 | .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | | ||
1015 | PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, | ||
1016 | .mclk_10khz = 5000, | ||
1017 | }; | ||
1018 | |||
1019 | static struct i2c_board_info a910_camera_i2c_board_info = { | ||
1020 | I2C_BOARD_INFO("mt9m111", 0x5d), | ||
1021 | }; | ||
1022 | |||
1023 | static struct soc_camera_link a910_iclink = { | ||
1024 | .bus_id = 0, | ||
1025 | .i2c_adapter_id = 0, | ||
1026 | .board_info = &a910_camera_i2c_board_info, | ||
1027 | .module_name = "mt9m111", | ||
1028 | .power = a910_camera_power, | ||
1029 | .reset = a910_camera_reset, | ||
1030 | }; | ||
1031 | |||
1032 | static struct platform_device a910_camera = { | ||
1033 | .name = "soc-camera-pdrv", | ||
1034 | .id = 0, | ||
1035 | .dev = { | ||
1036 | .platform_data = &a910_iclink, | ||
1037 | }, | ||
1038 | }; | ||
1039 | |||
879 | static struct platform_device *a910_devices[] __initdata = { | 1040 | static struct platform_device *a910_devices[] __initdata = { |
880 | &a910_gpio_keys, | 1041 | &a910_gpio_keys, |
881 | }; | 1042 | }; |
@@ -896,6 +1057,11 @@ static void __init a910_init(void) | |||
896 | 1057 | ||
897 | pxa_set_keypad_info(&a910_keypad_platform_data); | 1058 | pxa_set_keypad_info(&a910_keypad_platform_data); |
898 | 1059 | ||
1060 | if (a910_camera_init() == 0) { | ||
1061 | pxa_set_camera_info(&a910_pxacamera_platform_data); | ||
1062 | platform_device_register(&a910_camera); | ||
1063 | } | ||
1064 | |||
899 | platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); | 1065 | platform_add_devices(ARRAY_AND_SIZE(ezx_devices)); |
900 | platform_add_devices(ARRAY_AND_SIZE(a910_devices)); | 1066 | platform_add_devices(ARRAY_AND_SIZE(a910_devices)); |
901 | } | 1067 | } |