Linux设备驱动剖析之IIC(一)

本文主要介绍了Linux IIC子系统的初始化过程,包括在i2c_init函数中的总线注册,以及设备和驱动的匹配机制。通过分析i2c_device_match函数和i2c_match_id函数,阐述了IIC设备如何根据名称与驱动匹配。此外,还探讨了S3c6410平台上IIC控制器驱动的初始化和probe函数,以及struct s3c24xx_i2c结构体的相关细节。
摘要由CSDN通过智能技术生成

写在前面

由于IIC总线只需要两根线就可以完成读写操作,而且通信协议简单,一条总线上可以挂载多个设备,因此被广泛使用。但是IIC总线有一个缺点,就是传输速率比较低。本文基于Linux-2.6.36版本,说说IIC子系统在Linux中的实现。

借用某书上的IIC子系统的体系结构图:

Linux IIC子系统体系结构

下面开始分析IIC子系统。

IIC子系统的初始化在drivers/i2c/i2c-core.c文件中的i2c_init函数中:

00001221 static int __init i2c_init(void)
00001222 {
00001223     int retval;
00001224 
00001225     retval = bus_register(&i2c_bus_type);
00001226     if (retval)
00001227         return retval;
00001228 #ifdef CONFIG_I2C_COMPAT
00001229     i2c_adapter_compat_class = class_compat_register("i2c-adapter");
00001230     if (!i2c_adapter_compat_class) {
00001231         retval = -ENOMEM;
00001232         goto bus_err;
00001233     }
00001234 #endif
00001235     retval = i2c_add_driver(&dummy_driver);
00001236     if (retval)
00001237         goto class_err;
00001238     return 0;
00001239 
00001240 class_err:
00001241 #ifdef CONFIG_I2C_COMPAT
00001242     class_compat_unregister(i2c_adapter_compat_class);
00001243 bus_err:
00001244 #endif
00001245     bus_unregister(&i2c_bus_type);
00001246     return retval;
00001247 }

1225行,向系统注册IIC总线,其中i2c_bus_type的定义为:

00000343 struct bus_type i2c_bus_type = {
00000344     .name        = "i2c",
00000345     .match        = i2c_device_match,
00000346     .probe        = i2c_device_probe,
00000347     .remove        = i2c_device_remove,
00000348     .shutdown    = i2c_device_shutdown,
00000349     .pm        = &i2c_device_pm_ops,
00000350 };

345行,i2c_device_match函数时用来匹配IIC总线上的设备和设备驱动的,下面看下它的定义:

00000068 static int i2c_device_match(struct device *dev, struct device_driver *drv)
00000069 {
00000070     struct i2c_client    *client = i2c_verify_client(dev);
00000071     struct i2c_driver    *driver;
00000072 
00000073     if (!client)
00000074         return 0;
00000075 
00000076     /* Attempt an OF style match */
00000077     if (of_driver_match_device(dev, drv))
00000078         return 1;
00000079 
00000080     driver = to_i2c_driver(drv);
00000081     /* match on an id table if there is one */
00000082     if (driver->id_table)
00000083         return i2c_match_id(driver->id_table, client) != NULL;
00000084 
00000085     return 0;
00000086 }

在IIC子系统中,用struct i2c_client来描述一个具体的IIC设备(IIC从机)。73行,如果没有IIC设备的话就直接返回0,表示匹配不成功。

77行,用of的方式进行匹配,应该是设备树方面的,具体没了解过。

82行,如果驱动的id table存在则调用83行的i2c_match_id函数进行匹配:

00000057 static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
00000058                         const struct i2c_client *client)
00000059 {
00000060     while (id->name[0]) {
00000061         if (strcmp(client->name, id->name) == 0)
00000062             return id;
00000063         id++;
00000064     }
00000065     return NULL;
00000066 }

很简单,就是拿驱动的id table中的每一项与i2c_client的name成员进行比较,如果它们的名字相同就表示匹配成功,否则匹配失败,返回NULL。从这里也可以看出IIC的总线匹配方式与platform总线的匹配方式是不一样,一般情况下,IIC总线的匹配方式是根据设备名字和驱动中的id tabl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值