ACPI 中文文档ACPI 中文文档
首页
第 1 章
第 2 章
第 3 章
第 4 章
第 5 章
第 6 章
第 7 章
第 8 章
第 9 章
第 10 章
第 11 章
第 12 章
第 13 章
第 14 章
第 15 章
第 16 章
第 17 章
第 18 章
第 19 章
第 20 章
第 21 章
附录 A
首页
第 1 章
第 2 章
第 3 章
第 4 章
第 5 章
第 6 章
第 7 章
第 8 章
第 9 章
第 10 章
第 11 章
第 12 章
第 13 章
第 14 章
第 15 章
第 16 章
第 17 章
第 18 章
第 19 章
第 20 章
第 21 章
附录 A
  • 第 13 章

    • 总览
    • 13.1. SMBus 概述
    • 13.2. 从 ASL 代码访问 SMBus
    • 13.3. 使用 SMBus 协议

13.3. 使用 SMBus 协议

本节提供有关如何使用各类 SMBus 协议从 AML 访问 SMBus 设备的信息和示例。

13.3.1. 读取/写入 Quick(SMBQuick)

SMBus 读取/写入 Quick 协议(SMBQuick)通常用于通过设备特定的二进制命令(例如 ON 和 OFF)控制简单设备。该协议不使用命令值,因此在字段定义中只能指定单个元素(位于偏移量 0)。该协议不传输数据。

下面的 ASL 代码说明了应如何访问支持读取/写入 Quick 协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100) // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
    AccessAs(BufferAcc, SMBQuick)           // Use the SMBus Read/Write Quick protocol
    FLD0, 8                                 // Virtual register at command value 0.
}

/* Create the SMBus data buffer */

Name(BUFF, Buffer(34){})                    // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, OB1)            // OB1 = Status (Byte)

/* Signal device (e.g. OFF) */
Store(FLD0, BUFF)                           // Invoke Read Quick transaction
If(LEqual(OB1, 0x00)) {...}                 // Successful?

/* Signal device (e.g. ON) */
Store(BUFF, FLD0) // Invoke Write Quick transaction

在本示例中,定义了位于偏移量 0 的单个字段元素(FLD0)来表示该协议的读/写位。对 FLD0 的访问将导致对该设备发生一次 SMBus 事务。读取该字段会产生一次 Read Quick,而写入该字段会产生一次 Write Quick。无论哪种情况,都不会传输数据——对该寄存器的访问仅用作调用该事务的一种机制。

13.3.2. 发送/接收字节(SMBSendReceive)

SMBus 发送/接收字节协议(SMBSendReceive)传输单个字节的数据。与读/写快速命令一样,此协议不使用命令值,因此在字段定义中只能指定单个元素(位于偏移量 0 处)。

以下 ASL 代码说明了应如何访问支持发送/接收字节协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100) // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
AccessAs(BufferAcc, SMBSendReceive)    // Use the SMBus Send/Receive Byte protocol
FLD0, 8                                // Virtual register at command value 0.
}

// Create the SMBus data buffer

Name(BUFF, Buffer(34){})               // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)      // STAT = Status (Byte)
CreateByteField(BUFF, 0x02, DATA)      // DATA = Data (Byte)

// Receive a byte of data from the device

Store(FLD0, BUFF)                      // Invoke a Receive Byte transaction

If(LEqual(STAT, 0x00))                 // Successful?

{
                                       // DATA = Received byte...
}

// Send the byte '0x16' to the device
Store(0x16, DATA)                      // Save 0x16 into the data buffer
Store(BUFF, FLD0)                      // Invoke a Send Byte transaction

在此示例中,定义了位于偏移量 0 处的单个字段元素(FLD0)来表示该协议的数据字节。对 FLD0 的访问将导致对该设备发生一次 SMBus 事务。读取该字段会产生一次接收字节事务,而向该字段写入则会产生一次发送字节事务。

13.3.3. 读/写字节(SMBByte)

SMBus 读/写字节协议(SMBByte)同样传输单个字节的数据。但与发送/接收字节不同,此协议使用命令值来引用最多 256 个字节大小的虚拟寄存器。

