ASoC: SOF: Pass PCI SSID to machine driver
authorRichard Fitzgerald <rf@opensource.cirrus.com>
Tue, 12 Sep 2023 16:32:05 +0000 (17:32 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 12 Sep 2023 17:53:48 +0000 (18:53 +0100)
Pass the PCI SSID of the audio interface through to the machine driver.
This allows the machine driver to use the SSID to uniquely identify the
specific hardware configuration and apply any platform-specific
configuration.

struct snd_sof_pdata is passed around inside the SOF code, but it then
passes configuration information to the machine driver through
struct snd_soc_acpi_mach and struct snd_soc_acpi_mach_params. So SSID
information has been added to both snd_sof_pdata and
snd_soc_acpi_mach_params.

PCI does not define 0x0000 as an invalid value so we can't use zero to
indicate that the struct member was not written. Instead a flag is
included to indicate that a value has been written to the
subsystem_vendor and subsystem_device members.

sof_pci_probe() creates the struct snd_sof_pdata. It is passed a struct
pci_dev so it can fill in the SSID value.

sof_machine_check() finds the appropriate struct snd_soc_acpi_mach. It
copies the SSID information across to the struct snd_soc_acpi_mach_params.
This done before calling any custom set_mach_params() so that it could be
used by the set_mach_params() callback to apply variant params.

The machine driver receives the struct snd_soc_acpi_mach as its
platform_data.

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-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc-acpi.h
include/sound/sof.h
sound/soc/sof/sof-audio.c
sound/soc/sof/sof-pci-dev.c

index 6d31d535e8f6dd99f96879c53f1aeadc73aea086..23d6d6bfb073645c9ce583831b886c0765700619 100644 (file)
@@ -68,6 +68,10 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
  * @i2s_link_mask: I2S/TDM links enabled on the board
  * @num_dai_drivers: number of elements in @dai_drivers
  * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
+ * @subsystem_vendor: optional PCI SSID vendor value
+ * @subsystem_device: optional PCI SSID device value
+ * @subsystem_id_set: true if a value has been written to
+ *                   subsystem_vendor and subsystem_device.
  */
 struct snd_soc_acpi_mach_params {
        u32 acpi_ipc_irq_index;
@@ -80,6 +84,9 @@ struct snd_soc_acpi_mach_params {
        u32 i2s_link_mask;
        u32 num_dai_drivers;
        struct snd_soc_dai_driver *dai_drivers;
+       unsigned short subsystem_vendor;
+       unsigned short subsystem_device;
+       bool subsystem_id_set;
 };
 
 /**
index d3c41f87ac3191db251f3ee5bd64ad15ca5be85e..51294f2ba302c6e55096a0fcbf97180cfefa4cad 100644 (file)
@@ -64,6 +64,14 @@ struct snd_sof_pdata {
        const char *name;
        const char *platform;
 
+       /*
+        * PCI SSID. As PCI does not define 0 as invalid, the subsystem_id_set
+        * flag indicates that a value has been written to these members.
+        */
+       unsigned short subsystem_vendor;
+       unsigned short subsystem_device;
+       bool subsystem_id_set;
+
        struct device *dev;
 
        /*
index e7ef77012c3586649f364d538c42ab4c89496c48..9c2359d10ecf085dc3100e98c5702a9469c3a9d4 100644 (file)
@@ -1031,6 +1031,13 @@ int sof_machine_check(struct snd_sof_dev *sdev)
                mach = snd_sof_machine_select(sdev);
                if (mach) {
                        sof_pdata->machine = mach;
+
+                       if (sof_pdata->subsystem_id_set) {
+                               mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor;
+                               mach->mach_params.subsystem_device = sof_pdata->subsystem_device;
+                               mach->mach_params.subsystem_id_set = true;
+                       }
+
                        snd_sof_set_mach_params(mach, sdev);
                        return 0;
                }
index f5ece43d0ec2473b6a7e6c61a6ae5c52232c59d9..146d25983b08bde7de41e15feecc77e9afafdc87 100644 (file)
@@ -214,6 +214,14 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
                return ret;
 
        sof_pdata->name = pci_name(pci);
+
+       /* PCI defines a vendor ID of 0xFFFF as invalid. */
+       if (pci->subsystem_vendor != 0xFFFF) {
+               sof_pdata->subsystem_vendor = pci->subsystem_vendor;
+               sof_pdata->subsystem_device = pci->subsystem_device;
+               sof_pdata->subsystem_id_set = true;
+       }
+
        sof_pdata->desc = desc;
        sof_pdata->dev = dev;