Commit graph

740 commits

Author SHA1 Message Date
Krzysztof Kozlowski 9723cab054
ASoC: Use inline function for type safety in snd_soc_substream_to_rtd()
A common pattern in sound drivers is getting 'struct snd_soc_pcm_runtime'
from 'struct snd_pcm_substream' opaque pointer private_data field with
snd_soc_substream_to_rtd().  However 'private_data' appears in several
other structures as well, including 'struct snd_compr_stream'.  The
field might not hold the same type for every structure, although seems
the case at least for 'struct snd_compr_stream', so code can easily make
a mistake by using macro for wrong structure passed as argument.

Switch from macro to inline function, so such mistake will be build-time
detectable.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20240501175127.34301-1-krzysztof.kozlowski@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2024-05-02 12:57:25 +09:00
Cezary Rojewski 31a70a71b3
ASoC: pcm: Reverse iterate DAIs when shutting them down
During startup snd_soc_dai_startup() is launched in ascending order and
the exact same thing is done during shutdown procedure. Reverse the
order in the latter so that it is symmetric to the former.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20240426095733.3946951-2-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2024-04-30 00:09:46 +09:00
Andy Shevchenko 3249c68e3c
ASoC: soc.h: Don't use "proxy" headers
Update header inclusions to follow IWYU (Include What You Use)
principle.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20240422151513.2052167-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2024-04-23 10:39:33 +09:00
Luca Ceresoli d75a21611a
ASoC: core: add SOC_DOUBLE_RANGE_TLV() helper macro
No macro currently allows handling a stereo control that has left and right
in the same register and whose minimum register value is not zero. Add one
that does that.

Note that even though the snd_soc_*_volsw_range() look more appropriate
given the _range suffix, they are not suitable because they don't honor the
two shift values. The snd_soc_*_volsw() look more generic and are suitable
for the task.

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://msgid.link/r/20240305-rk3308-audio-codec-v4-3-312acdbe628f@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2024-03-26 14:55:20 +00:00
Krzysztof Kozlowski cf88ab486a
ASoC: Constify pointer to of_phandle_args
Constify pointer to of_phandle_args in few function arguments, for code
safety and self-documenting code.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://msgid.link/r/20240216145448.224185-1-krzysztof.kozlowski@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2024-02-19 17:02:10 +00:00
Takashi Iwai 0205f3753d ASoC: Updates for v6.8
This is a relatively quiet release, there's a lot of driver specific
 changes and the usual high level of activity in the SOF core but the
 one big core change was Mormioto-san's work to support more N:M
 CPU:CODEC mapping cases.  Highlights include:
 
  - Enhanced support for N:M CPU:CODEC mappings in the core and in
    audio-graph-card2.
  - Support for falling back to older SOF IPC versions where firmware for
    new versions is not available.
  - Support for notification of control changes generated by SOF firmware
    with IPC4.
  - Device tree support for describing parts of the card which can be
    active over suspend (for very low power playback or wake word use
    cases).
  - ACPI parsing support for the ES83xx driver, reducing the number of
    quirks neede for x86 systems.
  - Support for more AMD and Intel systems, NXP i.MX8m MICFIL, Qualcomm
    SM8250, SM8550, SM8650 and X1E80100.
  - Removal of Freescale MPC8610 support, the SoC is no longer supported
    by Linux.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmWbJ5EACgkQJNaLcl1U
 h9CZTwf/c8CPwoKABZear8jiQpZLUhFLuGQwSShPYVZ7XPzzTMp9BwVmd40DCnUi
 NeSc22t2UgT0H06nx3QK8sKOhrpQoBQVrIajf2AaxD44TJbsOYGGe4pMh1sXKAMF
 c0ybp8uRgsjiv2Y++SBXZLexGC11/b8eTFLV1nTK/i2nygGjbfWSJ9s4PpB9V6cA
 nZrQ/p+x/ZwaBejFUnvE06M7GHtCD6lxrB9Q1EmWA4RxcW7RNUtIN5gr16HlaMiC
 3gix4mg40llhBFF9s4eBjRBNKL2paiejPZwcYkAC8w+SkZ/roXaeN55g0avmDWyW
 AN9o096vaEVWKhZ/jdTHmFVf2PV2Iw==
 =rbT5
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v6.8' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v6.8

