aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/usb/acpi/chip.h7
-rw-r--r--src/drivers/usb/acpi/usb_acpi.c49
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);
}