]> www.infradead.org Git - users/hch/misc.git/commitdiff
ASoC: SDCA: Add quirk for incorrect function types for 3 systems
authorMaciej Strozek <mstrozek@opensource.cirrus.com>
Mon, 1 Sep 2025 15:15:07 +0000 (16:15 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 2 Sep 2025 09:50:29 +0000 (10:50 +0100)
Certain systems have CS42L43 DisCo that claims to conform to version 0.6.28
but uses the function types from the 1.0 spec. Add a quirk as a workaround.

Closes: https://github.com/thesofproject/linux/issues/5515
Cc: stable@vger.kernel.org
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20250901151518.3197941-1-mstrozek@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/sdca.h
sound/soc/sdca/sdca_device.c
sound/soc/sdca/sdca_functions.c

index 5a5d6de78d72834915f8f04352055a823f4558a6..9c6a351c9d474ff0f5669d8a7a587012b2fda828 100644 (file)
@@ -46,6 +46,7 @@ struct sdca_device_data {
 
 enum sdca_quirk {
        SDCA_QUIRKS_RT712_VB,
+       SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
 };
 
 #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
index 0244cdcdd109a7e0b326e791bdc78a7d9fb16d49..4798ce2c8f0b40febc5cd131c08d043743bcc6dd 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/property.h>
 #include <linux/soundwire/sdw.h>
@@ -55,11 +56,30 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave)
        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;
        }
index f26f597dca9e944744b88d26d5abd27781ca9804..13f68f7b6dd6aff6ba1b07be8e48faa3a9209f05 100644 (file)
@@ -90,6 +90,7 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
 {
        struct fwnode_handle *function_node = acpi_fwnode_handle(adev);
        struct sdca_device_data *sdca_data = data;
+       struct sdw_slave *slave = container_of(sdca_data, struct sdw_slave, sdca_data);
        struct device *dev = &adev->dev;
        struct fwnode_handle *control5; /* used to identify function type */
        const char *function_name;
@@ -137,11 +138,13 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
                return ret;
        }
 
-       ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
-       if (ret < 0) {
-               dev_err(dev, "SDCA version %#x invalid function type %d\n",
-                       sdca_data->interface_revision, function_type);
-               return ret;
+       if (!sdca_device_quirk_match(slave, SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING)) {
+               ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
+               if (ret < 0) {
+                       dev_err(dev, "SDCA version %#x invalid function type %d\n",
+                               sdca_data->interface_revision, function_type);
+                       return ret;
+               }
        }
 
        function_name = get_sdca_function_name(function_type);