aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-04-08 16:22:10 -0400
committerMark Brown <broonie@linaro.org>2014-04-08 16:22:10 -0400
commit30659894f379452d3ebaa00d44b118f1237fbcaf (patch)
tree5678c7261d7fc830b3e7d8708417f57f10e45932
parente9b433cf86ff4a314f3992fe0b7a9fe26cc5072a (diff)
parentc159a85013afbb8283f0c7272812952e04d5c3a1 (diff)
Merge tag 'asoc-v3.15-4' into asoc-linus
ASoC: Final updates for v3.15 merge window A few more updates from last week - use of the tdm_slot mapping from Xiubo plus a few smaller fixes and cleanups. # gpg: Signature made Mon 31 Mar 2014 10:49:42 BST using RSA key ID 7EA229BD # gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>" # gpg: aka "Mark Brown <broonie@debian.org>" # gpg: aka "Mark Brown <broonie@kernel.org>" # gpg: aka "Mark Brown <broonie@tardis.ed.ac.uk>" # gpg: aka "Mark Brown <broonie@linaro.org>" # gpg: aka "Mark Brown <Mark.Brown@linaro.org>"
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.txt15
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.txt42
-rw-r--r--arch/arm/mach-shmobile/board-bockw.c16
-rw-r--r--include/sound/soc-dai.h2
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/fsl/fsl_esai.c2
-rw-r--r--sound/soc/fsl/fsl_utils.c27
-rw-r--r--sound/soc/fsl/fsl_utils.h4
-rw-r--r--sound/soc/fsl/imx-ssi.c2
-rw-r--r--sound/soc/generic/simple-card.c220
-rw-r--r--sound/soc/sh/rcar/src.c18
-rw-r--r--sound/soc/soc-core.c17
-rw-r--r--sound/soc/tegra/tegra20_ac97.c15
-rw-r--r--sound/soc/tegra/tegra20_ac97.h1
-rw-r--r--sound/soc/tegra/tegra_wm9712.c17
15 files changed, 271 insertions, 129 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
index 7c6d33f29796..a44e9179faf5 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
@@ -7,14 +7,23 @@ Required properties:
7 required register is 7 required register is
8 SRU/ADG/SSI if generation1 8 SRU/ADG/SSI if generation1
9 SRU/ADG/SSIU/SSI if generation2 9 SRU/ADG/SSIU/SSI if generation2
10- rcar_sound,ssi : SSI subnode 10- rcar_sound,ssi : Should contain SSI feature.
11- rcar_sound,scu : SCU subnode 11 The number of SSI subnode should be same as HW.
12- rcar_sound,dai : DAI subnode 12 see below for detail.
13- rcar_sound,src : Should contain SRC feature.
14 The number of SRC subnode should be same as HW.
15 see below for detail.
16- rcar_sound,dai : DAI contents.
17 The number of DAI subnode should be same as HW.
18 see below for detail.
13 19
14SSI subnode properties: 20SSI subnode properties:
15- interrupts : Should contain SSI interrupt for PIO transfer 21- interrupts : Should contain SSI interrupt for PIO transfer
16- shared-pin : if shared clock pin 22- shared-pin : if shared clock pin
17 23
24SRC subnode properties:
25no properties at this point
26
18DAI subnode properties: 27DAI subnode properties:
19- playback : list of playback modules 28- playback : list of playback modules
20- capture : list of capture modules 29- capture : list of capture modules
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index 881914b139ca..131aa2ad7f1a 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -23,6 +23,11 @@ Optional properties:
23 23
24Required subnodes: 24Required subnodes:
25 25
26- simple-audio-card,dai-link : container for the CPU and CODEC sub-nodes
27 This container may be omitted when the
28 card has only one DAI link.
29 See the examples.
30
26- simple-audio-card,cpu : CPU sub-node 31- simple-audio-card,cpu : CPU sub-node
27- simple-audio-card,codec : CODEC sub-node 32- simple-audio-card,codec : CODEC sub-node
28 33
@@ -49,7 +54,7 @@ Note:
49 CPU and CODEC sides as we need to keep the settings identical for both ends 54 CPU and CODEC sides as we need to keep the settings identical for both ends
50 of the link. 55 of the link.
51 56
52Example: 57Example 1 - single DAI link:
53 58
54sound { 59sound {
55 compatible = "simple-audio-card"; 60 compatible = "simple-audio-card";
@@ -94,3 +99,38 @@ sh_fsi2: sh_fsi2@ec230000 {
94 interrupt-parent = <&gic>; 99 interrupt-parent = <&gic>;
95 interrupts = <0 146 0x4>; 100 interrupts = <0 146 0x4>;
96}; 101};
102
103Example 2 - many DAI links:
104
105sound {
106 compatible = "simple-audio-card";
107 simple-audio-card,name = "Cubox Audio";
108 simple-audio-card,format = "i2s";
109
110 simple-audio-card,dai-link@0 { /* I2S - HDMI */
111 simple-audio-card,cpu {
112 sound-dai = <&audio1 0>;
113 };
114 simple-audio-card,codec {
115 sound-dai = <&tda998x 0>;
116 };
117 };
118
119 simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */
120 simple-audio-card,cpu {
121 sound-dai = <&audio1 1>;
122 };
123 simple-audio-card,codec {
124 sound-dai = <&tda998x 1>;
125 };
126 };
127
128 simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */
129 simple-audio-card,cpu {
130 sound-dai = <&audio1 1>;
131 };
132 simple-audio-card,codec {
133 sound-dai = <&spdif_codec>;
134 };
135 };
136};
diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c
index c475220545f2..74c27d9d6900 100644
--- a/arch/arm/mach-shmobile/board-bockw.c
+++ b/arch/arm/mach-shmobile/board-bockw.c
@@ -429,14 +429,12 @@ static struct asoc_simple_card_info rsnd_card_info[] = {
429 .card = "SSI56-AK4643", 429 .card = "SSI56-AK4643",
430 .codec = "ak4642-codec.0-0012", 430 .codec = "ak4642-codec.0-0012",
431 .platform = "rcar_sound", 431 .platform = "rcar_sound",
432 .daifmt = SND_SOC_DAIFMT_LEFT_J, 432 .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
433 .cpu_dai = { 433 .cpu_dai = {
434 .name = "rsnd-dai.0", 434 .name = "rsnd-dai.0",
435 .fmt = SND_SOC_DAIFMT_CBS_CFS,
436 }, 435 },
437 .codec_dai = { 436 .codec_dai = {
438 .name = "ak4642-hifi", 437 .name = "ak4642-hifi",
439 .fmt = SND_SOC_DAIFMT_CBM_CFM,
440 .sysclk = 11289600, 438 .sysclk = 11289600,
441 }, 439 },
442 }, 440 },
@@ -446,10 +444,9 @@ static struct asoc_simple_card_info rsnd_card_info[] = {
446 .card = "SSI3-AK4554(playback)", 444 .card = "SSI3-AK4554(playback)",
447 .codec = "ak4554-adc-dac.0", 445 .codec = "ak4554-adc-dac.0",
448 .platform = "rcar_sound", 446 .platform = "rcar_sound",
447 .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J,
449 .cpu_dai = { 448 .cpu_dai = {
450 .name = "rsnd-dai.1", 449 .name = "rsnd-dai.1",
451 .fmt = SND_SOC_DAIFMT_CBM_CFM |
452 SND_SOC_DAIFMT_RIGHT_J,
453 }, 450 },
454 .codec_dai = { 451 .codec_dai = {
455 .name = "ak4554-hifi", 452 .name = "ak4554-hifi",
@@ -461,10 +458,9 @@ static struct asoc_simple_card_info rsnd_card_info[] = {
461 .card = "SSI4-AK4554(capture)", 458 .card = "SSI4-AK4554(capture)",
462 .codec = "ak4554-adc-dac.0", 459 .codec = "ak4554-adc-dac.0",
463 .platform = "rcar_sound", 460 .platform = "rcar_sound",
461 .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J,
464 .cpu_dai = { 462 .cpu_dai = {
465 .name = "rsnd-dai.2", 463 .name = "rsnd-dai.2",
466 .fmt = SND_SOC_DAIFMT_CBM_CFM |
467 SND_SOC_DAIFMT_LEFT_J,
468 }, 464 },
469 .codec_dai = { 465 .codec_dai = {
470 .name = "ak4554-hifi", 466 .name = "ak4554-hifi",
@@ -476,10 +472,9 @@ static struct asoc_simple_card_info rsnd_card_info[] = {
476 .card = "SSI7-AK4554(playback)", 472 .card = "SSI7-AK4554(playback)",
477 .codec = "ak4554-adc-dac.1", 473 .codec = "ak4554-adc-dac.1",
478 .platform = "rcar_sound", 474 .platform = "rcar_sound",
475 .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J,
479 .cpu_dai = { 476 .cpu_dai = {
480 .name = "rsnd-dai.3", 477 .name = "rsnd-dai.3",
481 .fmt = SND_SOC_DAIFMT_CBM_CFM |
482 SND_SOC_DAIFMT_RIGHT_J,
483 }, 478 },
484 .codec_dai = { 479 .codec_dai = {
485 .name = "ak4554-hifi", 480 .name = "ak4554-hifi",
@@ -491,10 +486,9 @@ static struct asoc_simple_card_info rsnd_card_info[] = {
491 .card = "SSI8-AK4554(capture)", 486 .card = "SSI8-AK4554(capture)",
492 .codec = "ak4554-adc-dac.1", 487 .codec = "ak4554-adc-dac.1",
493 .platform = "rcar_sound", 488 .platform = "rcar_sound",
489 .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J,
494 .cpu_dai = { 490 .cpu_dai = {
495 .name = "rsnd-dai.4", 491 .name = "rsnd-dai.4",
496 .fmt = SND_SOC_DAIFMT_CBM_CFM |
497 SND_SOC_DAIFMT_LEFT_J,
498 }, 492 },
499 .codec_dai = { 493 .codec_dai = {
500 .name = "ak4554-hifi", 494 .name = "ak4554-hifi",
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 2f66d5e8cd15..fad76769f153 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -142,7 +142,7 @@ struct snd_soc_dai_ops {
142 * Called by soc_card drivers, normally in their hw_params. 142 * Called by soc_card drivers, normally in their hw_params.
143 */ 143 */
144 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); 144 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
145 int (*of_xlate_tdm_slot_mask)(unsigned int slots, 145 int (*xlate_tdm_slot_mask)(unsigned int slots,
146 unsigned int *tx_mask, unsigned int *rx_mask); 146 unsigned int *tx_mask, unsigned int *rx_mask);
147 int (*set_tdm_slot)(struct snd_soc_dai *dai, 147 int (*set_tdm_slot)(struct snd_soc_dai *dai,
148 unsigned int tx_mask, unsigned int rx_mask, 148 unsigned int tx_mask, unsigned int rx_mask,
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 597962ec28fa..338a91642471 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -13,6 +13,7 @@ config SND_SOC_FSL_SPDIF
13config SND_SOC_FSL_ESAI 13config SND_SOC_FSL_ESAI
14 tristate 14 tristate
15 select REGMAP_MMIO 15 select REGMAP_MMIO
16 select SND_SOC_FSL_UTILS
16 17
17config SND_SOC_FSL_UTILS 18config SND_SOC_FSL_UTILS
18 tristate 19 tristate
@@ -120,6 +121,7 @@ if SND_IMX_SOC
120 121
121config SND_SOC_IMX_SSI 122config SND_SOC_IMX_SSI
122 tristate 123 tristate
124 select SND_SOC_FSL_UTILS
123 125
124config SND_SOC_IMX_PCM_FIQ 126config SND_SOC_IMX_PCM_FIQ
125 tristate 127 tristate
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 0ba37005ab04..c8e5db1414d7 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -18,6 +18,7 @@
18 18
19#include "fsl_esai.h" 19#include "fsl_esai.h"
20#include "imx-pcm.h" 20#include "imx-pcm.h"
21#include "fsl_utils.h"
21 22
22#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 23#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
23#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 24#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
@@ -581,6 +582,7 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = {
581 .hw_params = fsl_esai_hw_params, 582 .hw_params = fsl_esai_hw_params,
582 .set_sysclk = fsl_esai_set_dai_sysclk, 583 .set_sysclk = fsl_esai_set_dai_sysclk,
583 .set_fmt = fsl_esai_set_dai_fmt, 584 .set_fmt = fsl_esai_set_dai_fmt,
585 .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask,
584 .set_tdm_slot = fsl_esai_set_dai_tdm_slot, 586 .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
585}; 587};
586 588
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c
index b9e42b503a37..2ac7755da876 100644
--- a/sound/soc/fsl/fsl_utils.c
+++ b/sound/soc/fsl/fsl_utils.c
@@ -86,6 +86,33 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
86} 86}
87EXPORT_SYMBOL(fsl_asoc_get_dma_channel); 87EXPORT_SYMBOL(fsl_asoc_get_dma_channel);
88 88
89/**
90 * fsl_asoc_xlate_tdm_slot_mask - generate TDM slot TX/RX mask.
91 *
92 * @slots: Number of slots in use.
93 * @tx_mask: bitmask representing active TX slots.
94 * @rx_mask: bitmask representing active RX slots.
95 *
96 * This function used to generate the TDM slot TX/RX mask. And the TX/RX
97 * mask will use a 0 bit for an active slot as default, and the default
98 * active bits are at the LSB of the mask value.
99 */
100int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots,
101 unsigned int *tx_mask,
102 unsigned int *rx_mask)
103{
104 if (!slots)
105 return -EINVAL;
106
107 if (tx_mask)
108 *tx_mask = ~((1 << slots) - 1);
109 if (rx_mask)
110 *rx_mask = ~((1 << slots) - 1);
111
112 return 0;
113}
114EXPORT_SYMBOL_GPL(fsl_asoc_xlate_tdm_slot_mask);
115
89MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 116MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
90MODULE_DESCRIPTION("Freescale ASoC utility code"); 117MODULE_DESCRIPTION("Freescale ASoC utility code");
91MODULE_LICENSE("GPL v2"); 118MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h
index b2951126527c..df535db40313 100644
--- a/sound/soc/fsl/fsl_utils.h
+++ b/sound/soc/fsl/fsl_utils.h
@@ -22,5 +22,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name,
22 struct snd_soc_dai_link *dai, 22 struct snd_soc_dai_link *dai,
23 unsigned int *dma_channel_id, 23 unsigned int *dma_channel_id,
24 unsigned int *dma_id); 24 unsigned int *dma_id);
25 25int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots,
26 unsigned int *tx_mask,
27 unsigned int *rx_mask);
26#endif /* _FSL_UTILS_H */ 28#endif /* _FSL_UTILS_H */
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index df552fa1aa65..ab2fdd76b693 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -50,6 +50,7 @@
50#include <linux/platform_data/asoc-imx-ssi.h> 50#include <linux/platform_data/asoc-imx-ssi.h>
51 51
52#include "imx-ssi.h" 52#include "imx-ssi.h"
53#include "fsl_utils.h"
53 54
54#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV) 55#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
55 56
@@ -339,6 +340,7 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
339 .set_fmt = imx_ssi_set_dai_fmt, 340 .set_fmt = imx_ssi_set_dai_fmt,
340 .set_clkdiv = imx_ssi_set_dai_clkdiv, 341 .set_clkdiv = imx_ssi_set_dai_clkdiv,
341 .set_sysclk = imx_ssi_set_dai_sysclk, 342 .set_sysclk = imx_ssi_set_dai_sysclk,
343 .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask,
342 .set_tdm_slot = imx_ssi_set_dai_tdm_slot, 344 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
343 .trigger = imx_ssi_trigger, 345 .trigger = imx_ssi_trigger,
344}; 346};
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 2ee8ed56bcf1..21f1ccbdf582 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -20,9 +20,11 @@
20 20
21struct simple_card_data { 21struct simple_card_data {
22 struct snd_soc_card snd_card; 22 struct snd_soc_card snd_card;
23 struct asoc_simple_dai cpu_dai; 23 struct simple_dai_props {
24 struct asoc_simple_dai codec_dai; 24 struct asoc_simple_dai cpu_dai;
25 struct snd_soc_dai_link snd_link; 25 struct asoc_simple_dai codec_dai;
26 } *dai_props;
27 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
26}; 28};
27 29
28static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 30static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
@@ -68,13 +70,16 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
68 snd_soc_card_get_drvdata(rtd->card); 70 snd_soc_card_get_drvdata(rtd->card);
69 struct snd_soc_dai *codec = rtd->codec_dai; 71 struct snd_soc_dai *codec = rtd->codec_dai;
70 struct snd_soc_dai *cpu = rtd->cpu_dai; 72 struct snd_soc_dai *cpu = rtd->cpu_dai;
71 int ret; 73 struct simple_dai_props *dai_props;
74 int num, ret;
72 75
73 ret = __asoc_simple_card_dai_init(codec, &priv->codec_dai); 76 num = rtd - rtd->card->rtd;
77 dai_props = &priv->dai_props[num];
78 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
74 if (ret < 0) 79 if (ret < 0)
75 return ret; 80 return ret;
76 81
77 ret = __asoc_simple_card_dai_init(cpu, &priv->cpu_dai); 82 ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai);
78 if (ret < 0) 83 if (ret < 0)
79 return ret; 84 return ret;
80 85
@@ -146,13 +151,47 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
146 return 0; 151 return 0;
147} 152}
148 153
154static int simple_card_cpu_codec_of(struct device_node *node,
155 int daifmt,
156 struct snd_soc_dai_link *dai_link,
157 struct simple_dai_props *dai_props)
158{
159 struct device_node *np;
160 int ret;
161
162 /* CPU sub-node */
163 ret = -EINVAL;
164 np = of_get_child_by_name(node, "simple-audio-card,cpu");
165 if (np) {
166 ret = asoc_simple_card_sub_parse_of(np, daifmt,
167 &dai_props->cpu_dai,
168 &dai_link->cpu_of_node,
169 &dai_link->cpu_dai_name);
170 of_node_put(np);
171 }
172 if (ret < 0)
173 return ret;
174
175 /* CODEC sub-node */
176 ret = -EINVAL;
177 np = of_get_child_by_name(node, "simple-audio-card,codec");
178 if (np) {
179 ret = asoc_simple_card_sub_parse_of(np, daifmt,
180 &dai_props->codec_dai,
181 &dai_link->codec_of_node,
182 &dai_link->codec_dai_name);
183 of_node_put(np);
184 }
185 return ret;
186}
187
149static int asoc_simple_card_parse_of(struct device_node *node, 188static int asoc_simple_card_parse_of(struct device_node *node,
150 struct simple_card_data *priv, 189 struct simple_card_data *priv,
151 struct device *dev) 190 struct device *dev,
191 int multi)
152{ 192{
153 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 193 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
154 struct asoc_simple_dai *codec_dai = &priv->codec_dai; 194 struct simple_dai_props *dai_props = priv->dai_props;
155 struct asoc_simple_dai *cpu_dai = &priv->cpu_dai;
156 struct device_node *np; 195 struct device_node *np;
157 char *name; 196 char *name;
158 unsigned int daifmt; 197 unsigned int daifmt;
@@ -181,78 +220,71 @@ static int asoc_simple_card_parse_of(struct device_node *node,
181 return ret; 220 return ret;
182 } 221 }
183 222
184 /* CPU sub-node */ 223 /* loop on the DAI links */
185 ret = -EINVAL; 224 np = NULL;
186 np = of_get_child_by_name(node, "simple-audio-card,cpu"); 225 for (;;) {
187 if (np) { 226 if (multi) {
188 ret = asoc_simple_card_sub_parse_of(np, daifmt, 227 np = of_get_next_child(node, np);
189 cpu_dai, 228 if (!np)
190 &dai_link->cpu_of_node, 229 break;
191 &dai_link->cpu_dai_name); 230 }
192 of_node_put(np);
193 }
194 if (ret < 0)
195 return ret;
196 231
197 /* CODEC sub-node */ 232 ret = simple_card_cpu_codec_of(multi ? np : node,
198 ret = -EINVAL; 233 daifmt, dai_link, dai_props);
199 np = of_get_child_by_name(node, "simple-audio-card,codec"); 234 if (ret < 0)
200 if (np) { 235 goto err;
201 ret = asoc_simple_card_sub_parse_of(np, daifmt,
202 codec_dai,
203 &dai_link->codec_of_node,
204 &dai_link->codec_dai_name);
205 of_node_put(np);
206 }
207 if (ret < 0)
208 return ret;
209 236
210 /* 237 /*
211 * overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC 238 * overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC
212 * while the other bits should be identical unless buggy SW/HW design. 239 * while the other bits should be identical unless buggy SW/HW design.
213 */ 240 */
214 cpu_dai->fmt = codec_dai->fmt; 241 dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt;
242
243 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
244 ret = -EINVAL;
245 goto err;
246 }
247
248 /* simple-card assumes platform == cpu */
249 dai_link->platform_of_node = dai_link->cpu_of_node;
250
251 name = devm_kzalloc(dev,
252 strlen(dai_link->cpu_dai_name) +
253 strlen(dai_link->codec_dai_name) + 2,
254 GFP_KERNEL);
255 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
256 dai_link->codec_dai_name);
257 dai_link->name = dai_link->stream_name = name;
215 258
216 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) 259 if (!multi)
217 return -EINVAL; 260 break;
261
262 dai_link++;
263 dai_props++;
264 }
218 265
219 /* card name is created from CPU/CODEC dai name */ 266 /* card name is created from CPU/CODEC dai name */
220 name = devm_kzalloc(dev, 267 dai_link = priv->snd_card.dai_link;
221 strlen(dai_link->cpu_dai_name) +
222 strlen(dai_link->codec_dai_name) + 2,
223 GFP_KERNEL);
224 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
225 dai_link->codec_dai_name);
226 if (!priv->snd_card.name) 268 if (!priv->snd_card.name)
227 priv->snd_card.name = name; 269 priv->snd_card.name = dai_link->name;
228 dai_link->name = dai_link->stream_name = name;
229
230 /* simple-card assumes platform == cpu */
231 dai_link->platform_of_node = dai_link->cpu_of_node;
232 270
233 dev_dbg(dev, "card-name : %s\n", name); 271 dev_dbg(dev, "card-name : %s\n", priv->snd_card.name);
234 dev_dbg(dev, "platform : %04x\n", daifmt); 272 dev_dbg(dev, "platform : %04x\n", daifmt);
273 dai_props = priv->dai_props;
235 dev_dbg(dev, "cpu : %s / %04x / %d\n", 274 dev_dbg(dev, "cpu : %s / %04x / %d\n",
236 dai_link->cpu_dai_name, 275 dai_link->cpu_dai_name,
237 cpu_dai->fmt, 276 dai_props->cpu_dai.fmt,
238 cpu_dai->sysclk); 277 dai_props->cpu_dai.sysclk);
239 dev_dbg(dev, "codec : %s / %04x / %d\n", 278 dev_dbg(dev, "codec : %s / %04x / %d\n",
240 dai_link->codec_dai_name, 279 dai_link->codec_dai_name,
241 codec_dai->fmt, 280 dai_props->codec_dai.fmt,
242 codec_dai->sysclk); 281 dai_props->codec_dai.sysclk);
243
244 /*
245 * soc_bind_dai_link() will check cpu name
246 * after of_node matching if dai_link has cpu_dai_name.
247 * but, it will never match if name was created by fmt_single_name()
248 * remove cpu_dai_name to escape name matching.
249 * see
250 * fmt_single_name()
251 * fmt_multiple_name()
252 */
253 dai_link->cpu_dai_name = NULL;
254 282
255 return 0; 283 return 0;
284
285err:
286 of_node_put(np);
287 return ret;
256} 288}
257 289
258/* update the reference count of the devices nodes at end of probe */ 290/* update the reference count of the devices nodes at end of probe */
@@ -282,9 +314,21 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
282 struct snd_soc_dai_link *dai_link; 314 struct snd_soc_dai_link *dai_link;
283 struct device_node *np = pdev->dev.of_node; 315 struct device_node *np = pdev->dev.of_node;
284 struct device *dev = &pdev->dev; 316 struct device *dev = &pdev->dev;
285 int ret; 317 int num_links, multi, ret;
318
319 /* get the number of DAI links */
320 if (np && of_get_child_by_name(np, "simple-audio-card,dai-link")) {
321 num_links = of_get_child_count(np);
322 multi = 1;
323 } else {
324 num_links = 1;
325 multi = 0;
326 }
286 327
287 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 328 /* allocate the private data and the DAI link array */
329 priv = devm_kzalloc(dev,
330 sizeof(*priv) + sizeof(*dai_link) * num_links,
331 GFP_KERNEL);
288 if (!priv) 332 if (!priv)
289 return -ENOMEM; 333 return -ENOMEM;
290 334
@@ -293,18 +337,38 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
293 */ 337 */
294 priv->snd_card.owner = THIS_MODULE; 338 priv->snd_card.owner = THIS_MODULE;
295 priv->snd_card.dev = dev; 339 priv->snd_card.dev = dev;
296 dai_link = &priv->snd_link; 340 dai_link = priv->dai_link;
297 priv->snd_card.dai_link = dai_link; 341 priv->snd_card.dai_link = dai_link;
298 priv->snd_card.num_links = 1; 342 priv->snd_card.num_links = num_links;
343
344 /* get room for the other properties */
345 priv->dai_props = devm_kzalloc(dev,
346 sizeof(*priv->dai_props) * num_links,
347 GFP_KERNEL);
348 if (!priv->dai_props)
349 return -ENOMEM;
299 350
300 if (np && of_device_is_available(np)) { 351 if (np && of_device_is_available(np)) {
301 352
302 ret = asoc_simple_card_parse_of(np, priv, dev); 353 ret = asoc_simple_card_parse_of(np, priv, dev, multi);
303 if (ret < 0) { 354 if (ret < 0) {
304 if (ret != -EPROBE_DEFER) 355 if (ret != -EPROBE_DEFER)
305 dev_err(dev, "parse error %d\n", ret); 356 dev_err(dev, "parse error %d\n", ret);
306 goto err; 357 goto err;
307 } 358 }
359
360 /*
361 * soc_bind_dai_link() will check cpu name
362 * after of_node matching if dai_link has cpu_dai_name.
363 * but, it will never match if name was created by fmt_single_name()
364 * remove cpu_dai_name to escape name matching.
365 * see
366 * fmt_single_name()
367 * fmt_multiple_name()
368 */
369 if (num_links == 1)
370 dai_link->cpu_dai_name = NULL;
371
308 } else { 372 } else {
309 struct asoc_simple_card_info *cinfo; 373 struct asoc_simple_card_info *cinfo;
310 374
@@ -330,13 +394,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
330 dai_link->codec_name = cinfo->codec; 394 dai_link->codec_name = cinfo->codec;
331 dai_link->cpu_dai_name = cinfo->cpu_dai.name; 395 dai_link->cpu_dai_name = cinfo->cpu_dai.name;
332 dai_link->codec_dai_name = cinfo->codec_dai.name; 396 dai_link->codec_dai_name = cinfo->codec_dai.name;
333 memcpy(&priv->cpu_dai, &cinfo->cpu_dai, 397 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
334 sizeof(priv->cpu_dai)); 398 sizeof(priv->dai_props->cpu_dai));
335 memcpy(&priv->codec_dai, &cinfo->codec_dai, 399 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
336 sizeof(priv->codec_dai)); 400 sizeof(priv->dai_props->codec_dai));
337 401
338 priv->cpu_dai.fmt |= cinfo->daifmt; 402 priv->dai_props->cpu_dai.fmt |= cinfo->daifmt;
339 priv->codec_dai.fmt |= cinfo->daifmt; 403 priv->dai_props->codec_dai.fmt |= cinfo->daifmt;
340 } 404 }
341 405
342 /* 406 /*
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index eee75ebf961c..6232b7d307aa 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -182,16 +182,20 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
182 struct rsnd_dai_stream *io, 182 struct rsnd_dai_stream *io,
183 struct snd_pcm_runtime *runtime) 183 struct snd_pcm_runtime *runtime)
184{ 184{
185 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
185 struct rsnd_src *src; 186 struct rsnd_src *src;
186 unsigned int rate; 187 unsigned int rate = 0;
187 188
188 src = rsnd_mod_to_src(rsnd_io_to_mod_src(io)); 189 if (src_mod) {
190 src = rsnd_mod_to_src(src_mod);
191
192 /*
193 * return convert rate if SRC is used,
194 * otherwise, return runtime->rate as usual
195 */
196 rate = rsnd_src_convert_rate(src);
197 }
189 198
190 /*
191 * return convert rate if SRC is used,
192 * otherwise, return runtime->rate as usual
193 */
194 rate = rsnd_src_convert_rate(src);
195 if (!rate) 199 if (!rate)
196 rate = runtime->rate; 200 rate = runtime->rate;
197 201
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b322cf294d06..caebd6353112 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1253,7 +1253,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
1253 struct snd_soc_dai_link *dai_link = NULL; 1253 struct snd_soc_dai_link *dai_link = NULL;
1254 struct snd_soc_aux_dev *aux_dev = NULL; 1254 struct snd_soc_aux_dev *aux_dev = NULL;
1255 struct snd_soc_pcm_runtime *rtd; 1255 struct snd_soc_pcm_runtime *rtd;
1256 const char *temp, *name; 1256 const char *name;
1257 int ret = 0; 1257 int ret = 0;
1258 1258
1259 if (!dailess) { 1259 if (!dailess) {
@@ -1267,10 +1267,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1267 } 1267 }
1268 rtd->card = card; 1268 rtd->card = card;
1269 1269
1270 /* machine controls, routes and widgets are not prefixed */
1271 temp = codec->name_prefix;
1272 codec->name_prefix = NULL;
1273
1274 /* do machine specific initialization */ 1270 /* do machine specific initialization */
1275 if (!dailess && dai_link->init) 1271 if (!dailess && dai_link->init)
1276 ret = dai_link->init(rtd); 1272 ret = dai_link->init(rtd);
@@ -1280,7 +1276,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1280 dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); 1276 dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret);
1281 return ret; 1277 return ret;
1282 } 1278 }
1283 codec->name_prefix = temp;
1284 1279
1285 /* register the rtd device */ 1280 /* register the rtd device */
1286 rtd->codec = codec; 1281 rtd->codec = codec;
@@ -3625,14 +3620,14 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3625EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); 3620EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
3626 3621
3627/** 3622/**
3628 * snd_soc_of_xlate_tdm_slot - generate tx/rx slot mask. 3623 * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
3629 * @slots: Number of slots in use. 3624 * @slots: Number of slots in use.
3630 * @tx_mask: bitmask representing active TX slots. 3625 * @tx_mask: bitmask representing active TX slots.
3631 * @rx_mask: bitmask representing active RX slots. 3626 * @rx_mask: bitmask representing active RX slots.
3632 * 3627 *
3633 * Generates the TDM tx and rx slot default masks for DAI. 3628 * Generates the TDM tx and rx slot default masks for DAI.
3634 */ 3629 */
3635static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots, 3630static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
3636 unsigned int *tx_mask, 3631 unsigned int *tx_mask,
3637 unsigned int *rx_mask) 3632 unsigned int *rx_mask)
3638{ 3633{
@@ -3662,11 +3657,11 @@ static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots,
3662int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 3657int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
3663 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 3658 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
3664{ 3659{
3665 if (dai->driver && dai->driver->ops->of_xlate_tdm_slot_mask) 3660 if (dai->driver && dai->driver->ops->xlate_tdm_slot_mask)
3666 dai->driver->ops->of_xlate_tdm_slot_mask(slots, 3661 dai->driver->ops->xlate_tdm_slot_mask(slots,
3667 &tx_mask, &rx_mask); 3662 &tx_mask, &rx_mask);
3668 else 3663 else
3669 snd_soc_of_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); 3664 snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
3670 3665
3671 if (dai->driver && dai->driver->ops->set_tdm_slot) 3666 if (dai->driver && dai->driver->ops->set_tdm_slot)
3672 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, 3667 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 0a59e2383ef3..3b0fa12dbff7 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -37,7 +37,6 @@
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/dmaengine_pcm.h> 38#include <sound/dmaengine_pcm.h>
39 39
40#include "tegra_asoc_utils.h"
41#include "tegra20_ac97.h" 40#include "tegra20_ac97.h"
42 41
43#define DRV_NAME "tegra20-ac97" 42#define DRV_NAME "tegra20-ac97"
@@ -376,18 +375,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
376 ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 375 ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
377 ac97->playback_dma_data.maxburst = 4; 376 ac97->playback_dma_data.maxburst = 4;
378 377
379 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
380 if (ret)
381 goto err_clk_put;
382
383 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
384 if (ret)
385 goto err_asoc_utils_fini;
386
387 ret = clk_prepare_enable(ac97->clk_ac97); 378 ret = clk_prepare_enable(ac97->clk_ac97);
388 if (ret) { 379 if (ret) {
389 dev_err(&pdev->dev, "clk_enable failed: %d\n", ret); 380 dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
390 goto err_asoc_utils_fini; 381 goto err;
391 } 382 }
392 383
393 ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops); 384 ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops);
@@ -419,8 +410,6 @@ err_unregister_component:
419 snd_soc_unregister_component(&pdev->dev); 410 snd_soc_unregister_component(&pdev->dev);
420err_clk_disable_unprepare: 411err_clk_disable_unprepare:
421 clk_disable_unprepare(ac97->clk_ac97); 412 clk_disable_unprepare(ac97->clk_ac97);
422err_asoc_utils_fini:
423 tegra_asoc_utils_fini(&ac97->util_data);
424err_clk_put: 413err_clk_put:
425err: 414err:
426 snd_soc_set_ac97_ops(NULL); 415 snd_soc_set_ac97_ops(NULL);
@@ -434,8 +423,6 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
434 tegra_pcm_platform_unregister(&pdev->dev); 423 tegra_pcm_platform_unregister(&pdev->dev);
435 snd_soc_unregister_component(&pdev->dev); 424 snd_soc_unregister_component(&pdev->dev);
436 425
437 tegra_asoc_utils_fini(&ac97->util_data);
438
439 clk_disable_unprepare(ac97->clk_ac97); 426 clk_disable_unprepare(ac97->clk_ac97);
440 427
441 snd_soc_set_ac97_ops(NULL); 428 snd_soc_set_ac97_ops(NULL);
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
index 4acb3aaba29b..0a39d823edcb 100644
--- a/sound/soc/tegra/tegra20_ac97.h
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -90,6 +90,5 @@ struct tegra20_ac97 {
90 struct regmap *regmap; 90 struct regmap *regmap;
91 int reset_gpio; 91 int reset_gpio;
92 int sync_gpio; 92 int sync_gpio;
93 struct tegra_asoc_utils_data util_data;
94}; 93};
95#endif /* __TEGRA20_AC97_H__ */ 94#endif /* __TEGRA20_AC97_H__ */
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 45b57892b6a5..25a7f8211ecf 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -29,10 +29,13 @@
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31 31
32#include "tegra_asoc_utils.h"
33
32#define DRV_NAME "tegra-snd-wm9712" 34#define DRV_NAME "tegra-snd-wm9712"
33 35
34struct tegra_wm9712 { 36struct tegra_wm9712 {
35 struct platform_device *codec; 37 struct platform_device *codec;
38 struct tegra_asoc_utils_data util_data;
36}; 39};
37 40
38static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = { 41static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
@@ -118,15 +121,25 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev)
118 121
119 tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node; 122 tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node;
120 123
124 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
125 if (ret)
126 goto codec_unregister;
127
128 ret = tegra_asoc_utils_set_ac97_rate(&machine->util_data);
129 if (ret)
130 goto asoc_utils_fini;
131
121 ret = snd_soc_register_card(card); 132 ret = snd_soc_register_card(card);
122 if (ret) { 133 if (ret) {
123 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 134 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
124 ret); 135 ret);
125 goto codec_unregister; 136 goto asoc_utils_fini;
126 } 137 }
127 138
128 return 0; 139 return 0;
129 140
141asoc_utils_fini:
142 tegra_asoc_utils_fini(&machine->util_data);
130codec_unregister: 143codec_unregister:
131 platform_device_del(machine->codec); 144 platform_device_del(machine->codec);
132codec_put: 145codec_put:
@@ -141,6 +154,8 @@ static int tegra_wm9712_driver_remove(struct platform_device *pdev)
141 154
142 snd_soc_unregister_card(card); 155 snd_soc_unregister_card(card);
143 156
157 tegra_asoc_utils_fini(&machine->util_data);
158
144 platform_device_unregister(machine->codec); 159 platform_device_unregister(machine->codec);
145 160
146 return 0; 161 return 0;