diff options
author | Charlie Huang <chahuang@nvidia.com> | 2011-06-29 10:40:07 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-20 11:40:17 -0700 |
commit | 3c31abfab7cab9753e92239ee087b8a17d67a0ac (patch) | |
tree | 272e3f4dc086dc5b4731b2a087fc6ccf1a0b96d0 /arch | |
parent | 9b3810aed73f87c5ec0dba540f078ecf65a3e020 (diff) |
ARM: tegra: enterprise: Add front camera
modify enterprise board files to add support for ov9726
bug 829399
Change-Id: I9ebbb9926820d9209224906d2a3aa8dcde072a12
Reviewed-on: http://git-master/r/40467
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise-power.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise-sensors.c | 168 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.h | 9 |
3 files changed, 122 insertions, 60 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c index 7fd09d081995..7e00dbbf0031 100644 --- a/arch/arm/mach-tegra/board-enterprise-power.c +++ b/arch/arm/mach-tegra/board-enterprise-power.c @@ -286,17 +286,22 @@ static int gpio_switch_sdmmc3_vdd_sel_voltages[] = {2850}; /* LCD-D23 (GPIO M7) from T30*/ /* 2-0036 is dev_name of ar0832 */ +/* 2-0010 is dev_name of ov9726 */ static struct regulator_consumer_supply gpio_switch_cam_ldo_2v8_en_supply[] = { REGULATOR_SUPPLY("vaa", "2-0036"), REGULATOR_SUPPLY("vaa", "2-0032"), + REGULATOR_SUPPLY("avdd", "2-0010"), + REGULATOR_SUPPLY("vdd_2v8_cam", NULL), }; static int gpio_switch_cam_ldo_2v8_en_voltages[] = {2800}; /* LCD-D9 (GPIO F1) from T30*/ /* 2-0036 is dev_name of ar0832 */ +/* 2-0010 is dev_name of ov9726 */ static struct regulator_consumer_supply gpio_switch_cam_ldo_1v8_en_supply[] = { REGULATOR_SUPPLY("vdd", "2-0036"), REGULATOR_SUPPLY("vdd", "2-0032"), + REGULATOR_SUPPLY("dovdd", "2-0010"), REGULATOR_SUPPLY("vdd_1v8_cam", NULL), }; static int gpio_switch_cam_ldo_1v8_en_voltages[] = {1800}; diff --git a/arch/arm/mach-tegra/board-enterprise-sensors.c b/arch/arm/mach-tegra/board-enterprise-sensors.c index 3a8e75f6cf98..1c3950fd736e 100644 --- a/arch/arm/mach-tegra/board-enterprise-sensors.c +++ b/arch/arm/mach-tegra/board-enterprise-sensors.c @@ -27,7 +27,7 @@ #include <mach/gpio.h> #include <media/ar0832_main.h> #include <media/tps61050.h> - +#include <media/ov9726.h> #include "cpu-tegra.h" #include "gpio-names.h" #include "board-enterprise.h" @@ -52,11 +52,6 @@ static struct i2c_board_info enterprise_i2c4_nct1008_board_info[] = { } }; -struct enterprise_power_rail { - struct regulator *cam_reg; - struct regulator *csi_reg; -}; - static void enterprise_nct1008_init(void) { int ret; @@ -158,58 +153,89 @@ static void enterprise_isl_init(void) ARRAY_SIZE(enterprise_i2c0_isl_board_info)); } -static int enterprise_ar0832_power_on(struct enterprise_power_rail *prail) +enum CAMERA_INDEX { + CAM_REAR_LEFT, + CAM_REAR_RIGHT, + CAM_FRONT, + NUM_OF_CAM +}; + +struct enterprise_power_rail { + struct regulator *cam_reg; + struct regulator *csi_reg; +}; + +static struct enterprise_power_rail ent_vicsi_pwr[NUM_OF_CAM]; + +static int enterprise_cam_pwr(enum CAMERA_INDEX cam, bool pwr_on) { + struct enterprise_power_rail *reg_cam = &ent_vicsi_pwr[cam]; int ret = 0; - pr_info("%s: ++\n", __func__); + /* + * SW must turn on 1.8V first then 2.8V + * SW must turn off 2.8V first then 1.8V + */ + if (pwr_on) { + if (reg_cam->csi_reg == NULL) { + reg_cam->csi_reg = regulator_get(NULL, + "avdd_dsi_csi"); + if (IS_ERR_OR_NULL(reg_cam->csi_reg)) { + pr_err("%s: csi pwr err\n", __func__); + ret = PTR_ERR(reg_cam->csi_reg); + goto enterprise_cam_pwr_fail; + } + } - if (!prail->csi_reg) { - prail->csi_reg = regulator_get(NULL, "avdd_dsi_csi"); - if (IS_ERR_OR_NULL(prail->csi_reg)) { - pr_err("%s: failed to get csi pwr\n", __func__); - return PTR_ERR(prail->csi_reg); + ret = regulator_enable(reg_cam->csi_reg); + if (ret) { + pr_err("%s: enable csi pwr err\n", __func__); + goto enterprise_cam_pwr_fail; } - } - ret = regulator_enable(prail->csi_reg); - if (ret) { - pr_err("%s: failed to enable csi pwr\n", __func__); - goto fail_regulator_csi_reg; - } - if (!prail->cam_reg) { - prail->cam_reg = regulator_get(NULL, "vddio_cam"); - if (IS_ERR_OR_NULL(prail->cam_reg)) { - pr_err("%s: failed to get cam pwr\n", __func__); - ret = PTR_ERR(prail->cam_reg); - goto fail_regulator_csi_reg; + if (reg_cam->cam_reg == NULL) { + reg_cam->cam_reg = regulator_get(NULL, + "vddio_cam"); + if (IS_ERR_OR_NULL(reg_cam->cam_reg)) { + pr_err("%s: vddio pwr err\n", __func__); + ret = PTR_ERR(reg_cam->cam_reg); + regulator_disable(reg_cam->csi_reg); + goto enterprise_cam_pwr_fail; + } } - } - ret = regulator_enable(prail->cam_reg); - if (ret) { - pr_err("%s: failed to enable cam pwr\n", __func__); - goto fail_regulator_cam_reg; - } + ret = regulator_enable(reg_cam->cam_reg); + if (ret) { + pr_err("%s: enable vddio pwr err\n", __func__); + regulator_disable(reg_cam->csi_reg); + goto enterprise_cam_pwr_fail; + } + } else { + if (reg_cam->cam_reg) + regulator_disable(reg_cam->cam_reg); + + if (reg_cam->csi_reg) + regulator_disable(reg_cam->csi_reg); + } return 0; -fail_regulator_cam_reg: - regulator_put(prail->cam_reg); - prail->cam_reg = NULL; -fail_regulator_csi_reg: - regulator_put(prail->csi_reg); - prail->csi_reg = NULL; +enterprise_cam_pwr_fail: + if (!IS_ERR_OR_NULL(reg_cam->cam_reg)) + regulator_put(reg_cam->cam_reg); + reg_cam->cam_reg = NULL; + + if (!IS_ERR_OR_NULL(reg_cam->csi_reg)) + regulator_put(reg_cam->csi_reg); + reg_cam->csi_reg = NULL; + return ret; } -static struct enterprise_power_rail enterprise_ar0832_power_rail; - static int enterprise_ar0832_ri_power_on(int is_stereo) { int ret = 0; - pr_info("%s: ++\n", __func__); - ret = enterprise_ar0832_power_on(&enterprise_ar0832_power_rail); + ret = enterprise_cam_pwr(CAM_REAR_RIGHT, true); /* Release Reset */ if (is_stereo) { @@ -232,7 +258,7 @@ static int enterprise_ar0832_le_power_on(int is_stereo) int ret = 0; pr_info("%s: ++\n", __func__); - ret = enterprise_ar0832_power_on(&enterprise_ar0832_power_rail); + ret = enterprise_cam_pwr(CAM_REAR_LEFT, true); /* Release Reset */ gpio_set_value(CAM2_RST_L_GPIO, 1); @@ -250,23 +276,12 @@ static int enterprise_ar0832_le_power_on(int is_stereo) return ret; } -static int enterprise_ar0832_power_off(struct enterprise_power_rail *prail) -{ - if (prail->cam_reg) - regulator_disable(prail->cam_reg); - - if (prail->csi_reg) - regulator_disable(prail->csi_reg); - - return 0; -} - static int enterprise_ar0832_ri_power_off(int is_stereo) { int ret; pr_info("%s: ++\n", __func__); - ret = enterprise_ar0832_power_off(&enterprise_ar0832_power_rail); + ret = enterprise_cam_pwr(CAM_REAR_RIGHT, false); /* Assert Reset */ if (is_stereo) { @@ -283,7 +298,7 @@ static int enterprise_ar0832_le_power_off(int is_stereo) int ret; pr_info("%s: ++\n", __func__); - ret = enterprise_ar0832_power_off(&enterprise_ar0832_power_rail); + ret = enterprise_cam_pwr(CAM_REAR_LEFT, false); /* Assert Reset */ gpio_set_value(CAM2_RST_L_GPIO, 0); @@ -291,6 +306,35 @@ static int enterprise_ar0832_le_power_off(int is_stereo) return ret; } +static int enterprise_ov9726_power_on(void) +{ + pr_info("ov9726 power on\n"); + + /* switch mipi mux to front camera */ + gpio_set_value(CAM_CSI_MUX_SEL_GPIO, CAM_CSI_MUX_SEL_FRONT); + enterprise_cam_pwr(CAM_FRONT, true); + + return 0; +} + +static int enterprise_ov9726_power_off(void) +{ + pr_info("ov9726 power off\n"); + + enterprise_cam_pwr(CAM_FRONT, false); + + return 0; +} + +struct ov9726_platform_data enterprise_ov9726_data = { + .power_on = enterprise_ov9726_power_on, + .power_off = enterprise_ov9726_power_off, + .gpio_rst = CAM3_RST_L_GPIO, + .rst_low_active = true, + .gpio_pwdn = CAM3_PWDN_GPIO, + .pwdn_low_active = false, +}; + static struct tps61050_pin_state enterprise_tps61050_pinstate = { .mask = 0x0008, /*VGP3*/ .values = 0x0008, @@ -337,6 +381,7 @@ fail_regulator_flash_reg: return ret; } + struct enterprise_cam_gpio { int gpio; const char *label; @@ -405,6 +450,10 @@ static struct i2c_board_info ar0832_i2c2_boardinfo[] = { I2C_BOARD_INFO("tps61050", 0x33), .platform_data = &enterprise_tps61050_data, }, + { + I2C_BOARD_INFO("ov9726", OV9726_I2C_ADDR >> 1), + .platform_data = &enterprise_ov9726_data, + }, }; static int enterprise_cam_init(void) @@ -414,6 +463,7 @@ static int enterprise_cam_init(void) pr_info("%s:++\n", __func__); + memset(ent_vicsi_pwr, 0, sizeof(ent_vicsi_pwr)); for (i = 0; i < ARRAY_SIZE(enterprise_cam_gpio_data); i++) { ret = gpio_request(enterprise_cam_gpio_data[i].gpio, enterprise_cam_gpio_data[i].label); @@ -442,10 +492,12 @@ fail_free_gpio: int __init enterprise_sensors_init(void) { + int ret; enterprise_isl_init(); enterprise_nct1008_init(); enterprise_mpuirq_init(); - enterprise_cam_init(); + ret = enterprise_cam_init(); + + return ret; +} - return 0; -}
\ No newline at end of file diff --git a/arch/arm/mach-tegra/board-enterprise.h b/arch/arm/mach-tegra/board-enterprise.h index 849bd5de18ab..c2154252b09e 100644 --- a/arch/arm/mach-tegra/board-enterprise.h +++ b/arch/arm/mach-tegra/board-enterprise.h @@ -57,14 +57,19 @@ int enterprise_suspend_init(void); /*****************Camera GPIOs ******************/ #define CAM_CSI_MUX_SEL_GPIO TEGRA_GPIO_PM3 -#define CAM_LDO_1V8_EN_L_GPIO TEGRA_GPIO_PF1 -#define CAM_LDO_2V8_EN_L_GPIO TEGRA_GPIO_PM7 +#define CAM_CSI_MUX_SEL_REAR 1 +#define CAM_CSI_MUX_SEL_FRONT 0 + #define CAM1_RST_L_GPIO TEGRA_GPIO_PM5 /*REAR RIGHT*/ #define CAM1_PWDN_GPIO TEGRA_GPIO_PF3 /*REAR RIGHT*/ #define CAM2_RST_L_GPIO TEGRA_GPIO_PF4 /*REAR LEFT*/ #define CAM2_PWDN_GPIO TEGRA_GPIO_PF2 /*REAR LEFT*/ #define CAM3_RST_L_GPIO TEGRA_GPIO_PM2 /*FRONT*/ +#define CAM3_RST_L_TRUE 0 +#define CAM3_RST_L_FALSE 1 #define CAM3_PWDN_GPIO TEGRA_GPIO_PN4 /*FRONT*/ +#define CAM3_PWDN_TRUE 1 +#define CAM3_PWDN_FALSE 0 #define CAM_FLASH_EN_GPIO TEGRA_GPIO_PBB3 #define CAM_FLASH_MAX_TORCH_AMP 7 #define CAM_FLASH_MAX_FLASH_AMP 7 |