Skip to content

Instantly share code, notes, and snippets.

@rgov
Created February 18, 2021 04:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgov/7f37366ee11d7dd990caefedcfcf62ef to your computer and use it in GitHub Desktop.
Save rgov/7f37366ee11d7dd990caefedcfcf62ef to your computer and use it in GitHub Desktop.
Notes on writing an ACPI SSDT
DefinitionBlock ("gpio.aml", "SSDT", 5, "", "GPIO", 0x20210212)
{
External (_SB.PCI0.SBUS, DeviceObj)
Scope (\_SB.PCI0.SBUS)
{
Device (GPI0)
{
// This special _HID (Hardware ID) tells Linux to use Device Tree-
// compatible device identification.
Name (_HID, "PRP0001")
Name (_DDN, "NXP PCA9535 GPIO expander")
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2(
0x0020, // I2C address
ControllerInitiated,
400000, // Bus speed (see PCA9535 datasheet)
AddressingMode7Bit,
"\\_SB.PCI0.SBUS", // SMBus controller
0x00,
ResourceConsumer,
/* omitted */,
Exclusive,
/* omitted */
)
})
Name (_DSD, Package () {
// Device Properties
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
// These correspond to Linux Device Tree properties
Package () { "compatible", "nxp,pca9535" },
Package () { "gpio-line-names", Package () {
"GPIOA.0", "GPIOA.1", "GPIOA.2", "GPIOA.3",
"GPIOA.4", "GPIOA.5", "GPIOA.6", "GPIOA.7",
"GPIOB.0", "GPIOB.1", "GPIOB.2", "GPIOB.3",
"GPIOB.4", "GPIOB.5", "GPIOB.6", "GPIOB.7",
}},
}
})
}
}
Device (PPS0)
{
Name (_HID, "PRP0001")
Name (_CRS, ResourceTemplate () {
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0,
"\\_SB.PCI0.SBUS.GPI0", 0, ResourceConsumer, iPPS /* ref */)
{
0 // GPIOA.0 pin
}
})
Name (_DSD, Package() {
// Device Properties
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
// https://github.com/torvalds/linux/blob/v4.15/Documentation/devicetree/bindings/pps/pps-gpio.txt
Package () { "compatible", "pps-gpio" },
Package () { "gpios", Package () {
^PPS0, iPPS, 0, 0 /* required for GpioInt */
}},
}
})
}
}
$ i2cdetect -l
i2c-3    unknown    i915 gmbus panel                N/A
i2c-1    unknown    i915 gmbus ssc                  N/A
i2c-8    unknown    DPDDC-C                         N/A
i2c-6    unknown    i915 gmbus dpd                  N/A
i2c-4    unknown    i915 gmbus dpc                  N/A
i2c-2    unknown    i915 gmbus vga                  N/A
i2c-0    unknown    SMBus I801 adapter at e000      N/A
i2c-7    unknown    DPDDC-B                         N/A
i2c-5    unknown    i915 gmbus dpb                  N/A

Scanning the SMBus I801 adapter, we find the GPIO expander responding at address 0x20 (as expected per communication with ADL):

$ sudo i2cdetect -y 0
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- -- -- -- -- -- -- 58 59 -- -- 5c 5d -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --     

Using sysfs, we can manually tell Linux that the device at this address is a PCA9535:

$ echo 'pca9535 0x20' | sudo tee /sys/bus/i2c/devices/i2c-0/new_device
$ dmesg
[12360.244878] pca953x 0-0020: 0-0020 supply vcc not found, using dummy regulator
[12360.249010] pca953x 0-0020: interrupt support not compiled in
[12360.249104] i2c i2c-0: new_device: Instantiated device pca9535 at 0x20

Subsequently, a new gpiochip device appears in /sys/class/gpio, and individual GPIO pins can be exported from it.


Next we want to find the path on the PCI bus to the I2C/SMBus device. We can see that /sys/bus/i2c/devices/i2c-0/device points to /sys/devices/pci0000:00/0000:00:1f.3, or find it using lspci:

$ lspci
00:1f.3 SMBus: Intel Corporation Atom Processor E3800 Series SMBus Controller (rev 11)

Follow these instructions for decompiling the DSDT and searching it for 0x001F0003 (device 1f and function 03). We find:

Devcie (PCI0) {
    Device (SBUS)
    {
        Name (_ADR, 0x001F0003)  // _ADR: Address
        ...
    }
    ...
}

Thus the path is _SB.PCI0.SBUS.

Loading an SSDT

$ sudo modprobe acpi_configfs
$ sudo mkdir /sys/kernel/config/acpi/table/my_ssdt
$ sudo cp my_ssdt.aml /sys/kernel/config/acpi/table/my_ssdt/aml

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment