diff options
Diffstat (limited to 'sound/soc/sof/intel')
-rw-r--r-- | sound/soc/sof/intel/atom.c | 16 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-probes.c | 16 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-stream.c | 15 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 86 | ||||
-rw-r--r-- | sound/soc/sof/intel/mtl.c | 13 |
5 files changed, 86 insertions, 60 deletions
diff --git a/sound/soc/sof/intel/atom.c b/sound/soc/sof/intel/atom.c index ff5900b155dc..bd9789b483b1 100644 --- a/sound/soc/sof/intel/atom.c +++ b/sound/soc/sof/intel/atom.c @@ -274,22 +274,22 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *ssp_str) { const char *tplg_filename = NULL; - char *filename; - char *split_ext; + const char *split_ext; + char *filename, *tmp; - filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); + filename = kstrdup(sof_tplg_filename, GFP_KERNEL); if (!filename) return NULL; /* this assumes a .tplg extension */ - split_ext = strsep(&filename, "."); - if (split_ext) { + tmp = filename; + split_ext = strsep(&tmp, "."); + if (split_ext) tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s-%s.tplg", split_ext, ssp_str); - if (!tplg_filename) - return NULL; - } + kfree(filename); + return tplg_filename; } diff --git a/sound/soc/sof/intel/hda-probes.c b/sound/soc/sof/intel/hda-probes.c index 31e85d4aae8c..56a533c63cb0 100644 --- a/sound/soc/sof/intel/hda-probes.c +++ b/sound/soc/sof/intel/hda-probes.c @@ -25,9 +25,9 @@ hda_compr_get_stream(struct snd_compr_stream *cstream) return cstream->runtime->private_data; } -static int hda_probes_compr_assign(struct sof_client_dev *cdev, - struct snd_compr_stream *cstream, - struct snd_soc_dai *dai, u32 *stream_id) +static int hda_probes_compr_startup(struct sof_client_dev *cdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai, u32 *stream_id) { struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); struct hdac_ext_stream *hext_stream; @@ -45,9 +45,9 @@ static int hda_probes_compr_assign(struct sof_client_dev *cdev, return 0; } -static int hda_probes_compr_free(struct sof_client_dev *cdev, - struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) +static int hda_probes_compr_shutdown(struct sof_client_dev *cdev, + struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) { struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream); struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev); @@ -127,8 +127,8 @@ static int hda_probes_compr_pointer(struct sof_client_dev *cdev, /* SOF client implementation */ static const struct sof_probes_host_ops hda_probes_ops = { - .assign = hda_probes_compr_assign, - .free = hda_probes_compr_free, + .startup = hda_probes_compr_startup, + .shutdown = hda_probes_compr_shutdown, .set_params = hda_probes_compr_set_params, .trigger = hda_probes_compr_trigger, .pointer = hda_probes_compr_pointer, diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 4531e1ee5ed0..b58662faa4aa 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -411,6 +411,11 @@ int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_st return -ENODEV; } + if (!dmab) { + dev_err(sdev->dev, "error: no dma buffer allocated!\n"); + return -ENODEV; + } + if (hstream->posbuf) *hstream->posbuf = 0; @@ -485,16 +490,16 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, return -ENODEV; } - /* decouple host and link DMA */ - mask = 0x1 << hstream->index; - snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, - mask, mask); - if (!dmab) { dev_err(sdev->dev, "error: no dma buffer allocated!\n"); return -ENODEV; } + /* decouple host and link DMA */ + mask = 0x1 << hstream->index; + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + mask, mask); + /* clear stream status */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, SOF_HDA_CL_DMA_SD_INT_MASK | diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index b7fa95ea1090..8639ea63a10d 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -776,13 +776,12 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, return tplg_filename; } -static int dmic_topology_fixup(struct snd_sof_dev *sdev, - const char **tplg_filename, - const char *idisp_str, - int *dmic_found) +static int dmic_detect_topology_fixup(struct snd_sof_dev *sdev, + const char **tplg_filename, + const char *idisp_str, + int *dmic_found, + bool tplg_fixup) { - const char *default_tplg_filename = *tplg_filename; - const char *fixed_tplg_filename; const char *dmic_str; int dmic_num; @@ -808,14 +807,19 @@ static int dmic_topology_fixup(struct snd_sof_dev *sdev, break; } - fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename, - idisp_str, dmic_str); - if (!fixed_tplg_filename) - return -ENOMEM; + if (tplg_fixup) { + const char *default_tplg_filename = *tplg_filename; + const char *fixed_tplg_filename; + + fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename, + idisp_str, dmic_str); + if (!fixed_tplg_filename) + return -ENOMEM; + *tplg_filename = fixed_tplg_filename; + } dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num); *dmic_found = dmic_num; - *tplg_filename = fixed_tplg_filename; return 0; } @@ -1221,6 +1225,8 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, * - one external HDAudio codec */ if (!*mach && codec_num <= 2) { + bool tplg_fixup; + hda_mach = snd_soc_acpi_intel_hda_machines; dev_info(bus->dev, "using HDA machine driver %s now\n", @@ -1232,8 +1238,15 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, idisp_str = ""; /* topology: use the info from hda_machines */ - tplg_filename = hda_mach->sof_tplg_filename; - ret = dmic_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num); + if (pdata->tplg_filename) { + tplg_fixup = false; + tplg_filename = pdata->tplg_filename; + } else { + tplg_fixup = true; + tplg_filename = hda_mach->sof_tplg_filename; + } + ret = dmic_detect_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num, + tplg_fixup); if (ret < 0) return; @@ -1397,30 +1410,37 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev } if (mach && mach->link_mask) { int dmic_num = 0; + bool tplg_fixup; + const char *tplg_filename; mach->mach_params.links = mach->links; mach->mach_params.link_mask = mach->link_mask; mach->mach_params.platform = dev_name(sdev->dev); - pdata->fw_filename = pdata->desc->default_fw_filename[pdata->ipc_type]; - pdata->tplg_filename = mach->sof_tplg_filename; + + if (pdata->tplg_filename) { + tplg_fixup = false; + } else { + tplg_fixup = true; + tplg_filename = mach->sof_tplg_filename; + } /* * DMICs use up to 4 pins and are typically pin-muxed with SoundWire - * link 2 and 3, thus we only try to enable dmics if all conditions - * are true: - * a) link 2 and 3 are not used by SoundWire + * link 2 and 3, or link 1 and 2, thus we only try to enable dmics + * if all conditions are true: + * a) 2 or fewer links are used by SoundWire * b) the NHLT table reports the presence of microphones */ - if (!(mach->link_mask & GENMASK(3, 2))) { - const char *tplg_filename = mach->sof_tplg_filename; + if (hweight_long(mach->link_mask) <= 2) { int ret; - ret = dmic_topology_fixup(sdev, &tplg_filename, "", &dmic_num); + ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "", + &dmic_num, tplg_fixup); if (ret < 0) return NULL; - - pdata->tplg_filename = tplg_filename; } + if (tplg_fixup) + pdata->tplg_filename = tplg_filename; mach->mach_params.dmic_num = dmic_num; dev_dbg(sdev->dev, @@ -1466,18 +1486,22 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) mach = snd_soc_acpi_find_machine(desc->machines); if (mach) { bool add_extension = false; + bool tplg_fixup = false; /* * If tplg file name is overridden, use it instead of * the one set in mach table */ - if (!sof_pdata->tplg_filename) + if (!sof_pdata->tplg_filename) { sof_pdata->tplg_filename = mach->sof_tplg_filename; + tplg_fixup = true; + } /* report to machine driver if any DMICs are found */ mach->mach_params.dmic_num = check_dmic_num(sdev); - if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER && + if (tplg_fixup && + mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER && mach->mach_params.dmic_num) { tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s%d%s", @@ -1500,8 +1524,10 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) /* report SSP link mask to machine driver */ mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev); - if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER && + if (tplg_fixup && + mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER && mach->mach_params.i2s_link_mask) { + const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata); int ssp_num; if (hweight_long(mach->mach_params.i2s_link_mask) > 1 && @@ -1511,6 +1537,12 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) /* fls returns 1-based results, SSPs indices are 0-based */ ssp_num = fls(mach->mach_params.i2s_link_mask) - 1; + if (ssp_num >= chip->ssp_count) { + dev_err(sdev->dev, "Invalid SSP %d, max on this platform is %d\n", + ssp_num, chip->ssp_count); + return NULL; + } + tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s%d", sof_pdata->tplg_filename, @@ -1523,7 +1555,7 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) add_extension = true; } - if (add_extension) { + if (tplg_fixup && add_extension) { tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s", sof_pdata->tplg_filename, diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index a5e244ea0688..96239ebb1eed 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -372,20 +372,9 @@ static int mtl_dsp_core_power_up(struct snd_sof_dev *sdev, int core) ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl, (dspcxctl & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); - if (ret < 0) { + if (ret < 0) dev_err(sdev->dev, "%s: timeout on MTL_DSP2CXCTL_PRIMARY_CORE read\n", __func__); - return ret; - } - - /* did core power up ? */ - dspcxctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE); - if ((dspcxctl & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) - != MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) { - dev_err(sdev->dev, "power up core failed core %d adspcs %#x\n", - core, dspcxctl); - ret = -EIO; - } return ret; } |