Skip to contentSkip to conversation

i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

PATCH Superseded Timur Tabi 6 participants 19 messages Dec 3, 2008 – Dec 17, 2008

Subsystems (2)
lore
Share & tools
lore

Timur Tabi

author
#0 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

All implementations of the functions i2c_reg_read() and i2c_reg_write() are identical. We can save space and simplify the code by converting these functions into inlines and putting them in i2c.h.

---

v3: add 8xx-specific code, and include PRINTDs from blackfin and pxa

I'm posting this patch because I'm enhancing the I2C routines to support multiple I2C busses more easily, but I need to clean up the existing code first.

I'm going to be on vacation when the next merge window opens, so I'm posting this now in the hopes that it will be picked up when the window does open.

 cpu/arm920t/at91rm9200/i2c.c  |   14 ---------
 cpu/arm926ejs/davinci/i2c.c   |   17 -----------
 cpu/blackfin/i2c.c            |   16 ----------
 cpu/mpc512x/i2c.c             |   17 -----------
 cpu/mpc5xxx/i2c.c             |   16 ----------
 cpu/mpc8220/i2c.c             |   16 ----------
 cpu/mpc824x/drivers/i2c/i2c.c |   14 ---------
 cpu/mpc8260/i2c.c             |   16 ----------
 cpu/mpc8xx/i2c.c              |   33 ---------------------
 cpu/ppc4xx/i2c.c              |   20 -------------
 cpu/pxa/i2c.c                 |   15 ----------
 drivers/i2c/fsl_i2c.c         |   16 ----------
 drivers/i2c/soft_i2c.c        |   19 ------------
 include/i2c.h                 |   62 +++++++++++++++++++++++++++++++++++++++-
 14 files changed, 60 insertions(+), 231 deletions(-)
cpu/arm920t/at91rm9200/i2c.c +0 -14
index b68c5dd..9fd72d3 100644
@@ -189,20 +189,6 @@ i2c_init(int speed, int slaveaddr)
 	return;
 }
 
-uchar i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-	unsigned char buf;
-
-	i2c_read(i2c_addr, reg, 1, &buf, 1);
-
-	return(buf);
-}
-
-void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write(i2c_addr, reg, 1, &val, 1);
-}
-
 int i2c_set_bus_speed(unsigned int speed)
 {
 	return -1;
cpu/arm926ejs/davinci/i2c.c +0 -17
index d220a4c..3ba20ef 100644
@@ -331,21 +331,4 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	return(0);
 }
 
-
-u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
-{
-	u_int8_t	tmp;
-
-	i2c_read(chip, reg, 1, &tmp, 1);
-	return(tmp);
-}
-
-
-void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
-{
-	u_int8_t	tmp;
-
-	i2c_write(chip, reg, 1, &tmp, 1);
-}
-
 #endif /* CONFIG_DRIVER_DAVINCI_I2C */
cpu/blackfin/i2c.c +0 -16
index 60f03d4..2a3e223 100644
@@ -425,20 +425,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
 
 }
 
-uchar i2c_reg_read(uchar chip, uchar reg)
-{
-	uchar buf;
-
-	PRINTD("i2c_reg_read: chip=0x%02x, reg=0x%02x\n", chip, reg);
-	i2c_read(chip, reg, 0, &buf, 1);
-	return (buf);
-}
-
-void i2c_reg_write(uchar chip, uchar reg, uchar val)
-{
-	PRINTD("i2c_reg_write: chip=0x%02x, reg=0x%02x, val=0x%02x\n", chip,
-			reg, val);
-	i2c_write(chip, reg, 0, &val, 1);
-}
-
 #endif /* CONFIG_HARD_I2C */
cpu/mpc512x/i2c.c +0 -17
index 77a6f0d..4f6bc86 100644
@@ -382,23 +382,6 @@ Done:
 	return ret;
 }
 
-uchar i2c_reg_read (uchar chip, uchar reg)
-{
-	uchar buf;
-
-	i2c_read (chip, reg, 1, &buf, 1);
-
-	return buf;
-}
-
-void i2c_reg_write (uchar chip, uchar reg, uchar val)
-{
-	i2c_write (chip, reg, 1, &val, 1);
-
-	return;
-}
-
-
 int i2c_set_bus_num (unsigned int bus)
 {
 	if (bus >= I2C_BUS_CNT) {
cpu/mpc5xxx/i2c.c +0 -16
index 4d16bbe..7d76274 100644
@@ -380,20 +380,4 @@ Done:
 	return ret;
 }
 
-uchar i2c_reg_read(uchar chip, uchar reg)
-{
-	uchar buf;
-
-	i2c_read(chip, reg, 1, &buf, 1);
-
-	return buf;
-}
-
-void i2c_reg_write(uchar chip, uchar reg, uchar val)
-{
-	i2c_write(chip, reg, 1, &val, 1);
-
-	return;
-}
-
 #endif	/* CONFIG_HARD_I2C */
cpu/mpc8220/i2c.c +0 -16
index d67936d..76ecdf1 100644
@@ -387,20 +387,4 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buf, int len)
 	return ret;
 }
 
