[U-Boot] [RFC PATCH 12/12] dm: i2c: tegra: Convert to driver model for I2C for seaboard

Simon Glass sjg at chromium.org
Mon Oct 13 07:39:38 CEST 2014


This converts seaboard over to use driver model for I2C. This is so far
untested and only useful for broad comments / review. To complete this,
trimslice and whistler will also need conversion.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 arch/arm/cpu/tegra20-common/pmu.c           |  21 +-
 arch/arm/include/asm/arch-tegra/tegra_i2c.h |   2 +-
 board/nvidia/common/board.c                 |   4 -
 drivers/i2c/tegra_i2c.c                     | 313 ++++++++++------------------
 drivers/power/tps6586x.c                    |  27 +--
 include/configs/cardhu.h                    |   2 -
 include/configs/colibri_t30.h               |   2 -
 include/configs/seaboard.h                  |   3 -
 include/configs/tegra-common.h              |   1 +
 include/configs/tegra20-common.h            |   3 -
 include/tps6586x.h                          |   2 +-
 11 files changed, 140 insertions(+), 240 deletions(-)

diff --git a/arch/arm/cpu/tegra20-common/pmu.c b/arch/arm/cpu/tegra20-common/pmu.c
index c595f70..36a76a2 100644
--- a/arch/arm/cpu/tegra20-common/pmu.c
+++ b/arch/arm/cpu/tegra20-common/pmu.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <i2c.h>
 #include <tps6586x.h>
 #include <asm/io.h>
 #include <asm/arch/tegra.h>
@@ -23,9 +24,13 @@
 #define VDD_TRANSITION_STEP	0x06	/* 150mv */
 #define VDD_TRANSITION_RATE	0x06	/* 3.52mv/us */
 
+#define PMI_I2C_ADDRESS	0x34	/* chip requires this address */
+
 int pmu_set_nominal(void)
 {
-	int core, cpu, bus;
+	struct udevice *bus, *dev;
+	int core, cpu;
+	int ret;
 
 	/* by default, the table has been filled with T25 settings */
 	switch (tegra_get_chip_sku()) {
@@ -42,12 +47,18 @@ int pmu_set_nominal(void)
 		return -1;
 	}
 
-	bus = tegra_i2c_get_dvc_bus_num();
-	if (bus == -1) {
+	ret = tegra_i2c_get_dvc_bus(&bus);
+	if (ret) {
 		debug("%s: Cannot find DVC I2C bus\n", __func__);
-		return -1;
+		return ret;
 	}
-	tps6586x_init(bus);
+	ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, &dev);
+	if (ret) {
+		debug("%s: Cannot find DVC I2C chip\n", __func__);
+		return ret;
+	}
+
+	tps6586x_init(dev);
 	tps6586x_set_pwm_mode(TPS6586X_PWM_SM1);
 	return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP,
 				VDD_TRANSITION_RATE, VDD_RELATION);
