SMBus介绍

  • 系统管理总线协议概要
  • 系统管理总线 关键标记表
  • SMBus接口函数
    • 1. SMBus Quick Command
    • 2. SMBus接收字节函数:i2c_smbus_read_byte()
    • 3. SMBus发送字节函数:i2c_smbus_write_byte()
    • 4. SMBus读取字节函数:i2c_smbus_read_byte_data()
    • 5. SMBus读取字(两字节)函数:i2c_smbus_read_word_data()
    • 6. SMBus写字节函数:i2c_smbus_write_byte_data()
    • 7. SMBus写字(两字节)函数:i2c_smbus_write_word_data()
    • 8. 字的写读过程调用:SMBus Process Call
    • 9. SMBus(Block Read)读块数据:i2c_smbus_read_block_data()
    • 10. SMBus(Block Write)写块数据: i2c_smbus_write_block_data()
    • 11. 块数据的读写过程调用:SMBus Block Write - Block Read Process Call
  • I2C块数据传输(I2C Block Transactions)
    • I2C读块数据(I2C Block Read):i2c_smbus_read_i2c_block_data()
    • I2C写块数据(I2C Block Write)
  • i2c_smbus_xfer()

系统管理总线协议概要

文档参考linux内核文件Documentation\i2c\smbus-protocol
下面是对SMBus协议的总结。它适用于协议的所有版本(1.0、1.1和2.0)。不支持的某些协议特性
在本文档的最后简要说明。
SMBus协议是I2C协议的一个子集,一些适配器只能适配SMBus协议,但是幸运的是,很多设备拥有相同的协议子集——SMBus协议,这使得可以将它们放在SMBus上。

如果您为某些I2C设备编写驱动程序,请尽可能使用SMBus命令(如果设备只使用I2C协议的子集)。这使得在SMBus适配器和I2C适配器上使用设备驱动程序成为可能(在I2C适配器上SMBus命令集会自动转换为I2C,但是在大多数纯SMBus适配器上根本不能处理普通的I2C命令)。

下面是SMBus协议操作的列表,以及执行这些操作的函数。注意,SMBus协议规范中使用的名称通常与这些函数名称不匹配。对于传递单个数据字节的一些操作,使用SMBus协议操作名的函数执行完全不同的协议操作。

每个操作类型对应一个功能标志。在调用事务函数之前,设备驱动程序应该总是检查(只检查一次)相应的功能标志,以确保底层I2C适配器支持相关的事务。(详情参见如下)

