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.