一、 linux I2C体系结构
linux的I2C体系结构分为3个组成部分
1)I2C核心
I2C核心提供了I2C总线驱动与设备驱动的注册、注销方法,I2C通信方法(即Algorithm)上层的与具体适配器无关的代码及其探测设备、检测设备地址的上层代码等,如图:

2)I2C总线驱动
I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。
I2C总线驱动 主要包含I2C适配器数据结构I2C_adaper、I2C适配器的Algorithm数据结构I2C_algorithm和控制I2C适配器产生通信信号的函数。经I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生开始位、停止位、读写周期,以及以从设备方式被读写、产生ACK等。
3)I2C设备驱动
I2C设备驱动(也称客户驱动)是对I2C硬件体系结构设备端的实现,设备一般挂接在受CPU控制的I2C的适配器上,通过I2C适配器与CPU交换数据。
I2C设备驱动主要包含数据结构I2c_driver和i2c_client,我们需要根据具体设备实现其中的成员函数。
在linux kernel中,所有的i2c设备都在sysfs文件系统中显示,存于/sys/bus/i2c/目录下,以适配器地址和芯片的地址的形式列出,例如:

在linux内核源码中的drivers目录下有一个i2c目录,而在I2C目录下包含如下文件和文件夹
1)i2c-core.c
这个文件实现了i2C核心的功能以及/proc/bus/i2c*接口 。
2)i2c-dev.c
实现了I2c适配器设备文件的功能,每个I2c适配器都被分配一个设备。通过适配器访问设备时的主设备号都为89,次设备号为0-255。应用程序通过"i2c-%d"(i2c-0,i2c-1,...,i2c-10,...)文件名并使用文件操作接口open()、write()、read()、ioctl()、和close()等来访问这个设备。
i2c-dev.c并不是针对特定都设备而设计都,只是提供了通用都read()、write()和ioctl()等接口,应用层可以借用这些接口访问挂接在适配器上的i2c设备的存储空间或寄存器,并控制i2c设备的工作方式。
3)busses文件夹
这个文件包含了一些I2c主机控制权的驱动,如i2c-tegra.c、i2c-omap.c、i2c-versatile.c、i2c-s3c2410.c等
4)algos文件夹
实现了一些i2c总线适配器的通信方法
此外,内核中i2c.h文件对i2c_adapter、i2c_algorithm、i2c_driver和i2c_client这4个数据结构进行了定义。理解这四个结构体的作用十分重要,他们的定义位于include/linux/i2c.h文件中
cpp
719 struct i2c_adapter {
720 struct module *owner;
721 unsigned int class; /* classes to allow probing for */
722 const struct i2c_algorithm *algo; /* the algorithm to access the bus */
723 void *algo_data;
724
725 /* data fields that are valid for all devices */
726 const struct i2c_lock_operations *lock_ops;
727 struct rt_mutex bus_lock;
728 struct rt_mutex mux_lock;
729
730 int timeout; /* in jiffies */
731 int retries;
732 struct device dev; /* the adapter device */
733 unsigned long locked_flags; /* owned by the I2C core */
734 #define I2C_ALF_IS_SUSPENDED 0
735 #define I2C_ALF_SUSPEND_REPORTED 1
736
737 int nr;
738 char name[48];
739 struct completion dev_released;
740
741 struct mutex userspace_clients_lock;
742 struct list_head userspace_clients;
743
744 struct i2c_bus_recovery_info *bus_recovery_info;
745 const struct i2c_adapter_quirks *quirks;
746
747 struct irq_domain *host_notify_domain;
748 struct regulator *bus_regulator;
749 };
cpp
541 struct i2c_algorithm {
542 /*
543 * If an adapter algorithm can't do I2C-level access, set master_xfer
544 * to NULL. If an adapter algorithm can do SMBus access, set
545 * smbus_xfer. If set to NULL, the SMBus protocol is simulated
546 * using common I2C messages.
547 *
548 * master_xfer should return the number of messages successfully
549 * processed, or a negative value on error
550 */
551 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
552 int num);
553 int (*master_xfer_atomic)(struct i2c_adapter *adap,
554 struct i2c_msg *msgs, int num);
555 int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr,
556 unsigned short flags, char read_write,
557 u8 command, int size, union i2c_smbus_data *data);
558 int (*smbus_xfer_atomic)(struct i2c_adapter *adap, u16 addr,
559 unsigned short flags, char read_write,
560 u8 command, int size, union i2c_smbus_data *data);
561
562 /* To determine what the adapter supports */
563 u32 (*functionality)(struct i2c_adapter *adap);
564
565 #if IS_ENABLED(CONFIG_I2C_SLAVE)
566 int (*reg_slave)(struct i2c_client *client);
567 int (*unreg_slave)(struct i2c_client *client);
568 #endif
569 };
上述代码551行master_xfer对应为I2c传输函数指针,i2c主机驱动的大部分工作也聚集在这里。上述第555行代码对应为SMbus传输函数指针,SMbus不需要增加额外引脚,与i2c总线相比,在访问时序上也有一定的差异。
cpp
271 struct i2c_driver {
272 unsigned int class;
273
274 /* Standard driver model interfaces */
275 int (*probe)(struct i2c_client *client);
276 void (*remove)(struct i2c_client *client);
277
278
279 /* driver model interfaces that don't relate to enumeration */
280 void (*shutdown)(struct i2c_client *client);
281
282 /* Alert callback, for example for the SMBus alert protocol.
283 * The format and meaning of the data value depends on the protocol.
284 * For the SMBus alert protocol, there is a single bit of data passed
285 * as the alert response's low bit ("event flag").
286 * For the SMBus Host Notify protocol, the data corresponds to the
287 * 16-bit payload data reported by the slave device acting as master.
288 */
289 void (*alert)(struct i2c_client *client, enum i2c_alert_protocol protocol,
290 unsigned int data);
291
292 /* a ioctl like command that can be used to perform specific functions
293 * with the device.
294 */
295 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
296
297 struct device_driver driver;
298 const struct i2c_device_id *id_table;
299
300 /* Device detection callback for automatic device creation */
301 int (*detect)(struct i2c_client *client, struct i2c_board_info *info);
302 const unsigned short *address_list;
303 struct list_head clients;
304
305 u32 flags;
306 };
cpp
330 struct i2c_client {
331 unsigned short flags; /* div., see below */
332 #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
333 #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
334 /* Must equal I2C_M_TEN below */
335 #define I2C_CLIENT_SLAVE 0x20 /* we are the slave */
336 #define I2C_CLIENT_HOST_NOTIFY 0x40 /* We want to use I2C host notify */
337 #define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */
338 #define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
339 /* Must match I2C_M_STOP|IGNORE_NAK */
340
341 unsigned short addr; /* chip address - NOTE: 7bit */
342 /* addresses are stored in the */
343 /* _LOWER_ 7 bits */
344 char name[I2C_NAME_SIZE];
345 struct i2c_adapter *adapter; /* the adapter we sit on */
346 struct device dev; /* the device structure */
347 int init_irq; /* irq set at initialization */
348 int irq; /* irq issued by device */
349 struct list_head detected;
350 #if IS_ENABLED(CONFIG_I2C_SLAVE)
351 i2c_slave_cb_t slave_cb; /* callback for slave mode */
352 #endif
353 void *devres_group_id; /* ID of probe devres group */
354 };
下面分析这4个数据结构的作用及盘根错节的关系
- i2c_adapter(适配器)与i2_algorithm(算法,通信方法)
i2c_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个i2c适配器需要i2c_algorithm提供的通信函数来控制适配器产生特定的访问周期。缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含所使用的i2c_algorithm的指针。
i2c_algorithm的关键函数master_xfer()用于产生访问周期需要的信号,以i2c_msg(即i2c信息)为单位。i2c_msg结构体也是非常重要的,它定义于include/uapi/linux/i2c.h(在uapi目录下,证明用户空间的应用也可能用这个结构体)中,下图给出了它的定义,其中的成员表明了i2c的传输地址、方向、缓冲区、缓冲区长度等信息。
cpp
73 struct i2c_msg {
74 __u16 addr;
75 __u16 flags;
76 #define I2C_M_RD 0x0001 /* guaranteed to be 0x0001! */
77 #define I2C_M_TEN 0x0010 /* use only if I2C_FUNC_10BIT_ADDR */
78 #define I2C_M_DMA_SAFE 0x0200 /* use only in kernel space */
79 #define I2C_M_RECV_LEN 0x0400 /* use only if I2C_FUNC_SMBUS_READ_BLOCK_DATA */
80 #define I2C_M_NO_RD_ACK 0x0800 /* use only if I2C_FUNC_PROTOCOL_MANGLING */
81 #define I2C_M_IGNORE_NAK 0x1000 /* use only if I2C_FUNC_PROTOCOL_MANGLING */
82 #define I2C_M_REV_DIR_ADDR 0x2000 /* use only if I2C_FUNC_PROTOCOL_MANGLING */
83 #define I2C_M_NOSTART 0x4000 /* use only if I2C_FUNC_NOSTART */
84 #define I2C_M_STOP 0x8000 /* use only if I2C_FUNC_PROTOCOL_MANGLING */
85 __u16 len;
86 __u8 *buf;
87 };
2)i2c_driver与i2c_client
i2c_driver对应于一套驱动方法,其主要成员函数是probe()、remove()、suspen()、resumu()等,另外,struct i2c_device_id形式的id_table是该驱动所支持的i2c设备的ID表。i2c_client对应于真实的物理设备,每个i2c设备都需要一个i2c_client来描述。i2c_driver与i2c_client的关系是一对多,一个i2c_driver可以支持多个同类型的i2c_clinet 。
i2c_client的信息通常在BSP的板文件中通过i2c_board_info填充,如下:

