Linux下I2C驱动介绍
Linux下I2C驱动架构全面分析概要

Linux下I2C驱动架构全面分析I2C 概述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交换数据。
第二层:提供i2c adapter的algorithm,用具体适配器的xxx_xferf()函数来填充i2c_algorithm的master_xfer函数指针,并把赋值后的i2c_algorithm再赋值给i2c_adapter 的algo指针。
Linux I2C驱动完全分析2

Linux I2C驱动完全分析(二)先说一下,本文中有个疑惑,一直没有搞懂,写在这里,望高人指点一二,不胜感激!#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */这里I2C_FUNC_PROTOCOL_MANGLING 是什么意思?为什么定义这些东东?看了注释也不太理解。
求解释!3. I2C总线驱动代码分析s3c2440的总线驱动代码在i2c-s3c2410.c中。
照例先从init看起。
static int __init i2c_adap_s3c_init(void){return platform_driver_register(&s3c24xx_i2c_driver);}在init中只是调用了平台驱动注册函数注册了一个i2c的平台驱动s3c24xx_i2c_driver。
这个驱动是一个platform_driver的结构体变量。
注意这里不是i2c_driver结构体,因为i2c_driver是对设备的驱动,而这里对控制器的驱动要使用platform_driverstatic struct platform_driver s3c24xx_i2c_driver = {.probe = s3c24xx_i2c_probe,.remove = s3c24xx_i2c_remove,.suspend_late = s3c24xx_i2c_suspend_late,.resume = s3c24xx_i2c_resume,.id_table = s3c24xx_driver_ids,.driver = {.owner = THIS_MODULE,.name = "s3c-i2c",},};同样的,重要的函数还是那几个:probe,remove,suspend_late,resume。
LinuxI2C驱动--用户态驱动简单示例

