[i2c] i2c device attached to a SoC bus
Jean Delvare
khali at linux-fr.org
Thu Jun 14 09:14:07 CEST 2007
On Wed, 13 Jun 2007 00:30:22 +0200, Jorge Luis Zapata Muga wrote:
> On 6/12/07, Jean Delvare <khali at linux-fr.org> wrote:
> > Admittedly, this isn't a case which is properly supported at the
> > moment. Multimedia chips are supposed to be on multimedia adapters, not
> > random I2C adapters.
> >
> > Getting a reference to the i2c_client is only one of your problems.
> > Once you have it, you'll need to send commands to it. The commands are
> > supposed to come through /dev/videoN, right? So you'll need some code
> > to register a video device and route the requests to the i2c_client.
> > The question is, where do you plan to put this code? In your i2c bus
> > driver? Or in another driver?
>
> That's the point, the i2c bus driver is a generic driver for this
> platform, but on a specific machine there might be different i2c
> devices attached to it. The logic idea would be to keep the generic
> i2c bus driver under i2c/busses/ and for a specific machine's i2c
> client adapter define it under the driver's class directory
> (media/video, sound, etc). Then would have the device class interface,
> and only redirect the commands to the i2c client. In my machine's case
> i would code a v4l driver under media/video, and route the v4l command
> to the i2c driver, the problem, as you have already noted, is where to
> place the i2c adapter code, because the i2c_client struct is a must.
> If i place it under my v4l device, then the code of the bus driver is
> duplicated.
Here is my suggestion:
* Add an i2c device class check to tvp5150_attach_adapter, so that this
driver only probes adapters with class I2C_CLASS_TV_ANALOG set. Your
own i2c adapter won't set this class, so this will prevent the tvp5150
driver from attaching to your device before you want it to happen.
* Add a new-style i2c_driver definition to tvp5150. Ideally you would
completely replace it with new-style, but given that there are other
users of this driver which expect it to be old-style, it's probably
better to just add what you need for now. In practice, this means
cloning this definition:
static struct i2c_driver driver = {
.driver = {
.name = "tvp5150",
},
.id = I2C_DRIVERID_TVP5150,
.attach_adapter = tvp5150_attach_adapter,
.detach_client = tvp5150_detach_client,
.command = tvp5150_command,
};
Except that the copy will define .probe and .remove instead
of .attach_adapter and .detach_client. The big difference is that
new-style i2c devices are not automatically instantiated when their
driver loads. Instead, you instantiate and delete devices on the bus as
needed. .probe should be similar to tvp5150_detect_client() except that
it doesn't create, fill and attach the i2c_client structure. .remove
shold be similar to tvp5150_detach_client except that it doesn't detach
the client.
* In your media/video driver, use i2c_get_adapter() to obtain a
reference to your i2c adapter. This requires that you know the i2c
adapter number, but given that this is a SoC, I guess you'll only have
one i2c bus, so it should be OK. Don't forget to also call
i2c_put_adapter() on driver unload, otherwise your i2c adapter driver
will be locked in memory forever.
* Once you have a reference to your i2c adapter, you can call
i2c_new_device() to instantiate your tvp5150 on it. This will call
the .probe function of your new-style tvp5150 driver _and_ give you a
reference to your i2c_client - exactly what you need. Then you can use
this reference to route the v4l commands. On driver unload, you'll call
i2c_unregister_device().
--
Jean Delvare
More information about the i2c
mailing list