Fix incorrect license.
[linux-2.6.git] / arch / arm / mach-tegra / board-cardhu-sensors.c
index f248bd6..d352158 100644 (file)
@@ -1,21 +1,34 @@
 /*
  * arch/arm/mach-tegra/board-cardhu-sensors.c
  *
- * Copyright (c) 2011, NVIDIA, All Rights Reserved.
+ * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
  *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
  *
+ * Neither the name of NVIDIA CORPORATION nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <linux/i2c.h>
 #include "gpio-names.h"
 #include "board.h"
 #include <linux/mpu.h>
+#include <media/sh532u.h>
 
 #include <mach/gpio.h>
+#include <mach/edp.h>
 
 #include "gpio-names.h"
 #include "board-cardhu.h"
+#include "cpu-tegra.h"
 
 static struct regulator *cardhu_1v8_cam1 = NULL;
-static struct regulator *cardhu_avdd_dsi_csi = NULL;
+static struct regulator *cardhu_1v8_cam2 = NULL;
+static struct regulator *cardhu_1v8_cam3 = NULL;
 static struct regulator *cardhu_vdd_2v8_cam1 = NULL;
+static struct regulator *cardhu_vdd_2v8_cam2 = NULL;
+static struct regulator *cardhu_vdd_cam3 = NULL;
+
+static struct board_info board_info;
 
-#ifdef CONFIG_I2C_MUX_PCA954x
 static struct pca954x_platform_mode cardhu_pca954x_modes[] = {
-       { .adap_id = PCA954x_I2C_BUS0, },
-       { .adap_id = PCA954x_I2C_BUS1, },
-       { .adap_id = PCA954x_I2C_BUS2, },
-       { .adap_id = PCA954x_I2C_BUS3, },
+       { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, },
+       { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, },
+       { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, },
+       { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, },
 };
 
 static struct pca954x_platform_data cardhu_pca954x_data = {
        .modes    = cardhu_pca954x_modes,
        .num_modes      = ARRAY_SIZE(cardhu_pca954x_modes),
 };
-#endif
 
 static int cardhu_camera_init(void)
 {
        int ret;
-       struct board_info board_info;
 
-       tegra_get_board_info(&board_info);
        /* Boards E1198 and E1291 are of Cardhu personality
         * and donot have TCA6416 exp for camera */
        if ((board_info.board_id == BOARD_E1198) ||
@@ -71,12 +88,27 @@ static int cardhu_camera_init(void)
                if (ret < 0)
                        pr_err("%s: gpio_request failed for gpio %s\n",
                                __func__, "CAM1_POWER_DWN_GPIO");
+                               tegra_gpio_enable(CAM3_POWER_DWN_GPIO);
+               ret = gpio_request(CAM3_POWER_DWN_GPIO, "cam3_power_en");
+               if (ret < 0)
+                       pr_err("%s: gpio_request failed for gpio %s\n",
+                               __func__, "CAM3_POWER_DWN_GPIO");
+
+               tegra_gpio_enable(CAM2_POWER_DWN_GPIO);
+               ret = gpio_request(CAM2_POWER_DWN_GPIO, "camera2_power_en");
+               if (ret < 0)
+                       pr_err("%s: gpio_request failed for gpio %s\n",
+                               __func__, "CAM2_POWER_DWN_GPIO");
+
                tegra_gpio_enable(OV5650_RESETN_GPIO);
                ret = gpio_request(OV5650_RESETN_GPIO, "camera_reset");
                if (ret < 0)
                        pr_err("%s: gpio_request failed for gpio %s\n",
                                __func__, "OV5650_RESETN_GPIO");
+
+               gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
                gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
                mdelay(10);
 
                gpio_direction_output(OV5650_RESETN_GPIO, 1);
@@ -85,7 +117,6 @@ static int cardhu_camera_init(void)
                mdelay(5);
                gpio_direction_output(OV5650_RESETN_GPIO, 1);
                mdelay(5);
-
        }
 
        /* To select the CSIB MUX either for cam2 or cam3 */