-uchar i2c_reg_read (uchar chip, uchar reg)
-{
-	uchar buf;
-
-	i2c_read (chip, reg, 1, &buf, 1);
-
-	return buf;
-}
-
-void i2c_reg_write (uchar chip, uchar reg, uchar val)
-{
-	i2c_write (chip, reg, 1, &val, 1);
-
-	return;
-}
-
 #endif /* CONFIG_HARD_I2C */
cpu/mpc824x/drivers/i2c/i2c.c +0 -14
index 854345e..637ae4c 100644
@@ -267,18 +267,4 @@ int i2c_probe (uchar chip)
 	return i2c_read (chip, 0, 1, (uchar *) &tmp, 1);
 }
 
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
-	uchar buf[1];
-
-	i2c_read (i2c_addr, reg, 1, buf, 1);
-
-	return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
 #endif /* CONFIG_HARD_I2C */
cpu/mpc8260/i2c.c +0 -16
index a934193..68c37e6 100644
@@ -753,22 +753,6 @@ i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	return 0;
 }
 
-uchar
-i2c_reg_read(uchar chip, uchar reg)
-{
-	uchar buf;
-
-	i2c_read(chip, reg, 1, &buf, 1);
-
-	return (buf);
-}
-
-void
-i2c_reg_write(uchar chip, uchar reg, uchar val)
-{
-	i2c_write(chip, reg, 1, &val, 1);
-}
-
 #if defined(CONFIG_I2C_MULTI_BUS)
 /*
  * Functions for multiple I2C bus handling
cpu/mpc8xx/i2c.c +0 -33
index 29c7c71..338caba 100644
@@ -42,19 +42,6 @@ DECLARE_GLOBAL_DATA_PTR;
 /* define to enable debug messages */
 #undef	DEBUG_I2C
 
-/*-----------------------------------------------------------------------
- * Set default values
- */
-#ifndef	CONFIG_SYS_I2C_SPEED
-#define	CONFIG_SYS_I2C_SPEED	50000
-#endif
-
-#ifndef	CONFIG_SYS_I2C_SLAVE
-#define	CONFIG_SYS_I2C_SLAVE	0xFE
-#endif
-/*-----------------------------------------------------------------------
- */
-
 /* tx/rx timeout (we need the i2c early, so we don't use get_timer()) */
 #define TOUT_LOOP 1000000
 
@@ -717,24 +704,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	return 0;
 }
 
-uchar
-i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-	uchar buf;
-
-	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-
-	i2c_read(i2c_addr, reg, 1, &buf, 1);
-
-	return (buf);
-}
-
-void
-i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-
-	i2c_write(i2c_addr, reg, 1, &val, 1);
-}
-
 #endif	/* CONFIG_HARD_I2C */
cpu/ppc4xx/i2c.c +0 -20
index 0deb149..4456f3f 100644
@@ -420,26 +420,6 @@ int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
 	return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
 }
 
-/*-----------------------------------------------------------------------
- * Read a register
- */
-uchar i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-	uchar buf;
-
-	i2c_read(i2c_addr, reg, 1, &buf, 1);
-
-	return (buf);
-}
-
-/*-----------------------------------------------------------------------
- * Write a register
- */
-void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write(i2c_addr, reg, 1, &val, 1);
-}
-
 #if defined(CONFIG_I2C_MULTI_BUS)
 /*
  * Functions for multiple I2C bus handling
cpu/pxa/i2c.c +0 -15
index 08042be..6b72ba1 100644
@@ -455,19 +455,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 
 }
 
-uchar i2c_reg_read (uchar chip, uchar reg)
-{
-	uchar buf;
-
-	PRINTD(("i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg));
-	i2c_read(chip, reg, 1, &buf, 1);
-	return (buf);
-}
-
-void  i2c_reg_write(uchar chip, uchar reg, uchar val)
-{
-	PRINTD(("i2c_reg_write(chip=0x%02x, reg=0x%02x, val=0x%02x)\n",chip,reg,val));
-	i2c_write(chip, reg, 1, &val, 1);
-}
-
 #endif	/* CONFIG_HARD_I2C */
drivers/i2c/fsl_i2c.c +0 -16
index 281a88b..79fdc6d 100644
@@ -368,22 +368,6 @@ i2c_probe(uchar chip)
 	return i2c_read(chip, 0, 0, NULL, 0);
 }
 
-uchar
-i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-	uchar buf[1];
-
-	i2c_read(i2c_addr, reg, 1, buf, 1);
-
-	return buf[0];
-}
-
-void
-i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write(i2c_addr, reg, 1, &val, 1);
-}
-
 int i2c_set_bus_num(unsigned int bus)
 {
 #ifdef CONFIG_SYS_I2C2_OFFSET
drivers/i2c/soft_i2c.c +0 -19
index ebe60e2..a863348 100644
@@ -435,22 +435,3 @@ int  i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	return(failures);
 }
 
