summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJihoon Bang <jbang@nvidia.com>2011-09-27 11:23:55 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2011-09-30 02:43:06 -0700
commitc53f8fc9d5d05427684aafb4ad6552eb6cff7ff7 (patch)
tree5c922428d8d5f67a463bfdd2c28472bbf5cf8cc2
parent4681815651f5949840815a03698d55ec8186796c (diff)
arm: tegra: enterprise: add I2C mux driver instance
Add I2C mux driver instance to support two rear sensors. Add new GPIO pin to control reset for I2C mux. If board doesn't have I2C mux, it falls back to previous I2C tree. Bug 871860 Change-Id: I6621111e807f22a39718ef5d878de2cf869fd87a Reviewed-on: http://git-master/r/54763 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-enterprise-pinmux.c3
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c18
-rw-r--r--arch/arm/mach-tegra/board-enterprise-sensors.c88
-rw-r--r--arch/arm/mach-tegra/board-enterprise.h18
4 files changed, 107 insertions, 20 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-pinmux.c b/arch/arm/mach-tegra/board-enterprise-pinmux.c
index 6dd1a8ccf0ed..21fb3a8dc45f 100644
--- a/arch/arm/mach-tegra/board-enterprise-pinmux.c
+++ b/arch/arm/mach-tegra/board-enterprise-pinmux.c
@@ -205,6 +205,7 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux[] = {
DEFAULT_PINMUX(LCD_D7, RSVD1, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
+ DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D13, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D14, DISPLAYA, NORMAL, NORMAL, INPUT),
@@ -382,7 +383,6 @@ static __initdata struct tegra_pingroup_config enterprise_unused_pinmux[] = {
DEFAULT_PINMUX(LCD_HSYNC, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
DEFAULT_PINMUX(LCD_VSYNC, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
DEFAULT_PINMUX(LCD_D10, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
- DEFAULT_PINMUX(LCD_D11, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
DEFAULT_PINMUX(LCD_PWR0, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
DEFAULT_PINMUX(LCD_SCK, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
DEFAULT_PINMUX(LCD_SDOUT, DISPLAYA, PULL_DOWN, TRISTATE, OUTPUT),
@@ -456,7 +456,6 @@ static __initdata struct pin_info_low_power_mode enterprise_unused_gpio_pins[] =
PIN_GPIO_LPM("LCD_HSYNC", TEGRA_GPIO_PJ3, 0, 0),
PIN_GPIO_LPM("LCD_VSYNC", TEGRA_GPIO_PJ4, 0, 0),
PIN_GPIO_LPM("LCD_D10", TEGRA_GPIO_PF2, 0, 0),
- PIN_GPIO_LPM("LCD_D12", TEGRA_GPIO_PF3, 0, 0),
PIN_GPIO_LPM("LCD_PWR0", TEGRA_GPIO_PB2, 0, 0),
PIN_GPIO_LPM("LCD_SCK", TEGRA_GPIO_PZ4, 0, 0),
PIN_GPIO_LPM("LCD_SDOUT", TEGRA_GPIO_PN5, 0, 0),
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index 4bfc0cc1b745..9a837b2f6805 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -352,24 +352,38 @@ static struct regulator_consumer_supply gpio_switch_sdmmc3_vdd_sel_supply[] = {
static int gpio_switch_sdmmc3_vdd_sel_voltages[] = {2850};
/* LCD-D23 (GPIO M7) from T30*/
-/* 2-0036 is dev_name of ar0832 */
+/* 2-0036 is dev_name of ar0832 in Enterprise A01*/
+/* 2-0032 is alternative dev_name of ar0832 Enterprise A01*/
/* 2-0010 is dev_name of ov9726 */
+/* 2-0070 is dev_name of PCA9546 in Enterprise A02*/
+/* 6-0036 is dev_name of ar0832 in Enterprise A02 */
+/* 7-0036 is dev_name of ar0832 in Enterprise A02 */
static struct regulator_consumer_supply gpio_switch_cam_ldo_2v8_en_supply[] = {
REGULATOR_SUPPLY("vaa", "2-0036"),
REGULATOR_SUPPLY("vaa", "2-0032"),
REGULATOR_SUPPLY("avdd", "2-0010"),
REGULATOR_SUPPLY("vdd_2v8_cam", NULL),
+ REGULATOR_SUPPLY("vcc", "2-0070"),
+ REGULATOR_SUPPLY("vaa", "6-0036"),
+ REGULATOR_SUPPLY("vaa", "7-0036"),
};
static int gpio_switch_cam_ldo_2v8_en_voltages[] = {2800};
/* LCD-D9 (GPIO F1) from T30*/
-/* 2-0036 is dev_name of ar0832 */
+/* 2-0036 is dev_name of ar0832 in Enterprise A01*/
+/* 2-0032 is alternative dev_name of ar0832 Enterprise A01*/
/* 2-0010 is dev_name of ov9726 */
+/* 2-0070 is dev_name of PCA9546 in Enterprise A02*/
+/* 6-0036 is dev_name of ar0832 in Enterprise A02 */
+/* 7-0036 is dev_name of ar0832 in Enterprise A02 */
static struct regulator_consumer_supply gpio_switch_cam_ldo_1v8_en_supply[] = {
REGULATOR_SUPPLY("vdd", "2-0036"),
REGULATOR_SUPPLY("vdd", "2-0032"),
REGULATOR_SUPPLY("dovdd", "2-0010"),
REGULATOR_SUPPLY("vdd_1v8_cam", NULL),
+ REGULATOR_SUPPLY("vcc_i2c", "2-0070"),
+ REGULATOR_SUPPLY("vdd", "6-0036"),
+ REGULATOR_SUPPLY("vdd", "7-0036"),
};
static int gpio_switch_cam_ldo_1v8_en_voltages[] = {1800};
diff --git a/arch/arm/mach-tegra/board-enterprise-sensors.c b/arch/arm/mach-tegra/board-enterprise-sensors.c
index 19a4af27c619..845b18b1a399 100644
--- a/arch/arm/mach-tegra/board-enterprise-sensors.c
+++ b/arch/arm/mach-tegra/board-enterprise-sensors.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/i2c/pca954x.h>
#include <linux/err.h>
#include <linux/mpu.h>
#include <linux/nct1008.h>
@@ -45,6 +46,7 @@
#include "cpu-tegra.h"
#include "gpio-names.h"
#include "board-enterprise.h"
+#include "board.h"
static struct nct1008_platform_data enterprise_nct1008_pdata = {
.supported_hwrev = true,
@@ -276,6 +278,7 @@ static int enterprise_ar0832_ri_power_on(int is_stereo)
{
int ret = 0;
+ pr_info("%s: ++\n", __func__);
ret = enterprise_cam_pwr(CAM_REAR_RIGHT, true);
/* Release Reset */
@@ -390,26 +393,25 @@ static int enterprise_tps61050_pm(int pwr)
pr_info("%s: ++%d\n", __func__, pwr);
switch (pwr) {
case TPS61050_PWR_OFF:
- if (enterprise_flash_reg) {
+ if (enterprise_flash_reg)
regulator_disable(enterprise_flash_reg);
- regulator_put(enterprise_flash_reg);
- enterprise_flash_reg = NULL;
- }
break;
case TPS61050_PWR_STDBY:
case TPS61050_PWR_COMM:
case TPS61050_PWR_ON:
- enterprise_flash_reg = regulator_get(NULL, "vdd_1v8_cam");
- if (IS_ERR_OR_NULL(enterprise_flash_reg)) {
- pr_err("%s: failed to get flash pwr\n", __func__);
- return PTR_ERR(enterprise_flash_reg);
+ if (!enterprise_flash_reg) {
+ enterprise_flash_reg = regulator_get(NULL, "vdd_1v8_cam");
+ if (IS_ERR_OR_NULL(enterprise_flash_reg)) {
+ pr_err("%s: failed to get flash pwr\n", __func__);
+ return PTR_ERR(enterprise_flash_reg);
+ }
}
ret = regulator_enable(enterprise_flash_reg);
if (ret) {
pr_err("%s: failed to enable flash pwr\n", __func__);
goto fail_regulator_flash_reg;
}
- enterprise_msleep(10);
+ enterprise_msleep(1);
break;
default:
ret = -1;
@@ -443,6 +445,19 @@ static struct enterprise_cam_gpio enterprise_cam_gpio_data[] = {
[3] = TEGRA_CAMERA_GPIO(CAM3_RST_L_GPIO, "cam3_rst_lo", 0),
[4] = TEGRA_CAMERA_GPIO(CAM3_PWDN_GPIO, "cam3_pwdn", 1),
[5] = TEGRA_CAMERA_GPIO(CAM_FLASH_EN_GPIO, "flash_en", 1),
+ [6] = TEGRA_CAMERA_GPIO(CAM_I2C_MUX_RST_EXP, "cam_i2c_mux_rst", 1),
+};
+
+static struct pca954x_platform_mode enterprise_pca954x_modes[] = {
+ { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, },
+ { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, },
+ { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, },
+ { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, },
+};
+
+static struct pca954x_platform_data enterprise_pca954x_data = {
+ .modes = enterprise_pca954x_modes,
+ .num_modes = ARRAY_SIZE(enterprise_pca954x_modes),
};
static struct ar0832_platform_data enterprise_ar0832_ri_data = {
@@ -470,6 +485,21 @@ static struct tps61050_platform_data enterprise_tps61050_data = {
.gpio_sync = NULL,
};
+static const struct i2c_board_info enterprise_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("pca9546", 0x70),
+ .platform_data = &enterprise_pca954x_data,
+ },
+ {
+ I2C_BOARD_INFO("tps61050", 0x33),
+ .platform_data = &enterprise_tps61050_data,
+ },
+ {
+ I2C_BOARD_INFO("ov9726", OV9726_I2C_ADDR >> 1),
+ .platform_data = &enterprise_ov9726_data,
+ },
+};
+
/*
* Since ar0832 driver should support multiple devices, slave
* address should be changed after it is open. Default slave
@@ -478,12 +508,12 @@ static struct tps61050_platform_data enterprise_tps61050_data = {
*/
static struct i2c_board_info ar0832_i2c2_boardinfo[] = {
{
- /* 0x30: alternative slave address */
+ /* 0x36: alternative slave address */
I2C_BOARD_INFO("ar0832", 0x36),
.platform_data = &enterprise_ar0832_ri_data,
},
{
- /* 0x31: alternative slave address */
+ /* 0x32: alternative slave address */
I2C_BOARD_INFO("ar0832", 0x32),
.platform_data = &enterprise_ar0832_le_data,
},
@@ -497,13 +527,27 @@ static struct i2c_board_info ar0832_i2c2_boardinfo[] = {
},
};
+static struct i2c_board_info enterprise_i2c6_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("ar0832", 0x36),
+ .platform_data = &enterprise_ar0832_le_data,
+ },
+};
+
+static struct i2c_board_info enterprise_i2c7_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("ar0832", 0x36),
+ .platform_data = &enterprise_ar0832_ri_data,
+ },
+};
+
static int enterprise_cam_init(void)
{
int ret;
int i;
+ struct board_info bi;
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,
@@ -519,8 +563,23 @@ static int enterprise_cam_init(void)
tegra_gpio_enable(enterprise_cam_gpio_data[i].gpio);
}
- i2c_register_board_info(2, ar0832_i2c2_boardinfo,
- ARRAY_SIZE(ar0832_i2c2_boardinfo));
+ tegra_get_board_info(&bi);
+
+ if (bi.fab == BOARD_FAB_A01)
+ i2c_register_board_info(2, ar0832_i2c2_boardinfo,
+ ARRAY_SIZE(ar0832_i2c2_boardinfo));
+ else if (bi.fab == BOARD_FAB_A02) {
+ i2c_register_board_info(2, enterprise_i2c2_boardinfo,
+ ARRAY_SIZE(enterprise_i2c2_boardinfo));
+ /*
+ * Right camera is on PCA954x's I2C BUS1,
+ * Left camera is on BUS0
+ */
+ i2c_register_board_info(PCA954x_I2C_BUS0, enterprise_i2c6_boardinfo,
+ ARRAY_SIZE(enterprise_i2c6_boardinfo));
+ i2c_register_board_info(PCA954x_I2C_BUS1, enterprise_i2c7_boardinfo,
+ ARRAY_SIZE(enterprise_i2c7_boardinfo));
+ }
return 0;
@@ -534,6 +593,7 @@ fail_free_gpio:
int __init enterprise_sensors_init(void)
{
int ret;
+
enterprise_isl_init();
enterprise_nct1008_init();
enterprise_mpuirq_init();
diff --git a/arch/arm/mach-tegra/board-enterprise.h b/arch/arm/mach-tegra/board-enterprise.h
index d5f6bda883b7..1e9f9830879e 100644
--- a/arch/arm/mach-tegra/board-enterprise.h
+++ b/arch/arm/mach-tegra/board-enterprise.h
@@ -25,6 +25,14 @@
#include <mach/irqs.h>
#include <linux/mfd/tps80031.h>
+/* Processor Board ID */
+#define BOARD_E1205 0x0C05
+
+/* Board Fab version */
+#define BOARD_FAB_A00 0x0
+#define BOARD_FAB_A01 0x1
+#define BOARD_FAB_A02 0x2
+
int enterprise_charge_init(void);
int enterprise_sdhci_init(void);
int enterprise_pinmux_init(void);
@@ -43,6 +51,13 @@ int enterprise_edp_init(void);
#define TOUCH_GPIO_RST_ATMEL_T9 TEGRA_GPIO_PF5
#define TOUCH_BUS_ATMEL_T9 1
+/* PCA954x I2C bus expander bus addresses */
+#define PCA954x_I2C_BUS_BASE 6
+#define PCA954x_I2C_BUS0 (PCA954x_I2C_BUS_BASE + 0)
+#define PCA954x_I2C_BUS1 (PCA954x_I2C_BUS_BASE + 1)
+#define PCA954x_I2C_BUS2 (PCA954x_I2C_BUS_BASE + 2)
+#define PCA954x_I2C_BUS3 (PCA954x_I2C_BUS_BASE + 3)
+
/*****************External GPIO tables ******************/
/* External peripheral gpio base. */
#define ENT_TPS80031_GPIO_BASE TEGRA_NR_GPIOS
@@ -62,9 +77,7 @@ int enterprise_edp_init(void);
#define CAM_CSI_MUX_SEL_FRONT 0
#define CAM1_RST_L_GPIO TEGRA_GPIO_PM5 /*REAR RIGHT*/
-#define CAM1_PWDN_GPIO TEGRA_GPIO_PF3 /*REAR RIGHT*/
#define CAM2_RST_L_GPIO TEGRA_GPIO_PF4 /*REAR LEFT*/
-#define CAM2_PWDN_GPIO TEGRA_GPIO_PF2 /*REAR LEFT*/
#define CAM3_RST_L_GPIO TEGRA_GPIO_PM2 /*FRONT*/
#define CAM3_RST_L_TRUE 0
#define CAM3_RST_L_FALSE 1
@@ -74,6 +87,7 @@ int enterprise_edp_init(void);
#define CAM_FLASH_EN_GPIO TEGRA_GPIO_PBB3
#define CAM_FLASH_MAX_TORCH_AMP 7
#define CAM_FLASH_MAX_FLASH_AMP 7
+#define CAM_I2C_MUX_RST_EXP TEGRA_GPIO_PF3 /*I2C Mux Reset*/
/* Baseband GPIO addresses */