]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - arch/arm/mach-tegra/board-dalmore-sensors.c
ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / board-dalmore-sensors.c
index 6da7f314f70786a3e65decc1a1f7659b0433ac64..581524ffb493fc96106b6e6c55c6136202204120 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/board-dalmore-sensors.c
  *
- * Copyright (c) 2012 NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2012-2013 NVIDIA CORPORATION, All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
 
 #include <linux/i2c.h>
 #include <linux/delay.h>
-#include <mach/gpio.h>
-#include "gpio-names.h"
-#include "board.h"
-#include <mach/gpio.h>
-#include <media/imx091.h>
-#include <media/ov9772.h>
-#include "board-dalmore.h"
-#include "cpu-tegra.h"
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
+#include <linux/mpu.h>
 #include <linux/regulator/consumer.h>
-#include <linux/i2c/pca954x.h>
-#include <linux/i2c/pca953x.h>
-#include <linux/nct1008.h>
 #include <linux/gpio.h>
-
+#include <linux/therm_est.h>
+#include <linux/nct1008.h>
+#include <linux/pid_thermal_gov.h>
+#include <mach/edp.h>
+#include <linux/edp.h>
 #include <mach/gpio-tegra.h>
-#include <mach/fb.h>
-
+#include <mach/pinmux-t11.h>
+#include <mach/pinmux.h>
+#ifndef CONFIG_OF
 #include <media/imx091.h>
+#include <media/ad5816.h>
+#include <media/ov9772.h>
+#endif
+#include <media/as364x.h>
 #include <generated/mach-types.h>
+#include <linux/power/sbs-battery.h>
 
-#include <linux/mpu.h>
+#include "gpio-names.h"
+#include "board.h"
+#include "board-common.h"
 #include "board-dalmore.h"
+#include "cpu-tegra.h"
+#include "devices.h"
+#include "tegra-board-id.h"
+#include "dvfs.h"
+
+#ifndef CONFIG_OF
+static struct nvc_gpio_pdata imx091_gpio_pdata[] = {
+       {IMX091_GPIO_RESET, CAM_RSTN, true, false},
+       {IMX091_GPIO_PWDN, CAM1_POWER_DWN_GPIO, true, false},
+       {IMX091_GPIO_GP1, CAM_GPIO1, true, false}
+};
+#endif
 
 static struct board_info board_info;
 
