summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorCharlie Huang <chahuang@nvidia.com>2011-06-29 10:40:07 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-07-20 11:40:17 -0700
commit3c31abfab7cab9753e92239ee087b8a17d67a0ac (patch)
tree272e3f4dc086dc5b4731b2a087fc6ccf1a0b96d0 /arch
parent9b3810aed73f87c5ec0dba540f078ecf65a3e020 (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.c5
-rw-r--r--arch/arm/mach-tegra/board-enterprise-sensors.c168
-rw-r--r--arch/arm/mach-tegra/board-enterprise.h9
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