1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // Copyright(c) 2024 Intel Corporation 3 4 /* 5 * The MIPI SDCA specification is available for public downloads at 6 * https://www.mipi.org/mipi-sdca-v1-0-download 7 */ 8 9 #include <linux/acpi.h> 10 #include <linux/dmi.h> 11 #include <linux/module.h> 12 #include <linux/property.h> 13 #include <linux/soundwire/sdw.h> 14 #include <sound/sdca.h> 15 #include <sound/sdca_function.h> 16 17 void sdca_lookup_interface_revision(struct sdw_slave *slave) 18 { 19 struct fwnode_handle *fwnode = slave->dev.fwnode; 20 21 /* 22 * if this property is not present, then the sdca_interface_revision will 23 * remain zero, which will be considered as 'not defined' or 'invalid'. 24 */ 25 fwnode_property_read_u32(fwnode, "mipi-sdw-sdca-interface-revision", 26 &slave->sdca_data.interface_revision); 27 } 28 EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, "SND_SOC_SDCA"); 29 30 static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave) 31 { 32 struct sdw_slave_id *id = &slave->id; 33 int i; 34 35 /* 36 * The RT712_VA relies on the v06r04 draft, and the 37 * RT712_VB on a more recent v08r01 draft. 38 */ 39 if (slave->sdca_data.interface_revision < 0x0801) 40 return false; 41 42 if (id->mfg_id != 0x025d) 43 return false; 44 45 if (id->part_id != 0x712 && 46 id->part_id != 0x713 && 47 id->part_id != 0x716 && 48 id->part_id != 0x717) 49 return false; 50 51 for (i = 0; i < slave->sdca_data.num_functions; i++) { 52 if (slave->sdca_data.function[i].type == SDCA_FUNCTION_TYPE_SMART_MIC) 53 return true; 54 } 55 56 return false; 57 } 58 59 static bool sdca_device_quirk_skip_func_type_patching(struct sdw_slave *slave) 60 { 61 const char *vendor, *sku; 62 63 vendor = dmi_get_system_info(DMI_SYS_VENDOR); 64 sku = dmi_get_system_info(DMI_PRODUCT_SKU); 65 66 if (vendor && sku && 67 !strcmp(vendor, "Dell Inc.") && 68 (!strcmp(sku, "0C62") || !strcmp(sku, "0C63") || !strcmp(sku, "0C6B")) && 69 slave->sdca_data.interface_revision == 0x061c && 70 slave->id.mfg_id == 0x01fa && slave->id.part_id == 0x4243) 71 return true; 72 73 return false; 74 } 75 76 bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk) 77 { 78 switch (quirk) { 79 case SDCA_QUIRKS_RT712_VB: 80 return sdca_device_quirk_rt712_vb(slave); 81 case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING: 82 return sdca_device_quirk_skip_func_type_patching(slave); 83 default: 84 break; 85 } 86 return false; 87 } 88 EXPORT_SYMBOL_NS(sdca_device_quirk_match, "SND_SOC_SDCA"); 89