[U-Boot] [PATCH] 7/12 Multiadapter/multibus I2C, drivers part 4

ksi at koi8.net ksi at koi8.net
Fri Feb 13 22:23:36 CET 2009


On Fri, 13 Feb 2009, Heiko Schocher wrote:

> Hello ksi,
> 
> ksi at koi8.net wrote:
> > Signed-off-by: Sergey Kubushyn <ksi at 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 <ksi at koi8.net>
> > + *
> > + * Changes for multibus/multiadapter I2C support.
> > + *
> >   * (C) Copyright 2001, 2002
> >   * Wolfgang Denk, DENX Software Engineering, wd at 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?

The reason behind this patch is making SEVERAL different SOFT_I2C ADAPTERS
available. Not BUSSES but separate PHYSICAL I2C ADAPTERS made of different
pin pairs from different chips.

OK, please explain how are you going to make different functions for
different adapters? Let's say you want to use 2 on-SoC GPIO pins for
adapter #0, 2 GPIOs from a PCI-PCI bridge for adapter #1, and 2 pins from
some chip sitting behind that bridge for adapter #2 if all those pin sets
are accessed totally different. I won't even start about using pins from
different chips for SDA and SCL (let's say you only have one GPIO available
on your SoC and another one on PCI Bridge.)

What your patch creates is just aliases to the SAME physical adapter.

Please explain.

> 
> 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 <hs at denx.de>
> Date: Fri, 13 Feb 2009 11:10:54 +0100
> Subject: [PATCH] soft_i2c: add multibus support
> 
> 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
> 

---
******************************************************************
*  KSI at home    KOI8 Net  < >  The impossible we do immediately.  *
*  Las Vegas   NV, USA   < >  Miracles require 24-hour notice.   *
******************************************************************


More information about the U-Boot mailing list