-/*-----------------------------------------------------------------------
- * Read a register
- */
-uchar i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-	uchar buf;
-
-	i2c_read(i2c_addr, reg, 1, &buf, 1);
-
-	return(buf);
-}
-
-/*-----------------------------------------------------------------------
- * Write a register
- */
-void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write(i2c_addr, reg, 1, &val, 1);
-}
include/i2c.h +60 -2

74 lines not on this page · raw message

Signature · 1 line
1.5.5
#2 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

In reply to Timur Tabi

Dear Timur Tabi,

Quoted 7 lines · In message <[email protected]> you wrote:

All implementations of the functions i2c_reg_read() and i2c_reg_write() are identical. We can save space and simplify the code by converting these functions into inlines and putting them in i2c.h.

---

Quoted 8 lines

v3: add 8xx-specific code, and include PRINTDs from blackfin and pxa

I'm posting this patch because I'm enhancing the I2C routines to support multiple I2C busses more easily, but I need to clean up the existing code first.

I'm going to be on vacation when the next merge window opens, so I'm posting this now in the hopes that it will be picked up when the window does open.

We've been discussing this long enough when the previous window was open, so ...

Quoted 7 lines
 cpu/arm920t/at91rm9200/i2c.c  |   14 ---------
 cpu/arm926ejs/davinci/i2c.c   |   17 -----------
 cpu/blackfin/i2c.c            |   16 ----------
 cpu/mpc512x/i2c.c             |   17 -----------
 cpu/mpc5xxx/i2c.c             |   16 ----------
 cpu/mpc8220/i2c.c             |   16 ----------
 cpu/mpc824x/drivers/i2c/i2c.c |   14 ---------
Quoted 8 lines
 cpu/mpc8260/i2c.c             |   16 ----------
 cpu/mpc8xx/i2c.c              |   33 ---------------------
 cpu/ppc4xx/i2c.c              |   20 -------------
 cpu/pxa/i2c.c                 |   15 ----------
 drivers/i2c/fsl_i2c.c         |   16 ----------
 drivers/i2c/soft_i2c.c        |   19 ------------
 include/i2c.h                 |   62 +++++++++++++++++++++++++++++++++++++++-
 14 files changed, 60 insertions(+), 231 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All these theories, diverse as they are, have two things  in  common:
they explain the observed facts, and they are completeley and utterly
wrong.                       - Terry Pratchett, _The Light Fantastic_
#3 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

On Mon, 15 Dec 2008, Wolfgang Denk wrote:

Are you going to implement support for multiple I2C busses on some boards? I'm working on something like this now so it would be nice to coordinate our efforts somehow...

There is a provision for using 2 I2C busses in fsl-i2c.c now but I'm trying to make it more uniform to allow for different controllers on the same board. I have the first prototype of our MPC8548E based motherboard in PCB fab right now and I do have 3 I2C busses on it all of which are required for U-Boot. That is 2 busses off of 2 MPC8548E I2C controllers and the third one off of Silicon Motion SM502 MFD.

I have SM502 I2C driver written but not tested (no real hardware to test it on yet, will be ready in something like a month) but the entire multibus multicontroller I2C framework is not in U-Boot yet.

Are you working on something like this or just on moving i2c_reg_read() and i2c_reg_write() functions to inlines?

Quoted 43 lines

Dear Timur Tabi,

In message <[email protected]> you

Quoted 1 line · wrote:

All implementations of the functions i2c_reg_read() and

i2c_reg_write() are

Quoted 1 line

identical. We can save space and simplify the code by converting

these

Quoted 8 lines

functions into inlines and putting them in i2c.h.

---

v3: add 8xx-specific code, and include PRINTDs from blackfin and pxa

I'm posting this patch because I'm enhancing the I2C routines to

support

Quoted 1 line

multiple I2C busses more easily, but I need to clean up the existing

code

Quoted 3 lines

first.

I'm going to be on vacation when the next merge window opens, so I'm

posting

Quoted 1 line

this now in the hopes that it will be picked up when the window does

open.

We've been discussing this long enough when the previous window was open, so ...

Quoted 6 lines
 cpu/arm920t/at91rm9200/i2c.c  |   14 ---------
 cpu/arm926ejs/davinci/i2c.c   |   17 -----------
 cpu/blackfin/i2c.c            |   16 ----------
 cpu/mpc512x/i2c.c             |   17 -----------
 cpu/mpc5xxx/i2c.c             |   16 ----------
 cpu/mpc8220/i2c.c             |   16 ----------
Quoted 8 lines
 cpu/mpc824x/drivers/i2c/i2c.c |   14 ---------
 cpu/mpc8260/i2c.c             |   16 ----------
 cpu/mpc8xx/i2c.c              |   33 ---------------------
 cpu/ppc4xx/i2c.c              |   20 -------------
 cpu/pxa/i2c.c                 |   15 ----------
 drivers/i2c/fsl_i2c.c         |   16 ----------
 drivers/i2c/soft_i2c.c        |   19 ------------
 include/i2c.h                 |   62
Quoted 21 lines

+++++++++++++++++++++++++++++++++++++++-

Quoted 1 line
 14 files changed, 60 insertions(+), 231 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

