Commit Graph

521 Commits

Author SHA1 Message Date
Kuninori Morimoto
25106550f1
ASoC: soc-dpcm.h: remove snd_soc_dpcm::hw_param
Current soc-pcm.c is coping fe hw_param to dpcm->hw_param (A),
fixup it (B), and copy it to be (C).

	int dpcm_be_dai_hw_params(...)
	{
		...
		for_each_dpcm_be(fe, stream, dpcm) {
			...
			/* copy params for each dpcm */
(A)			memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params, ...) ;

			/* perform any hw_params fixups */
(B)			ret = snd_soc_link_be_hw_params_fixup(be, &dpcm->hw_params);
			...

			/* copy the fixed-up hw params for BE dai */
(C)			memcpy(&be->dpcm[stream].hw_params, &dpcm->hw_params, ...);
			...
		}
		...
	}

But here, (1) it is coping hw_params without caring stream (Playback/Capture),
(2) we can get same value from be. We don't need to have dpcm->hw_params.
This patch removes it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Link: https://lore.kernel.org/r/87v8ogsl6h.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-19 13:05:34 +01:00
Kuninori Morimoto
3989ade2d1
ASoC: soc.h: remove num_cpus/codecs
Current rtd has both dai_link pointer (A) and num_cpus/codecs (B).

(A)	rtd->dai_link	= dai_link;
(B)	rtd->num_cpus	= dai_link->num_cpus;
(B)	rtd->num_codecs	= dai_link->num_codecs;

But, we can get num_cpus/codecs (B) via dai_link (A).
This means we don't need to keep num_cpus/codecs on rtd.
This patch removes these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sfkmv9n3.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-20 12:19:30 +01:00
Kuninori Morimoto
6932b20d4f
ASoC: soc-pcm.c: check fe condition at out of loop
Current dpcm_add_paths() is checking fe condition in loop (= A),
but fe condition (X) is not related to the loop (B).

(X)	static int dpcm_add_paths(fe, stream, ...)
	{
		...
(B)		for_each_dapm_widgets(list, i, widget) {
			...
(A)			if (!fe->dpcm[stream].runtime && !fe->fe_compr)
				continue;
			...
		}
		...
	}

This patch checks fe condition at out of loop

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pmgi4dz4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:07 +01:00
Kuninori Morimoto
041107289c
ASoC: soc-pcm.c: add soc_pcm_ret()
Current soc-pcm.c has many similar code for error case.
This patch adds soc_pcm_ret() and share the code and error message.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r10y4dzb.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:06 +01:00
Kuninori Morimoto
10d5d8cbf6
ASoC: soc-pcm.c: remove unnecessary codec2codec_close_delayed_work()
commit 4bf2e385aa ("ASoC: core: Init pcm runtime work early to
avoid warnings") has added generic close_delayed_work() which checks
close_delayed_work_func

	static void close_delayed_work(...) {
		...
=>		if (rtd->close_delayed_work_func)
			rtd->close_delayed_work_func(rtd);
	}

So, we don't need to have NULL function for Codec2Codec.

=>	static void codec2codec_close_delayed_work()
	{
		/*
		 * Currently nothing to do for c2c links
		 * Since c2c links are internal nodes in the DAPM graph and
		 * don't interface with the outside world or application layer
		 * we don't have to do any special handling on close.
		 */
	}

	int soc_new_pcm(...)
	{
		...
		if (rtd->dai_link->params)
=>			rtd->close_delayed_work_func = codec2codec_close_delayed_work;
		else
			rtd->close_delayed_work_func = snd_soc_close_delayed_work;
		...
	}

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sfle4dzk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:05 +01:00
Kuninori Morimoto
6bbabd2880
ASoC: soc-pcm.c: call __soc_pcm_close() in soc_pcm_close()
commit b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
added __soc_pcm_close() for non-lock version of soc_pcm_close().
But soc_pcm_close() is not using it. It is no problem, but confusable.

	static int __soc_pcm_close(...)
	{
=>		return soc_pcm_clean(rtd, substream, 0);
	}

	static int soc_pcm_close(...)
	{
		...
		snd_soc_dpcm_mutex_lock(rtd);
=>		soc_pcm_clean(rtd, substream, 0);
		snd_soc_dpcm_mutex_unlock(rtd);
		return 0;
	}

This patch use it.

Fixes: b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87czctgg3w.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-25 17:58:30 +01:00
Kuninori Morimoto
4d45d944e8
ASoC: soc-pcm.c: summarize related settings at soc_new_pcm()
soc_new_pcm() sets pcm->no_device_suspend, but it sets other pcm->xxx
at the same function with different timing.
pcm->no_device_suspend setup timing has no effect. This patch tidyup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87bksdgflq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-22 14:07:21 +01:00
Takashi Iwai
754590651c
ASoC: DPCM: Don't pick up BE without substream
When DPCM tries to add valid BE connections at dpcm_add_paths(), it
doesn't check whether the picked BE actually supports for the given
stream direction.  Due to that, when an asymmetric BE stream is
present, it picks up wrongly and this may result in a NULL dereference
at a later point where the code assumes the existence of a
corresponding BE substream.

This patch adds the check for the presence of the substream for the
target BE for avoiding the problem above.

Note that we have already some fix for non-existing BE substream at
commit 6246f283d5 ("ASoC: dpcm: skip missing substream while
applying symmetry").  But the code path we've hit recently is rather
happening before the previous fix.  So this patch tries to fix at
picking up a BE instead of parsing BE lists.

Fixes: bbf7d3b1c4 ("ASoC: soc-pcm: align BE 'atomicity' with that of the FE")
Reported-by: Alex Natalsson <harmoniesworlds@gmail.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/CADs9LoPZH_D+eJ9qjTxSLE5jGyhKsjMN7g2NighZ16biVxsyKw@mail.gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220801170510.26582-1-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-05 14:20:51 +01:00
Pierre-Louis Bossart
4ccf0949cd
ASoC: soc-pcm: demote warnings on non-atomic BE connection
When an FE, typically non-atomic, is connected to an atomic BE, we
force the BE as non-atomic. There's no reason to throw a warning, this
is a perfectly fine configuration and a conversion that's required
by-design.

This removes the unconditional warnings such as

[   12.054213]  iDisp1: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.074693]  iDisp2: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.096612]  iDisp3: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.118637]  iDisp4: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.140660]  dmic01: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.147521]  dmic16k: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic

and demotes them to dev_dbg(), as suggested in review comments.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220708200641.26923-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-07-12 13:45:07 +01:00
Pierre-Louis Bossart
f4d6aca0c8
ASoC: soc-pcm: fix BE transition for TRIGGER_START
A obvious editing mistake caught with a cppcheck warning

sound/soc/soc-pcm.c:2132:8: style: Variable 'ret' is reassigned a
value before the old one has been used. [redundantAssignment]
   ret = soc_pcm_trigger(be_substream, cmd);
       ^
