Age | Commit message (Collapse) | Author |
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Merge the for-6.14 to resolve conflicts with simple-card-utils.c due to
parallel delveopment.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|