-static char *dalmore_cam_reg_name[] = {
-       "vdd_sensor_2v85",      /* 2.85V */
-       "avddio_usb",           /* VDDIO USB CAM */
-       "dvdd_cam",             /* DVDD CAM */
-       "vddio_cam",            /* Tegra CAM_I2C, CAM_MCLK, VDD 1.8V */
-       "avdd_cam1",            /* Analog VDD 2.7V */
-       "avdd_cam2",            /* Analog VDD 2.7V */
+static struct throttle_table tj_throttle_table[] = {
+       /* CPU_THROT_LOW cannot be used by other than CPU */
+       /*      CPU,  C2BUS,  C3BUS,   SCLK,    EMC   */
+       { { 1810500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1785000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1759500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1734000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1708500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1683000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1657500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1632000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1606500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1581000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1555500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1530000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1504500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1479000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1453500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1428000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1402500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1377000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1351500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1326000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1300500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1275000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1249500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1224000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1198500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1173000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1147500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1122000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1096500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1071000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1045500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1020000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  994500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  969000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  943500, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  918000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  892500, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  867000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  841500, 564000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  816000, 564000, NO_CAP, NO_CAP, 792000 } },
+       { {  790500, 564000, NO_CAP, 372000, 792000 } },
+       { {  765000, 564000, 468000, 372000, 792000 } },
+       { {  739500, 528000, 468000, 372000, 792000 } },
+       { {  714000, 528000, 468000, 336000, 792000 } },
+       { {  688500, 528000, 420000, 336000, 792000 } },
+       { {  663000, 492000, 420000, 336000, 792000 } },
+       { {  637500, 492000, 420000, 336000, 408000 } },
+       { {  612000, 492000, 420000, 300000, 408000 } },
+       { {  586500, 492000, 360000, 336000, 408000 } },
+       { {  561000, 420000, 420000, 300000, 408000 } },
+       { {  535500, 420000, 360000, 228000, 408000 } },
+       { {  510000, 420000, 288000, 228000, 408000 } },
+       { {  484500, 324000, 288000, 228000, 408000 } },
+       { {  459000, 324000, 288000, 228000, 408000 } },
+       { {  433500, 324000, 288000, 228000, 408000 } },
+       { {  408000, 324000, 288000, 228000, 408000 } },
 };
 
-static struct regulator *dalmore_cam_reg[ARRAY_SIZE(dalmore_cam_reg_name)];
+static struct balanced_throttle tj_throttle = {
+       .throt_tab_size = ARRAY_SIZE(tj_throttle_table),
+       .throt_tab = tj_throttle_table,
+};
 
-static int dalmore_imx091_power_on(void)
+static int __init dalmore_throttle_init(void)
 {
+       if (machine_is_dalmore())
+               balanced_throttle_register(&tj_throttle, "tegra-balanced");
+       return 0;
+}
+module_init(dalmore_throttle_init);
+
+static struct nct1008_platform_data dalmore_nct1008_pdata = {
+       .supported_hwrev = true,
+       .ext_range = true,
+       .conv_rate = 0x06, /* 4Hz conversion rate */
+       .shutdown_ext_limit = 105, /* C */
+       .shutdown_local_limit = 120, /* C */
+
+       .num_trips = 1,
+       .trips = {
+               {
+                       .cdev_type = "suspend_soctherm",
+                       .trip_temp = 50000,
+                       .trip_type = THERMAL_TRIP_ACTIVE,
+                       .upper = 1,
+                       .lower = 1,
+                       .hysteresis = 5000,
+               },
+       },
+};
 
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
-               if (!dalmore_cam_reg[i]) {
-                       dalmore_cam_reg[i] = regulator_get(NULL,
-                                       dalmore_cam_reg_name[i]);
-                       if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
-                               pr_err("%s: didn't get regulator #%d: %ld\n",
-                               __func__, i, PTR_ERR(dalmore_cam_reg[i]));
-                               goto reg_alloc_fail;
-                       }
-               }
-               regulator_enable(dalmore_cam_reg[i]);
+static struct i2c_board_info dalmore_i2c4_nct1008_board_info[] = {
+       {
+               I2C_BOARD_INFO("nct1008", 0x4C),
+               .platform_data = &dalmore_nct1008_pdata,
+               .irq = -1,
        }
+};
+
+#define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
+       {                                                       \
+               .pingroup       = TEGRA_PINGROUP_##_pingroup,   \
+               .func           = TEGRA_MUX_##_mux,             \
+               .pupd           = TEGRA_PUPD_##_pupd,           \
+               .tristate       = TEGRA_TRI_##_tri,             \
+               .io             = TEGRA_PIN_##_io,              \
+               .lock           = TEGRA_PIN_LOCK_##_lock,       \
+               .od             = TEGRA_PIN_OD_DEFAULT,         \
+               .ioreset        = TEGRA_PIN_IO_RESET_##_ioreset \
+}
+
+#ifndef CONFIG_OF
+static int dalmore_focuser_power_on(struct ad5816_power_rail *pw)
+{
+       int err;
+
+       if (unlikely(WARN_ON(!pw || !pw->vdd || !pw->vdd_i2c)))
+               return -EFAULT;
 
-       gpio_direction_output(CAM_RSTN, 0);
-       mdelay(10);
-       gpio_direction_output(CAM_AF_PWDN, 1);
-       gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
-       gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
-       gpio_direction_output(CAM_RSTN, 1);
+       err = regulator_enable(pw->vdd_i2c);
+       if (unlikely(err))
+               goto ad5816_vdd_i2c_fail;
+
+       err = regulator_enable(pw->vdd);
+       if (unlikely(err))
+               goto ad5816_vdd_fail;
 
        return 0;
 
-reg_alloc_fail:
+ad5816_vdd_fail:
+       regulator_disable(pw->vdd_i2c);
 
-       for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
-               if (dalmore_cam_reg[i]) {
-                       regulator_put(dalmore_cam_reg[i]);
-                       dalmore_cam_reg[i] = NULL;
-               }
-       }
+ad5816_vdd_i2c_fail:
+       pr_err("%s FAILED\n", __func__);
 
        return -ENODEV;
 }
 
-static int dalmore_imx091_power_off(void)
+static int dalmore_focuser_power_off(struct ad5816_power_rail *pw)
 {
-       int i;
-       gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
-
-       for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
-               if (dalmore_cam_reg[i]) {
-                       regulator_disable(dalmore_cam_reg[i]);
-                       regulator_put(dalmore_cam_reg[i]);
-                       dalmore_cam_reg[i] = NULL;
-               }
-       }
+       if (unlikely(WARN_ON(!pw || !pw->vdd || !pw->vdd_i2c)))
+               return -EFAULT;
+
+       regulator_disable(pw->vdd);
+       regulator_disable(pw->vdd_i2c);
 
        return 0;
 }
 