sound/soc/soc-pcm.c:2126:9: note: ret is assigned
    ret = soc_pcm_trigger(be_substream,
        ^
sound/soc/soc-pcm.c:2129:9: note: ret is assigned
    ret = soc_pcm_trigger(be_substream,
        ^

Fixes: 374b50e234 ('ASoC: soc-pcm: improve BE transition for TRIGGER_START')
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20220520210615.607229-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-05-23 14:52:59 +01:00
Pierre-Louis Bossart
374b50e234
ASoC: soc-pcm: improve BE transition for TRIGGER_START
When the BE was in PAUSED state, the correct trigger is PAUSE_RELEASE.

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@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220406190056.233481-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-19 16:33:52 +01:00
Pierre-Louis Bossart
9995c1d096
ASoC: soc-pcm: improve BE transition for PAUSE_RELEASE
Commit 3aa1e96a2b ("ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE")
did not modify the existing logic and kept the same logic for the following
transition

    play FE1    -> BE state is START
    pause FE1   -> BE state is PAUSED
    play FE2    -> BE state is START
    stop FE2    -> BE state is STOP <<< !!
    release FE1 -> BE state is START
    stop FE1    -> BE state is STOP

At the time it was identified by reviewers that a better solution
might consist in

    play FE1    -> BE state is START
    pause FE1   -> BE state is PAUSED
    play FE2    -> BE state is START
    stop FE2    -> BE state is PAUSE <<< !!
    release FE1 -> BE state is START
    stop FE1    -> BE state is STOP

This patch suggest a transition to PAUSE when all the 'active' streams
are paused. This would allow for a more consistent resource management
for platforms where PAUSE and STOP are handled differently.

To track the special case of an FE going from PAUSE_PUSH to STOP, we
add a state variable for each FE context. This 'fe_pause' boolean is
set on PAUSE_PUSH and cleared on either PAUSE_RELEASE and STOP
triggers.

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@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220406190056.233481-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-19 16:33:51 +01:00
Christophe JAILLET
fb6d679fee
ASoC: soc-pcm: use GFP_KERNEL when the code is sleepable
At the kzalloc() call in dpcm_be_connect(), there is no spin lock involved.
It's merely protected by card->pcm_mutex, instead.  The spinlock is applied
at the later call with snd_soc_pcm_stream_lock_irq() only for the list
manipulations.  (See it's *_irq(), not *_irqsave(); that means the context
being sleepable at that point.)  So, we can use GFP_KERNEL safely there.

This patch revert commit d8a9c6e1f6 ("ASoC: soc-pcm: use GFP_ATOMIC for
dpcm structure") which is no longer needed since commit b7898396f4
("ASoC: soc-pcm: Fix and cleanup DPCM locking").

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/e740f1930843060e025e3c0f17ec1393cfdafb26.1648757961.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-04 14:25:39 +01:00
Takashi Iwai
9f620684c1
ASoC: soc-pcm: Move debugfs removal out of spinlock
The recent fix for DPCM locking also covered the loop in
dpcm_be_disconnect() with the FE stream lock.  This caused an
unexpected side effect, thought: calling debugfs_remove_recursive() in
the spinlock may lead to lockdep splats as the code there assumes the
SOFTIRQ-safe context.

For avoiding the problem, this patch changes the disconnection
procedure to two phases: at first, the matching entries are removed
from the linked list, then the resources are freed outside the lock.

Fixes: b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
Reported-and-tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220119155249.26754-3-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-01-28 15:59:18 +00:00
Takashi Iwai
3c75c0ea5d
ASoC: soc-pcm: Fix DPCM lockdep warning due to nested stream locks
The recent change for DPCM locking caused spurious lockdep warnings.
Actually the warnings are false-positive, as those are triggered due
to the nested stream locks for FE and BE.  Since both locks belong to
the same lock class, lockdep sees it as if a deadlock.

For fixing this, we need to take PCM stream locks for BE with the
nested lock primitives.  Since currently snd_pcm_stream_lock*() helper
assumes only the top-level single locking, a new helper function
snd_pcm_stream_lock_irqsave_nested() is defined for a single-depth
nested lock, which is now used in the BE DAI trigger that is always
performed inside a FE stream lock.

Fixes: b2ae806630 ("ASoC: soc-pcm: serialize BE triggers")
Reported-and-tested-by: Hans de Goede <hdegoede@redhat.com>
Reported-and-tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/73018f3c-9769-72ea-0325-b3f8e2381e30@redhat.com
Link: https://lore.kernel.org/alsa-devel/9a0abddd-49e9-872d-2f00-a1697340f786@samsung.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220119155249.26754-2-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-01-28 15:59:16 +00:00
Pierre-Louis Bossart
3aa1e96a2b
ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE
A BE connected to more than one FE, e.g. in a mixer case, can go
through the following transitions.

play FE1    -> BE state is START
pause FE1   -> BE state is PAUSED
play FE2    -> BE state is START
stop FE2    -> BE state is STOP (see note [1] below)
release FE1 -> BE state is START
stop FE1    -> BE state is STOP

play FE1    -> BE state is START
pause FE1   -> BE state is PAUSED
play FE2    -> BE state is START
release FE1 -> BE state is START
stop FE2    -> BE state is START
stop FE1    -> BE state is STOP

play FE1    -> BE state is START
play FE2    -> BE state is START (no change)
pause FE1   -> BE state is START (no change)
pause FE2   -> BE state is PAUSED
release FE1 -> BE state is START
release FE2 -> BE state is START (no change)
stop FE1    -> BE state is START (no change)
stop FE2    -> BE state is STOP

The existing code for PAUSE_RELEASE only allows for the case where the
BE is paused, which clearly would not work in the sequences above.

Extend the allowed states to restart the BE when PAUSE_RELEASE is
received, and increase the refcount if the BE is already in START.

[1] the existing logic does not move the BE state back to PAUSED when
the FE2 is stopped. This patch does not change the logic; it would be
painful to keep a history of changes on the FE side, the state machine
is already rather complicated with transitions based on the last BE
state and the trigger type.

Reported-by: Bard Liao <bard.liao@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-7-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:48 +00:00
Pierre-Louis Bossart
848aedfdc6
ASoC: soc-pcm: test refcount before triggering
On start/pause_release/resume, when more than one FE is connected to
the same BE, it's possible that the trigger is sent more than
once. This is not desirable, we only want to trigger a BE once, which
is straightforward to implement with a refcount.

For stop/pause/suspend, the problem is more complicated: the check
implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a
conceptual deadlock when we trigger the BE before the FE. In this
case, the FE states have not yet changed, so there are corner cases
where the TRIGGER_STOP is never sent - the dual case of start where
multiple triggers might be sent.

This patch suggests an unconditional trigger in all cases, without
checking the FE states, using a refcount protected by the BE PCM
stream lock.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-6-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:47 +00:00
Takashi Iwai
b2ae806630
ASoC: soc-pcm: serialize BE triggers
When more than one FE is connected to a BE, e.g. in a mixing use case,
the BE can be triggered multiple times when the FE are opened/started
concurrently. This race condition is problematic in the case of
SoundWire BE dailinks, and this is not desirable in a general
case.

This patch relies on the existing BE PCM lock, which takes atomicity into
account. The locking model assumes that all interactions start with
the FE, so that there is no deadlock between FE and BE locks.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
[test, checkpatch fix and clarification of commit message by plbossart]
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-5-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:46 +00:00
Takashi Iwai
b7898396f4
ASoC: soc-pcm: Fix and cleanup DPCM locking
The existing locking for DPCM has several issues
a) a confusing mix of card->mutex and card->pcm_mutex.
b) a dpcm_lock spinlock added inconsistently and on paths that could
be recursively taken. The use of irqsave/irqrestore was also overkill.

The suggested model is:

1) The pcm_mutex is the top-most protection of BE links in the FE. The
pcm_mutex is applied always on either the top PCM callbacks or the
external call from DAPM, not taken in the internal functions.

2) the FE stream lock is taken in higher levels before invoking
dpcm_be_dai_trigger()

3) when adding and deleting a BE, both the pcm_mutex and FE stream
lock are taken.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
[clarification of commit message by plbossart]
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-4-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:45 +00:00
Pierre-Louis Bossart
bbf7d3b1c4
ASoC: soc-pcm: align BE 'atomicity' with that of the FE
Since the flow for DPCM is based on taking a lock for the FE first, we
need to make sure during the connection between a BE and an FE that
they both use the same 'atomicity', otherwise we may sleep in atomic
context.

If the FE is nonatomic, this patch forces the BE to be nonatomic as
well. That should have no negative impact since the BE 'inherits' the
FE properties.

However, if the FE is atomic and the BE is not, then the configuration
is flagged as invalid.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
[ removed FE stream lock by tiwai ]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:44 +00:00
Pierre-Louis Bossart
d8a9c6e1f6
ASoC: soc-pcm: use GFP_ATOMIC for dpcm structure
We allocate a structure in dpcm_be_connect(), which may be called in
atomic context. Using GFP_KERNEL is not quite right, we have to use
GFP_ATOMIC to prevent the allocator from sleeping.

Suggested-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:42 +00:00
Kuninori Morimoto
dd894f4caf
ASoC: soc-pcm: tidyup soc_pcm_pointer()'s delay update method
No driver directly updates runtime->delay in .pointer.
This patch cleanups its method.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87zgq4wnkx.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:45 +00:00
Kuninori Morimoto
403f830e7a
ASoC: soc-component: add snd_soc_pcm_component_delay()
Current soc-pcm.c :: soc_pcm_pointer() is assuming that
component driver might update runtime->delay silently in
snd_soc_pcm_component_pointer() (= A).

	static snd_pcm_uframes_t soc_pcm_pointer(...)
	{
		...

		/* clearing the previous total delay */
=>		runtime->delay = 0;

(A)		offset = snd_soc_pcm_component_pointer(substream);

		/* base delay if assigned in pointer callback */
=>		delay = runtime->delay;
		...
	}

