ASoC: soc-acpi: add comp_ids field for machine driver matching
authorBrent Lu <brent.lu@intel.com>
Fri, 29 Oct 2021 17:14:04 +0000 (01:14 +0800)
committerMark Brown <broonie@kernel.org>
Fri, 29 Oct 2021 17:55:16 +0000 (18:55 +0100)
A machine driver needs to be enumerated by more than one ACPI HID if
it supports second headphone driver (i.e. rt5682 and rt5682s).
However, the id field in snd_soc_acpi_mach structure could contain
only one HID. By adding a 'comp_ids' field which can contain several
HIDs, we can enumerate a machine driver by multiple ACPI HIDs.

Signed-off-by: Brent Lu <brent.lu@intel.com>
Link: https://lore.kernel.org/r/20211029171409.611600-2-brent.lu@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc-acpi.h
sound/soc/soc-acpi.c

index 2f3fa385c0927df4f24242a2434cbfb8c38109bc..31f4c4f9aeea072bec17ef6b0f71a4a3186835ec 100644 (file)
@@ -129,6 +129,8 @@ struct snd_soc_acpi_link_adr {
  * all firmware/topology related fields.
  *
  * @id: ACPI ID (usually the codec's) used to find a matching machine driver.
+ * @comp_ids: list of compatible audio codecs using the same machine driver,
+ * firmware and topology
  * @link_mask: describes required board layout, e.g. for SoundWire.
  * @links: array of link _ADR descriptors, null terminated.
  * @drv_name: machine driver name
@@ -146,6 +148,7 @@ struct snd_soc_acpi_link_adr {
 /* Descriptor for SST ASoC machine driver */
 struct snd_soc_acpi_mach {
        const u8 id[ACPI_ID_LEN];
+       const struct snd_soc_acpi_codecs *comp_ids;
        const u32 link_mask;
        const struct snd_soc_acpi_link_adr *links;
        const char *drv_name;
index 395229bf5c51d38ffbe2a7ae7bde16cdc0a6d8d8..2ae99b49d3f5f6b72c5990f05432bf06c588d888 100644 (file)
@@ -8,14 +8,34 @@
 #include <linux/module.h>
 #include <sound/soc-acpi.h>
 
+static bool snd_soc_acpi_id_present(struct snd_soc_acpi_mach *machine)
+{
+       const struct snd_soc_acpi_codecs *comp_ids = machine->comp_ids;
+       int i;
+
+       if (machine->id[0]) {
+               if (acpi_dev_present(machine->id, NULL, -1))
+                       return true;
+       }
+
+       if (comp_ids) {
+               for (i = 0; i < comp_ids->num_codecs; i++) {
+                       if (acpi_dev_present(comp_ids->codecs[i], NULL, -1))
+                               return true;
+               }
+       }
+
+       return false;
+}
+
 struct snd_soc_acpi_mach *
 snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
 {
        struct snd_soc_acpi_mach *mach;
        struct snd_soc_acpi_mach *mach_alt;
 
-       for (mach = machines; mach->id[0]; mach++) {
-               if (acpi_dev_present(mach->id, NULL, -1)) {
+       for (mach = machines; mach->id[0] || mach->comp_ids; mach++) {
+               if (snd_soc_acpi_id_present(mach)) {
                        if (mach->machine_quirk) {
                                mach_alt = mach->machine_quirk(mach);
                                if (!mach_alt)