summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/board-dalmore-sensors.c
diff options
context:
space:
mode:
authorCharlie Huang <chahuang@nvidia.com>2012-10-08 18:12:30 -0700
committerSimone Willett <swillett@nvidia.com>2012-10-29 15:12:36 -0700
commit359d88c8606bf2aba16f7ce5f73fe259296d41c5 (patch)
tree90cf99ff730e3d4b5a463b6399d75c7d02a1b087 /arch/arm/mach-tegra/board-dalmore-sensors.c
parent123901e38b650c6c1f40ad4046b8c6eac63c1c31 (diff)
ARM: tegra: pluto/dalmore: power sequence updates
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>
Diffstat (limited to 'arch/arm/mach-tegra/board-dalmore-sensors.c')
-rw-r--r--arch/arm/mach-tegra/board-dalmore-sensors.c316
1 files changed, 169 insertions, 147 deletions
diff --git a/arch/arm/mach-tegra/board-dalmore-sensors.c b/arch/arm/mach-tegra/board-dalmore-sensors.c
index f7fa7aeb02f2..6257c4e7c955 100644
--- a/arch/arm/mach-tegra/board-dalmore-sensors.c
+++ b/arch/arm/mach-tegra/board-dalmore-sensors.c
@@ -37,9 +37,12 @@
#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"
@@ -51,17 +54,6 @@
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,