i2c设备驱动分析-At24(kernel-3.17)

来源:互联网 发布:webservice java 编辑:程序博客网 时间:2024/04/28 17:56

这篇文章是学习At24.c驱动的记录:


1.首先定义i2c_driver结构体:

static struct i2c_driver at24_driver = {.driver = {.name = "at24",.owner = THIS_MODULE,},.probe = at24_probe,.remove = at24_remove,.id_table = at24_ids,};

对id_table成员的说明:at24_ids定义如下:

static const struct i2c_device_id at24_ids[] = {/* needs 8 addresses as A0-A2 are ignored */{ "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },/* old variants can't be handled with this generic entry! */{ "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },{ "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },/* spd is a 24c02 in memory DIMMs */{ "spd", AT24_DEVICE_MAGIC(2048 / 8,AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },{ "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },/* 24rf08 quirk is handled at i2c-core */{ "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },{ "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },{ "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },{ "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },{ "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },{ "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },{ "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },{ "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },{ "at24", 0 },{ /* END OF LIST */ }};


i2c_device_id表格在驱动程序中的做用是进行与设备的匹配,根据name进行对比:

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,const struct i2c_client *client){while (id->name[0]) {if (strcmp(client->name, id->name) == 0)return id;id++;}return NULL;}

2.at24驱动的初始化:

把at24_driver添加到i2c-bus总线中,函数如下:

static int __init at24_init(void){if (!io_limit) {pr_err("at24: io_limit must not be 0!\n");return -EINVAL;}io_limit = rounddown_pow_of_two(io_limit);return i2c_add_driver(&at24_driver);}
i2c_add_driver是个宏定义,会调用i2c_register_driver函数(i2c-core.c)进行注册;


3.At24驱动注册:

/* * An i2c_driver is used with one or more i2c_client (device) nodes to access * i2c slave chips, on a bus instance associated with some i2c_adapter. */int i2c_register_driver(struct module *owner, struct i2c_driver *driver){int res;/* Can't register until after driver model init */if (unlikely(WARN_ON(!i2c_bus_type.p)))return -EAGAIN;/* add the driver to the list of i2c drivers in the driver core */driver->driver.owner = owner;driver->driver.bus = &i2c_bus_type;/* When registration returns, the driver core * will have called probe() for all matching-but-unbound devices. */res = driver_register(&driver->driver);if (res)return res;/* Drivers should switch to dev_pm_ops instead. */if (driver->suspend)pr_warn("i2c-core: driver [%s] using legacy suspend method\n",driver->driver.name);if (driver->resume)pr_warn("i2c-core: driver [%s] using legacy resume method\n",driver->driver.name);pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);INIT_LIST_HEAD(&driver->clients);/* Walk the adapters that are already present */i2c_for_each_dev(driver, __process_new_driver);return 0;}

这个函数会调用driver_register进行驱动程序注册,如果成功,最终会调用i2c_device_probe(i2c-core.c)函数,最后会调用At24.c文件中的at24_probe函数,到这里,at24设备就已经加入到i2c-bus总线中。




0 0
原创粉丝点击