最近碰到实际应用案例中有通过module_i2c_driver 注册实际i2c 设备驱动,再通过struct i2c_driver的.id_table 成员指向的struct i2c_device_id 对象表格来实现 i2c_client的最终被probe;
还有一类是直接通过 i2c_new_client_device 使用板上信息struct i2c_board_info 实例来创建i2c_client的。
但是这类创建出来的设备再应用层使用的时候,出现通信数据不对的情形。为了更好的梳理这两类访问方法的过程,将源码实现做个具体的解读。
参考
https://blog.csdn.net/m0_59249795/article/details/123902869
https://blog.csdn.net/li_wen01/category_6277839.html
在前面的platform device和platform driver初始化中,我们已经实现了I2C总线驱动(adapter),但是我们的设备驱动还没有实现。如果我们现在要访问I2C设备(比如eeprom),我知道的有三总方法:
(一)i2c-dev操作I2C设备:不用添加设备驱动,用户直接在应用层完成对具体I2C 设备的驱动工作。
(二)sysfs操作I2C设备:需添加设备驱动,通过sys展示出来的文件操作设备(比如/sys/devices/platform/s3c2440-i2c/i2c-0/0-0050/eeprom)
(三)设备节点操作i2C设备:添加设备驱动,为设备驱动创建设备节点,从/dev访问I2C设备(比如/dev/eeprom)
一、
通过创建设备树节点,设备树节点和i2c 设备保持相同的命名。
在module_i2c_driver 注册实际i2c 设备驱动,实现probe的调用实现关系如下
1)module_i2c_driver
950 #define module_i2c_driver(__i2c_driver) \
951 module_driver(__i2c_driver, **i2c_add_driver, \**
952 i2c_del_driver)
882 #define i2c_add_driver(driver) \
**883 i2c_register_driver(THIS_MODULE, driver)**
- i2c_register_driver
1846 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
1847 {
1848 int res;
1849
1850 /* Can't register until after driver model init */
1851 if (WARN_ON(!is_registered))
1852 return -EAGAIN;
1853
1854 /* add the driver to the list of i2c drivers in the driver core */
1855 driver->driver.owner = owner;
1856 driver->driver.bus = &i2c_bus_type;
**1857 INIT_LIST_HEAD(&driver->clients);**
1858
1859 /* When registration returns, the driver core
1860 * will have called probe() for all matching-but-unbound devices.
1861 */
1862 res = driver_register(&driver->driver);
1863 if (res)
1864 return res;
1865
1866 pr_debug("driver [%s] registered\n", driver->driver.name);
1867
1868 /* Walk the adapters that are already present */
**1869 i2c_for_each_dev(driver, __process_new_driver);**
1870
1871 return 0;
1872 }
1873 EXPORT_SYMBOL(i2c_register_driver);
初始化总线驱动对应的clients 列表,1869 行 去实现具体的i2c 驱动的枚举加载
- i2c_for_each_dev __process_new_driver
1822 int i2c_for_each_dev(void *data, int (*fn)(struct device *dev, void *data))
1823 {
1824 int res;
1825
1826 mutex_lock(&core_lock);
1827 res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);
1828 mutex_unlock(&core_lock);
1829
1830 return res;
1831 }
1832 EXPORT_SYMBOL_GPL(i2c_for_each_dev);
1833
1834 static int __process_new_driver(struct device *dev, void *data)
1835 {
1836 if (dev->type != &i2c_adapter_type)
1837 return 0;
**1838 return i2c_do_add_adapter(data, to_i2c_adapter(dev));**
1839 }
to_i2c_adapter(dev) 实现常规设备描述对struct i2c_adapter的转换。
- i2c_do_add_adapter
1335 static int i2c_do_add_adapter(struct i2c_driver *driver,
1336 struct i2c_adapter *adap)
1337 {
1338 /* Detect supported devices on that bus, and instantiate them */
**1339 i2c_detect(adap, driver);**
1340
1341 return 0;
1342 }
- i2c_detect
2348 static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
2349 {
2350 const unsigned short *address_list;
2351 struct i2c_client *temp_client;
2352 int i, err = 0;
2353
2354 address_list = driver->address_list;
**2355 if (!driver->detect || !address_list)**
2356 return 0;
2357
2358 /* Warn that the adapter lost class based instantiation */
2359 if (adapter->class == I2C_CLASS_DEPRECATED) {
2360 dev_dbg(&adapter->dev,
2361 "This adapter dropped support for I2C classes and won't auto-detect %s devices anymore. "
2362 "If you need it, check 'Documentation/i2c/instantiating-devices.rst' for alternatives.\n",
2363 driver->driver.name);
2364 return 0;
2365 }
2366
2367 /* Stop here if the classes do not match */
2368 if (!(adapter->class & driver->class))
2369 return 0;
2370
2371 /* Set up a temporary client to help detect callback */
2372 temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
2373 if (!temp_client)
2374 return -ENOMEM;
2375 temp_client->adapter = adapter;
2376
2377 for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
2378 dev_dbg(&adapter->dev,
2379 "found normal entry for adapter %d, addr 0x%02x\n",
2380 i2c_adapter_id(adapter), address_list[i]);
2381 temp_client->addr = address_list[i];
2382 **err = i2c_detect_address(temp_client, driver);**
2383 if (unlikely(err))
2384 break;
2385 }
2386
2387 kfree(temp_client);
2388 return err;
2389 }
如果驱动的detect 操作有实现,且地址列表不为空。创建一个临时的temp_client,从驱动的address_list[i]取出对应总线设备地址,通过i2c_detect_address去总线确认
- i2c_detect_address
2286 static int i2c_detect_address(struct i2c_client *temp_client,
2287 struct i2c_driver *driver)
2288 {
2289 struct i2c_board_info info;
2290 struct i2c_adapter *adapter = temp_client->adapter;
2291 int addr = temp_client->addr;
2292 int err;
2293
2294 /* Make sure the address is valid */
2295 err = i2c_check_7bit_addr_validity_strict(addr);
2296 if (err) {
2297 dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
2298 addr);
2299 return err;
2300 }
2301
2302 /* Skip if already in use (7 bit, no need to encode flags) */
2303 if (i2c_check_addr_busy(adapter, addr))
2304 return 0;
2305
2306 /* Make sure there is something at this address */
2307 if (!i2c_default_probe(adapter, addr))
2308 return 0;
2309
2310 /* Finally call the custom detection function */
2311 memset(&info, 0, sizeof(struct i2c_board_info));
2312 info.addr = addr;
2313 **err = driver->detect(temp_client, &info);**
2314 if (err) {
2315 /* -ENODEV is returned if the detection fails. We catch it
2316 here as this isn't an error. */
2317 return err == -ENODEV ? 0 : err;
2318 }
2319
2320 /* Consistency check */
2321 if (info.type[0] == '\0') {
2322 dev_err(&adapter->dev,
2323 "%s detection function provided no name for 0x%x\n",
2324 driver->driver.name, addr);
2325 } else {
2326 struct i2c_client *client;
2327
2328 /* Detection succeeded, instantiate the device */
2329 if (adapter->class & I2C_CLASS_DEPRECATED)
2330 dev_warn(&adapter->dev,
2331 "This adapter will soon drop class based instantiation of devices. "
2332 "Please make sure client 0x%02x gets instantiated by other means. "
2333 "Check 'Documentation/i2c/instantiating-devices.rst' for details.\n",
2334 info.addr);
2335
2336 dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
2337 info.type, info.addr);
**2338 client = i2c_new_client_device(adapter, &info);**
2339 if (!IS_ERR(client))
**2340 list_add_tail(&client->detected, &driver->clients);**
2341 else
2342 dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
2343 info.type, info.addr);
2344 }
2345 return 0;
2346 }
这里去正式的i2c_client确认和添加。
i2c_driver驱动实例中 如果没有实现detect 操作,只能通过总线的i2c_device_match 来扫描加载设备, i2c_device_probe来加载设备,通过driver->probe的传入 clients来最终添加设备。
实现关系如下
677 struct bus_type i2c_bus_type = {
678 .name = "i2c",
679 .match = i2c_device_match,
680 .probe = i2c_device_probe,
681 .remove = i2c_device_remove,
682 .shutdown = i2c_device_shutdown,
683 };
684 EXPORT_SYMBOL_GPL(i2c_bus_type);
101 const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
102 const struct i2c_client *client)
103 {
104 if (!(id && client))
105 return NULL;
106
107 while (id->name[0]) {
108 if (strcmp(client->name, id->name) == 0)
109 return id;
110 id++;
111 }
112 return NULL;
113 }
114 EXPORT_SYMBOL_GPL(i2c_match_id);
115
116 static int i2c_device_match(struct device *dev, struct device_driver *drv)
117 {
118 struct i2c_client *client = i2c_verify_client(dev);
119 struct i2c_driver *driver;
120
121
122 /* Attempt an OF style match */
123 if (i2c_of_match_device(drv->of_match_table, client))
124 return 1;
125
126 /* Then ACPI style match */
127 if (acpi_driver_match_device(dev, drv))
128 return 1;
129
130 driver = to_i2c_driver(drv);
131
132 /* Finally an I2C match */
133 if (i2c_match_id(driver->id_table, client))
134 return 1;
135
136 return 0;
137 }
466 static int i2c_device_probe(struct device *dev)
467 {
468 struct i2c_client *client = i2c_verify_client(dev);
469 struct i2c_driver *driver;
470 bool do_power_on;
471 int status;
472
473 if (!client)
474 return 0;
475
476 client->irq = client->init_irq;
477
478 if (!client->irq) {
479 int irq = -ENOENT;
480
481 if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
482 dev_dbg(dev, "Using Host Notify IRQ\n");
483 /* Keep adapter active when Host Notify is required */
484 pm_runtime_get_sync(&client->adapter->dev);
485 irq = i2c_smbus_host_notify_to_irq(client);
486 } else if (dev->of_node) {
487 irq = of_irq_get_byname(dev->of_node, "irq");
488 if (irq == -EINVAL || irq == -ENODATA)
489 irq = of_irq_get(dev->of_node, 0);
490 } else if (ACPI_COMPANION(dev)) {
491 bool wake_capable;
492
493 irq = i2c_acpi_get_irq(client, &wake_capable);
494 if (irq > 0 && wake_capable)
495 client->flags |= I2C_CLIENT_WAKE;
496 }
497 if (irq == -EPROBE_DEFER) {
498 status = irq;
499 goto put_sync_adapter;
500 }
501
502 if (irq < 0)
503 irq = 0;
504
505 client->irq = irq;
506 }
507
508 **driver = to_i2c_driver(dev->driver);**
509
510 /*
511 * An I2C ID table is not mandatory, if and only if, a suitable OF
512 * or ACPI ID table is supplied for the probing device.
513 */
514 if (!driver->id_table &&
515 !acpi_driver_match_device(dev, dev->driver) &&
516 !i2c_of_match_device(dev->driver->of_match_table, client)) {
517 status = -ENODEV;
518 goto put_sync_adapter;
519 }
520
521 if (client->flags & I2C_CLIENT_WAKE) {
522 int wakeirq;
523
524 wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
525 if (wakeirq == -EPROBE_DEFER) {
526 status = wakeirq;
527 goto put_sync_adapter;
528 }
529
530 device_init_wakeup(&client->dev, true);
531
532 if (wakeirq > 0 && wakeirq != client->irq)
533 status = dev_pm_set_dedicated_wake_irq(dev, wakeirq);
534 else if (client->irq > 0)
535 status = dev_pm_set_wake_irq(dev, client->irq);
536 else
537 status = 0;
538
539 if (status)
540 dev_warn(&client->dev, "failed to set up wakeup irq\n");
541 }
542
543 dev_dbg(dev, "probe\n");
544
545 status = of_clk_set_defaults(dev->of_node, false);
546 if (status < 0)
547 goto err_clear_wakeup_irq;
548
549 do_power_on = !i2c_acpi_waive_d0_probe(dev);
550 status = dev_pm_domain_attach(&client->dev, do_power_on);
551 if (status)
552 goto err_clear_wakeup_irq;
553
554 client->devres_group_id = devres_open_group(&client->dev, NULL,
555 GFP_KERNEL);
556 if (!client->devres_group_id) {
557 status = -ENOMEM;
558 goto err_detach_pm_domain;
559 }
560
561 /*
562 * When there are no more users of probe(),
563 * rename probe_new to probe.
564 */
565 if (driver->probe_new)
566 status = driver->probe_new(client);
567 else if (driver->probe)
**568 status = driver->probe(client,
569 i2c_match_id(driver->id_table, client));**
570 else
571 status = -EINVAL;
572
573 /*
574 * Note that we are not closing the devres group opened above so
575 * even resources that were attached to the device after probe is
576 * run are released when i2c_device_remove() is executed. This is
577 * needed as some drivers would allocate additional resources,
578 * for example when updating firmware.
579 */
580
581 if (status)
582 goto err_release_driver_resources;
583
584 return 0;
585
586 err_release_driver_resources:
587 devres_release_group(&client->dev, client->devres_group_id);
588 err_detach_pm_domain:
589 dev_pm_domain_detach(&client->dev, do_power_on);
590 err_clear_wakeup_irq:
591 dev_pm_clear_wake_irq(&client->dev);
592 device_init_wakeup(&client->dev, false);
593 put_sync_adapter:
594 if (client->flags & I2C_CLIENT_HOST_NOTIFY)
595 pm_runtime_put_sync(&client->adapter->dev);
596
597 return status;
598 }
设备树创建和调用设备驱动的过程如下
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
struct device_node *node)
{
struct i2c_client *client;
struct i2c_board_info info;
int ret;
dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
ret = of_i2c_get_board_info(&adap->dev, node, &info);
if (ret)
return ERR_PTR(ret);
client = i2c_new_client_device(adap, &info);
if (IS_ERR(client))
dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
return client;
}
在of_i2c_register_device 函数中也是调用了i2c_new_client_device,实现板上信息对应的i2c_client创建, 而这个板上信息使用of_i2c_get_board_info(&adap->dev, node, &info); 从设备树的节点上获取。
void of_i2c_register_devices(struct i2c_adapter *adap)
{
struct device_node *bus, *node;
struct i2c_client *client;
/* Only register child devices if the adapter has a node pointer set */
if (!adap->dev.of_node)
return;
dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
if (!bus)
bus = of_node_get(adap->dev.of_node);
for_each_available_child_of_node(bus, node) {
if (of_node_test_and_set_flag(node, OF_POPULATED))
continue;
client = of_i2c_register_device(adap, node);
if (IS_ERR(client)) {
dev_err(&adap->dev,
"Failed to create I2C device for %pOF\n",
node);
of_node_clear_flag(node, OF_POPULATED);
}
}
of_node_put(bus);
}
of_i2c_register_device 被i2c_register_adapter调用,i2c_register_adapter 被 __i2c_add_numbered_adapter调用,最终实现了i2c_add_adapter 和i2c_add_numbered_adapter 这类master 设备的接口。
二、 i2c_new_client_device 过程
i2c_new_client_device 会创建struct i2c_client对象,同时会通过device_register 创建一个sysfs 设备树上的一个节点。而且是对应的adaptor 目录下面。
这个client 和 ”(一)i2c-dev操作I2C设备:不用添加设备驱动,用户直接在应用层完成对具体I2C 设备的驱动工作“ 生成的client 是不同的。
struct i2c_client *
i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
struct i2c_client *client;
int status;
client = kzalloc(sizeof *client, GFP_KERNEL);
if (!client)
return ERR_PTR(-ENOMEM);
client->adapter = adap;
client->dev.platform_data = info->platform_data;
client->flags = info->flags;
client->addr = info->addr;
client->init_irq = info->irq;
if (!client->init_irq)
client->init_irq = i2c_dev_irq_from_resources(info->resources,
info->num_resources);
strscpy(client->name, info->type, sizeof(client->name));
status = i2c_check_addr_validity(client->addr, client->flags);
if (status) {
dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",
client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
goto out_err_silent;
}
/* Check for address business */
status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
if (status)
goto out_err;
client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type;
client->dev.of_node = of_node_get(info->of_node);
client->dev.fwnode = info->fwnode;
device_enable_async_suspend(&client->dev);
i2c_dev_set_name(adap, client, info);
if (info->swnode) {
status = device_add_software_node(&client->dev, info->swnode);
if (status) {
dev_err(&adap->dev,
"Failed to add software node to client %s: %d\n",
client->name, status);
goto out_err_put_of_node;
}
}
status = device_register(&client->dev);
if (status)
goto out_remove_swnode;
dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
client->name, dev_name(&client->dev));
return client;
out_remove_swnode:
device_remove_software_node(&client->dev);
out_err_put_of_node:
of_node_put(info->of_node);
out_err:
dev_err(&adap->dev,
"Failed to register i2c client %s at 0x%02x (%d)\n",
client->name, client->addr, status);
out_err_silent:
kfree(client);
return ERR_PTR(status);
}
EXPORT_SYMBOL_GPL(i2c_new_client_device);