ASoC: SOF: Make creation of machine device from SOF core optional
[linux-2.6-microblaze.git] / sound / soc / sof / intel / hda.c
index bfdb817..8d27846 100644 (file)
@@ -344,16 +344,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
        struct hdac_bus *bus = sof_to_bus(sdev);
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
        struct hdac_ext_link *hlink;
-       struct snd_soc_acpi_mach_params *mach_params;
-       struct snd_soc_acpi_mach *hda_mach;
-       struct snd_sof_pdata *pdata = sdev->pdata;
-       struct snd_soc_acpi_mach *mach;
-       const char *tplg_filename;
-       const char *idisp_str;
-       const char *dmic_str;
-       int dmic_num = 0;
-       int codec_num = 0;
-       int i;
 #endif
        int ret = 0;
 
@@ -387,94 +377,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
        if (bus->mlcap)
                snd_hdac_ext_bus_get_ml_capabilities(bus);
 
-       /* codec detection */
-       if (!bus->codec_mask) {
-               dev_info(bus->dev, "no hda codecs found!\n");
-       } else {
-               dev_info(bus->dev, "hda codecs found, mask %lx\n",
-                        bus->codec_mask);
-
-               for (i = 0; i < HDA_MAX_CODECS; i++) {
-                       if (bus->codec_mask & (1 << i))
-                               codec_num++;
-               }
-
-               /*
-                * If no machine driver is found, then:
-                *
-                * hda machine driver is used if :
-                * 1. there is one HDMI codec and one external HDAudio codec
-                * 2. only HDMI codec
-                */
-               if (!pdata->machine && codec_num <= 2 &&
-                   HDA_IDISP_CODEC(bus->codec_mask)) {
-                       hda_mach = snd_soc_acpi_intel_hda_machines;
-                       pdata->machine = hda_mach;
-
-                       /* topology: use the info from hda_machines */
-                       pdata->tplg_filename =
-                               hda_mach->sof_tplg_filename;
-
-                       /*
-                        * firmware: pick the first in machine list,
-                        * or use nocodec firmware name if list is empty
-                        */
-                       mach = pdata->desc->machines;
-                       if (mach->id[0])
-                               pdata->fw_filename = mach->sof_fw_filename;
-                       else
-                               pdata->fw_filename =
-                                       pdata->desc->nocodec_fw_filename;
-
-                       dev_info(bus->dev, "using HDA machine driver %s now\n",
-                                hda_mach->drv_name);
-
-                       if (codec_num == 1)
-                               idisp_str = "-idisp";
-                       else
-                               idisp_str = "";
-
-                       /* first check NHLT for DMICs */
-                       dmic_num = check_nhlt_dmic(sdev);
-
-                       /* allow for module parameter override */
-                       if (hda_dmic_num != -1)
-                               dmic_num = hda_dmic_num;
-
-                       switch (dmic_num) {
-                       case 2:
-                               dmic_str = "-2ch";
-                               break;
-                       case 4:
-                               dmic_str = "-4ch";
-                               break;
-                       default:
-                               dmic_num = 0;
-                               dmic_str = "";
-                               break;
-                       }
-
-                       tplg_filename = pdata->tplg_filename;
-                       tplg_filename = fixup_tplg_name(sdev, tplg_filename,
-                                                       idisp_str, dmic_str);
-                       if (!tplg_filename) {
-                               hda_codec_i915_exit(sdev);
-                               return ret;
-                       }
-                       pdata->tplg_filename = tplg_filename;
-               }
-       }
-
-       /* used by hda machine driver to create dai links */
-       if (pdata->machine) {
-               mach_params = (struct snd_soc_acpi_mach_params *)
-                       &pdata->machine->mach_params;
-               mach_params->codec_mask = bus->codec_mask;
-               mach_params->platform = dev_name(sdev->dev);
-               mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi;
-               mach_params->dmic_num = dmic_num;
-       }
-
        /* create codec instances */
        hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);
 
