diff options
-rw-r--r-- | src/drivers/usb/acpi/chip.h | 7 | ||||
-rw-r--r-- | src/drivers/usb/acpi/usb_acpi.c | 49 |
2 files changed, 45 insertions, 11 deletions
diff --git a/src/drivers/usb/acpi/chip.h b/src/drivers/usb/acpi/chip.h index 8afdf6fc8e..73c69cc89f 100644 --- a/src/drivers/usb/acpi/chip.h +++ b/src/drivers/usb/acpi/chip.h @@ -59,6 +59,13 @@ struct drivers_usb_acpi_config { unsigned int enable_delay_ms; /* Delay to be inserted after device is disabled. */ unsigned int enable_off_delay_ms; + + /* + * Define a GPIO that shows the privacy status of the USB device. + * E.g. On a camera: if it is one, it is recording black frames. + * E.g. On a mic: if it is one, it is recording white-noise. + */ + struct acpi_gpio privacy_gpio; }; #endif /* __USB_ACPI_CHIP_H__ */ diff --git a/src/drivers/usb/acpi/usb_acpi.c b/src/drivers/usb/acpi/usb_acpi.c index 8a597e3e9e..9d68d0a923 100644 --- a/src/drivers/usb/acpi/usb_acpi.c +++ b/src/drivers/usb/acpi/usb_acpi.c @@ -10,14 +10,27 @@ static bool usb_acpi_add_gpios_to_crs(struct drivers_usb_acpi_config *cfg) { - /* - * Return false if reset GPIO is not provided or is provided as part of power - * resource. - */ - if (cfg->has_power_resource || cfg->reset_gpio.pin_count == 0) - return false; - - return true; + if (cfg->privacy_gpio.pin_count) + return true; + + if (cfg->reset_gpio.pin_count && !cfg->has_power_resource) + return true; + + return false; +} + +static int usb_acpi_write_gpio(struct acpi_gpio *gpio, int *curr_index) +{ + int ret = -1; + + if (gpio->pin_count == 0) + return ret; + + acpi_device_write_gpio(gpio); + ret = *curr_index; + (*curr_index)++; + + return ret; } static void usb_acpi_fill_ssdt_generator(const struct device *dev) @@ -50,15 +63,29 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev) /* Resources */ if (usb_acpi_add_gpios_to_crs(config) == true) { struct acpi_dp *dsd; + int idx = 0; + int reset_gpio_index = -1; + int privacy_gpio_index; acpigen_write_name("_CRS"); acpigen_write_resourcetemplate_header(); - acpi_device_write_gpio(&config->reset_gpio); + if (!config->has_power_resource) { + reset_gpio_index = usb_acpi_write_gpio( + &config->reset_gpio, &idx); + } + privacy_gpio_index = usb_acpi_write_gpio(&config->privacy_gpio, + &idx); acpigen_write_resourcetemplate_footer(); dsd = acpi_dp_new_table("_DSD"); - acpi_dp_add_gpio(dsd, "reset-gpio", path, 0, 0, - config->reset_gpio.active_low); + if (reset_gpio_index >= 0) + acpi_dp_add_gpio(dsd, "reset-gpio", path, + reset_gpio_index, 0, + config->reset_gpio.active_low); + if (privacy_gpio_index >= 0) + acpi_dp_add_gpio(dsd, "privacy-gpio", path, + privacy_gpio_index, 0, + config->privacy_gpio.active_low); acpi_dp_write(dsd); } |