【问题标题】:How to configure ACPI *.asl for a virtual mdio-gpio device connected to a I2C gpio expander如何为连接到 I2C gpio 扩展器的虚拟 mdio-gpio 设备配置 ACPI *.asl
【发布时间】:2021-01-14 21:55:30
【问题描述】:

我正在使用 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 扩展器端口是否应该在 MDO 设备中再次定义为 GgioIo 结构?

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 中的拉动偏差?驱动程序从of_ 加载配置,但我不知道在 ACPI 中的何处定义它。我希望这里有人有想法。

【问题讨论】:

标签: linux gpio i2c acpi


【解决方案1】:

首先让我们看看设计的主要架构:

+-------------------+
|  HOST             |       +------+
|              MDIO <------>+ MDIO |
|              Intf |       | Phy  |
|                   |       +--^---+
| +------+          |          |       +-----+
| | I²C  |          |          |       | LED |
| | host |          |          |       +--^--+
| +--^---+          |          |          |
|    |              |       +--+---+      |
+-------------------+       | I²C  |      |
     +----------------------> GPIO +------+
                            +------+

从这个示意图中,我们可以看到设备是如何相互关联的。现在让我们转向 ACPI 表示。一开始我们需要定义 I²C GPIO 扩展器。从meta-acpi 项目中的示例中,我们可以找到如何描述 PCA9535。假设我们找到了 I²C 主机控制器设备(\_SB_.PCI0.D01D 根据您的帖子)并且您有扩展器而没有锁定 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 自己使用 资源。这很可能不是你的情况。最好将其与 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
        }
    })
}

您也可以在 StackOverflow 网站上查看 similar questions(从给定的链接开始,其余部分有参考)。

【讨论】:

  • 非常感谢!我想我现在明白了,我理解错了。明天我会试一试,当它工作时接受答案
  • 我想...在 stackoverflow 接受我的投票之前,我需要至少 15 分的“声誉”...
  • @AlexanderOtt,没问题。我希望你现在一切正常,这很重要。
猜你喜欢
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 2017-05-14
  • 2020-11-04
  • 2015-07-19
  • 1970-01-01
  • 2021-04-02
相关资源
最近更新 更多