<file:Documentation/i2c/functionality>
INTRODUCTION(介绍)
------------
Because not every I2C or SMBus adapter implements everything in the
I2C specifications, a client can not trust that everything it needs
is implemented when it is given the option to attach to an adapter:
the client needs some way to check whether an adapter has the needed
functionality.
(因为并不是每一个I2C或SMBus适配器实现I2C的一切规范,客户端可以不相信一切需要实现时选择连接到适配器:客户端需要一些方法来检查适配器是否所需的功能。)FUNCTIONALITY CONSTANTS(功能常量)
-----------------------
For the most up-to-date list of functionality constants, please check
(最新的功能常量定义如下,请查收。定义在linux-5.18\include\uapi\linux\i2c.h)
<linux/i2c.h>!I2C_FUNC_I2C                    Plain i2c-level commands (Pure SMBusadapters typically can not do these)/普通的iic级别命令(纯SMBus适配器通常不能执行这些操作)I2C_FUNC_10BIT_ADDR             Handles the 10-bit address extensions /处理10位地址扩展I2C_FUNC_PROTOCOL_MANGLING      Knows about the I2C_M_IGNORE_NAK,I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACKflags (which modify the I2C protocol!)I2C_FUNC_NOSTART                Can skip repeated start sequence /可以跳过重复的开始序列I2C_FUNC_SMBUS_QUICK            Handles the SMBus write_quick commandI2C_FUNC_SMBUS_READ_BYTE        Handles the SMBus read_byte commandI2C_FUNC_SMBUS_WRITE_BYTE       Handles the SMBus write_byte commandI2C_FUNC_SMBUS_READ_BYTE_DATA   Handles the SMBus read_byte_data commandI2C_FUNC_SMBUS_WRITE_BYTE_DATA  Handles the SMBus write_byte_data commandI2C_FUNC_SMBUS_READ_WORD_DATA   Handles the SMBus read_word_data commandI2C_FUNC_SMBUS_WRITE_WORD_DATA  Handles the SMBus write_byte_data commandI2C_FUNC_SMBUS_PROC_CALL        Handles the SMBus process_call commandI2C_FUNC_SMBUS_READ_BLOCK_DATA  Handles the SMBus read_block_data commandI2C_FUNC_SMBUS_WRITE_BLOCK_DATA Handles the SMBus write_block_data commandI2C_FUNC_SMBUS_READ_I2C_BLOCK   Handles the SMBus read_i2c_block_data commandI2C_FUNC_SMBUS_WRITE_I2C_BLOCK  Handles the SMBus write_i2c_block_data commandA few combinations of the above flags are also defined for your convenience:为了方便起见,还定义了上述标志的一些组合I2C_FUNC_SMBUS_BYTE             Handles the SMBus read_byteand write_byte commandsI2C_FUNC_SMBUS_BYTE_DATA        Handles the SMBus read_byte_dataand write_byte_data commandsI2C_FUNC_SMBUS_WORD_DATA        Handles the SMBus read_word_dataand write_word_data commandsI2C_FUNC_SMBUS_BLOCK_DATA       Handles the SMBus read_block_dataand write_block_data commandsI2C_FUNC_SMBUS_I2C_BLOCK        Handles the SMBus read_i2c_block_dataand write_i2c_block_data commandsI2C_FUNC_SMBUS_EMUL             Handles all SMBus commands that can beemulated by a real I2C adapter (usingthe transparent emulation layer)In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as
part of I2C_FUNC_PROTOCOL_MANGLING.
在3.5之前的内核版本中,I2C_FUNC_NOSTART是作为I2C_FUNC_PROTOCOL_MANGLING的一部分实现的。ADAPTER IMPLEMENTATION /适配器实现
----------------------
When you write a new adapter driver, you will have to implement a
function callback `functionality'. Typical implementations are given
below. /当你写一个新的适配器驱动,你将不得不实现一个函数回调“功能”。下面给出了典型的实现。A typical SMBus-only adapter would list all the SMBus transactions it
supports. This example comes from the i2c-piix4 driver:static u32 piix4_func(struct i2c_adapter *adapter){return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |I2C_FUNC_SMBUS_BLOCK_DATA;}A typical full-I2C adapter would use the following (from the i2c-pxa
driver):static u32 i2c_pxa_functionality(struct i2c_adapter *adap){return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;}I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
addition of I2C block transactions) which i2c-core can emulate using
I2C_FUNC_I2C without any help from the adapter driver. The idea is
to let the client drivers check for the support of SMBus functions
without having to care whether the said functions are implemented in
hardware by the adapter, or emulated in software by i2c-core on top
of an I2C adapter.CLIENT CHECKING
---------------Before a client tries to attach to an adapter, or even do tests to check
whether one of the devices it supports is present on an adapter, it should
check whether the needed functionality is present. The typical way to do
this is (from the lm75 driver):static int lm75_detect(...){(...)if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |I2C_FUNC_SMBUS_WORD_DATA))goto exit;(...)}Here, the lm75 driver checks if the adapter can do both SMBus byte data
and SMBus word data transactions. If not, then the driver won't work on
this adapter and there's no point in going on. If the check above is
successful, then the driver knows that it can call the following
functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
thumb, the functionality constants you test for with
i2c_check_functionality() should match exactly the i2c_smbus_* functions
which you driver is calling.Note that the check above doesn't tell whether the functionalities are
implemented in hardware by the underlying adapter or emulated in
software by i2c-core. Client drivers don't have to care about this, as
i2c-core will transparently implement SMBus transactions on top of I2C
adapters.CHECKING THROUGH /DEV
---------------------If you try to access an adapter from a userspace program, you will have
to use the /dev interface. You will still have to check whether the
functionality you need is supported, of course. This is done using
the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
below:int file;if (file = open("/dev/i2c-0", O_RDWR) < 0) {/* Some kind of error handling */exit(1);}if (ioctl(file, I2C_FUNCS, &funcs) < 0) {/* Some kind of error handling */exit(1);}if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {/* Oops, the needed functionality (SMBus write_quick function) isnot available! */exit(1);}/* Now it is safe to use the SMBus write_quick command */

系统管理总线 关键标记表

符号 大小 含义
S 1 bit 开始位(开始信号)
P 1 bit 停止位(停止信号)
Rd/Wr 1 bit 读/写 位,高电平(1)是读位,低电平(0)是写位
A, NA 1 bit Accept and reverse accept bit. 按照I2C协议,为应答位,低电平有效
Addr 7 bit I2C 7位地址。注意,可以像往常一样扩展它以获得一个10位的I2C地址。
Comm 8 bit 通常用于选择设备上的寄存器的数据字节,实际就是芯片片内寄存器地址
Data 8 bit 普通的数据字节
Count 8 bit 当为块操作时,为发送数据的字节数
由I2C设备发送的数据,与主机适配器发送的数据相反。

SMBus接口函数

1. SMBus Quick Command

命令功能:发送一个读写位给设备
操作时序:A Addr Rd/Wr [A] P
功能标记宏:I2C_FUNC_SMBUS_QUICK

2. SMBus接收字节函数:i2c_smbus_read_byte()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_read_byte - SMBus "receive byte" protocol* @client: Handle to slave device* This executes the SMBus "receive byte" protocol, returning negative errno* else the byte received from the device.*/
s32 i2c_smbus_read_byte(const struct i2c_client *client)
{union i2c_smbus_data data;int status;status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_READ, 0,I2C_SMBUS_BYTE, &data);return (status < 0) ? status : data.byte;
}
EXPORT_SYMBOL(i2c_smbus_read_byte);

函数功能:不指定设备寄存器从设备读取单个字节。该函数有如下两种应用场景:

  • 1.有些设备比较简单,寄存器资源很少,这个接口就足够了。
  • 2.对于其他相对复杂的设备,如果想读跟先前的SMBus操作中一样的寄存器,可以使用该接口。
    操作时序:S Addr Rd [A] [Data] NA P
    功能标记宏:I2C_FUNC_SMBUS_READ_BYTE

3. SMBus发送字节函数:i2c_smbus_write_byte()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_write_byte - SMBus "send byte" protocol* @client: Handle to slave device* @value: Byte to be sent* This executes the SMBus "send byte" protocol, returning negative errno* else zero on success.*/
s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value)
{return i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
}
EXPORT_SYMBOL(i2c_smbus_write_byte);

函数功能:发送单个字节给设备,跟i2c_smbus_read_byte()相反的功能
操作时序:S Addr Wr [A] Data [A] P
功能标记宏:I2C_FUNC_SMBUS_QUICK

4. SMBus读取字节函数:i2c_smbus_read_byte_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_read_byte_data - SMBus "read byte" protocol* @client: Handle to slave device* @command: Byte interpreted by slave* This executes the SMBus "read byte" protocol, returning negative errno* else a data byte received from the device.*/
s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
{union i2c_smbus_data data;int status;status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_READ, command,I2C_SMBUS_BYTE_DATA, &data);return (status < 0) ? status : data.byte;
}
EXPORT_SYMBOL(i2c_smbus_read_byte_data);

函数功能:从一个指定的寄存器中读取一个字节,该寄存器通过comm byte(芯片片内寄存器地址)指定
操作时序:S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
功能标记宏:I2C_FUNC_SMBUS_READ_BYTE_DATA

5. SMBus读取字(两字节)函数:i2c_smbus_read_word_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_read_word_data - SMBus "read word" protocol* @client: Handle to slave device* @command: Byte interpreted by slave** This executes the SMBus "read word" protocol, returning negative errno* else a 16-bit unsigned "word" received from the device.*/
s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)
{union i2c_smbus_data data;int status;status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_READ, command,I2C_SMBUS_WORD_DATA, &data);return (status < 0) ? status : data.word;
}
EXPORT_SYMBOL(i2c_smbus_read_word_data);

函数功能:跟i2c_smbus_read_byte_data()的功能很相似:从一个指定的寄存器中读取数据,该寄存器通过comm byte(芯片片内寄存器地址)指定,不同的是,读取的数据为一个字(两字节)。
操作时序:S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
功能标记宏:I2C_FUNC_SMBUS_READ_WORD_DATA

注意,有一个方便的函数i2c_smbus_read_word_swap可用于读取两个数据字节相反的位置(不符合SMBus,但非常流行)。
即操作时序为:S Addr Wr [A] Comm [A] S Addr Rd [A] [DataHigh] A [DataLow] NA P
以LM77温度传感器的一个例子佐证,见如下

6. SMBus写字节函数:i2c_smbus_write_byte_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_write_byte_data - SMBus "write byte" protocol* @client: Handle to slave device* @command: Byte interpreted by slave* @value: Byte being written* This executes the SMBus "write byte" protocol, returning negative errno* else zero on success.*/
s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value)
{union i2c_smbus_data data;data.byte = value;return i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_WRITE, command,I2C_SMBUS_BYTE_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_byte_data);

函数功能:与i2c_smbus_read_byte_data()函数的功能恰好相反:给一个设备写一个字节到指定的寄存器中,该寄存器通过comm byte(芯片片内寄存器地址)指定。
操作时序:S Addr Wr [A] Comm [A] Data [A] P
功能标记宏:I2C_FUNC_SMBUS_WRITE_BYTE_DATA
以向mma8653三轴加速度传感器写一个字节数据为例,如下图所示

7. SMBus写字(两字节)函数:i2c_smbus_write_word_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_write_word_data - SMBus "write word" protocol* @client: Handle to slave device* @command: Byte interpreted by slave* @value: 16-bit "word" being written* This executes the SMBus "write word" protocol, returning negative errno* else zero on success.*/
s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command,u16 value)
{union i2c_smbus_data data;data.word = value;return i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_WRITE, command,I2C_SMBUS_WORD_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_word_data);

函数功能:该函数功能恰好与i2c_smbus_read_word_data()函数功能相反:向某个设备的特定寄存器写入2字节(16bit)的数据,该特定寄存器通过设备的片内寄存器地址来指定。
操作时序:S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
功能标记宏:I2C_FUNC_SMBUS_WRITE_WORD_DATA
同样,注意,有一个方便的函数i2c_smbus_write_word_swap可用于以相反的方向写两个字节数据(不符合SMBus,但非常流行)。
即操作时序为:S Addr Wr [A] Comm [A] DataHigh [A] DataLow [A] P

8. 字的写读过程调用:SMBus Process Call

过程调用第一个要求:先写后读,也就是说主设备向从设备写一个字,然后,从设备根据这个来自于主设备的字,在相同的偏移地址处作出相应的反应,发出一个字给主设备,让主设备读取。
过程调用第二个要求:“读写同址” 主设备发起repeat start来启动读的指令时,只需要对该从设备进行重复的寻址,而不需要再发起一个comm code(片内寄存器地址),因为这个片内寄存器地址在前面写的过程已经完成。所以主设备就不需要再告诉从设备读取数据的寄存器地址。所以称读写同址。
操作时序:S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Rd [A] [DataLow] A [DataHigh] NA P
功能标记宏: I2C_FUNC_SMBUS_PROC_CALL
时序见下示意图

9. SMBus(Block Read)读块数据:i2c_smbus_read_block_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_read_block_data - SMBus "block read" protocol* @client: Handle to slave device* @command: Byte interpreted by slave* @values: Byte array into which data will be read; big enough to hold*   the data returned by the slave.  SMBus allows at most 32 bytes.* This executes the SMBus "block read" protocol, returning negative errno* else the number of data bytes in the slave's response.** Note that using this function requires that the client's adapter support* the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality.  Not all adapter drivers* support this; its emulation through I2C messaging relies on a specific* mechanism (I2C_M_RECV_LEN) which may not be implemented.*/
s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command,u8 *values)
{union i2c_smbus_data data;int status;status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_READ, command,I2C_SMBUS_BLOCK_DATA, &data);if (status)return status;memcpy(values, &data.block[1], data.block[0]);return data.block[0];
}
EXPORT_SYMBOL(i2c_smbus_read_block_data);

函数功能:从一个设备的指定偏移地址读取不超过32字节的数据,且读取数据的数量由count指定。
操作时序:S Addr Wr [A] Comm [A]
S Addr Rd [A] [Count] A [Data] A [Data] A … A [Data] NA P
功能标记宏: I2C_FUNC_SMBUS_READ_BLOCK_DATA

10. SMBus(Block Write)写块数据: i2c_smbus_write_block_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/*** i2c_smbus_write_block_data - SMBus "block write" protocol* @client: Handle to slave device* @command: Byte interpreted by slave* @length: Size of data block; SMBus allows at most 32 bytes* @values: Byte array which will be written.** This executes the SMBus "block write" protocol, returning negative errno* else zero on success.*/
s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command,u8 length, const u8 *values)
{union i2c_smbus_data data;if (length > I2C_SMBUS_BLOCK_MAX)length = I2C_SMBUS_BLOCK_MAX;data.block[0] = length;memcpy(&data.block[1], values, length);return i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_WRITE, command,I2C_SMBUS_BLOCK_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_block_data);

函数功能:与i2c_smbus_read_block_data() 函数功能恰恰相反,向某个设备从指定的偏移地址开始写最多32个字节的数据,数据的具体数量由Count指定。
操作时序:S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] … [A] Data [A] P
功能标记宏:I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

11. 块数据的读写过程调用:SMBus Block Write - Block Read Process Call

同 8. 字的写读过程调用:块数据的写读过程调用也有“先写后读”和“读写同址”的要求
操作时序:S Addr Wr [A] Comm [A] Count [A] Data [A] …
S Addr Rd [A] [Count] A [Data] … A P
功能标记宏:I2C_FUNC_SMBUS_BLOCK_PROC_CALL

I2C块数据传输(I2C Block Transactions)

I2C块数据传输是被SMBus layer支持的,但是不属于SMBus协议的范畴。
I2C块数据传输没有数据大小的限制,但是SMBus块数据的传输有32字节大小的限制。

I2C读块数据(I2C Block Read):i2c_smbus_read_i2c_block_data()

函数定义实现在linux-5.1.18\drivers\i2c\i2c-core-smbus.c

/* Returns the number of read bytes */
s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command,u8 length, u8 *values)
{union i2c_smbus_data data;int status;if (length > I2C_SMBUS_BLOCK_MAX)length = I2C_SMBUS_BLOCK_MAX;data.block[0] = length;status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_READ, command,I2C_SMBUS_I2C_BLOCK_DATA, &data);if (status < 0)return status;memcpy(values, &data.block[1], data.block[0]);return data.block[0];
}
EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);

函数功能:从某个设备指定的片内寄存器地址开始读块数据
函数参数:client:操作的从设备;command:片内寄存器偏移地址;length:要读块数据的长度;values:存放读取的块数据的内存。
操作时序:S Addr Wr [A] Comm [A]
S Addr Rd [A] [Data] A [Data] A … A [Data] NA P
功能标记宏:I2C_FUNC_SMBUS_READ_I2C_BLOCK

I2C写块数据(I2C Block Write)

s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command,u8 length, const u8 *values)
{union i2c_smbus_data data;if (length > I2C_SMBUS_BLOCK_MAX)length = I2C_SMBUS_BLOCK_MAX;data.block[0] = length;memcpy(data.block + 1, values, length);return i2c_smbus_xfer(client->adapter, client->addr, client->flags,I2C_SMBUS_WRITE, command,I2C_SMBUS_I2C_BLOCK_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);

函数功能:从某个设备指定的片内寄存器地址开始写块数据
函数参数:client:操作的从设备;command:片内寄存器偏移地址;length:要读块数据的长度;values:存放读取的块数据的内存。

i2c_smbus_xfer()

上面的一系列函数最终都是调用的i2c_smbus_xfer()函数,i2c_smbus_xfer()函数代码如下:

/*** i2c_smbus_xfer - execute SMBus protocol operations* @adapter: Handle to I2C bus* @addr: Address of SMBus slave on that bus* @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC)* @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE* @command: Byte interpreted by slave, for protocols which use such bytes* @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL* @data: Data to be read or written* This executes an SMBus protocol operation, and returns a negative* errno code else zero on success.*/
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,unsigned short flags, char read_write,u8 command, int protocol, union i2c_smbus_data *data)
{s32 res;i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);res = __i2c_smbus_xfer(adapter, addr, flags, read_write,command, protocol, data);i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);return res;
}

s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,unsigned short flags, char read_write,u8 command, int protocol, union i2c_smbus_data *data)
{unsigned long orig_jiffies;int try;s32 res;/* If enabled, the following two tracepoints are conditional on* read_write and protocol.*/trace_smbus_write(adapter, addr, flags, read_write,command, protocol, data);trace_smbus_read(adapter, addr, flags, read_write,command, protocol);flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;if (adapter->algo->smbus_xfer) {/* Retry automatically on arbitration loss */orig_jiffies = jiffies;for (res = 0, try = 0; try <= adapter->retries; try++) {res = adapter->algo->smbus_xfer(adapter, addr, flags,read_write, command,protocol, data);if (res != -EAGAIN)break;if (time_after(jiffies,orig_jiffies + adapter->timeout))break;}if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)goto trace;/** Fall back to i2c_smbus_xfer_emulated if the adapter doesn't* implement native support for the SMBus operation.*/}res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,command, protocol, data);trace:/* If enabled, the reply tracepoint is conditional on read_write. */trace_smbus_reply(adapter, addr, flags, read_write,command, protocol, data, res);trace_smbus_result(adapter, addr, flags, read_write,command, protocol, res);return res;
}

系统管理总线(SMBus)介绍相关推荐

  1. SMBus---------System Management Bus(系统管理总线)

    SMBus是System Management Bus(系统管理总线)的缩写,是1995年由Intel提出的.SMBus只有两根信号线:双向数据线和时钟信号线.PCI插槽上也给SMBus预留了两个引脚 ...

  2. lin通讯从节点同步间隔场_低成本总线技术——LIN总线协议规范介绍

    专注原创汽车技术干货分享,小编求关注哦! 在前面一篇文章中"野百合也有春天"--低成本总线LIN介绍介绍了LIN总线的发展历程及其基本概念.现在这篇文章主要介绍LIN总线协议规范. ...

  3. (4)ZYNQ AXI4总线协议介绍

    1.1 ZYNQ AXI4总线协议介绍 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)ZYNQ AXI4总线协议介绍: 5)结束语. 1.1.2 本节引言 " ...

  4. 片上总线Wishbone 学习(二)Wishbone总线标准介绍

    片上总线Wishbone 学习(二)Wishbone总线标准介绍 Wishbone总线产生.发展 市场是推动技术前进的主要动力,人们对各种电子产品不断的更新,更好,更完美的追求刺激了技术的不断升级和创 ...

  5. CAN FD总线详细介绍

    文章目录 前言 一.CAN FD简介 1.1 CAN FD是什么? 1.2 为什么要CAN FD? 1.3 CAN FD的特点 二.CAN FD协议 2.1 CAN FD帧结构 2.1.1 帧起始 2 ...

  6. 关于汽车CAN总线的介绍

    汽车CAN总线 是一种用于车辆电子控制系统的通信协议,它的全称为控制器局域网(Controller Area Network),是由Bosch公司在1986年研发的.CAN总线最初被用于汽车电子控制系 ...

  7. AXI4(AXI-full)总线详细介绍

    AXI4(AXI-full)总线详细介绍 1.1 什么是AXI 1.1.1 zynq的三种AXI总线 1.1.2 AXI的三种接口 1.1.3 AXI协议 1.1.3.1 AXI握手协议 1.1.3. ...

  8. 【硬件】DELL服务器硬件监控及DELL系统管理工具OMSA介绍

    1.1.1. DELL服务器硬件监控及DELL系统管理工具OMSA介绍 本文介绍采用使用Nagios和OMSA监控DELL服务器的硬件健康状态,Nagios监控的方式是NRPE模式,需要配置check ...

  9. 【Avalon总线】1.Avalon总线总体介绍

    最近在学习Avalon总线相关的知识,所以在学习的过程中写下了这一系列的博文.文章主要是根据ALTERA公司的文档写的.文章中如有错误请指出,谢谢! 1 Avalon总线总体介绍 Avalon总线提供 ...

最新文章

  1. cannot find package “github.com/coreos/go-systemd/journal”
  2. 哈尔滨工业大学计算机改专业课,哈尔滨工业大学计算机专业课 复试 2013HITCS
  3. 如何php防止XSS攻击
  4. redis缓存存在的隐患及其解决方案
  5. SDR、DDR、QDR存储器的比较
  6. ArcEngine读取数据(数据访问)-转载
  7. 用MediaPlayer做个带进度条可后台的音乐播放器
  8. Visual Entity 手册
  9. 软件测试bug文档模板,软件bug测试记录模板
  10. SAP NetWeaver 平台介绍
  11. MAC上安装JDK后的所在目录
  12. VB.Net程序设计:分页控件
  13. 服务器安装虚拟声卡,虚拟声卡安装使用 虚拟声卡注意事项
  14. HART转PROFIBUS DP(V0)+RS485方法
  15. 计算机网络telnet命令作用,telnet命令使用方法详解
  16. Agilent GeneSpring GX V11.5_win32_win64扩展生物学分析软件
  17. Snaker工作流学习(二)
  18. 又是一年数博会,你了解多少呢?
  19. 在canvas上实现3D效果
  20. 高等数学——导数的定义和常见导数

热门文章

  1. dhcp接口模式/全局模式
  2. 基于ADAU1452DSP数字音频信号处理
  3. 好物周刊#1:提示工程师养成指南
  4. 无纸化办公系统--工作总结
  5. 未来纽约 7500 个电话亭将悉数改为 Wi-Fi 热点
  6. 渗透测试基础- - -web日志分析
  7. 转载:全局拉普拉斯平滑之(1)Strucutre extraction from texture via relative total variation及稀疏矩阵求解...
  8. Android实习报告
  9. selenium实战-同步网易云音乐歌单到qq音乐
  10. 【seo知识】用户的搜索意图(intention of SE users)