summaryrefslogtreecommitdiff
path: root/include/sound/soc.h
AgeCommit message (Collapse)Author
2025-05-12ASoC: soc-core: merge snd_soc_unregister_component() and ↵Kuninori Morimoto
snd_soc_unregister_component_by_driver() We have below 2 functions, but these are very similar (A) snd_soc_unregister_component_by_driver() (B) snd_soc_unregister_component() (A) void snd_soc_unregister_component_by_driver(...) { ... (a) mutex_lock(&client_mutex); ^ (X) component = snd_soc_lookup_component_nolocked(dev, component_driver->name); | if (!component) ^^^^^^^^^^^^^^^^^^^^^^ | goto out; (b) | snd_soc_del_component_unlocked(component); v out: (c) mutex_unlock(&client_mutex); } (B) void snd_soc_unregister_component_by_driver(...) { (a) mutex_lock(&client_mutex); ^ while (1) { | (X) struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, NULL); | ^^^^ (b) if (!component) | break; | | snd_soc_del_component_unlocked(component); v } (c) mutex_unlock(&client_mutex); } Both are calling lock (a), find component and remove it (b), and unlock (c). The big diff is whether use driver name for lookup() or not (X). Merge these into snd_soc_unregister_component_by_driver() (B), and snd_soc_unregister_component_by_driver() (A) can be macro. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87h61qy2vn.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-05-09ASoC: soc.h: remove unnecessary definitionsKuninori Morimoto
We don't need these definitions. Remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87ldr6pqlh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-05-09ASoC: soc.h: remove snd_soc_disconnect_sync()Kuninori Morimoto
There is no snd_soc_disconnect_sync() implementation, and no one is using it. Let's remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87jz6qpql7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-05-03ASoC: soc-utils: add snd_soc_dlc_is_dummy()Mark Brown
Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>: We are using dummy component/dlc, but didn't have its check funciton. This patch adds it.
2025-05-02ASoC: soc-utils: add snd_soc_dlc_is_dummy()Kuninori Morimoto
We have snd_soc_xxx_is_dummy() functions, but not for dlc. Let's add it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87cydc8vup.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-04-06ASoC: core: Complete support for card rebindingCezary Rojewski
Since commit e894efef9ac7 ("ASoC: core: add support to card rebind") there is a support for card rebind. The support is only partial though. Let's consider the following scenarios both of which aim to enumerate a sound card: 1) snd_soc_add_component(comp1); (...) snd_soc_register_card(card1); 2) snd_soc_register_card(card1); (...) snd_soc_add_component(comp1); For the sake of simplicity, let comp1 be the last dependency needed for the card1 to enumerate. Case 1) will end up succeeding whereas 2) is a certain fail - snd_soc_bind_card() does not honor unbind_card_list so even a non-fatal return code of EPROBE_DEFER will cause the card to collapse. Given the typical usecase of platform_device serving as a card->dev and its probe() ending with: int carddev_probe(struct platform_device *pdev) { (...) return devm_snd_soc_register_card(dev, card); } failure to register card triggers device_unbind_cleanup() - really_probe() in dd.c. To allow for card registration to be deferred while being friendly towards existing users of devm_snd_soc_register_card(), add new card->devres_dev field, and devm_xxx() variants for card registration: devm_snd_soc_register_deferrable_card() (external) devm_snd_soc_bind_card() (internal) In essence, if requested, devm_snd_soc_bind_card() replaces snd_soc_bind_card(). The rebind procedure takes care of destroying old devres before attempting the new bind. This makes sure nothing is left hanging if binding fails and card becomes unbound but is still registered to the ASoC framework. To allow snd_soc_bind_card() to be reused by the deferrable friends, move 'client_mutex' locking to the function's callers and select between devm_xxx and non-devm_xxx variants of snd_soc_bind_card() based on card->devres_dev. On top of the feature, the refactoring brings two benefits: a) single lock/unlock of 'client_mutex' in snd_soc_add_component() instead of ambiguous unlock and immediate lock in snd_soc_try_rebind_card() b) all unbind_card_list manipulations done under 'client_mutex' Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://patch.msgid.link/20250404101622.3673850-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-19ASoC: ops: Remove snd_soc_put_volsw_range()Charles Keepax
With the addition of the soc_mixer_ctl_to_reg() helper it is now very clear that the only difference between snd_soc_put_volsw() and snd_soc_put_volsw_range() is that the former supports double controls with both values in the same register. As such we can combine both functions. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250318171459.3203730-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-19ASoC: ops: Remove snd_soc_get_volsw_range()Charles Keepax
With the addition of the soc_mixer_reg_to_ctl() helper it is now very clear that the only difference between snd_soc_get_volsw() and snd_soc_get_volsw_range() is that the former supports double controls with both values in the same register. As such we can combine both functions. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250318171459.3203730-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-19ASoC: ops: Remove snd_soc_info_volsw_range()Charles Keepax
The only difference between snd_soc_info_volsw() and snd_soc_info_volsw_range() is that the later will not force a 2 value control to be of type integer if the name ends in "Volume". The kernel currently contains no users of snd_soc_info_volsw_range() that would return a boolean control with this code, so the risk is quite low and it seems appropriate that it should contain volume control detection. So remove snd_soc_info_volsw_range() and point its users at snd_soc_info_volsw(). Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250318171459.3203730-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-14ASoC: Merge up fixesMark Brown
Merge the for-6.14 to resolve conflicts with simple-card-utils.c due to parallel delveopment.
2025-03-05ASoC: ops: Consistently treat platform_max as control valueCharles Keepax
This reverts commit 9bdd10d57a88 ("ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min"), and makes some additional related updates. There are two ways the platform_max could be interpreted; the maximum register value, or the maximum value the control can be set to. The patch moved from treating the value as a control value to a register one. When the patch was applied it was technically correct as snd_soc_limit_volume() also used the register interpretation. However, even then most of the other usages treated platform_max as a control value, and snd_soc_limit_volume() has since been updated to also do so in commit fb9ad24485087 ("ASoC: ops: add correct range check for limiting volume"). That patch however, missed updating snd_soc_put_volsw() back to the control interpretation, and fixing snd_soc_info_volsw_range(). The control interpretation makes more sense as limiting is typically done from the machine driver, so it is appropriate to use the customer facing representation rather than the internal codec representation. Update all the code to consistently use this interpretation of platform_max. Finally, also add some comments to the soc_mixer_control struct to hopefully avoid further patches switching between the two approaches. Fixes: fb9ad24485087 ("ASoC: ops: add correct range check for limiting volume") Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250228151456.3703342-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-04ASoC: Tidy up SOC_DOUBLE_* and SOC_SINGLE_* helpersCharles Keepax
Re-implement SOC_DOUBLE_VALUE() in terms of SOC_DOUBLE_S_VALUE(). SOC_DOUBLE_S_VALUE() already had a minimum value so add this to SOC_DOUBLE_VALUE as well, this allows replacement of several hard coded value entries. Likewise update SOC_SINGLE_VALUE to match, which allows replacement of even more hard coded values. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250304140500.976127-14-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-03ASoC: Tidy up SOC_DOUBLE_R_* helpersCharles Keepax
Re-implement SOC_DOUBLE_R_VALUE() in terms of SOC_DOUBLE_R_S_VALUE(). SOC_DOUBLE_R_S_VALUE() already had a minimum value so add this to SOC_DOUBLE_R_VALUE() as well, which makes SOC_DOUBLE_R_RANGE_VALUE() redundant, so its usage is replaced. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250303171424.444556-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-03-03ASoC: Remove unused helper macroCharles Keepax
SOC_SINGLE_VALUE_EXT() has no users, so remove it. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250303171424.444556-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-02-24ASoC: topology: Save num_channels value for mixer controlsCezary Rojewski
To provide minimal support for multi-channel kcontrols i.e.: more than stereo configuration, store the number of channels specified within the SectionControlMixer. The field is part of the topology standard, currently skipped by the ASoC core. Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://patch.msgid.link/20250217102115.3539427-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-02-16ASoC: remove update from snd_soc_cardKuninori Morimoto
snd_soc_card :: update is used only for passing parameters to dapm_widget_update() like below. card->update = update; ret = soc_dapm_xxx(card, ...); card->update = NULL; Let's passing it via function parameter and remove update from snd_soc_card. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87ldubyjz9.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-02-16ASoC: soc-core: makes snd_soc_set_dmi_name() localKuninori Morimoto
soc-core.c only calls snd_soc_set_dmi_name(), so we don't need to have EXPORT_SYMBOL_GPL() for it. Let's makes it local function. No one uses *flavour parameter, let's remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87v7tfyk7b.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-02-06ASoC: add common snd_soc_ret() and use itKuninori Morimoto
Each soc-xxx.c is using own snd_xxx_ret(), but we want to share it. Let's add common snd_soc_ret() for it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87frkt2qlx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-01-13ASoC: soc-core: Enable to use extra format on each DAIKuninori Morimoto
Current ASoC is using dai_link->dai_fmt to set DAI format for both CPU/Codec. But because it is using same settings, and SND_SOC_DAIFMT_CLOCK_PROVIDER is flipped for CPU, we can't set both CPU/Codec as clock consumer, for example. To solve this issue, this patch enable to use extra format for each DAI which can keep compatibility with legacy system, 1. SND_SOC_DAIFMT_FORMAT_MASK 2. SND_SOC_DAIFMT_CLOCK 3. SND_SOC_DAIFMT_INV 4. SND_SOC_DAIFMT_CLOCK_PROVIDER Legacy dai_fmt includes 1, 2, 3, 4 New idea dai_fmt includes 1, 2, 3 ext_fmt includes 4 Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Stephen Gordon <gordoste@iinet.net.au> Link: https://patch.msgid.link/87r05go5ja.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2025-01-09ASoC: remove disable_route_checksKuninori Morimoto
No driver is using disable_route_checks, let's remove it. Because snd_soc_dapm_add_routes() itself will indicate detail error when failed, this patch removes duplicate dev_err() not only dev_warn() in error case. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Suggested-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Tested-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Link: https://patch.msgid.link/87tta8268e.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-11-01ASoC: cleanup function parameter for rtd and its idKuninori Morimoto
some functions had parameter like below xxx(..., rtd, ..., id); This "id" is rtd->id. We don't need to have "id" on each functions because we can get it from "rtd". Let's cleanup it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87plnqb84p.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-11-01ASoC: remove rtd->numKuninori Morimoto
No one is using rtd->num. Let's remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87sesmb852.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-11-01ASoC: rename rtd->num to rtd->idKuninori Morimoto
Current rtd has "num". It sounds/looks like size of rtd or something, but it will be mainly used at snd_pcm_new() as "device index". This naming is confusable. Let's rename it to "id" Some drivers are using rtd->num, so let's keep it so far, and remove it if all user was switched. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87zfmub85z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-10-28ASoC: soc-devres: Remove unused devm_snd_soc_register_daiDr. David Alan Gilbert
The last use of devm_snd_soc_register_dai() was removed by commit fc4cb1e15f0c ("ASoC: topology: Properly unregister DAI on removal") in 2021. Remove it, and the helper it used. Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> Link: https://patch.msgid.link/20241028021226.477909-1-linux@treblig.org Signed-off-by: Mark Brown <broonie@kernel.org>
2024-10-23ASoC: soc-pcm: remove dpcm_xxx flagsKuninori Morimoto
dpcm_xxx flags are no longer needed. Let's remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/875xpm9vh3.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-10-17ASoC: makes snd_soc_set_runtime_hwparams() inlineKuninori Morimoto
snd_soc_set_runtime_hwparams() is now doing very simple things. We can makes it simply inline function, without having EXPORT_SYMBOL_GPL() Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/87cyk0eso0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-09-06ASoC: makes rtd->initialized bit fieldKuninori Morimoto
rtd->initialized is used to know whether soc_init_pcm_runtime() was correctly fined, and used to call snd_soc_link_exit(). We don't need to have it as bool, let's make it bit-field same as other flags. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Cc: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Cc: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://patch.msgid.link/87o752k7gq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-08-22ASoC: soc-pcm: Indicate warning if dpcm_playback/capture were used for ↵Kuninori Morimoto
availability limition I have been wondering why DPCM needs special flag (= dpcm_playback/capture) to use it. Below is the history why it was added to ASoC. (A) In beginning, there was no dpcm_xxx flag on ASoC. It checks channels_min for DPCM, same as current non-DPCM. Let's name it as "validation check" here. if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { if (cpu_dai->driver->playback.channels_min) playback = 1; if (cpu_dai->driver->capture.channels_min) capture = 1; (B) commit 1e9de42f4324 ("ASoC: dpcm: Explicitly set BE DAI link supported stream directions") force to use dpcm_xxx flag on DPCM. According to this commit log, this is because "Some BE dummy DAI doesn't set channels_min for playback/capture". But we don't know which DAI is it, and not know why it can't/don't have channels_min. Let's name it as "no_chan_DAI" here. According to the code and git-log, it is used as DCPM-BE and is CPU DAI. I think the correct solution was set channels_min on "no_chan_DAI" side, not update ASoC framework side. But everything is under smoke today. if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { playback = rtd->dai_link->dpcm_playback; capture = rtd->dai_link->dpcm_capture; (C) commit 9b5db059366a ("ASoC: soc-pcm: dpcm: Only allow playback/capture if supported") checks channels_min (= validation check) again. Because DPCM availability was handled by dpcm_xxx flag at that time, but some Sound Card set it even though it wasn't available. Clearly there's a contradiction here. I think correct solution was update Sound Card side instead of ASoC framework. Sound Card side will be updated to handle this issue later (commit 25612477d20b ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper")) if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { ... playback = rtd->dai_link->dpcm_playback && snd_soc_dai_stream_valid(cpu_dai, ...); capture = rtd->dai_link->dpcm_capture && snd_soc_dai_stream_valid(cpu_dai, ...); This (C) patch should have broken "no_chan_DAI" which doesn't have channels_min, but there was no such report during this 4 years. Possibilities case are as follows - No one is using "no_chan_DAI" - "no_chan_DAI" is no longer exist : was removed ? - "no_chan_DAI" is no longer exist : has channels_min ? Because of these history, this dpcm_xxx is unneeded flag today. But because we have been used it for 10 years since (B), it may have been used differently. For example some DAI available both playback/capture, but it set dpcm_playback flag only, in this case dpcm_xxx flag is used as availability limitation. We can use playback_only flag instead in this case, but it is very difficult to find such DAI today. Let's add grace time to remove dpcm_playback/capture flag. This patch don't use dpcm_xxx flag anymore, and indicates warning to use xxx_only flag if both playback/capture were available but using only one of dpcm_xxx flag, and not using xxx_only flag. Link: https://lore.kernel.org/r/87edaym2cg.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Jerome Brunet <jbrunet@baylibre.com> Link: https://patch.msgid.link/87seuyaahn.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-07-29ASoC: Use __counted_by() annotation for snd_soc_pcm_runtimeTakashi Iwai
The struct snd_soc_pcm_runtime has a flex array of snd_soc_component objects at its end, and the size is kept in num_components field. We can add __counted_by() annotation for compiler's assistance to catch array overflows. A slight additional change is the assignment of rtd->components[]; the array counter has to be incremented at first for avoiding false-positive reports from compilers. Also, the allocation size of snd_soc_pcm_runtime is cleaned up with the standard struct_size() helper, too. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20240726155237.21961-1-tiwai@suse.de Signed-off-by: Mark Brown <broonie@kernel.org>
2024-06-18ASoC: Constify passed data to core functionKrzysztof Kozlowski
Several ASoC functions receive pointers to data which is not modified, e.g. pointers to 'snd_soc_dai', 'snd_soc_pcm_runtime', 'snd_pcm_hw_params' and 'snd_soc_dai_link'. All these pointers can be made as a pointer to const. This makes code safer, serves as clear annotation of function's intentions (no ownership passed to the function, no modifications) and allows putting pointed structures in rodata (if ever applicable). Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://msgid.link/r/20240617-n-asoc-const-auto-selectable-formats-v1-3-8004f346ee38@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
2024-06-18ASoC: Constify of_phandle_args in snd_soc_dai_link_componentKrzysztof Kozlowski
ASoC core code does not modify contents of 'of_phandle_args' in 'struct snd_soc_dai_link_component', so the pointer can be made as a pointer to const. This makes code safer, serves as clear annotation of core's intentions and allows putting pointed structures in rodata (if ever applicable). Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://msgid.link/r/20240617-n-asoc-const-auto-selectable-formats-v1-2-8004f346ee38@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
2024-05-02ASoC: Use inline function for type safety in snd_soc_substream_to_rtd()Krzysztof Kozlowski
A common pattern in sound drivers is getting 'struct snd_soc_pcm_runtime' from 'struct snd_pcm_substream' opaque pointer private_data field with snd_soc_substream_to_rtd(). However 'private_data' appears in several other structures as well, including 'struct snd_compr_stream'. The field might not hold the same type for every structure, although seems the case at least for 'struct snd_compr_stream', so code can easily make a mistake by using macro for wrong structure passed as argument. Switch from macro to inline function, so such mistake will be build-time detectable. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20240501175127.34301-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
2024-04-30ASoC: pcm: Reverse iterate DAIs when shutting them downCezary Rojewski
During startup snd_soc_dai_startup() is launched in ascending order and the exact same thing is done during shutdown procedure. Reverse the order in the latter so that it is symmetric to the former. Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20240426095733.3946951-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-04-23ASoC: soc.h: Don't use "proxy" headersAndy Shevchenko
Update header inclusions to follow IWYU (Include What You Use) principle. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20240422151513.2052167-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-03-26ASoC: core: add SOC_DOUBLE_RANGE_TLV() helper macroLuca Ceresoli
No macro currently allows handling a stereo control that has left and right in the same register and whose minimum register value is not zero. Add one that does that. Note that even though the snd_soc_*_volsw_range() look more appropriate given the _range suffix, they are not suitable because they don't honor the two shift values. The snd_soc_*_volsw() look more generic and are suitable for the task. Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Link: https://msgid.link/r/20240305-rk3308-audio-codec-v4-3-312acdbe628f@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
2024-02-19ASoC: Constify pointer to of_phandle_argsKrzysztof Kozlowski
Constify pointer to of_phandle_args in few function arguments, for code safety and self-documenting code. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://msgid.link/r/20240216145448.224185-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
2024-01-08Merge tag 'asoc-v6.8' of ↵Takashi Iwai
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Updates for v6.8 This is a relatively quiet release, there's a lot of driver specific changes and the usual high level of activity in the SOF core but the one big core change was Mormioto-san's work to support more N:M CPU:CODEC mapping cases. Highlights include: - Enhanced support for N:M CPU:CODEC mappings in the core and in audio-graph-card2. - Support for falling back to older SOF IPC versions where firmware for new versions is not available. - Support for notification of control changes generated by SOF firmware with IPC4. - Device tree support for describing parts of the card which can be active over suspend (for very low power playback or wake word use cases). - ACPI parsing support for the ES83xx driver, reducing the number of quirks neede for x86 systems. - Support for more AMD and Intel systems, NXP i.MX8m MICFIL, Qualcomm SM8250, SM8550, SM8650 and X1E80100. - Removal of Freescale MPC8610 support, the SoC is no longer supported by Linux.
2023-12-19ASoC: soc.h: don't create dummy Component via COMP_DUMMY()Kuninori Morimoto
Many ASoC drivers define CPU/Codec/Platform dai_link by below macro. SND_SOC_DAILINK_DEFS(link, (A) DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai")), (B) DAILINK_COMP_ARRAY(COMP_CODEC("codec", "dai1"), (B) COMP_CODEC("codec", "dai2")), (C) DAILINK_COMP_ARRAY(COMP_EMPTY())); In this case, this macro will be converted to like below [o] = static struct snd_soc_dai_link_component (A) [o] link_cpus[] = {{ .dai_name = "cpu_dai" }}; (B) [o] link_codecs[] = {{ .dai_name = "dai1", .name = "codec" }, { .dai_name = "dai2", .name = "codec" }} (C) [o] link_platforms[] = {{ }}; CPU and Codec info will be filled by COMP_CPU() / COMP_CODEC (= A,B), and Platform will have empty data by COMP_EMPTY() (= C) in this case. Platform empty info will be filled when driver probe() (most of case, CPU info will be copied to use soc-generic-dmaengine-pcm). For example in case of DPCM FE/BE, it will be like below. Codec will be dummy Component / DAI in this case (X). SND_SOC_DAILINK_DEFS(link, DAILINK_COMP_ARRAY(COMP_CPU(...)), (X) DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); (X) part will converted like below [o] link_codecs[] = {{ .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }} Even though we already have common asoc_dummy_dlc for dummy Component / DAI, this macro will re-create new dummy dlc. Some drivers defines many dai_link info via SND_SOC_DAILINK_DEFS(), this means many dummy dlc also will be re-created. This is waste of memory. If we can use existing common asoc_dummy_dlc at (X), we can avoid to re-creating dummy dlc, then, we can save the memory. At that time, we want to keep existing code as much as possible, because too many drivers are using this macro. But because of its original style, using common asoc_dummy_dlc from it is very difficult or impossible. So let's change the mind. The macro is used like below SND_SOC_DAILINK_DEFS(link, DAILINK_COMP_ARRAY(COMP_CPU(...)), (x) DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); static struct snd_soc_dai_link dai_links[] = { { .name = ..., .stream_name = ..., (y) SND_SOC_DAILINK_REG(link), }, (y) part will be like below static struct snd_soc_dai_link dai_links[] = { { .name = ..., .stream_name = ..., ^ ... | .codecs = link_codecs, (y) .num_codecs = ARRAY_SIZE(link_codecs), v ... } This patch try to use trick on COMP_DUMMY() - #define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } + #define COMP_DUMMY() By this tric, (x) part will be like below. before [o] link_codecs[] = {{ .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }} after [o] link_codecs[] = { }; This is same as below [o] link_codecs[0]; This means it has pointer (link_codecs), but the array size is 0. (y) part will be like below. static struct snd_soc_dai_link dai_links[] = { { ... .codecs = link_codecs, .num_codecs = 0, ... }, This is very special settings that normal use usually not do, but new macro do. We can find this special settings on soc-core.c and fill it as "dummy DAI" (= asoc_dummy_dlc). By this tric, we can avoid to re-create dummy dlc and save the memory. This patch add tric at COMP_DUMMY() and add snd_soc_fill_dummy_dai() to fill dummy DAI. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://msgid.link/r/871qbi93qu.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-11-27ASoC: pcm: Honor subformat when configuring runtimeCezary Rojewski
Subformat options are ignored when setting up hardware parameters and assigning PCM stream capabilities. Account for them to allow for granular format selection. As there is only one user currently (format S32_LE), subformat is represented by a simple u32 and stores flags only for that one user alone. Such approach allows for alloc/free-less code until there are more users on the horizon. Acked-by: Mark Brown <broonie@kernel.org> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Acked-by: Jaroslav Kysela <perex@perex.cz> Link: https://lore.kernel.org/r/20231117120610.1755254-4-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-11-27ASoC: makes CPU/Codec channel connection map more genericKuninori Morimoto
Current ASoC CPU:Codec = N:M connection is using connection mapping idea, but it is used for N < M case only. We want to use it for any case. By this patch, not only N:M connection, but all existing connection (1:1, 1:N, N:N) will use same connection mapping. Then, because it will use default mapping, no conversion patch is needed to exising drivers. More over, CPU:Codec = N:M (N > M) also supported in the same time. ch_maps array will has CPU/Codec index by this patch. Image CPU0 <---> Codec0 CPU1 <-+-> Codec1 CPU2 <-/ ch_map ch_map[0].cpu = 0 ch_map[0].codec = 0 ch_map[1].cpu = 1 ch_map[1].codec = 1 ch_map[2].cpu = 2 ch_map[2].codec = 1 Link: https://lore.kernel.org/r/87fs6wuszr.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/878r7yqeo4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Tested-by: Jerome Brunet <jbrunet@baylibre.com> Link: https://lore.kernel.org/r/87ttpq4f2c.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-10-10ASoC: Merge fixes for consistent cs42l43 schemaMark Brown
We have adjacent changes for the cs42l43 DT schema, merge the fixes branch up so that there's a single thing for people to base future changes on.
2023-09-29ASoC: core: Do not call link_exit() on uninitialized rtd objectsAmadeusz Sławiński
On init we have sequence: for_each_card_prelinks(card, i, dai_link) { ret = snd_soc_add_pcm_runtime(card, dai_link); ret = init_some_other_things(...); if (ret) goto probe_end: for_each_card_rtds(card, rtd) { ret = soc_init_pcm_runtime(card, rtd); probe_end: while on exit: for_each_card_rtds(card, rtd) snd_soc_link_exit(rtd); If init_some_other_things() step fails due to error we end up with not fully setup rtds and try to call snd_soc_link_exit on them, which depending on contents on .link_exit handler, can end up dereferencing NULL pointer. Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com> Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Link: https://lore.kernel.org/r/20230929103243.705433-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-26ASoC: remove asoc_xxx() compatible macroKuninori Morimoto
No driver is using asoc_xxx() any more. This patch removes compatible macro for asoc_xxx(). Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/878r8tfo06.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-25ASoC: soc.h: convert asoc_xxx() to snd_soc_xxx()Kuninori Morimoto
ASoC is using 2 type of prefix (asoc_xxx() vs snd_soc_xxx()), but there is no particular reason about that [1]. To reduce confusing, standarding these to snd_soc_xxx() is sensible. This patch adds asoc_xxx() macro to keep compatible for a while. It will be removed if all drivers were switched to new style. Link: https://lore.kernel.org/r/87h6td3hus.wl-kuninori.morimoto.gx@renesas.com [1] Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87fs3ks26i.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-12ASoC: soc-card: Add storage for PCI SSIDRichard Fitzgerald
Add members to struct snd_soc_card to store the PCI subsystem ID (SSID) of the soundcard. The PCI specification provides two registers to store a vendor-specific SSID that can be read by drivers to uniquely identify a particular "soundcard". This is defined in the PCI specification to distinguish products that use the same silicon (and therefore have the same silicon ID) so that product-specific differences can be applied. PCI only defines 0xFFFF as an invalid value. 0x0000 is not defined as invalid. So the usual pattern of zero-filling the struct and then assuming a zero value unset will not work. A flag is included to indicate when the SSID information has been filled in. Unlike DMI information, which has a free-format entirely up to the vendor, the PCI SSID has a strictly defined format and a registry of vendor IDs. It is usual in Windows drivers that the SSID is used as the sole identifier of the specific end-product and the Windows driver contains tables mapping that to information about the hardware setup, rather than using ACPI properties. This SSID is important information for ASoC components that need to apply hardware-specific configuration on PCI-based systems. As the SSID is a generic part of the PCI specification and is treated as identifying the "soundcard", it is reasonable to include this information in struct snd_soc_card, instead of components inventing their own custom ways to pass this information around. Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20230912163207.3498161-2-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-11ASoC: soc.h: replace custom COUNT_ARGS() & CONCATENATE() implementationsAndy Shevchenko
Replace custom implementation of the macros from args.h. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/20230904111524.1740930-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17ASoC: soc-core.c: add snd_soc_copy_dai_args()Kuninori Morimoto
To use multi Component support, we need to check dai_args whether Card could get DAI from args (CPU/Codec needs set dai_args on DAI driver). If it could, we need to allocate dai_args for dlc. This patch adds snd_soc_copy_dai_args() for it. This is helper function for multi Component support. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87bkgko94e.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17ASoC: soc-core.c: add snd_soc_dlc_use_cpu_as_platform()Kuninori Morimoto
Current snd_soc_is_matching_component() checks "of_node" or "dai_args". Thus coping "of_node" only is not enough to use CPU as Platform. This patch adds snd_soc_dlc_use_cpu_as_platform() and help it. This is helper function for multi Component support. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87cz10o94k.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17ASoC: soc-core.c: add snd_soc_get_dai_via_args()Kuninori Morimoto
To enable multi Component, Card driver need to get DAI via dai_args to identify it. This patch adds snd_soc_get_dai_via_args() for it. This is helper function for multi Component support. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87edlgo94p.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17ASoC: soc-core.c: enable multi ComponentKuninori Morimoto
Current ASoC Card is using dlc (snd_soc_dai_link_component) to find target DAI / Component to be used. Current dlc has below 3 items to identify DAI / Component (a) name for Component (b) of_node for Component (c) dai_name for DAI (a) or (b) is used to identify target Component, and (c) is used to identify DAI. One of the biggest issue on it today is dlc needs "name matching" for "dai_name" (c). It was not a big deal when we were using platform_device, because we could specify nessesary "dai_name" via its platform_data. But we need to find DAI name pointer from whole registered datas and/or each related driver somehow in case of DT, because we can't specify it. Therefore, Card driver parses DT and assumes the DAI, and find its name pointer. How to assume is based on each Component and/or Card. Next biggest issue is Component node (a)/(b). Basically, Component is registered when CPU/Codec driver was probed() (X). Here, 1 Component is possible to have some DAIs. int xxx_probe(struct platform_device *pdev) { ... (X) ret = devm_snd_soc_register_component(pdev->dev, &component_driver, &dai_driver, dai_driver_num); ... } The image of each data will be like below. One note here is "driver" is included for later explanation. +-driver------+ |+-component-+| || dai0|| || dai1|| || ...|| |+-----------+| +-------------+ The point here is 1 driver has 1 Component, because basically driver calles snd_soc_register_component() (= X) once. Here is the very basic CPU/Codec connection image. HW image SW image +-- Board ------------+ +-card--------------------------+ |+-----+ +------+| |+-driver------+ +-driver------+| || CPU | <--> |CodecA|| ||+-component-+| |+-component-+|| |+-----+ +------+| ||| dai|<=>|dai ||| +---------------------+ ||+-----------+| |+-----------+|| |+-------------+ +-------------+| +-------------------------------+ It will be very complex if it has multi DAIs. Here is intuitive easy to understandable HW / SW example. HW image SW image +-- Board ---------------+ +-card--------------------------+ |+--------+ +------+| |+-driver------+ +-driver------+| || CPU ch0| <--> |CodecA|| ||+-component-+| |+-component-+|| || | +------+| ||| ch0 dai|<=>|dai ||| || | +------+| ||| || |+-----------+|| || ch1| <--> |CodecB|| ||| || +-------------+| |+--------+ +------+| ||| || +-driver------+| +------------------------+ ||| || |+-component-+|| ||| ch1 dai|<=>|dai ||| ||+-----------+| |+-----------+|| |+-------------+ +-------------+| +-------------------------------+ It will be handled as multi interface as "one Card". card0,0: CPU-ch0 - CodecA card0,1: CPU-ch1 - CodecB ^ But, here is the HW image example which will be more complex +-- Basic Board ---------+ |+--------+ +------+| || CPU ch0| <--> |CodecA|| || ch1| <-+ +------+| |+--------+ | | +-------------|----------+ +-- expansion board -----+ | | +------+| | +->|CodecB|| | +------+| +------------------------+ We intuitively think we want to handle these as "2 Sound Cards". card0,0: CPU-ch0 - CodecA card1,0: CPU-ch1 - CodecB ^ But below image which we can register today doesn't allow it, because the same Component will be connected to both Card0/1, but it will be rejected by (Z). +-driver------+ |+-component-+| +-card0-------------------------+ ||| || +-driver------+| ||| || |+-component-+|| ||| ch0 dai|<=>|dai ||| ||| || |+-----------+|| ||| || +-------------+| +-------------------------------+ || || +-card1-------------------------+ ||| || +-driver------+| ||| || |+-component-+|| ||| ch1 dai|<=>|dai ||| ||| || |+-----------+|| ||| || +-------------+| +-------------------------------+ |+-----------+| +-------------+ static int soc_probe_component() { ... if (component->card) { (Z) if (component->card != card) { dev_err(component->dev, ...); return -ENODEV; } return 0; } ... } So, how about to call snd_soc_register_component() (= X) multiple times on probe() to avoid buplicated component->card limitation, to be like below ? +-driver------+ +-card0-------------------------+ || | +-driver------+| ||+-component-+| |+-component-+|| ||| ch0 dai|<=>|dai ||| ||+-----------+| |+-----------+|| || | +-------------+| +-------------------------------+ | | +-card1-------------------------+ || | +-driver------+| ||+-component-+| |+-component-+|| ||| ch1 dai|<=>|dai ||| ||+-----------+| |+-----------+|| || | +-------------+| +-------------------------------+ +-------------+ Yes, looks good. But unfortunately it doesn't help us for now. Let's see soc_component_to_node() and snd_soc_is_matching_component() static struct device_node *soc_component_to_node(struct snd_soc_component *component) { ... (A) of_node = component->dev->of_node; ... } static int snd_soc_is_matching_component(...) { ... (B) if (dlc->of_node && component_of_node != dlc->of_node) ... } dlc checkes "of_node" to identify target component (B), but this "of_node" came from component->dev (A) which is added by snd_soc_register_component() (X) on probe(). This means we can have different "component->card", but have same "component->dev" in this case. Even though we calls snd_soc_register_component() (= X) multiple times, all Components have same driver's dev, thus it is impossible to identified the Component. And if it was impossible to identify Component, it is impossible to identify DAI on current implementation. So, how to handle above complex HW image today is 2 patterns. One is handles it as "1 big sound card". The SW image is like below. SW image +-card--------------------------+ |+-driver------+ +-driver------+| ||+-component-+| |+-component-+|| ||| ch0 dai|<=>|dai ||| ||| || |+-----------+|| ||| || +-------------+| ||| || +-driver------+| ||| || |+-component-+|| ||| ch1 dai|<->|dai ||| ||+-----------+| |+-----------+|| |+-------------+ +-------------+| +-------------------------------+ But the problem is not intuitive. We want to handle it as "2 Cards". 2nd pattern is like below. SW image +-card0-------------------------+ |+-driver------+ +-driver------+| ||+-component-+| |+-component-+|| ||| ch0 dai|<=>|dai ||| ||+-----------+| |+-----------+|| |+-------------+ +-------------+| +-------------------------------+ +-card1-------------------------+ |+-driver------+ +-driver------+| ||+-component-+| |+-component-+|| ||| ch1 dai|<=>|dai ||| ||+-----------+| |+-----------+|| |+-------------+ +-------------+| +-------------------------------+ It handles as "2 Cards", but CPU part needs to be probed as 2 drivers. It is also not intuitive. To solve this issue, we need to have multi Component support. In current implementation, we need to identify Component first to identify DAI, and it is using name matching to identify DAI. But how about to be enable to directly identify DAI by unique way instead of name matching ? In such case, we can directly identify DAI, then it can identify Component from DAI. For example Simple-Card / Audio-Graph-Card case, it is specifying DAI via its node. Simple-Card sound-dai = <&cpu-sound>; Audio-Graph-Card dais = <&cpu-sound>; If each CPU/Codec driver keeps this property when probing, we can identify DAI directly from Card. Being able to identify DAI directly means being able to identify its Component as well even though Component has same dev (= B). This patch adds new "dai_node" for it. To keeping compatibility, it checks "dai_node" first if it has, otherwise, use existing method (name matching). Link: https://lore.kernel.org/r/87fskz5yrr.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87fs5wo94v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>