Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: Pass PCI SSID to machine driver

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>

authored by

Richard Fitzgerald and committed by
Mark Brown
ba2de401 47f56e38

+30
+7
include/sound/soc-acpi.h
··· 68 68 * @i2s_link_mask: I2S/TDM links enabled on the board 69 69 * @num_dai_drivers: number of elements in @dai_drivers 70 70 * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode 71 + * @subsystem_vendor: optional PCI SSID vendor value 72 + * @subsystem_device: optional PCI SSID device value 73 + * @subsystem_id_set: true if a value has been written to 74 + * subsystem_vendor and subsystem_device. 71 75 */ 72 76 struct snd_soc_acpi_mach_params { 73 77 u32 acpi_ipc_irq_index; ··· 84 80 u32 i2s_link_mask; 85 81 u32 num_dai_drivers; 86 82 struct snd_soc_dai_driver *dai_drivers; 83 + unsigned short subsystem_vendor; 84 + unsigned short subsystem_device; 85 + bool subsystem_id_set; 87 86 }; 88 87 89 88 /**
+8
include/sound/sof.h
··· 64 64 const char *name; 65 65 const char *platform; 66 66 67 + /* 68 + * PCI SSID. As PCI does not define 0 as invalid, the subsystem_id_set 69 + * flag indicates that a value has been written to these members. 70 + */ 71 + unsigned short subsystem_vendor; 72 + unsigned short subsystem_device; 73 + bool subsystem_id_set; 74 + 67 75 struct device *dev; 68 76 69 77 /*
+7
sound/soc/sof/sof-audio.c
··· 1031 1031 mach = snd_sof_machine_select(sdev); 1032 1032 if (mach) { 1033 1033 sof_pdata->machine = mach; 1034 + 1035 + if (sof_pdata->subsystem_id_set) { 1036 + mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; 1037 + mach->mach_params.subsystem_device = sof_pdata->subsystem_device; 1038 + mach->mach_params.subsystem_id_set = true; 1039 + } 1040 + 1034 1041 snd_sof_set_mach_params(mach, sdev); 1035 1042 return 0; 1036 1043 }
+8
sound/soc/sof/sof-pci-dev.c
··· 214 214 return ret; 215 215 216 216 sof_pdata->name = pci_name(pci); 217 + 218 + /* PCI defines a vendor ID of 0xFFFF as invalid. */ 219 + if (pci->subsystem_vendor != 0xFFFF) { 220 + sof_pdata->subsystem_vendor = pci->subsystem_vendor; 221 + sof_pdata->subsystem_device = pci->subsystem_device; 222 + sof_pdata->subsystem_id_set = true; 223 + } 224 + 217 225 sof_pdata->desc = desc; 218 226 sof_pdata->dev = dev; 219 227