Ventana: KBC: Removing the KBC usage on ventana
[linux-2.6.git] / arch / arm / mach-tegra / board-enterprise-sensors.c
index 3a8e75f..2874971 100644 (file)
@@ -1,21 +1,34 @@
 /*
  * arch/arm/mach-tegra/board-enterprise-sensors.c
  *
- * Copyright (c) 2011, NVIDIA, All Rights Reserved.
+ * Copyright (c) 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>
@@ -27,7 +40,8 @@
 #include <mach/gpio.h>
 #include <media/ar0832_main.h>
 #include <media/tps61050.h>
-
+#include <media/ov9726.h>
+#include <mach/edp.h>
 #include "cpu-tegra.h"
 #include "gpio-names.h"
 #include "board-enterprise.h"
@@ -36,11 +50,10 @@ static struct nct1008_platform_data enterprise_nct1008_pdata = {
        .supported_hwrev = true,
        .ext_range = true,
        .conv_rate = 0x08,
-       .offset = 0,
        .hysteresis = 5,
-       .shutdown_ext_limit = 75,
-       .shutdown_local_limit = 75,
-       .throttling_ext_limit = 90,
+       .shutdown_ext_limit = 90,
+       .shutdown_local_limit = 90,
+       .throttling_ext_limit = 75,
        .alarm_fn = tegra_throttling_enable,
 };
 
@@ -52,14 +65,16 @@ 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;
+       struct nct1008_platform_data *pdata;
+#ifdef CONFIG_TEGRA_EDP_LIMITS
+       const struct tegra_edp_limits *z;
+       int zones_sz;
+       int i;
+       bool throttle_ok = false;
+#endif
 
        tegra_gpio_enable(TEGRA_GPIO_PH7);
        ret = gpio_request(TEGRA_GPIO_PH7, "temp_alert");
@@ -75,8 +90,33 @@ static void enterprise_nct1008_init(void)
                return;
        }
 
+       /* Temperature guardband AP30S DSC: bug 844025 */
+       pdata = enterprise_i2c4_nct1008_board_info[0].platform_data;
+       pdata->offset = 33; /* 4 * 8.25C */
+
        i2c_register_board_info(4, enterprise_i2c4_nct1008_board_info,
                                ARRAY_SIZE(enterprise_i2c4_nct1008_board_info));
+#ifdef CONFIG_TEGRA_EDP_LIMITS
+       tegra_get_cpu_edp_limits(&z, &zones_sz);
+       zones_sz = min(zones_sz, MAX_ZONES);
+       for (i = 0; i < zones_sz; i++) {
+               enterprise_nct1008_pdata.thermal_zones[i] = z[i].temperature;
+               if (enterprise_nct1008_pdata.thermal_zones[i] ==
+                   enterprise_nct1008_pdata.throttling_ext_limit) {
+                       throttle_ok = true;
+               }
+       }
+
+       if (throttle_ok != true)
+               pr_warn("%s: WARNING! Throttling limit %dC would be inaccurate"
+                       " as it is NOT one of the EDP points\n",
+                       __func__, enterprise_nct1008_pdata.throttling_ext_limit);
+       else
+               pr_info("%s: Throttling limit %dC OK\n",
+                       __func__, enterprise_nct1008_pdata.throttling_ext_limit);
+
+       enterprise_nct1008_pdata.thermal_zones_sz = zones_sz;
+#endif
 }
 
 #define SENSOR_MPU_NAME "mpu3050"
@@ -158,58 +198,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 +303,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 +321,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 +343,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 +351,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 +426,7 @@ fail_regulator_flash_reg:
        return ret;
 }
 
+
 struct enterprise_cam_gpio {
        int gpio;
        const char *label;
@@ -405,6 +495,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 +508,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 +537,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