ASoC: Intel: add I2S function topology support#5657
ASoC: Intel: add I2S function topology support#5657bardliao wants to merge 6 commits intothesofproject:topic/sof-devfrom
Conversation
ujfalusi
left a comment
There was a problem hiding this comment.
only checked the first patch
| } | ||
|
|
||
| dev_err(dev, "%s: No match for SSP%d in NHLT table\n", __func__, | ||
| dev_dbg(dev, "%s: No match for SSP%d in NHLT table\n", __func__, |
There was a problem hiding this comment.
I would have this as separate patch?
we are also going to look for DMIC blobs in several nhlt, so change those prints as well?
There was a problem hiding this comment.
Not sure about the DMIC blobs. Maybe we can change the DMIC prints when we look for DMIC blobs in several nhlt?
There was a problem hiding this comment.
but we do after the second patch...
There could be NHLT blobs w/o DMIC (SSP fragment) and we would print error/warn?
There was a problem hiding this comment.
intel_nhlt_get_endpoint_blob() will be called for each NHLT blobs, but it uses dev_dbg already.
There was a problem hiding this comment.
you need to call out that in preparation for supporting multiple topology fragments per function which could end up calling this function multiple types with NHLT blobs from different fragments, downgrade the error message to debug level.
There was a problem hiding this comment.
Commit message updated. But do you mean to move the commit to before the ASoC: SOF: get nhlt from all topologies commit?
| channel_count, sample_rate, | ||
| dir, dev_type); | ||
| if (cfg) | ||
| break; |
There was a problem hiding this comment.
goto out; and remove the cfg check after the loop?
a0fd522 to
8d4c0c3
Compare
| } | ||
|
|
||
| dev_err(dev, "%s: No match for SSP%d in NHLT table\n", __func__, | ||
| dev_dbg(dev, "%s: No match for SSP%d in NHLT table\n", __func__, |
There was a problem hiding this comment.
but we do after the second patch...
There could be NHLT blobs w/o DMIC (SSP fragment) and we would print error/warn?
| dai_index); | ||
| if (dev_type < 0) | ||
| list_for_each_entry(nhlt, &ipc4_data->nhlt_list, list) { | ||
| dev_type = intel_nhlt_ssp_device_type(sdev->dev, nhlt->nhlt, |
There was a problem hiding this comment.
nitpick: nhlt->nhlt, can we do entry->nhlt instead? the outer nhlt is not nhlt as such.
| if (!(*tplg_files)[tplg_num]) | ||
| return -ENOMEM; | ||
| tplg_num++; | ||
| } |
There was a problem hiding this comment.
To my untrained eyes this looks like identical to what sof_sdw_get_tplg_files() would do, just that this lacks the SDW part, no?
Why not rename that function ad use it for all types as universal tool?
There was a problem hiding this comment.
Yeah, I thought about it. And yes, they look quite similar, but the existing topologies may use different PCM IDs for different machines. I think it would be better to use separated function to keep the flexibility to have different function topology names for different machines.
8d4c0c3 to
1af3d92
Compare
|
Tested HDMI in capture and I2S functional. observed the expected behavior. |
| } | ||
|
|
||
| dev_err(dev, "%s: No match for SSP%d in NHLT table\n", __func__, | ||
| dev_dbg(dev, "%s: No match for SSP%d in NHLT table\n", __func__, |
There was a problem hiding this comment.
you need to call out that in preparation for supporting multiple topology fragments per function which could end up calling this function multiple types with NHLT blobs from different fragments, downgrade the error message to debug level.
1af3d92 to
9fdc58f
Compare
lgirdwood
left a comment
There was a problem hiding this comment.
LGTM, one nitpick would be it could do with more inline commentary when it comes to how we are searching for files.
9fdc58f to
fd2f6cc
Compare
ujfalusi
left a comment
There was a problem hiding this comment.
I think this looks good, but not really sure how it is planned to be used in practice ;)
|
CI needs kicked. |
|
SOFCI TEST |
fd2f6cc to
e6325cc
Compare
|
change: |
There was a problem hiding this comment.
Pull request overview
This PR extends SOF “function topology” support beyond SoundWire machines to also cover Intel I2S (SSP) machines. It does so by (a) allowing multiple NHLT tables (BIOS + topology manifest) to be tracked and consulted during blob lookups, and (b) adding an I2S-specific function-topology file selection helper and wiring it into PTL machine matching.
Changes:
- Replace single
ipc4_data->nhltstorage with annhlt_listand update IPC4 NHLT blob/device-type lookups to iterate across tables. - Add
sof_i2s_get_tplg_files()to generate function-topology fragment lists for I2S machines and enable it for PTL I2S entries. - Reduce log severity in
intel_nhlt_ssp_device_type()when NHLT is missing/no match.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| sound/soc/sof/ipc4-topology.c | Use a list of NHLT tables for SSP/DMIC endpoint blob lookup; add topology-manifest NHLT entries to the list. |
| sound/soc/sof/ipc4-priv.h | Introduce struct snd_ipc4_nhlt and replace single NHLT pointer with nhlt_list. |
| sound/soc/sof/ipc4-loader.c | Initialize nhlt_list during IPC4 firmware parsing. |
| sound/soc/sof/intel/hda-dai.c | Add BIOS NHLT to nhlt_list and attempt to free it during teardown. |
| sound/soc/intel/common/sof-function-topology-lib.h | Export new sof_i2s_get_tplg_files() API. |
| sound/soc/intel/common/sof-function-topology-lib.c | Implement I2S function-topology selection and refactor common helpers. |
| sound/soc/intel/common/soc-acpi-intel-ptl-match.c | Enable function topologies for PTL I2S machines via sof_i2s_get_tplg_files. |
| sound/hda/core/intel-nhlt.c | Downgrade NHLT “missing/no match” logs from error to debug. |
Comments suppressed due to low confidence (1)
sound/soc/sof/ipc4-loader.c:156
INIT_LIST_HEAD(&ipc4_data->nhlt_list)here re-initializes the list during firmware parsing. If any NHLT entries were already added earlier (e.g. from BIOS during ops init), this will discard them and leave dangling list nodes. The list should be initialized once whensof_ipc4_fw_datais allocated, and this re-init should be removed or guarded so it cannot clobber existing entries.
static size_t sof_ipc4_fw_parse_basefw_ext_man(struct snd_sof_dev *sdev)
{
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct sof_ipc4_fw_library *fw_lib;
ssize_t payload_offset;
int ret;
INIT_LIST_HEAD(&ipc4_data->nhlt_list);
if (sdev->dsp_test_mode_enabled)
fw_lib = devm_kzalloc(sdev->dev, sizeof(*fw_lib), GFP_KERNEL);
else
fw_lib = devm_kzalloc(sdev->dev, sizeof(*fw_lib), GFP_KERNEL);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4 && !hda_use_tplg_nhlt) { | ||
| struct sof_ipc4_fw_data *ipc4_data = sdev->private; | ||
| struct snd_ipc4_nhlt *entry; | ||
|
|
||
| ipc4_data->nhlt = intel_nhlt_init(sdev->dev); | ||
| entry = devm_kzalloc(sdev->dev, sizeof(*entry), GFP_KERNEL); | ||
| if (!entry) | ||
| return; | ||
|
|
||
| entry->nhlt = intel_nhlt_init(sdev->dev); | ||
|
|
||
| list_add(&entry->list, &ipc4_data->nhlt_list); | ||
| } |
There was a problem hiding this comment.
@copilot INIT_LIST_HEAD(&ipc4_data->nhlt_list); is called in the sof_ipc4_fw_parse_basefw_ext_man() function which will be called when loading the firmware that is guarantee before this function is called.
| void hda_ops_free(struct snd_sof_dev *sdev) | ||
| { | ||
| if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { | ||
| struct sof_ipc4_fw_data *ipc4_data = sdev->private; | ||
| struct snd_ipc4_nhlt *entry; | ||
|
|
||
| if (!hda_use_tplg_nhlt) | ||
| intel_nhlt_free(ipc4_data->nhlt); | ||
| if (!hda_use_tplg_nhlt) { | ||
| entry = list_first_entry(&ipc4_data->nhlt_list, | ||
| struct snd_ipc4_nhlt, list); | ||
| intel_nhlt_free(entry->nhlt); | ||
| list_del(&entry->list); | ||
| } |
| int ret; | ||
|
|
||
| ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform); | ||
| if (ret != 1) { | ||
| dev_err(card->dev, "Invalid platform name %s of tplg %s\n", | ||
| platform, mach->sof_tplg_filename); | ||
| return -EINVAL; | ||
| } |
| unsigned int ssp_port; | ||
|
|
||
| if (sscanf(dai_link->name, "SSP%d", &ssp_port) != 1) { | ||
| dev_err(dev, "Invalid SSP port %d\n", ssp_port); | ||
| return -EINVAL; | ||
| } | ||
| if (strstr(dai_link->name, "Codec")) { | ||
| /* | ||
| * Assume DAI link 0 is jack which is true in all existing | ||
| * machine drivers | ||
| */ | ||
| if (dai_link->id == 0) { | ||
| *tplg_dev = TPLG_DEVICE_SSP_JACK; | ||
| *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL, | ||
| "ssp%d-jack", ssp_port); | ||
| } else { | ||
| *tplg_dev = TPLG_DEVICE_SSP_AMP; | ||
| *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL, | ||
| "ssp%d-amp", ssp_port); | ||
| } | ||
| } else if (strstr(dai_link->name, "BT")) { | ||
| *tplg_dev = TPLG_DEVICE_SSP_BT; | ||
| *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL, | ||
| "ssp%d-bt", ssp_port); | ||
| } else if (strstr(dai_link->name, "HDMI")) { |
| if (strstr(dai_link->name, "SSP")) { | ||
| unsigned int ssp_port; | ||
|
|
||
| if (sscanf(dai_link->name, "SSP%d", &ssp_port) != 1) { | ||
| dev_err(card->dev, "Invalid SSP port %d\n", ssp_port); | ||
| return -EINVAL; | ||
| } | ||
| if (strstr(dai_link->name, "Codec")) { | ||
| /* | ||
| * Assume DAI link 0 is jack which is true in all existing | ||
| * machine driver | ||
| */ | ||
| if (dai_link->id == 0) { | ||
| tplg_dev = TPLG_DEVICE_SSP_JACK; | ||
| tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL, | ||
| "ssp%d-jack", ssp_port); | ||
| } else { | ||
| tplg_dev = TPLG_DEVICE_SSP_AMP; | ||
| tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL, | ||
| "ssp%d-amp", ssp_port); | ||
| } | ||
| } else if (strstr(dai_link->name, "BT")) { | ||
| tplg_dev = TPLG_DEVICE_SSP_BT; | ||
| tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL, | ||
| "ssp%d-bt", ssp_port); | ||
| } else if (strstr(dai_link->name, "HDMI")) { |
The existing code assumes there is only one NHLT blob either from BIOS or topology. As function topologies are used and each function topology contains a NHLT blob section, we need to search the matching NHLT blob from all the NHLT blobs. The commit suggests adding a list of NHLTs and search the NHLTs from the list. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
To support multiple topology fragments per function, this function could be called multiple types with different NHLT blobs from different fragments. Downgrade the error message to debug level since the SSP device type could be found from one of the nhlt. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The existing code supports get_function_tplg_files callback for SoundWire machine driver only. Some common sections can be used to extend the support to other machines. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
…et_tplg_files The Intel SOF SDW machine drive also supports I2S interface. Add related supports for the sof_sdw_get_tplg_files() callback. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
… I2S machines Add sof_i2s_get_tplg_files() callback for Intel SOF I2S machines. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Use sof_i2s_get_tplg_files() for SOF es83x6 machines. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Currently, function topology is only used by the SoundWire machines. Extend the support to the I2S machines.