LINUX驱动之IIC驱动

前言

LINUX驱动之IIC驱动_第1张图片
1.Linux的I2C体系结构分为3个组成部分
1.1 I2C核心层
提供了I2C总线驱动和设备驱动的注册,注销方法,I2C通信方法上层的即Algorithm)与具体适配器无关的代码以及探测设备,检测设备地址的上层代码等,主要用于提供统一的I2C操作函数
1.2 I2C适配器层
对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部,主要用于IIC设备的硬件操作
1.3 I2C设备驱动层
I2C设备驱动(也称为客户驱动)是对设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据

2.I2C设备驱动层采用bus-dev-drv模型设计
LINUX驱动之IIC驱动_第2张图片
I2C总线上的device可以包含两种数据:i2c_client和i2c_adapter,还提供了match,probe方法,driver端必须提id_table,device端必须提供name,在总线的match函数中会匹配id_table->name和client->name,如果一致则调用总线的probe函数,对于总线的probe函数功能如下所述,下图为简化后的代码,client表示匹配成功的dev,driver表示匹配成功的drv,该函数作用在于设置client->driver=driver,调用driver->probe函数,函数probe主要是注册一个字符设备驱动,而这个字符设备驱动程序的读,写函数统一通过i2c_smbus_read_byte_data(),i2c_smbus_write_byte_data()来实现数据的传输,最终都会调用都会调用i2c_smbus_xfer函数,该函数在适配器中的algo成员会有说明
LINUX驱动之IIC驱动_第3张图片
向总线注册一个i2c_client的函数是i2c_new_device(),向总线注册一个i2c_driver的函数是i2c_register_driver(),如下图所示,在i2c_new_device中分配一个cilent内存,用参数adap(指明client的设配器),info初始化client(info必须指明设备名字及其气质),注册client到链表中
LINUX驱动之IIC驱动_第4张图片

适配器驱动分析

LINUX驱动之IIC驱动_第5张图片
i2c适配器用结构体strucr i2c_adapter表示,适配器对应一个i2c总线(soc上的一个i2c控制器),如果soc上有多个i2c总线,那么内核就必须用多个struct i2c_adapter来表示,内核总有多个适配器,就需要用一定的数据结构来组织和管理,对应的设备文件是/dev/i2c-x,也就是说用户可以通过/dev/i2c-x这些设备文件来操作i2c的硬件控制器,struct i2c_adapter结构中的成员algo是真正实现数据传输的方法合集,其定义如下
LINUX驱动之IIC驱动_第6张图片LINUX驱动之IIC驱动_第7张图片
master_xfer指向传输数据的函数,smbus_xfer表示smbus协议的函数,functionality用于返回该适配器的功能,传输的数据用struct i2c_mag来表示,内核中的i2c_adapter是通过一种叫做idr的数据结构来组织管理的,idr在linux内核中指的就是整数ID管理机制,从本质上来说,这就是一种将整数ID号和特定指针关联在一起的机制,例如,内核中的i2c_adapter->nr成员表示适配的ID,这个ID与对应的i2c_adapter结构体指针管理,通过这个ID可以获取对用的i2c_adapter结构体,对于注册一个i2c_adapter有以下两个步骤

1.分配并初始化一个i2c_adapter结构体变量,主要初始化成员:name,class,algo,nr等成员
2.如果没有指定nr(nr == -1),用i2c_add_adapter()如果指定nr,用i2c_add_numbered_adapter()

你可能感兴趣的:(数据结构)