在i2c总线驱动i2c_bus_type的match()函数i2c_device_match()中,会调用i2c_match_id()函数匹配在板文件中定义的ID和i2c_driver所支持的ID表 。
3)i2c_adapter与i2c_client
i2c_adapter与i2c_cilent的关系与i2c硬件体系中适配器和设备的关系一致,即i2c_clinet依附于i2c_adapter。由于一个适配器可以连接多个i2c设备,所有一个i2c_adapter也可以被多个i2c_client依附,i2c_adapter中包含依附它的i2c_client的链表。
假设i2c总线适配器xxx上有两个使用相同驱动程序的yyyI2c设备,在打开该I2c总线的设备节点后,相关数据结构之间的逻辑组织关系如图:

从上面的分析可知,虽然i2c硬件体系结构比较简单,但是i2c体系结构在linux中的实现却相当复杂。当工程师拿到实际的电路板时 ,面对复杂的linux i2c子系统,应该如何下手写驱动呢?究竟有哪些是需要亲自做的,哪些是内核已经提供的呢?理清这个问题非常有意义,可以使我们做面对具体问题时迅速抓住重点。
一方面,适配器驱动可能是linux内核本身还不包含的;另一方面,挂接做适配器上的具体设备驱动可能也是linux内核还不包含的。因此,工程师要实现的主要工作如下:
1)提供I2c硬件适配器的硬件驱动,探测、初始化i2c适配器(如申请i2c的i/O地址和中断号)、驱动cpu控制的i2c适配器从硬件上产生各种信号以及处理i2c中断等。
2)提供i2c适配器的Algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。
3)实现i2c设备驱动中的i2c_driver接口,具体设备yyy的yyy_probe()、yyy_remove()、yyy_suspen()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、resume和id_table指针。
4)实现i2c设备所对应类型的具体驱动,i2c_driver只是实现设备与总线的挂接,而挂接在总线上的设备则千差万别。例如,如果是字符设备,就实现文件操作接口,即实现具体设备yyy的yyy_read()、yyy_write()和yyy_ioctl函数等;如果是声卡就实现ALSA驱动。
上述工作中前两个属于I2c总线驱动,后两个属于i2c设备驱动。
二、 linux I2c核心
I2c核心(drivers/i2c/i2c-core-base.c) 中提供了一组不依赖于硬件平台的接口函数,这个文件一般不需要被工程师修改,但是理解其中的主要函数非常关键,因为i2c总线驱动和设备驱动以i2c核心作为纽带。i2c核心的主要函数如下。
1)增加、删除i2c_adapter


