summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2011-07-06 13:19:44 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:58:57 -0700
commite8dec207c28ddd16877d2c04ad725b9f3d944854 (patch)
tree8fae67ef3265c2cb9353873f88aea2a3727dbdac /drivers/i2c
parent95a1fba652775984d27fe8ec632147f588b556b6 (diff)
i2c: Add FDT support
BUG=chromium-os:17064 TEST=Build U-Boot Run "i2c probe" for each i2c bus on Seaboard, Kaen and Aebl Change-Id: I1528a6c08d500c001a1210f9947c494b7ffc81f6 Reviewed-on: http://gerrit.chromium.org/gerrit/4049 Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/tegra2_i2c.c104
1 files changed, 75 insertions, 29 deletions
diff --git a/drivers/i2c/tegra2_i2c.c b/drivers/i2c/tegra2_i2c.c
index 6f82131eb0..50867344fe 100644
--- a/drivers/i2c/tegra2_i2c.c
+++ b/drivers/i2c/tegra2_i2c.c
@@ -30,12 +30,16 @@
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/tegra2_i2c.h>
+#include <fdt_decode.h>
+
+DECLARE_GLOBAL_DATA_PTR;
static unsigned int i2c_bus_num;
struct i2c_bus {
int id;
enum periph_id periph_id;
+ int speed;
int pinmux_config;
struct i2c_control *control;
struct i2c_ctlr *regs;
@@ -156,11 +160,11 @@ static void i2c_reset_controller(struct i2c_bus *i2c_bus)
set_packet_mode(i2c_bus);
}
-static void i2c_init_controller(struct i2c_bus *i2c_bus, u32 clock_khz)
+static void i2c_init_controller(struct i2c_bus *i2c_bus)
{
/* TODO: Fix bug which makes us need to do this */
clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_OSC,
- clock_khz * 1000 * (8 * 2 - 1));
+ i2c_bus->speed * (8 * 2 - 1));
/* Reset I2C controller. */
i2c_reset_controller(i2c_bus);
@@ -368,40 +372,81 @@ static int tegra2_i2c_read_data(u32 addr, u8 *data, u32 len)
return error;
}
-void i2c_init_board(void)
+#ifndef CONFIG_OF_CONTROL
+static const enum periph_id i2c_periph_ids[CONFIG_SYS_MAX_I2C_BUS] = {
+ PERIPH_ID_DVC_I2C,
+ PERIPH_ID_I2C1,
+ PERIPH_ID_I2C2,
+ PERIPH_ID_I2C3
+};
+
+static const u32 *i2c_bus_base[CONFIG_SYS_MAX_I2C_BUS] = {
+ (u32 *)TEGRA2_DVC_BASE,
+ (u32 *)TEGRA2_I2C1_BASE,
+ (u32 *)TEGRA2_I2C2_BASE,
+ (u32 *)TEGRA2_I2C3_BASE
+};
+
+/* pinmux_configs based on the pinmux configuration */
+static const int pinmux_configs[CONFIG_SYS_MAX_I2C_BUS] = {
+ CONFIG_I2CP_PIN_MUX, /* for I2CP (DVC I2C) */
+ CONFIG_I2C1_PIN_MUX, /* for I2C1 */
+ CONFIG_I2C2_PIN_MUX, /* for I2C2 */
+ CONFIG_I2C3_PIN_MUX /* for I2C3 */
+};
+
+static int i2c_get_config(int *index, struct i2c_bus *i2c_bus)
{
- struct i2c_bus *i2c_bus;
- int i;
+ int i = *index;
- enum periph_id i2c_periph_ids[CONFIG_SYS_MAX_I2C_BUS] = {
- PERIPH_ID_DVC_I2C,
- PERIPH_ID_I2C1,
- PERIPH_ID_I2C2,
- PERIPH_ID_I2C3
- };
+ if (i >= CONFIG_SYS_MAX_I2C_BUS)
+ return -1;
- u32 *i2c_bus_base[CONFIG_SYS_MAX_I2C_BUS] = {
- (u32 *)TEGRA2_DVC_BASE,
- (u32 *)TEGRA2_I2C1_BASE,
- (u32 *)TEGRA2_I2C2_BASE,
- (u32 *)TEGRA2_I2C3_BASE
- };
+ i2c_bus->periph_id = i2c_periph_ids[i];
+ i2c_bus->pinmux_config = pinmux_configs[i];
+ i2c_bus->regs = (struct i2c_ctlr *)i2c_bus_base[i];
+ i2c_bus->speed = I2CSPEED_KHZ * 1000;
- /* pinmux_configs based on the pinmux configuration */
- int pinmux_configs[CONFIG_SYS_MAX_I2C_BUS] = {
- CONFIG_I2CP_PIN_MUX, /* for I2CP (DVC I2C) */
- CONFIG_I2C1_PIN_MUX, /* for I2C1 */
- CONFIG_I2C2_PIN_MUX, /* for I2C2 */
- CONFIG_I2C3_PIN_MUX /* for I2C3 */
- };
+ *index = i + 1;
+
+ return 0;
+}
+#else
+static int i2c_get_config(int *index, struct i2c_bus *i2c_bus)
+{
+ const void *blob = gd->blob;
+ struct fdt_i2c config;
+ int node = fdt_decode_next_alias(blob,
+ "i2c",
+ COMPAT_NVIDIA_TEGRA250_I2C,
+ index);
+ if (node < 0)
+ return -1;
+
+ if (fdt_decode_i2c(blob, node, &config))
+ return -1;
+
+ i2c_bus->periph_id = config.periph_id;
+ i2c_bus->pinmux_config = config.pinmux;
+ i2c_bus->regs = config.reg;
+ i2c_bus->speed = config.speed;
+
+ return 0;
+}
+#endif
+
+int i2c_init_board(void)
+{
+ struct i2c_bus *i2c_bus;
+ int index = 0;
+ int i;
/* build the i2c_controllers[] for each controller */
for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; ++i) {
i2c_bus = &i2c_controllers[i];
i2c_bus->id = i;
- i2c_bus->periph_id = i2c_periph_ids[i];
- i2c_bus->pinmux_config = pinmux_configs[i];
- i2c_bus->regs = (struct i2c_ctlr *)i2c_bus_base[i];
+
+ i2c_get_config(&index, i2c_bus);
if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C)
i2c_bus->control =
@@ -409,8 +454,10 @@ void i2c_init_board(void)
else
i2c_bus->control = &i2c_bus->regs->control;
- i2c_init_controller(i2c_bus, I2CSPEED_KHZ);
+ i2c_init_controller(i2c_bus);
}
+
+ return 0;
}
void i2c_init(int speed, int slaveaddr)
@@ -564,4 +611,3 @@ int i2c_set_bus_num(unsigned int bus)
return 0;
}
#endif
-