以下 ASL 代码说明了应如何访问支持读/写字节协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100)  // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
    AccessAs(BufferAcc, SMBByte)             // Use the SMBus Read/Write Byte protocol
    FLD0, 8,                                 // Virtual register at command value 0.
    FLD1, 8,                                 // Virtual register at command value 1.
    FLD2, 8                                  // Virtual register at command value 2.
}

                                             // Create the SMBus data buffer
Name(BUFF, Buffer(34){}) // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT) // STAT = Status (Byte)
CreateByteField(BUFF, 0x02, DATA) // DATA = Data (Byte)

// Read a byte of data from the device using command value 1
Store(FLD1, BUFF) // Invoke a Read Byte transaction
If(LEqual(STAT, 0x00)) // Successful?
{
                                             // DATA = Byte read from FLD1...
}

// Write the byte '0x16' to the device using command value 2
Store(0x16, DATA)                            // Save 0x16 into the data buffer
Store(BUFF, FLD2)                            // Invoke a Write Byte transaction

在此示例中,定义了三个字段元素(FLD0、FLD1 和 FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。对任一字段元素的访问都将导致对该设备发生一次 SMBus 事务。读取 FLD1 会产生一次命令值为 1 的读字节事务,而向 FLD2 写入会产生一次命令值为 2 的写字节事务。

13.3.4. 读/写字(SMBWord)

SMBus 读/写字协议(SMBWord)传输 2 字节的数据。此协议同样使用命令值来引用最多 256 个字大小的虚拟设备寄存器。

以下 ASL 代码说明了应如何访问支持读/写字协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100)  // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
    AccessAs(BufferAcc, SMBWord)         // Use the SMBus Read/Write Word protocol
    FLD0, 8,                             // Virtual register at command value 0.
    FLD1, 8,                             // Virtual register at command value 1.
    FLD2, 8                              // Virtual register at command value 2.
}

                                         // Create the SMBus data buffer
Name(BUFF, Buffer(34){})                 // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)        // STAT = Status (Byte)
CreateWordField(BUFF, 0x02, DATA)        // DATA = Data (Word)

// Read two bytes of data from the device using command value 1
Store(FLD1, BUFF)                        // Invoke a Read Word transaction
If(LEqual(STAT, 0x00))                   // Successful?
{
                                         // DATA = Word read from FLD1...
}

// Write the word '0x5416' to the device using command value 2
Store(0x5416, DATA)                      // Save 0x5416 into the data buffer
Store(BUFF, FLD2)                        // Invoke a Write Word transaction

在此示例中,定义了三个字段元素(FLD0、FLD1 和 FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。对任一字段元素的访问都将导致对该设备发生一次 SMBus 事务。读取 FLD1 会产生一次命令值为 1 的读字事务,而向 FLD2 写入会产生一次命令值为 2 的写字事务。

请注意,尽管访问每个字段元素时传输的是一个字(16 位)数据,这些字段仍被列为每个 8 位。实际数据大小由协议决定。每个字段元素都声明为 8 位长度,以便使命令值与字节偏移量等效。

13.3.5. 读/写块(SMBBlock)

SMBus 读/写块协议(SMBBlock)传输可变大小(0-32 字节)的数据。此协议使用命令值来引用最多 256 个块大小的虚拟寄存器。

以下 ASL 代码说明了应如何访问支持读/写块协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100) // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
  AccessAs(BufferAcc, SMBBlock)           // Use the SMBus Read/Write Block protocol
  FLD0, 8,                                // Virtual register at command value 0.
  FLD1, 8,                                // Virtual register at command value 1.
  FLD2, 8                                 // Virtual register at command value 2.
}

// Create the SMBus data buffer
Name(BUFF, Buffer(34){})                  // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)         // STAT = Status (Byte)
CreateByteField(BUFF, 0x01, SIZE)         // SIZE = Length (Byte)
CreateField(BUFF, 0x10, 256, DATA)        // DATA = Data (Block)