2)增加/删除i2c_dirver

3)i2c传输、发送和接收

i2c_transfer()函数用于进行i2c适配器和i2c设备之间的一组消息交互,其中第2个参数是指向i2c_msg数组的指针,所以i2c_transfer()一次可以传输多个i2c_msg(考虑到很多外设的读写波形比较复杂,比如读寄存器可能要先写,所以需要两个以上的消息)。而对于时序比较简单的外设,i2c_maste_send()函数和i2c_master_recv()函数内部都会调用i2c_transfer()函数分别完成一条写消息和读消息。

i2c_transfer()函数本身不具备驱动适配器物理硬件以完成消息交互的能力,它只是寻找到与i2c_adapter对应的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正驱动硬件流程。


三、 linux I2c适配器驱动
3.1 I2c适配器驱动的注册与注销
由于I2c总线控制器通常是在内存上的,所以本身也连接在platform总线上,要通过platform_driver和platform_device的匹配来执行。因此尽管i2c适配器给别人提供了总线,它自己也被认为是接在platform总线上的一个客户。linux的总线、设备和驱动模型实际上是一个树形结构,每个节点虽然可能成为别人的总线控制器,但是自己也被认为是从上一级总线枚举出来的。
通常我们会在与I2c适配器所对应的platform_driver的probe()函数中完成两个工作。
1)初始化I2c适配器所使用的硬件资源,如申请I/O地址、中断号、时钟等
- 通过i2c_add_adapter()添加i2c_adapter的数据结构,当然这个i2c_adapter数据结构的成员已经被xxx适配器的相应函数指针初始化。
通常我们会在platform_driver的remove()函数中完成与加载函数相反的工作
3)释放i2c适配器所使用的硬件资源,如释放I/O地址、中断号、时钟等。
4)通过i2c_del_adapter()删除i2c_adapter的数据结构

