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>
This commit is contained in:
parent
ae763de649
commit
685dbe14e9
|
@ -1019,33 +1019,72 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
|
||||||
return dp_array;
|
return dp_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
struct acpi_dp *gpio;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (!dp || !param_count)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
gpio = acpi_dp_new_table(name);
|
||||||
|
if (!gpio)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The device that has _CRS containing GpioIO()/GpioInt() */
|
||||||
|
acpi_dp_add_reference(gpio, NULL, params->ref);
|
||||||
|
|
||||||
|
/* Index of the GPIO resource in _CRS starting from zero */
|
||||||
|
acpi_dp_add_integer(gpio, NULL, params->index);
|
||||||
|
|
||||||
|
/* 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,
|
struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
|
||||||
const char *ref, int index, int pin,
|
const char *ref, int index, int pin,
|
||||||
int active_low)
|
int active_low)
|
||||||
{
|
{
|
||||||
if (!dp)
|
struct acpi_gpio_res_params param = {
|
||||||
return NULL;
|
.ref = ref,
|
||||||
|
.index = index,
|
||||||
|
.pin = pin,
|
||||||
|
.active_low = active_low,
|
||||||
|
};
|
||||||
|
|
||||||
struct acpi_dp *gpio = acpi_dp_new_table(name);
|
return acpi_dp_add_gpio_array(dp, name, ¶m, 1);
|
||||||
|
|
||||||
if (!gpio)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* The device that has _CRS containing GpioIO()/GpioInt() */
|
|
||||||
acpi_dp_add_reference(gpio, NULL, ref);
|
|
||||||
|
|
||||||
/* Index of the GPIO resource in _CRS starting from zero */
|
|
||||||
acpi_dp_add_integer(gpio, NULL, index);
|
|
||||||
|
|
||||||
/* Pin in the GPIO resource, typically zero */
|
|
||||||
acpi_dp_add_integer(gpio, NULL, pin);
|
|
||||||
|
|
||||||
/* Set if pin is active low */
|
|
||||||
acpi_dp_add_integer(gpio, NULL, active_low);
|
|
||||||
|
|
||||||
acpi_dp_add_array(dp, gpio);
|
|
||||||
|
|
||||||
return gpio;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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,
|
const char *ref, int index, int pin,
|
||||||
int active_low);
|
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 */
|
/* Add a child table of Device Properties */
|
||||||
struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
|
struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
|
||||||
struct acpi_dp *child);
|
struct acpi_dp *child);
|
||||||
|
|
Loading…
Reference in New Issue