diff options
Diffstat (limited to 'sound/soc/sdca/sdca_device.c')
| -rw-r--r-- | sound/soc/sdca/sdca_device.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/sound/soc/sdca/sdca_device.c b/sound/soc/sdca/sdca_device.c index c44dc21cb634..405e80b979de 100644 --- a/sound/soc/sdca/sdca_device.c +++ b/sound/soc/sdca/sdca_device.c @@ -7,6 +7,10 @@ */ #include <linux/acpi.h> +#include <linux/device.h> +#include <linux/dmi.h> +#include <linux/module.h> +#include <linux/property.h> #include <linux/soundwire/sdw.h> #include <sound/sdca.h> #include <sound/sdca_function.h> @@ -22,7 +26,26 @@ void sdca_lookup_interface_revision(struct sdw_slave *slave) fwnode_property_read_u32(fwnode, "mipi-sdw-sdca-interface-revision", &slave->sdca_data.interface_revision); } -EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, SND_SOC_SDCA); +EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, "SND_SOC_SDCA"); + +static void devm_acpi_table_put(void *ptr) +{ + acpi_put_table((struct acpi_table_header *)ptr); +} + +void sdca_lookup_swft(struct sdw_slave *slave) +{ + acpi_status status; + + status = acpi_get_table(ACPI_SIG_SWFT, 0, + (struct acpi_table_header **)&slave->sdca_data.swft); + if (ACPI_FAILURE(status)) + dev_info(&slave->dev, "SWFT not available\n"); + else + devm_add_action_or_reset(&slave->dev, devm_acpi_table_put, + &slave->sdca_data.swft); +} +EXPORT_SYMBOL_NS(sdca_lookup_swft, "SND_SOC_SDCA"); static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave) { @@ -46,22 +69,40 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave) return false; for (i = 0; i < slave->sdca_data.num_functions; i++) { - if (slave->sdca_data.sdca_func[i].type == - SDCA_FUNCTION_TYPE_SMART_MIC) + if (slave->sdca_data.function[i].type == SDCA_FUNCTION_TYPE_SMART_MIC) return true; } return false; } +static bool sdca_device_quirk_skip_func_type_patching(struct sdw_slave *slave) +{ + const char *vendor, *sku; + + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + sku = dmi_get_system_info(DMI_PRODUCT_SKU); + + if (vendor && sku && + !strcmp(vendor, "Dell Inc.") && + (!strcmp(sku, "0C62") || !strcmp(sku, "0C63") || !strcmp(sku, "0C6B")) && + slave->sdca_data.interface_revision == 0x061c && + slave->id.mfg_id == 0x01fa && slave->id.part_id == 0x4243) + return true; + + return false; +} + bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk) { switch (quirk) { case SDCA_QUIRKS_RT712_VB: return sdca_device_quirk_rt712_vb(slave); + case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING: + return sdca_device_quirk_skip_func_type_patching(slave); default: break; } return false; } -EXPORT_SYMBOL_NS(sdca_device_quirk_match, SND_SOC_SDCA); +EXPORT_SYMBOL_NS(sdca_device_quirk_match, "SND_SOC_SDCA"); |
