summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/usb/acpi/chip.h3
-rw-r--r--src/drivers/usb/acpi/usb_acpi.c126
2 files changed, 129 insertions, 0 deletions
diff --git a/src/drivers/usb/acpi/chip.h b/src/drivers/usb/acpi/chip.h
index 9acd382c3d..855a5d798b 100644
--- a/src/drivers/usb/acpi/chip.h
+++ b/src/drivers/usb/acpi/chip.h
@@ -47,6 +47,9 @@ struct drivers_usb_acpi_config {
/* Does the device have a power resource? */
bool has_power_resource;
+ /* Intel Bluetooth */
+ bool is_intel_bluetooth;
+
/* GPIO used to take device out of reset or to put it into reset. */
struct acpi_gpio reset_gpio;
/* Delay to be inserted after device is taken out of reset. */
diff --git a/src/drivers/usb/acpi/usb_acpi.c b/src/drivers/usb/acpi/usb_acpi.c
index 569147abad..b01c9492b3 100644
--- a/src/drivers/usb/acpi/usb_acpi.c
+++ b/src/drivers/usb/acpi/usb_acpi.c
@@ -8,6 +8,129 @@
#include <device/device.h>
#include "chip.h"
+/*
+ * Intel Bluetooth DSM
+ *
+ * Check Tile Activation (2d19d3e1-5708-4696-bd5b-2c3dbae2d6a9)
+ *
+ * Arg2 == 0: Return a package with the following bits set
+ * BIT(0) Indicates whether the device supports other functions
+ * BIT(1) Check Tile Activation
+ *
+ * Check/Set Reset Delay (aa10f4e0-81ac-4233-abf6-3b2ac50e28d9)
+ * Arg2 == 0: Return a package with the following bit set
+ * BIT(0) Indicates whether the device supports other functions
+ * BIT(1) Check Bluetooth reset timing
+ * Arg2 == 1: Set the reset delay based on Arg3
+ */
+
+static void check_reset_delay(void *arg)
+{
+ acpigen_write_if_lequal_op_int(ARG1_OP, 0);
+ {
+ acpigen_write_return_singleton_buffer(0x03);
+ }
+ acpigen_write_else();
+ {
+ acpigen_write_return_singleton_buffer(0x00);
+ }
+ acpigen_pop_len();
+}
+
+static void set_reset_delay(void *arg)
+{
+ acpigen_write_store_op_to_namestr(ARG3_OP, "RDLY");
+}
+
+static void get_feature_flag(void *arg)
+{
+ acpigen_write_if_lequal_op_int(ARG1_OP, 0);
+ {
+ acpigen_write_return_singleton_buffer(0x03);
+ }
+ acpigen_write_else();
+ {
+ acpigen_write_return_singleton_buffer(0x00);
+ }
+ acpigen_pop_len();
+}
+
+void (*uuid_callbacks1[])(void *) = { check_reset_delay, set_reset_delay };
+void (*uuid_callbacks2[])(void *) = { get_feature_flag };
+
+static void acpi_device_intel_bt(void)
+{
+/*
+ * Name (RDLY, 0x69)
+ */
+ acpigen_write_name_integer("RDLY", 0x69);
+
+/*
+ * Method (_DSM, 4, Serialized)
+ * {
+ * If ((Arg0 == ToUUID ("aa10f4e0-81ac-4233-abf6-3b2ac50e28d9")))
+ * {
+ * If ((Arg2 == Zero))
+ * {
+ * If ((Arg1 == Zero))
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x03
+ * })
+ * }
+ * Else
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ * }
+ * If ((Arg2 == One))
+ * {
+ * RDLY = Arg3
+ * }
+ * Return (Zero)
+ * }
+ * ElseIf ((Arg0 == ToUUID ("2d19d3e1-5708-4696-bd5b-2c3dbae2d6a9")))
+ * {
+ * If ((Arg2 == Zero))
+ * {
+ * If ((Arg1 == Zero))
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ * Else
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ * }
+ * Return (Zero)
+ * }
+ * Else
+ * {
+ * Return (Buffer (One)
+ * {
+ * 0x00
+ * })
+ * }
+ * }
+ */
+ struct dsm_uuid uuid_callbacks[] = {
+ DSM_UUID("aa10f4e0-81ac-4233-abf6-3b2ac50e28d9", uuid_callbacks1, 2, NULL),
+ DSM_UUID("2d19d3e1-5708-4696-bd5b-2c3dbae2d6a9", uuid_callbacks2, 1, NULL),
+ };
+
+ acpigen_write_dsm_uuid_arr(uuid_callbacks, ARRAY_SIZE(uuid_callbacks));
+}
+
static bool usb_acpi_add_gpios_to_crs(struct drivers_usb_acpi_config *cfg)
{
if (cfg->privacy_gpio.pin_count)
@@ -107,6 +230,9 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev)
acpi_device_add_power_res(&power_res_params);
}
+ if (config->is_intel_bluetooth)
+ acpi_device_intel_bt();
+
acpigen_pop_len();
printk(BIOS_INFO, "%s: %s at %s\n", path,