[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