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/目录下,有如下文件:
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()函数
阅读(1517) | 评论(0) | 转发(0) |