1.Linux的I2C分3个组成部分:
①
i2c
核心:
提供
I2C
总线驱动和设备驱动的注册、注销方法,
I2C
通信方法,上层的与具体适配器无关的代码以及探测设备、检测设备地址的层代码。
②
i2c总线驱动
:
是对
CPU
内部
I2C
控制器的驱动实现,包含
I2C
适配器数据结构,
i2c_adapter,i2c_algorithm
和控制
I2C
适配器产生通信信号的函数,可以设置
I2C
适配器的开始位、停止位,产生
ACK
等。
③
i2c
设备驱动:
对
I2C
设备器件的驱动,包含数据结构
i2c_driver
和
i2c_client,
我们需要根据具体的设备实现其中的成员函数(实际驱动开发需要做的)。
2.I2C驱动代码
Linux2.6中所有i2c设备都在sysfs中显示,存于/sys/bus/i2c目录,以适配器地址和芯片地址的形式列出,tree /sys/bus/i2c/
在内核源码树下,drivers/i2c/目录下,有如下文件:
在内核源码树下,drivers/i2c/目录下,有如下文件:
i2c-core.c--实现i2c核心功能以及/proc/bus/i2c*接口
i2c-dev.c--实现适配器功能,每个i2c适配器都被分配一个设备,通过适配器访问设备时主设备号都为89,此设备号0-255.
i2c-dev.c并没有针对特定的设备而设计,只是提供通用的read(),write(),ioctl()等接口,应用层可借用这些接口访问挂接在适配器上的i2c设备的存储空间和寄存器,并控制i2c设备的工作方式。
chips文件夹---包含特定的i2c芯片驱动
Busses文件夹----包含I2C总线驱动,比如2410的i2c-s3c2410.c
Algos文件夹--
实现一些i2c总线适配器的algorithm.
3.I2C驱动中重要的数据结构:
i2c_adapter
、
i2c_algorithm
、
i2c_client
、
i2c_driver,其关系是
①
i2c_adapter
与
i2c_algorithm
i2c_adapter
对应于物理上的一个
适配器
,
i2c_algorithm
对应一套
通信方法
。一个适配器需要i2c_algorithm提供的通信函数来控制适配器上产生特定的访问周期,缺少i2c_algorithm,i2c_adapter啥也做不了,i2c_algorithm中包含一个指向i2c_adapter的指针。
i2c_algorithm中的关键函数是
master_xfer
,用于产生i2c访问周期需要的
信号
,以
i2c_msg
为单位.
②
i2c_driver
和
i2c_client
i2c_driver
对应一套
驱动方法
,纯粹用于辅助作用的数据结构,不对应任何物理实体,
i2c_client
对应于真实的
物理设备
(外设),
每个i2c设备都用一个i2c_client描述
,一般被包含在具体字符设备的私有信息结构体中。
i2c_driver和i2c_client发生关联的时刻是i2c_driver的attach_adapter()函数被运行时。attach_adapter会探测物理设备,当确定一个client存在时,把该client的数据结构的adapter指针指向对应的i2c_adapter,driver指针指向该i2c_driver,并会调用i2c_adapter的client_register()函数,相反过程发生在i2c_driver的detach_client函数被调用时。
③
i2c_adpater
与
i2c_client
i2c_adpater与i2c_client的关系与i2c硬件体系中的适配器与设备的关系一致,即
i2c_client依赖于i2c_adpater
,
一个适配器上可连接多个I2C设备
,所以i2c_adpater中包括依赖于它的i2c_client的链表。
4.I2C接口函数
Linux I2C核心(drivers/i2c/i2c-core.c)提供了一组不依赖于硬件平台的
①
增加/删除i2c_adapter
- int i2c_add_adapter(struct i2c_adapter *adap);
- int i2c_del_adapter(struct i2c_adapter *adap);
②
增加/删除i2c_driver
- int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
- static inline int i2c_add_driver(struct i2c_driver *driver)
- int i2c_del_driver(struct i2c_driver *driver)
③
i2c_client依附/脱离
- int i2c_attach_client(struct i2c_client *client)
- int i2c_detach_client(struct i2c_client *client)
在i2c_attach_client函数里,当一个具体的client被侦测到并被关联的时候,设备和syffs文件将被注册,相反的在client被取消关联时,sysfs文件和设备也被注销
④
i2c传输、发送和接收
- int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
- int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
- int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
i2c_transfer函数用于进行I2C适配器和I2C设备之间的一组消息交互,i2c_transfer本身不具备驱动适配器物理硬件完成消息交互的能力,他调用i2c_adapter对于的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正驱动硬件流程。
⑤
i2c控制命令分配
- int i2c_control(struct i2c_client *client,unsigned int cmd, unsigned long arg)
- void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
将发给I2C适配器设备文件ioctl的命令分配给对应适配器的algorithm的algo_control()函数活i2c_driver()的command()函数
<script>window._bd_share_config={"common":{"bdsnskey":{},"bdtext":"","bdmini":"2","bdminilist":false,"bdpic":"","bdstyle":"0","bdsize":"16"},"share":{}};with(document)0[(getelementsbytagname('head')[0]||body).appendchild(createelement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new date()/36e5)];</script>
阅读(1660) | 评论(0) | 转发(10) |
相关热门文章
给主人留下些什么吧!~~
评论热议
本文详细介绍了Linux I2C驱动的组成及工作原理,包括I2C核心、总线驱动、设备驱动等内容,并阐述了i2c_adapter、i2c_algorithm等关键数据结构之间的关系。
&spm=1001.2101.3001.5002&articleId=68061530&d=1&t=3&u=21b53ce6552c4b178a22a8e82a3ddc01)
627

被折叠的 条评论
为什么被折叠?



