[i2c] Identifying I2C busses

Jean Delvare khali at linux-fr.org
Wed Mar 7 21:17:23 CET 2007


Hi David,

On Tue, 6 Mar 2007 14:20:53 -0800, David Brownell wrote:
> On Tuesday 06 March 2007 6:53 am, Jean Delvare wrote:
> > * You mostly convinced me that your approach was correct. One thing
> > which worries me though: is there any other subsystem in the whole
> > Linux tree which works that way (mixing requested identification
> > numbers with dynamically assigned ones)? What makes I2C different?
> 
> SPI does it that way.  The board_info was essentially a clone of the
> mechanism used there ... although since it's so small, the SPI core
> is always statically linked.  That's not the best model for I2C, where
> the core is several times larger.  (And some folk even objected to
> that restriction for SPI ... not enough to supply a patch though!)

Yeah, now that I look at the spi core, I see the common parts with what
you proposed for i2c. I cannot find an equivalent of
__i2c_first_dynamic_bus_num though.

> At the time I did that SPI stuff I mentioned that I was looking for
> a model that would also work for I2C.  I suspect you didn't take
> that seriously at the time.  ;)

I suspect I didn't really have the time to look into SPI back then. I
was busy enough with I2C and hardware monitoring - and still am.

> I2C is not different in that respect:  neither serial bus supports
> a very useful level of autoconfiguration.  So both need a way to
> declare devices, including both "early" and "late" modes, etc.
> 
> 
> > * I'm very curious about how the stacked-board designs you mentioned
> > don't have problems with I2C address collisions if they work the way
> > you described.
> 
> They're designed to work together -- without collisions.  Stacking
> provides a lot of design, manufacturing and packaging flexibility.
> 
> Many of those CPU card designs seem to be geared, as I implied, to
> folk designing semicustom systems.  The skills involved in making a
> cpu card (6-8 layer PCB design, SMT manufacturing, board testing)
> are not the same as those involved in small runs of a custom I/O box
> to surround such a card.
> 
> (Related:  how do DRAM cards avoid collisions on their I2C EEPROMS?
> I'm guessing three pins in each slot get hooked up to the EEPROM
> address select pins, and they're wired on the baseboard so each slot
> has a unique number.  Similar approaches can work for other kinds
> of board stack, when an EEPROM is used to identify each card and
> maybe record factory-tested calibration data.)

You're right, 24C02 EEPROMs have 3 pins to select the address from 0x50
to 0x57 and each DRAM slot uses a different combination. Something
similar could work for your stack of cards, except that not all I2C
devices have a selectable address. And you may want to have more than
one chip of a kind on a given board. This is way more complex than DRAM
modules which are all the same I2C-bus-wise.

> > On a related topic, I am not fond of your "list of arrays of variable
> > size" approach to store the I2C device declarations. This seems to be
> > more complex than needed. Can't we simply go with a list of individual
> > records?
> 
> That could work.  I don't see much point to that change though...

Simplicity of the data structures.

> > Here's what I have in mind (beware, I changed the struct 
> > names):
> > 
> > struct i2c_device_info {
> > 	char		driver[KOBJ_NAME_LEN];
> > 	char		type[I2C_NAME_SIZE];
> > 	unsigned short	dev_addr;
> > 	void		*platform_data;
> > 	int		irq;
> > };
> > 
> > struct i2c_board_info {
> > 	struct list_head	list;
> > 	short			bus_num;
> > 	struct i2c_device_info	device_info;
> > };
> > 
> > And __i2c_board_list would be a list of struct i2c_board_info. This
> > should make your code somewhat more simple, at the price of additional
> > calls to i2c_register_board_info() and maybe some more memory
> > fragmentation, but I don't think this is a major problem. What do you
> > think?
> 
> I guess I still don't see a real advantage.  It hits the malloc heap more
> often at board init time; a handful of loop instructions move from scanning
> that list into setting it up.  If it bothers you deeply, I can change
> that to provide a list of singletons.

Now that we decided to move bus_num out of struct i2c_device_info, will
it make a big difference fragmentation-wise? I assumed not. I guess
that you'll have one or two I2C devices to declare on each card for
each bus, hardly more, right?

The code that sets the list up is __init anyway, if I followed your
explanations properly, so adding some more instructions there shouldn't
be worrisome.

So, yes, I believe that a list of singletons if prefered. If you really
care about memory fragmentation, then using a list wasn't the right
choice in the first place, and you want to switch to an array.

> > A different approach is one list per bus number, that would scale
> > better (no common pool), but that makes things a bit more complex
> > again, and as you underlined, we don't expect thousands of devices to
> > be declared anyway so scalability probably doesn't matter. I guess
> > real-world scenarii have a max of 2 I2C busses?
> 
> I've seen chips with three:  two lowspeed ones, and a highspeed one.
> Regardless of how they're factored, I personally have never happened
> across a production board with even a dozen I2C devices.

OK, not numbers were complexity matters.

> > * I am not happy with the idea of having one function named
> > i2c_add_adapter, and one named i2c_register_adapter (i.e. almost the
> > same name) doing something similar but different, without this
> > difference being visible in their name. We need to come up with
> > something better than that. Either we can have a single function, or we
> > need to rename i2c_register_adapter to something which expresses its
> > difference to i2c_add_adapter. i2c_add_numbered_adapter or something.
> 
> Your notion of using the device handle as the (relatively) stable
> bus ID would let there be only one function...

It's up to you, I'm not insisting. I _am_ fine with two functions, as
long as the name of the new one is meaningful.

> > * With regards to i2c-mainboard, wouldn't it be more simple to just
> > make it mandatory to build i2c-core into the kernel when you need the
> > early device declaration process? I seem to remember that this is a
> > common practice in the embedded world anyway, because you need I2C
> > early in the boot process.
> 
> Simpler ... yes.  It's common regardless of whether the board needs I2C
> early:  modular drivers cost more space than non-modular ones, and in any
> case one doesn't want the driver for a key system bus to be modular.
> But common doesn't mean universally desirable.
> 
> Also, I'm not sure that'd be a reasonable restriction.  It'd be no skin
> off my back, for sure, but I know some folk would object.  And how would
> you force static linkage of the i2c-core module in those cases?  It'd be
> tricky to guarantee "make allmodconfig" works on all the relevant boards...

Is there no Kconfig syntax to handle that case? Too bad :(

> So despite the minor mess, I don't see an easy way around that being
> a separate file.  Moving it out of i2c-core.c was a cleanup.  :)

This forces you to export some new symbols, and exports aren't free. I
wanted to avoid that. But if you see no other solution, so be it.

> > * Your implementation doesn't seem to support I2C bus number
> > reservation if there is no chip on that bus. Isn't it going to be
> > confusing? Don't we want a function in i2c-core that lets the platform
> > code explicitly bump __i2c_first_dynamic_bus_num, rather that deducing
> > it from the i2c devices definitions?
> 
> Good point, but a simpler fix is just to let i2c_register_boardinfo()
> do that bumping even when there are no devices to register.  That falls
> out easily from making the bus number be a parameter to that function
> rather than a member of the i2c_board_info structure.

I didn't expect people to call i2c_register_boardinfo() if there is no
device to register. But you can argue that they now have to and it's
their bug if they don't. So again, up to you.

Thanks,
-- 
Jean Delvare



More information about the i2c mailing list