ARM: tegra: pluto/dalmore: power sequence updates
Charlie Huang [Tue, 9 Oct 2012 01:12:30 +0000 (18:12 -0700)]
use pinmux enable/disable ALT funtion to enable/disable MCLK/PBB0 sensor
mclk output.

modify imx091/imx132/ov9772 power on/off sequences according to their specs.

enable the AF regulator whenever a sensor is on (rear/front) as a workaround,
as this is required by the focuser ad5816 in the rear sensor module.

put gpio initialization into lateinit stage.

update the both dalmore/pluto board power files to adapt with the
sensor/focuser/flash kernel drivers.

bug 1060778
bug 1059684
bug 1054873

Change-Id: If67c1ad1d4ff15e04446f6d93dc75d07cda97052
Signed-off-by: Charlie Huang <chahuang@nvidia.com>
Reviewed-on: http://git-master/r/147648
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

arch/arm/mach-tegra/board-dalmore-pinmux-t11x.h
arch/arm/mach-tegra/board-dalmore-power.c
arch/arm/mach-tegra/board-dalmore-sensors.c
arch/arm/mach-tegra/board-pluto-pinmux-t11x.h
arch/arm/mach-tegra/board-pluto-power.c
arch/arm/mach-tegra/board-pluto-sensors.c
arch/arm/mach-tegra/pinmux-t11-tables.c

