diff options
-rw-r--r-- | board/nvidia/seaboard/tegra250.dtsi | 2 | ||||
-rw-r--r-- | common/fdt_decode.c | 22 | ||||
-rw-r--r-- | drivers/i2c/tegra_i2c.c | 22 | ||||
-rw-r--r-- | include/fdt_decode.h | 1 |
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 { |