1) The behavior that ".pointer callback secretly updates
   runtime->delay" is strange and confusable.

2) Current snd_soc_pcm_component_pointer() uses 1st found component's
   .pointer callback only, thus it is no problem for now.
   But runtime->delay might be overwrote if it adjusted to multiple
   components in the future.

3) Component delay is updated at .pointer callback timing (secretly).
   But some components which doesn't have .pointer callback might want
   to increase runtime->delay for some reasons.

We already have .delay function for DAI, but not have for Component.
This patch adds new snd_soc_pcm_component_delay() for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/874k8cy25t.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:41 +00:00
Kuninori Morimoto
8544f08c81
ASoC: soc-dai: update snd_soc_dai_delay() to snd_soc_pcm_dai_delay()
Current soc_pcm_pointer() is manually calculating
both CPU-DAI's   max delay (= A)
and  Codec-DAI's max delay (= B).

	static snd_pcm_uframes_t soc_pcm_pointer(...)
	{
		...
 ^		for_each_rtd_cpu_dais(rtd, i, cpu_dai)
(A)			cpu_delay = max(cpu_delay, ...);
 v		delay += cpu_delay;

 ^		for_each_rtd_codec_dais(rtd, i, codec_dai)
(B)			codec_delay = max(codec_delay, ...);
 v		delay += codec_delay;

		runtime->delay = delay;
		...
	}

Current soc_pcm_pointer() and the total delay calculating
is not readable / difficult to understand.

This patch update snd_soc_dai_delay() to snd_soc_pcm_dai_delay(),
and calcule both CPU/Codec delay in one function.

Link: https://lore.kernel.org/r/87fszl4yrq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/875yssy25z.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:40 +00:00
Kuninori Morimoto
86e4aef6c9
ASoC: soc-pcm: tidyup soc_pcm_hw_clean() - step2
DAI active count is not exchanged during for_each_rtd_dais()
loops. We don't need to keep snd_soc_dai_stream_active() as
"active" on soc_pcm_hw_clean(). This patch avoid verbose code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ilxvt7e6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-18 13:56:36 +01:00
Kuninori Morimoto
121966d03b
ASoC: soc-pcm: tidyup soc_pcm_hw_clean() - step1
soc_pcm_hw_clean() is using "continue" during for_each_rtd_dais(),
but it is very verbose. This patch cleanup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87k0ibt7ej.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-18 13:56:35 +01:00
Pierre-Louis Bossart
9609cfcda0
ASoC: soc-pcm: restore mixer functionality
Recent changes in soc-pcm completely broke basic support for mixers on
Intel systems: the filters on BE states prevent the connection of a
second mixer input while the back-end is already active.

Rather than reverting the changes, which would be problematic for
Tegra systems, this patch suggests an additional filter which will
only apply to Tegra systems. This is a temporary solution which will
have to be revisited - additional issues have been reported with DPCM.

Fixes: 0c25db3f76 ('ASoC: soc-pcm: Don't reconnect an already active BE')
Suggested-by: Sameer Pujar <spujar@nvidia.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20211004212141.193136-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-07 19:20:00 +01:00
Ranjani Sridharan
d1a7af0979
AsoC: dapm: export a couple of functions
Export a couple of DAPM functions that can be used by
ASoC drivers to determine connected widgets when a PCM
is started.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20210927120517.20505-6-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-01 20:48:23 +01:00
Sameer Pujar
0c25db3f76
ASoC: soc-pcm: Don't reconnect an already active BE
In some cases, multiple FE components have the same BE component in their
respective DPCM paths. One such example would be a mixer component, which
can receive two or more inputs and sends a mixed output. In such cases,
to avoid reconfiguration of already active DAI (mixer output DAI in this
case), check the BE stream state to filter out the redundancy.

In summary, allow connection of BE if the respective current stream state
is either NEW or CLOSED.

Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Link: https://lore.kernel.org/r/1631551342-25469-2-git-send-email-spujar@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-09-20 13:31:27 +01:00
Mark Brown
3202e2f5fa
ASoC: Revert PCM trigger changes
These have turned up some issues in further testing.

Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-30 12:15:15 +01:00
Pierre-Louis Bossart
6479f75886
ASoC: soc-pcm: test refcount before triggering
On start/pause_release/resume, when more than one FE is connected to
the same BE, it's possible that the trigger is sent more than
once. This is not desirable, we only want to trigger a BE once, which
is straightforward to implement with a refcount.

For stop/pause/suspend, the problem is more complicated: the check
implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a
conceptual deadlock when we trigger the BE before the FE. In this
case, the FE states have not yet changed, so there are corner cases
where the TRIGGER_STOP is never sent - the dual case of start where
multiple triggers might be sent.

This patch suggests an unconditional trigger in all cases, without
checking the FE states, using a refcount protected by a spinlock.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Message-Id: <20210817164054.250028-3-pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-26 17:42:08 +01:00
Pierre-Louis Bossart
0c75fc7193
ASoC: soc-pcm: protect BE dailink state changes in trigger
When more than one FE is connected to a BE, e.g. in a mixing use case,
the BE can be triggered multiple times when the FE are opened/started
concurrently. This race condition is problematic in the case of
SoundWire BE dailinks, and this is not desirable in a general
case. The code carefully checks when the BE can be stopped or
hw_free'ed, but the trigger code does not use any mutual exclusion.

Fix by using the same spinlock already used to check FE states, and
set the state before the trigger. In case of errors,  the initial
state will be restored.

This patch does not change how the triggers are handled, it only makes
sure the states are handled in critical sections.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Message-Id: <20210817164054.250028-2-pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-26 17:42:07 +01:00
Mark Brown
ddaa1ed52c
Merge some cs42l42 patches into asoc-5.15 2021-08-06 01:46:24 +01:00
Kuninori Morimoto
9bdc573d84
ASoC: soc-pcm: cleanup cppcheck warning at dpcm_runtime_setup_be_chan()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:1624:30: style: The scope of the variable 'codec_stream' can be reduced. [variableScope]
  struct snd_soc_pcm_stream *codec_stream;
                             ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o8aozf28.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:50 +01:00
Kuninori Morimoto
7931df9bf0
ASoC: soc-pcm: cleanup cppcheck warning at dpcm_be_is_active()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:1305:30: style: The scope of the variable 'widget' can be reduced. [variableScope]
 struct snd_soc_dapm_widget *widget;
                             ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pmv4zf2c.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:47 +01:00
Kuninori Morimoto
940a1f4357
ASoC: soc-pcm: cleanup cppcheck warning at soc_get_playback_capture()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:2578:22: style: The scope of the variable 'codec_dai' can be reduced. [variableScope]
 struct snd_soc_dai *codec_dai;
                     ^
sound/soc/soc-pcm.c:2580:6: style: The scope of the variable 'stream' can be reduced. [variableScope]
 int stream;
     ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1fkzf2g.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:46 +01:00
Kuninori Morimoto
33be10b563
ASoC: soc-pcm: cleanup cppcheck warning at soc_pcm_components_close()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:631:9: style: The scope of the variable 'r' can be reduced. [variableScope]
 int i, r, ret = 0;
        ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sg00zf2l.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:45 +01:00
Kuninori Morimoto
2bc3e1f21b
ASoC: soc-pcm: cleanup cppcheck warning at soc_pcm_apply_msb()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:446:29: style: The scope of the variable 'pcm_codec' can be reduced. [variableScope]
 struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
                            ^
sound/soc/soc-pcm.c:446:41: style: The scope of the variable 'pcm_cpu' can be reduced. [variableScope]
 struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
                                        ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tukgzf2p.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:44 +01:00
Vijendar Mukunda
59dd33f82d
ASoC: soc-pcm: add a flag to reverse the stop sequence
On stream stop, currently CPU DAI stop sequence invoked first
followed by DMA. For Few platforms, it is required to stop the
DMA first before stopping CPU DAI.

Introduced new flag in dai_link structure for reordering stop sequence.
Based on flag check, ASoC core will re-order the stop sequence.

Fixes: 4378f1fbe9 ("ASoC: soc-pcm: Use different sequence for start/stop trigger")
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://lore.kernel.org/r/20210716123015.15697-1-vijendar.mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-16 13:54:58 +01:00
Jaroslav Kysela
12ffd72682
ASoC: soc-pcm: fix the return value in dpcm_apply_symmetry()
In case, where the loops are not executed for a reason, the uninitialized
variable 'err' is returned to the caller. Make code fully predictible
and assign zero in the declaration.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Cc: Mark Brown <broonie@kernel.org>
Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/20210614071746.1787072-1-perex@perex.cz
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-06-14 14:59:17 +01:00
Kuninori Morimoto
9c2ae363f3
ASoC: soc-pcm: ignore dummy-DAI at soc_pcm_params_symmetry()
soc_pcm_params_symmetry() checks CPU / Codec symmetry.
Unfortunately there was bug on it (= A) which didn't check Codec.
But is back by (B).

	A: v5.7:  commit c840f7698d ("ASoC: soc-pcm: Merge for_each_rtd_cpu/codec_dais()")
	B: v5.12: commit 3a90672111 ("ASoC: soc-pcm: cleanup soc_pcm_params_symmetry()")

In total,
old - v5.6 (= Generation-1):

	symmetric_rate		: DAI_Link / CPU / Codec
	symmetric_channels	: DAI_Link / CPU / Codec
	symmetric_sample_bits	: DAI_Link / CPU / Codec

v5.7 - v5.11 (= Generation-2): (= because of bug by (A))

	symmetric_rate		: DAI_Link / CPU
	symmetric_channels	: DAI_Link / CPU / Codec
	symmetric_sample_bits	: DAI_Link / CPU / Codec

v5.12 - (= Generation-3): (= back by (B))

	symmetric_rate		: DAI_Link / CPU / Codec
	symmetric_channels	: DAI_Link / CPU / Codec
	symmetric_sample_bits	: DAI_Link / CPU / Codec

OTOH, we can use DPCM which is configured by FE / BE.
Both FE / BE uses dummy-DAI.

	FE: CPU       <-> dummy-DAI
	BE: dummy-DAI <-> Codec

One note is that we can use .be_hw_params_fixup in DPCM case.
This means BE settings might be fixuped/updated by FE.
This feature is used for example on MIXer case.
It can be happen not only for rate, but for channels/sample_bits too.

Because of these reasons, below issue happen on
Generation-1 / Generation-3, if...

	1) Sound Card used DPCM
	2) It exchanges rate to 48kHz by using .be_hw_params_fixup()
	3) Codec had symmetric_rate = 1

