Hello ksi, k...@koi8.net wrote: > Signed-off-by: Sergey Kubushyn <k...@koi8.net> > --- > diff -purN u-boot-i2c.orig/drivers/i2c/soft_i2c.c > u-boot-i2c/drivers/i2c/soft_i2c.c > --- u-boot-i2c.orig/drivers/i2c/soft_i2c.c 2009-02-12 10:43:41.000000000 > -0800 > +++ u-boot-i2c/drivers/i2c/soft_i2c.c 2009-02-12 10:46:00.000000000 -0800 > @@ -1,4 +1,8 @@ > /* > + * Copyright (c) 2009 Sergey Kubushyn <k...@koi8.net> > + * > + * Changes for multibus/multiadapter I2C support. > + * > * (C) Copyright 2001, 2002 > * Wolfgang Denk, DENX Software Engineering, w...@denx.de. [...]
The following patch is based on your patches without 7/12 and adds multibus support for the soft_i2c driver without doing such a big change as you did. Maybe it is not yet perfect, because it is just a fast try, but I think we should go this way. What do you/others think? Also it is compatible with existing board ports. I tried this on an 8xx based board (mgsuvd) with success. >From 4f47e858059d02ca9a9a38b35bef55b69c98c3d3 Mon Sep 17 00:00:00 2001 From: Heiko Schocher <h...@denx.de> Date: Fri, 13 Feb 2009 11:10:54 +0100 Subject: [PATCH] soft_i2c: add multibus support Signed-off-by: Heiko Schocher <h...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot