i2c scl是如何工作的判断电脑是i2c ps/2 smbus devices

Linux I2C framework(2)_I2C provider
本文从Provider的角度,介绍怎么借助I2C framework管理I2C相关的SOC资源。换句话说,就是怎么编写I2C controller驱动。
2. 关键数据结构和API介绍
2.1 I2C adapter
由“”可知,I2C framework使用struct i2c_adapter抽象I2C控制器,具体如下:
1: /* include/linux/i2c.h */
* i2c_adapter is the structure used to identify a physical i2c bus along
* with the access algorithms necessary to access it.
7: struct i2c_adapter {
struct module *
unsigned int
/* classes to allow probing for */
const struct i2c_algorithm * /* the algorithm to access the bus */
void *algo_
/* data fields that are valid for all devices
struct rt_mutex bus_
/* in jiffies */
/* the adapter device */
char name[48];
struct completion dev_
struct mutex userspace_clients_
struct list_head userspace_
struct i2c_bus_recovery_info *bus_recovery_
该数据结构比较简单,只需要着重关注如下事项:
1)由它的注释可知,struct i2c_adapter是用于标识物理的I2C总线(physical i2c bus),且该总线需要有一套用于访问slave设备的算法(access algorithm)。
2)所谓的access algorithm,就是通过I2C总线发送和接收数据的方法,它保存在algo指针(struct i2c_algorithm,具体可参考后续2.2小节的描述)中。
3)基于I2C传输的特性,不一定每一次总线访问(发送或者接收数据)都会成功,在传输失败的时候,可以选择重试。重试的逻辑由I2C core自行完成,但I2C controller driver需要设定重试的次数,这就是retries字段的意义。另外,有些consumer对结果的返回是有时间要求的,因此不能无节制的重试,timeout字段(单位为jiffies)在retries基础上,增加了时间限制,超过这个时间,就不能重试了。
4)nr,该I2C bus的ID,会体现在sysfs中(/sys/bus/i2c/devices/i2c-n中的‘n’),可由I2C controller driver在注册adapter时指定,或者通过DTS解析(后面会介绍),或者自动分配。
5)class,该I2C bus支持哪些类型的slave device,只有匹配的slave device才能和bus绑定。具体的类型包括(可参考include/linux/i2c.h中的定义和注释):
    I2C_CLASS_HWMON,硬件监控类,如lm_sensors等;
    I2C_CLASS_DDC,DDC是数字显示通道(Digital Display Channel)的意思, 通常用于显示设备信息的获取;
    I2C_CLASS_SPD,存储类的模组;
    I2C_CLASS_DEPRECATED,不再使用的class。