Signature · 10 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All these theories, diverse as they are, have two things  in  common:
they explain the observed facts, and they are completeley and utterly
wrong.                       - Terry Pratchett, _The Light Fantastic_
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

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

author
#4 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 5 lines · ksi at koi8.net wrote:

On Mon, 15 Dec 2008, Wolfgang Denk wrote:

Are you going to implement support for multiple I2C busses on some boards? I'm working on something like this now so it would be nice to coordinate our efforts somehow...

Yes, my goal is to add low-level i2c functions that take an i2c bus as a parameter. So instead of

	i2c_set_bus_num(1);
	i2c_read(...);

you can do

	i2c_read(1, ...)

or something like that. My goal is to eliminate i2c_set_bus_num() and everything related to it.

It sounds like we're working on something very similar. This is very low-priority for me, though.

Signature · 2 lines
Timur Tabi
Linux kernel developer at Freescale
#5 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 17 lines · Timur Tabi
Quoted 3 lines · ksi at koi8.net wrote:

On Mon, 15 Dec 2008, Wolfgang Denk wrote:

Are you going to implement support for multiple I2C busses on some

boards?

Quoted 1 line

I'm working on something like this now so it would be nice to

coordinate our

Quoted 1 line

efforts somehow...

Yes, my goal is to add low-level i2c functions that take an i2c bus as a parameter. So instead of

	i2c_set_bus_num(1);
	i2c_read(...);

you can do

Quoted 7 lines
	i2c_read(1, ...)

or something like that. My goal is to eliminate i2c_set_bus_num() and everything related to it.

It sounds like we're working on something very similar. This is very low-priority for me, though.

That looks similar. But why do you want to remove i2c_set_bus_num()? I think it would be less work to keep it. This way you can leave 90% or so of existing I2C code unchanged by setting bus number to 0 at init. In your case you will have to find each and every call to i2c_read... and change it to the new format that includes bus number in parameters list.

My idea is to have global bus number variable in a single place and a single i2c_set_bus_num() that can be excluded for most boards with a single bus with #ifdef...

Then, we could use some kind of array of I2C structures each containing pointers to appropriate i2c-{read,write,probe,init}() functions with generic i2c functions just calling those pointers using bus number as index into that array.

That would allow for unlimited number of different adapters for any board. Initial code for initializing such an array would have to go into each and every $(BOARD).c board specific file.

We could even make some default #ifdef'd structure that would've included automagically if something like CONFIG_I2C_MULTIBUS was not defined thus making most of the boards (actually almost all of them) work without modifications.

Please let me know what you think...

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

author
#6 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 2 lines · ksi at koi8.net wrote:

That looks similar. But why do you want to remove i2c_set_bus_num()? I think it would be less work to keep it.

Perhaps, but it would be even better to get rid of it. IMHO, it's a kludge. It was a hack added to allow existing I2C routines to function while adding minimal support for multiple buses on those platforms that needed it.

Quoted 2 lines

This way you can leave 90% or so of
existing I2C code unchanged by setting bus number to 0 at init.

I only intend on exporting the multiple-bus versions of the I2C function if CONFIG_I2C_MULTI_BUS is defined.

Quoted 3 lines

My idea is to have global bus number variable in a single place and a single i2c_set_bus_num() that can be excluded for most boards with a single bus with #ifdef...

We already have something like that. A global variable is inconvenient because every time you want to access the bus, you need to do something like this:

	bus = i2c_get_bus_num();
	i2c_set_bus_num(x);
	i2c_write(...)
	i2c_set_bus_num(bus);

We need to save/restore the current bus number, because the I2C command-line has the concept of a

Quoted 4 lines

Then, we could use some kind of array of I2C structures each containing pointers to appropriate i2c-{read,write,probe,init}() functions with generic i2c functions just calling those pointers using bus number as index into that array.

Sounds complicated.

Quoted 1 line

That would allow for unlimited number of different adapters for any board.

Ah, now this is something else entirely. I don't think U-boot supports this at all. I think you're being too ambitious. It's a noble idea, and I think U-boot should support it, but I think we need to simplify the support for multiple buses first.

Quoted 2 lines

Initial code for initializing such an array would have to go into each and every $(BOARD).c board specific file.

Ugh.

Signature · 2 lines
Timur Tabi
Linux kernel developer at Freescale
#7 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 11 lines · Timur Tabi
Quoted 1 line · ksi at koi8.net wrote:

That looks similar. But why do you want to remove i2c_set_bus_num()? I

think

Quoted 1 line

it would be less work to keep it.

Perhaps, but it would be even better to get rid of it. IMHO, it's a kludge. It
was a hack added to allow existing I2C routines to function while adding minimal
support for multiple buses on those platforms that needed it.

I have nothing against changing parameters list for i2c_read/write(), it's just more work and less elegant.

Quoted 6 lines
Quoted 2 lines

This way you can leave 90% or so of
existing I2C code unchanged by setting bus number to 0 at init.

I only intend on exporting the multiple-bus versions of the I2C function if
CONFIG_I2C_MULTI_BUS is defined.

That looks messy... Why would we use two different versions if we can make everything uniform?

