commit e8444560b4d9302a511f0996f4cfdf85b628f4ca upstream.
The HDAudio ASoC support relies on the set_tdm_slots() helper to store
the HDaudio stream tag in the tx_mask. This only works because of the
pre-existing order in soc-pcm.c, where the hw_params() is handled for
codec_dais *before* cpu_dais. When the order is reversed, the
stream_tag is used as a mask in the codec fixup functions:
/* fixup params based on TDM slot masks */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
codec_dai->tx_mask)
soc_pcm_codec_params_fixup(&codec_params,
codec_dai->tx_mask);
As a result of this confusion, the codec_params_fixup() ends-up
generating bad channel masks, depending on what stream_tag was
allocated.
We could add a flag to state that the tx_mask is really not a mask,
but it would be quite ugly to persist in overloading concepts.
Instead, this patch suggests a more generic get/set 'stream' API based
on the existing model for SoundWire. We can expand the concept to
store 'stream' opaque information that is specific to different DAI
types. In the case of HDAudio DAIs, we only need to store a stream tag
as an unsigned char pointer. The TDM rx_ and tx_masks should really
only be used to store masks.
Rename get_sdw_stream/set_sdw_stream callbacks and helpers as
get_stream/set_stream. No functionality change beyond the rename.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Acked-By: Vinod Koul <vkoul@kernel.org>
Link: https://lore.kernel.org/r/20211224021034.26635-5-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
soc_pcm_open() does rollback when failed (A),
but, it is almost same as soc_pcm_close().
static int soc_pcm_open(xxx)
{
...
if (ret < 0)
goto xxx_err;
...
return 0;
^ config_err:
| ...
| rtd_startup_err:
(A) ...
| component_err:
| ...
v return ret;
}
The difference is
soc_pcm_close() is for all dai/component/substream,
rollback is for succeeded part only.
This kind of duplicated code can be a hotbed of bugs,
thus, we want to share soc_pcm_close() and rollback.
Now, soc_pcm_open/close() are handling
=> 1) snd_soc_dai_startup/shutdown()
2) snd_soc_link_startup/shutdown()
3) snd_soc_component_module_get/put()
4) snd_soc_component_open/close()
5) pm_runtime_put/get()
This patch is for 1) snd_soc_dai_startup/shutdown().
The idea of having bit-flag or counter is not enough for this purpose.
For example if one DAI is used for 2xPlaybacks for some reasons,
and if 1st Playback was succeeded but 2nd Playback was failed,
2nd Playback rollback doesn't need to call shutdown.
But it has succeeded bit-flag or counter via 1st Playback,
thus, 2nd Playback rollback will call unneeded shutdown.
And 1st Playback's necessary shutdown will not be called,
because bit-flag or counter was cleared by wrong 2nd Playback rollback.
To avoid such case, this patch marks substream pointer when startup() was
succeeded. If rollback needed, it will check rollback flag and marked
substream pointer.
One note here is that it cares *current* startup() only now.
but we might want to check *whole* marked substream in the future.
This patch is using macro named "push/pop", so that it can be easily
update.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87lfgubwoc.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
snd_soc_dai_digital_mute() is internally using both
mute_stream() (1) or digital_mute() (2), but the difference between
these 2 are only handling "direction".
We can merge digital_mute() into mute_stream
int snd_soc_dai_digital_mute(xxx, int direction)
{
...
else if (dai->driver->ops->mute_stream)
(1) return dai->driver->ops->mute_stream(xxx, direction);
else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
dai->driver->ops->digital_mute)
(2) return dai->driver->ops->digital_mute(xxx);
...
}
To prepare merging mute_stream()/digital_mute(),
this patch adds .no_capture_mute support to emulate .digital_mute().
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87eeplxxj7.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Current snd_soc_dai_action() is updating
dai->stream_active for Playback/Capture (A),
dai->active for DAI (B)
void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action)
{
(A) dai->stream_active[stream] += action;
(B) dai->active += action;
dai->component->active += action;
}
But, these are very verbose, because we can calculate
DAI active from stream_active.
This patch adds snd_soc_dai_active() which calculate
DAI active from DAI stream_active.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/877dxe6n4i.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
On Baytrail/Cherrytrail, the Atom/SST driver fails miserably:
[ 9.741953] intel_sst_acpi 80860F28:00: FW Version 01.0c.00.01
[ 9.832992] intel_sst_acpi 80860F28:00: FW sent error response 0x40034
[ 9.833019] intel_sst_acpi 80860F28:00: FW alloc failed ret -4
[ 9.833028] intel_sst_acpi 80860F28:00: sst_get_stream returned err -5
[ 9.833033] sst-mfld-platform sst-mfld-platform: ASoC: DAI prepare error: -5
[ 9.833037] Baytrail Audio Port: ASoC: prepare FE Baytrail Audio Port failed
[ 9.853942] intel_sst_acpi 80860F28:00: FW sent error response 0x40034
[ 9.853974] intel_sst_acpi 80860F28:00: FW alloc failed ret -4
[ 9.853984] intel_sst_acpi 80860F28:00: sst_get_stream returned err -5
[ 9.853990] sst-mfld-platform sst-mfld-platform: ASoC: DAI prepare error: -5
[ 9.853994] Baytrail Audio Port: ASoC: prepare FE Baytrail Audio Port failed
Commit b56be800f1 ("ASoC: soc-pcm: call
snd_soc_dai_startup()/shutdown() once") was the initial problematic
commit.
Commit 1ba616bd1a ("ASoC: soc-dai: fix DAI startup/shutdown sequence")
was an attempt to fix things but it does not work on Baytrail,
reverting all changes seems necessary for now.
Fixes: 1ba616bd1a ("ASoC: soc-dai: fix DAI startup/shutdown sequence")
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200415030437.23803-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
DAI driver has playback/capture stream.
OTOH, we have SNDRV_PCM_STREAM_PLAYBACK/CAPTURE.
Because of this kind of implementation,
ALSA SoC needs to have many verbose code.
To solve this issue, this patch adds snd_soc_dai_get_pcm_stream() macro
to get playback/capture stream pointer from stream.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ftf7jcab.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Current soc_pcm_open() calls snd_soc_dai_startup() under loop.
Thus, it needs to care about started/not-yet-started codec DAI.
But, if soc-dai.c is handling it, soc-pcm.c don't need to care
about it.
This patch adds started flag to soc-dai.h, and simplify soc-pcm.c.
This is one of prepare for cleanup soc-pcm-open()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/875zgfcey5.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Historically, CPU and Codec were implemented different, but now it is
merged as Component.
ALSA SoC is supporting suspend/resume at DAI and Component level.
The method is like below.
1) Suspend/Resume all CPU DAI if bus-control was 0
2) Suspend/Resume all Component
3) Suspend/Resume all CPU DAI if bus-control was 1
Historically 2) was Codec special operation.
Because CPU and Codec were merged into Component,
CPU suspend/resume has 3 chance to suspend(= 1/2/3), but
Codec suspend/resume has 1 chance (= 2).
Here, DAI side suspend/resume is caring bus-control, but no driver
which is supporting suspend/resume is setting bus-control.
This means 3) was never used.
Here, used parameter for suspend/resume component->dev and dai->dev are
same pointer.
For that reason, we can merge DAI and Component suspend/resume.
One note is that we should use 2), because it is caring BIAS level.
This patch removes 1) and 3).
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1zvx7i8.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>