@@ -100,18 +131,13 @@ static int cardhu_camera_init(void)
        return 0;
 }
 
-static int cardhu_ov5650_power_on(void)
+static int cardhu_left_ov5650_power_on(void)
 {
-       struct board_info board_info;
-       tegra_get_board_info(&board_info);
        /* Boards E1198 and E1291 are of Cardhu personality
         * and donot have TCA6416 exp for camera */
        if ((board_info.board_id == BOARD_E1198) ||
                (board_info.board_id == BOARD_E1291)) {
 
-               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
-               mdelay(10);
-
                if (cardhu_vdd_2v8_cam1 == NULL) {
                        cardhu_vdd_2v8_cam1 = regulator_get(NULL, "vdd_2v8_cam1");
                        if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam1))) {
@@ -120,10 +146,10 @@ static int cardhu_ov5650_power_on(void)
                                goto reg_alloc_fail;
                        }
                }
-
                regulator_enable(cardhu_vdd_2v8_cam1);
                mdelay(5);
        }
+
        /* Enable VDD_1V8_Cam1 */
        if (cardhu_1v8_cam1 == NULL) {
                cardhu_1v8_cam1 = regulator_get(NULL, "vdd_1v8_cam1");
@@ -135,17 +161,15 @@ static int cardhu_ov5650_power_on(void)
        }
        regulator_enable(cardhu_1v8_cam1);
 
-       /* Enable AVDD_CSI_DSI */
-       if (cardhu_avdd_dsi_csi == NULL) {
-               cardhu_avdd_dsi_csi = regulator_get(NULL, "avdd_dsi_csi");
-               if (WARN_ON(IS_ERR(cardhu_avdd_dsi_csi))) {
-                       pr_err("%s: couldn't get regulator avdd_dsi_csi: %ld\n",
-                               __func__, PTR_ERR(cardhu_avdd_dsi_csi));
-                       goto reg_alloc_fail;
-               }
-       }
-       regulator_enable(cardhu_avdd_dsi_csi);
        mdelay(5);
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+               mdelay(20);
+               gpio_direction_output(OV5650_RESETN_GPIO, 0);
+               mdelay(100);
+               gpio_direction_output(OV5650_RESETN_GPIO, 1);
+       }
        return 0;
 
 reg_alloc_fail:
@@ -153,53 +177,204 @@ reg_alloc_fail:
                regulator_put(cardhu_1v8_cam1);
                cardhu_1v8_cam1 = NULL;
        }
-       if (cardhu_avdd_dsi_csi) {
-               regulator_put(cardhu_avdd_dsi_csi);
-               cardhu_avdd_dsi_csi = NULL;
-       }
        if (cardhu_vdd_2v8_cam1) {
                regulator_put(cardhu_vdd_2v8_cam1);
                cardhu_vdd_2v8_cam1 = NULL;
        }
+
        return -ENODEV;
 
 }
 
-static int cardhu_ov5650_power_off(void)
+static int cardhu_left_ov5650_power_off(void)
 {
-       struct board_info board_info;
-       tegra_get_board_info(&board_info);
        /* Boards E1198 and E1291 are of Cardhu personality
         * and donot have TCA6416 exp for camera */
        if ((board_info.board_id == BOARD_E1198) ||
                (board_info.board_id == BOARD_E1291)) {
                gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
        }
        if (cardhu_1v8_cam1)
                regulator_disable(cardhu_1v8_cam1);
-       if (cardhu_avdd_dsi_csi)
-               regulator_disable(cardhu_avdd_dsi_csi);
        if (cardhu_vdd_2v8_cam1)
                regulator_disable(cardhu_vdd_2v8_cam1);
 
        return 0;
 }
 
