i2c控制器驱动
先看i2c适配器注册kernel4.4/drivers/i2c/busses/i2c-sprd-v2.c
static const struct i2c_algorithm sprd_i2c_algo = {
.master_xfer = sprd_i2c_master_xfer, //i2c传输实现
.functionality = sprd_i2c_func,
};
static int sprd_i2c_probe(struct platform_device *pdev)
{
pi2c->adap.owner = THIS_MODULE;
pi2c->adap.retries = 3;
pi2c->adap.algo = &sprd_i2c_algo;
i2c_add_numbered_adapter(&pi2c->adap);
}
int i2c_add_numbered_adapter(struct i2c_adapter *adap)
{
return __i2c_add_numbered_adapter(adap);
}
static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
{
return i2c_register_adapter(adap);
}
static int i2c_register_adapter(struct i2c_adapter *adap)
{
of_i2c_register_devices(adap);
}
static void of_i2c_register_devices(struct i2c_adapter *adap)
{
for_each_available_child_of_node(adap->dev.of_node, node) {
of_i2c_register_device(adap, node);
}
}
将dts下挂在i2c总线下的设备注册到内核。
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
struct device_node *node)
{
i2c_new_device(adap, &info);
}
i2c设备驱动
#define i2c_add_driver(driver) \
i2c_register_driver(THIS_MODULE, driver)
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
res = driver_register(&driver->driver);
}
int driver_register(struct device_driver *drv)
{
ret = bus_add_driver(drv);
}
int bus_add_driver(struct device_driver *drv)
{
error = driver_attach(drv);
}
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
static int __driver_attach(struct device *dev, void *data)
{
driver_match_device(drv, dev))
driver_probe_device(drv, dev);
}
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
ret = really_probe(dev, drv);
}
static int really_probe(struct device *dev, struct device_driver *drv)
{
ret = dev->bus->probe(dev);
}
i2c总线注册
drivers/i2c/i2c-core.c
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
if (of_driver_match_device(dev, drv))//根据dts的compatible字段匹配,成功值是true
return 1;
}
static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
status = driver->probe(client, i2c_match_id(driver->id_table, client));
}
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
}
static int __init i2c_init(void)
{
retval = bus_register(&i2c_bus_type);
}
postcore_initcall(i2c_init);
整体流程图