忘记了在哪本书上看到过,说必须给 I2C 设备驱动的 id 表数组添加上一个空元素作为最后一个元素,就像下面的代码所展示的那样:
- struct i2c_device_id {
- char name[I2C_NAME_SIZE];
- kernel_ulong_t driver_data; /* Data private to the driver */
- }
- static const struct i2c_device_id rt5677_i2c_id[] = {
- { "rt5677", 0 },
- { } // 末尾需要是一个空元素
- };
- struct i2c_driver rt5677_i2c_driver = {
- .driver = {
- .name = "rt5677",
- .owner = THIS_MODULE,
- #ifdef CONFIG_PM
- .pm = &rt5677_pm_ops,
- #endif
- #ifdef RTACPI_I2C
- .acpi_match_table = ACPI_PTR(rt5677_acpi_match),
- #endif
- },
- .probe = rt5677_i2c_probe,
- .remove = rt5677_i2c_remove,
- .shutdown = rt5677_i2c_shutdown,
- .id_table = rt5677_i2c_id, // 指定id_table
- };
- /**
- * hda_match - bind hda device to hda driver.
- * @dev: device.
- * @drv: driver.
- *
- */
- static int soc_hda_match(struct device *dev, struct device_driver *drv)
- {
- struct snd_soc_hda_device *pdev = to_soc_hda_device(dev);
- struct snd_soc_hda_driver *pdrv = to_soc_hda_driver(drv);
- /* Then try to match against the id table */
- if (pdrv->id_table)
- return soc_hda_match_id(pdrv->id_table, pdev) != NULL; // 传入 id_table 指针进行匹配
- /* fall-back to driver name match */
- return (strcmp(pdev->name, drv->name) == 0);
- }
- static const struct snd_soc_hda_device_id *soc_hda_match_id(
- const struct snd_soc_hda_device_id *id,
- struct snd_soc_hda_device *pdev)
- {
- while (id->name[0]) { // 如果 name 不为空,则执行下列匹配
- if (pdev->id == id->id) {
- pdev->id_entry = id;
- return id;
- } else if (strcmp(pdev->name, id->name) == 0) {
- pdev->id_entry = id;
- return id;
- }
- id++; // 继续处理 id_table 中的下一个元素
- }
- return NULL;
- }