[PATCH] soft_i2c: add multibus support

Heiko Schocher hs at denx.de
Fri Feb 13 11:10:54 CET 2009


Signed-off-by: Heiko Schocher <hs at denx.de>
---
 drivers/i2c/i2c_core.c   |    3 +
 drivers/i2c/soft_i2c.c   |  129 ++++++++++++++++++++++++++++------------------
 include/configs/mgsuvd.h |    3 +
 include/i2c.h            |    8 +++-
 4 files changed, 91 insertions(+), 52 deletions(-)

diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c
index 4466908..e0afd10 100644
--- a/drivers/i2c/i2c_core.c
+++ b/drivers/i2c/i2c_core.c
@@ -39,6 +39,7 @@ extern i2c_adap_t	tsi108_i2c_adap;
 #endif

 i2c_adap_t	*i2c_adap[CONFIG_SYS_NUM_I2C_ADAPTERS] = CONFIG_SYS_I2C_ADAPTERS;
+i2c_adap_t	*cur_adap_nr = NULL;
 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
 i2c_bus_t	i2c_bus[CONFIG_SYS_NUM_I2C_BUSSES] = CONFIG_SYS_I2C_BUSSES;
 #endif
@@ -208,6 +209,7 @@ int i2c_set_bus_num(unsigned int bus)
 #endif

 	i2c_cur_bus = bus;
+	cur_adap_nr = (i2c_adap_t *)&ADAP(bus);
 	return(0);
 }

