Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is use of struct i2c_device_id if we are already using struct of_device_id?

I was trying to understand a codec driver code on Linux kernel 4.4. The codec is connected to sound card using i2c bus and the codec driver code is written as I2C client. Client's struct i2c_driver contains both i2c_device_id information and of_device_id information.

Now as per my understanding client's probe function will be called when compatible string of struct of_device_id matches with compatible string of device node information. Then what is the use of struct i2c_device_id?

NOTE: Codec driver is using device tree.

like image 218
aditya pratyay Avatar asked Mar 09 '23 23:03

aditya pratyay


2 Answers

Your i2c_device_id structure is referenced by the i2c_driver structure; the I²C framework uses it to find the driver that is to be attached to a specific I²C device. This is similar to how the of_device_id information is used to find the driver for a specific device described in the device tree.

As the driver writer, you do not really know how the codec will actually be enumerated later (I²C or OF), so you should provide both pieces of information.

When you are using MODULE_DEVICE_TABLE(), the values in the i2c_device_id structure are used to find the module to load. (This is unlikely to happen in an embedded system that has neither hotplugging nor modules, but if the codec is ever used in a modular system (e.g., for testing), the autoloading might not work.)
Furthermore, the information provided by MODULE_DEVICE_TABLE() can be used to determine which kernel configuration options are needed for some specific hardware.

like image 200
CL. Avatar answered Mar 12 '23 12:03

CL.


Say you have the following i2c driver structures:

static const struct i2c_device_id lm75_ids[] = {
        { "adt75", adt75, },
        { }
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);

static const struct of_device_id lm75_of_match[] = {
        { .compatible = "adi,adt75" },
        { },
};
MODULE_DEVICE_TABLE(of, lm75_of_match);

static struct i2c_driver lm75_driver = {
        .driver = {
                .name   = "lm75",
                .of_match_table = of_match_ptr(lm75_of_match),
        },
        .probe          = lm75_probe,
        .id_table       = lm75_ids,
};
module_i2c_driver(lm75_driver);

When an I2C device is instantiated via userland:

echo adt75 0x50 > /sys/bus/i2c/devices/i2c-3/new_device

The i2c-core matches the name "adt75" to the name in the struct i2c_device_id array, and it passes that element to lm75_probe.

When an I2C device is instantiated via OF device tree, its compatible property is matched (format: "manufacturer,model") and the "model" component is matched against the struct i2c_device_id array - which also passed that element to lm75_probe. Pretty neat!

struct of_device_id also has a .data property, which you can access via a different mechanism.

like image 42
tompreston Avatar answered Mar 12 '23 13:03

tompreston