From a8d2f641770fdece865290c879675c2bd37a87b1 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Wed, 28 Nov 2018 10:59:32 +0800 Subject: [PATCH] ASoC: SOF: refine the selection of machine drivers Now hda machine driver and no codec driver is mutually exclusive. If hda machine driver is selected in kconfig, no codec driver would not work. The new algorithm is: if no machine is found at pci or acpi probe function, no codec driver is appiled first. At the hda probe time, hda machine driver is applied if there are hda codecs except hdmi codec. Signed-off-by: Rander Wang --- sound/soc/sof/core.c | 6 +++--- sound/soc/sof/intel/hda.c | 41 +++++++++++++++++++++++++++++++----- sound/soc/sof/sof-acpi-dev.c | 6 ------ sound/soc/sof/sof-pci-dev.c | 16 -------------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index f92279c688e688..0f021ac062d144 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -260,9 +260,6 @@ static int sof_probe(struct platform_device *pdev) spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); - /* set up platform component driver */ - snd_sof_new_platform_drv(sdev); - /* set default timeouts if none provided */ if (plat_data->desc->ipc_timeout == 0) sdev->ipc_timeout = TIMEOUT_DEFAULT_IPC; @@ -280,6 +277,9 @@ static int sof_probe(struct platform_device *pdev) return ret; } + /* set up platform component driver */ + snd_sof_new_platform_drv(sdev); + /* register any debug/trace capabilities */ ret = snd_sof_dbg_init(sdev); if (ret < 0) { diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index d90134cf3b36e8..9150d669698525 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "../sof-priv.h" #include "../ops.h" @@ -438,8 +439,11 @@ static int hda_init_caps(struct snd_sof_dev *sdev) struct pci_dev *pci = sdev->pci; struct hdac_ext_link *hlink = NULL; struct snd_soc_acpi_mach_params *mach_params; + struct snd_soc_acpi_mach *mach; + struct snd_sof_pdata *pdata; + int codec_num = 0; int ret = 0; - int err; + int err, i; device_disable_async_suspend(bus->dev); @@ -472,10 +476,37 @@ static int hda_init_caps(struct snd_sof_dev *sdev) else dev_info(bus->dev, "hda codecs found, mask %lx!\n", bus->codec_mask); - /* used by hda machine driver to create dai links */ - mach_params = (struct snd_soc_acpi_mach_params *) - &sdev->pdata->machine->mach_params; - mach_params->codec_mask = bus->codec_mask; + if (bus->codec_mask) { + for (i = 0; i < HDA_MAX_CODECS; i++) { + if (bus->codec_mask & (1 << i)) + codec_num++; + } + + /* if there are HDMI codec and HDA codecs, hda machine + * is applied. For I2S codec + HDMI codec, there is only one + * hda codec. For other cases, the value should be zero. + */ + if (codec_num > 1) { + /* used by hda machine driver to create dai links */ + pdata = sdev->pdata; + + mach = snd_soc_acpi_intel_hda_machines; + mach->pdata = pdata->machine->pdata; + mach->sof_fw_filename = + pdata->desc->nocodec_fw_filename; + mach->new_mach_data = + pdata->machine->new_mach_data; + + mach_params = &mach->mach_params; + mach_params->codec_mask = bus->codec_mask; + mach_params->platform = pdata->platform; + + devm_kfree(sdev->dev, (void *)pdata->machine); + pdata->machine = mach; + + dev_info(sdev->dev, "Find hda codecs, use hda machine driver\n"); + } + } /* create codec instances */ hda_codec_probe_bus(sdev); diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index f77bd078f78947..e35381799b49ca 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -224,18 +224,12 @@ static int sof_acpi_probe(struct platform_device *pdev) /* find machine */ mach = snd_soc_acpi_find_machine(desc->machines); if (!mach) { -#if IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC) /* fallback to nocodec mode */ dev_warn(dev, "No matching ASoC machine driver found - using nocodec\n"); mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) return ret; -#else - dev_warn(dev, "No matching ASoC machine driver found - falling back to HDA codec\n"); - mach = snd_soc_acpi_intel_hda_machines; - mach->sof_fw_filename = desc->nocodec_fw_filename; -#endif } #endif diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 0381d5198e5895..2cd661aa40ba76 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -222,20 +222,6 @@ static int sof_pci_probe(struct pci_dev *pci, #else /* find machine */ mach = snd_soc_acpi_find_machine(desc->machines); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - if (!mach) { - dev_warn(dev, "No matching ASoC machine driver found - falling back to HDA codec\n"); - mach = snd_soc_acpi_intel_hda_machines; - mach->sof_fw_filename = desc->nocodec_fw_filename; - - /* - * TODO: we need to find a way to check if codecs are actually - * present - */ - } -#endif /* CONFIG_SND_SOC_SOF_HDA */ - -#if IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC) if (!mach) { /* fallback to nocodec mode */ dev_warn(dev, "No matching ASoC machine driver found - using nocodec\n"); @@ -244,8 +230,6 @@ static int sof_pci_probe(struct pci_dev *pci, if (ret < 0) goto release_regions; } -#endif /* CONFIG_SND_SOC_SOF_NOCODEC */ - #endif /* CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE */ mach->pdata = ops;