如何为连接到 I2C gpio 扩展器的虚拟 mdio-gpio 设备配置 ACPI *.asl
How to configure ACPI *.asl for a virtual mdio-gpio device connected to a I2C gpio expander
我正在使用 Q7 模块 (x86) 并尝试在 Linux 上使用 ACPI SSDT 覆盖配置我们的外围设备。但我为此苦苦挣扎。我想我误解了 ACPI 的一些核心概念。
问题
CPU -> I2C -> PCA9575 GPIO Expander -> virtual,mdio-gpio -> Ethernet Phy
什么有效
DefinitionBlock ("abc.asl", "SSDT", 2, "test", "HAL", 2)
{
External (\_SB_.PCI0.D01D, DeviceObj)
Scope (\_SB.PCI0.D01D)
{
Device (ABC0)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2 (
0x20, // SlaveAddress : I2C Address
ControllerInitiated, // SlaveMode : ControllerInitiated
100000, // ConnectionSpeed : max Bus Speed for this device
AddressingMode7Bit, // AddressingMode : Adress Mode
"\_SB.PCI0.D01D", // ResourceSource : I2C host controller
0x00, // ResourceSourceIndex : must be 0
ResourceConsumer, // ResourceUsage : must be ResourceConsumer
, // DescriptorName : optional name for integer value which is an offset to a buffer field...
Exclusive // Shared : Shared or Exclusive
,) // VendorData : optional field
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "nxp,pca9575" },
Package () { "gpio-line-names", Package ()
{ "LED_Red",
"",
"MDC",
"MDIO",
}
},
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-red", "LED0" },
Package () { "mdc-gpios", "MDC0" },
Package () { "mdio-gpios", "MDIO" },
}
})
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"gpio-hog", 1},
Package () {"gpios", Package () {0, 1}},
Package () {"output-low", 1},
}
})
... <placeholder for virtual,mdio-gpiocode here> ...
}
}
}
识别PCA9575 GPIO扩展器并在Linux中注册为gpiochip。 LED 固定为低电平且“被占用”。看来这部分并没有完全错。
什么不起作用
我将这段代码插入到占位符中
Device (MD00)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "virtual,mdio-gpio" },
Package () {"gpios", Package () {^MDC0, 2, 0,
^MDIO, 3, 0,}},
}
})
}
但是当我尝试通过 configfs 加载此文件时,我可以在 dmesg
中看到一条错误消息,指出 _CRS 字段中定义的资源的兼容字段丢失。但我什至没有定义 _CRS 字段。
我也不确定我的 GPIO 是否定义正确。我无法使用 Package () {"gpios", Package () {0, 1}},
命令设置拉取模式。
我问自己,GPIO Expander Ports是否应该在MDO Device中再次定义为GgioIo Structures?
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2}
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3}
})
它似乎也不起作用,我很困惑。我不确定我是否正确使用了 GPIO PCA9575 驱动程序。我在哪里可以配置 ACPI 中的 pull bias?驱动程序从 of_
加载配置,但我不知道在 ACPI 中的何处定义它。我希望这里有人有想法。
首先让我们看看设计的主要架构:
+-------------------+
| HOST | +------+
| MDIO <------>+ MDIO |
| Intf | | Phy |
| | +--^---+
| +------+ | | +-----+
| | I²C | | | | LED |
| | host | | | +--^--+
| +--^---+ | | |
| | | +--+---+ |
+-------------------+ | I²C | |
+----------------------> GPIO +------+
+------+
从这张示意图中我们可以看出设备是如何相互关联的。现在让我们转到 ACPI 表示。一开始我们需要定义 I²C GPIO expander。从 meta-acpi 项目中的示例我们可以找到如何描述 PCA9535。假设我们找到了 I²C 主机控制器设备(\_SB_.PCI0.D01D
根据您的 post)并且您有没有锁定 IRQ 事件的扩展器这一事实,以下是原始 ASL 摘录和如何将其与驱动程序中的正确配置:
Device (ABC0)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP PCA9575 GPIO expander")
Name (RBUF, ResourceTemplate()
{
I2cSerialBusV2(0x0020, ControllerInitiated, 400000,
AddressingMode7Bit, "\_SB.PCI0.D01D",
0x00, ResourceConsumer, , Exclusive, )
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,pca9575"},
Package () {"gpio-line-names", Package () {
"LED_Red",
"",
"MDC",
"MDIO",
}},
}
})
Method (_CRS, 0, NotSerialized)
{
Return (RBUF)
}
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
}
这段摘录为我们提供了系统中的新GPIO芯片,其资源可以被其他人消耗。
例如,在您的 Virtual MDIO Phy 案例中(另见 _DSD Device Properties Related to GPIO)
Device (MD00)
{
Name (_HID, "PRP0001")
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2} // pin 2
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3} // pin 3
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", "virtual,mdio-gpio" },
Package () {
"gpios", Package () {
^MD00, 0, 0, 0, // index 0 in _CRS -> pin 2
^MD00, 1, 0, 0, // index 1 in _CRS -> pin 3
}
},
}
})
}
现在是时候查看 LED 绑定代码了。为了澄清起见,hogging 是指当您希望 GPIO provider 到 consume 资源本身时。这很可能不是你的情况。最好将其与 LED GPIO 驱动程序连接:
Device (LEDS)
{
Name (_HID, "PRP0001")
Name (_DDN, "GPIO LEDs device")
Name (_CRS, ResourceTemplate () {
GpioIo (
Exclusive, // Not shared
PullUp, // Default off
0, // Debounce timeout
0, // Drive strength
IoRestrictionOutputOnly, // Only used as output
"\_SB.PCI0.D01D.ABC0", // GPIO controller
0) // Must be 0
{
0, // LED_Red
}
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", Package() { "gpio-leds" } },
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-0", "LED0" },
}
})
/*
* For more information about these bindings see:
* Documentation/devicetree/bindings/leds/common.yaml,
* Documentation/devicetree/bindings/leds/leds-gpio.yaml and
* Documentation/firmware-guide/acpi/gpio-properties.rst.
*/
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "label", "red" },
Package () { "default-state", "on" },
Package () { "gpios", Package () { ^LEDS, 0, 0, 1 } }, // active low
}
})
}
您也可以在 Whosebug 网站上查看 (从给定的 link 开始,还有对其余部分的引用)。
我正在使用 Q7 模块 (x86) 并尝试在 Linux 上使用 ACPI SSDT 覆盖配置我们的外围设备。但我为此苦苦挣扎。我想我误解了 ACPI 的一些核心概念。
问题
CPU -> I2C -> PCA9575 GPIO Expander -> virtual,mdio-gpio -> Ethernet Phy
什么有效
DefinitionBlock ("abc.asl", "SSDT", 2, "test", "HAL", 2)
{
External (\_SB_.PCI0.D01D, DeviceObj)
Scope (\_SB.PCI0.D01D)
{
Device (ABC0)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2 (
0x20, // SlaveAddress : I2C Address
ControllerInitiated, // SlaveMode : ControllerInitiated
100000, // ConnectionSpeed : max Bus Speed for this device
AddressingMode7Bit, // AddressingMode : Adress Mode
"\_SB.PCI0.D01D", // ResourceSource : I2C host controller
0x00, // ResourceSourceIndex : must be 0
ResourceConsumer, // ResourceUsage : must be ResourceConsumer
, // DescriptorName : optional name for integer value which is an offset to a buffer field...
Exclusive // Shared : Shared or Exclusive
,) // VendorData : optional field
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "nxp,pca9575" },
Package () { "gpio-line-names", Package ()
{ "LED_Red",
"",
"MDC",
"MDIO",
}
},
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-red", "LED0" },
Package () { "mdc-gpios", "MDC0" },
Package () { "mdio-gpios", "MDIO" },
}
})
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"gpio-hog", 1},
Package () {"gpios", Package () {0, 1}},
Package () {"output-low", 1},
}
})
... <placeholder for virtual,mdio-gpiocode here> ...
}
}
}
识别PCA9575 GPIO扩展器并在Linux中注册为gpiochip。 LED 固定为低电平且“被占用”。看来这部分并没有完全错。
什么不起作用
我将这段代码插入到占位符中
Device (MD00)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "virtual,mdio-gpio" },
Package () {"gpios", Package () {^MDC0, 2, 0,
^MDIO, 3, 0,}},
}
})
}
但是当我尝试通过 configfs 加载此文件时,我可以在 dmesg
中看到一条错误消息,指出 _CRS 字段中定义的资源的兼容字段丢失。但我什至没有定义 _CRS 字段。
我也不确定我的 GPIO 是否定义正确。我无法使用 Package () {"gpios", Package () {0, 1}},
命令设置拉取模式。
我问自己,GPIO Expander Ports是否应该在MDO Device中再次定义为GgioIo Structures?
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2}
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3}
})
它似乎也不起作用,我很困惑。我不确定我是否正确使用了 GPIO PCA9575 驱动程序。我在哪里可以配置 ACPI 中的 pull bias?驱动程序从 of_
加载配置,但我不知道在 ACPI 中的何处定义它。我希望这里有人有想法。
首先让我们看看设计的主要架构:
+-------------------+
| HOST | +------+
| MDIO <------>+ MDIO |
| Intf | | Phy |
| | +--^---+
| +------+ | | +-----+
| | I²C | | | | LED |
| | host | | | +--^--+
| +--^---+ | | |
| | | +--+---+ |
+-------------------+ | I²C | |
+----------------------> GPIO +------+
+------+
从这张示意图中我们可以看出设备是如何相互关联的。现在让我们转到 ACPI 表示。一开始我们需要定义 I²C GPIO expander。从 meta-acpi 项目中的示例我们可以找到如何描述 PCA9535。假设我们找到了 I²C 主机控制器设备(\_SB_.PCI0.D01D
根据您的 post)并且您有没有锁定 IRQ 事件的扩展器这一事实,以下是原始 ASL 摘录和如何将其与驱动程序中的正确配置:
Device (ABC0)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP PCA9575 GPIO expander")
Name (RBUF, ResourceTemplate()
{
I2cSerialBusV2(0x0020, ControllerInitiated, 400000,
AddressingMode7Bit, "\_SB.PCI0.D01D",
0x00, ResourceConsumer, , Exclusive, )
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,pca9575"},
Package () {"gpio-line-names", Package () {
"LED_Red",
"",
"MDC",
"MDIO",
}},
}
})
Method (_CRS, 0, NotSerialized)
{
Return (RBUF)
}
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
}
这段摘录为我们提供了系统中的新GPIO芯片,其资源可以被其他人消耗。
例如,在您的 Virtual MDIO Phy 案例中(另见 _DSD Device Properties Related to GPIO)
Device (MD00)
{
Name (_HID, "PRP0001")
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2} // pin 2
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3} // pin 3
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", "virtual,mdio-gpio" },
Package () {
"gpios", Package () {
^MD00, 0, 0, 0, // index 0 in _CRS -> pin 2
^MD00, 1, 0, 0, // index 1 in _CRS -> pin 3
}
},
}
})
}
现在是时候查看 LED 绑定代码了。为了澄清起见,hogging 是指当您希望 GPIO provider 到 consume 资源本身时。这很可能不是你的情况。最好将其与 LED GPIO 驱动程序连接:
Device (LEDS)
{
Name (_HID, "PRP0001")
Name (_DDN, "GPIO LEDs device")
Name (_CRS, ResourceTemplate () {
GpioIo (
Exclusive, // Not shared
PullUp, // Default off
0, // Debounce timeout
0, // Drive strength
IoRestrictionOutputOnly, // Only used as output
"\_SB.PCI0.D01D.ABC0", // GPIO controller
0) // Must be 0
{
0, // LED_Red
}
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", Package() { "gpio-leds" } },
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-0", "LED0" },
}
})
/*
* For more information about these bindings see:
* Documentation/devicetree/bindings/leds/common.yaml,
* Documentation/devicetree/bindings/leds/leds-gpio.yaml and
* Documentation/firmware-guide/acpi/gpio-properties.rst.
*/
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "label", "red" },
Package () { "default-state", "on" },
Package () { "gpios", Package () { ^LEDS, 0, 0, 1 } }, // active low
}
})
}
您也可以在 Whosebug 网站上查看