summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/nvidia/seaboard/tegra250.dtsi2
-rw-r--r--common/fdt_decode.c22
-rw-r--r--drivers/i2c/tegra_i2c.c22
-rw-r--r--include/fdt_decode.h1
4 files changed, 43 insertions, 4 deletions
diff --git a/board/nvidia/seaboard/tegra250.dtsi b/board/nvidia/seaboard/tegra250.dtsi
index 030a9720280..62c6c7774d9 100644
--- a/board/nvidia/seaboard/tegra250.dtsi
+++ b/board/nvidia/seaboard/tegra250.dtsi
@@ -249,6 +249,7 @@
reg = <0x7000d000 0x007c>;
pinmux = <1>;
speed = <100000>;
+ use-dvc-ctlr;
periph-id = <47>; // PERIPH_ID_DVC_I2C
};
@@ -258,4 +259,3 @@
status = "disabled";
};
};
-
diff --git a/common/fdt_decode.c b/common/fdt_decode.c
index 9c56bcf1d39..c9bb28f6d61 100644
--- a/common/fdt_decode.c
+++ b/common/fdt_decode.c
@@ -114,6 +114,27 @@ static s32 get_int(const void *blob, int node, const char *prop_name,
}
/**
+ * Look up a boolean property in a node and return it.
+ *
+ * A boolean properly is true if present in the device tree and false if not
+ * present.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @return 1 if the properly is present; 0 if it isn't present
+ */
+static int get_bool(const void *blob, int node, const char *prop_name)
+{
+ const s32 *cell;
+ int len;
+
+ debug("%s: %s\n", __func__, prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ return (cell) ? 1 : 0;
+}
+
+/**
* Look up a property in a node and check that it has a minimum length.
*
* @param blob FDT blob
@@ -641,6 +662,7 @@ int fdt_decode_i2c(const void *blob, int node, struct fdt_i2c *config)
config->pinmux = get_int(blob, node, "pinmux", 0);
config->speed = get_int(blob, node, "speed", 0);
config->periph_id = get_int(blob, node, "periph-id", -1);
+ config->use_dvc_ctlr = get_bool(blob, node, "use-dvc-ctlr");
if (config->periph_id == -1)
return -FDT_ERR_MISSING;
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 3a94116831b..0f795091191 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -44,6 +44,15 @@ struct i2c_bus {
enum periph_id periph_id;
int speed;
int pinmux_config;
+
+ /*
+ * If non-zero, this I2C part has registers as described in
+ * 'struct dvc_ctlr' instead of 'struct i2c_ctlr'. On Tegra2, the
+ * "DVC" i2c controller has this. On Tegra3, none of the i2c
+ * controllers do.
+ */
+ int use_dvc_ctlr;
+
struct i2c_control *control;
struct i2c_ctlr *regs;
};
@@ -140,7 +149,7 @@ static void set_packet_mode(struct i2c_bus *i2c_bus)
config = bf_pack(I2C_CNFG_NEW_MASTER_FSM, 1) |
bf_pack(I2C_CNFG_PACKET_MODE, 1);
- if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C) {
+ if (i2c_bus->use_dvc_ctlr) {
struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
writel(config, &dvc->cnfg);
@@ -173,7 +182,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
i2c_reset_controller(i2c_bus);
/* Configure I2C controller. */
- if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C) { /* only for DVC I2C */
+ if (i2c_bus->use_dvc_ctlr) { /* only for DVC I2C */
struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
bf_writel(DVC_CTRL_REG3_I2C_HW_SW_PROG, 1, &dvc->ctrl3);
@@ -422,6 +431,12 @@ static int i2c_get_config(int *index, struct i2c_bus *i2c_bus)
i2c_bus->regs = (struct i2c_ctlr *)i2c_bus_base[i];
i2c_bus->speed = I2CSPEED_KHZ * 1000;
+#ifdef CONFIG_TEGRA2
+ i2c_bus->use_dvc_ctlr = (periph_id == PERIPH_ID_DVC_I2C);
+#else
+ i2c_bus->use_dvc_ctlr = 0;
+#endif
+
*index = i + 1;
return 0;
@@ -445,6 +460,7 @@ static int i2c_get_config(int *index, struct i2c_bus *i2c_bus)
i2c_bus->pinmux_config = config.pinmux;
i2c_bus->regs = config.reg;
i2c_bus->speed = config.speed;
+ i2c_bus->use_dvc_ctlr = config.use_dvc_ctlr;
return 0;
}
@@ -463,7 +479,7 @@ int i2c_init_board(void)
i2c_get_config(&index, i2c_bus);
- if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C)
+ if (i2c_bus->use_dvc_ctlr)
i2c_bus->control =
&((struct dvc_ctlr *)i2c_bus->regs)->control;
else
diff --git a/include/fdt_decode.h b/include/fdt_decode.h
index 4fb2afe665d..8e522653bca 100644
--- a/include/fdt_decode.h
+++ b/include/fdt_decode.h
@@ -224,6 +224,7 @@ struct fdt_i2c {
int pinmux;
u32 speed;
enum periph_id periph_id;
+ int use_dvc_ctlr; /* 1 if we need to use the DVC */
};
enum {