ACPI ASL/AML:使用 linux 驱动程序获取 GPIO 和 LED

问题描述 投票:0回答:1

我的基于 x86 的系统中有一个 GPIO 扩展器 (PCF8574),它连接到 SMBus。

  • GPIO0-3用作GPIO。
  • GPIO4-7 用于控制 LED。

为了让它工作并希望稍后进入 BIOS/EFI,我使用 ACPI ASL。

目前我正在使用 Ubuntu 22.04.03 LTS 和 HWE Kernel 6.5.0-14

我搜索了很多类似 thisthis 的帖子,也向 chatgpt 寻求帮助,但是是的……这也不起作用:D

我目前坚持遵循 ASL,这几乎可以工作,但当我尝试加载它时,我收到了这个:

[   48.736439] ACPI: Host-directed Dynamic ACPI Table Load:
[   48.736468] ACPI: SSDT 0xFFFF8A7BCF287800 000435 (v01 VENDOR EXPANDER 00000001 INTL 20200925)
[   48.747914] pcf857x i2c-PRP0001:03: probed
[   48.748820] leds-gpio: probe of PRP0001:04 failed with error -16

GPIO 通过

gpioinfo
/
gpiodetect
识别,可控并正确命名。

-16 表示设备或资源繁忙。似乎 led 驱动程序说资源正忙,但我认为 leds-gpio 驱动程序将使用提供的 gpios 而不是 i2c 资源。我错了吗?是否可以像这样“拆分”GPIO 扩展器?

我的美国手语:

DefinitionBlock ("expander.aml", "SSDT", 1, "VENDOR", "EXPANDER", 0x00000001)
{
    External (\_SB.PC00.SBUS, DeviceObj) 

    Scope (\_SB.PC00.SBUS)  // Scope of the I2C controller
    {
        Device (EXIO)  // GPIO expander device
        {
            Name (_HID, "PRP0001")  // Hardware ID
            Name (_DDN, "GPIO-Expander")
            Name (_UID, 3)     // Unique ID
            Name (_CID, "nxp,pcf8574")
            Name (_DSD, Package ()
            {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "compatible", Package() { "nxp,pcf8574" } },
                    Package () { "gpio-line-names", Package () {
                        "SATA1-Status",
                        "SATA1-Hotplug",
                        "SATA2-Status",
                        "SATA2-Hotplug",
                        }
                    },
                }
            })

            Name (_CRS, ResourceTemplate () {
                I2CSerialBusV2 (
                    0x21,                        // SlaveAddress
                    ControllerInitiated,         // SlaveMode
                    100000,                      // ConnectionSpeed
                    AddressingMode7Bit,          // AddressingMode
                    "\\_SB.PC00.SBUS",           // ResourceSource
                    0x00,                        // ResourceSourceIndex
                    ResourceConsumer,            // ResourceUsage
                    ,                            // DescriptorName
                    Exclusive                    // ShareType
                                                 // VendorData
                )
            })

            Method (_STA, 0, NotSerialized)
            {
                Return (0x0F)
            }
        }

        Device (LEDS)
        {
            Name (_HID, "PRP0001")
            Name (_DDN, "GPIO LEDs device")
            Name (_UID, 3)
            Name (_CRS, ResourceTemplate () {
                GpioIo (
                    Exclusive,                  // Not shared
                    PullNone,                   // Default off
                    0,                          // Debounce timeout
                    0,                          // Drive strength
                    IoRestrictionOutputOnly,    // Only used as output
                    "\\_SB.PC00.SBUS.EXIO",     // GPIO controller
                    0)                          // Must be 0
                {
                    4,  // LED1
                    5,  // LED2
                    6,  // LED3
                    7,  // LED4                        
                }
            })
            
            Name (_DSD, Package () {
                ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
                Package () {
                    Package () { "led-4", "LED0" },
                    Package () { "led-5", "LED1" },
                    Package () { "led-6", "LED2" },
                    Package () { "led-7", "LED3" },
                },
                
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "compatible", Package() { "gpio-leds" } },
                },
            })
            
            Name (LED0, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-4" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^LEDS, 0, 0, 1}},
                }
            })
            
            Name (LED1, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-5" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^LEDS, 0, 0, 1}},
                }
            })
            
            Name (LED2, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-6" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^LEDS, 0, 0, 1}},
                }
            })
            
            Name (LED3, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-7" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^LEDS, 0, 0, 1}},
                }
            })
        }
    }
}
x86-64 linux-device-driver gpio i2c acpi
1个回答
0
投票