LinuxI2C驱动--⽤户态驱动简单⽰例1. Linux内核⽀持I2C通⽤设备驱动(⽤户态驱动:由应⽤层实现对硬件的控制可以称之为⽤户态驱动),实现⽂件位于drivers/i2c/i2c-dev.c,设备⽂件为/dev/i2c-02. I2C通⽤设备驱动以字符设备注册进内核的static const struct file_operations i2cdev_fops = {.owner = THIS_MODULE,.llseek = no_llseek,.read = i2cdev_read,.write = i2cdev_write,.unlocked_ioctl = i2cdev_ioctl,.open = i2cdev_open,.release = i2cdev_release,};res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);3. 对设备⽂件进⾏读写时,可以调⽤read、write或者ioctl等⽅法,他们都是通过调⽤函数i2c_transfer来实现对I2C设备的操作的int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num){int ret;/* REVISIT the fault reporting model here is weak:** - When we get an error after receiving N bytes from a slave,* there is no way to report "N".** - When we get a NAK after transmitting N bytes to a slave,* there is no way to report "N" ... or to let the master* continue executing the rest of this combined message, if* that's the appropriate response.** - When for example "num" is two and we successfully complete* the first message but get an error part way through the* second, it's unclear whether that should be reported as* one (discarding status on the second message) or errno* (discarding status on the first one).*/if (adap->algo->master_xfer) {#ifdef DEBUGfor (ret = 0; ret < num; ret++) {dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, ""len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)'R' : 'W', msgs[ret].addr, msgs[ret].len,(msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");}#endifif (in_atomic() || irqs_disabled()) {ret = mutex_trylock(&adap->bus_lock);if (!ret)/* I2C activity is ongoing. */return -EAGAIN;} else {mutex_lock_nested(&adap->bus_lock, adap->level);}ret = adap->algo->master_xfer(adap,msgs,num);mutex_unlock(&adap->bus_lock);return ret;} else {dev_dbg(&adap->dev, "I2C level transfers not supported\n");return -EOPNOTSUPP;}}4. i2c_transfer通过代码可以看出,i2c_transfer 通过调⽤相应的 adapter 的 master_xfer ⽅法实现的,⽽ master_xfer 主要是根据 struct i2c_msg 类型的msgs来进⾏处理的。
Linux2.6内核i2c驱动架构

三. i2c驱动架构分析 i2c驱动架构分析
2、硬件抽象层 、 i2c-core.h和i2c-core.c为其主体框架代码,提供了 为其主体框架代码, 和 为其主体框架代码 核心数据结构的定义、 适配器驱动和设备驱动的注 核心数据结构的定义、i2c适配器驱动和设备驱动的注 注销管理等API。其为硬件平台无关层,向下屏 册、注销管理等 。其为硬件平台无关层, 蔽了物理总线适配器的差异, 蔽了物理总线适配器的差异,定义了统一的访问策略 和接口;其向上提供了统一的接口,以便I2C设备驱 和接口;其向上提供了统一的接口,以便 设备驱 动通过总线适配器进行数据收发。 动通过总线适配器进行数据收发。 3、用户接口层 、 i2c设备驱动层为用户接口层,其为用户提供了通 设备驱动层为用户接口层, 设备驱动层为用户接口层 总线访问具体设备的接口。 过I2C总线访问具体设备的接口。 I2c设备驱动主要包 总线访问具体设备的接口 设备驱动主要包 含了数据结构i2c_driver和i2c_client,我们需要根据 含了数据结构 和 , 具体设备实现其中的成员函数。 具体设备实现其中的成员函数。
Linux2.6内核i2c驱动架构
目录
一.i2c简介 i2c简介 二.驱动相关知识介绍 三.i2c驱动架构分析 i2c驱动架构分析
一. i2c简介 i2c简介
I2C 协议
I2C协议是有PHILIPS公司在1992年最先提出, PHILIPS公司专利。 I2C协议是有PHILIPS公司在1992年最先提出,乃PHILIPS公司专利。只要购 协议是有PHILIPS公司在1992年最先提出 公司专利 Philips的I2C元件同时传递了一个在Philips的 元件同时传递了一个在Philips 专利下, 买Philips的I2C元件同时传递了一个在Philips的I2C 专利下,在I2C 系统使用 元件使系统符合由Philips定义的I2C规范的许可证。任何使用I2C Philips定义的I2C规范的许可证 I2C的元件都必须 元件使系统符合由Philips定义的I2C规范的许可证。任何使用I2C的元件都必须 得到PHILIPS公司的授权。 PHILIPS公司的授权 得到PHILIPS公司的授权。 I2C总线的特征 I2C总线的特征 只要求两条总线线路一条串行数据线(SDA)一条串行时钟线(SCL)。 1.只要求两条总线线路一条串行数据线(SDA)一条串行时钟线(SCL)。 同时SDL SCL都是双向线路 分别通过上拉电阻连接到正的电源电压。 SDL和 都是双向线路, 同时SDL和SCL都是双向线路,分别通过上拉电阻连接到正的电源电压。 .每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主 2 .每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主 从机关系软件设定地址;主机可以作为主机发送器或主机接收器。 机/从机关系软件设定地址;主机可以作为主机发送器或主机接收器。 3.它是一个真正的多主机总线 它是一个真正的多主机总线, 3.它是一个真正的多主机总线,如果两个或更多主机同时初始化数据传输 可以通过冲突检测和仲裁防止数据被破坏。 可以通过冲突检测和仲裁防止数据被破坏。 串行的8 位双向数据传输位速率在标准模式下可达100kbit/s 100kbit/s。 4. 串行的8 位双向数据传输位速率在标准模式下可达100kbit/s。快速模 式下可达400kbit/s 高速模式下可达3.4Mbit/s 400kbit/s。 3.4Mbit/s。 式下可达400kbit/s。高速模式下可达3.4Mbit/s。 5.片上的滤波器可以滤去总线数据线上的毛刺波, 5.片上的滤波器可以滤去总线数据线上的毛刺波,保证数据完整 片上的滤波器可以滤去总线数据线上的毛刺波
linux 应用访问i2c设备原理

linux 应用访问i2c设备原理Linux是一个开放源代码的操作系统内核,支持许多硬件设备的驱动程序。
其中一种常用的硬件接口是I2C(Inter-Integrated Circuit)总线。
I2C总线允许多个设备通过共享同一组线路进行通信,这些设备可以是传感器、存储器、转换器等外围设备。
Linux提供了一种访问I2C设备的机制,通过此机制,应用程序可以与I2C设备进行通信。
在本文中,将介绍Linux应用程序访问I2C设备的原理及步骤。
1.硬件连接:首先,需要将I2C设备连接到主机上。
I2C总线由两根线路组成,即SDA(Serial Data Line)和SCL(Serial Clock Line)。
SDA用于传输数据,SCL用于提供时钟信号。
I2C设备通常具有一个I2C地址,用于在总线上识别不同的设备。
2. Linux内核驱动:Linux内核提供了I2C总线的驱动程序,用于与I2C设备进行通信。
通常,这些驱动程序已经包含在内核中,不需要单独安装。
但是,可能需要通过编译内核时打开相应的配置选项来启用I2C支持。
3. I2C设备驱动:每个I2C设备都需要一个设备驱动程序,用于与应用程序进行交互。
这些驱动程序通常由设备制造商提供,也有一些常见的驱动程序包含在Linux内核中。
设备驱动程序将设备上的读写操作映射到I2C总线上的读写操作。
4.用户空间库:为了更方便地编写应用程序,Linux提供了一些用户空间库,用于访问I2C设备。
其中最常用的库是libi2c-dev,它提供了一组API函数,可以通过文件描述符进行I2C通信。
此库通常已经安装在Linux系统中,可以通过编译时链接到应用程序中。
5.应用程序访问:应用程序需要通过打开I2C总线来访问I2C设备。
首先,需要获取I2C总线的文件描述符,可以通过调用open()函数并传递文件路径来实现。
常见的I2C总线路径为"/dev/i2c-x",其中"x"是总线号。
I2C设备驱动介绍

I2C设备驱动介绍I2C(Inter-Integrated Circuit)是一种串行通信协议,用于连接并使多个外部设备与主控制器进行通信。
在嵌入式系统中,I2C设备驱动起着至关重要的作用,负责将操作系统与I2C总线上的设备进行通信,促进数据的传输和交互。
1.初始化:驱动程序需要初始化I2C控制器,包括设置时钟频率、地址范围等。
2.设备注册:设备驱动需要在操作系统中注册I2C设备,以便操作系统能够识别和管理设备。
3.读写操作:驱动程序需要实现读写设备寄存器的功能,包括发送开始和停止信号、以及发送、接收数据等。
4.错误处理:驱动程序需要处理I2C通信过程中可能出现的错误,例如传输失败、设备无响应等情况。
5.中断处理:驱动程序需要支持I2C设备的中断机制,以便及时处理设备的状态变化或数据传输完成的中断信号。
6.电源管理:驱动程序需要支持设备的电源管理功能,包括设备的唤醒、睡眠等操作。
7.设备控制:驱动程序需要实现设备特定的控制功能,例如设置传感器的采样率、配置设备的工作模式等。
8. 虚拟文件系统接口:在Linux系统中,驱动程序通常通过虚拟文件系统接口(如/dev)与用户空间进行交互,提供读写设备寄存器的功能。
1.确定设备:首先,开发者应该确定需要驱动的I2C设备。
这可能包括传感器、EEPROM、显示器等。
2.确定硬件连接:确定I2C设备与主控制器之间的硬件连接和电气特性。
这包括设备的I2C地址、I2C总线上的物理接口等。
3.编写驱动程序:在操作系统中,开发者可以根据设备的文档或芯片厂商提供的驱动程序框架,编写自己的I2C设备驱动程序。
驱动程序需要实现上述提到的功能,并且根据设备的特点进行相应的适配和优化。
4.编译和测试:完成驱动程序的编写后,需要将其编译成与操作系统内核匹配的模块或静态链接库。
然后,通过加载驱动模块或重新编译内核来使驱动程序生效。
最后,进行测试,确保驱动程序在各种场景下的正常运行。
Linux IIC驱动

Linux IIC驱动在嵌入式系统中,IIC设备是非常常见的。
下面就讨论下在LINUX如何实现IIC设备的驱动。
因为IIC的主机适配驱动程序一般芯片厂家在BSP里面都会提供,这里就不详细说明了,下面主要介绍下客户驱动程序如何实现。
首先,我们需要在驱动的初始化函数中注册IIC。
我们需要调用i2c_add_driver 。
这个函数的原形是int i2c_add_driver(struct i2c_driver * IIC),在驱动的exit函数里面需要调用i2c_del_driver释放资源。
下面是注册和释放的例子:static const struct i2c_device_id tsc2003_id[] = {{ “ts_2003”, 0 },{ }};static struct i2c_driver tsc2003_driver = {.probe = tsc2003_probe,.remove = tsc2003_remove,.id_table = tsc2003_id,.driver = {.name = “ts_2003”,},};static int __init tsc2003_init(void){int res;res = i2c_add_driver(&tsc2003_driver);if(res){return res;}return 0;}void __exit tsc2003_exit(void){i2c_del_driver(&tsc2003_driver);}在tsc2003_init这个函数里面调用了i2c_add_driver注册IIC。
下面介绍下i2c_driver这个结构:这个结构里面定义了.probe = tsc2003_probe,那么系统在检测到IIC核心定义了.name指定的设备名。
那么系统会调用tsc2003_probe,并且将struct i2c_client的指针作为参数传递进来。
手把手教你写Linux I2C设备驱动

手把手教你写Linux I2C设备驱动Linux I2C驱动是嵌入式Linux驱动开发人员经常需要编写的一种驱动,因为凡是系统中使用到的I2C设备,几乎都需要编写相应的I2C驱动去配置和控制它,例如RTC实时时钟芯片、音视频采集芯片、音视频输出芯片、EEROM芯片、AD/DA转换芯片等等。
Linux I2C驱动涉及的知识点还是挺多的,主要分为Linux I2C的总线驱动(I2C BUS Driver)和设备驱动(I2C Clients Driver),本文主要关注如何快速地完成一个具体的I2C 设备驱动(I2C Clients Driver)。
关于Linux I2C驱动的整体架构、核心原理等可以在网上搜索其他相关文章学习。
本文主要参考了Linux内核源码目录下的 ./Documentation/i2c/writing-clients 文档。
以手头的一款视频采集芯片TVP5158为驱动目标,编写Linux I2C设备驱动。
1. i2c_driver结构体对象每一个I2C设备驱动,必须首先创造一个i2c_driver结构体对象,该结构体包含了I2C 设备探测和注销的一些基本方法和信息,示例如下:1.static struct i2c_driver tvp5158_i2c_driver = {2. .driver = {3. .name = "tvp5158_i2c_driver",4. },5. .attach_adapter = &tvp5158_attach_adapter,6. .detach_client = &tvp5158_detach_client,7. .command = NULL,8.};其中,name字段标识本驱动的名称(不要超过31个字符),attach_adapter和detac h_client字段为函数指针,这两个函数在I2C设备注册的时候会自动调用,需要自己实现这两个函数,后面将详细讲述。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、I2C概述I2C是philips公司提供的外设总线,I2C有两条数据线,一条是串行数据线SDA、一条是时钟线SCL,使用SDA和SCL实现了数据的交换,便于布线。
I2C总线方便用在EEPROM、实时钟、小型LCD等与CPU外部的接口上。
2、Linux下的驱动思路Linux系统下编写I2c驱动主要有两种方法:一种是把I2C当做普通字符设备来使用;另一种利用Linux下驱动的体系结构来实现。
第一种方法:优点:思路比较直接,不用花费大量时间去了解Linux系统下I2C体系结构缺点:不仅对I2C设备操作要了解,还有了解I2C的适配器操作不仅对I2C设备器和设备操作需要了解,编写的驱动移植性差,内核提供的I2C设备器都没有用上。
第二种方法:第一种的优点就是第二种的缺点,第一种的缺点就是第二种的优点。
3、I2C框架概述Linux的I2C体系结构分为3部分:1)I2C核心I2C核心提供了I2C总线驱动和设备驱动的注册和注销的方法,I2C 通信方法(algorithm)上层,与具体适配器无关的代码,检测设备上层的代码等。
2)I2C总线驱动I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可以直接受CPU来控制。
3)I2C设备驱动I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备端挂在受CPU控制的适配器上,通过I2C适配器与CPU交换数据。
Linux下的I2C体系结构:1)Linux下的I2C体系结构4、I2C设备驱动编写方法首先让我们明白适配器驱动的作用是让我们能够通过它发出标准的I2C时序,在linux内核源代码中driver/I2C/buss包含一些适配器的驱动,例如s3c2410的驱动I2C-s3c2410.c,适配器被加载到内核中,接下的任务就是实现设备驱动的编写。
编写设备驱动的方法主要分为两种方法:第一种:利用设备提供的I2C-dev.c来实现I2C适配器设备文件,然后通过上层应用程序来操作I2C设备器来控制I2C设备。
第二种:为I2C设备独立编写一个设备驱动注意:第二种方法不能用设备提供的I2C-dev.c5、I2C系统下的文件架构在linux下driver下面有个I2C目录,在I2C目录下包含以下文件和文件夹1)I2C-core.c 这个文件实现I2C核心功能以及/proc/bus/I2C*接口2)I2C-dev.c 实现I2C适配器设备文件的功能,每个I2C适配器被分配一个设备,通过适配器访问设备的时候,主设备号是89,此设备号是0-255. I2C-dev.c并没有针对特定设备而设计,只提供了read() write()和ioctl()等接口,应用层可以通过这些接口访问挂在适配器上的I2C设备存储空间和寄存器,并控制I2C设备的工作方式。
3)Chips 这个文件下面包含特定的I2C设备驱动。
4)Busses 这个文件包含一些I2C总线驱动。
5)Algos文件夹下实现了I2C总线适配器的algorithm6、重要结构体1)在内核中的I2C.h这个头文件中对I2C_driver;I2C_client;I2C_adapter和I2C_algorithm 这个四个结构体进行了定义。
理解这4个结构体的作用十分关键。
i2c_adapter结构体struct i2c_adapter {struct module *owner; //所属模块unsigned int id; //algorithm的类型,定义于i2c-id.h,unsigned int class;const struct i2c_algorithm *algo; //总线通信方法结构体指针void *algo_data;//algorithm数据struct rt_mutex bus_lock; //控制并发访问的自旋锁int timeout;int retries; //重试次数struct device dev; //适配器设备int nr;char name[48]; //适配器名称struct completion dev_released; //用于同步struct list_head userspace_clients; //client链表头};I2c_algorithm结构体struct i2c_algorithm {int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);//I2C传输函数指针int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, unioni2c_smbus_data *data);//smbus传输函数指针u32 (*functionality) (struct i2c_adapter *);//返回适配器支持的功能};SMbus大部分基于I2C总线规范,SMbus不需要增加额外引脚。
与I2C总线相比,SMbus 增加了一些新的功能特性,在访问时序也有一定的差异。
i2c_driver结构体struct i2c_driver {unsigned int class;int (*attach_adapter)(struct i2c_adapter *);//依附i2c_adapter函数指针int (*detach_adapter)(struct i2c_adapter *);//脱离i2c_adapter函数指针int (*probe)(struct i2c_client *, const struct i2c_device_id *);int (*remove)(struct i2c_client *);void (*shutdown)(struct i2c_client *);int (*suspend)(struct i2c_client *, pm_message_t mesg);int (*resume)(struct i2c_client *);void (*alert)(struct i2c_client *, unsigned int data);int (*command)(struct i2c_client *client, unsigned int cmd, void*arg);//命令列表struct device_driver driver;const struct i2c_device_id *id_table;//该驱动所支持的设备ID表int (*detect)(struct i2c_client *, struct i2c_board_info *);const unsigned short *address_list;struct list_head clients;};i2c_client结构体struct i2c_client {unsigned short flags;//标志unsigned short addr; //低7位为芯片地址char name[I2C_NAME_SIZE];//设备名称struct i2c_adapter *adapter;//依附的i2c_adapterstruct i2c_driver *driver;//依附的i2c_driverstruct device dev;//设备结构体int irq;//设备所使用的结构体struct list_head detected;//链表头};2)各结构体的作用和他们之间的关系i.I2C_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。
一个i2c适配器需要i2c_algorithm中提供的通信函数来控制适配器上产生特定的访问周期。
缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含其使用的i2c_algorithm的指针。
i2c_algorithm中的关键函数master_xfer()用于产生I2C访问周期需要的信号,以i2c_msg(即I2C消息)为单位。
i2c_msg也很重要,代码清单如下:struct i2c_msg {__u16 addr;//设备地址__u16 flags;//标志__u16 len;//消息长度__u8 *buf;//消息数据};ii.i2c_driver与i2c_client i2c_driver对应一套驱动方法,其主要成员函数是probe(),remove(),suspend(),resume()等,另外id_table是该驱动所支持的I2C设备的ID表。
i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述。
i2c_driver与i2c_client的关系是一对多,一个i2c_driver上可以支持多个同等类型的i2c_client。
i2c_client信息通常在BSP的板文件中通过i2c_board_info填充。
一般在arch/arm目录下的板文件中。
在I2C总线驱动i2c_bus_type的match()函数i2c_device_match()中,会调用i2c_match_id()函数匹配板文件中的ID和i2c_driver所支持的ID表。
iii.i2c_adpater与i2c_client i2c_adpater与i2c_client的关系与I2C硬件体系中适配器和设备的关系一致,即i2c_client依附与i2c_adpater.由于一个适配器上可以连接多个I2C设备,所以就一个i2c_adpter也可以被多个i2c_client依附,i2c_adpter中包括依附与它的i2c_client的链表。
3) 编写驱动需要完成的工作编写具体的I2C驱动时,工程师需要处理的主要工作如下:i.提供I2C适配器的硬件驱动,探测,初始化I2C适配器(如申请I2C的I/O地址和中断号),驱动CPU控制的I2C适配器从硬件上产生。
ii.提供I2C控制的algorithm, 用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋给i2c_adapter的algo指针。
iii.实现I2C设备驱动中的i2c_driver接口,用具体yyy的yyy_probe(),yyy_remove(),yyy_suspend(),yyy_resume()函数指针和i2c_device_id设备ID表赋给i2c_driver的probe,remove,suspend,resume和id_table指针。