I didn't confirm, but maybe same things happen
if it exchanged channels/sample_bits at Generation-1/2/3 too.

	# aplay 44100.wav
	# aplay 44100.wav
=>	[kernel] be.ak4613-hifi: ASoC: unmatched rate symmetry: snd-soc-dummy-dai:44100 - soc_pcm_params_symmetry:48000
	[kernel] be.ak4613-hifi: ASoC: hw_params BE failed -22
	[kernel] fe.rsnd-dai.0: ASoC: hw_params BE failed -22
	aplay: set_params:1407: Unable to install hw params:
	ACCESS:  RW_INTERLEAVED
	FORMAT:  S16_LE
	SUBFORMAT:  STD
	SAMPLE_BITS: 16
	FRAME_BITS: 32
	CHANNELS: 2
	RATE: 44100
	PERIOD_TIME: (23219 23220)
	PERIOD_SIZE: 1024
	PERIOD_BYTES: 4096
	PERIODS: 4
	BUFFER_TIME: (92879 92880)
	BUFFER_SIZE: 4096
	BUFFER_BYTES: 16384
	TICK_TIME: 0

soc_pcm_params_symmetry() checks by below

	if (symmetry)
		for_each_rtd_cpu_dais(rtd, i, cpu_dai)
			if (cpu_dai->xxx && cpu_dai->xxx != d.xxx) {
				dev_err(rtd->dev, "...");
				return -EINVAL;
			}

Because of above reason 3) (= Codec had symmetric_rate = 1)
BE can't ignore "if (symmetric)".

At 1st aplay, soc_pcm_params_symmetry() ignores it,
because dummy-DAI->rate is 0.
After this check, each DAI sets/keep settings.

In above sample case, BE gets 48000 and FE gets 44100,
and it happen BE -> FE order.
Because DPCM is sharing *same* dummy-DAI,
dummy-DAI sets as 48000 by BE, and is overwrote by 44100 by FE.

This settings never be cleaned (= a) after 1st aplay,
because dummy-DAI is used from FE/BE, never be last user (b).

	static int soc_pcm_hw_clean(...)
	{
		...
		for_each_rtd_dais(rtd, i, dai) {
			...
(b)			if (snd_soc_dai_active(dai) == 1)
(a)				soc_pcm_set_dai_params(dai, NULL);
			...
		}
		...
	}

At 2nd aplay, BE gets 48000 but dummy-DAI is keeping 44100,
soc_pcm_params_symmetry() checks will fail.

To solve this issue, this patch ignores dummy-DAI
at soc_pcm_params_symmetry()

Link: https://lore.kernel.org/r/87a6q0z4xt.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87y2djxa2n.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-16 14:34:13 +01:00
Kuninori Morimoto
ee39d77ed9
ASoC: soc-pcm: indicate DAI name if soc_pcm_params_symmetry() failed
It indicates unmatched symmetry value, but not indicates on which DAI.
This patch indicates it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/871rbbyono.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-16 14:34:11 +01:00
Kuninori Morimoto
1cacbac447
ASoC: soc-pcm: don't use "name" on __soc_pcm_params_symmetry() macro
__soc_pcm_params_symmetry() macro is using "name" as parameter
which will be exchanged to rate/channles/sample_bit, like below

	dai->name => dai->rate
	dai->name => dai->channels
	dai->name => dai->sample_bit

But, dai itself has "name". This means

	1) It is very confusable naming
	2) It can't use dai->name

This patch use "xxx" instead of "name"

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/8735vryoob.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-16 14:34:10 +01:00
Shengjiu Wang
8bdfc0455e
ASoC: soc-component: Add snd_soc_pcm_component_ack
Add snd_soc_pcm_component_ack back, which can be used to get an
updated buffer pointer in the platform driver.
On Asymmetric multiprocessor, this pointer can be sent to Cortex-M
core for audio processing.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1615516725-4975-2-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-25 13:58:06 +00:00
Kuninori Morimoto
60adbd8fbf
ASoC: don't indicate error message for snd_soc_[pcm_]component_xxx()
All snd_soc_component_xxx() and snd_soc_pcm_component_xxx() itself
indicate error message if failed.
Its caller doesn't need to indicate duplicated error message.
This patch removes it.

All snd_soc_component_xxx() indicate error message if failed.
Its caller doesn't need to indicate duplicated error message.
This patch removes it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878s6puta6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:05 +00:00
Kuninori Morimoto
62462e0182
ASoC: don't indicate error message for snd_soc_[pcm_]dai_xxx()
All snd_soc_dai_xxx() and snd_soc_pcm_dai_xxx() itself
indicate error message if failed.
Its caller doesn't need to indicate duplicated error message.
This patch removes it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87a6r5utaa.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:04 +00:00
Kuninori Morimoto
f52366e683
ASoC: soc-pcm: don't indicate error message for dpcm_be_dai_hw_free()
dpcm_be_dai_hw_free() never fail, error message is not needed.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87blblutaf.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:03 +00:00
Kuninori Morimoto
e20c9c4f96
ASoC: soc-pcm: don't indicate error message for soc_pcm_hw_free()
soc_pcm_hw_free() never fail, error message is not needed.
We can't use void function for it, because it is used
part of struct snd_pcm_ops :: hw_free.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87czw1utaj.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:02 +00:00
Kuninori Morimoto
273db971cf
ASoC: soc-pcm: indicate error message at dpcm_fe/be_dai_prepare()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at dpcm_fe/be_dai_prepare()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87eeghutap.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:01 +00:00
Kuninori Morimoto
33b6b94f55
ASoC: soc-pcm: indicate error message at dpcm_fe/be_dai_hw_params()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at dpcm_fe/be_dai_hw_params()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ft0xutat.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:24:00 +00:00
Kuninori Morimoto
06aaeb8742
ASoC: soc-pcm: indicate error message at dpcm_fe/be_dai_startup()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at dpcm_fe/be_dai_startup().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87h7ldutay.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:59 +00:00
Kuninori Morimoto
81c82a9edb
ASoC: soc-pcm: indicate error message at dpcm_run_update_startup/shutdown()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch also
do below to dpcm_run_update_startup()
	1) remove duplicated ret = -EINVAL
	2) remove blank line
