I have a GPIO-Expander (PCF8574) in my x86-based System which is connected to the SMBus.
To get it to work and later hopefully into the BIOS/EFI I use ACPI ASL.
Currently I'm using Ubuntu 22.04.03 LTS with HWE Kernel 6.5.0-14
I searched a lot like this or this thread and also asked chatgpt for help but yeaaaaah... that didnt work either :D
I'm currently stuck with following ASL, which almost work but as I try to load it, I receive this:
[ 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
The GPIOs are recognized via gpioinfo
/gpiodetect
, are controllable and named properly.
-16 would mean device or resource busy. It seems that the led-drivers says the resource is busy, but I thought that the leds-gpio driver will use the provided gpios not the i2c-resource. Am I wrong? Is it possible to "split" a gpio-expander like this?
My 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" } },
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, 1, 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, 2, 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, 3, 1}},
}
})
}
}
}
EDIT: I changed the LED pin within their property to the corresponding index number, the problem is solved Big thanks to 0andriy who pointed this out.
Thanks to 0andriy who pointed out the problems:
After changing the LEDs to their corresponding Indexes, it worked. :)
Name (LED0, Package () {
[...]
Package () { "gpios", Package () {^LEDS, 0, 0, 1}},
[...]
})
Name (LED1, Package () {
[...]
Package () { "gpios", Package () {^LEDS, 0, 1, 1}},
[...]
})
Name (LED2, Package () {
[...]
Package () { "gpios", Package () {^LEDS, 0, 2, 1}},
[...]
})
Name (LED3, Package () {
[...]
Package () { "gpios", Package () {^LEDS, 0, 3, 1}},
[...]
})
In hindsight it totally made sense that the device is responsing with busy, due to the fact that I assigned four LEDs to the same GPIO...