// Read block data from the device using command value 1
Store(FLD1, BUFF)                         // Invoke a Read Block transaction
If(LEqual(STAT, 0x00))                    // Successful?
{
                                          // SIZE = Size (number of bytes)
                                          // of the block data read from FLD1...
                                          // DATA = Block data read from FLD1...
 }

 // Write the block 'TEST' to the device using command value 2
 Store("TEST", DATA)                       // Save "TEST" into the data buffer
 Store(4, SIZE)                            // Length of valid data in the data buffer
 Store(BUFF, FLD2)                         // Invoke a Write Word transaction

在此示例中,定义了三个字段元素(FLD0、FLD1 和 FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。对任一字段元素的访问都将导致对该设备发生一次 SMBus 事务。读取 FLD1 会产生一次命令值为 1 的读块事务,而向 FLD2 写入会产生一次命令值为 2 的写块事务。

13.3.6. 字处理调用(SMBProcessCall)

SMBus 处理调用协议(SMBProcessCall)双向传输 2 字节的数据(执行一次写字后再执行一次读字,作为一个原子事务)。此协议使用命令值来引用最多 256 个字大小的虚拟寄存器。

以下 ASL 代码说明了应如何访问支持处理调用协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100) // SMBus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
    AccessAs(BufferAcc, SMBProcessCall)     // Use the SMBus Process Call protocol
    FLD0, 8,                                // Virtual register at command value 0.
    FLD1, 8,                                // Virtual register at command value 1.
    FLD2, 8                                 // Virtual register at command value 2.
}

// Create the SMBus data buffer
Name(BUFF, Buffer(34){})                    // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)           // STAT = Status (Byte)
CreateWordField(BUFF, 0x02, DATA)           // DATA = Data (Word)

// Process Call with input value '0x5416' to the device using command value 1
Store(0x5416, DATA)                         // Save 0x5416 into the data buffer
Store(Store(BUFF, FLD1), BUFF)              // Invoke a Process Call transaction
If(LEqual(STAT, 0x00))                      // Successful?
{
                                            // DATA = Word returned from FLD1...
}

在此示例中,定义了三个字段元素(FLD0、FLD1 和 FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。对任一字段元素的访问都将导致对该设备发生一次 SMBus 事务。读取或写入 FLD1 都会产生一次命令值为 1 的处理调用事务。请注意,与其他协议不同,处理调用在单个原子事务中同时涉及一次写操作和一次读操作。这意味着,SMBus 数据缓冲区的 Data 元素会在事务调用之前被设置为输入值,并在事务成功完成后保存输出值。

13.3.7. 块处理调用(SMBBlockProcessCall)

SMBus 块写入-读取块处理调用协议(SMBBlockProcessCall)双向传输一个数据块(执行一次写块后再执行一次读块,作为一个原子事务)。可传输的数据总量上限为 32 字节。此协议使用命令值来引用最多 256 个块大小的虚拟寄存器。

以下 ASL 代码说明了应如何访问支持处理调用协议的设备:

OperationRegion(SMBD, SMBus, 0x4200, 0x100)  // SMbus device at slave address 0x42
Field(SMBD, BufferAcc, NoLock, Preserve)
{
    AccessAs(BufferAcc, SMBBlockProcessCall) // Use the Block Process Call protocol
    FLD0, 8, // Virtual register representing a command value of 0
    FLD1, 8 // Virtual register representing a command value of 1
}

// Create the SMBus data buffer as BUFF
Name(BUFF, Buffer(34)())           // Create SMBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)  // STAT = Status (Byte)
CreateByteField(BUFF, 0x01, SIZE)  // SIZE = Length (Byte)
CreateField(BUFF, 0x10, 256, DATA) // Data (Block)

// Process Call with input value "ACPI" to the device using command value 1

Store("ACPI", DATA)                // Fill in outgoing data
Store(8, SIZE)                     // Length of the valid data
Store(Store(BUFF, FLD1), BUFF)     // Execute the PC
if (LEqual(STAT, 0x00))            // Test the status
{
                                   // BUFF now contains information returned
                                   // from PC
                                   // SIZE now equals size of data returned
}
Prev
13.2. 从 ASL 代码访问 SMBus