2024年6月12日发(作者:)
1. 几个基本概念
1.1. 设备模型
由 总线(bus_type) + 设备(device) + 驱动(device_driver) 组成,在该模型下,所有的设
备通过总线连接起来,即使有些设备没有连接到一根物理总线上,linux为其设置了一个内部的、
虚拟的platform总线,用以维持总线、驱动、设备的关系。
因此,对于实现一个linux下的设备驱动,可以划分为两大步:
1、设备注册;
2、驱动注册。
当然,其中还有一些细节问题:
1、驱动的probe函数
2、驱动和设备是怎么进行绑定的。
1.2. i2c设备驱动的几个数据结构
i2c_adapter:
每一个i2c_adapter对应一个物理上的i2c控制器,在i2c总线驱动probe函数中动态创建。通过
i2c_add_adapter注册到i2c_core。
i2c_algorithm:
i2c_algorithm中的关键函数master_xfer(),以i2c_msg为单位产生i2c访问需要的信号。不同
的平台所对应的master_xfer()是不同的,需要根据所用平台的硬件特性实现自己的xxx_xfer()方
法以填充i2c_algorithm的master_xfer指针;在A31上即是sun6i_i2c_algorithm函数。
i2c_client:
代表一个挂载到i2c总线上的i2c从设备,包含该设备所需要的数据:
该i2c从设备所依附的i2c控制器 struct i2c_adapter *adapter
该i2c从设备的驱动程序struct i2c_driver *driver
该i2c从设备的访问地址addr, name
该i2c从设备的名称name。
2. i2c总线驱动
2.1. 功能划分
从硬件功能上可划分为:i2c控制器和i2c外设(从设备)。每个i2c控制器总线上都可以挂载多
个i2c外设。Linux中对i2c控制器和外设分开管理:通过 i2c-sun6i.c 文件完成了i2c控制器
的设备注册和驱动注册;通过i2c-core.c为具体的i2c外设提供了统一的设备注册接口和驱动
注册接口,它分离了设备驱动device driver和硬件控制的实现细节(如操作i2c的寄存器)。
2.2. i2c-sun6i.c
该文件是与具体硬件平台相关的,对应于A3x系列芯片。该文件实际上是i2c总线驱动的实现,
本质上就是向内核注册i2c总线设备、注册总线驱动、实现总线传输的时序控制算法。i2c控制
器被注册为Platform设备,如下:
if (twi_used_mask & TWI0_USED_MASK)
platform_device_register(&sun6i_twi0_device);
if (twi_used_mask & TWI1_USED_MASK)
platform_device_register(&sun6i_twi1_device);
if (twi_used_mask & TWI2_USED_MASK)
platform_device_register(&sun6i_twi2_device);
if (twi_used_mask & TWI3_USED_MASK)
platform_device_register(&sun6i_twi3_device);
if (twi_used_mask)
return platform_driver_register(&sun6i_i2c_driver);
需要注意的是:设备与驱动的对应关系是多对一的;即如果设备类型是一样的,会共用同一套驱
动,因此上面代码只是注册了一次驱动platform_driver_register(&sun6i_i2c_driver)。
设备注册:
将i2c控制器设备注册为platform设备,为每一个控制器定义一个struct platform_device数
据结构,并且把.name都设置为"sun6i-i2c"(后面会通过名字进行匹配驱动的),然后是调用
platform_device_register()将设备注册到platform bus上。
设备注册完成后其直观的表现就是在文件系统下出现:/sys/bus/platform/devices/sun6i-i2c.0


发布评论