ARM: tegra: enterprise: Add front camera
Charlie Huang [Wed, 29 Jun 2011 17:40:07 +0000 (10:40 -0700)]
modify enterprise board files to add support for ov9726

bug 829399

Original-Change-Id: I9ebbb9926820d9209224906d2a3aa8dcde072a12
Reviewed-on: http://git-master/r/40467
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: Rb444bad59ae0f7ce83b79c8326175fa15964d069

arch/arm/mach-tegra/board-enterprise-power.c
arch/arm/mach-tegra/board-enterprise-sensors.c
arch/arm/mach-tegra/board-enterprise.h

index 4da5d1d..2e8855b 100644 (file)
@@ -285,17 +285,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};
index 3a8e75f..1c3950f 100644 (file)
@@ -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
index 0ccff3e..334d0c9 100644 (file)
@@ -58,14 +58,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