Quoted 11 lines
Quoted 1 line

My idea is to have global bus number variable in a single place and a

single

Quoted 1 line

i2c_set_bus_num() that can be excluded for most boards with a single

bus

Quoted 1 line

with #ifdef...

We already have something like that. A global variable is inconvenient because
every time you want to access the bus, you need to do something like this:

Quoted 8 lines
	bus = i2c_get_bus_num();
	i2c_set_bus_num(x);
	i2c_write(...)
	i2c_set_bus_num(bus);

We need to save/restore the current bus number, because the I2C command-line has
the concept of a

Eh, you can just set bus number every time you're gonna do i2c read/write... That i2c_get_bus_num() doesn't make any sence at all. Just set bus number every time you access i2c device. U-boot is single-task so there is no other process that can change it from under you and you do not save anything with checking that bus number. I can't see any practical use for i2c_get_bus_num() except for showing it with an interactive command. That is, in turn, is also redundant -- one would not save any keystrokes by typing something like "i2c bus" and not typing "i2c bus X" if that X is what he wants. Just type the second command every time when in doubt and you won't have to type the first one :)

Also, for all boards with a single I2C bus we can assume bus=0 so there is no need for bus-related functions/commands at all...

Quoted 9 lines
Quoted 1 line

Then, we could use some kind of array of I2C structures each

containing

Quoted 1 line

pointers to appropriate i2c-{read,write,probe,init}() functions with

generic

Quoted 1 line

i2c functions just calling those pointers using bus number as index

into

Quoted 1 line

that array.

Sounds complicated.

What is complicated? It is something like 3-4 lines of code per I2C bus. Look how e.g. NAND subsystem is initialized...

And, BTW, this initialization can even go into include/configs/$(BOARD).h.

Quoted 10 lines
Quoted 1 line

That would allow for unlimited number of different adapters for any

board.

Ah, now this is something else entirely. I don't think U-boot supports this at
all. I think you're being too ambitious. It's a noble idea, and I think U-boot
should support it, but I think we need to simplify the support for multiple
buses first.

It ain't rocket science :) The reason why I'm doing this is exactly what you said -- U-boot does NOT support it at all. And I do really need this and I think I'm not the only one.

Quoted 5 lines
Quoted 1 line

Initial code for initializing such an array would have to go into each

and

Quoted 1 line

every $(BOARD).c board specific file.

Ugh.

Ah, that's not biggie. And I volunteer to do this and come up with patches.

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

author
#8 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 2 lines · ksi at koi8.net wrote:

That looks messy... Why would we use two different versions if we can make everything uniform?

Because we already have something that makes it uniform, and it's broken. The idea of having a "current i2c bus" that needs to be set before read/write operations can be performed is the broken part!

Quoted 1 line

Eh, you can just set bus number every time you're gonna do i2c read/write...

Not with the current i2c command line. We would need another global variable in the i2c command line code to store what IT thinks is the current bus.

Quoted 2 lines

That i2c_get_bus_num() doesn't make any sence at all. Just set bus number every time you access i2c device.

That's risky. Sooner or later, you will want to know what the current bus number is, at least for debugging or status purposes.

Quoted 3 lines

U-boot is single-task so there is no other
process that can change it from under you and you do not save anything with checking that bus number.

Sounds to me like you haven't really looked at the U-Boot code. There are plenty of places where one function does I2C operations, then calls another function that does its own.

I think all this boils down to one core disagreement we have: I think the idea of a "current" i2c bus is a bad one.

Signature · 2 lines
Timur Tabi
Linux kernel developer at Freescale
#9 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 11 lines · Timur Tabi
Quoted 1 line · ksi at koi8.net wrote:

That looks messy... Why would we use two different versions if we can

make

Quoted 1 line

everything uniform?

Because we already have something that makes it uniform, and it's broken. The
idea of having a "current i2c bus" that needs to be set before read/write
operations can be performed is the broken part!

Eh, we don't have any uniformity. That "uniformity" we do have is only for a trivial case of a single I2C bus. Everything else is a bunch of SoC specific hacks made differently fo different platforms. The fsl-i2c.c e.g. uses local bus number variable.

Quoted 6 lines
Quoted 1 line

Eh, you can just set bus number every time you're gonna do i2c

read/write...

Not with the current i2c command line. We would need another global variable in
the i2c command line code to store what IT thinks is the current bus.

That can be taken care of.

Quoted 7 lines
Quoted 1 line

That i2c_get_bus_num() doesn't make any sence at all. Just set bus

number

Quoted 1 line

every time you access i2c device.

That's risky. Sooner or later, you will want to know what the current bus
number is, at least for debugging or status purposes.

So what? Just use i2c_get_bus() for this... We can even add a string to i2c_func structure for textual representation.

Quoted 10 lines
Quoted 2 lines

U-boot is single-task so there is no other
process that can change it from under you and you do not save anything

with

Quoted 1 line

checking that bus number.

Sounds to me like you haven't really looked at the U-Boot code. There are
plenty of places where one function does I2C operations, then calls another
function that does its own.