-static int dalmore_ov9772_power_on(void)
-{
+static struct tegra_pingroup_config mclk_disable =
+       VI_PINMUX(CAM_MCLK, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
-               if (!dalmore_cam_reg[i]) {
-                       dalmore_cam_reg[i] = regulator_get(NULL,
-                                       dalmore_cam_reg_name[i]);
-                       if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
-                               pr_err("%s: didn't get regulator #%d: %ld\n",
-                               __func__, i, PTR_ERR(dalmore_cam_reg[i]));
-                               goto reg_alloc_fail;
-                       }
-               }
-               regulator_enable(dalmore_cam_reg[i]);
-       }
+static struct tegra_pingroup_config mclk_enable =
+       VI_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       gpio_direction_output(CAM_RSTN, 0);
-       mdelay(10);
-       gpio_direction_output(CAM_AF_PWDN, 1);
-       gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
-       gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
-       gpio_direction_output(CAM_RSTN, 1);
+static struct tegra_pingroup_config pbb0_disable =
+       VI_PINMUX(GPIO_PBB0, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       return 0;
+static struct tegra_pingroup_config pbb0_enable =
+       VI_PINMUX(GPIO_PBB0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
+#endif
 
-reg_alloc_fail:
+/*
+ * As a workaround, dalmore_vcmvdd need to be allocated to activate the
+ * sensor devices. This is due to the focuser device(AD5816) will hook up
+ * the i2c bus if it is not powered up.
+*/
+static struct regulator *dalmore_vcmvdd;
 
-       for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
-               if (dalmore_cam_reg[i]) {
-                       regulator_put(dalmore_cam_reg[i]);
-                       dalmore_cam_reg[i] = NULL;
+static int dalmore_get_vcmvdd(void)
+{
+       if (!dalmore_vcmvdd) {
+               dalmore_vcmvdd = regulator_get(NULL, "vdd_af_cam1");
+               if (unlikely(WARN_ON(IS_ERR(dalmore_vcmvdd)))) {
+                       pr_err("%s: can't get regulator vcmvdd: %ld\n",
+                               __func__, PTR_ERR(dalmore_vcmvdd));
+                       dalmore_vcmvdd = NULL;
+                       return -ENODEV;
                }
        }
+       return 0;
+}
+
+#ifndef CONFIG_OF
+static int dalmore_imx091_power_on(struct nvc_regulator *vreg)
+{
+       int err;
+
+       if (unlikely(WARN_ON(!vreg)))
+               return -EFAULT;
+
+       if (dalmore_get_vcmvdd())
+               goto imx091_poweron_fail;
+
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+       usleep_range(10, 20);
 
+       err = regulator_enable(vreg[IMX091_VREG_AVDD].vreg);
+       if (err)
+               goto imx091_avdd_fail;
+
+       err = regulator_enable(vreg[IMX091_VREG_IOVDD].vreg);
+       if (err)
+               goto imx091_iovdd_fail;
+
+       usleep_range(1, 2);
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 1);
+
+       err = regulator_enable(dalmore_vcmvdd);
+       if (unlikely(err))
+               goto imx091_vcmvdd_fail;
+
+       tegra_pinmux_config_table(&mclk_enable, 1);
+       usleep_range(300, 310);
+
+       return 1;
+
+imx091_vcmvdd_fail:
+       regulator_disable(vreg[IMX091_VREG_IOVDD].vreg);
+
+imx091_iovdd_fail:
+       regulator_disable(vreg[IMX091_VREG_AVDD].vreg);
+
+imx091_avdd_fail:
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+
+imx091_poweron_fail:
+       pr_err("%s FAILED\n", __func__);
        return -ENODEV;
 }
 
-static int dalmore_ov9772_power_off(void)
+static int dalmore_imx091_power_off(struct nvc_regulator *vreg)
 {
-       int i;
-       gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
-
-       for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
-               if (dalmore_cam_reg[i]) {
-                       regulator_disable(dalmore_cam_reg[i]);
-                       regulator_put(dalmore_cam_reg[i]);
-                       dalmore_cam_reg[i] = NULL;
-               }
-       }
+       if (unlikely(WARN_ON(!vreg)))
+               return -EFAULT;
 
-       return 0;
+       usleep_range(1, 2);
+       tegra_pinmux_config_table(&mclk_disable, 1);
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+       usleep_range(1, 2);
+
+       regulator_disable(dalmore_vcmvdd);
+       regulator_disable(vreg[IMX091_VREG_IOVDD].vreg);
+       regulator_disable(vreg[IMX091_VREG_AVDD].vreg);
+
+       return 1;
+}
+
+static struct nvc_imager_cap imx091_cap = {
+       .identifier             = "IMX091",
+       .sensor_nvc_interface   = 3,
+       .pixel_types[0]         = 0x100,
+       .orientation            = 0,
+       .direction              = 0,
+       .initial_clock_rate_khz = 6000,
+       .clock_profiles[0] = {
+               .external_clock_khz     = 24000,
+               .clock_multiplier       = 850000, /* value / 1,000,000 */
+       },
+       .clock_profiles[1] = {
+               .external_clock_khz     = 0,
+               .clock_multiplier       = 0,
+       },
+       .h_sync_edge            = 0,
+       .v_sync_edge            = 0,
+       .mclk_on_vgp0           = 0,
+       .csi_port               = 0,
+       .data_lanes             = 4,
+       .virtual_channel_id     = 0,
+       .discontinuous_clk_mode = 1,
+       .cil_threshold_settle   = 0x0,
+       .min_blank_time_width   = 16,
+       .min_blank_time_height  = 16,
+       .preferred_mode_index   = 0,
+       .focuser_guid           = NVC_FOCUS_GUID(0),
+       .torch_guid             = NVC_TORCH_GUID(0),
+       .cap_version            = NVC_IMAGER_CAPABILITIES_VERSION2,
+};
+
+static struct imx091_platform_data imx091_pdata = {
+       .num                    = 0,
+       .sync                   = 0,
+       .dev_name               = "camera",
+       .gpio_count             = ARRAY_SIZE(imx091_gpio_pdata),
+       .gpio                   = imx091_gpio_pdata,
+       .flash_cap              = {
+               .sdo_trigger_enabled = 1,
+               .adjustable_flash_timing = 1,
+       },
+       .cap                    = &imx091_cap,
+       .power_on               = dalmore_imx091_power_on,
+       .power_off              = dalmore_imx091_power_off,
+};
+#endif
+
+static struct sbs_platform_data sbs_pdata = {
+       .poll_retry_count = 100,
+       .i2c_retry_count = 2,
+};
+
+#ifndef CONFIG_OF
+static int dalmore_ov9772_power_on(struct ov9772_power_rail *pw)
+{
+       int err;
+
+       if (unlikely(!pw || !pw->avdd || !pw->dovdd))
+               return -EFAULT;
+
+       if (dalmore_get_vcmvdd())
+               goto ov9772_get_vcmvdd_fail;
+
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+       gpio_set_value(CAM_RSTN, 0);
+
+       err = regulator_enable(pw->avdd);
+       if (unlikely(err))
+               goto ov9772_avdd_fail;
+
+       err = regulator_enable(pw->dovdd);
+       if (unlikely(err))
+               goto ov9772_dovdd_fail;
+
+       gpio_set_value(CAM_RSTN, 1);
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 1);
+
+       err = regulator_enable(dalmore_vcmvdd);
+       if (unlikely(err))
+               goto ov9772_vcmvdd_fail;
+
+       tegra_pinmux_config_table(&pbb0_enable, 1);
+       usleep_range(340, 380);
+
+       /* return 1 to skip the in-driver power_on sequence */
+       return 1;
+
+ov9772_vcmvdd_fail:
+       regulator_disable(pw->dovdd);
+
+ov9772_dovdd_fail:
+       regulator_disable(pw->avdd);
+
+ov9772_avdd_fail:
+       gpio_set_value(CAM_RSTN, 0);
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+
+ov9772_get_vcmvdd_fail:
+       pr_err("%s FAILED\n", __func__);
+       return -ENODEV;
+}
+
+static int dalmore_ov9772_power_off(struct ov9772_power_rail *pw)
+{
+       if (unlikely(!pw || !dalmore_vcmvdd || !pw->avdd || !pw->dovdd))
+               return -EFAULT;
+
+       usleep_range(21, 25);
+       tegra_pinmux_config_table(&pbb0_disable, 1);
+
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+       gpio_set_value(CAM_RSTN, 0);
+
+       regulator_disable(dalmore_vcmvdd);
+       regulator_disable(pw->dovdd);
+       regulator_disable(pw->avdd);
+
+       /* return 1 to skip the in-driver power_off sequence */
+       return 1;
+}
+
+static struct nvc_gpio_pdata ov9772_gpio_pdata[] = {
+       { OV9772_GPIO_TYPE_SHTDN, CAM2_POWER_DWN_GPIO, true, 0, },
+       { OV9772_GPIO_TYPE_PWRDN, CAM_RSTN, true, 0, },
+};
+
+static struct ov9772_platform_data dalmore_ov9772_pdata = {
+       .num            = 1,
+       .dev_name       = "camera",
+       .gpio_count     = ARRAY_SIZE(ov9772_gpio_pdata),
+       .gpio           = ov9772_gpio_pdata,
+       .power_on       = dalmore_ov9772_power_on,
+       .power_off      = dalmore_ov9772_power_off,
+};
+#endif
+
+static int dalmore_as3648_power_on(struct as364x_power_rail *pw)
+{
+       int err = dalmore_get_vcmvdd();
+
+       if (err)
+               return err;
+
+       return regulator_enable(dalmore_vcmvdd);
+}
+
+static int dalmore_as3648_power_off(struct as364x_power_rail *pw)
+{
+       if (!dalmore_vcmvdd)
+               return -ENODEV;
+
+       return regulator_disable(dalmore_vcmvdd);
 }
 