This is a relatively quiet release, there's a lot of driver specific
changes and the usual high level of activity in the SOF core but the
one big core change was Mormioto-san's work to support more N:M
CPU:CODEC mapping cases.  Highlights include:

 - Enhanced support for N:M CPU:CODEC mappings in the core and in
   audio-graph-card2.
 - Support for falling back to older SOF IPC versions where firmware for
   new versions is not available.
 - Support for notification of control changes generated by SOF firmware
   with IPC4.
 - Device tree support for describing parts of the card which can be
   active over suspend (for very low power playback or wake word use
   cases).
 - ACPI parsing support for the ES83xx driver, reducing the number of
   quirks neede for x86 systems.
 - Support for more AMD and Intel systems, NXP i.MX8m MICFIL, Qualcomm
   SM8250, SM8550, SM8650 and X1E80100.
 - Removal of Freescale MPC8610 support, the SoC is no longer supported
   by Linux.
2024-01-08 08:18:02 +01:00
Kuninori Morimoto 13f58267cd
ASoC: soc.h: don't create dummy Component via COMP_DUMMY()
Many ASoC drivers define CPU/Codec/Platform dai_link by below macro.

	SND_SOC_DAILINK_DEFS(link,
(A)		     DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai")),
(B)		     DAILINK_COMP_ARRAY(COMP_CODEC("codec", "dai1"),
(B)					COMP_CODEC("codec", "dai2")),
(C)		     DAILINK_COMP_ARRAY(COMP_EMPTY()));

In this case, this macro will be converted to like below

	[o] = static struct snd_soc_dai_link_component

(A)	[o] link_cpus[]      = {{ .dai_name = "cpu_dai" }};
(B)	[o] link_codecs[]    = {{ .dai_name = "dai1", .name = "codec" },
				{ .dai_name = "dai2", .name = "codec" }}
(C)	[o] link_platforms[] = {{ }};

CPU and Codec info will be filled by COMP_CPU() / COMP_CODEC (= A,B),
and Platform will have empty data by COMP_EMPTY() (= C) in this case.

Platform empty info will be filled when driver probe()
(most of case, CPU info will be copied to use soc-generic-dmaengine-pcm).

For example in case of DPCM FE/BE, it will be like below.
Codec will be dummy Component / DAI in this case (X).

	SND_SOC_DAILINK_DEFS(link,
		     DAILINK_COMP_ARRAY(COMP_CPU(...)),
(X)		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
		     DAILINK_COMP_ARRAY(COMP_EMPTY()));

(X) part will converted like below

	[o] link_codecs[]    = {{ .name = "snd-soc-dummy",
				  .dai_name = "snd-soc-dummy-dai", }}

Even though we already have common asoc_dummy_dlc for dummy
Component / DAI, this macro will re-create new dummy dlc.
Some drivers defines many dai_link info via SND_SOC_DAILINK_DEFS(),
this means many dummy dlc also will be re-created. This is waste of
memory.

If we can use existing common asoc_dummy_dlc at (X),
we can avoid to re-creating dummy dlc, then, we can save the memory.

At that time, we want to keep existing code as much as possible, because
too many drivers are using this macro. But because of its original style,
using common asoc_dummy_dlc from it is very difficult or impossible.