So what? Does it make it multitasking? Can that another function preempt the first one and change bus number from under it?

Quoted 3 lines

I think all this boils down to one core disagreement we have: I think the idea
of a "current" i2c bus is a bad one.

I can see nothing wrong with that but I also have nothing against changing all i2c_{read,write,probe}() functions to take bus number as an argument.

I offered 4 possible scenarios and additional parameter to i2c functions was one of them. Wolfgang said that current bus approach looks better than others and I agree with him. But it is not rocket science to use an additional parameter either. The only thing is it MUST be consistent, i.e. we should NOT have 2 different sets of functions based on CONFIG_MULTIBUS or whatever. If we are to make this change ALL boards must be multibus with majority of them having bus count of 1.

Does anybody else have something to say on this? I'm going to write code so let's make some decision. I don't want this to end up as a company hack and making it properly affects a lot of U-boot...

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

#10 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 17 lines · ksi at koi8.net wrote:
Quoted 10 lines · Timur Tabi
Quoted 1 line · ksi at koi8.net wrote:

That looks messy... Why would we use two different versions if we can

make

Quoted 1 line

everything uniform?

Because we already have something that makes it uniform, and it's broken. The
idea of having a "current i2c bus" that needs to be set before read/write
operations can be performed is the broken part!

Eh, we don't have any uniformity. That "uniformity" we do have is only for a trivial case of a single I2C bus. Everything else is a bunch of SoC specific hacks made differently fo different platforms. The fsl-i2c.c e.g. uses local bus number variable.

[snip]

Quoted 15 lines
Quoted 3 lines

I think all this boils down to one core disagreement we have: I think the idea
of a "current" i2c bus is a bad one.

I can see nothing wrong with that but I also have nothing against changing all i2c_{read,write,probe}() functions to take bus number as an argument.

I offered 4 possible scenarios and additional parameter to i2c functions was one of them. Wolfgang said that current bus approach looks better than others and I agree with him. But it is not rocket science to use an additional parameter either. The only thing is it MUST be consistent, i.e. we should NOT have 2 different sets of functions based on CONFIG_MULTIBUS or whatever. If we are to make this change ALL boards must be multibus with majority of them having bus count of 1.

Quoted 3 lines

Does anybody else have something to say on this? I'm going to write code so let's make some decision. I don't want this to end up as a company hack and making it properly affects a lot of U-boot...

IMHO Sergey's approach is reasonable. It is pragmatic in that it builds on and improves the existing method. It only touches boards with multiple i2c buses.

The best is the enemy of the good. - Voltaire
<http://www.bartleby.com/66/2/63002.html>

My two cents,
gvb

#11 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

In reply to ksi at koi8.net

Dear ksi at koi8.net,

Quoted 4 lines · In message <[email protected]> you wrote:

I offered 4 possible scenarios and additional parameter to i2c functions was one of them. Wolfgang said that current bus approach looks better than others and I agree with him. But it is not rocket science to use an

You and me agree on this.

Quoted 2 lines

additional parameter either. The only thing is it MUST be consistent, i.e. we should NOT have 2 different sets of functions based on CONFIG_MULTIBUS or

We agree on this, too.

Quoted 2 lines

whatever. If we are to make this change ALL boards must be multibus with majority of them having bus count of 1.

I don't think this makes sense - it would just add complexity and memory footprint without added benefit.

Quoted 3 lines

Does anybody else have something to say on this? I'm going to write code so let's make some decision. I don't want this to end up as a company hack and making it properly affects a lot of U-boot...

I support your position, not Timur's.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
We fight only when there is no other choice. We prefer  the  ways  of
peaceful contact.
	-- Kirk, "Spectre of the Gun", stardate 4385.3
#12 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 26 lines · Wolfgang Denk

Dear ksi at koi8.net,

In message <[email protected]> you

Quoted 2 lines · wrote:

I offered 4 possible scenarios and additional parameter to i2c

functions was

Quoted 2 lines

one of them. Wolfgang said that current bus approach looks better than others and I agree with him. But it is not rocket science to use an

You and me agree on this.

Quoted 1 line

additional parameter either. The only thing is it MUST be consistent,

i.e.

Quoted 1 line

we should NOT have 2 different sets of functions based on

CONFIG_MULTIBUS or

We agree on this, too.

Quoted 1 line

whatever. If we are to make this change ALL boards must be multibus

with

Quoted 1 line

majority of them having bus count of 1.

I don't think this makes sense - it would just add complexity and memory footprint without added benefit.

Quoted 7 lines
Quoted 1 line

Does anybody else have something to say on this? I'm going to write

code so

Quoted 1 line

let's make some decision. I don't want this to end up as a company

hack and

Quoted 1 line

making it properly affects a lot of U-boot...

I support your position, not Timur's.

OK, so I'm on it. It might take a couple of weeks for patches to show up.

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

#13 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

In reply to Timur Tabi

Dear Timur,

Quoted 8 lines · In message <[email protected]> you wrote:
Quoted 2 lines · ksi at koi8.net wrote:

That looks messy... Why would we use two different versions if we can make everything uniform?

