summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2011-10-18 18:13:22 -0700
committerDoug Anderson <dianders@chromium.org>2011-10-19 16:41:55 -0700
commitb166ce8bdde0a2b7c506a93d4d60f92e932c64d4 (patch)
tree5f82a8d17e84f0d35fd5b02d1485acb82cfbf075
parent547a6442998ecf52fcccfe923a64ac81e1f374f2 (diff)
CHROMIUM: tegra3: i2c: Move DVC semantics choice to device tree
On the tegra30, it appears that the "DVC" i2c controller has been normalized and no longer requires special semantics for accessing it (it has also just been renamed to "i2c5"). This change makes it so that we don't pick DVC semantics based on the periperal ID, but instead allow the device tree to specify. BUG=chromium-os:21540 TEST=Compiled / booted on Kaen Change-Id: Idfd96d1193b5ac267c61416544c63cc03dab396d Signed-off-by: Doug Anderson <dianders@chromium.org> Reviewed-on: http://gerrit.chromium.org/gerrit/10279 Reviewed-by: Simon Glass <sjg@chromium.org>
-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 {