index 73075aa..810cf58 100644 (file)
@@ -63,7 +63,7 @@ static __initdata struct tegra_pingroup_config dalmore_pinmux_common[] = {
        I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
 
        /* VI pinmux */
-       VI_PINMUX(CAM_MCLK, VI_ALT2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
+       VI_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
 
        /* VI_ALT1 pinmux */
        VI_PINMUX(GPIO_PBB0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
index b0b1e5a..8e30842 100644 (file)
@@ -284,11 +284,13 @@ static struct regulator_consumer_supply max77663_ldo6_supply[] = {
 static struct regulator_consumer_supply max77663_ldo7_supply[] = {
        REGULATOR_SUPPLY("avdd_cam1", NULL),
        REGULATOR_SUPPLY("avdd_2v8_cam_af", NULL),
+       REGULATOR_SUPPLY("vana", "2-0036"),
 };
 
 /* FIXME!! Put the device address of camera */
 static struct regulator_consumer_supply max77663_ldo8_supply[] = {
        REGULATOR_SUPPLY("avdd_cam2", NULL),
+       REGULATOR_SUPPLY("avdd", "2-0010"),
 };
 
 static struct max77663_regulator_fps_cfg max77663_fps_cfgs[] = {
@@ -571,6 +573,7 @@ static struct regulator_consumer_supply palmas_ldo4_supply[] = {
 
 static struct regulator_consumer_supply palmas_ldo7_supply[] = {
        REGULATOR_SUPPLY("vdd_af_cam1", NULL),
+       REGULATOR_SUPPLY("vdd", "2-000e"),
 };
 
 #define palmas_ldo8_supply max77663_ldo4_supply
@@ -762,6 +765,9 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
        REGULATOR_SUPPLY("dvdd_cam", NULL),
        REGULATOR_SUPPLY("vdd_cam_1v8", NULL),
        REGULATOR_SUPPLY("vi2c", "2-0030"),
+       REGULATOR_SUPPLY("vif", "2-0036"),
+       REGULATOR_SUPPLY("dovdd", "2-0010"),
+       REGULATOR_SUPPLY("vdd_i2c", "2-000e"),
 };
 
 /* EN_CAM_1v8 on e1611 From PMU GP6 */
@@ -769,6 +775,9 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_e1611_supply[] = {
        REGULATOR_SUPPLY("dvdd_cam", NULL),
        REGULATOR_SUPPLY("vdd_cam_1v8", NULL),
        REGULATOR_SUPPLY("vi2c", "2-0030"),
+       REGULATOR_SUPPLY("vif", "2-0036"),
+       REGULATOR_SUPPLY("dovdd", "2-0010"),
+       REGULATOR_SUPPLY("vdd_i2c", "2-000e"),
 };
 
 static struct regulator_consumer_supply fixed_reg_vdd_hdmi_5v0_supply[] = {
index f7fa7ae..6257c4e 100644 (file)
 #include <linux/nct1008.h>
 #include <mach/edp.h>
 #include <mach/gpio-tegra.h>
+#include <mach/pinmux-t11.h>
+#include <mach/pinmux.h>
 #include <media/imx091.h>
 #include <media/ov9772.h>
 #include <media/as364x.h>
+#include <media/ad5816.h>
 #include <generated/mach-types.h>
 
 #include "gpio-names.h"
 
 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 regulator *dalmore_cam_reg[ARRAY_SIZE(dalmore_cam_reg_name)];
-
 static struct balanced_throttle tj_throttle = {
        .throt_tab_size = 10,
        .throt_tab = {
@@ -106,59 +98,113 @@ static struct i2c_board_info dalmore_i2c4_nct1008_board_info[] = {
        }
 };
 
+#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 \
+       }
+
+static struct tegra_pingroup_config mclk_disable =
+       VI_PINMUX(CAM_MCLK, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
+
+static struct tegra_pingroup_config mclk_enable =
+       VI_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
+
+static struct tegra_pingroup_config pbb0_disable =
+       VI_PINMUX(GPIO_PBB0, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
+
+static struct tegra_pingroup_config pbb0_enable =
+       VI_PINMUX(GPIO_PBB0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
+
+/*
+ * 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;
 
-static int dalmore_imx091_power_on(struct device *dev)
+static int dalmore_get_vcmvdd(void)
 {
-       int i;
-       for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
-               if (!dalmore_cam_reg[i]) {
-                       dalmore_cam_reg[i] = regulator_get(dev,
-                                       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;
-                       }
+       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;
                }
-               regulator_enable(dalmore_cam_reg[i]);
        }
+       return 0;
+}
 
-       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 int dalmore_imx091_power_on(struct imx091_power_rail *pw)
+{
+       int err;
 
-       return 0;
+       if (unlikely(!pw || !pw->avdd || !pw->iovdd))
+               return -EFAULT;
 
-reg_alloc_fail:
+       if (dalmore_get_vcmvdd())
+               goto imx091_poweron_fail;
 
-       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;
-               }
-       }
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+       usleep_range(10, 20);
 
+       err = regulator_enable(pw->avdd);
+       if (err)
+               goto imx091_avdd_fail;
+
+       err = regulator_enable(pw->iovdd);
+       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(pw->iovdd);
+
+imx091_iovdd_fail:
+       regulator_disable(pw->avdd);
+
+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_imx091_power_off(struct device *dev)
+static int dalmore_imx091_power_off(struct imx091_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(!pw || !dalmore_vcmvdd || !pw->avdd || !pw->iovdd))
+               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(pw->iovdd);
+       regulator_disable(pw->avdd);
+
+       return 1;
 }
 
 struct imx091_platform_data dalmore_imx091_data = {
@@ -166,62 +212,77 @@ struct imx091_platform_data dalmore_imx091_data = {
        .power_off = dalmore_imx091_power_off,
 };
 
-static int dalmore_ov9772_power_on(struct device *dev)
+static int dalmore_ov9772_power_on(struct ov9772_power_rail *pw)
 {
-       int i;
-       for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
-               if (!dalmore_cam_reg[i]) {
-                       dalmore_cam_reg[i] = regulator_get(dev,
-                                       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]);
-       }
+       int err;
 
-       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);
+       if (unlikely(!pw || !pw->avdd || !pw->dovdd))
+               return -EFAULT;
 
-       return 0;
+       if (dalmore_get_vcmvdd())
+               goto ov9772_get_vcmvdd_fail;
 
-reg_alloc_fail:
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+       gpio_set_value(CAM_RSTN, 0);
 
-       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;
-               }
-       }
+       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 device *dev)
+static int dalmore_ov9772_power_off(struct ov9772_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(!pw || !dalmore_vcmvdd || !pw->avdd || !pw->dovdd))
+               return -EFAULT;
 
-       return 0;
+       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, TEGRA_GPIO_PBB5, true, 0, },
-       { OV9772_GPIO_TYPE_PWRDN, TEGRA_GPIO_PBB3, true, 0, },
+       { 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 = {
@@ -235,15 +296,10 @@ static struct ov9772_platform_data dalmore_ov9772_pdata = {
 
 static int dalmore_as3648_power_on(struct as364x_power_rail *pw)
 {
-       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 vdd_af_cam1: %ld\n",
-                              __func__, PTR_ERR(dalmore_vcmvdd));
-                       dalmore_vcmvdd = NULL;
-                       return -ENODEV;
-               }
-       }
+       int err = dalmore_get_vcmvdd();
+
+       if (err)
+               return err;
 
        return regulator_enable(dalmore_vcmvdd);
 }
@@ -275,6 +331,13 @@ static struct as364x_platform_data dalmore_as3648_pdata = {
        .power_off_callback = dalmore_as3648_power_off,
 };
 
+static struct ad5816_platform_data pluto_ad5816_pdata = {
+       .cfg            = 0,
+       .num            = 0,
+       .sync           = 0,
+       .dev_name       = "focuser",
+};
+
 static struct i2c_board_info dalmore_i2c_board_info_e1625[] = {
        {
                I2C_BOARD_INFO("imx091", 0x36),
@@ -288,63 +351,22 @@ static struct i2c_board_info dalmore_i2c_board_info_e1625[] = {
                I2C_BOARD_INFO("as3648", 0x30),
                .platform_data = &dalmore_as3648_pdata,
        },
-};
-
-struct dalmore_cam_gpio {
-       int gpio;
-       const char *label;
-       int value;
-};
-
-#define TEGRA_CAMERA_GPIO(_gpio, _label, _value)               \
-       {                                                       \
-               .gpio = _gpio,                                  \
-               .label = _label,                                \
-               .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),
+       {
+               I2C_BOARD_INFO("ad5816", 0x0E),
+               .platform_data = &pluto_ad5816_pdata,
+       },
 };
 
 static int dalmore_camera_init(void)
 {
-
-       int ret;
-       int i;
-
-       pr_debug("%s: ++\n", __func__);
-
-       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);
-       }
+       tegra_pinmux_config_table(&mclk_disable, 1);
+       tegra_pinmux_config_table(&pbb0_disable, 1);
 
        i2c_register_board_info(2, dalmore_i2c_board_info_e1625,
                ARRAY_SIZE(dalmore_i2c_board_info_e1625));
        return 0;
-fail_free_gpio:
-
-       while (i--)
-               gpio_free(dalmore_cam_gpio_data[i].gpio);
-       return ret;
-
 }
 
-
 /* MPU board file definition   */
 static struct mpu_platform_data mpu9150_gyro_data = {
        .int_config     = 0x10,
index 443efe2..a83fe33 100644 (file)
@@ -60,7 +60,7 @@ static __initdata struct tegra_pingroup_config pluto_pinmux_common[] = {
        I2C_PINMUX(CAM_I2C_SDA, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
 
        /* VI pinmux */
-       VI_PINMUX(CAM_MCLK, VI_ALT2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
+       VI_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
 
        /* VI_ALT1 pinmux */
        VI_PINMUX(GPIO_PBB0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
index ae4de53..d36bb68 100644 (file)
@@ -155,6 +155,7 @@ static struct regulator_consumer_supply palmas_ldo4_supply[] = {
 
 static struct regulator_consumer_supply palmas_ldo5_supply[] = {
        REGULATOR_SUPPLY("avdd_cam1", NULL),
+       REGULATOR_SUPPLY("vana", "2-0010"),
 };
 
 static struct regulator_consumer_supply palmas_ldo6_supply[] = {
@@ -173,6 +174,7 @@ static struct regulator_consumer_supply palmas_ldo6_supply[] = {
 
 static struct regulator_consumer_supply palmas_ldo7_supply[] = {
        REGULATOR_SUPPLY("vdd_af_cam1", NULL),
+       REGULATOR_SUPPLY("vdd", "2-000e"),
 };
 static struct regulator_consumer_supply palmas_ldo8_supply[] = {
        REGULATOR_SUPPLY("vdd_rtc", NULL),
@@ -183,6 +185,7 @@ static struct regulator_consumer_supply palmas_ldo9_supply[] = {
 };
 static struct regulator_consumer_supply palmas_ldoln_supply[] = {
        REGULATOR_SUPPLY("avdd_cam2", NULL),
+       REGULATOR_SUPPLY("vana", "2-0036"),
 };
 
 static struct regulator_consumer_supply palmas_ldousb_supply[] = {
@@ -374,10 +377,15 @@ static struct regulator_consumer_supply fixed_reg_en_battery_supply[] = {
 static struct regulator_consumer_supply fixed_reg_en_vdd_1v8_cam_supply[] = {
        REGULATOR_SUPPLY("vddio_cam_mb", NULL),
        REGULATOR_SUPPLY("vdd_1v8_cam12", NULL),
+       REGULATOR_SUPPLY("vif", "2-0010"),
+       REGULATOR_SUPPLY("vif", "2-0036"),
+       REGULATOR_SUPPLY("vdd_i2c", "2-000e"),
 };
 
 static struct regulator_consumer_supply fixed_reg_en_vdd_1v2_cam_supply[] = {
        REGULATOR_SUPPLY("vdd_1v2_cam", NULL),
+       REGULATOR_SUPPLY("vdig", "2-0010"),
+       REGULATOR_SUPPLY("vdig", "2-0036"),
 };
 
 static struct regulator_consumer_supply fixed_reg_en_avdd_usb3_1v05_supply[] = {
index 679ea42..bb4359c 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/nct1008.h>
 #include <mach/edp.h>
 #include <mach/gpio-tegra.h>
+#include <mach/pinmux-t11.h>
+#include <mach/pinmux.h>
 #include <media/max77665-flash.h>
 #include <media/imx091.h>
 #include <media/imx132.h>
@@ -184,23 +186,6 @@ static struct i2c_board_info pluto_i2c1_isl_board_info[] = {
        }
 };
 
-struct pluto_cam_gpio {
-       int gpio;
-       const char *label;
-       int value;
-};
-
-static char *pluto_cam_reg_name[] = {
-       "avdd_cam1",            /* Analog VDD 2.7V */
-       "avdd_cam2",            /* Analog VDD 2.7V */
-       "vdd_1v2_cam",          /* Digital VDD 1.2V */
-       "vdd_1v8_cam12",        /* Digital VDDIO 1.8V */
-       "vddio_cam_mb",         /* CAM_I2C PULL-UP VDD 1.8V */
-       "vdd_af_cam1",          /* AF VDD */
-};
-
-static struct regulator *pluto_cam_reg[ARRAY_SIZE(pluto_cam_reg_name)];
-
 static struct balanced_throttle tj_throttle = {
        .throt_tab_size = 10,
        .throt_tab = {
@@ -245,107 +230,141 @@ static struct i2c_board_info pluto_i2c4_nct1008_board_info[] = {
        }
 };
 
-static int pluto_imx091_power_on(struct device *dev)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
-               if (!pluto_cam_reg[i]) {
-                       pluto_cam_reg[i] = regulator_get(dev,
-                                       pluto_cam_reg_name[i]);
-                       if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
-                               pr_err("%s: didn't get regulator #%d: %ld\n",
-                               __func__, i, PTR_ERR(pluto_cam_reg[i]));
-                               goto reg_alloc_fail;
-                       }
-               }
-               regulator_enable(pluto_cam_reg[i]);
+#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 \
        }
 
-       gpio_direction_output(CAM_RSTN, 0);
-       gpio_direction_output(CAM_GPIO1, 1);
-       gpio_direction_output(CAM_RSTN, 1);
+static struct tegra_pingroup_config mclk_disable =
+       VI_PINMUX(CAM_MCLK, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       mdelay(1);
+static struct tegra_pingroup_config mclk_enable =
+       VI_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       return 0;
+static struct tegra_pingroup_config pbb0_disable =
+       VI_PINMUX(GPIO_PBB0, VI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-reg_alloc_fail:
+static struct tegra_pingroup_config pbb0_enable =
+       VI_PINMUX(GPIO_PBB0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT);
 
-       for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
-               if (pluto_cam_reg[i]) {
-                       regulator_put(pluto_cam_reg[i]);
-                       pluto_cam_reg[i] = NULL;
+/*
+ * more regulators need to be allocated to activate the sensor devices.
+ * pluto_vcmvdd: this is a workaround due to the focuser device(AD5816) will
+ *               hook up the i2c bus if it is not powered up.
+ * pluto_i2cvdd: by default, the power supply on the i2c bus is OFF. So it
+ *               should be turned on every time any sensor device is activated.
+*/
+static struct regulator *pluto_vcmvdd;
+static struct regulator *pluto_i2cvdd;
+
+static int pluto_get_extra_regulators(void)
+{
+       if (!pluto_vcmvdd) {
+               pluto_vcmvdd = regulator_get(NULL, "vdd_af_cam1");
+               if (WARN_ON(IS_ERR(pluto_vcmvdd))) {
+                       pr_err("%s: can't get regulator vdd_af_cam1: %ld\n",
+                               __func__, PTR_ERR(pluto_vcmvdd));
+                       pluto_vcmvdd = NULL;
+                       return -ENODEV;
                }
        }
-       pr_info("%s fail\n", __func__);
-
-       return -ENODEV;
-}
-
-static int pluto_imx091_power_off(struct device *dev)
-{
-       int i;
 
-       for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
-               if (pluto_cam_reg[i]) {
-                       regulator_disable(pluto_cam_reg[i]);
-                       regulator_put(pluto_cam_reg[i]);
-                       pluto_cam_reg[i] = NULL;
+       if (!pluto_i2cvdd) {
+               pluto_i2cvdd = regulator_get(NULL, "vddio_cam_mb");
+               if (unlikely(WARN_ON(IS_ERR(pluto_i2cvdd)))) {
+                       pr_err("%s: can't get regulator vddio_cam_mb: %ld\n",
+                               __func__, PTR_ERR(pluto_i2cvdd));
+                       pluto_i2cvdd = NULL;
+                       return -ENODEV;
                }
        }
 
        return 0;
 }
 
-static int pluto_imx132_power_on(struct device *dev)
+static int pluto_imx091_power_on(struct imx091_power_rail *pw)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
-               if (!pluto_cam_reg[i]) {
-                       pluto_cam_reg[i] = regulator_get(dev,
-                                       pluto_cam_reg_name[i]);
-                       if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
-                               pr_err("%s: didn't get regulator #%d: %ld\n",
-                               __func__, i, PTR_ERR(pluto_cam_reg[i]));
-                               goto reg_alloc_fail;
-                       }
-               }
-               regulator_enable(pluto_cam_reg[i]);
-       }
+       int err;
+
+       if (unlikely(WARN_ON(!pw || !pw->dvdd || !pw->iovdd || !pw->avdd)))
+               return -EFAULT;
 
-       gpio_direction_output(CAM_RSTN, 0);
-       gpio_direction_output(CAM_GPIO2, 1);
-       gpio_direction_output(CAM_RSTN, 1);
+       if (pluto_get_extra_regulators())
+               goto imx091_poweron_fail;
 
-       mdelay(1);
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+       usleep_range(10, 20);
+
+       err = regulator_enable(pw->avdd);
+       if (unlikely(err))
+               goto imx091_avdd_fail;
+
+       err = regulator_enable(pw->dvdd);
+       if (unlikely(err))
+               goto imx091_dvdd_fail;
+
+       err = regulator_enable(pw->iovdd);
+       if (unlikely(err))
+               goto imx091_iovdd_fail;
+
+       usleep_range(1, 2);
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 1);
+
+       tegra_pinmux_config_table(&mclk_enable, 1);
+       err = regulator_enable(pluto_i2cvdd);
+       if (unlikely(err))
+               goto imx091_i2c_fail;
+
+       err = regulator_enable(pluto_vcmvdd);
+       if (unlikely(err))
+               goto imx091_vcm_fail;
+       usleep_range(300, 310);
 
        return 0;
 
-reg_alloc_fail:
-       for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
-               if (pluto_cam_reg[i]) {
-                       regulator_put(pluto_cam_reg[i]);
-                       pluto_cam_reg[i] = NULL;
-               }
-       }
+imx091_vcm_fail:
+       regulator_disable(pluto_i2cvdd);
+
+imx091_i2c_fail:
+       tegra_pinmux_config_table(&mclk_disable, 1);
+       gpio_set_value(CAM1_POWER_DWN_GPIO, 0);
+       regulator_disable(pw->iovdd);
+
+imx091_iovdd_fail:
+       regulator_disable(pw->dvdd);
 
+imx091_dvdd_fail:
+       regulator_disable(pw->avdd);
+
+imx091_avdd_fail:
+imx091_poweron_fail:
+       pr_err("%s FAILED\n", __func__);
        return -ENODEV;
 }
 
-
-static int pluto_imx132_power_off(struct device *dev)
+static int pluto_imx091_power_off(struct imx091_power_rail *pw)
 {
-       int i;
+       if (unlikely(WARN_ON(!pw || !pluto_i2cvdd || !pluto_vcmvdd ||
+                       !pw->dvdd || !pw->iovdd || !pw->avdd)))
+               return -EFAULT;
 
-       for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
-               if (pluto_cam_reg[i]) {
-                       regulator_disable(pluto_cam_reg[i]);
-                       regulator_put(pluto_cam_reg[i]);
-                       pluto_cam_reg[i] = NULL;
-               }
-       }
+       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(pw->iovdd);
+       regulator_disable(pw->dvdd);
+       regulator_disable(pw->avdd);
+       regulator_disable(pluto_i2cvdd);
+       regulator_disable(pluto_vcmvdd);
 
        return 0;
 }
@@ -355,6 +374,88 @@ struct imx091_platform_data pluto_imx091_data = {
        .power_off = pluto_imx091_power_off,
 };
 
+static int pluto_imx132_power_on(struct imx132_power_rail *pw)
+{
+       int err;
+
+       if (unlikely(WARN_ON(!pw || !pw->avdd || !pw->iovdd || !pw->dvdd)))
+               return -EFAULT;
+
+       if (pluto_get_extra_regulators())
+               goto pluto_imx132_poweron_fail;
+
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+
+       tegra_pinmux_config_table(&pbb0_enable, 1);
+
+       err = regulator_enable(pluto_i2cvdd);
+       if (unlikely(err))
+               goto imx132_i2c_fail;
+
+       err = regulator_enable(pluto_vcmvdd);
+       if (unlikely(err))
+               goto imx132_vcm_fail;
+
+       err = regulator_enable(pw->avdd);
+       if (unlikely(err))
+               goto imx132_avdd_fail;
+
+       err = regulator_enable(pw->dvdd);
+       if (unlikely(err))
+               goto imx132_dvdd_fail;
+
+       err = regulator_enable(pw->iovdd);
+       if (unlikely(err))
+               goto imx132_iovdd_fail;
+
+       usleep_range(1, 2);
+
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 1);
+
+       return 0;
+
+imx132_iovdd_fail:
+       regulator_disable(pw->dvdd);
+
+imx132_dvdd_fail:
+       regulator_disable(pw->avdd);
+
+imx132_avdd_fail:
+       regulator_disable(pluto_vcmvdd);
+
+imx132_vcm_fail:
+       regulator_disable(pluto_i2cvdd);
+
+imx132_i2c_fail:
+       tegra_pinmux_config_table(&pbb0_disable, 1);
+
+pluto_imx132_poweron_fail:
+       pr_err("%s failed.\n", __func__);
+       return -ENODEV;
+}
+
+static int pluto_imx132_power_off(struct imx132_power_rail *pw)
+{
+       if (unlikely(WARN_ON(!pw || !pw->avdd || !pw->iovdd || !pw->dvdd ||
+                       !pluto_i2cvdd || !pluto_vcmvdd)))
+               return -EFAULT;
+
+       gpio_set_value(CAM2_POWER_DWN_GPIO, 0);
+
+       usleep_range(1, 2);
+
+       regulator_disable(pw->iovdd);
+       regulator_disable(pw->dvdd);
+       regulator_disable(pw->avdd);
+
+       tegra_pinmux_config_table(&pbb0_disable, 1);
+
+       regulator_disable(pluto_vcmvdd);
+       regulator_disable(pluto_i2cvdd);
+
+       return 0;
+}
+
 struct imx132_platform_data pluto_imx132_data = {
        .power_on = pluto_imx132_power_on,
        .power_off = pluto_imx132_power_off,
@@ -382,50 +483,17 @@ static struct i2c_board_info pluto_i2c_board_info_e1625[] = {
        },
 };
 
-#define TEGRA_CAMERA_GPIO(_gpio, _label, _value)               \
-       {                                                       \
-               .gpio = _gpio,                                  \
-               .label = _label,                                \
-               .value = _value,                                \
-       }
-static struct pluto_cam_gpio pluto_cam_gpio_data[] = {
-       [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 1),
-       [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 1),
-       [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 int pluto_camera_init(void)
 {
-       int ret;
-       int i;
-
        pr_debug("%s: ++\n", __func__);
 
-       for (i = 0; i < ARRAY_SIZE(pluto_cam_gpio_data); i++) {
-               ret = gpio_request(pluto_cam_gpio_data[i].gpio,
-                               pluto_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(pluto_cam_gpio_data[i].gpio,
-                                       pluto_cam_gpio_data[i].value);
-               gpio_export(pluto_cam_gpio_data[i].gpio, false);
-       }
+       tegra_pinmux_config_table(&mclk_disable, 1);
+       tegra_pinmux_config_table(&pbb0_disable, 1);
 
        i2c_register_board_info(2, pluto_i2c_board_info_e1625,
                ARRAY_SIZE(pluto_i2c_board_info_e1625));
 
        return 0;
-
-fail_free_gpio:
-       while (i--)
-               gpio_free(pluto_cam_gpio_data[i].gpio);
-       return ret;
 }
 
 /* MPU board file definition */
index b60ee5a..a9f8f38 100644 (file)
@@ -250,7 +250,7 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
        PINGROUP(SDMMC4_DAT5,     PAA5,         SDMMC4,     SDMMC4,     SPI3,       GMI,        RSVD3,       RSVD,      INPUT,  0x3274),\
        PINGROUP(SDMMC4_DAT6,     PAA6,         SDMMC4,     SDMMC4,     SPI3,       GMI,        RSVD3,       RSVD,      INPUT,  0x3278),\
        PINGROUP(SDMMC4_DAT7,     PAA7,         SDMMC4,     SDMMC4,     RSVD1,      GMI,        RSVD3,       RSVD,      INPUT,  0x327c),\
-       PINGROUP(CAM_MCLK,        PCC0,         CAM,        VI,         VI_ALT1,    VI_ALT2,    RSVD3,       RSVD,      INPUT,  0x3284),\
+       PINGROUP(CAM_MCLK,        PCC0,         CAM,        VI,         VI_ALT1,    VI_ALT3,    RSVD3,       RSVD,      INPUT,  0x3284),\
        PINGROUP(GPIO_PCC1,       PCC1,         CAM,        I2S4,       RSVD1,      RSVD2,      RSVD3,       RSVD,      INPUT,  0x3288),\
        PINGROUP(GPIO_PBB0,       PBB0,         CAM,        I2S4,       VI,         VI_ALT1,    VI_ALT3,     RSVD,      INPUT,  0x328c),\
        PINGROUP(CAM_I2C_SCL,     PBB1,         CAM,        VGP1,       I2C3,       RSVD2,      RSVD3,       RSVD,      INPUT,  0x3290),\