diff options
author | Karthikeyan Ramasubramanian <kramasub@google.com> | 2020-10-05 10:44:50 -0600 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2020-10-14 05:43:00 +0000 |
commit | 685dbe14e93104847f2a3b885d58aef4f8e67192 (patch) | |
tree | f0b5550b8fb585876e94dc07c379af120e931d0a | |
parent | ae763de649d7d8ebcc00f2e6792b37c4766e1047 (diff) |
acpi/device: Add GPIO binding property for an array of GPIOs
This change is required for use-cases like GPIO based I2C multiplexer
where more than one GPIOs are used as select lines.
BUG=b:169444894
TEST=Build and boot waddledee to OS. Ensure that the GPIO bindings for
an array of GPIOs are added to the ACPI table as follows:
Device (MUX0)
{
...
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.PCI0.GPIO", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0125
}
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.PCI0.GPIO", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0126
}
})
Name (_DSD, Package (0x02) // _DSD: Device-Specific Data
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
Package (0x01)
{
Package (0x02)
{
"mux-gpios",
Package (0x08)
{
\_SB.PCI0.I2C3.MUX0,
Zero,
Zero,
Zero,
\_SB.PCI0.I2C3.MUX0,
One,
Zero,
Zero
}
}
}
})
}
Change-Id: I7c6cc36b1bfca2d48c84f169e6b43fd4be8ba330
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46056
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
-rw-r--r-- | src/acpi/device.c | 67 | ||||
-rw-r--r-- | src/include/acpi/acpi_device.h | 16 |
2 files changed, 69 insertions, 14 deletions
diff --git a/src/acpi/device.c b/src/acpi/device.c index 450427d47c..5de31b7776 100644 --- a/src/acpi/device.c +++ b/src/acpi/device.c @@ -1019,33 +1019,72 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, return dp_array; } -struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, - const char *ref, int index, int pin, - int active_low) +struct acpi_dp *acpi_dp_add_gpio_array(struct acpi_dp *dp, const char *name, + const struct acpi_gpio_res_params *params, + size_t param_count) { - if (!dp) - return NULL; + struct acpi_dp *gpio; + uint32_t i; - struct acpi_dp *gpio = acpi_dp_new_table(name); + if (!dp || !param_count) + return NULL; + gpio = acpi_dp_new_table(name); if (!gpio) return NULL; - /* The device that has _CRS containing GpioIO()/GpioInt() */ - acpi_dp_add_reference(gpio, NULL, ref); + /* + * Generate ACPI identifiers as follows: + * Package () { + * name, // e.g. cs-gpios + * Package() { + * ref, index, pin, active_low, // GPIO-0 (params[0]) + * ref, index, pin, active_low, // GPIO-1 (params[1]) + * ... + * } + * } + */ + for (i = 0; i < param_count; i++, params++) { + /* + * If refs is NULL, leave a hole in the gpio array. This can be used in + * conditions where some controllers use both GPIOs and native signals. + */ + if (!params->ref) { + acpi_dp_add_integer(gpio, NULL, 0); + continue; + } - /* Index of the GPIO resource in _CRS starting from zero */ - acpi_dp_add_integer(gpio, NULL, index); + /* The device that has _CRS containing GpioIO()/GpioInt() */ + acpi_dp_add_reference(gpio, NULL, params->ref); - /* Pin in the GPIO resource, typically zero */ - acpi_dp_add_integer(gpio, NULL, pin); + /* Index of the GPIO resource in _CRS starting from zero */ + acpi_dp_add_integer(gpio, NULL, params->index); - /* Set if pin is active low */ - acpi_dp_add_integer(gpio, NULL, active_low); + /* Pin in the GPIO resource, typically zero */ + acpi_dp_add_integer(gpio, NULL, params->pin); + /* Set if pin is active low */ + acpi_dp_add_integer(gpio, NULL, params->active_low); + } acpi_dp_add_array(dp, gpio); return gpio; + +} + + +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low) +{ + struct acpi_gpio_res_params param = { + .ref = ref, + .index = index, + .pin = pin, + .active_low = active_low, + }; + + return acpi_dp_add_gpio_array(dp, name, ¶m, 1); } /* diff --git a/src/include/acpi/acpi_device.h b/src/include/acpi/acpi_device.h index be13bd7ec8..301f9b0156 100644 --- a/src/include/acpi/acpi_device.h +++ b/src/include/acpi/acpi_device.h @@ -545,6 +545,22 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, const char *ref, int index, int pin, int active_low); +struct acpi_gpio_res_params { + /* Reference to the parent device. */ + const char *ref; + /* Index to the GpioIo resource within the _CRS. */ + int index; + /* Index to the pin within the GpioIo resource, usually 0. */ + int pin; + /* Flag to indicate if pin is active low. */ + int active_low; +}; + +/* Add a GPIO binding device property for array of GPIOs */ +struct acpi_dp *acpi_dp_add_gpio_array(struct acpi_dp *dp, const char *name, + const struct acpi_gpio_res_params *params, + size_t param_count); + /* Add a child table of Device Properties */ struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, struct acpi_dp *child); |