diff --git a/arch/arm/include/asm/arch-tegra/tegra_i2c.h b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
index 7ca6907..eeeb247 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_i2c.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
@@ -167,6 +167,6 @@ struct i2c_ctlr {
  *
  * @return number of bus, or -1 if there is no DVC active
  */
-int tegra_i2c_get_dvc_bus_num(void);
+int tegra_i2c_get_dvc_bus(struct udevice **busp);
 
 #endif	/* _TEGRA_I2C_H_ */
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 03f055d..7226fa4 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -132,10 +132,6 @@ int board_init(void)
 	power_det_init();
 
 #ifdef CONFIG_SYS_I2C_TEGRA
-#ifndef CONFIG_SYS_I2C_INIT_BOARD
-#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
-#endif
-	i2c_init_board();
 # ifdef CONFIG_TEGRA_PMU
 	if (pmu_set_nominal())
 		debug("Failed to select nominal voltages\n");
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 257b72f..85a6837 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -7,6 +7,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <fdtdec.h>
 #include <i2c.h>
 #include <asm/io.h>
@@ -19,6 +21,12 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+enum i2c_type {
+	TYPE_114,
+	TYPE_STD,
+	TYPE_DVC,
+};
+
 /* Information about i2c controller */
 struct i2c_bus {
 	int			id;
@@ -27,20 +35,17 @@ struct i2c_bus {
 	int			pinmux_config;
 	struct i2c_control	*control;
 	struct i2c_ctlr		*regs;
-	int			is_dvc;	/* DVC type, rather than I2C */
-	int			is_scs;	/* single clock source (T114+) */
+	enum i2c_type		type;
 	int			inited;	/* bus is inited */
 };
 
-static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS];
-
 static void set_packet_mode(struct i2c_bus *i2c_bus)
 {
 	u32 config;
 
 	config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK;
 
-	if (i2c_bus->is_dvc) {
+	if (i2c_bus->type == TYPE_DVC) {
 		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
 
 		writel(config, &dvc->cnfg);
@@ -73,7 +78,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
 	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
 		i2c_bus->speed * 2 * 8);
 
-	if (i2c_bus->is_scs) {
+	if (i2c_bus->type == TYPE_114) {
 		/*
 		 * T114 I2C went to a single clock source for standard/fast and
 		 * HS clock speeds. The new clock rate setting calculation is:
@@ -98,7 +103,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
 	i2c_reset_controller(i2c_bus);
 
 	/* Configure I2C controller. */
-	if (i2c_bus->is_dvc) {	/* only for DVC I2C */
+	if (i2c_bus->type == TYPE_DVC) {	/* only for DVC I2C */
 		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
 
 		setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK);
@@ -272,7 +277,7 @@ exit:
 	return error;
 }
 
-static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
+static int tegra_i2c_write_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
 				u32 len, bool end_with_repeated_start)
 {
 	int error;
@@ -286,14 +291,14 @@ static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
 	trans_info.num_bytes = len;
 	trans_info.is_10bit_address = 0;
 
-	error = send_recv_packets(bus, &trans_info);
+	error = send_recv_packets(i2c_bus, &trans_info);
 	if (error)
 		debug("tegra_i2c_write_data: Error (%d) !!!\n", error);
 
 	return error;
 }
 
-static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
+static int tegra_i2c_read_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
 			       u32 len)
 {
 	int error;
@@ -305,7 +310,7 @@ static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
 	trans_info.num_bytes = len;
 	trans_info.is_10bit_address = 0;
 
-	error = send_recv_packets(bus, &trans_info);
+	error = send_recv_packets(i2c_bus, &trans_info);
 	if (error)
 		debug("tegra_i2c_read_data: Error (%d) !!!\n", error);
 
@@ -316,41 +321,25 @@ static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
 #error "Please enable device tree support to use this driver"
 #endif
 
-/**
- * Check that a bus number is valid and return a pointer to it
- *
- * @param bus_num	Bus number to check / return
- * @return pointer to bus, if valid, else NULL
- */
-static struct i2c_bus *tegra_i2c_get_bus(struct i2c_adapter *adap)
+static int tegra_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
 {
-	struct i2c_bus *bus;
+	struct i2c_bus *i2c_bus = dev_get_priv(dev);
 
-	bus = &i2c_controllers[adap->hwadapnr];
-	if (!bus->inited) {
-		debug("%s: Bus %u not available\n", __func__, adap->hwadapnr);
-		return NULL;
-	}
-
-	return bus;
-}
-
-static unsigned int tegra_i2c_set_bus_speed(struct i2c_adapter *adap,
-			unsigned int speed)
-{
-	struct i2c_bus *bus;
-
-	bus = tegra_i2c_get_bus(adap);
-	if (!bus)
-		return 0;
-	bus->speed = speed;
-	i2c_init_controller(bus);
+	i2c_bus->speed = speed;
+	i2c_init_controller(i2c_bus);
 
 	return 0;
 }
 
-static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
+static int tegra_i2c_probe(struct udevice *dev)
 {
+	struct i2c_bus *i2c_bus = dev_get_priv(dev);
+	const void *blob = gd->fdt_blob;
+	int node = dev->of_offset;
+	bool is_dvc;
+
+	i2c_bus->id = dev->seq;
+	i2c_bus->type = dev_get_of_data(dev);
 	i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
 
 	/*
@@ -358,7 +347,6 @@ static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
 	 * far no one needs anything other than the default.
 	 */
 	i2c_bus->pinmux_config = FUNCMUX_DEFAULT;
-	i2c_bus->speed = fdtdec_get_int(blob, node, "clock-frequency", 0);
 	i2c_bus->periph_id = clock_decode_periph_id(blob, node);
 
 	/*
@@ -371,107 +359,25 @@ static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
 	 *		i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
 	 */
 	if (i2c_bus->periph_id == -1)
-		return -FDT_ERR_NOTFOUND;
-
-	return 0;
-}
+		return -EINVAL;
 
-/*
- * Process a list of nodes, adding them to our list of I2C ports.
- *
- * @param blob		fdt blob
- * @param node_list	list of nodes to process (any <=0 are ignored)
- * @param count		number of nodes to process
- * @param is_dvc	1 if these are DVC ports, 0 if standard I2C
- * @param is_scs	1 if this HW uses a single clock source (T114+)
- * @return 0 if ok, -1 on error
- */
-static int process_nodes(const void *blob, int node_list[], int count,
-			 int is_dvc, int is_scs)
-{
-	struct i2c_bus *i2c_bus;
-	int i;
-
-	/* build the i2c_controllers[] for each controller */
-	for (i = 0; i < count; i++) {
-		int node = node_list[i];
-
-		if (node <= 0)
-			continue;
-
-		i2c_bus = &i2c_controllers[i];
-		i2c_bus->id = i;
-
-		if (i2c_get_config(blob, node, i2c_bus)) {
-			printf("i2c_init_board: failed to decode bus %d\n", i);
-			return -1;
-		}
-
-		i2c_bus->is_scs = is_scs;
-
-		i2c_bus->is_dvc = is_dvc;
-		if (is_dvc) {
-			i2c_bus->control =
-				&((struct dvc_ctlr *)i2c_bus->regs)->control;
-		} else {
-			i2c_bus->control = &i2c_bus->regs->control;
-		}
-		debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
-		      is_dvc ? "dvc" : "i2c", i, i2c_bus->regs,
-		      i2c_bus->periph_id, i2c_bus->speed);
-		i2c_init_controller(i2c_bus);
-		debug("ok\n");
-		i2c_bus->inited = 1;
-
-		/* Mark position as used */
-		node_list[i] = -1;
+	is_dvc = dev_get_of_data(dev) == TYPE_DVC;
+	if (is_dvc) {
+		i2c_bus->control =
+			&((struct dvc_ctlr *)i2c_bus->regs)->control;
+	} else {
+		i2c_bus->control = &i2c_bus->regs->control;
 	}
+	i2c_init_controller(i2c_bus);
+	debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
+	      is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs,
+	      i2c_bus->periph_id, i2c_bus->speed);
 
 	return 0;
 }
 
-/* Sadly there is no error return from this function */
-void i2c_init_board(void)
-{
-	int node_list[TEGRA_I2C_NUM_CONTROLLERS];
-	const void *blob = gd->fdt_blob;
-	int count;
-
-	/* First check for newer (T114+) I2C ports */
-	count = fdtdec_find_aliases_for_id(blob, "i2c",
-			COMPAT_NVIDIA_TEGRA114_I2C, node_list,
-			TEGRA_I2C_NUM_CONTROLLERS);
-	if (process_nodes(blob, node_list, count, 0, 1))
-		return;
-
-	/* Now get the older (T20/T30) normal I2C ports */
-	count = fdtdec_find_aliases_for_id(blob, "i2c",
-			COMPAT_NVIDIA_TEGRA20_I2C, node_list,
-			TEGRA_I2C_NUM_CONTROLLERS);
-	if (process_nodes(blob, node_list, count, 0, 0))
-		return;
-
-	/* Now look for dvc ports */
-	count = fdtdec_add_aliases_for_id(blob, "i2c",
-			COMPAT_NVIDIA_TEGRA20_DVC, node_list,
-			TEGRA_I2C_NUM_CONTROLLERS);
-	if (process_nodes(blob, node_list, count, 1, 0))
-		return;
-}
-
-static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
-{
-	/* No i2c support prior to relocation */
-	if (!(gd->flags & GD_FLG_RELOC))
-		return;
-
-	/* This will override the speed selected in the fdt for that port */
-	debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
-	i2c_set_bus_speed(speed);
-}
-
 /* i2c write version without the register address */
-int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
+int i2c_write_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer, int len,
 		   bool end_with_repeated_start)
 {
 	int rc;
@@ -484,7 +390,7 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
 	debug("\n");
 
 	/* Shift 7-bit address over for lower-level i2c functions */
-	rc = tegra_i2c_write_data(bus, chip << 1, buffer, len,
+	rc = tegra_i2c_write_data(i2c_bus, chip << 1, buffer, len,
 				  end_with_repeated_start);
 	if (rc)
 		debug("i2c_write_data(): rc=%d\n", rc);
@@ -493,13 +399,13 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
 }
 
 /* i2c read version without the register address */
-int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
+int i2c_read_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer, int len)
 {
 	int rc;
 
 	debug("inside i2c_read_data():\n");
 	/* Shift 7-bit address over for lower-level i2c functions */
-	rc = tegra_i2c_read_data(bus, chip << 1, buffer, len);
+	rc = tegra_i2c_read_data(i2c_bus, chip << 1, buffer, len);
 	if (rc) {
 		debug("i2c_read_data(): rc=%d\n", rc);
 		return rc;
@@ -515,48 +421,41 @@ int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
 }
 
 /* Probe to see if a chip is present. */
-static int tegra_i2c_probe(struct i2c_adapter *adap, uchar chip)
+static int tegra_i2c_probe_chip(struct udevice *dev, uint chip)
 {
-	struct i2c_bus *bus;
+	struct i2c_bus *i2c_bus = dev_get_priv(dev);
 	int rc;
 	uchar reg;
 
 	debug("i2c_probe: addr=0x%x\n", chip);
-	bus = tegra_i2c_get_bus(adap);
-	if (!bus)
-		return 1;
 	reg = 0;
-	rc = i2c_write_data(bus, chip, &reg, 1, false);
+	rc = i2c_write_data(i2c_bus, chip, &reg, 1, false);
 	if (rc) {
 		debug("Error probing 0x%x.\n", chip);
-		return 1;
+		return rc;
 	}
 	return 0;
 }
 
-static int i2c_addr_ok(const uint addr, const int alen)
+static int tegra_i2c_set_addr_len(struct udevice *dev, const uint alen)
 {
 	/* We support 7 or 10 bit addresses, so one or two bytes each */
-	return alen == 1 || alen == 2;
+	if (alen == 1 || alen == 2)
+		return 0;
+
+	return -EINVAL;
 }
 
 /* Read bytes */
-static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
-			int alen, uchar *buffer, int len)
+static int tegra_i2c_read(struct udevice *dev, uint chip_addr, uint addr,
+			  uint alen, uchar *buffer, int len)
 {
-	struct i2c_bus *bus;
+	struct i2c_bus *i2c_bus = dev_get_priv(dev);
 	uint offset;
 	int i;
 
 	debug("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n",
-	      chip, addr, alen, len);
-	bus = tegra_i2c_get_bus(adap);
-	if (!bus)
-		return 1;
-	if (!i2c_addr_ok(addr, alen)) {
-		debug("i2c_read: Bad address %x.%d.\n", addr, alen);
-		return 1;
-	}
+	      chip_addr, addr, alen, len);
 	for (offset = 0; offset < len; offset++) {
 		if (alen) {
 			uchar data[alen];
@@ -564,13 +463,14 @@ static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 				data[alen - i - 1] =
 					(addr + offset) >> (8 * i);
 			}
-			if (i2c_write_data(bus, chip, data, alen, true)) {
+			if (i2c_write_data(i2c_bus, chip_addr, data, alen,
+					   true)) {
 				debug("i2c_read: error sending (0x%x)\n",
 					addr);
 				return 1;
 			}
 		}
-		if (i2c_read_data(bus, chip, buffer + offset, 1)) {
+		if (i2c_read_data(i2c_bus, chip_addr, buffer + offset, 1)) {
 			debug("i2c_read: error reading (0x%x)\n", addr);
 			return 1;
 		}
@@ -580,28 +480,22 @@ static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 }
 
 /* Write bytes */
-static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
-			int alen, uchar *buffer, int len)
+static int tegra_i2c_write(struct udevice *dev, uint chip_addr, uint addr,
+			uint alen, const uchar *buffer, int len)
 {
-	struct i2c_bus *bus;
+	struct i2c_bus *i2c_bus = dev_get_priv(dev);
 	uint offset;
 	int i;
 
 	debug("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n",
-	      chip, addr, alen, len);
-	bus = tegra_i2c_get_bus(adap);
-	if (!bus)
-		return 1;
-	if (!i2c_addr_ok(addr, alen)) {
-		debug("i2c_write: Bad address %x.%d.\n", addr, alen);
-		return 1;
-	}
+	      chip_addr, addr, alen, len);
 	for (offset = 0; offset < len; offset++) {
 		uchar data[alen + 1];
 		for (i = 0; i < alen; i++)
 			data[alen - i - 1] = (addr + offset) >> (8 * i);
 		data[alen] = buffer[offset];
-		if (i2c_write_data(bus, chip, data, alen + 1, false)) {
+		if (i2c_write_data(i2c_bus, chip_addr, data, alen + 1,
+				   false)) {
 			debug("i2c_write: error sending (0x%x)\n", addr);
 			return 1;
 		}
@@ -610,37 +504,58 @@ static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 	return 0;
 }
 
-int tegra_i2c_get_dvc_bus_num(void)
+int tegra_i2c_get_dvc_bus(struct udevice **busp)
 {
-	int i;
+	struct udevice *bus;
 
-	for (i = 0; i < TEGRA_I2C_NUM_CONTROLLERS; i++) {
-		struct i2c_bus *bus = &i2c_controllers[i];
-
-		if (bus->inited && bus->is_dvc)
-			return i;
+	for (uclass_first_device(UCLASS_I2C, &bus);
+	     bus;
+	     uclass_next_device(&bus)) {
+		if (dev_get_of_data(bus) == TYPE_DVC) {
+			*busp = bus;
+			return 0;
+		}
 	}
 
-	return -1;
+	return -ENODEV;
 }
 
-/*
- * Register soft i2c adapters
- */
-U_BOOT_I2C_ADAP_COMPLETE(tegra0, tegra_i2c_init, tegra_i2c_probe,
-			 tegra_i2c_read, tegra_i2c_write,
-			 tegra_i2c_set_bus_speed, 100000, 0, 0)
-U_BOOT_I2C_ADAP_COMPLETE(tegra1, tegra_i2c_init, tegra_i2c_probe,
-			 tegra_i2c_read, tegra_i2c_write,
-			 tegra_i2c_set_bus_speed, 100000, 0, 1)
-U_BOOT_I2C_ADAP_COMPLETE(tegra2, tegra_i2c_init, tegra_i2c_probe,
-			 tegra_i2c_read, tegra_i2c_write,
-			 tegra_i2c_set_bus_speed, 100000, 0, 2)
-U_BOOT_I2C_ADAP_COMPLETE(tegra3, tegra_i2c_init, tegra_i2c_probe,
-			 tegra_i2c_read, tegra_i2c_write,
-			 tegra_i2c_set_bus_speed, 100000, 0, 3)
-#if TEGRA_I2C_NUM_CONTROLLERS > 4
-U_BOOT_I2C_ADAP_COMPLETE(tegra4, tegra_i2c_init, tegra_i2c_probe,
-			 tegra_i2c_read, tegra_i2c_write,
-			 tegra_i2c_set_bus_speed, 100000, 0, 4)
-#endif
+static const struct dm_i2c_ops tegra_i2c_ops = {
+	.probe		= tegra_i2c_probe_chip,
+	.read		= tegra_i2c_read,
+	.write		= tegra_i2c_write,
+	.set_bus_speed	= tegra_i2c_set_bus_speed,
+	.set_addr_len	= tegra_i2c_set_addr_len,
+};
+
+static int tegra_i2c_child_pre_probe(struct udevice *dev)
+{
+	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
+
+	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
+					   i2c_chip);
+}
+
+static int tegra_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+	return 0;
+}
+
+static const struct udevice_id tegra_i2c_ids[] = {
+	{ .compatible = "tegra114-i2c", .data = TYPE_114 },
+	{ .compatible = "tegra,i2c", .data = TYPE_STD },
+	{ .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC },
+	{ }
+};
+
+U_BOOT_DRIVER(i2c_tegra) = {
+	.name	= "i2c_tegra",
+	.id	= UCLASS_I2C,
+	.of_match = tegra_i2c_ids,
+	.ofdata_to_platdata = tegra_i2c_ofdata_to_platdata,
+	.probe	= tegra_i2c_probe,
+	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
+	.child_pre_probe = tegra_i2c_child_pre_probe,
+	.priv_auto_alloc_size = sizeof(struct i2c_bus),
+	.ops	= &tegra_i2c_ops,
+};
diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c
index d29d969..29bab4c 100644
--- a/drivers/power/tps6586x.c
+++ b/drivers/power/tps6586x.c
@@ -10,9 +10,7 @@
 #include <asm/io.h>
 #include <i2c.h>
 
-static int bus_num;		/* I2C bus we are on */
-#define I2C_ADDRESS		0x34	/* chip requires this address */
-static char inited;		/* 1 if we have been inited */
+static struct udevice *tps6586x_dev;
 
 enum {
 	/* Registers that we access */
@@ -37,13 +35,9 @@ static int tps6586x_read(int reg)
 	int	i;
 	uchar	data;
 	int	retval = -1;
-	int	old_bus_num;
-
-	old_bus_num = i2c_get_bus_num();
-	i2c_set_bus_num(bus_num);
 
 	for (i = 0; i < MAX_I2C_RETRY; ++i) {
-		if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
+		if (!i2c_read(tps6586x_dev, reg,  &data, 1)) {
 			retval = (int)data;
 			goto exit;
 		}
@@ -53,7 +47,6 @@ static int tps6586x_read(int reg)
 	}
 
 exit:
-	i2c_set_bus_num(old_bus_num);
 	debug("pmu_read %x=%x\n", reg, retval);
 	if (retval < 0)
 		debug("%s: failed to read register %#x: %d\n", __func__, reg,
@@ -65,13 +58,9 @@ static int tps6586x_write(int reg, uchar *data, uint len)
 {
 	int	i;
 	int	retval = -1;
-	int	old_bus_num;
-
-	old_bus_num = i2c_get_bus_num();
-	i2c_set_bus_num(bus_num);
 
 	for (i = 0; i < MAX_I2C_RETRY; ++i) {
-		if (!i2c_write(I2C_ADDRESS, reg, 1, data, len)) {
+		if (!i2c_write(tps6586x_dev, reg, data, len)) {
 			retval = 0;
 			goto exit;
 		}
@@ -81,7 +70,6 @@ static int tps6586x_write(int reg, uchar *data, uint len)
 	}
 
 exit:
-	i2c_set_bus_num(old_bus_num);
 	debug("pmu_write %x=%x: ", reg, retval);
 	for (i = 0; i < len; i++)
 		debug("%x ", data[i]);
@@ -163,7 +151,7 @@ int tps6586x_set_pwm_mode(int mask)
 	uchar val;
 	int ret;
 
-	assert(inited);
+	assert(tps6586x_dev);
 	ret = tps6586x_read(PFM_MODE);
 	if (ret != -1) {
 		val = (uchar)ret;
@@ -184,7 +172,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
 	int sm0, sm1;
 	int bad;
 
-	assert(inited);
+	assert(tps6586x_dev);
 
 	/* get current voltage settings */
 	if (read_voltages(&sm0, &sm1)) {
@@ -255,10 +243,9 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
 	return bad ? -1 : 0;
 }
 
-int tps6586x_init(int bus)
+int tps6586x_init(struct udevice *dev)
 {
-	bus_num = bus;
-	inited = 1;
+	tps6586x_dev = dev;
 
 	return 0;
 }
diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h
index 09129c7..5be3752 100644
--- a/include/configs/cardhu.h
+++ b/include/configs/cardhu.h
@@ -45,8 +45,6 @@
 #define CONFIG_SYS_I2C_TEGRA
 #define CONFIG_SYS_I2C_INIT_BOARD
 #define CONFIG_I2C_MULTI_BUS
-#define CONFIG_SYS_MAX_I2C_BUS		TEGRA_I2C_NUM_CONTROLLERS
-#define CONFIG_SYS_I2C_SPEED		100000
 #define CONFIG_CMD_I2C
 #define CONFIG_SYS_I2C
 
diff --git a/include/configs/colibri_t30.h b/include/configs/colibri_t30.h
index 782b9d1..18ce2fa 100644
--- a/include/configs/colibri_t30.h
+++ b/include/configs/colibri_t30.h
@@ -27,9 +27,7 @@
 /* I2C */
 #define CONFIG_SYS_I2C_TEGRA
 #define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_SYS_I2C_SPEED		100000
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C
 
 /* SD/MMC */
 #define CONFIG_MMC
diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
index 04e4f82..5f77051 100644
--- a/include/configs/seaboard.h
+++ b/include/configs/seaboard.h
@@ -37,10 +37,7 @@
 
 /* I2C */
 #define CONFIG_SYS_I2C_TEGRA
-#define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_SYS_I2C_SPEED		100000
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C
 
 /* SD/MMC */
 #define CONFIG_MMC
diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h
index 4719ee1..a68b474 100644
--- a/include/configs/tegra-common.h
+++ b/include/configs/tegra-common.h
@@ -26,6 +26,7 @@
 #endif
 #define CONFIG_DM_SPI
 #define CONFIG_DM_SPI_FLASH
+#define CONFIG_DM_I2C
 
 #define CONFIG_SYS_TIMER_RATE		1000000
 #define CONFIG_SYS_TIMER_COUNTER	NV_PA_TMRUS_BASE
diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h
index 21bf977..6330281 100644
--- a/include/configs/tegra20-common.h
+++ b/include/configs/tegra20-common.h
@@ -97,9 +97,6 @@
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
 
-/* Total I2C ports on Tegra20 */
-#define TEGRA_I2C_NUM_CONTROLLERS	4
-
 #define CONFIG_SYS_NAND_SELF_INIT
 #define CONFIG_SYS_NAND_ONFI_DETECTION
 
diff --git a/include/tps6586x.h b/include/tps6586x.h
index 78ce428..9ea0c89 100644
--- a/include/tps6586x.h
+++ b/include/tps6586x.h
@@ -47,6 +47,6 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
  * @param bus	I2C bus number containing the TPS6586X chip
  * @return 0 (always succeeds)
  */
-int tps6586x_init(int bus);
+int tps6586x_init(struct udevice *bus);
 
 #endif	/* _TPS6586X_H_ */
-- 
2.1.0.rc2.206.gedb03e5



More information about the U-Boot mailing list