[i2c] How to find an i2c_adapter in the system

Jean Delvare khali at linux-fr.org
Mon Nov 12 22:14:42 CET 2007

Hi Hendrik,

On Sat, 10 Nov 2007 11:17:50 +0100, Hendrik Sattler wrote:
> I have written a driver for the OZ99x chips that are connected via SMBus.
> I also used the new method (.probe/.remove).
> Like in the earlier postings about Fujitsu-Siemens laptops, there is an 
> additional module (fjkeyinf) that reads the BIOS information and instantiates 
> new devices from that information. It is supposed to be a reworked approach 
> of the apanel driver.

apanel driver which I think I reviewed back then, but that was never
merged upstream. Do you happen to know why?

> However, I face several problems doing so:
> 1.
> For i2c_new_device(), I need a struct i2c_adapter*. How do I enumerate the 
> adapters currently present?

You don't. Individual I2C chip drivers aren't supposed to deal with
this, only i2c-core has access to the list of adapters.

> I could use i2c_get_adapter in a counting loop but that has the strict 
> requirement that for every i >= 0 this function provides a valid non-NULL 
> pointer until all adapter are enumerated (no holes in the numbering).
> I am not sure that this is garanteed.

No, this isn't guaranteed. And as you can't lock the adapter list from
outside of i2c-core, there is also no guarantee that the list doesn't
change while you're walking. So just don't do that.

Anyway, if you really did that, how would you find out the I2C bus you
actually want? There is no reliable way to do that.

> 2.
> How do I tell the I2C framework that there is a device on a bus whose kernel 
> module is currently not loaded?

There are two possibilities. You can declare I2C devices at platform
level using i2c_register_board_info(), or you can call
i2c_new_device(). The former requires static i2c adapter numbers and is
primarily meant for embedded systems, but it could probably be extended
to support PC motherboards. The latter requires that you already have a
pointer to the i2c_adapter in question, and is primarily meant for
multimedia drivers.

> 3.
> How is a user supposed to specify a i2c address for a driver? SysFS somehow?

There is currently no way to do this with the new-style I2C framework.
It's on my to-do list. Anyway, end-users shouldn't have to do this,
this will be mainly intended for debugging and testing.

> I could use the legacy module but the new model has some advantages that allow 
> a easy decoupling of the two modules (see platform_data). Additionally, the 
> restriction on a specific bus comes from fkeyinf and shall not be the more 
> generic oz99x.

If you really want to write a new-style driver, you'll have to modify
the i2c-i801 driver in one of the following ways:

* Add code to the i2c-i801 driver that instantiate the oz99x device on
systems that are known to have one. That's a bit ugly, because if we go
down that route, virtually all PC-motherboard i2c bus drivers will end
up with board-specific code to instantiate a variety of I2C devices.
This promises to be very difficult to maintain (but would be easy to do
for testing purposes.)

* Declare the oz99x device in a struct i2c_board_info in platform code
(somewhere in arch/x86/kernel?) for systems that have this chip, and
have i2c-i801 register its bus using i2c_add_numbered_adapter(). This
is probably more viable in the long run.

Jean Delvare

More information about the i2c mailing list