So let's change the mind. The macro is used like below

	SND_SOC_DAILINK_DEFS(link,
		     DAILINK_COMP_ARRAY(COMP_CPU(...)),
(x)		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
		     DAILINK_COMP_ARRAY(COMP_EMPTY()));

	static struct snd_soc_dai_link dai_links[] = {
	{
		.name = ...,
		.stream_name = ...,
(y)		SND_SOC_DAILINK_REG(link),
	},

(y) part will be like below

        static struct snd_soc_dai_link dai_links[] = {
        {
                .name = ...,
                .stream_name = ...,
 ^		...
 |		.codecs		= link_codecs,
(y)		.num_codecs	= ARRAY_SIZE(link_codecs),
 v		...
	}

This patch try to use trick on COMP_DUMMY()

-	#define COMP_DUMMY()	{ .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }
+	#define COMP_DUMMY()

By this tric, (x) part will be like below.

before
	[o] link_codecs[] = {{ .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }}
after
	[o] link_codecs[] = { };

This is same as below

	[o] link_codecs[0];

This means it has pointer (link_codecs), but the array size is 0.
(y) part will be like below.

	static struct snd_soc_dai_link dai_links[] = {
	{
		...
		.codecs		= link_codecs,
		.num_codecs	= 0,
		...
	},

This is very special settings that normal use usually not do,
but new macro do.
We can find this special settings on soc-core.c and fill it as
"dummy DAI" (= asoc_dummy_dlc). By this tric, we can avoid to re-create
dummy dlc and save the memory.

This patch add tric at COMP_DUMMY() and add snd_soc_fill_dummy_dai()
to fill dummy DAI.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://msgid.link/r/871qbi93qu.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-12-19 13:23:46 +00:00
Cezary Rojewski 4a6ba09e89 ASoC: pcm: Honor subformat when configuring runtime
Subformat options are ignored when setting up hardware parameters and
assigning PCM stream capabilities. Account for them to allow for
granular format selection.

As there is only one user currently (format S32_LE), subformat is
represented by a simple u32 and stores flags only for that one user
alone. Such approach allows for alloc/free-less code until there are
more users on the horizon.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20231117120610.1755254-4-cezary.rojewski@intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-11-27 17:27:20 +01:00
Kuninori Morimoto 45cc50d134
ASoC: makes CPU/Codec channel connection map more generic
Current ASoC CPU:Codec = N:M connection is using connection mapping idea,
but it is used for N < M case only. We want to use it for any case.

By this patch, not only N:M connection, but all existing connection
(1:1, 1:N, N:N) will use same connection mapping. Then, because it will
use default mapping, no conversion patch is needed to exising drivers.

More over, CPU:Codec = N:M (N > M) also supported in the same time.

ch_maps array will has CPU/Codec index by this patch.

Image
	CPU0 <---> Codec0
	CPU1 <-+-> Codec1
	CPU2 <-/

ch_map
	ch_map[0].cpu = 0	ch_map[0].codec = 0
	ch_map[1].cpu = 1	ch_map[1].codec = 1
	ch_map[2].cpu = 2	ch_map[2].codec = 1

Link: https://lore.kernel.org/r/87fs6wuszr.wl-kuninori.morimoto.gx@renesas.com
Link: https://lore.kernel.org/r/878r7yqeo4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tested-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/87ttpq4f2c.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-11-27 13:44:00 +00:00
Mark Brown 3c716e7f8a
ASoC: Merge fixes for consistent cs42l43 schema
We have adjacent changes for the cs42l43 DT schema, merge the fixes
branch up so that there's a single thing for people to base future
changes on.
2023-10-10 17:07:17 +01:00
Amadeusz Sławiński dd9f9cc1e6
ASoC: core: Do not call link_exit() on uninitialized rtd objects
On init we have sequence:

	for_each_card_prelinks(card, i, dai_link) {
		ret = snd_soc_add_pcm_runtime(card, dai_link);

	ret = init_some_other_things(...);
	if (ret)
		goto probe_end:

	for_each_card_rtds(card, rtd) {
		ret = soc_init_pcm_runtime(card, rtd);

probe_end:

while on exit:
	for_each_card_rtds(card, rtd)
		snd_soc_link_exit(rtd);

If init_some_other_things() step fails due to error we end up with
not fully setup rtds and try to call snd_soc_link_exit on them, which
depending on contents on .link_exit handler, can end up dereferencing
NULL pointer.

Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Link: https://lore.kernel.org/r/20230929103243.705433-2-amadeuszx.slawinski@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-29 14:17:49 +02:00
Kuninori Morimoto ad484cc98f
ASoC: remove asoc_xxx() compatible macro
No driver is using asoc_xxx() any more.
This patch removes compatible macro for asoc_xxx().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878r8tfo06.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-26 17:18:45 +02:00
Kuninori Morimoto 1d5a2b5dd0
ASoC: soc.h: convert asoc_xxx() to snd_soc_xxx()
ASoC is using 2 type of prefix (asoc_xxx() vs snd_soc_xxx()), but there
is no particular reason about that [1].
To reduce confusing, standarding these to snd_soc_xxx() is sensible.

This patch adds asoc_xxx() macro to keep compatible for a while.
It will be removed if all drivers were switched to new style.

Link: https://lore.kernel.org/r/87h6td3hus.wl-kuninori.morimoto.gx@renesas.com [1]
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87fs3ks26i.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-25 14:16:13 +02:00
Richard Fitzgerald 47f56e38a1
ASoC: soc-card: Add storage for PCI SSID
Add members to struct snd_soc_card to store the PCI subsystem ID (SSID)
of the soundcard.

The PCI specification provides two registers to store a vendor-specific
SSID that can be read by drivers to uniquely identify a particular
"soundcard". This is defined in the PCI specification to distinguish
products that use the same silicon (and therefore have the same silicon
ID) so that product-specific differences can be applied.

PCI only defines 0xFFFF as an invalid value. 0x0000 is not defined as
invalid. So the usual pattern of zero-filling the struct and then
assuming a zero value unset will not work. A flag is included to
indicate when the SSID information has been filled in.

Unlike DMI information, which has a free-format entirely up to the vendor,
the PCI SSID has a strictly defined format and a registry of vendor IDs.

It is usual in Windows drivers that the SSID is used as the sole identifier
of the specific end-product and the Windows driver contains tables mapping
that to information about the hardware setup, rather than using ACPI
properties.

This SSID is important information for ASoC components that need to apply
hardware-specific configuration on PCI-based systems.

As the SSID is a generic part of the PCI specification and is treated as
identifying the "soundcard", it is reasonable to include this information
in struct snd_soc_card, instead of components inventing their own custom
ways to pass this information around.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20230912163207.3498161-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-12 18:53:47 +01:00
Andy Shevchenko 428cc4106a
ASoC: soc.h: replace custom COUNT_ARGS() & CONCATENATE() implementations
Replace custom implementation of the macros from args.h.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/20230904111524.1740930-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-09-11 01:29:59 +01:00
Kuninori Morimoto bbde4a30c6
ASoC: soc-core.c: add snd_soc_copy_dai_args()
To use multi Component support, we need to check dai_args whether
Card could get DAI from args (CPU/Codec needs set dai_args on DAI driver).
If it could, we need to allocate dai_args for dlc.
This patch adds snd_soc_copy_dai_args() for it.

This is helper function for multi Component support.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87bkgko94e.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17 06:15:46 +01:00
Kuninori Morimoto 988bad5ee4
ASoC: soc-core.c: add snd_soc_dlc_use_cpu_as_platform()
Current snd_soc_is_matching_component() checks "of_node" or "dai_args".
Thus coping "of_node" only is not enough to use CPU as Platform.
This patch adds snd_soc_dlc_use_cpu_as_platform() and help it.

This is helper function for multi Component support.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87cz10o94k.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17 06:15:45 +01:00
Kuninori Morimoto 442ae56cf5
ASoC: soc-core.c: add snd_soc_get_dai_via_args()
To enable multi Component, Card driver need to get DAI via dai_args
to identify it. This patch adds snd_soc_get_dai_via_args() for it.

This is helper function for multi Component support.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87edlgo94p.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17 06:15:44 +01:00
Kuninori Morimoto 45655ec69c
ASoC: soc-core.c: enable multi Component
Current ASoC Card is using dlc (snd_soc_dai_link_component) to find
target DAI / Component to be used.
Current dlc has below 3 items to identify DAI / Component

	(a) name	for Component
	(b) of_node	for Component
	(c) dai_name	for DAI

(a) or (b) is used to identify target Component, and (c) is used
to identify DAI.

One of the biggest issue on it today is dlc needs "name matching"
for "dai_name" (c).

It was not a big deal when we were using platform_device, because we
could specify nessesary "dai_name" via its platform_data.

But we need to find DAI name pointer from whole registered datas and/or
each related driver somehow in case of DT, because we can't specify it.
Therefore, Card driver parses DT and assumes the DAI, and find its name
pointer. How to assume is based on each Component and/or Card.

Next biggest issue is Component node (a)/(b).

Basically, Component is registered when CPU/Codec driver was
probed() (X). Here, 1 Component is possible to have some DAIs.

	int xxx_probe(struct platform_device *pdev)
	{
		...
(X)		ret = devm_snd_soc_register_component(pdev->dev,
					&component_driver,
					&dai_driver, dai_driver_num);
		...
	}

The image of each data will be like below.
One note here is "driver" is included for later explanation.

	+-driver------+
	|+-component-+|
	||       dai0||
	||       dai1||
	||        ...||
	|+-----------+|
	+-------------+

The point here is 1 driver has 1 Component, because basically driver
calles snd_soc_register_component() (= X) once.

Here is the very basic CPU/Codec connection image.

	HW image			SW image
	+-- Board ------------+		+-card--------------------------+
	|+-----+      +------+|		|+-driver------+ +-driver------+|
	|| CPU | <--> |CodecA||		||+-component-+| |+-component-+||
	|+-----+      +------+|		|||        dai|<=>|dai        |||
	+---------------------+		||+-----------+| |+-----------+||
					|+-------------+ +-------------+|
					+-------------------------------+

It will be very complex if it has multi DAIs.
Here is intuitive easy to understandable HW / SW example.

	HW image			SW image
	+-- Board ---------------+	+-card--------------------------+
	|+--------+      +------+|	|+-driver------+ +-driver------+|
	|| CPU ch0| <--> |CodecA||	||+-component-+| |+-component-+||
	||        |      +------+|	|||    ch0 dai|<=>|dai        |||
	||        |      +------+|	|||           || |+-----------+||
	||     ch1| <--> |CodecB||	|||           || +-------------+|
	|+--------+      +------+|	|||           || +-driver------+|
	+------------------------+	|||           || |+-component-+||
					|||    ch1 dai|<=>|dai        |||
					||+-----------+| |+-----------+||
					|+-------------+ +-------------+|
					+-------------------------------+

It will be handled as multi interface as "one Card".

	card0,0: CPU-ch0 - CodecA
	card0,1: CPU-ch1 - CodecB
	    ^

But, here is the HW image example which will be more complex

	+-- Basic Board ---------+
	|+--------+      +------+|
	|| CPU ch0| <--> |CodecA||
	||     ch1| <-+  +------+|
	|+--------+   |          |
	+-------------|----------+
	+-- expansion board -----+
	|             |  +------+|
	|             +->|CodecB||
	|                +------+|
	+------------------------+

We intuitively think we want to handle these as "2 Sound Cards".

	card0,0: CPU-ch0 - CodecA
	card1,0: CPU-ch1 - CodecB
	    ^

But below image which we can register today doesn't allow it,
because the same Component will be connected to both Card0/1,
but it will be rejected by (Z).

	 +-driver------+
	 |+-component-+|
	+-card0-------------------------+
	|||           || +-driver------+|
	|||           || |+-component-+||
	|||    ch0 dai|<=>|dai        |||
	|||           || |+-----------+||
	|||           || +-------------+|
	+-------------------------------+
	 ||           ||
	+-card1-------------------------+
	|||           || +-driver------+|
	|||           || |+-component-+||
	|||    ch1 dai|<=>|dai        |||
	|||           || |+-----------+||
	|||           || +-------------+|
	+-------------------------------+
	 |+-----------+|
	 +-------------+

	static int soc_probe_component()
	{
		...
		if (component->card) {
(Z)			if (component->card != card) {
				dev_err(component->dev, ...);
				return -ENODEV;
			}
			return 0;
		}
		...
	}

So, how about to call snd_soc_register_component() (= X) multiple times
on probe() to avoid buplicated component->card limitation, to be like
below ?

	 +-driver------+
	+-card0-------------------------+
	||             | +-driver------+|
	||+-component-+| |+-component-+||
	|||    ch0 dai|<=>|dai        |||
	||+-----------+| |+-----------+||
	||             | +-------------+|
	+-------------------------------+
	 |             |
	+-card1-------------------------+
	||             | +-driver------+|
	||+-component-+| |+-component-+||
	|||    ch1 dai|<=>|dai        |||
	||+-----------+| |+-----------+||
	||             | +-------------+|
	+-------------------------------+
         +-------------+

Yes, looks good. But unfortunately it doesn't help us for now.
Let's see soc_component_to_node() and snd_soc_is_matching_component()

	static struct device_node
	*soc_component_to_node(struct snd_soc_component *component)
	{
		...
(A)		of_node = component->dev->of_node;
		...
	}

	static int snd_soc_is_matching_component(...)
	{
		...
(B)		if (dlc->of_node && component_of_node != dlc->of_node)
		...
	}

dlc checkes "of_node" to identify target component (B),
but this "of_node" came from component->dev (A) which is added
by snd_soc_register_component() (X) on probe().

This means we can have different "component->card", but have same
"component->dev" in this case.

Even though we calls snd_soc_register_component() (= X) multiple times,
all Components have same driver's dev, thus it is impossible to
identified the Component.
And if it was impossible to identify Component, it is impossible to
identify DAI on current implementation.

So, how to handle above complex HW image today is 2 patterns.
One is handles it as "1 big sound card".
The SW image is like below.

SW image
	+-card--------------------------+
	|+-driver------+ +-driver------+|
	||+-component-+| |+-component-+||
	|||    ch0 dai|<=>|dai        |||
	|||           || |+-----------+||
	|||           || +-------------+|
	|||           || +-driver------+|
	|||           || |+-component-+||
	|||    ch1 dai|<->|dai        |||
	||+-----------+| |+-----------+||
	|+-------------+ +-------------+|
	+-------------------------------+

But the problem is not intuitive.
We want to handle it as "2 Cards".

2nd pattern is like below.

SW image
	+-card0-------------------------+
	|+-driver------+ +-driver------+|
	||+-component-+| |+-component-+||
	|||    ch0 dai|<=>|dai        |||
	||+-----------+| |+-----------+||
	|+-------------+ +-------------+|
	+-------------------------------+

	+-card1-------------------------+
	|+-driver------+ +-driver------+|
	||+-component-+| |+-component-+||
	|||    ch1 dai|<=>|dai        |||
	||+-----------+| |+-----------+||
	|+-------------+ +-------------+|
	+-------------------------------+

It handles as "2 Cards", but CPU part needs to be probed as 2 drivers.
It is also not intuitive.

To solve this issue, we need to have multi Component support.

In current implementation, we need to identify Component first
to identify DAI, and it is using name matching to identify DAI.

But how about to be enable to directly identify DAI by unique way
instead of name matching ? In such case, we can directly identify DAI,
then it can identify Component from DAI.

For example Simple-Card / Audio-Graph-Card case, it is specifying DAI
via its node.

Simple-Card

	sound-dai = <&cpu-sound>;

Audio-Graph-Card

	dais = <&cpu-sound>;

If each CPU/Codec driver keeps this property when probing,
we can identify DAI directly from Card.
Being able to identify DAI directly means being able to identify its
Component as well even though Component has same dev (= B).

This patch adds new "dai_node" for it.

To keeping compatibility, it checks "dai_node" first if it has,
otherwise, use existing method (name matching).

Link: https://lore.kernel.org/r/87fskz5yrr.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87fs5wo94v.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-17 06:15:43 +01:00
Kuninori Morimoto 3c8b586185
ASoC: soc-core.c: add index on snd_soc_of_get_dai_name()
Current snd_soc_of_get_dai_name() doesn't accept index
for #sound-dai-cells. It is not useful for user.
This patch adds it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pm5qdgng.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-20 12:49:22 +01:00
Kuninori Morimoto 05722a0ce6
ASoC: soc-core.c: add snd_soc_{of_}get_dlc()
Current soc-core.c has snd_soc_{of_}get_dai_name() to get DAI name
for dlc (snd_soc_dai_link_component). It gets .dai_name, but we need
.of_node too. Therefor user need to arrange.

It will be more useful if it gets both .dai_name and .of_node.
This patch adds snd_soc_{of_}get_dlc() for it, and existing functions
uses it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r0q6dgnm.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-20 12:49:21 +01:00
Mark Brown a11e6515b0
ASoC: add new trigger ordering method
Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

This patch-set adds new "trigger" starting/stopping method.
2023-06-13 17:39:51 +01:00
Kuninori Morimoto 099770e2da
ASoC: remove old trigger ordering method
All drivers switch to use generic trigger ordering method.
Let's remove old method.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87legufnyy.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-13 12:11:23 +01:00
Kuninori Morimoto 356caf663d
ASoC: add new trigger ordering method
Current ASoC is assuming that trigger starting order is
Link -> Component -> DAI as default, and its reverse order for stopping.
But some Driver / Card want to reorder it for some reasons.
We have such flags, but is unbalance like below.

	struct snd_soc_component_driver	:: start_dma_last
	struct snd_soc_dai_link		:: stop_dma_first

We want to have more flexible, and more generic method.
This patch adds new snd_soc_trigger_order for start/stop at
component / DAI-link.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r0qmfnzx.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-13 12:11:19 +01:00
Bard Liao ac950278b0
ASoC: add N cpus to M codecs dai link support
Currently, ASoC supports dailinks with the following mappings:
1 cpu DAI to N codec DAIs
N cpu DAIs to N codec DAIs
But the mapping between N cpu DAIs and M codec DAIs is not supported.
The reason is that we didn't have a mechanism to map cpu and codec DAIs

This patch suggests a new snd_soc_dai_link_codec_ch_map struct in
struct snd_soc_dai_link{} which provides codec DAI to cpu DAI mapping
information used to implement N cpu DAIs to M codec DAIs
support.

When a dailink contains two or more cpu DAIs, we should set channel
number of cpus based on its channel mask. The new struct also provides
channel mask information for each codec and we can construct the cpu
channel mask by combining all codec channel masks which map to the cpu.

The N:M mapping is however restricted to the N <= M case due to physical
restrictions on a time-multiplexed bus such as I2S/TDM, AC97, SoundWire
and HDaudio.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20230607031242.1032060-2-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-13 12:11:15 +01:00
Kuninori Morimoto 1c943f60e8
ASoC: add snd_soc_get_stream_cpu()
We are using get_stream_cpu() to get CPU stream which cares
Codec2Codec. But it is static function for now, and we want to use it
from other files. This patch makes it global function.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87fs7cj9mf.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-06 16:57:31 +01:00
Kuninori Morimoto b9aa53fbee
ASoC: soc.h: remove snd_soc_compr_ops :: trigger
ASoC framework is not using trigger call-back for snd_soc_compr_ops.
This patch remove it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87edmwj9m1.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-06 16:57:30 +01:00
Kuninori Morimoto d2a4e0d740
ASoC: soc-utils.c: add asoc_dummy_dlc
ASoC uses dummy Component, sharing snd_soc_dai_link_component
for it is better idea. This patch adds it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com
Link: https://lore.kernel.org/r/87a5yy0zyk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org
2023-05-08 08:47:05 +09:00
Kuninori Morimoto 38e42f6d6c
ASoC: expand snd_soc_dpcm_mutex_lock/unlock()
soc-pcm.c has snd_soc_dpcm_mutex_lock/unlock(),
but other files can't use it because it is static function.

It requests snd_soc_pcm_runtime as parameter (A), but sometimes we
want to use it by snd_soc_card (B).

(A)	static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd)
	{
		mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
	}			   ^^^^^^^^^

(B)	mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass);
			   ^^^^

We want to use it with both "rtd" and "card" for dapm lock/unlock.
To enable it, this patch uses _Generic macro.

This patch makes snd_soc_dpcm_mutex_{un}lock() global function, and use it on
each files.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87bkk1x3ud.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-17 12:57:25 +01:00
Kuninori Morimoto 4a778bdc7a
ASoC: expand snd_soc_dapm_mutex_lock/unlock()
soc.h has snd_soc_dapm_mutex_lock/unlock() definition and
many drivers are using it, but soc-dapm.c is not.

1st reason is snd_soc_dapm_mutex_lock/unlock() requests
snd_soc_dapm_context pointer as parameter (A), but sometimes soc-dapm.c
needs to use snd_soc_card (B).

(A)	static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)
	{
		mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
	}			   ^^^^^^^^^^

(B)	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
			   ^^^^

2nd reason is it want to use SND_SOC_DAPM_CLASS_INIT for mutex_lock_nested(),
but helper is using _RUNTIME (A).

The conclusion is we want to use "dapm vs card" and "_RUNTIME vs _INIT"
for dapm lock/unlock. To enable this selfish request, this patch uses
_Generic macro. We can use snd_soc_dapm_mutex_lock/unlock() for both
dapm and card case.

	snd_soc_dapm_mutex_lock(dapm);	snd_soc_dapm_mutex_unlock(dapm);
	snd_soc_dapm_mutex_lock(card);	snd_soc_dapm_mutex_unlock(card);

Current soc-dapm.c is using both mutex_lock() and mutex_lock_nested().
This patch handles mutex_lock() as mutex_lock_nested(..., 0),
in other words, handles below as same.

	mutex_lock(&card->dapm_mutex);
	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);

Because people might misunderstand that _init() is mutex initialization,
this patch renames _INIT to _ROOT and adds new
snd_soc_dapm_mutex_lock_root() for it.

This patch also moves snd_soc_dapm_subclass definition from soc-dapm.h
to soc.h to keep related code together.

Because very complex soc.h vs soc-dapm.h relationship,
it is difficult/impossible to define these helper into soc-dapm.h.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87cz4hx3v0.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-17 12:57:24 +01:00
Kuninori Morimoto 1ea63f29c2
ASoC: soc.h: remove unused params/num_params
No drivers are using params/num_params any more.
Let's remove these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87iledc2ke.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-05 12:16:39 +01:00
Kuninori Morimoto 7ddc7f91be
ASoC: soc.h: clarify Codec2Codec params
snd_soc_dai_link has params/num_params, but it is unclear that
params for what. This patch clarify it is params for Codec2Codec.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o7o5c2lk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-05 12:16:36 +01:00
Kuninori Morimoto ffaf886e24
ASoC: soc-core.c: add snd_soc_add_pcm_runtimes()
Current ASoC supports snd_soc_add_pcm_runtime(), but user need to
call it one-by-one if it has multi dai_links.
This patch adds snd_soc_add_pcm_runtimes() which supports multi
dai_links.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87h6u76nhq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-03-28 01:26:03 +01:00
Kuninori Morimoto 2e5f86174e
ASoC: soc.h: add snd_soc_card_is_instantiated() helper
ASoC framework/driver checks whether card was instantiated every
where. Then, it should check card pointer too in such case.
This patch adds snd_soc_card_is_instantiated() for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/875ycnfoqp.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-01-31 11:04:53 +00:00
Kuninori Morimoto 3289dc026a
ASoC: soc.h: use array instead of playback/capture_widget
snd_soc_pcm_runtime has playback/capture_widget for Codec2Coddec.
The naming is unclear.
This patch names it as c2c_widget and uses array.

	struct snd_soc_pcm_runtime {
		...
=>		struct snd_soc_dapm_widget *playback_widget;
=>		struct snd_soc_dapm_widget *capture_widget;
		...
	}

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pmfqv9mk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-20 12:19:32 +01:00
Kuninori Morimoto a26ec2acb2
ASoC: soc.h: use defined number instead of direct number
snd_soc_pcm_runtime has dpcm for Playback/Capture, but it is defined
directly "2". It should use defined number.

	struct snd_soc_pcm_runtime {
		...
=>		struct snd_soc_dpcm_runtime dpcm[2];
		...
	}

This patch fixup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r106v9mv.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-20 12:19:31 +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
Srinivas Kandagatla 26bdcc4ba1
ASoC: core: remove setting platform_max in kcontrol macros
platform_max should not be set by the driver, its intended for machine drivers
or DT to override the max value for platform specific reasons.

So remove setting this from Kcontrol macros.

Setting this to max in these macros would limit the range when min
value is less then zero.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20220816172129.6661-1-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-17 13:00:30 +01:00
Uwe Kleine-König 1892a99188
ASoC: core: Make snd_soc_unregister_card() return void
The function snd_soc_unregister_card() returned 0 unconditionally and most
callers don't care to check the return value. Make it return void and
adapt the callers that didn't ignore the return value before.

This is a preparation for making platform remove callbacks return void.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20220621145834.198519-1-u.kleine-koenig@pengutronix.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-06-22 13:39:34 +01:00
Charles Keepax 6b183919f7
ASoC: core: Add new SOC_DOUBLE_SX_TLV macro
Currently macros only exist for SX style (implicit sign bit 2's
compliment) volume controls where the volumes for left and right
are in separate registers. Some future Cirrus devices will have
both volumes in the same register, as such add a new macro to
support this.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220621102041.1713504-4-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-06-21 13:15:35 +01:00
Mark Brown 14cc584912
ASoC: Merge fixes
Required for more changes for the ops.
2022-06-14 11:25:45 +01:00
Amadeusz Sławiński 81eef68f3b
ASoC: Remove unused hw_write_t type
Commit 81da8a0b79 ("ASoC: remove codec hw_write/control_data") removed
use of hw_write_t in struct snd_soc_codec, but it left type definition.
Fully clean it up.

Fixes: 81da8a0b79 ("ASoC: remove codec hw_write/control_data")
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20220610124420.4160986-1-amadeuszx.slawinski@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-06-10 17:52:00 +01:00
Martin Povišer df4d27b19b
ASoC: Introduce 'fixup_controls' card method
The new method is called just before the card is registered, providing
an opportune time for machine-level drivers to do some final controls
amending: deactivating individual controls or obtaining control
references for later use.

Some controls can be created by DAPM after 'late_probe' has been called,
hence the need for this new method.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
Link: https://lore.kernel.org/r/20220606191910.16580-5-povik+lin@cutebit.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-06-10 13:32:20 +01:00
Charles Keepax 64c917d1cf
ASoC: core: Correct spelling fliped -> flipped
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220513090532.1450944-1-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-05-16 12:58:39 +01:00
Richard Fitzgerald 5349c0c93d
ASoC: soc.h: Add SOC_SINGLE_S_EXT_TLV macro
Add a SOC_SINGLE_S_EXT_TLV macro as a convenience wrapper
around SOC_DOUBLE_R_S_EXT_TLV for mono volume controls.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220425125012.3044919-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-25 13:58:22 +01:00
Simon Trimmer cf51406ccb
ASoC: soc.h: Introduce SOC_DOUBLE_R_S_EXT_TLV() macro
A straightforward extension of the SOC_DOUBLE_R_S_TLV() macro that
allows the get and put functions to be customised.

Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220425125012.3044919-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-25 13:58:21 +01:00
Richard Fitzgerald 1ef34dd2b9
ASoC: soc-utils: Add helper to calculate BCLK from TDM info
Add a helper function snd_soc_tdm_params_to_bclk() to calculate
the bclk from params info and the tdm sots configuration.

When using a TDM frame of N slots of width W bits:

   bclk = sample_rate * N * W

As a convenience to simplify calling code, if the slot count or
slot width are 0 a value will be obtained from the params. This
allows calling code to use this one function to handle cases of
TDM where only one parameter is fixed, or I2S where the slot width
is fixed (for example to set a 32-bit slot for 24-bit samples).

Also as a convenience the slot count can optionally be rounded up
to a multiple. This is mainly useful for I2S systems, since I2S has
two phases of LRCLK the number of slots is always a multiple of 2.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220405135419.1230088-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-05 18:27:55 +01:00
Richard Fitzgerald bc8cb02976
ASoC: soc.h: Add SOC_SINGLE_S_TLV() macro
Add a convenience macro for defining a single (mono) TLV control
with a signed value. This can already be done by using
SOC_DOUBLE_R_S_TLV() with the same address for left and right
registers, but a dedicated macro is more readable.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220405135419.1230088-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-05 18:27:54 +01:00
Martin Povišer 900dedd7e4
ASoC: Introduce snd_soc_of_get_dai_link_cpus
This function is an analogue of snd_soc_of_get_dai_link_codecs to help
machine drivers read CPU DAI lists from devicetrees.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
Link: https://lore.kernel.org/r/20220331000449.41062-5-povik+lin@cutebit.org
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-05 10:23:08 +01:00
Stephan Gerhold 3d4641a42c
ASoC: core: Add snd_soc_of_parse_pin_switches() from simple-card-utils
The ASoC core already has several helpers to parse card properties
from the device tree. Move the parsing code for "pin-switches" from
simple-card-utils to a shared snd_soc_of_parse_pin_switches() function
so other drivers can also use it to set up pin switches configured in
the device tree.

Cc: Paul Cercueil <paul@crapouillou.net>
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Link: https://lore.kernel.org/r/20211214142049.20422-2-stephan@gerhold.net
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-23 18:34:23 +00:00