-struct imx091_platform_data dalmore_imx091_data = {
-       .power_on = dalmore_imx091_power_on,
-       .power_off = dalmore_imx091_power_off,
+static struct as364x_platform_data dalmore_as3648_pdata = {
+       .config         = {
+               .led_mask       = 3,
+               .max_total_current_mA = 1000,
+               .max_peak_current_mA = 600,
+               .vin_low_v_run_mV = 3070,
+               .strobe_type = 1,
+               },
+       .pinstate       = {
+               .mask   = 1 << (CAM_FLASH_STROBE - TEGRA_GPIO_PBB0),
+               .values = 1 << (CAM_FLASH_STROBE - TEGRA_GPIO_PBB0)
+               },
+       .dev_name       = "torch",
+       .type           = AS3648,
+       .gpio_strobe    = CAM_FLASH_STROBE,
+
+       .power_on_callback = dalmore_as3648_power_on,
+       .power_off_callback = dalmore_as3648_power_off,
 };
 
-struct ov9772_platform_data dalmore_ov9772_data = {
-       .power_on = dalmore_ov9772_power_on,
-       .power_off = dalmore_ov9772_power_off,
+#ifndef CONFIG_OF
+static struct ad5816_platform_data dalmore_ad5816_pdata = {
+       .cfg = 0,
+       .num = 0,
+       .sync = 0,
+       .dev_name = "focuser",
+       .power_on = dalmore_focuser_power_on,
+       .power_off = dalmore_focuser_power_off,
 };
+#endif
 
 static struct i2c_board_info dalmore_i2c_board_info_e1625[] = {
+#ifndef CONFIG_OF
        {
                I2C_BOARD_INFO("imx091", 0x36),
-               .platform_data = &dalmore_imx091_data,
+               .platform_data = &imx091_pdata,
        },
        {
                I2C_BOARD_INFO("ov9772", 0x10),
-               .platform_data = &dalmore_ov9772_data,
+               .platform_data = &dalmore_ov9772_pdata,
+       },
+#endif
+       {
+               I2C_BOARD_INFO("as3648", 0x30),
+               .platform_data = &dalmore_as3648_pdata,
        },
+#ifndef CONFIG_OF
+       {
+               I2C_BOARD_INFO("ad5816", 0x0E),
+               .platform_data = &dalmore_ad5816_pdata,
+       },
+#endif
 };
 
-struct dalmore_cam_gpio {
-       int gpio;
-       const char *label;
-       int value;
-};
+static int dalmore_camera_init(void)
+{
+#ifndef CONFIG_OF
+       tegra_pinmux_config_table(&mclk_disable, 1);
+       tegra_pinmux_config_table(&pbb0_disable, 1);
+#endif
+
+       i2c_register_board_info(2, dalmore_i2c_board_info_e1625,
+               ARRAY_SIZE(dalmore_i2c_board_info_e1625));
+       return 0;
+}
 
 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)               \
        {                                                       \
@@ -213,111 +547,306 @@ struct dalmore_cam_gpio {
                .value = _value,                                \
        }
 
-static struct dalmore_cam_gpio dalmore_cam_gpio_data[] = {
-       [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 0),
-       [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 0),
-       [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
-       [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
-       [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
-       [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
+static struct i2c_board_info dalmore_i2c_board_info_cm3218[] = {
+       {
+               I2C_BOARD_INFO("cm3218", 0x48),
+       },
 };
 
-static int dalmore_camera_init(void)
+/* MPU board file definition   */
+static struct mpu_platform_data mpu9150_gyro_data = {
+       .int_config     = 0x10,
+       .level_shifter  = 0,
+       /* Located in board_[platformname].h */
+       .orientation    = MPU_GYRO_ORIENTATION,
+       .sec_slave_type = SECONDARY_SLAVE_TYPE_NONE,
+       .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
+                          0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
+};
+
+static struct mpu_platform_data mpu_compass_data = {
+       .orientation    = MPU_COMPASS_ORIENTATION,
+       .config         = NVI_CONFIG_BOOT_MPU,
+};
+
+static struct mpu_platform_data bmp180_pdata = {
+       .config         = NVI_CONFIG_BOOT_MPU,
+};
+
+static struct i2c_board_info __initdata inv_mpu9150_i2c2_board_info[] = {
+       {
+               I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
+               .platform_data = &mpu9150_gyro_data,
+       },
+       {
+               /* The actual BMP180 address is 0x77 but because this conflicts
+                * with another device, this address is hacked so Linux will
+                * call the driver.  The conflict is technically okay since the
+                * BMP180 is behind the MPU.  Also, the BMP180 driver uses a
+                * hard-coded address of 0x77 since it can't be changed anyway.
+                */
+               I2C_BOARD_INFO("bmp180", 0x78),
+               .platform_data = &bmp180_pdata,
+       },
+       {
+               I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
+               .platform_data = &mpu_compass_data,
+       },
+};
+
+static void mpuirq_init(void)
 {
+       int ret = 0;
+       unsigned gyro_irq_gpio = MPU_GYRO_IRQ_GPIO;
+       unsigned gyro_bus_num = MPU_GYRO_BUS_NUM;
+       char *gyro_name = MPU_GYRO_NAME;
 
-       int ret;
-       int i;
+       pr_info("*** MPU START *** mpuirq_init...\n");
 
-       pr_debug("%s: ++\n", __func__);
+       ret = gpio_request(gyro_irq_gpio, gyro_name);
 
-       for (i = 0; i < ARRAY_SIZE(dalmore_cam_gpio_data); i++) {
-               ret = gpio_request(dalmore_cam_gpio_data[i].gpio,
-                               dalmore_cam_gpio_data[i].label);
-               if (ret < 0) {
-                       pr_err("%s: gpio_request failed for gpio #%d\n",
-                               __func__, i);
-                       goto fail_free_gpio;
-               }
-               gpio_direction_output(dalmore_cam_gpio_data[i].gpio,
-                                       dalmore_cam_gpio_data[i].value);
-               gpio_export(dalmore_cam_gpio_data[i].gpio, false);
+       if (ret < 0) {
+               pr_err("%s: gpio_request failed %d\n", __func__, ret);
+               return;
        }
 
-       i2c_register_board_info(2, dalmore_i2c_board_info_e1625,
-               ARRAY_SIZE(dalmore_i2c_board_info_e1625));
+       ret = gpio_direction_input(gyro_irq_gpio);
+       if (ret < 0) {
+               pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
+               gpio_free(gyro_irq_gpio);
+               return;
+       }
+       pr_info("*** MPU END *** mpuirq_init...\n");
 
-fail_free_gpio:
+       inv_mpu9150_i2c2_board_info[0].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
+       i2c_register_board_info(gyro_bus_num, inv_mpu9150_i2c2_board_info,
+               ARRAY_SIZE(inv_mpu9150_i2c2_board_info));
+}
 
-       while (i--)
-               gpio_free(dalmore_cam_gpio_data[i].gpio);
-       return ret;
+static int dalmore_nct1008_init(void)
+{
+       int nct1008_port;
+       int ret = 0;
 
+       if ((board_info.board_id == BOARD_E1612) ||
+           (board_info.board_id == BOARD_E1641) ||
+           (board_info.board_id == BOARD_E1613) ||
+           (board_info.board_id == BOARD_P2454))
+       {
+               /* per email from Matt 9/10/2012 */
+               nct1008_port = TEGRA_GPIO_PX6;
+       } else if (board_info.board_id == BOARD_E1611) {
+               if (board_info.fab == 0x04)
+                       nct1008_port = TEGRA_GPIO_PO4;
+               else
+                       nct1008_port = TEGRA_GPIO_PX6;
+       } else {
+               nct1008_port = TEGRA_GPIO_PX6;
+               pr_err("Warning: nct alert_port assumed TEGRA_GPIO_PX6"
+                       " for unknown dalmore board id E%d\n",
+                       board_info.board_id);
+       }
+
+       tegra_add_all_vmin_trips(dalmore_nct1008_pdata.trips,
+                               &dalmore_nct1008_pdata.num_trips);
+
+       dalmore_i2c4_nct1008_board_info[0].irq = gpio_to_irq(nct1008_port);
+       pr_info("%s: dalmore nct1008 irq %d",
+                       __func__, dalmore_i2c4_nct1008_board_info[0].irq);
+
+       ret = gpio_request(nct1008_port, "temp_alert");
+       if (ret < 0)
+               return ret;
+
+       ret = gpio_direction_input(nct1008_port);
+       if (ret < 0) {
+               pr_info("%s: calling gpio_free(nct1008_port)", __func__);
+               gpio_free(nct1008_port);
+       }
+
+       /* dalmore has thermal sensor on GEN1-I2C i.e. instance 0 */
+       i2c_register_board_info(0, dalmore_i2c4_nct1008_board_info,
+               ARRAY_SIZE(dalmore_i2c4_nct1008_board_info));
+
+       return ret;
 }
 
+static struct i2c_board_info __initdata bq20z45_pdata[] = {
+       {
+               I2C_BOARD_INFO("sbs-battery", 0x0B),
+               .platform_data = &sbs_pdata,
+       },
+};
 
-/* MPU board file definition   */
-static struct mpu_platform_data mpu9150_gyro_data = {
-       .int_config     = 0x10,
-       .level_shifter  = 0,
-       .orientation    = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h    */
-       .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS,
-       .sec_slave_id   = COMPASS_ID_AK8975,
-       .secondary_i2c_addr     = MPU_COMPASS_ADDR,
-       .secondary_read_reg     = 0x06,
-       .secondary_orientation  = MPU_COMPASS_ORIENTATION,
-       .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
-                          0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
+#ifdef CONFIG_TEGRA_SKIN_THROTTLE
+static struct thermal_trip_info skin_trips[] = {
+       {
+               .cdev_type = "skin-balanced",
+               .trip_temp = 43000,
+               .trip_type = THERMAL_TRIP_PASSIVE,
+               .upper = THERMAL_NO_LIMIT,
+               .lower = THERMAL_NO_LIMIT,
+               .hysteresis = 0,
+       },
+       {
+               .cdev_type = "tegra-shutdown",
+               .trip_temp = 57000,
+               .trip_type = THERMAL_TRIP_CRITICAL,
+               .upper = THERMAL_NO_LIMIT,
+               .lower = THERMAL_NO_LIMIT,
+               .hysteresis = 0,
+       },
 };
 
-#define TEGRA_CAMERA_GPIO(_gpio, _label, _value)               \
-       {                                                       \
-               .gpio = _gpio,                                  \
-               .label = _label,                                \
-               .value = _value,                                \
-       }
+static struct therm_est_subdevice skin_devs[] = {
+       {
+               .dev_data = "Tdiode",
+               .coeffs = {
+                       2, 1, 1, 1,
+                       1, 1, 1, 1,
+                       1, 1, 1, 0,
+                       1, 1, 0, 0,
+                       0, 0, -1, -7
+               },
+       },
+       {
+               .dev_data = "Tboard",
+               .coeffs = {
+                       -11, -7, -5, -3,
+                       -3, -2, -1, 0,
+                       0, 0, 1, 1,
+                       1, 2, 2, 3,
+                       4, 6, 11, 18
+               },
+       },
+};
 
-static struct i2c_board_info __initdata inv_mpu9150_i2c2_board_info[] = {
-        {
-                I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
-                .platform_data = &mpu9150_gyro_data,
-        },
+static struct pid_thermal_gov_params skin_pid_params = {
+       .max_err_temp = 4000,
+       .max_err_gain = 1000,
+
+       .gain_p = 1000,
+       .gain_d = 0,
+
+       .up_compensation = 15,
+       .down_compensation = 15,
 };
 
-static void mpuirq_init(void)
+static struct thermal_zone_params skin_tzp = {
+       .governor_name = "pid_thermal_gov",
+       .governor_params = &skin_pid_params,
+};
+
+static struct therm_est_data skin_data = {
+       .num_trips = ARRAY_SIZE(skin_trips),
+       .trips = skin_trips,
+       .toffset = 9793,
+       .polling_period = 1100,
+       .passive_delay = 15000,
+       .tc1 = 10,
+       .tc2 = 1,
+       .ndevs = ARRAY_SIZE(skin_devs),
+       .devs = skin_devs,
+       .tzp = &skin_tzp,
+};
+
+static struct throttle_table skin_throttle_table[] = {
+       /* CPU_THROT_LOW cannot be used by other than CPU */
+       /*      CPU,  C2BUS,  C3BUS,   SCLK,    EMC   */
+       { { 1810500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1785000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1759500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1734000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1708500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1683000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1657500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1632000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1606500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1581000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1555500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1530000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1504500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1479000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1453500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1428000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1402500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1377000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1351500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1326000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1300500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1275000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1249500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1224000, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1198500, NO_CAP, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1173000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1147500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1122000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1096500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1071000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1045500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { { 1020000, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  994500, 636000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  969000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  943500, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  918000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  892500, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  867000, 600000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  841500, 564000, NO_CAP, NO_CAP, NO_CAP } },
+       { {  816000, 564000, NO_CAP, NO_CAP, 792000 } },
+       { {  790500, 564000, NO_CAP, 372000, 792000 } },
+       { {  765000, 564000, 468000, 372000, 792000 } },
+       { {  739500, 528000, 468000, 372000, 792000 } },
+       { {  714000, 528000, 468000, 336000, 792000 } },
+       { {  688500, 528000, 420000, 336000, 792000 } },
+       { {  663000, 492000, 420000, 336000, 792000 } },
+       { {  637500, 492000, 420000, 336000, 408000 } },
+       { {  612000, 492000, 420000, 300000, 408000 } },
+       { {  586500, 492000, 360000, 336000, 408000 } },
+       { {  561000, 420000, 420000, 300000, 408000 } },
+       { {  535500, 420000, 360000, 228000, 408000 } },
+       { {  510000, 420000, 288000, 228000, 408000 } },
+       { {  484500, 324000, 288000, 228000, 408000 } },
+       { {  459000, 324000, 288000, 228000, 408000 } },
+       { {  433500, 324000, 288000, 228000, 408000 } },
+       { {  408000, 324000, 288000, 228000, 408000 } },
+};
+
+static struct balanced_throttle skin_throttle = {
+       .throt_tab_size = ARRAY_SIZE(skin_throttle_table),
+       .throt_tab = skin_throttle_table,
+};
+
+static int __init dalmore_skin_init(void)
 {
-        int ret = 0;
-        unsigned gyro_irq_gpio = MPU_GYRO_IRQ_GPIO;
-        unsigned gyro_bus_num = MPU_GYRO_BUS_NUM;
-        char *gyro_name = MPU_GYRO_NAME;
-
-        pr_info("*** MPU START *** mpuirq_init...\n");
-
-        ret = gpio_request(gyro_irq_gpio, gyro_name);
-
-        if (ret < 0) {
-                pr_err("%s: gpio_request failed %d\n", __func__, ret);
-                return;
-        }
-
-        ret = gpio_direction_input(gyro_irq_gpio);
-        if (ret < 0) {
-                pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
-                gpio_free(gyro_irq_gpio);
-                return;
-        }
-        pr_info("*** MPU END *** mpuirq_init...\n");
-
-        inv_mpu9150_i2c2_board_info[0].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
-        i2c_register_board_info(gyro_bus_num, inv_mpu9150_i2c2_board_info,
-                ARRAY_SIZE(inv_mpu9150_i2c2_board_info));
+       if (machine_is_dalmore()) {
+               balanced_throttle_register(&skin_throttle, "skin-balanced");
+               tegra_skin_therm_est_device.dev.platform_data = &skin_data;
+               platform_device_register(&tegra_skin_therm_est_device);
+       }
+
+       return 0;
 }
+late_initcall(dalmore_skin_init);
+#endif
 
 int __init dalmore_sensors_init(void)
 {
+       int err;
+
        tegra_get_board_info(&board_info);
 
+       err = dalmore_nct1008_init();
+       if (err)
+               return err;
+
        dalmore_camera_init();
        mpuirq_init();
 
+       i2c_register_board_info(0, dalmore_i2c_board_info_cm3218,
+               ARRAY_SIZE(dalmore_i2c_board_info_cm3218));
+
+       i2c_register_board_info(0, bq20z45_pdata,
+               ARRAY_SIZE(bq20z45_pdata));
+
        return 0;
 }