do below to dpcm_run_update_shutdown()
	1) remove unused ret

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87im5tutb3.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:58 +00:00
Kuninori Morimoto
bbd2bac8d6
ASoC: soc-pcm: indicate error message at dpcm_apply_symmetry()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at dpcm_apply_symmetry(...)

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87k0q9utb9.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:57 +00:00
Kuninori Morimoto
db3aa39c91
ASoC: soc-pcm: indicate error message at dpcm_be_dai_trigger()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

Now, dpcm_be_dai_trigger() user uses it like below.

	err = dpcm_be_dai_trigger(...);
	if (err < 0)
		dev_err(..., "ASoC: trigger FE failed %d\n", err);

But we can get more detail information if dpcm_be_dai_trigger() itself
had dev_err(). And above error message is confusable,
failed is *BE*, not *FE*.

This patch indicates error message at dpcm_be_dai_trigger().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87lfaputbe.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:56 +00:00
Kuninori Morimoto
d479f00b79
ASoC: soc-pcm: indicate error message at dpcm_path_get()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

Now, many place uses dpcm_path_get() like below

	ret = dpcm_path_get(...);
	if (ret < 0)
		goto error;
(A)	else if (ret == 0)
		dev_dbg(...)

But here, (A) part can be indicated at dpcm_path_get() not caller.
It is simple and readable code.

This patch do it.
Small detail behaviors will be exchanged by this patch.

	1) indicates debug info (= path numbers) if path > 0 case only
	   (It was *always* indicated).
	2) soc_dpcm_fe_runtime_update() is indicating error message
	   for paths < 0 case, but it is already done at dpcm_path_get().
	   Thus just remove it. but dev_dbg() vs dev_warn() is exchanged.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87mtv5utbj.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:55 +00:00
Kuninori Morimoto
dab7eeb404
ASoC: soc-pcm: indicate error message at soc_pcm_prepare()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at soc_pcm_prepare().

By this patch, dpcm_fe/be_dai_prepare(...)
temporary lacks FE/BE error info, but it will reborn soon.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o8flutbn.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:54 +00:00
Kuninori Morimoto
cb11f79b4a
ASoC: soc-pcm: indicate error message at soc_pcm_hw_params()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at soc_pcm_hw_params().

By this patch, dpcm_fe/be_dai_hw_params(...)
temporary lacks FE/BE error info, but it will reborn soon.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pn01utbt.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:53 +00:00
Kuninori Morimoto
e4b044f458
ASoC: soc-pcm: indicate error message at soc_pcm_open()
Indicating error message when failed case is very useful for debuging.
In many case, its style is like below.

	int function(...)
	{
		...
		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		if (ret < 0)
			dev_err(...)
		...
	}

This is not so bad, but in this style *each caller* needs to indicate
duplicate same error message, and some caller is forgetting to do it.
And caller can't indicate detail function() error information.

If function() indicates error message, we can get same and
detail information without forgot.

	int function(...)
	{
		...
		if (ret < 0)
			dev_err(...)

		return ret;
	}

	int caller(...)
	{
		...
		ret = function(...);
		...
	}

This patch follow above style at soc_pcm_open().

By this patch, dpcm_fe/be_dai_startup(...)
temporary lacks FE/BE error info, but it will reborn soon.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1khutby.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-19 12:23:52 +00:00
Kuninori Morimoto
531590bb40
ASoC: soc-pcm: share DPCM BE DAI stop operation
soc-pcm has very similar but different DPCM BE DAI stop operation at
	1) dpcm_be_dai_startup() error case rollback
	2) dpcm_be_dai_startup_unwind()
	3) dpcm_be_dai_shutdown()

The differences are
	1) for rollback
	2) Doesn't check by snd_soc_dpcm_be_can_update() (Is this bug ?)
	3) Do soc_pcm_hw_free() if it was not !OPENed and !HW_FREEed,
	   and call soc_pcm_close().

We can share same code by
	1) hw_free is not needed. Needs last dpcm as rollback.
	2) hw_free is not needed.
	3) hw_free is     needed.

