diff options
author | Mark Brown <broonie@kernel.org> | 2024-04-30 23:34:44 +0900 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2024-04-30 23:34:44 +0900 |
commit | af2ab6ccb93fb4031d15022a1f60904450a9517a (patch) | |
tree | 02a2bf5fbd7b98988c878e0dd1d0c16e82ba7bb5 | |
parent | 34c43ad927da59d032e263ee3ae1528c1ed31780 (diff) | |
parent | eed4872a4220f30de37aeca695d2881630410b66 (diff) | |
download | sound-af2ab6ccb93fb4031d15022a1f60904450a9517a.tar.gz |
ASoc: SOF: misc updates for 6.10
Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:
Fixes when fw_lib_prefix is not set, updated error messages, improved
dmesg logs to SoundWire configurations not supported by ACPI
tables/topology and support for IEC61937 passthrough.
-rw-r--r-- | sound/soc/sof/debug.c | 23 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 158 | ||||
-rw-r--r-- | sound/soc/sof/ipc4-topology.c | 50 | ||||
-rw-r--r-- | sound/soc/sof/topology.c | 7 |
4 files changed, 162 insertions, 76 deletions
diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index cf282c8b18af5a..bf635cc96ede05 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -326,8 +326,27 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev) debugfs_create_str("fw_path", 0444, fw_profile, (char **)&plat_data->fw_filename_prefix); - debugfs_create_str("fw_lib_path", 0444, fw_profile, - (char **)&plat_data->fw_lib_prefix); + /* library path is not valid for IPC3 */ + if (plat_data->ipc_type != SOF_IPC_TYPE_3) { + /* + * fw_lib_prefix can be NULL if the vendor/platform does not + * support loadable libraries + */ + if (plat_data->fw_lib_prefix) { + debugfs_create_str("fw_lib_path", 0444, fw_profile, + (char **)&plat_data->fw_lib_prefix); + } else { + static char *fw_lib_path; + + fw_lib_path = devm_kasprintf(sdev->dev, GFP_KERNEL, + "Not supported"); + if (!fw_lib_path) + return -ENOMEM; + + debugfs_create_str("fw_lib_path", 0444, fw_profile, + (char **)&fw_lib_path); + } + } debugfs_create_str("tplg_path", 0444, fw_profile, (char **)&plat_data->tplg_filename_prefix); debugfs_create_str("fw_name", 0444, fw_profile, diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 2fc10bec7331c7..d509cfa38a6429 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1645,6 +1645,7 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev { struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; + struct sdw_extended_slave_id *ids; struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; u32 link_mask; @@ -1653,92 +1654,109 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev hdev = pdata->hw_pdata; link_mask = hdev->info.link_mask; + if (!link_mask) { + dev_info(sdev->dev, "SoundWire links not enabled\n"); + return NULL; + } + + if (!hdev->sdw) { + dev_dbg(sdev->dev, "SoundWire context not allocated\n"); + return NULL; + } + + if (!hdev->sdw->num_slaves) { + dev_warn(sdev->dev, "No SoundWire peripheral detected in ACPI tables\n"); + return NULL; + } + /* * Select SoundWire machine driver if needed using the * alternate tables. This case deals with SoundWire-only * machines, for mixed cases with I2C/I2S the detection relies * on the HID list. */ - if (link_mask) { - for (mach = pdata->desc->alt_machines; - mach && mach->link_mask; mach++) { - /* - * On some platforms such as Up Extreme all links - * are enabled but only one link can be used by - * external codec. Instead of exact match of two masks, - * first check whether link_mask of mach is subset of - * link_mask supported by hw and then go on searching - * link_adr - */ - if (~link_mask & mach->link_mask) - continue; - - /* No need to match adr if there is no links defined */ - if (!mach->links) - break; - - link = mach->links; - for (i = 0; i < hdev->info.count && link->num_adr; - i++, link++) { - /* - * Try next machine if any expected Slaves - * are not found on this link. - */ - if (!snd_soc_acpi_sdw_link_slaves_found(sdev->dev, link, - hdev->sdw->ids, - hdev->sdw->num_slaves)) - break; - } - /* Found if all Slaves are checked */ - if (i == hdev->info.count || !link->num_adr) - break; - } - 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); + for (mach = pdata->desc->alt_machines; + mach && mach->link_mask; mach++) { + /* + * On some platforms such as Up Extreme all links + * are enabled but only one link can be used by + * external codec. Instead of exact match of two masks, + * first check whether link_mask of mach is subset of + * link_mask supported by hw and then go on searching + * link_adr + */ + if (~link_mask & mach->link_mask) + continue; - if (pdata->tplg_filename) { - tplg_fixup = false; - } else { - tplg_fixup = true; - tplg_filename = mach->sof_tplg_filename; - } + /* No need to match adr if there is no links defined */ + if (!mach->links) + break; + link = mach->links; + for (i = 0; i < hdev->info.count && link->num_adr; + i++, link++) { /* - * DMICs use up to 4 pins and are typically pin-muxed with 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 + * Try next machine if any expected Slaves + * are not found on this link. */ - if (hweight_long(mach->link_mask) <= 2) { - int ret; - - ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "", - &dmic_num, tplg_fixup); - if (ret < 0) - return NULL; - } - if (tplg_fixup) - pdata->tplg_filename = tplg_filename; - mach->mach_params.dmic_num = dmic_num; + if (!snd_soc_acpi_sdw_link_slaves_found(sdev->dev, link, + hdev->sdw->ids, + hdev->sdw->num_slaves)) + break; + } + /* Found if all Slaves are checked */ + if (i == hdev->info.count || !link->num_adr) + break; + } + 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); + + if (pdata->tplg_filename) { + tplg_fixup = false; + } else { + tplg_fixup = true; + tplg_filename = mach->sof_tplg_filename; + } - dev_dbg(sdev->dev, - "SoundWire machine driver %s topology %s\n", - mach->drv_name, - pdata->tplg_filename); + /* + * DMICs use up to 4 pins and are typically pin-muxed with 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 (hweight_long(mach->link_mask) <= 2) { + int ret; - return mach; + ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "", + &dmic_num, tplg_fixup); + if (ret < 0) + return NULL; } + if (tplg_fixup) + pdata->tplg_filename = tplg_filename; + mach->mach_params.dmic_num = dmic_num; - dev_info(sdev->dev, "No SoundWire machine driver found\n"); + dev_dbg(sdev->dev, + "SoundWire machine driver %s topology %s\n", + mach->drv_name, + pdata->tplg_filename); + + return mach; } + dev_info(sdev->dev, "No SoundWire machine driver found for the ACPI-reported configuration:\n"); + ids = hdev->sdw->ids; + for (i = 0; i < hdev->sdw->num_slaves; i++) + dev_info(sdev->dev, "link %d mfg_id 0x%04x part_id 0x%04x version %#x\n", + ids[i].link_id, ids[i].id.mfg_id, ids[i].id.part_id, ids[i].id.sdw_version); + return NULL; } #else diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index c29c1de4e92583..a972b2b5122a38 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -407,6 +407,52 @@ static void sof_ipc4_widget_update_kcontrol_module_id(struct snd_sof_widget *swi } } +static int +sof_ipc4_update_card_components_string(struct snd_sof_widget *swidget, + struct snd_sof_pcm *spcm, int dir) +{ + struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + struct snd_soc_component *scomp = spcm->scomp; + struct snd_soc_card *card = scomp->card; + const char *pt_marker = "iec61937-pcm"; + + /* + * Update the card's components list with iec61937-pcm and a list of PCM + * ids where ChainDMA is enabled. + * These PCMs can be used for bytestream passthrough. + */ + if (!pipeline->use_chain_dma) + return 0; + + if (card->components) { + const char *tmp = card->components; + + if (strstr(card->components, pt_marker)) + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s,%d", + card->components, + spcm->pcm.pcm_id); + else + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s %s:%d", + card->components, + pt_marker, + spcm->pcm.pcm_id); + + devm_kfree(card->dev, tmp); + } else { + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s:%d", pt_marker, + spcm->pcm.pcm_id); + } + + if (!card->components) + return -ENOMEM; + + return 0; +} + static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) { struct sof_ipc4_available_audio_format *available_fmt; @@ -452,6 +498,10 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) if (!spcm) goto skip_gtw_cfg; + ret = sof_ipc4_update_card_components_string(swidget, spcm, dir); + if (ret) + goto free_available_fmt; + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { struct snd_sof_pcm_stream *sps = &spcm->stream[dir]; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index bcdb499c96a022..ec931a26b54f00 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1531,10 +1531,9 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, /* check token parsing reply */ if (ret < 0) { dev_err(scomp->dev, - "error: failed to add widget id %d type %d name : %s stream %s\n", - tw->shift, swidget->id, tw->name, - strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 - ? tw->sname : "none"); + "failed to add widget type %d name : %s stream %s\n", + swidget->id, tw->name, strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 + ? tw->sname : "none"); goto widget_free; } |