-struct ov5650_platform_data cardhu_ov5650_data = {
-       .power_on = cardhu_ov5650_power_on,
-       .power_off = cardhu_ov5650_power_off,
+struct ov5650_platform_data cardhu_left_ov5650_data = {
+       .power_on = cardhu_left_ov5650_power_on,
+       .power_off = cardhu_left_ov5650_power_off,
+};
+
+static int cardhu_right_ov5650_power_on(void)
+{
+       /* Boards E1198 and E1291 are of Cardhu personality
+        * and donot have TCA6416 exp for camera */
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
+
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
+               mdelay(10);
+
+               if (cardhu_vdd_2v8_cam2 == NULL) {
+                       cardhu_vdd_2v8_cam2 = regulator_get(NULL, "vdd_2v8_cam2");
+                       if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam2))) {
+                               pr_err("%s: couldn't get regulator vdd_2v8_cam2: %ld\n",
+                                       __func__, PTR_ERR(cardhu_vdd_2v8_cam2));
+                               goto reg_alloc_fail;
+                       }
+               }
+               regulator_enable(cardhu_vdd_2v8_cam2);
+               mdelay(5);
+       }
+
+       /* Enable VDD_1V8_Cam2 */
+       if (cardhu_1v8_cam2 == NULL) {
+               cardhu_1v8_cam2 = regulator_get(NULL, "vdd_1v8_cam2");
+               if (WARN_ON(IS_ERR(cardhu_1v8_cam2))) {
+                       pr_err("%s: couldn't get regulator vdd_1v8_cam2: %ld\n",
+                               __func__, PTR_ERR(cardhu_1v8_cam2));
+                       goto reg_alloc_fail;
+               }
+       }
+       regulator_enable(cardhu_1v8_cam2);
+
+       mdelay(5);
+       return 0;
+
+reg_alloc_fail:
+       if (cardhu_1v8_cam2) {
+               regulator_put(cardhu_1v8_cam2);
+               cardhu_1v8_cam2 = NULL;
+       }
+       if (cardhu_vdd_2v8_cam2) {
+               regulator_put(cardhu_vdd_2v8_cam2);
+               cardhu_vdd_2v8_cam2 = NULL;
+       }
+
+       return -ENODEV;
+
+}
+
+static int cardhu_right_ov5650_power_off(void)
+{
+       /* Boards E1198 and E1291 are of Cardhu personality
+        * and donot have TCA6416 exp for camera */
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
+       }
+
+       if (cardhu_1v8_cam2)
+               regulator_disable(cardhu_1v8_cam2);
+       if (cardhu_vdd_2v8_cam2)
+               regulator_disable(cardhu_vdd_2v8_cam2);
+
+       return 0;
+}
+
+static void cardhu_ov5650_synchronize_sensors(void)
+{
+       if (board_info.board_id == BOARD_E1198) {
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               mdelay(50);
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+               mdelay(50);
+       }
+       else if (board_info.board_id == BOARD_E1291) {
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
+               mdelay(50);
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
+               mdelay(50);
+       }
+       else
+               pr_err("%s: UnSupported BoardId\n", __func__);
+}
+
+struct ov5650_platform_data cardhu_right_ov5650_data = {
+       .power_on = cardhu_right_ov5650_power_on,
+       .power_off = cardhu_right_ov5650_power_off,
+       .synchronize_sensors = cardhu_ov5650_synchronize_sensors,
 };
 
 static int cardhu_ov2710_power_on(void)
 {
-       cardhu_ov5650_power_on();
+       /* CSI-B and front sensor are muxed on verbier */
        gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
+
+       /* Boards E1198 and E1291 are of Cardhu personality
+        * and donot have TCA6416 exp for camera */
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
+
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
+               gpio_direction_output(CAM3_POWER_DWN_GPIO, 0);
+               mdelay(10);
+
+               if (cardhu_vdd_cam3 == NULL) {
+                       cardhu_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
+                       if (WARN_ON(IS_ERR(cardhu_vdd_cam3))) {
+                               pr_err("%s: couldn't get regulator vdd_cam3: %ld\n",
+                                       __func__, PTR_ERR(cardhu_vdd_cam3));
+                               goto reg_alloc_fail;
+                       }
+               }
+               regulator_enable(cardhu_vdd_cam3);
+       }
+
+       /* Enable VDD_1V8_Cam3 */
+       if (cardhu_1v8_cam3 == NULL) {
+               cardhu_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
+               if (WARN_ON(IS_ERR(cardhu_1v8_cam3))) {
+                       pr_err("%s: couldn't get regulator vdd_1v8_cam3: %ld\n",
+                               __func__, PTR_ERR(cardhu_1v8_cam3));
+                       goto reg_alloc_fail;
+               }
+       }
+       regulator_enable(cardhu_1v8_cam3);
+       mdelay(5);
+
        return 0;