This patch adds new dpcm_be_dai_stop() and share these 3.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87a6rduoam.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:32 +00:00
Kuninori Morimoto
20048a9a40
ASoC: soc-pcm: remove unneeded !rtd->dai_link check
rtd->dai_link is setuped at soc_new_pcm_runtime(),
thus "rtd->dai_link == NULL" is never happen.
This patch removes unneeded !rtd->dai_link check

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87blbtuoar.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:31 +00:00
Kuninori Morimoto
1db19c1518
ASoC: soc-pcm: fixup dpcm_be_dai_startup() user count
At dpcm_be_dai_startup_unwind(), it indicates error message at (1)
if this function was called with no users.
But, it doesn't use "continue" here. Thus, users will be a
negative number at (2)

	void dpcm_be_dai_startup_unwind(...)
	{
		...
		for_each_dpcm_be(...) {
			...
(1)			if (be->dpcm[stream].users == 0)
				dev_err(...);

(2)			if (--be->dpcm[stream].users != 0)
				continue;

At dpcm_be_dai_startup(), it indicates error message if
user reached to MAX USERS at (A).
But, it doesn't use "continue" here. Thus, it will be over
MAX USERS at (B).

	int dpcm_be_dai_startup(...)
	{
		...
		for_each_dpcm_be(...) {
			...
(A)			if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
				dev_err(...);

(B)			if (be->dpcm[stream].users++ != 0)
				continue;

These are just bug. This patch fixup these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87czw9uoav.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:30 +00:00
Kuninori Morimoto
c393281a3c
ASoC: soc-pcm: add soc_hw_sanity_check()
Current soc_pcm_open() is checking runtime->hw parameters, but having
such function is very helpful for reading code.

This patch adds new soc_hw_sanity_check() and checks runtime->hw
parameters there. And print its debug message there, too.

Debug message print out timing is exchanged after this patch,
but it is not a big deal, because it is for debug.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87eegpuob1.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:29 +00:00
Kuninori Morimoto
68cbc55737
ASoC: soc-pcm: add soc_pcm_update_symmetry()
Current soc-pcm has soc_pcm_has_symmetry() and using it as

	if (soc_pcm_has_symmetry(substream))
		substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;

We want to share same operation as same function.
This patch adds soc_pcm_update_symmetry() and pack above code in
one function.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ft15uob6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:28 +00:00
Kuninori Morimoto
56e749ba75
ASoC: soc-pcm: direct copy at snd_soc_set_runtime_hwparams()
snd_soc_set_runtime_hwparams() is called from each driver
to initialize hw parameters,
but coping each parameters one-by-one.

Current code is not copying all parameters, but no big effect
if we do it. This patch copies all parameters by simple code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87h7lluoba.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:27 +00:00
Kuninori Morimoto
6fb8944cd2
ASoC: soc-pcm: add soc_cpu/codec_dai_name() macro
soc-pcm needs DAI name and it will be "multicpu/multicodec" if it has
many DAIs. But current code is using very verbose for it.
This patch uses macro and makes code simple.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87im61uobf.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:26 +00:00
Kuninori Morimoto
f8fc9ec56f
ASoC: soc-pcm: check DAI activity under soc_pcm_apply_symmetry()
soc_pcm_apply_symmetry() is used like below in all cases.

	if (snd_soc_dai_active(dai)) {
		err = soc_pcm_apply_symmetry(fe_substream, dai);
		...
	}

Because of this style, the code is deep nested.
This patch checks it under soc_pcm_apply_symmetry(), and makes code simple.

	static int soc_pcm_apply_symmetry(...)
	{
		...
=>		if (!snd_soc_dai_active(...))
			return 0;
		...
	}

=>	ret = soc_pcm_apply_symmetry();
	if (ret < 0)
		...

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87k0qhuobl.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-12 14:26:25 +00:00
Mark Brown
d59748076b
Merge series "ASoC: core: remove cppcheck warnings" from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:
This is the first batch of cleanups to make cppcheck more usable,
currently we have way too many warnings that drown real issues.

Pierre-Louis Bossart (6):
  ASoC: soc-ops: remove useless assignment
  ASoC: soc-pcm: remove redundant assignment
  ASoC: soc-pcm: remove shadowing variable
  ASoC: soc-pcm: add error log
  ASoC: soc-topology: clarify expression
  ASoC: generic: simple-card-utils: remove useless assignment

 sound/soc/generic/simple-card-utils.c |  2 +-
 sound/soc/soc-ops.c                   |  2 +-
 sound/soc/soc-pcm.c                   |  4 ++--
 sound/soc/soc-topology.c              | 16 ++++++++--------
 4 files changed, 12 insertions(+), 12 deletions(-)

--
2.25.1
2021-03-10 13:08:32 +00:00
Pierre-Louis Bossart
61456212e8
ASoC: soc-pcm: add error log
cppcheck warning:

sound/soc/soc-pcm.c:1907:6: style: Variable 'err' is assigned a value
that is never used. [unreadVariable]
 err = dpcm_be_dai_hw_free(fe, stream);
     ^

it's not clear why dpcm_be_dai_hw_free() is sometimes called without
testing the error status, and sometimes an error message is provided.

When in doubt, add an error message for consistency. This may have to
be revisited.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210218221921.88991-5-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:56 +00:00
Pierre-Louis Bossart
61b9eedd93
ASoC: soc-pcm: remove shadowing variable
cppcheck warning:

sound/soc/soc-pcm.c:1718:7: style: Local variable 'i' shadows outer
variable [shadowVariable]
  int i;
      ^
sound/soc/soc-pcm.c:1696:6: note: Shadowed declaration
 int i;
     ^
sound/soc/soc-pcm.c:1718:7: note: Shadow variable
  int i;
      ^

the second variable seems totally unnecessary.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210218221921.88991-4-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:55 +00:00
Pierre-Louis Bossart
9dbe774091
ASoC: soc-pcm: remove redundant assignment
cppcheck warning:

sound/soc/soc-pcm.c:2398:7: style: Variable 'ret' is reassigned a
value before the old one has been used. [redundantAssignment]
  ret = -EINVAL;
      ^
sound/soc/soc-pcm.c:2395:7: note: ret is assigned
  ret = -EINVAL;
      ^
sound/soc/soc-pcm.c:2398:7: note: ret is overwritten
  ret = -EINVAL;
      ^

This looks like a copy/paste or git merge issue.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210218221921.88991-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:54 +00:00
Kuninori Morimoto
4fe28461e2
ASoC: soc-pcm: unpack dpcm_set_fe_runtime()
dpcm_fe_dai_startup() (= A) calls dpcm_set_fe_runtime() (= B) to setup
DPCM runtime. From *naming point of view*, it sounds like setup function
for FE.

(A)	static int dpcm_fe_dai_startup(...)
	{
		...
(B)		dpcm_set_fe_runtime(...);
		...
	}

But in dpcm_set_fe_runtime() (= B),
It  setups FE by dpcm_runtime_setup_fe() (= X),
and setups BE by dpcm_runtime_merge_xxx() (= Y).

(B)	static void dpcm_set_fe_runtime(...)
	{
		...
(X)		dpcm_runtime_setup_fe(...);

 ^		dpcm_runtime_setup_be_format(...);
(Y)		dpcm_runtime_setup_be_chan(...);
 v		dpcm_runtime_setup_be_rate(...);
	}

These means that the function which is called as xxx_fe_xxx()
is setups both FE and BE. This is confusable and can be hot bed for bug.

Now dpcm_set_fe_runtime() (= B) is simple enough and confusable naming,
let's unpack it at dpcm_fe_dai_startup().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87mtvxvsgn.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:48 +00:00
Kuninori Morimoto
1b8cb123f3
ASoC: soc-pcm: add dpcm_runtime_setup()
dpcm_fe_dai_startup() (= A) calls dpcm_set_fe_runtime() (= B) to setup
DPCM runtime. From *naming point of view*, it sounds like setup function
for FE.

(A)	static int dpcm_fe_dai_startup(...)
	{
		...
(B)		dpcm_set_fe_runtime(...);
		...
	}

But in dpcm_set_fe_runtime() (= B),
It  setups FE by dpcm_runtime_setup_fe() (= X),
and setups BE by dpcm_runtime_merge_xxx() (= Y).

(B)	static void dpcm_set_fe_runtime(...)
	{
		...
(X)		dpcm_runtime_setup_fe(...);

 ^		dpcm_runtime_merge_format(...);
(Y)		dpcm_runtime_merge_chan(...);
 v		dpcm_runtime_merge_rate(...);
	}

These means that the function which is called as xxx_fe_xxx()
is setups both FE and BE. This is confusable and can be hot bed for bug.

This patch renames unclear dpcm_runtime_merge_xxx() (= Y) to
more clear dpcm_runtime_setup_be_xxx().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o8gdvsgr.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:47 +00:00
Kuninori Morimoto
5f53898af1
ASoC: soc-pcm: add dpcm_runtime_setup_fe()
dpcm_fe_dai_startup() (= A) calls dpcm_set_fe_runtime() (= B) to setup
DPCM runtime. From *naming point of view*, it sounds like setup function
for FE.

(A)	static int dpcm_fe_dai_startup(...)
	{
		...
(B)		dpcm_set_fe_runtime(...);
		...
	}

But in dpcm_set_fe_runtime() (= B),
It  setups FE by for_each loop (= X),
and setups BE by dpcm_runtime_merge_xxx() (= Y).

(B)	static void dpcm_set_fe_runtime(...)
	{
		...
 ^		for_each_rtd_cpu_dais(...) {
 |			...
(X)			soc_pcm_hw_update_rate(...);
 |			soc_pcm_hw_update_chan(...);
 |			soc_pcm_hw_update_format(...);
 v		}

 ^		dpcm_runtime_merge_format(...);
(Y)		dpcm_runtime_merge_chan(...);
 v		dpcm_runtime_merge_rate(...);
	}

These means that the function which is called as xxx_fe_xxx()
is setups both FE and BE. This is confusable and can be hot bed for bug.

To tidyup it, as 1st step, this patch adds new dpcm_runtime_setup_fe()
for (X).

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pn0tvsgx.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:46 +00:00
Kuninori Morimoto
7f4a763642
ASoC: soc-pcm: unpack dpcm_init_runtime_hw()
dpcm_init_runtime_hw() is now just verbose function.
This patch unpacks it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1l9vsh4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:45 +00:00
Kuninori Morimoto
6053a840f7
ASoC: soc-pcm: remove strange format storing
dpcm_init_runtime_hw() (= A) is used from dpcm_set_fe_runtime() (= B)
with for_each_rtd_cpu_dais() loop (= C), and it checks formats (= D).

(A)	static void dpcm_init_runtime_hw(...)
	{
		...
 ^		if (runtime->hw.formats)
 | (D1)			runtime->hw.formats &= stream->formats;
(D)		else
 | (D2)			runtime->hw.formats = stream->formats;
 v	}

(B)	static void dpcm_set_fe_runtime(...)
	{
		...
(C)		for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
			...
(A)			dpcm_init_runtime_hw(...);
		}
	}

If this for_each_rtd_cpu_dais() loop (= C) calls
dpcm_init_runtime_hw() (= A) multiple times, this means it is Multi-CPU.

If we focus to format operation at (D), using mask (= D1) is understandable
because it restricts unsupported format.
But, enabling format when zero format case (= D2) is very strange,
because it might enables unsupported format.

This runtime->hw.formats is initialized by ULLONG_MAX at soc_pcm_hw_init(),
thus becoming zero format means it can't use such format.
And doing this strange format operation is only here.

This patch removes strange format operation (= D2), and use standard
soc_pcm_hw_update_format() for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sg5pvshq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-10 13:06:44 +00:00
Kai Vehmanen
8a353d7baf
ASoC: soc-pcm: fix hw param limits calculation for multi-DAI
In case DPCM runtime has multiple CPU DAIs, dpcm_init_runtime_hw() is
called multiple times, once for each CPU DAI. This will lead to
ignoring hw limits of all but the last DAI.

Fix this by moving soc_pcm_hw_init() up by one level to
dpcm_init_runtime_hw().

Fixes: 140f553d12 ("ASoC: soc-pcm: fix hwparams min/max init for dpcm")
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20210216172251.3023723-1-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-17 18:04:40 +00:00
Kai Vehmanen
140f553d12
ASoC: soc-pcm: fix hwparams min/max init for dpcm
When runtime is initialized with dpcm_init_runtime_hw(), some of the
min/max calculations assume that defaults are set. For example
calculation of channel min/max values may be done using zero-initialized
data and soc_pcm_hw_update_chan() will always return max-channels of 0
in this case. This will result in failure to open the PCM at all.

Fix the issue by calling soc_pcm_hw_init() before calling any
soc_pcm_hw_update_*() functions.

Remove the conditional code on runtime->hw.formats as this field
is anyways set in soc_pcm_hw_init().

Fixes: 6cb56a4549 ("ASoC: soc-pcm: add soc_pcm_hw_update_chan()")
Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20210214220414.2876690-1-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-15 20:19:50 +00:00
Kuninori Morimoto
debc71f26c
ASoC: soc-pcm: add soc_pcm_hw_update_format()
We have soc_pcm_hw_update_xxx() now.
This patch creates same function for format.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87pn1g90oa.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-12 12:36:45 +00:00
Kuninori Morimoto
6cb56a4549
ASoC: soc-pcm: add soc_pcm_hw_update_chan()
We have soc_pcm_hw_update_rate() now.
This patch creates same function for chan.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87r1lw90oo.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-12 12:36:44 +00:00
Kuninori Morimoto
f6c04af5dc
ASoC: soc-pcm: add soc_pcm_hw_update_rate()
To update hw, we need to follow setting order

	1) set hw->rates
	2) call snd_pcm_limit_hw_rates()
	3) update hw->rate_min/max