Because we already have something that makes it uniform, and it's broken. The idea of having a "current i2c bus" that needs to be set before read/write operations can be performed is the broken part!

Hm... what exactly is broken with the concept of having a "current device" or a "current bus"? We use it elasewhere, too (like for selection IDE or S-ATA devices and such), and so far I am not aware of fundamental issues because of that.

You sound as if we were designing a system where tens of independend users could log in simultaneously and concurrently access different devices on different busses.

But this is NOT the case. We're strictly single user, single threaded, and when one command is runnign we are certain that there cannot be any interference from other I2C accesses.

Quoted 4 lines
Quoted 1 line

Eh, you can just set bus number every time you're gonna do i2c read/write...

Not with the current i2c command line. We would need another global variable in the i2c command line code to store what IT thinks is the current bus.

Not really. It is really sufficient to set the bus for each command. There is no need to save and restore any previous state, because accesses cannot be nested because of the way how U-Boot is designed.

Quoted 5 lines
Quoted 2 lines

That i2c_get_bus_num() doesn't make any sence at all. Just set bus number every time you access i2c device.

That's risky. Sooner or later, you will want to know what the current bus number is, at least for debugging or status purposes.

The design has been discussed before, and I see little reason why we should not throw all this away and come up with something new, more complicated.

Quoted 3 lines

Sounds to me like you haven't really looked at the U-Boot code. There are plenty of places where one function does I2C operations, then calls another function that does its own.

Really? Where exactly does such a thing happen?

I tend to call this a bug that needs to be fixed, if there is ssuch code.

Quoted 2 lines

I think all this boils down to one core disagreement we have: I think the idea of a "current" i2c bus is a bad one.

This statement is probably correct: I don't share your point of view here, either.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Be wiser than other people if you can, but do not tell them so.
                                       -- Philip Earl of Chesterfield
author
#14 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 4 lines · Wolfgang Denk

Hm... what exactly is broken with the concept of having a "current device" or a "current bus"? We use it elasewhere, too (like for selection IDE or S-ATA devices and such), and so far I am not aware of fundamental issues because of that.

I think it's a kludge because you have to set the current device before you can access it. It seems ridiculous that you have to do this:

	i2c_set_bus_num(x)
	i2c_write(...)

when you could do this:

	i2c_write(x, ...)
Quoted 5 lines
Quoted 3 lines

Sounds to me like you haven't really looked at the U-Boot code. There are plenty of places where one function does I2C operations, then calls another function that does its own.

Really? Where exactly does such a thing happen?

Well, I can't find a real example, but here's something close. Take a look at function pib_init() in mpc8568mds.c. This function needs to talk to the 2nd I2C bus. It has no idea who called it, so it has no idea what the current I2C bus is. Therefore, it has to save and restore it.

Now consider the code that calls pib_init(). Technically, this code cannot know that pib_init() does I2C operations. So it doesn't know that pib_init() could change the current I2C bus. So it wouldn't know to save and restore what it needs.

This situation could happen anywhere.

Quoted 2 lines

I tend to call this a bug that needs to be fixed, if there is ssuch code.

It's not a bug. Function X does I2C operations, and function Y also does I2C operations, but on a different device. If function X calls function Y, then Y needs to save and restore the current bus number. You will never get rid of this requirement as long as you have the concept of a current I2C bus number.

So you're still going to need i2c_get_bus_num() and i2c_set_bus_num(), and you're still going to have code like this:

	bus = i2c_get_bus_num();
	i2c_set_bus_num(x);
	i2c_write(...)
	i2c_set_bus_num(bus);
Quoted 2 lines

This statement is probably correct: I don't share your point of view here, either.

In that case, I have no interest in working on this new I2C design. You guys obviously have everything under control, so good luck.

Signature · 2 lines
Timur Tabi
Linux Kernel Developer @ Freescale
#15 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 11 lines · Timur Tabi
Quoted 4 lines · Wolfgang Denk

Hm... what exactly is broken with the concept of having a "current device" or a "current bus"? We use it elasewhere, too (like for selection IDE or S-ATA devices and such), and so far I am not aware of fundamental issues because of that.

I think it's a kludge because you have to set the current device before you
can access it. It seems ridiculous that you have to do this:

Quoted 6 lines
	i2c_set_bus_num(x)
	i2c_write(...)

when you could do this:

	i2c_write(x, ...)

Only if you have more than one I2C bus that 95% of supported boards don't have (95% is a wild guess; in reality, methinks, it is even closer to 99%.) That means you should only do this for less than 5% of existing boards.

Adding a parameter would require you to make changes for 100% of boards.

common/cmd_i2c.c is a single file, common for all platforms so it is a special case.

Quoted 23 lines
Quoted 1 line
Quoted 1 line

Sounds to me like you haven't really looked at the U-Boot code.

There are

Quoted 5 lines
Quoted 3 lines

plenty of places where one function does I2C operations, then calls another
function that does its own.

Really? Where exactly does such a thing happen?

