I2C 是 philips 提出的外设总线.
I2C 只有两条线,一条串行数据线:SDA,一条是时钟线 SCL ,使用 SCL,SDA 这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线。因此, I2C 总线被非常广泛地应用在 EEPROM,实时钟,小型 LCD 等设备
与 CPU 的接口中。
linux 下的驱动思路
在 linux 系统下编写 I2C 驱动,目前主要有两种方法, 一种是把 I2C 设备
当作一个普通的字符设备来处理, 另一种是利用 linux 下 I2C 驱动体系结构来
完成。下面比较下这两种方法:
第一种方法:
优点:思路比较直接,不需要花很多时间去了解 linux 中复杂的 I2C
子系统的操作方法。
缺点:
要求工程师不仅要对 I2C 设备的操作熟悉,而且要熟悉 I2C 的适配器
(I2C 控制器)操作。
要求工程师对 I2C 的设备器及 I2C 的设备操作方法都比较熟悉,最重
要的是写出的程序可以移植性差。
对内核的资源无法直接使用,因为内核提供的所有 I2C 设备器以及设
备驱动都是基于 I2C 子系统的格式。
第一种方法的优点就是第二种方法的缺点,
第一种方法的缺点就是第二种方法的优点。
I2C 架构概述
Linux 的 I2C 体系结构分为 3 个组成部分:
I2C 核心: I2C 核心提供了 I2C 总线驱动和设备驱动的注册,注销方法,
I2C 通信方法(”algorithm”)上层的,与具体适配器无关的代码以及探测设备,
检测设备地址的上层代码等。
I2C 总线驱动: I2C 总线驱动是对 I2C 硬件体系结构中适配器端的实现,
适配器可由 CPU 控制,甚至可以直接集成在 CPU 内部。
I2C 设备驱动: I2C 设备驱动(也称为客户驱动)是对 I2C 硬件体系结构中
设备端的实现,设备一般挂接在受 CPU 控制的 I2C 适配器上,通过 I2C 适配器
与 CPU 交换数据。
linux 驱动中 i2c 驱动架构

上图完整的描述了 linux i2c 驱动架构,虽然 I2C 硬件体系结构比较简单,
但是 i2c 体系结构在 linux 中的实现却相当复杂。
那么我们如何编写特定 i2c 接口器件的驱动程序?就是说上述架构中的那
些部分需要我们完成,而哪些是 linux 内核已经完善的或者是芯片提供商已经
提供的?
架构层次分类
第一层:提供 i2c adapter 的硬件驱动,探测、初始化 i2c adapter(如申
请 i2c 的 io 地址和中断号),驱动 soc 控制的 i2c adapter 在硬件上产生信号
(start、 stop、 ack)以及处理 i2c 中断。 覆盖图中的硬件实现层
第二层:提供 i2c adapter 的 algorithm,用具体适配器的 xxx_xferf()
函数来填充 i2c_algorithm 的 master_xfer 函数指针,并把赋值后的
i2c_algorithm 再赋值给 i2c_adapter 的 algo 指针。 覆盖图中的访问抽象层、
i2c 核心层
第三层:实现 i2c 设备驱动中的 i2c_driver 接口,用具体的 i2c device 设
备的 attach_adapter()、detach_adapter()方法赋值给 i2c_driver 的成员函
数指针。实现设备 device 与总线(或者叫 adapter)的挂接。覆盖图中的 driver
驱动层
第四层:实现 i2c 设备所对应的具体 device 的驱动, i2c_driver 只是实现
设备与总线的挂接,而挂接在总线上的设备则是千差万别的,所以要实现具体设
备 device 的 write()、 read()、 ioctl()等方法,赋值给 file_operations,然
后注册字符设备(多数是字符设备)。 覆盖图中的 driver 驱动层
第一层和第二层又叫 i2c 总线驱动(bus),第三第四属于 i2c 设备驱动
(device driver)。
在 linux 驱动架构中,几乎不需要驱动开发人员再添加 bus,因为 linux 内
核几乎集成所有总线 bus,如 usb、 pci、 i2c 等等。并且总线 bus 中的(与特定
硬件相关的代码)已由芯片提供商编写完成,例如三星的 s3c-2440 平台 i2c 总
线 bus 为/drivers/i2c/buses/i2c-s3c2410.c

浙公网安备 33010602011771号