To avoid random settings, this patch adds new soc_pcm_hw_update_rate()
and share updating code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87sg6c90qv.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-12 12:36:43 +00:00
Shengjiu Wang
b6eabd247d
ASoC: soc-pcm: change error message to debug message
This log message should be a debug message, because it
doesn't return directly but continue next loop.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/1612771965-5776-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-10 17:22:56 +00:00
Kuninori Morimoto
dd5abc7834
ASoC: soc-pcm: fixup snd_pcm_limit_hw_rates() timing
soc-pcm has snd_pcm_limit_hw_rates() which determine rate_min/rate_max.
It updates runtime->hw.rate_min/max (A) based on hw->rates (B).

	int snd_pcm_limit_hw_rates(...)
	{
		int i;
		for (...) {
(B)			if (runtime->hw.rates & (1 << i)) {
(A)				runtime->hw.rate_min = ...
				break;
			}
		}
		for (...) {
(B)			if (runtime->hw.rates & (1 << i)) {
(A)				runtime->hw.rate_max = ...
				break;
			}
		}
		return 0;
	}

This means, setup order is

	1) set hw->rates
	2) call snd_pcm_limit_hw_rates()
	3) update hw->rate_min/max

soc_pcm_init_runtime_hw() is calling it in good order

	static void soc_pcm_init_runtime_hw(xxx)
	{
		...
1)		hw->rates = snd_pcm_rate_mask_intersect(...);

2)		snd_pcm_limit_hw_rates(...);

3)		hw->rate_min = max(...);
		hw->rate_min = max(...);
		hw->rate_max = min_not_zero(...);
		hw->rate_max = min_not_zero(...);
	}

But, dpcm_fe_dai_startup() is not.

	static int dpcm_fe_dai_startup(xxx)
	{
		...
1) 3)		dpcm_set_fe_runtime(...);
2)		snd_pcm_limit_hw_rates(...);
		...
	}

More detail of dpcm_set_fe_runtime() is

	static void dpcm_set_fe_runtime()
	{
		...
		for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
			...

3) 1)			dpcm_init_runtime_hw(...);
		}
		...
3) 1)		dpcm_runtime_merge_rate(...);
	}

This patch fixup these into

	static void dpcm_set_fe_runtime()
	{
		...
		for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
			...

1) 2) 3)		dpcm_init_runtime_hw(...);
		}
		...
1) 2) 3)	dpcm_runtime_merge_rate(...);
	}

	static int dpcm_fe_dai_startup(xxx)
	{
		...
		dpcm_set_fe_runtime(...);
-		snd_pcm_limit_hw_rates(...);
		...
	}

Link: https://lore.kernel.org/r/87k15l7ewd.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/8735ytaig8.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-03 17:41:43 +00:00
Kuninori Morimoto
4b260f4254
ASoC: soc-pcm: use snd_pcm_hardware at dpcm_runtime_merge_xxx()
soc-pcm has dpcm_runtime_merge_xxx() functions,
but uses parameters are very verbose.

	dpcm_runtime_merge_format(...,	&runtime->hw.formats);
	dpcm_runtime_merge_chan(...,	&runtime->hw.channels_min,
					&runtime->hw.channels_max);
	dpcm_runtime_merge_rate(...,	&runtime->hw.rates,
					&runtime->hw.rate_min,
					&runtime->hw.rate_max);

We want to replace it into

	dpcm_runtime_merge_format(...,	runtime);
	dpcm_runtime_merge_chan(...,	runtime);
	dpcm_runtime_merge_rate(...,	runtime);

This patch do it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/874kj9aigd.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-03 17:41:42 +00:00
Kuninori Morimoto
2b39123b13
ASoC: soc-pcm: add soc_create_pcm() and simplify soc_new_pcm()
soc_new_pcm() implementation is very long / verbose / complex,
thus, it is very difficult to read.
If we read it carefully, we can notice that it is consisted by

	int soc_new_pcm(...)
	{
		(1) judging playback/caputre part
		(2) creating the PCM part
		(3) setup pcm/rtd part
	}

This patch adds new soc_create_pcm() for (2) part
and offload it from snd_pcm_new().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/875z3paigi.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-03 17:41:41 +00:00
Kuninori Morimoto
7fc6bebd58
ASoC: soc-pcm: add soc_get_playback_capture() and simplify soc_new_pcm()
soc_new_pcm() implementation is very long / verbose / complex,
thus, it is very difficult to read.
If we read it carefully, we can notice that it is consisted by

	int soc_new_pcm(...)
	{
		(1) judging playback/caputre part
		(2) creating the PCM part
		(3) setup pcm/rtd part
	}

This patch adds new soc_get_playback_capture() for (1) part
and offload it from soc_new_pcm().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877do5aign.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-03 17:41:40 +00:00
Kuninori Morimoto
e04e7b8ccd
ASoC: soc-pcm: tidyup pcm setting
Current soc_new_pcm() setups pcm randomly.
This patch tidyup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878s8laigt.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-02-03 17:41:39 +00:00
Kuninori Morimoto
3a90672111
ASoC: soc-pcm: cleanup soc_pcm_params_symmetry()
soc_pcm_params_symmetry() checks rate/channel/sample_bits state.
These are very similar but different, thus, it needs to have very
verbose code.
This patch use macro for it and make code more simple.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878s8un6si.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-21 12:38:22 +00:00
Kuninori Morimoto
fac110cbcd
ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry()
soc_pcm_apply_symmetry() want to call snd_pcm_hw_constraint_single()
for rate/channel/sample_bits, but, it needs many condition checks.
These are very similar but different, thus, it needs to have very
verbose code.
This patch use macro for it and make code more simple.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87a6tan6sm.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-21 12:38:21 +00:00
Kuninori Morimoto
f14654ddf2
ASoC: sync parameter naming : rate / sample_bits
snd_pcm_runtime / snd_soc_dai / snd_soc_dai_driver / snd_soc_dai_link
have related parameter which is similar but not same naming.

	struct snd_pcm_runtime {
		...
(A)		unsigned int rate;
		...
(B)		unsigned int sample_bits;
		...
	};

	struct snd_soc_dai {
		...
(A)		unsigned int rate;
(B)		unsigned int sample_bits;
		...
	};

	struct snd_soc_dai_driver {
		...
(A)		unsigned int symmetric_rates:1;
(B)		unsigned int symmetric_samplebits:1;
		...
	};

	struct snd_soc_dai_link {
		...
(A)		unsigned int symmetric_rates:1;
(B)		unsigned int symmetric_samplebits:1;
		...
	};

