Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: SOF: ipc4-topology: Add support for NHLT with 16-bit only DMIC blob

The ACPI NHLT table always had 32-bit DMIC blob even if 16-bit was also
present and taken as a 'rule' which obviously got broken and there is at
least one device on the market which ships with only 16-bit DMIC
configuration blob.
This corner case has never been supported and it is going to need topology
updates for DMIC copier to support multiple formats.

As for the kernel side: if the copier supports multiple formats and the
preferred 32-bit DMIC blob is not found then we will try to get a 16-bit
DMIC configuration and look for a 16-bit copier config.

Fixes: f9209644ae76 ("ASoC: SOF: ipc4-topology: Correct DAI copier config and NHLT blob request")
Link: https://github.com/thesofproject/linux/issues/4973
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://msgid.link/r/20240516075611.18018-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Peter Ujfalusi and committed by
Mark Brown
d556f807 6f80324b

+22 -3
+22 -3
sound/soc/sof/ipc4-topology.c
··· 1483 1483 dir, dev_type); 1484 1484 1485 1485 if (!cfg) { 1486 + bool get_new_blob = false; 1487 + 1486 1488 if (format_change) { 1487 1489 /* 1488 1490 * The 32-bit blob was not found in NHLT table, try to ··· 1492 1490 */ 1493 1491 bit_depth = params_width(params); 1494 1492 format_change = false; 1493 + get_new_blob = true; 1494 + } else if (linktype == SOF_DAI_INTEL_DMIC && !single_format) { 1495 + /* 1496 + * The requested 32-bit blob (no format change for the 1497 + * blob request) was not found in NHLT table, try to 1498 + * look for 16-bit blob if the copier supports multiple 1499 + * formats 1500 + */ 1501 + bit_depth = 16; 1502 + format_change = true; 1503 + get_new_blob = true; 1504 + } 1495 1505 1506 + if (get_new_blob) { 1496 1507 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, 1497 1508 dai_index, nhlt_type, 1498 1509 bit_depth, bit_depth, ··· 1528 1513 1529 1514 if (format_change) { 1530 1515 /* 1531 - * Update the params to reflect that we have loaded 32-bit blob 1532 - * instead of the 16-bit. 1516 + * Update the params to reflect that different blob was loaded 1517 + * instead of the requested bit depth (16 -> 32 or 32 -> 16). 1533 1518 * This information is going to be used by the caller to find 1534 1519 * matching copier format on the dai side. 1535 1520 */ ··· 1537 1522 1538 1523 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1539 1524 snd_mask_none(m); 1540 - snd_mask_set_format(m, SNDRV_PCM_FORMAT_S32_LE); 1525 + if (bit_depth == 16) 1526 + snd_mask_set_format(m, SNDRV_PCM_FORMAT_S16_LE); 1527 + else 1528 + snd_mask_set_format(m, SNDRV_PCM_FORMAT_S32_LE); 1529 + 1541 1530 } 1542 1531 1543 1532 return 0;