summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@google.com>2020-10-05 10:44:50 -0600
committerPatrick Georgi <pgeorgi@google.com>2020-10-14 05:43:00 +0000
commit685dbe14e93104847f2a3b885d58aef4f8e67192 (patch)
treef0b5550b8fb585876e94dc07c379af120e931d0a
parentae763de649d7d8ebcc00f2e6792b37c4766e1047 (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.c67
-rw-r--r--src/include/acpi/acpi_device.h16
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, &param, 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);