+
+reg_alloc_fail:
+       if (cardhu_1v8_cam3) {
+               regulator_put(cardhu_1v8_cam3);
+               cardhu_1v8_cam3 = NULL;
+       }
+       if (cardhu_vdd_cam3) {
+               regulator_put(cardhu_vdd_cam3);
+               cardhu_vdd_cam3 = NULL;
+       }
+
+       return -ENODEV;
 }
 
 static int cardhu_ov2710_power_off(void)
 {
-       cardhu_ov5650_power_off();
+       gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
+
+       /* Boards E1198 and E1291 are of Cardhu personality
+        * and donot have TCA6416 exp for camera */
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
+               gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
+               gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
+       }
+
+       if (cardhu_1v8_cam3)
+               regulator_disable(cardhu_1v8_cam3);
+       if (cardhu_vdd_cam3)
+               regulator_disable(cardhu_vdd_cam3);
+
        return 0;
 }
 
@@ -209,17 +384,55 @@ struct ov2710_platform_data cardhu_ov2710_data = {
 };
 
 static const struct i2c_board_info cardhu_i2c3_board_info[] = {
-#ifdef CONFIG_I2C_MUX_PCA954x
        {
                I2C_BOARD_INFO("pca9546", 0x70),
                .platform_data = &cardhu_pca954x_data,
        },
-#endif
+};
+
+static int sh532u_power_control(void *cdata, int is_enable) {
+       static struct regulator *vdd_2v8_cam1_af = NULL;
+       if (vdd_2v8_cam1_af == NULL) {
+               vdd_2v8_cam1_af = regulator_get(NULL, "vdd_2v8_cam1_af");
+               if (WARN_ON(IS_ERR_OR_NULL(vdd_2v8_cam1_af))) {
+                       pr_err("%s: couldn't get regulator vdd_2v8_cam1_af:"
+                               " %ld\n", __func__, PTR_ERR(vdd_2v8_cam1_af));
+                       return -ENODEV;
+               }
+       }
+       if (is_enable) {
+               regulator_enable(vdd_2v8_cam1_af);
+               mdelay(20);
+       } else
+               regulator_disable(vdd_2v8_cam1_af);
+       return 0;
+}
+static int sh532u_init(void *cdata) {
+       return sh532u_power_control(cdata, true);
+}
+static int sh532u_deinit(void *cdata) {
+       return sh532u_power_control(cdata, false);
+}
+
+struct sh532u_platform_data sh532u_pdata = {
+       .board_init = sh532u_init,
+       .board_deinit = sh532u_deinit,
 };
 static struct i2c_board_info cardhu_i2c6_board_info[] = {
        {
-               I2C_BOARD_INFO("ov5650", 0x36),
-               .platform_data = &cardhu_ov5650_data,
+               I2C_BOARD_INFO("ov5650L", 0x36),
+               .platform_data = &cardhu_left_ov5650_data,
+       },
+       {
+               I2C_BOARD_INFO("sh532u", 0x72),
+               .platform_data = &sh532u_pdata,
+       },
+};
+
+static struct i2c_board_info cardhu_i2c7_board_info[] = {
+       {
+               I2C_BOARD_INFO("ov5650R", 0x36),
+               .platform_data = &cardhu_right_ov5650_data,
        },
 };
 