上诉代码中的xxx_adpater_hw_init()和xxx_adpater_hw_free()函数的实现都与具体的CPU和i2c适配硬件直接相关。
3.2 I2c总线的通信方法
我们需要为特定的i2c适配器实现通信方法,主要是实现i2c_algorithm的functionality()函数和master_xfer()函数。
functionality()函数非常,用于返回algorithm所支持的通信协议,如I2C_FUNC_I2C、I2C_FUNC_10BIT_ADDR、I2C_FUNC_SMBUS_READ_BYTE、I2C_FUNC_SMBUS_WRITE_BYTE等。
master_xfer()函数在i2c适配器上完成传递给它的i2c_msg数组中的每个I2C消息。


四、 linux I2c设备驱动
I2c设备驱动要使用i2c_driver和i2c_client数据结构并填充i2c_driver中的成员函数。i2c_client一般被包含在设备的私有信息结构体yyy_data中,而i2c_driver则适合被定义为全局变量并初始化。

4.1 linux I2c设备驱动的模块加载与卸载
i2c设备驱动的模块加载函数通过i2c核心的i2c_add_driver()API函数添加i2c_driver的工作,而模块卸载函数需要做相反的工作:通过i2c核心的i2c_del_driver()函数删除i2c_dirver 。模板如下:

4.2、 linux I2c设备驱动的数据传输
在i2c设备上读写数据的时序且数据通常通过i2c_msg数组进行组织,最后通过i2c_transfer()函数完成。

4.3、 linux的i2c-dev.c文件分析
i2c-dev.c完全可以被看作一个i2c设备驱动,不过,它实现的i2c-client是虚拟的,临时的。主要是为了方便从用户空间操作i2c外设。i2c-dev.c针对每个i2c适配器生成一个主设备号为89的设备文件,实现了i2c_driver的成员函数及其文件操作接口,因此i2c-dev.c的主体是"i2c_driver成员函数+字符设备驱动"。
i2c-dev.c提供的i2cdev_read()、i2cdec_write()函数对应于用户空间要使用的read()和write()文件操作接口,这两个函数分别调用i2c核心的i2c_maser_recv()和i2c_master_send()函数来构造一条i2c消息并引发适配器Algorithm通信函数的调用,以完成消息的传输,它对应下面的时序:

