介绍I2C基本协议,以及在linux内核中I2C驱动程序框架。
I2C驱动基于标准了总线设备驱动模型,因此本文仅示意分析I2C驱动框架,驱动实现细节按照总线设备驱动模型来实现,不做过多分析。
只有两脚
根据引脚可以推断,一个数据脚为半双工,且数据脚方向为双向。没有片选信号,因此数据通信需要带有地址信息。

时钟为高电平期间,数据线从高变低是开始,从低变高是结束。
时钟为高器件,数据线不允许变化,变化就是开始和结束。时钟为低电平器件,数据bit进行变化传输。

通信完成一个字节后,从设备或者主设备主动将SDA拉低从而产生一个ACK信号给对方,默认情况下被外部上拉置位高电平。

遵循总线设备驱动模型。总线驱动在设置config支持i2c后在内核启动阶段被注册。与SPI总线类似,设备树中描述控制器及其下的设备,被转换为控制器及i2c_client设备。并注册不同类型的设备驱动,完成匹配。
i2c_bus_type(总线)、i2c_adpater(控制器)、i2c_client(设备)、驱动(i2c_driver)
- i2c1: i2c@021a0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
- reg = <0x021a0000 0x4000>;
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6UL_CLK_I2C1>;
- status = "disabled";
- };
-
- &i2c1 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- status = "okay";
-
- mag3110@0e {
- compatible = "fsl,mag3110";
- reg = <0x0e>;
- position = <2>;
- };
-
- fxls8471@1e {
- compatible = "fsl,fxls8471";
- reg = <0x1e>;
- position = <0>;
- interrupt-parent = <&gpio5>;
- interrupts = <0 8>;
- };
- };






与SPI驱动类似,I2C完全符合总线设备驱动模型。I2C通信只有2根型号,可产生开始信号,停止信号,数据传输,ACK反馈等。