@@ -243,6 +245,7 @@ void i2c_init_all(void)
 {
 	int	i;

+	cur_adap_nr = (i2c_adap_t *)&ADAP(0);
 	for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
 		if ((i2c_adap[i]->speed != 0) && (i2c_adap[i]->init != NULL)) {
 			i2c_adap[i]->init(i2c_adap[i]->speed, i2c_adap[i]->slaveaddr);
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index da6cec1..b5302a4 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -55,7 +55,6 @@ DECLARE_GLOBAL_DATA_PTR;
 /*-----------------------------------------------------------------------
  * Definitions
  */
-
 #define RETRIES		0


@@ -216,52 +215,6 @@ static int write_byte(uchar data)
 	return(nack);	/* not a nack is an ack */
 }

-#if defined(CONFIG_I2C_MULTI_BUS)
-/*
- * Functions for multiple I2C bus handling
- */
-unsigned int i2c_get_bus_num(void)
-{
-	return i2c_bus_num;
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#if defined(CONFIG_I2C_MUX)
-	if (bus < CONFIG_SYS_MAX_I2C_BUS) {
-		i2c_bus_num = bus;
-	} else {
-		int	ret;
-
-		ret = i2x_mux_select_mux(bus);
-		if (ret == 0)
-			i2c_bus_num = bus;
-		else
-			return ret;
-	}
-#else
-	if (bus >= CONFIG_SYS_MAX_I2C_BUS)
-		return -1;
-	i2c_bus_num = bus;
-#endif
-	return 0;
-}
-
-/* TODO: add 100/400k switching */
-unsigned int i2c_get_bus_speed(void)
-{
-	return CONFIG_SYS_I2C_SPEED;
-}
-
-int i2c_set_bus_speed(unsigned int speed)
-{
-	if (speed != CONFIG_SYS_I2C_SPEED)
-		return -1;
-
-	return 0;
-}
-#endif
-
 /*-----------------------------------------------------------------------
  * if ack == I2C_ACK, ACK the byte so can continue reading, else
  * send I2C_NOACK to end the read.
@@ -299,7 +252,7 @@ static uchar read_byte(int ack)
 /*-----------------------------------------------------------------------
  * Initialization
  */
-void i2c_init (int speed, int slaveaddr)
+void soft_i2c_init (int speed, int slaveaddr)
 {
 #if defined(CONFIG_SYS_I2C_INIT_BOARD)
 	/* call board specific i2c bus reset routine before accessing the   */
@@ -322,7 +275,7 @@ void i2c_init (int speed, int slaveaddr)
  * completion of EEPROM writes since the chip stops responding until
  * the write completes (typically 10mSec).
  */
-int i2c_probe(uchar addr)
+int soft_i2c_probe(u_int8_t addr)
 {
 	int rc;

@@ -340,7 +293,7 @@ int i2c_probe(uchar addr)
 /*-----------------------------------------------------------------------
  * Read bytes
  */
-int  i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+int  soft_i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 {
 	int shift;
 	PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
@@ -414,7 +367,7 @@ int  i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 /*-----------------------------------------------------------------------
  * Write bytes
  */
-int  i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+int  soft_i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 {
 	int shift, failures = 0;

@@ -444,3 +397,77 @@ int  i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	send_stop();
 	return(failures);
 }
+
+static unsigned int soft_i2c_get_bus_speed(void)
+{
+	return cur_adap_nr->speed;
+}
+
+static unsigned int soft_i2c_set_bus_speed(unsigned int speed)
+{
+	if (speed != cur_adap_nr->speed)
+		return -1;
+	return(speed);
+}
+
+i2c_adap_t	soft_i2c_adap[] = {
+	{
+		.init		=	soft_i2c_init,
+		.probe		=	soft_i2c_probe,
+		.read		=	soft_i2c_read,
+		.write		=	soft_i2c_write,
+		.set_bus_speed	=	soft_i2c_set_bus_speed,
+		.get_bus_speed	=	soft_i2c_get_bus_speed,
+		.speed		=	CONFIG_SYS_SOFT_I2C_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C_SLAVE,
+		.init_done	=	0,
+		.hwadapnr	=	0,
+		.name		=	"soft-i2c"
+	},
+#if defined(I2C_SOFT_DECLARATIONS2)
+	{
+		.init		=	soft_i2c_init,
+		.probe		=	soft_i2c_probe,
+		.read		=	soft_i2c_read,
+		.write		=	soft_i2c_write,
+		.set_bus_speed	=	soft_i2c_set_bus_speed,
+		.get_bus_speed	=	soft_i2c_get_bus_speed,
+		.speed		=	CONFIG_SYS_SOFT_I2C2_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C2_SLAVE,
+		.init_done	=	0,
+		.hwadapnr	=	1,
+		.name		=	"soft-i2c#2"
+	},
+#endif
+#if defined(I2C_SOFT_DECLARATIONS3)
+	{
+		.init		=	soft_i2c_init,
+		.probe		=	soft_i2c_probe,
+		.read		=	soft_i2c_read,
+		.write		=	soft_i2c_write,
+		.set_bus_speed	=	soft_i2c_set_bus_speed,
+		.get_bus_speed	=	soft_i2c_get_bus_speed,
+		.speed		=	CONFIG_SYS_SOFT_I2C3_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C3_SLAVE,
+		.init_done	=	0,
+		.hwadapnr	=	2,
+		.name		=	"soft-i2c#3"
+	},
+#endif
+#if defined(I2C_SOFT_DECLARATIONS4)
+	{
+		.init		=	soft_i2c_init,
+		.probe		=	soft_i2c_probe,
+		.read		=	soft_i2c_read,
+		.write		=	soft_i2c_write,
+		.set_bus_speed	=	soft_i2c_set_bus_speed,
+		.get_bus_speed	=	soft_i2c_get_bus_speed,
+		.speed		=	CONFIG_SYS_SOFT_I2C4_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C4_SLAVE,
+		.init_done	=	0,
+		.hwadapnr	=	3,
+		.name		=	"soft-i2c#4"
+	},
+#endif
+};
+
diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h
index 3ea0725..b1debbc 100644
--- a/include/configs/mgsuvd.h
+++ b/include/configs/mgsuvd.h
@@ -270,6 +270,7 @@
 #define CONFIG_SYS_NUM_I2C_BUSSES	3
 #define CONFIG_SYS_I2C_MAX_HOPS		1
 #define CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define I2C_SOFT_DEFS
 #define I2C_SOFT_DECLARATIONS		I2C_SOFT_DEFS
 #define CONFIG_SYS_SOFT_I2C_SPEED	50000
 #define CONFIG_SYS_SOFT_I2C_SLAVE	0x7F
@@ -277,6 +278,8 @@
 #define CONFIG_SYS_I2C_BUSSES	{	{0, {I2C_NULL_HOP}}, \
 			{0, {{I2C_MUX_PCA9542, 0x70, 0}}}, \
 			{0, {{I2C_MUX_PCA9542, 0x70, 1}}}}
+
+#define CONFIG_I2C_CMD_TREE		1
 /*
  * Software (bit-bang) I2C driver configuration
  */
diff --git a/include/i2c.h b/include/i2c.h
index ea2c3b2..a3cc3ca 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -95,7 +95,8 @@ typedef struct i2c_adapter {
 	int		speed;
 	int		slaveaddr;
 	int		init_done;
-	char		*name;	
+	int		hwadapnr;
+	char		*name;
 } i2c_adap_t;

 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
@@ -130,6 +131,7 @@ extern i2c_bus_t	i2c_bus[];
 #endif

 extern i2c_adap_t	*i2c_adap[];
+extern i2c_adap_t	*cur_adap_nr;

 /*
  * i2c_get_bus_num:
@@ -226,7 +228,11 @@ void i2c_reloc_fixup(void);
 # else
 #  define I2C_SOFT_DEFS
 # endif
+#endif

+#ifndef CONFIG_SYS_I2C_SLAVE
+#define CONFIG_SYS_I2C_SLAVE	0x7f
+#endif
 /*
  * Initialization, must be called once on start up, may be called
  * repeatedly to change the speed and slave addresses.
-- 
1.6.0.6

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


More information about the U-Boot mailing list