6)dev,我们在“”的第2章提到过,I2C framework将I2C adapter当做了I2C bus中的一类特殊的设备,因此dev变量是它在设备模型中的体现。
2.2 i2c algorithm
由2.1的描述可知,struct i2c_algorithm抽象了通过I2C总线发送和接收数据的方法,其定义如下:
1: /* include/linux/i2c.h */
* struct i2c_algorithm - represent I2C transfer method
* @master_xfer: Issue a set of i2c transactions to the given I2C adapter
defined by the msgs array, with num messages available to transfer via
the adapter specified by adap.
* @smbus_xfer: Issue smbus transactions to the given I2C adapter. If this
is not present, then the bus layer will try and convert the SMBus calls
into I2C transfers instead.
* @functionality: Return the flags that this algorithm/adapter pair supports
from the I2C_FUNC_* flags.
* The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can
* be addressed using the same bus algorithms - i.e. bit-banging or the PCF85
* to name two of the most common.
* The return codes from the @master_xfer field should indicate the type of
* error code that occured during the transfer, as documented in the kernel
* Documentation file Documentation/i2c/fault-codes.
23: struct i2c_algorithm {
/* If an adapter algorithm can't do I2C-level access, set master_xfer
to NULL. If an adapter algorithm can do SMBus access, set
smbus_xfer. If set to NULL, the SMBus protocol is simulated
using common I2C messages */
/* master_xfer should return the number of messages successfully
processed, or a negative value on error */
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data);
/* To determine what the adapter supports */
u32 (*functionality) (struct i2c_adapter *);
1)functionality,通过一个bitmap,告诉调用者该I2C adapter支持的功能,包括(具体可参考include/uapi/linux/i2c.h中的定义和注释):
I2C_FUNC_I2C,支持传统的I2C功能;
I2C_FUNC_10BIT_ADDR,支持10bit地址;
I2C_FUNC_PROTOCOL_MANGLING,支持非标准的协议行为(具体请参考2.3小节的介绍);
I2C_FUNC_NOSTART,支持不需要发送START信号的I2C传输(具体请参考2.3小节的介绍);
I2C_FUNC_SMBUS_xxx,SMBUS相关的功能,不再详细介绍。
2)master_xfer,I2C协议有关的数据传输接口,输入参数是struct i2c_msg类型(可参考2.3小节的介绍)的数组(大小由num指定)。返回值是成功传输的msg的个数,如有错误返回负值。
3)smbus_xfer,SMBUS有关的数据传输接口,如果为NULL,I2C core会尝试使用master_xfer模拟。
2.3 i2c msg
由2.2的介绍可知,I2C传输(读或者写)以i2c msg为单位,该数据结构的定义如下:
1: /* include/uapi/linux/i2c.h */
3: struct i2c_msg {
/* slave address
6: #define I2C_M_TEN
/* this is a ten bit chip address */
7: #define I2C_M_RD
/* read data, from slave to master */
8: #define I2C_M_STOP
/* if I2C_FUNC_PROTOCOL_MANGLING */
9: #define I2C_M_NOSTART
/* if I2C_FUNC_NOSTART */
10: #define I2C_M_REV_DIR_ADDR
/* if I2C_FUNC_PROTOCOL_MANGLING */
11: #define I2C_M_IGNORE_NAK
/* if I2C_FUNC_PROTOCOL_MANGLING */
12: #define I2C_M_NO_RD_ACK
/* if I2C_FUNC_PROTOCOL_MANGLING */
13: #define I2C_M_RECV_LEN
/* length will be first received byte */
/* msg length
/* pointer to msg data
1)addr,I2C slave device的地址。
2)flags,数据传输可携带的flag,包括(具体可参考include/uapi/linux/i2c.h中的定义和注释):
     I2C_M_TEN,支持10-bit的slave地址;
     I2C_M_RD,此次传输是读操作;
     其它flag,下面再详细描述。
3)len,数据传输的长度,单位为byte。
4)buf,数据buf。
2.4 I2C传输有关的flags
正常情况下,如果I2C msg中的flags为0,adapter将按照标准I2C协议操作总线,进行传输操作,即(具体可参考Documentation/i2c/i2c-protocol):
S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
注1:对读操作来说,当master收到slave发送的NA(NACK)消息时,表明已经没有数据可读,应当停止读取(当然,有例外,下面会介绍)。
读写混合操作:
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
否则,可按照flags中指定的行为,进行非标的I2C传输(当然,adapter需要支持,具体可参考2.2小节中有关functionality的介绍),这些flag包括:
1)I2C_M_IGNORE_NAK
读操作的时候,忽略slave返回的NA,把它当做ACK信号,继续读取。还别说,那真有那比较贱的slave,比如电视(通过I2C读取EDID的时候)。
2)I2C_M_NO_RD_ACK
读操作的时候,忽略所有的NACK/ACK信号。(霸气,不过没用过!)
3)I2C_M_NOSTART
读写混合操作的情况下,假如要传输多个msg(以2个为例),如果第二个msg携带了该标志,则不再发送'S Addr Wr/Rd [A]'信号,即从
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
S Addr Rd [A] [Data] NA  Data [A] P
奇奇怪怪的场景啊,用到的时候再仔细阅读kernel的document吧。
4)I2C_M_REV_DIR_ADDR,将读写flag翻转,即读的时候发Wr信号,写的时候发Rd信号。至于为什么这么用,只有天知道。
5)I2C_M_STOP,msg传输完成后forece STOP。不太明白现实意义,用过的同学帮忙科普一下。
6)I2C_M_RECV_LEN,SMBUS的一个flag,意义不明。
2.5 I2C adapter相关的API
I2C adapter定义好之后,要把它注册到kernel中去,相关的API如下:
1: /* include/linux/i2c.h */
3: extern int i2c_add_adapter(struct i2c_adapter *);
4: extern void i2c_del_adapter(struct i2c_adapter *);
5: extern int i2c_add_numbered_adapter(struct i2c_adapter *);
7: static inline u32 i2c_get_functionality(struct i2c_adapter *adap)
8: static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)
9: static inline int i2c_adapter_id(struct i2c_adapter *adap)
11: extern struct i2c_adapter *i2c_get_adapter(int nr);
12: extern void i2c_put_adapter(struct i2c_adapter *adap);
14: /* must call put_device() when done with returned i2c_adapter device */
15: extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
1)i2c_add_adapter和i2c_add_numbered_adapter是I2C adapter的注册接口,它们的区别是:i2c_add_adapter会自动分配adapter ID(adapter->nr,见2.1),i2c_add_numbered_adapter则可以指定ID(adapter->nr需要时有效值,否则会调用i2c_add_adapter自动分配)。
2)i2c_del_adapter将I2C adapter从内核中删除。
3)i2c_get_functionality获取指定adapter所支持的功能,i2c_check_functionality可用于检查指定adapter是否具备指定功能。
4)i2c_adapter_id可以获取指定adapter的ID。
5)i2c_get_adapter通过ID获得指定adapter的指针,由于该接口会尝试调用try_module_get增加模块的引用计数,因此使用完毕后,需要调用i2c_put_adapter将引用计数减去。
6)of_find_i2c_adapter_by_node,通过device的device_node查找相应的adapter结构,使用完后需要调用put_device将adapter->dev所在的模块引用计数减去。
3. 编写I2C controller驱动的步骤
了解了I2C adapter有关的数据结构和API之后,编写I2C控制器驱动就简单多了,主要步骤如下:
1)定义一个struct i2c_algorithm变量,并根据I2C controller的特性,实现其中的回调函数。
2)在DTS文件(一般都放到DTSI)中,定义I2C controller相关的DTS node,例如:
1: /* arch/arm/boot/dts/am33xx.dtsi
3: i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c";
#address-cells = ;
#size-cells = ;
ti,hwmods = "i2c1";
interrupts = ;
status = "disabled";
13: i2c1: i2c@ {
compatible = "ti,omap4-i2c";
#address-cells = ;
#size-cells = ;
ti,hwmods = "i2c2";
interrupts = ;
status = "disabled";
3)在drives/i2c/busses目录下,以i2c-xxx.c的命名方式,编写I2C controller的platform driver,并提供match id、probe、remove等接口。
4)在platform driver的probe接口中,分配一个adapter结构,并进行必要的初始化操作后,调用i2c_add_adapter或者i2c_add_numbered_adapter接口,将其注册到kernel中即可。
4. i2c_add_adapter流程分析
最后,我们简单的看一下i2c adapter的add流程,主要关注三点:adapter ID的分配;设备模型有关的内容;I2C slave device的创建和注册。
4.1 adapter ID的分配
由第2章的描述可知,I2C adapter ID(adapter->nr)可通过两种方法分配,一种是driver直接赋值,并经过下面的函数调用注册adapter(具体可参考drivers/i2c/i2c-core.c):
i2c_add_numbered_adapter--->__i2c_add_numbered_adapter--->i2c_register_adapter
另一种方法,是调用i2c_add_adapter动态分配,如下:
1: /* drivers/i2c/i2c-core.c */
3: int i2c_add_adapter(struct i2c_adapter *adapter)
struct device *dev = &adapter->
if (dev->of_node) {
id = of_alias_get_id(dev->of_node, "i2c");
if (id >= 0) {
adapter->nr =
return __i2c_add_numbered_adapter(adapter);
mutex_lock(&core_lock);
id = idr_alloc(&i2c_adapter_idr, adapter,
__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
mutex_unlock(&core_lock);
if (id < 0)
adapter->nr =
return i2c_register_adapter(adapter);
动态分配也有两种手段:
8~13行,通过of_alias_get_id获取。该方法会通过DTS中的alias解析指定I2C adapter的ID,例如:
&#160;&#160;&#160;&#160;&#160;&#160;&#160; i2c0 = &i2c0;
i2c0: i2c@44e0b000 {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; compatible = "ti,omap4-i2c";
&#160;&#160;&#160;&#160;&#160;&#160;&#160; …
/* arch/arm/boot/dts/am33xx.dtsi */
相关讨论可参考“”留言中的讨论。
16~19,通过idr_alloc分配(idr也是比较好玩的一个功能,有空分析一下,这里不再细述了)。
最后,在较新版本的kernel中,adapter ID的作用仅仅体现在sysfs中,即:
/sys/bus/i2c/devices/i2c-n/
---->/sys/devices/xxxxxxxx.i2c/i2c-n
中的‘n’。
4.2 设备模型有关的流程
adapter ID分配完后,或执行i2c_register_adapter,该接口会在“/sys/devices/xxxxxxxx.i2c/”中创建该adapter的目录(/sys/devices/xxxxxxxx.i2c/i2c-n),如下:
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.bus = &i2c_bus_
adap->dev.type = &i2c_adapter_
res = device_register(&adap->dev);
由此可知,I2C adapter被挂到i2c总线(i2c_bus_type)上了,同时,通过“device_register--->device_add--->bus_add_device--->sysfs_create_link”的调用,在/sys/bus/i2c/devices/中创建对应的符号链接(/sys/bus/i2c/devices/i2c-n/)。支持,I2C adapter有关的设备模型结构,在sysfs中创建完毕。
注2:adapter的目录创建的位置,取决于adapter->dev的parent的设备,通常是I2C控制器所对应的platform设备,如:
static int
omap_i2c_probe(struct platform_device *pdev)
&#160;&#160;&#160; …
&#160;&#160;&#160; adap->dev.parent = &pdev->
&#160;&#160;&#160; …
4.3 I2C slave device的创建和注册
在DTS的支持下,I2C adapter注册的时候,会为它下面所有的slave device创建struct i2c_client结构,并注册到I2C bus上,调用流程是:
i2c_register_adapter--->of_i2c_register_devices--->i2c_new_device
由于牵涉到I2C consumer的DTS结构,该部分内容下一篇文章再介绍。
原创文章,转发请注明出处。蜗窝科技,。PCA9557 具有复位和配置寄存器的远程 8 位 I2C 和 SMBus 低功率 I/O 扩展器 | 德州仪器
(正在供货)
具有复位和配置寄存器的远程 8 位 I2C 和 SMBus 低功率 I/O 扩展器
&(英文內容)
In English
日本語表示
相关终端应用
Special Note
To request samples of the PCA9557, please send an email to:
Other packages can be sampled via the Sample and Buy table below.
This 8-bit I/O expander for the two-line bidirectional bus
(I2C) is designed for 2.3-V to 5.5-V VCC
operation. The device provides general-purpose remote I/O expansion for most microcontroller
families via the I2C interface [serial clock (SCL) and serial data
The PCA9557 consists of one 8-bit configuration (input or output selection), input port,
output port, and polarity inversion (active-high) registers. At power on, the I/Os are configured
as inputs. However, the system master can enable the I/Os as either inputs or outputs by writing to
the I/O configuration bits. The data for each input or output is kept in the corresponding input or
output register. The polarity of the input port register can be inverted with the polarity
inversion register. All registers can be read by the system master.
The device outputs (latched) have high-current drive capability for directly driving
LEDs. The device has low current consumption.
The system master can reset the PCA9557 in the event of a timeout or other improper
operation by asserting a low in the active-low reset (RESET) input. The
power-on reset puts the registers in their default state and initializes the
I2C/SMBus state machine. Asserting RESET causes
the same reset/initialization to occur without depowering the part.
Three hardware pins (A0, A1, and A2) are used to program and vary the fixed
I2C address, allowing up to eight devices to share the same
I2C bus or SMBus.
Low Standby Current Consumption of 1&μA&Max
I2C to Parallel Port Expander
Operating Power-Supply Voltage Range of 2.3&V to 5.5&V
5-V Tolerant I/O Ports
400-kHz Fast I2C Bus
Three Hardware Address Pins Allow for Use of up to Eight Devices on
Lower-Voltage Higher-Performance Migration Path for PCA9556
Input/Output Configuration Register
Polarity Inversion Register
Active-Low Reset Input
Internal Power-On Reset
High-Impedance Open Drain on P0
Power Up With All Channels Configured as Inputs
No Glitch on Power Up
Noise Filter on SCL/SDA Inputs
Latched Outputs With High Current Drive Maximum Capability for Directly Driving
Latch-Up Performance Exceeds 100 mA Per JESD 78, Class II
ESD Protection Exceeds JESD 22
2000-V Human-Body Model (A114-A)
200-V Machine Model (A115-A)
1000-V Charged-Device Model (C101)
All trademarks are the property of their respective owners.
查看更多内容
Voltage Nodes
Max Frequency
I2C Address
Number of I/Os
Operating Temperature Range
Package Group
Package Size: mm2:W x L (PKG)
Pin/Package
2.7 3.3 3.6 5&
-40 to 85&
SOIC SSOP TSSOP TVSOP VQFN&
16VQFN: 14 mm2: 3.5 x 4(VQFN) 16VQFN: 16 mm2: 4 x 4(VQFN) 16TVSOP: 23 mm2: 6.4 x 3.6(TVSOP) 16TSSOP: 32 mm2: 6.4 x 5(TSSOP) 16SSOP: 48 mm2: 7.8 x 6.2(SSOP) 16SOIC: 59 mm2: 6 x 9.9(SOIC)&
16SOIC 16VQFN 16SSOP 16TSSOP 16TVSOP&
相关终端应用 (3)
特色工具和软件
(电路设计和仿真)您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
I2C與SMBus的区别.doc 5页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
&#xe600;下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:150 &&
I2C與SMBus的区别
你可能关注的文档:
··········
··········
I2C与SMBus的区别SMBus是一种二线制串行总线,1996年第一版规范开始商用。它大部分基于I2C总线规范。和I2C一样,SMBus不需增加额外引脚,创建该总线主要是为了增加新的功能特性,但只工作在100KHZ且专门面向智能电池管理应用。它工作在主/从模式:主器件提供时钟,在其发起一次传输时提供一个起始位,在其终止一次传输时提供一个停止位;从器件拥有一个唯一的7或10位从器件地址。 SMBus与I2C总线之间在时序特性上存在一些差别。首先,SMBus需要一定数据保持时间,而I2C总线则是从内部延长数据保持时间。SMBus具有超时功能,因此当SCL太低而超过35ms时,从器件将复位正在进行的通信。相反,I2C采用硬件复位。SMBus具有一种警报响应地址(ARA),因此当从器件产生一个中断时,它不会马上清除中断,而是一直保持到其收到一个由主器件发送的含有其地址的ARA为止。SMBus只工作在从10kHz到最高100KHZ。最低工作频率10kHz是由SMBus超时功能决定的。ComparingtheI2CBustotheSMBus
Abstract:TheI2CbusandtheSMBusarepopular2-wirebusesthatareessentiallycompatiblewitheachother.Normallydevices,bothmastersandslaves,arefreelyinterchangeablebetweenbothbuses.Bothbusesfeatureaddressableslaves(althoughspecificaddressallocationscanvarybetweenthetwo).Thebusesoperateatthesamespeed,pletecompatibilitybetweenbothbusesisensuredonlybelow100kHz.ThisapplicationnotefocusesonthesignificantdifferencesbetweenI2CandSMB.TheI2CbusandtheSMBusarepopular2-wirebusesthatareessentiallycompatiblewitheachother.Normallydevices,bothmastersandslaves,arefreelyinterchangeablebetweenbothbuses.Bothbusesfeatureaddressableslaves(althoughspecificaddressallocationscanvarybetweenthetwobuses).Thebusesoperateatthesamespeed,upto100kHz,buttheI2Cbushasboth400kHzand2MHzversions.Obviously,completecompatibilitybetweenbothbusesusingalldevicesisensuredonlybelow100kHz. Thisapplicationnotefocusesonthesignificantdifferencesbetweenthetwobuses.AlthoughitisassumedthatthereaderhassomeknowledgeoftheI2Cbusand/ortheSMBus,let'sfirstreviewsomeprotocolbasics:StartandStopevents.Theseareespeciallyimportantinthattheyarewaysofsignalingtoaninterfacethatitneedstogotoaninitializedorresetstate.DataandClockmustbehightogenerateStartandStop.Amastercan'tgenerateaStartorStopunlessboththeData(SDAforI2CandSMBDataforSMBus)andClock(SCLforI2CandSMBClkforSMBus)linesarefree(notpulledlow).Thisisaconsequenceofbeinganopen-collectorbus.StartandStopconditionsaretheonlytimestherewillbeatransitionontheDatalinewhileClock
正在加载中,请稍后...

我要回帖

更多关于 如何从i2c 读取 的文章

 

随机推荐