但是,很遗憾,大多数稍微复杂一点的i2c设备的读写流程并不对应一条消息,往往需要两条甚至多条消息来进行一次读写周期(即下面图示模式),在这种情况下,在应用层仍然调用read()、write()文件API来读写I2c设备,将不能正确地读写。

鉴于以上原因,i2c-dev.c中i2cdev_read()和i2cdec_write()函数不具备太强的通用性,没有太大的实用价值,只能适用非RepStart模式的情况。对于由两条以上消息组成的读写 ,在用户空间需要组织i2c_msg消息数组并调用I2C_RDWR IOCTL命令。


常用的IOCTL包括I2C_SLAVE(设置从设备地址)、I2C_RETRIES(没有收到设备ACK情况下的重试次数,默认为1)、I2C_TIMEOU(超时)以及I2C_RDWR。
五、Tegra I2c总线驱动实例
NVIDIA Tegra I2c总线总线驱动位于drivers/i2c/busses/i2c-tegra.c文件中,这里不具体研究它的硬件细节,只看一下驱动框架和流程。
I2c总线驱动是一个单独的驱动,在模块的加载和卸载函数中,只需要注册和注销platform_driver结构体。
cpp
1629 static const struct of_device_id tegra_i2c_of_match[] = {
1630 { .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, },
1631 { .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, },
1632 #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
1633 { .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_i2c_hw, },
1634 #endif
1635 { .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, },
1636 { .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, },
1637 { .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
1638 { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
1639 { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
1640 #if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)
1641 { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
1642 #endif
1643 {},
1644 };
1645 MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
1967 static struct platform_driver tegra_i2c_driver = {
1968 .probe = tegra_i2c_probe,
1969 .remove_new = tegra_i2c_remove,
1970 .driver = {
1971 .name = "tegra-i2c",
1972 .of_match_table = tegra_i2c_of_match,
1973 .acpi_match_table = tegra_i2c_acpi_match,
1974 .pm = &tegra_i2c_pm,
1975 },
1976 };
1977 module_platform_driver(tegra_i2c_driver);

当在arch/arm/mach-tegra下创建一个名字为tegra-i2c的同名的platform_device,或者在tegra的设备树中添加了tegra_i2c_of_match匹配表兼容的节点后,上述platform_driver中的probe()函数就会执行。
其中probe指针指向的tegra_i2c_probe()函数将被调用。以初始化,适配器硬件、申请适配器要的内存、时钟、中断等资源,最终注册适配器。




上述代码中提到tegra_i2c_dev结构体可进行适配器所有信息的封装,类似私有信息结构体。下图是tegra_i2c_dev结构体的定义。我们在编程中要时刻牢记linux这个编程习惯,这实际上也是面向对象的一种体现。
cpp
260 struct tegra_i2c_dev {
261 struct device *dev;
262 struct i2c_adapter adapter;
263
264 const struct tegra_i2c_hw_feature *hw;
265 struct reset_control *rst;
266 unsigned int cont_id;
267 unsigned int irq;
268
269 phys_addr_t base_phys;
270 void __iomem *base;
271
272 struct clk_bulk_data clocks[2];
273 unsigned int nclocks;
274
275 struct clk *div_clk;
276 struct i2c_timings timings;
277
278 struct completion msg_complete;
279 size_t msg_buf_remaining;
280 unsigned int msg_len;
281 int msg_err;
282 u8 *msg_buf;
283
284 struct completion dma_complete;
285 struct dma_chan *dma_chan;
286 unsigned int dma_buf_size;
287 struct device *dma_dev;
288 dma_addr_t dma_phys;
289 void *dma_buf;
290
291 bool multimaster_mode;
292 bool atomic_mode;
293 bool dma_mode;
294 bool msg_read;
295 bool is_dvc;
296 bool is_vi;
297 };
tegra_i2c_probe()函数中的platform_set_drvdata(pdev,i2c_dev)和i2c_set_adapterdata(&I2C_dev->adapter,i2c_dev)已经把这个结构体的实例依附到了platform_device和i2c_adapter的私有数据上了,在其他地方只要用到相应的方法就可以把这个结构体的实例取出来。
从前面的白图代码60行可以看出,于i2c适配器对应的i2c_algorithm结构体实例为tera_i2c_algo,下图给出定义

上诉代码第一行指定了Tera I2c总线通信传输函数tegra_i2c_xfer(),这个函数非常关键,所有在i2c总线上对设备的访问最终应该由它完成。下图为这个重要函数以及其依赖的tegra_i2c_xfer_msg()函数的源码:
cpp
1213 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
1214 struct i2c_msg *msg,
1215 enum msg_end_type end_state)
1216 {
1217 unsigned long time_left, xfer_time = 100;
1218 size_t xfer_size;
1219 u32 int_mask;
1220 int err;
1221
1222 err = tegra_i2c_flush_fifos(i2c_dev);
1223 if (err)
1224 return err;
1225
1226 i2c_dev->msg_buf = msg->buf;
1227 i2c_dev->msg_len = msg->len;
1228
1229 i2c_dev->msg_err = I2C_ERR_NONE;
1230 i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
1231 reinit_completion(&i2c_dev->msg_complete);
1232
1233 /*
1234 * For SMBUS block read command, read only 1 byte in the first transfer.
1235 * Adjust that 1 byte for the next transfer in the msg buffer and msg
1236 * length.
1237 */
1238 if (msg->flags & I2C_M_RECV_LEN) {
1239 if (end_state == MSG_END_CONTINUE) {
1240 i2c_dev->msg_len = 1;
1241 } else {
1242 i2c_dev->msg_buf += 1;
1243 i2c_dev->msg_len -= 1;
1244 }
1245 }
1246
1247 i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
1248
1249 if (i2c_dev->msg_read)
1250 xfer_size = i2c_dev->msg_len;
1251 else
1252 xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
1253
1254 xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
1255
1256 i2c_dev->dma_mode = xfer_size > I2C_PIO_MODE_PREFERRED_LEN &&
1257 i2c_dev->dma_buf && !i2c_dev->atomic_mode;
1258
1259 tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
1260
1261 /*
1262 * Transfer time in mSec = Total bits / transfer rate
1263 * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits
1264 */
1265 xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC,
1266 i2c_dev->timings.bus_freq_hz);
1267
1268 int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
1269 tegra_i2c_unmask_irq(i2c_dev, int_mask);
1270
1271 if (i2c_dev->dma_mode) {
1272 if (i2c_dev->msg_read) {
1273 dma_sync_single_for_device(i2c_dev->dma_dev,
1274 i2c_dev->dma_phys,
1275 xfer_size, DMA_FROM_DEVICE);
1276
1277 err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
1278 if (err)
1279 return err;
1280 } else {
1281 dma_sync_single_for_cpu(i2c_dev->dma_dev,
1282 i2c_dev->dma_phys,
1283 xfer_size, DMA_TO_DEVICE);
1284 }
1285 }
1286
1287 tegra_i2c_push_packet_header(i2c_dev, msg, end_state);
1288
1289 if (!i2c_dev->msg_read) {
1290 if (i2c_dev->dma_mode) {
1291 memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
1292 msg->buf, i2c_dev->msg_len);
1293
1294 dma_sync_single_for_device(i2c_dev->dma_dev,
1295 i2c_dev->dma_phys,
1296 xfer_size, DMA_TO_DEVICE);
1297
1298 err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
1299 if (err)
1300 return err;
1301 } else {
1302 tegra_i2c_fill_tx_fifo(i2c_dev);
1303 }
1304 }
1305
1306 if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
1307 int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
1308
1309 if (!i2c_dev->dma_mode) {
1310 if (msg->flags & I2C_M_RD)
1311 int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
1312 else if (i2c_dev->msg_buf_remaining)
1313 int_mask |= I2C_INT_TX_FIFO_DATA_REQ;
1314 }
1315
1316 tegra_i2c_unmask_irq(i2c_dev, int_mask);
1317 dev_dbg(i2c_dev->dev, "unmasked IRQ: %02x\n",
1318 i2c_readl(i2c_dev, I2C_INT_MASK));
1319
1320 if (i2c_dev->dma_mode) {
1321 time_left = tegra_i2c_wait_completion(i2c_dev,
1322 &i2c_dev->dma_complete,
1323 xfer_time);
1324
1325 /*
1326 * Synchronize DMA first, since dmaengine_terminate_sync()
1327 * performs synchronization after the transfer's termination
1328 * and we want to get a completion if transfer succeeded.
1329 */
1330 dmaengine_synchronize(i2c_dev->dma_chan);
1331 dmaengine_terminate_sync(i2c_dev->dma_chan);
1332
1333 if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
1334 dev_err(i2c_dev->dev, "DMA transfer timed out\n");
1335 tegra_i2c_init(i2c_dev);
1336 return -ETIMEDOUT;
1337 }
1338
1339 if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
1340 dma_sync_single_for_cpu(i2c_dev->dma_dev,
1341 i2c_dev->dma_phys,
1342 xfer_size, DMA_FROM_DEVICE);
1343
1344 memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
1345 }
1346 }
1347
1348 time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete,
1349 xfer_time);
1350
1351 tegra_i2c_mask_irq(i2c_dev, int_mask);
1352
1353 if (time_left == 0) {
1354 dev_err(i2c_dev->dev, "I2C transfer timed out\n");
1355 tegra_i2c_init(i2c_dev);
1356 return -ETIMEDOUT;
1357 }
1358
1359 dev_dbg(i2c_dev->dev, "transfer complete: %lu %d %d\n",
1360 time_left, completion_done(&i2c_dev->msg_complete),
1361 i2c_dev->msg_err);
1362
1363 i2c_dev->dma_mode = false;
1364
1365 err = tegra_i2c_error_recover(i2c_dev, msg);
1366 if (err)
1367 return err;
1368
1369 return 0;
1370 }
1372 static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
1373 int num)
1374 {
1375 struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
1376 int i, ret;
1377
1378 ret = pm_runtime_get_sync(i2c_dev->dev);
1379 if (ret < 0) {
1380 dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret);
1381 pm_runtime_put_noidle(i2c_dev->dev);
1382 return ret;
1383 }
1384
1385 for (i = 0; i < num; i++) {
1386 enum msg_end_type end_type = MSG_END_STOP;
1387
1388 if (i < (num - 1)) {
1389 /* check whether follow up message is coming */
1390 if (msgs[i + 1].flags & I2C_M_NOSTART)
1391 end_type = MSG_END_CONTINUE;
1392 else
1393 end_type = MSG_END_REPEAT_START;
1394 }
1395 /* If M_RECV_LEN use ContinueXfer to read the first byte */
1396 if (msgs[i].flags & I2C_M_RECV_LEN) {
1397 ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
1398 if (ret)
1399 break;
1400 /* Set the msg length from first byte */
1401 msgs[i].len += msgs[i].buf[0];
1402 dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
1403 }
1404 ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);
1405 if (ret)
1406 break;
1407 }
1408
1409 pm_runtime_put(i2c_dev->dev);
1410
1411 return ret ?: i;
1412 }

从代码层面上看,第35行的for循环遍历所有的i2c_msg,每个i2c_msg则由tegra_i2c_xfer_msg()函数处理,它每次发起硬件操作后,实际上需要通过wait_for_completion_timeout()等待传输的完成,因此这里面就会有一个被调度出去的过程。中断到来且i2c的包传输结束的时候,就是唤醒这个睡眠进程的时候。

六、 总结
linux的i2c驱动体系相当复杂,它主要由3部分组成,即i2c核心、i2c总线驱动和i2c设备驱动。I2c核心是i2c总线驱动和i2c设备驱动的中间枢纽,它以通用的、与平台的无关的接口是实现了i2c中设备与适配器的沟通。i2c总线驱动填充i2c_adapter和i2c_algorithm结构体,i2c设备驱动填充i2c_driver结构体并实现其本身所对应设备类型的驱动。
另外,系统中i2c-dev.c文件定义的主设备号89的设备可以方便地给应用程序提供读写i2c设备寄存器的能力,使得工程师在大多数时候并不需要为具体的i2c设备驱动定义文件操作接口。