ASoC: cs35l56: Use PCI SSID as the firmware UID
authorRichard Fitzgerald <rf@opensource.cirrus.com>
Tue, 12 Sep 2023 16:32:07 +0000 (17:32 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 12 Sep 2023 17:53:50 +0000 (18:53 +0100)
If the driver properties do not define a cirrus,firmware-uid try to get the
PCI SSID as the UID.

On PCI-based systems the PCI SSID is used to uniquely identify the specific
sound hardware. This is the standard mechanism for x86 systems and is the
way to get a unique system identifier for systems that use the CS35L56 on
SoundWire.

For non-SoundWire systems there is no Windows equivalent of the ASoC driver
in I2C/SPI mode. These would be:

1. HDA systems, which are handled by the HDA subsystem.
2. Linux-specific systems.
3. Composite devices where the cs35l56 is not present in ACPI and is
   configured using software nodes.

Case 2 can use the firmware-uid property, though the PCI SSID is supported
as an alternative, as it is the standard PCI mechanism.

Case 3 is a SoundWire system where some other codec is the SoundWire bridge
device and CS35L56 is not listed in ACPI. As these are SoundWire systems
they will normally use the PCI SSID.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20230912163207.3498161-5-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/cs35l56.c

index 600b79c62ec48a5dec9d843cb036477c7867f20a..a0006419ba5810229f34f38651c01274e507661b 100644 (file)
@@ -772,9 +772,20 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
 {
        struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
        struct dentry *debugfs_root = component->debugfs_root;
+       unsigned short vendor, device;
 
        BUILD_BUG_ON(ARRAY_SIZE(cs35l56_tx_input_texts) != ARRAY_SIZE(cs35l56_tx_input_values));
 
+       if (!cs35l56->dsp.system_name &&
+           (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) {
+               cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
+                                                         GFP_KERNEL,
+                                                         "%04x%04x",
+                                                         vendor, device);
+               if (!cs35l56->dsp.system_name)
+                       return -ENOMEM;
+       }
+
        if (!wait_for_completion_timeout(&cs35l56->init_completion,
                                         msecs_to_jiffies(5000))) {
                dev_err(cs35l56->base.dev, "%s: init_completion timed out\n", __func__);