@@ -763,4 +665,133 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+static int hda_generic_machine_select(struct snd_sof_dev *sdev)
+{
+       struct hdac_bus *bus = sof_to_bus(sdev);
+       struct snd_soc_acpi_mach_params *mach_params;
+       struct snd_soc_acpi_mach *hda_mach;
+       struct snd_sof_pdata *pdata = sdev->pdata;
+       const char *tplg_filename;
+       const char *idisp_str;
+       const char *dmic_str;
+       int dmic_num = 0;
+       int codec_num = 0;
+       int i;
+
+       /* codec detection */
+       if (!bus->codec_mask) {
+               dev_info(bus->dev, "no hda codecs found!\n");
+       } else {
+               dev_info(bus->dev, "hda codecs found, mask %lx\n",
+                        bus->codec_mask);
+
+               for (i = 0; i < HDA_MAX_CODECS; i++) {
+                       if (bus->codec_mask & (1 << i))
+                               codec_num++;
+               }
+
+               /*
+                * If no machine driver is found, then:
+                *
+                * hda machine driver is used if :
+                * 1. there is one HDMI codec and one external HDAudio codec
+                * 2. only HDMI codec
+                */
+               if (!pdata->machine && codec_num <= 2 &&
+                   HDA_IDISP_CODEC(bus->codec_mask)) {
+                       hda_mach = snd_soc_acpi_intel_hda_machines;
+
+                       /* topology: use the info from hda_machines */
+                       pdata->tplg_filename =
+                               hda_mach->sof_tplg_filename;
+
+                       dev_info(bus->dev, "using HDA machine driver %s now\n",
+                                hda_mach->drv_name);
+
+                       if (codec_num == 1)
+                               idisp_str = "-idisp";
+                       else
+                               idisp_str = "";
+
+                       /* first check NHLT for DMICs */
+                       dmic_num = check_nhlt_dmic(sdev);
+
+                       /* allow for module parameter override */
+                       if (hda_dmic_num != -1)
+                               dmic_num = hda_dmic_num;
+
+                       switch (dmic_num) {
+                       case 2:
+                               dmic_str = "-2ch";
+                               break;
+                       case 4:
+                               dmic_str = "-4ch";
+                               break;
+                       default:
+                               dmic_num = 0;
+                               dmic_str = "";
+                               break;
+                       }
+
+                       tplg_filename = pdata->tplg_filename;
+                       tplg_filename = fixup_tplg_name(sdev, tplg_filename,
+                                                       idisp_str, dmic_str);
+                       if (!tplg_filename)
+                               return -EINVAL;
+
+                       pdata->machine = hda_mach;
+                       pdata->tplg_filename = tplg_filename;
+               }
+       }
+
+       /* used by hda machine driver to create dai links */
+       if (pdata->machine) {
+               mach_params = (struct snd_soc_acpi_mach_params *)
+                       &pdata->machine->mach_params;
+               mach_params->codec_mask = bus->codec_mask;
+               mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi;
+               mach_params->dmic_num = dmic_num;
+       }
+
+       return 0;
+}
+#else
+static int hda_generic_machine_select(struct snd_sof_dev *sdev)
+{
+       return 0;
+}
+#endif
+
+void hda_set_mach_params(const struct snd_soc_acpi_mach *mach,
+                        struct device *dev)
+{
+       struct snd_soc_acpi_mach_params *mach_params;
+
+       mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
+       mach_params->platform = dev_name(dev);
+}
+
+void hda_machine_select(struct snd_sof_dev *sdev)
+{
+       struct snd_sof_pdata *sof_pdata = sdev->pdata;
+       const struct sof_dev_desc *desc = sof_pdata->desc;
+       struct snd_soc_acpi_mach *mach;
+
+       mach = snd_soc_acpi_find_machine(desc->machines);
+       if (mach) {
+               sof_pdata->tplg_filename = mach->sof_tplg_filename;
+               sof_pdata->machine = mach;
+       }
+
+       /*
+        * Choose HDA generic machine driver if mach is NULL.
+        * Otherwise, set certain mach params.
+        */
+       hda_generic_machine_select(sdev);
+
+       if (!sof_pdata->machine)
+               dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
+}
+
 MODULE_LICENSE("Dual BSD/GPL");