此响应是由我最近创建的私有 AI 生成的,并在没有任何公共 api 的情况下自行微调。请尝试一下,让我知道这个回复的有用性和相关性。非常感谢!

您似乎正在尝试将 GPIO 扩展器拆分为两个独立的设备:一个用于 GPIO (EXIO),另一个用于 LED (LEDS)。然而,问题是您为两个设备定义了相同的 I2C 从机地址 (0x21),这导致了冲突。

要解决此问题,您可以修改 ASL 代码以使用代表 GPIO 扩展器的单个设备 (EXIO),然后在该设备内定义 GPIO 和 LED。这是您的 ASL 代码的更新版本:

DefinitionBlock ("expander.aml", "SSDT", 1, "VENDOR", "EXPANDER", 0x00000001)
{
    External (\_SB.PC00.SBUS, DeviceObj) 
    Scope (\_SB.PC00.SBUS)  // Scope of the I2C controller
    {
        Device (EXIO)  // GPIO expander device
        {
            Name (_HID, "PRP0001")  // Hardware ID
            Name (_DDN, "GPIO-Expander")
            Name (_UID, 3)     // Unique ID
            Name (_CID, "nxp,pcf8574")
            Name (_DSD, Package ()
            {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "compatible", Package() { "nxp,pcf8574", "gpio-leds" } },
                    Package () { "gpio-line-names", Package () {
                        "SATA1-Status",
                        "SATA1-Hotplug",
                        "SATA2-Status",
                        "SATA2-Hotplug",
                        "LED1",
                        "LED2",
                        "LED3",
                        "LED4"
                        }
                    },
                }
            })
            Name (_CRS, ResourceTemplate () {
                I2CSerialBusV2 (
                    0x21,                        // SlaveAddress
                    ControllerInitiated,         // SlaveMode
                    100000,                      // ConnectionSpeed
                    AddressingMode7Bit,          // AddressingMode
                    "\\_SB.PC00.SBUS",           // ResourceSource
                    0x00,                        // ResourceSourceIndex
                    ResourceConsumer,            // ResourceUsage
                    ,                            // DescriptorName
                    Exclusive                    // ShareType
                                                 // VendorData
                )
                GpioIo (
                    Exclusive,                  // Not shared
                    PullNone,                   // Default off
                    0,                          // Debounce timeout
                    0,                          // Drive strength
                    IoRestrictionOutputOnly,    // Only used as output
                    "\\_SB.PC00.SBUS.EXIO",     // GPIO controller
                    0)                          // Must be 0
                {
                    4,  // LED1
                    5,  // LED2
                    6,  // LED3
                    7   // LED4                        
                }
            })
            
            Name (LED0, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-4" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^EXIO, 0, 0, 1}},
                }
            })
            
            Name (LED1, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-5" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^EXIO, 0, 0, 1}},
                }
            })
            
            Name (LED2, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-6" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^EXIO, 0, 0, 1}},
                }
            })
            
            Name (LED3, Package () {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package () {
                    Package () { "label", "led-7" },
                    Package () { "led-max-microamp", 10000 },
                    Package () { "default-state", "off"},
                    Package () { "gpios", Package () {^EXIO, 0, 0, 1}},
                }
            })
            
            Method (_STA, 0, NotSerialized)
            {
                Return (0x0F)
            }
        }
    }
}

In this updated code:

The EXIO device represents the GPIO expander and includes both the GPIOs and LEDs.

The compatible property in the _DSD package includes both "nxp,pcf8574" and "gpio-leds" to indicate that the device supports both GPIO and LED functionality.

The gpio-line-names property includes names for all 8 GPIO lines, including the LEDs.

The GpioIo resource is defined within the _CRS method of the EXIO device, specifying the GPIO lines used for the LEDs.

The LED packages (LED0, LED1, LED2, LED3) reference the EXIO device for the GPIO resources.

With these changes, the GPIO expander should be recognized as a single device, and the GPIOs and LEDs should be properly configured.
© www.soinside.com 2019 - 2024. All rights reserved.