Because it is similar but not same naming rule,
code can be verbose / can't share macro.

This patch sync naming rule for framework.
	- xxx_rates;
	+ xxx_rate;

	- xxx_samplebits;
	+ xxx_sample_bits;

old name will be removed if all drivers were switched
to new naming rule.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87wnweolj6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-21 12:37:43 +00:00
Kuninori Morimoto
80f454e283
ASoC: soc-pcm: revert soc_pcm_apply_symmetry()
commit a39748d03c ("ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry()")
was applied by miscommunication.
To more cleanup code, and to be easy review, this patch reverts it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87y2guoljm.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-21 12:37:43 +00:00
Kuninori Morimoto
a39748d03c
ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry()
soc_pcm_apply_symmetry() want to call snd_pcm_hw_constraint_single()
for rate/channel/sample_bits, but, it needs many condition check.
These are very similar but different, thus, it needs to have very
verbose code.
This patch use macro for it and make code more simple.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87wnxo7uyq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-13 11:33:12 +00:00
Kuninori Morimoto
2805b8bd3e
ASoC: soc-pcm: add soc_pcm_set_dai_params()
Getting rate/channels/sample_bits from param needs fixed method.
This patch adds new soc_pcm_set_dai_params() and replace existing code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87y2i47uyw.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-13 11:33:11 +00:00
Kuninori Morimoto
a7e20444ef
ASoC: soc-pcm: add dpcm_set_be_update_state()
soc-pcm has dpcm_set_fe_update_state() to update FE's runtime_update
(except dpcm_fe_dai_do_trigger() which needs to update it without it).
OTOH, it doesn't have BE's update function.

	O: dpcm_set_fe_update_state()
	X: dpcm_set_be_update_state()

This patch add BE's dpcm_set_fe_update_state()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87zh2k7uz1.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-13 11:33:10 +00:00
Kuninori Morimoto
9c6d7f9346
ASoC: soc-pcm: move dpcm_set_fe_update_state()
This patch moves dpcm_set_fe_update_state() to top side.
This is prepare for cleanup soc-pcm.c

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/871rfw99jn.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-13 11:33:10 +00:00
Dan Carpenter
e91b65b36f
ASoC: soc-pcm: Fix an uninitialized error code
The error path here doesn't set "ret" so it returns uninitialized data
instead of a negative error code.

Fixes: 2c1382840c ("ASoC: soc-pcm: disconnect BEs if the FE is not ready")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/X/wfXQFxeMLvpO+1@mwanda
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-11 14:03:55 +00:00
Souptick Joarder
4eeed5f403
ASoC: soc-pcm: return correct -ERRNO in failure path
Kernel test robot throws below error ->

sound/soc/soc-pcm.c:2523 dpcm_run_update_startup() error: uninitialized
symbol 'ret'.

Initializing ret = 0 and returning correct -ERRNO in failure path.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Link: https://lore.kernel.org/r/1610163901-5523-1-git-send-email-jrdr.linux@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-11 14:03:52 +00:00
朱灿灿
2c1382840c
ASoC: soc-pcm: disconnect BEs if the FE is not ready
FE is connected to two BEs, BE1 is active, BE2 is deactive.
When closing BE1, FE/BE1 is in HW_FREE state, then BE2 is
startup by mixer runtime update.

For FE is in HW_FREE state, dpcm_run_update_startup() will skip
BE2's startup because FE's state is HW_FREE, BE2 stays in FE's
be_clients list.

During FE's closed, the dpcm_fe_dai_close() will close all related
BEs, BE2 will be closed. This will lead to BE2's dpcm[stream].users
mismatch.

We need disconnet all pending BEs in the corner case.

Signed-off-by: zhucancan <zhucancan@vivo.com>
Link: https://lore.kernel.org/r/AAoArwDfDnoefyxzy2wyiaqm.1.1608885766936.Hmail.zhucancan@vivo.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-01-07 16:14:13 +00:00
Kuninori Morimoto
6374f493d9
ASoC: soc-pcm: care trigger rollback
soc_pcm_trigger() calls DAI/Component/Link trigger,
but some of them might be failed.

	static int soc_pcm_trigger(...)
	{
		...
		switch (cmd) {
		case SNDRV_PCM_TRIGGER_START:
		case SNDRV_PCM_TRIGGER_RESUME:
		case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
			ret = snd_soc_link_trigger(substream, cmd);
			if (ret < 0)
				break;

(*)			ret = snd_soc_pcm_component_trigger(substream, cmd);
			if (ret < 0)
				break;

			ret = snd_soc_pcm_dai_trigger(substream, cmd);
			break;
		case SNDRV_PCM_TRIGGER_STOP:
		case SNDRV_PCM_TRIGGER_SUSPEND:
		case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
			ret = snd_soc_pcm_dai_trigger(substream, cmd);
			if (ret < 0)
				break;

			ret = snd_soc_pcm_component_trigger(substream, cmd);
			if (ret < 0)
				break;

			ret = snd_soc_link_trigger(substream, cmd);
			break;
		}
		...
	}

For example, if soc_pcm_trigger() failed at (*) point,
we need to rollback previous succeeded trigger.

This patch adds trigger mark for DAI/Component/Link,
and do STOP if START/RESUME/PAUSE_RELEASE were failed.

Because it need to use new rollback parameter,
we need to modify DAI/Component/Link trigger functions in the same time.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87a6uycssd.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-12-09 12:13:38 +00:00
Kuninori Morimoto
a9faca15a6
ASoC: soc-pcm: remove dpcm_do_trigger()
dpcm_be_dai_trigger() is calling dpcm_do_trigger()
at each SNDRV_PCM_TRIGGER_xxx (1).

	int dpcm_be_dai_trigger(...)
	{
		for_each_dpcm_be(fe, stream, dpcm) {
(B)			...
			switch (cmd) {
			case SNDRV_PCM_TRIGGER_START:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			case SNDRV_PCM_TRIGGER_RESUME:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			case SNDRV_PCM_TRIGGER_STOP:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			case SNDRV_PCM_TRIGGER_SUSPEND:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
				...
(1)				ret = dpcm_do_trigger(...);
				...
			}
		}
	}

But it is just very verbose and duplicated function.
Because We can indicate dev_dbg() (A) at dpcm_be_dai_trigger() (B).
And dev_err() (C) is not needed because soc_pcm_trigger() itself
indicates error message when error.

	static int dpcm_do_trigger(...)
	{
		int ret;

(A)		dev_dbg(...);

		ret = soc_pcm_trigger(substream, cmd);
		if (ret < 0)
(C)			dev_err(...);

		return ret;
	}

This patch replace dpcm_do_trigger() to soc_pcm_trigger().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87blfecssk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-12-09 12:13:37 +00:00
Ranjani Sridharan
bb9dd3ce61
ASoC: pcm: send DAPM_STREAM_STOP event in dpcm_fe_dai_shutdown
A recent change removed the call to send the DAPM_STREAM_STOP
event in dpcm_fe_dai_shutdown. But this causes a regression
when a PCM prepare is not paired with a hw_free. So, add
the DAPM_STREAM_STOP event back to dpcm_fe_dai_shutdown()
to fix this.

The new sequence would be:
soc_pcm_prepare()
    -> SND_SOC_DAPM_STREAM_START

soc_pcm_hw_free()
    -> soc_pcm_hw_free()
	-> SND_SOC_DAPM_STREAM_STOP

dpcm_fe_dai_shutdown()
    -> SND_SOC_DAPM_STREAM_STOP

Note that the DAPM_STREAM_STOP will be called twice but it seems
harmless.

Fixes: a27b421f1d ('ASoC: pcm: call snd_soc_dapm_stream_stop() in soc_pcm_hw_clean')

Reported-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20201202193343.912942-1-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-12-07 14:18:02 +00:00