GPIO 控制器特定于设备的方法 (_DSM)
为了支持 Windows 中常规用途 I/O (GPIO) 驱动程序堆栈与平台固件之间的各种特定于设备类的通信,Microsoft 定义了在 ACPI 命名空间的 GPIO 控制器下包含的特定于设备的方法 (_DSM)。
目前,此方法定义两个函数:
函数索引 0:所有 _DSM 方法都需要提供的标准查询函数。
函数索引 1:ActiveBoth 极性函数,用于通知 GPIO 堆栈控制器上未断言为逻辑低的任何 ActiveBoth 引脚。 GPIO 堆栈假设 ActiveBoth 引脚断言为逻辑低,因此此函数允许平台替代特定引脚的默认值。
GUID 定义
GPIO 控制器 _DSM 方法的 GUID 定义为:
{4F248F40-D5E2-499F-834C-27758EA1CD3F}
函数 0
每个 _DSM 的函数 0 都是一个返回支持的函数索引集的查询函数,始终是必需的。 有关函数 0 的定义,请参阅 ACPI 5.0 规范中的第 9.14.1 节“_DSM(设备特定方法)”。
函数 1
GPIO 控制器 _DSM 方法的函数 1 的参数定义如下:
参数
Arg0:GPIO 控制器 _DSM 的 UUID
// GUID: {4F248F40-D5E2-499F-834C-27758EA1CD3F}
DEFINE_GUID (GPIO_CONTROLLER _DSM_GUID,
0x4f248f40, 0xd5e2, 0x499f, 0x83, 0x4c, 0x27, 0x75, 0x8e, 0xa1, 0xcd. 0x3f);
Arg1:修订 ID
#define GPIO_CONTROLLER _DSM_REVISION_ID 0
Arg2:ActiveBoth 断言极性的函数索引:
#define GPIO_CONTROLLER_DSM_ACTIVE_BOTH_POLARITY_FUNCTION_INDEX 1
Arg3:包为空(未使用)
返回值
一个整数包,每个整数分别是 GPIO 控制器上引脚的控制器相对引脚数,即:
定义为 ActiveBoth 中断,并且
其断言状态不是逻辑低(换句话说,是逻辑高)。
例如,用户按下该按钮时,如果模拟的 ActiveBoth 引脚连接到一个推送按钮设备,则引脚将进入断言状态(引脚处的逻辑高输入级别),并在用户按住按钮时保持断言状态。 当用户放开按钮时,引脚状态将更改为未断言(逻辑低输入级别)。
ASL 代码示例
以下 ASL 代码示例标识一组初始极性为 ActiveHigh 的 GPIO 引脚。
//
// _DSM - Device-Specific Method
//
// Arg0: UUID Unique function identifier
// Arg1: Integer Revision Level
// Arg2: Integer Function Index (0 = Return Supported Functions)
// Arg3: Package Parameters
//
Function(_DSM,{BuffObj, PkgObj, IntObj},{BuffObj, IntObj, IntObj, PkgObj})
{
//
// Switch based on which unique function identifier was passed in
//
//
// GPIO CLX UUID
//
If(LEqual(Arg0,ToUUID("4F248F40-D5E2-499F-834C-27758EA1CD3F")))
{
switch(Arg2)
{
//
// Function 0: Return supported functions, based on
// revision
//
case(0)
{
// Revision 0+: Functions 0 & 1 are supported
return (Buffer() {0x3})
}
//
// Function 1: For emulated ActiveBoth controllers,
// returns a package of controller-relative pin
// numbers. Each corresponding pin will have an
// initial polarity of ActiveHigh.
//
// A pin number of 0xffff is ignored.
//
case(1)
{
// Marks pins 0x28, 0x29 and 0x44 to be ActiveHigh.
Return (Package() {0x28, 0x29, 0x44})
}
//
// Unrecognized function for this revision
//
default
{
BreakPoint
}
}
}
else
{
//
// If this is not one of the UUIDs we recognize, then return
// a buffer with bit 0 set to 0 to indicate that no functions
// are supported for this UUID.
//
return (Buffer() {0})
}
}