@@ -238,11 +451,18 @@ static struct nct1008_platform_data cardhu_nct1008_pdata = {
        .hysteresis = 5,
        .shutdown_ext_limit = 75,
        .shutdown_local_limit = 75,
-       .throttling_ext_limit = 60,
-       .alarm_fn = NULL,
+       .throttling_ext_limit = 90,
+       .alarm_fn = tegra_throttling_enable,
+};
+
+static struct i2c_board_info cardhu_i2c4_bq27510_board_info[] = {
+       {
+               I2C_BOARD_INFO("bq27510", 0x55),
+               .irq = AC_PRESENT_GPIO,
+       },
 };
 
-static struct i2c_board_info cardhu_i2c4_board_info[] = {
+static struct i2c_board_info cardhu_i2c4_nct1008_board_info[] = {
        {
                I2C_BOARD_INFO("nct1008", 0x4C),
                .platform_data = &cardhu_nct1008_pdata,
@@ -250,26 +470,32 @@ static struct i2c_board_info cardhu_i2c4_board_info[] = {
        }
 };
 
+#ifdef CONFIG_TEGRA_EDP_LIMITS
+extern void cardhu_thermal_zones_info(struct tegra_edp_limits **, int *);
+#endif
+
 static int cardhu_nct1008_init(void)
 {
        int nct1008_port = -1;
-       struct board_info BoardInfo;
        int ret;
+#ifdef CONFIG_TEGRA_EDP_LIMITS
+       struct tegra_edp_limits *z;
+       int zones_sz;
+       int i;
+#endif
 
-       tegra_get_board_info(&BoardInfo);
-       if ((BoardInfo.board_id == BOARD_E1198) ||
-               (BoardInfo.board_id == BOARD_E1291)) {
+       if ((board_info.board_id == BOARD_E1198) ||
+               (board_info.board_id == BOARD_E1291)) {
                nct1008_port = TEGRA_GPIO_PCC2;
-       } else if ((BoardInfo.board_id == BOARD_E1186) ||
-               (BoardInfo.board_id == BOARD_E1187)) {
+       } else if ((board_info.board_id == BOARD_E1186) ||
+               (board_info.board_id == BOARD_E1187)) {
                /* FIXME: seems to be conflicting with usb3 vbus on E1186 */
                /* nct1008_port = TEGRA_GPIO_PH7; */
        }
 
        if (nct1008_port >= 0) {
                /* FIXME: enable irq when throttling is supported */
-               /* cardhu_i2c4_board_info[0].irq = */
-               /* TEGRA_GPIO_TO_IRQ(nct1008_port); */
+               cardhu_i2c4_nct1008_board_info[0].irq = TEGRA_GPIO_TO_IRQ(nct1008_port);
 
                ret = gpio_request(nct1008_port, "temp_alert");
                if (ret < 0)
@@ -280,8 +506,16 @@ static int cardhu_nct1008_init(void)
                        gpio_free(nct1008_port);
                else
                        tegra_gpio_enable(nct1008_port);
-
        }
+
+#ifdef CONFIG_TEGRA_EDP_LIMITS
+       cardhu_thermal_zones_info(&z, &zones_sz);
+       zones_sz = min(zones_sz, MAX_ZONES);
+       for (i = 0; i < zones_sz; i++)
+               cardhu_nct1008_pdata.thermal_zones[i] = z[i].temperature;
+
+       cardhu_nct1008_pdata.thermal_zones_sz = zones_sz;
+#endif
        return ret;
 }
 
@@ -310,11 +544,9 @@ static const struct i2c_board_info cardhu_i2c2_board_info_tca6416[] = {
 
 static int __init pmu_tca6416_init(void)
 {
-       struct board_info board_info;
-       tegra_get_board_info(&board_info);
        if ((board_info.board_id == BOARD_E1198) ||
-                       (board_info.board_id == BOARD_E1291))
-               return 0;
+               (board_info.board_id == BOARD_E1291))
+                       return 0;
 
        pr_info("Registering pmu pca6416\n");
        i2c_register_board_info(4, cardhu_i2c4_board_info_tca6416,
@@ -324,8 +556,6 @@ static int __init pmu_tca6416_init(void)
 
 static int __init cam_tca6416_init(void)
 {
-       struct board_info board_info;
-       tegra_get_board_info(&board_info);
        /* Boards E1198 and E1291 are of Cardhu personality
         * and donot have TCA6416 exp for camera */
        if ((board_info.board_id == BOARD_E1198) ||
@@ -392,41 +622,55 @@ static void cardhu_mpuirq_init(void)
 #endif
 
 
+static struct i2c_board_info cardhu_i2c2_isl_board_info[] = {
+       {
+               I2C_BOARD_INFO("isl29028", 0x44),
+       }
+};
+
 int __init cardhu_sensors_init(void)
 {
        int err;
 
+       tegra_get_board_info(&board_info);
+
        cardhu_camera_init();
        cam_tca6416_init();
 
        i2c_register_board_info(2, cardhu_i2c3_board_info,
                ARRAY_SIZE(cardhu_i2c3_board_info));
 
-       /* CAM-A is on BUS0 to set CAM-B need to change
-        * PCA954x_I2C_BUS0 to PCA954x_I2C_BUS1 */
+       /* Left  camera is on PCA954x's I2C BUS0, Right camera is on BUS1 &
+        * Front camera is on BUS2 */
        i2c_register_board_info(PCA954x_I2C_BUS0, cardhu_i2c6_board_info,
                ARRAY_SIZE(cardhu_i2c6_board_info));
 
+       i2c_register_board_info(PCA954x_I2C_BUS1, cardhu_i2c7_board_info,
+               ARRAY_SIZE(cardhu_i2c7_board_info));
+
        i2c_register_board_info(PCA954x_I2C_BUS2, cardhu_i2c8_board_info,
                ARRAY_SIZE(cardhu_i2c8_board_info));
 
        pmu_tca6416_init();
 
-       i2c_register_board_info(4, cardhu_i2c4_board_info,
-               ARRAY_SIZE(cardhu_i2c4_board_info));
+       if (board_info.board_id == BOARD_E1291)
+               i2c_register_board_info(4, cardhu_i2c4_bq27510_board_info,
+                       ARRAY_SIZE(cardhu_i2c4_bq27510_board_info));
+
+       i2c_register_board_info(2, cardhu_i2c2_isl_board_info,
+               ARRAY_SIZE(cardhu_i2c2_isl_board_info));
 
        err = cardhu_nct1008_init();
        if (err)
                return err;
 
+       i2c_register_board_info(4, cardhu_i2c4_nct1008_board_info,
+               ARRAY_SIZE(cardhu_i2c4_nct1008_board_info));
+
 #ifdef CONFIG_SENSORS_MPU3050
        cardhu_mpuirq_init();
 #endif
 
-       if (ARRAY_SIZE(cardhu_i2c3_board_info))
-               i2c_register_board_info(3, cardhu_i2c3_board_info,
-                       ARRAY_SIZE(cardhu_i2c3_board_info));
-
 #ifdef CONFIG_SENSORS_MPU3050
        i2c_register_board_info(2, mpu3050_i2c0_boardinfo,
                ARRAY_SIZE(mpu3050_i2c0_boardinfo));
@@ -472,6 +716,7 @@ int __init cardhu_ov5650_late_init(void)
        int ret;
        int i;
 
+       printk("%s: \n", __func__);
        for (i = 0; i < ARRAY_SIZE(ov5650_gpio_keys); i++) {
                ret = gpio_request(ov5650_gpio_keys[i].gpio,
                        ov5650_gpio_keys[i].name);
@@ -480,6 +725,7 @@ int __init cardhu_ov5650_late_init(void)
                                __func__, i);
                        goto fail;
                }
+               printk("%s: enable - %d\n", __func__, i);
                gpio_direction_output(ov5650_gpio_keys[i].gpio,
                        ov5650_gpio_keys[i].enabled);
                gpio_export(ov5650_gpio_keys[i].gpio, false);