Well, I can't find a real example, but here's something close. Take a look
at function pib_init() in mpc8568mds.c. This function needs to talk to the
2nd I2C bus. It has no idea who called it, so it has no idea what the current I2C bus is. Therefore, it has to save and restore it.

Now consider the code that calls pib_init(). Technically, this code cannot
know that pib_init() does I2C operations. So it doesn't know that pib_init()
could change the current I2C bus. So it wouldn't know to save and restore
what it needs.

Quoted 1 line

This situation could happen anywhere.

No, that is not an issue. That pib_init() does not happen out of a blue, it is YOU who call it in $(BOARD).c file so you MUST know what you are doing.

Quoted 21 lines
Quoted 2 lines

I tend to call this a bug that needs to be fixed, if there is ssuch code.

It's not a bug. Function X does I2C operations, and function Y also does I2C
operations, but on a different device. If function X calls function Y, then
Y needs to save and restore the current bus number. You will never get rid
of this requirement as long as you have the concept of a current I2C bus number.

So you're still going to need i2c_get_bus_num() and i2c_set_bus_num(), and
you're still going to have code like this:

	bus = i2c_get_bus_num();
	i2c_set_bus_num(x);
	i2c_write(...)
	i2c_set_bus_num(bus);
Quoted 11 lines
Quoted 2 lines

This statement is probably correct: I don't share your point of view here, either.

In that case, I have no interest in working on this new I2C design. You guys
obviously have everything under control, so good luck.

Signature · 2 lines
Timur Tabi
Linux Kernel Developer @ Freescale

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

#16 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

In reply to Timur Tabi

Dear Timur,

Quoted 10 lines · In message <[email protected]> you wrote:

I think it's a kludge because you have to set the current device before you can access it. It seems ridiculous that you have to do this:

	i2c_set_bus_num(x)
	i2c_write(...)

when you could do this:

	i2c_write(x, ...)

That's your argument. The other side's argument is that it's overhead (note that I do not use such a strong term as "ridiculous" as you did) to add a bus number argument to each and every board, where only a tiny fraction of them will ever have mnore than one I2C bus used.

So there is arguments bor both implementations, and it was decided to implement the first approach.

We've been trhough this before, it makes little sense that yous tir this up again.

Quoted 6 lines
Quoted 1 line

Really? Where exactly does such a thing happen?

Well, I can't find a real example, but here's something close. Take a look at function pib_init() in mpc8568mds.c. This function needs to talk to the 2nd I2C bus. It has no idea who called it, so it has no idea what the current I2C bus is. Therefore, it has to save and restore it.

IUt has to set it, yes. But there is no need to restore it, because there are no nested I2C calls.

Quoted 1 line

This situation could happen anywhere.

It could, if you intentionally create such a case. In real life, it never happens. Or can trivially be avoided.

Quoted 4 lines

It's not a bug. Function X does I2C operations, and function Y also does I2C operations, but on a different device. If function X calls function Y, then Y needs to save and restore the current bus number. You will never get rid of this requirement as long as you have the concept of a current I2C bus number.

There are no examples for such code. And I cannot see where it would be necessary.

Quoted 7 lines

So you're still going to need i2c_get_bus_num() and i2c_set_bus_num(), and you're still going to have code like this:

	bus = i2c_get_bus_num();
	i2c_set_bus_num(x);
	i2c_write(...)
	i2c_set_bus_num(bus);

Nope. This is not necessary.

I repeat: there are no nested I2C calls.

That's full in line with the design philosophy that we are strictly single tasking. There are no multiple tasks using the same driver or bus.

Quoted 2 lines

In that case, I have no interest in working on this new I2C design. You guys obviously have everything under control, so good luck.

C'me on. Don't act like a prima donna.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Life sucks, but it's better than the alternative."
- Peter da Silva
#17 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

In reply to ksi at koi8.net
Quoted 4 lines · On Mon, Dec 15, 2008 at 04:24:26PM -0800, ksi at koi8.net wrote:

Then, we could use some kind of array of I2C structures each containing pointers to appropriate i2c-{read,write,probe,init}() functions with generic i2c functions just calling those pointers using bus number as index into that array.

Why not just pass a pointer to the i2c device, rather than an index?

-Scott

#18 lore raw

PATCH v3 1/1 i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions

Quoted 10 lines · Scott Wood
Quoted 1 line · On Mon, Dec 15, 2008 at 04:24:26PM -0800, ksi at koi8.net wrote:

Then, we could use some kind of array of I2C structures each

containing

Quoted 1 line

pointers to appropriate i2c-{read,write,probe,init}() functions with

generic

Quoted 1 line

i2c functions just calling those pointers using bus number as index

into

Quoted 1 line

that array.

Why not just pass a pointer to the i2c device, rather than an index?

Because it is easier to change bus with i2c_set_bus() function and then use regular i2c_{read,write,probe}() functions. We are NOT passing anything. One global variable, bus_num or so, that is changed with i2c_set_bus() is used as an index for any i2c_{read,write,probe}() function. Those functions are just one line inlines calling appropriate pointers in i2c_func[bus_num] area. This way one can still use regular e.g. i2c_write() that translates to i2c_func[bus_num].i2c_write.

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