ACPI Pinctrl
On some platforms, certains peripheral buses or devices could be connected to the same external pin header with a different pin configuration requirement. A simple example of this would be a board where pins for I2C data and clock is multiplexed and shared with GPIO pins for a display controller. Pins would require different configurations in these two modes. For example, I2C functionality would require pin bias to be set to pull up with pull strength of 10K Ohms and for GPIO functionality pin bias needs to be set to pull down with pull strength of 20K Ohms, input Schmitt-trigger enabled and a slew rate of 3.
ACPI 6.2 version introduced the following resources to be able to describe different pin functions and configurations required for devices.
PinFunction
PinConfig
PinGroup
PinGroupFunction
PinGroupConfig
OSPM will have to handle the above resources and select the pin function and configuration through vendor-specific interfaces (e.g: memory mapped registers) for the devices to be fully functional.
Design Document for Linux Kernel:
https://docs.google.com/document/d/1bgLAOEGmhVnxSF_Bx6-blg1_ZNnv8BTQGYW6gixOvjY/edit?usp=sharing
Status
Implemented ACPI Pinctrl device in I.MX8MP platform
Implemented Linux ACPI pinctrl extensions to support ACPI pin resources.
https://lore.kernel.org/linux-gpio/20221130164027.682898-1-niyas.sait@linaro.org/ ← In Upstream Review
Added support for ACPI in I.MX pinctrl driver
Example : I2C controller SDA/SCL muxed with display controller GPIO pin
//
// Description: GPIO
//
Device (GPI0)
{
Name (_HID, "PNPFFFE")
Name (_UID, 0x0)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized)
{
Name (RBUF, ResourceTemplate()
{
Memory32Fixed(ReadWrite, 0x4FE00000, 0x20)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x54}
})
Return(RBUF)
}
}
//
// Description: I2C controller 1
//
Device (I2C1)
{
Name (_HID, "PNPFFFF")
Name (_UID, 0x0)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized)
{
Name (RBUF, ResourceTemplate()
{
Memory32Fixed(ReadWrite, 0x4F800000, 0x20)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x55}
PinFunction(Exclusive, PullDefault, 0x5, "\\\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3}
// Configure 10k Pull up for I2C SDA/SCL pins
PinConfig(Exclusive, 0x01, 10000, "\\\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3}
})
Return(RBUF)
}
}
//
// Description: Physical display panel
//
Device (SDIO)
{
Name (_HID, "PNPFFFD")
Name (_UID, 0x0)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized)
{
Name (RBUF, ResourceTemplate()
{
Memory32Fixed(ReadWrite, 0x4F900000, 0x20)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x57}
GpioIo(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\\\_SB.GPI0",) {2, 3}
// Configure 20k Pull down
PinConfig(Exclusive, 0x02, 20000, "\\\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3}
// Enable Schmitt-trigger
PinConfig(Exclusive, 0x0D, 1, "\\\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3}
// Set slew rate to custom value 3
PinConfig(Exclusive, 0x0B, 3, "\\\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3}
})
Return(RBUF)
}
}