summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2018-12-13 21:32:25 -0500
committerMark Brown <broonie@kernel.org>2018-12-14 06:47:04 -0500
commitae3cb5790906b5caf519f6f21792c30fb5ddf8db (patch)
tree1ee0b95b0eeb0b93279e7acf529798e95ae37c44 /sound
parent91a531e48b20677c1f820f3bbd4237abd8144919 (diff)
ASoC: audio-graph-card: merge audio-graph-scu-card
audio-graph-card and audio-graph-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card. We couldn't use normal sound and DPCM sound in same sound card by audio-graph-card. This patch merges both sound card into it. Now we can use both feature on same driver. audio-grap-card is now supporting .compatible = "audio-graph-scu-card". Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/generic/Kconfig1
-rw-r--r--sound/soc/generic/audio-graph-card.c366
2 files changed, 320 insertions, 47 deletions
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index fa5aff9c1041..5395782424b4 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -22,6 +22,7 @@ config SND_AUDIO_GRAPH_CARD
22 help 22 help
23 This option enables generic simple sound card support 23 This option enables generic simple sound card support
24 with OF-graph DT bindings. 24 with OF-graph DT bindings.
25 It also support DPCM of multi CPU single Codec ststem.
25 26
26config SND_AUDIO_GRAPH_SCU_CARD 27config SND_AUDIO_GRAPH_SCU_CARD
27 tristate "ASoC Audio Graph SCU sound card support" 28 tristate "ASoC Audio Graph SCU sound card support"
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 1da9532ef897..8ec09bc711f8 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -27,6 +27,8 @@ struct graph_card_data {
27 struct asoc_simple_dai *codec_dai; 27 struct asoc_simple_dai *codec_dai;
28 struct snd_soc_dai_link_component codecs; /* single codec */ 28 struct snd_soc_dai_link_component codecs; /* single codec */
29 struct snd_soc_dai_link_component platform; 29 struct snd_soc_dai_link_component platform;
30 struct asoc_simple_card_data adata;
31 struct snd_soc_codec_conf *codec_conf;
30 unsigned int mclk_fs; 32 unsigned int mclk_fs;
31 } *dai_props; 33 } *dai_props;
32 unsigned int mclk_fs; 34 unsigned int mclk_fs;
@@ -34,6 +36,8 @@ struct graph_card_data {
34 struct asoc_simple_jack mic_jack; 36 struct asoc_simple_jack mic_jack;
35 struct snd_soc_dai_link *dai_link; 37 struct snd_soc_dai_link *dai_link;
36 struct asoc_simple_dai *dais; 38 struct asoc_simple_dai *dais;
39 struct asoc_simple_card_data adata;
40 struct snd_soc_codec_conf *codec_conf;
37 struct gpio_desc *pa_gpio; 41 struct gpio_desc *pa_gpio;
38}; 42};
39 43
@@ -42,6 +46,8 @@ struct graph_card_data {
42#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev) 46#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
43#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i)) 47#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
44 48
49#define PREFIX "audio-graph-card,"
50
45static int asoc_graph_card_outdrv_event(struct snd_soc_dapm_widget *w, 51static int asoc_graph_card_outdrv_event(struct snd_soc_dapm_widget *w,
46 struct snd_kcontrol *kcontrol, 52 struct snd_kcontrol *kcontrol,
47 int event) 53 int event)
@@ -156,7 +162,140 @@ static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
156 return 0; 162 return 0;
157} 163}
158 164
159static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, 165static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
166 struct snd_pcm_hw_params *params)
167{
168 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
169 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
170
171 asoc_simple_card_convert_fixup(&dai_props->adata, params);
172
173 /* overwrite by top level adata if exist */
174 asoc_simple_card_convert_fixup(&priv->adata, params);
175
176 return 0;
177}
178
179static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep,
180 struct device_node *codec_ep,
181 struct graph_card_data *priv,
182 int *dai_idx, int link_idx,
183 int *conf_idx, int is_cpu)
184{
185 struct device *dev = graph_priv_to_dev(priv);
186 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx);
187 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx);
188 struct snd_soc_card *card = graph_priv_to_card(priv);
189 struct device_node *ep = is_cpu ? cpu_ep : codec_ep;
190 struct device_node *node = of_graph_get_port_parent(ep);
191 struct asoc_simple_dai *dai;
192 int ret;
193
194 dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec");
195
196 if (is_cpu) {
197 struct snd_soc_dai_link_component *codecs;
198
199 /* BE is dummy */
200 codecs = dai_link->codecs;
201 codecs->of_node = NULL;
202 codecs->dai_name = "snd-soc-dummy-dai";
203 codecs->name = "snd-soc-dummy";
204
205 /* FE settings */
206 dai_link->dynamic = 1;
207 dai_link->dpcm_merged_format = 1;
208
209 dai =
210 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
211
212 ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
213 if (ret)
214 return ret;
215
216 ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, dai);
217 if (ret < 0)
218 return ret;
219
220 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
221 "fe.%s",
222 dai_link->cpu_dai_name);
223 if (ret < 0)
224 return ret;
225
226 /* card->num_links includes Codec */
227 asoc_simple_card_canonicalize_cpu(dai_link,
228 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
229 } else {
230 struct snd_soc_codec_conf *cconf;
231
232 /* FE is dummy */
233 dai_link->cpu_of_node = NULL;
234 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
235 dai_link->cpu_name = "snd-soc-dummy";
236
237 /* BE settings */
238 dai_link->no_pcm = 1;
239 dai_link->be_hw_params_fixup = asoc_graph_card_be_hw_params_fixup;
240
241 dai =
242 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
243
244 cconf =
245 dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++];
246
247 ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
248 if (ret < 0)
249 return ret;
250
251 ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, dai);
252 if (ret < 0)
253 return ret;
254
255 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
256 "be.%s",
257 dai_link->codecs->dai_name);
258 if (ret < 0)
259 return ret;
260
261 /* check "prefix" from top node */
262 snd_soc_of_parse_audio_prefix(card, cconf,
263 dai_link->codecs->of_node,
264 "prefix");
265 /* check "prefix" from each node if top doesn't have */
266 if (!cconf->of_node)
267 snd_soc_of_parse_node_prefix(node, cconf,
268 dai_link->codecs->of_node,
269 PREFIX "prefix");
270 }
271
272 asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata);
273
274 ret = asoc_simple_card_of_parse_tdm(ep, dai);
275 if (ret)
276 return ret;
277
278 ret = asoc_simple_card_canonicalize_dailink(dai_link);
279 if (ret < 0)
280 return ret;
281
282 of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs);
283
284 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
285 NULL, &dai_link->dai_fmt);
286 if (ret < 0)
287 return ret;
288
289 dai_link->dpcm_playback = 1;
290 dai_link->dpcm_capture = 1;
291 dai_link->ops = &asoc_graph_card_ops;
292 dai_link->init = asoc_graph_card_dai_init;
293
294 return 0;
295}
296
297static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep,
298 struct device_node *codec_ep,
160 struct graph_card_data *priv, 299 struct graph_card_data *priv,
161 int *dai_idx, int link_idx) 300 int *dai_idx, int link_idx)
162{ 301{
@@ -165,10 +304,10 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
165 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); 304 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx);
166 struct asoc_simple_dai *cpu_dai; 305 struct asoc_simple_dai *cpu_dai;
167 struct asoc_simple_dai *codec_dai; 306 struct asoc_simple_dai *codec_dai;
168 struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL);
169 struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep);
170 int ret; 307 int ret;
171 308
309 dev_dbg(dev, "link_of\n");
310
172 cpu_dai = 311 cpu_dai =
173 dai_props->cpu_dai = &priv->dais[(*dai_idx)++]; 312 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
174 codec_dai = 313 codec_dai =
@@ -177,45 +316,45 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
177 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, 316 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
178 NULL, &dai_link->dai_fmt); 317 NULL, &dai_link->dai_fmt);
179 if (ret < 0) 318 if (ret < 0)
180 goto dai_link_of_err; 319 return ret;
181 320
182 of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); 321 of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs);
183 of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs); 322 of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs);
184 323
185 ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link); 324 ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
186 if (ret < 0) 325 if (ret < 0)
187 goto dai_link_of_err; 326 return ret;
188 327
189 ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link); 328 ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
190 if (ret < 0) 329 if (ret < 0)
191 goto dai_link_of_err; 330 return ret;
192 331
193 ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai); 332 ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai);
194 if (ret < 0) 333 if (ret < 0)
195 goto dai_link_of_err; 334 return ret;
196 335
197 ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai); 336 ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai);
198 if (ret < 0) 337 if (ret < 0)
199 goto dai_link_of_err; 338 return ret;
200 339
201 ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai); 340 ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
202 if (ret < 0) 341 if (ret < 0)
203 goto dai_link_of_err; 342 return ret;
204 343
205 ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai); 344 ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
206 if (ret < 0) 345 if (ret < 0)
207 goto dai_link_of_err; 346 return ret;
208 347
209 ret = asoc_simple_card_canonicalize_dailink(dai_link); 348 ret = asoc_simple_card_canonicalize_dailink(dai_link);
210 if (ret < 0) 349 if (ret < 0)
211 goto dai_link_of_err; 350 return ret;
212 351
213 ret = asoc_simple_card_set_dailink_name(dev, dai_link, 352 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
214 "%s-%s", 353 "%s-%s",
215 dai_link->cpu_dai_name, 354 dai_link->cpu_dai_name,
216 dai_link->codecs->dai_name); 355 dai_link->codecs->dai_name);
217 if (ret < 0) 356 if (ret < 0)
218 goto dai_link_of_err; 357 return ret;
219 358
220 dai_link->ops = &asoc_graph_card_ops; 359 dai_link->ops = &asoc_graph_card_ops;
221 dai_link->init = asoc_graph_card_dai_init; 360 dai_link->init = asoc_graph_card_dai_init;
@@ -223,11 +362,7 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
223 asoc_simple_card_canonicalize_cpu(dai_link, 362 asoc_simple_card_canonicalize_cpu(dai_link,
224 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1); 363 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
225 364
226dai_link_of_err: 365 return 0;
227 of_node_put(cpu_ep);
228 of_node_put(codec_ep);
229
230 return ret;
231} 366}
232 367
233static int asoc_graph_card_parse_of(struct graph_card_data *priv) 368static int asoc_graph_card_parse_of(struct graph_card_data *priv)
@@ -236,8 +371,14 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
236 struct device *dev = graph_priv_to_dev(priv); 371 struct device *dev = graph_priv_to_dev(priv);
237 struct snd_soc_card *card = graph_priv_to_card(priv); 372 struct snd_soc_card *card = graph_priv_to_card(priv);
238 struct device_node *node = dev->of_node; 373 struct device_node *node = dev->of_node;
374 struct device_node *cpu_port;
375 struct device_node *cpu_ep = NULL;
376 struct device_node *codec_ep = NULL;
377 struct device_node *codec_port = NULL;
378 struct device_node *codec_port_old = NULL;
239 int rc, ret; 379 int rc, ret;
240 int link_idx, dai_idx; 380 int link_idx, dai_idx, conf_idx;
381 int cpu;
241 382
242 ret = asoc_simple_card_of_parse_widgets(card, NULL); 383 ret = asoc_simple_card_of_parse_widgets(card, NULL);
243 if (ret < 0) 384 if (ret < 0)
@@ -247,35 +388,159 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
247 if (ret < 0) 388 if (ret < 0)
248 return ret; 389 return ret;
249 390
391 asoc_simple_card_parse_convert(dev, node, NULL, &priv->adata);
392
250 /* Factor to mclk, used in hw_params() */ 393 /* Factor to mclk, used in hw_params() */
251 of_property_read_u32(node, "mclk-fs", &priv->mclk_fs); 394 of_property_read_u32(node, "mclk-fs", &priv->mclk_fs);
252 395
253 link_idx = 0; 396 link_idx = 0;
254 dai_idx = 0; 397 dai_idx = 0;
255 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { 398 conf_idx = 0;
256 ret = asoc_graph_card_dai_link_of(it.node, priv, 399 codec_port_old = NULL;
257 &dai_idx, link_idx++); 400 for (cpu = 1; cpu >= 0; cpu--) {
258 if (ret < 0) { 401 /*
259 of_node_put(it.node); 402 * Detect all CPU first, and Detect all Codec 2nd.
260 403 *
261 return ret; 404 * In Normal sound case, all DAIs are detected
405 * as "CPU-Codec".
406 *
407 * In DPCM sound case,
408 * all CPUs are detected as "CPU-dummy", and
409 * all Codecs are detected as "dummy-Codec".
410 * To avoid random sub-device numbering,
411 * detect "dummy-Codec" in last;
412 */
413 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
414 cpu_port = it.node;
415 cpu_ep = NULL;
416 while (1) {
417 cpu_ep = of_get_next_child(cpu_port, cpu_ep);
418 if (!cpu_ep)
419 break;
420
421 codec_ep = of_graph_get_remote_endpoint(cpu_ep);
422 codec_port = of_get_parent(codec_ep);
423
424 of_node_put(codec_ep);
425 of_node_put(codec_port);
426
427 dev_dbg(dev, "%pOFf <-> %pOFf\n", cpu_ep, codec_ep);
428
429 if (of_get_child_count(codec_port) > 1) {
430 /*
431 * for DPCM sound
432 */
433 if (!cpu) {
434 if (codec_port_old == codec_port)
435 continue;
436 codec_port_old = codec_port;
437 }
438 ret = asoc_graph_card_dai_link_of_dpcm(
439 cpu_ep, codec_ep, priv,
440 &dai_idx, link_idx++,
441 &conf_idx, cpu);
442 } else if (cpu) {
443 /*
444 * for Normal sound
445 */
446 ret = asoc_graph_card_dai_link_of(
447 cpu_ep, codec_ep, priv,
448 &dai_idx, link_idx++);
449 }
450 if (ret < 0)
451 return ret;
452 }
262 } 453 }
263 } 454 }
264 455
265 return asoc_simple_card_parse_card_name(card, NULL); 456 return asoc_simple_card_parse_card_name(card, NULL);
266} 457}
267 458
268static int asoc_graph_get_dais_count(struct device *dev) 459static void asoc_graph_get_dais_count(struct device *dev,
460 int *link_num,
461 int *dais_num,
462 int *ccnf_num)
269{ 463{
270 struct of_phandle_iterator it; 464 struct of_phandle_iterator it;
271 struct device_node *node = dev->of_node; 465 struct device_node *node = dev->of_node;
272 int count = 0; 466 struct device_node *cpu_port;
467 struct device_node *cpu_ep;
468 struct device_node *codec_ep;
469 struct device_node *codec_port;
470 struct device_node *codec_port_old;
471 struct device_node *codec_port_old2;
273 int rc; 472 int rc;
274 473
275 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) 474 /*
276 count++; 475 * link_num : number of links.
277 476 * CPU-Codec / CPU-dummy / dummy-Codec
278 return count; 477 * dais_num : number of DAIs
478 * ccnf_num : number of codec_conf
479 * same number for "dummy-Codec"
480 *
481 * ex1)
482 * CPU0 --- Codec0 link : 5
483 * CPU1 --- Codec1 dais : 7
484 * CPU2 -/ ccnf : 1
485 * CPU3 --- Codec2
486 *
487 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
488 * => 7 DAIs = 4xCPU + 3xCodec
489 * => 1 ccnf = 1xdummy-Codec
490 *
491 * ex2)
492 * CPU0 --- Codec0 link : 5
493 * CPU1 --- Codec1 dais : 6
494 * CPU2 -/ ccnf : 1
495 * CPU3 -/
496 *
497 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
498 * => 6 DAIs = 4xCPU + 2xCodec
499 * => 1 ccnf = 1xdummy-Codec
500 *
501 * ex3)
502 * CPU0 --- Codec0 link : 6
503 * CPU1 -/ dais : 6
504 * CPU2 --- Codec1 ccnf : 2
505 * CPU3 -/
506 *
507 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
508 * => 6 DAIs = 4xCPU + 2xCodec
509 * => 2 ccnf = 2xdummy-Codec
510 */
511 codec_port_old = NULL;
512 codec_port_old2 = NULL;
513 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
514 cpu_port = it.node;
515 cpu_ep = NULL;
516 while (1) {
517 cpu_ep = of_get_next_child(cpu_port, cpu_ep);
518 if (!cpu_ep)
519 break;
520
521 codec_ep = of_graph_get_remote_endpoint(cpu_ep);
522 codec_port = of_get_parent(codec_ep);
523
524 of_node_put(codec_ep);
525 of_node_put(codec_port);
526
527 (*link_num)++;
528 (*dais_num)++;
529
530 if (codec_port_old == codec_port) {
531 if (codec_port_old2 != codec_port_old) {
532 (*link_num)++;
533 (*ccnf_num)++;
534 }
535
536 codec_port_old2 = codec_port_old;
537 continue;
538 }
539
540 (*dais_num)++;
541 codec_port_old = codec_port;
542 }
543 }
279} 544}
280 545
281static int asoc_graph_soc_card_probe(struct snd_soc_card *card) 546static int asoc_graph_soc_card_probe(struct snd_soc_card *card)
@@ -302,20 +567,23 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
302 struct asoc_simple_dai *dais; 567 struct asoc_simple_dai *dais;
303 struct device *dev = &pdev->dev; 568 struct device *dev = &pdev->dev;
304 struct snd_soc_card *card; 569 struct snd_soc_card *card;
305 int num, ret, i; 570 struct snd_soc_codec_conf *cconf;
571 int lnum = 0, dnum = 0, cnum = 0;
572 int ret, i;
306 573
307 /* Allocate the private data and the DAI link array */ 574 /* Allocate the private data and the DAI link array */
308 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 575 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
309 if (!priv) 576 if (!priv)
310 return -ENOMEM; 577 return -ENOMEM;
311 578
312 num = asoc_graph_get_dais_count(dev); 579 asoc_graph_get_dais_count(dev, &lnum, &dnum, &cnum);
313 if (num == 0) 580 if (!lnum || !dnum)
314 return -EINVAL; 581 return -EINVAL;
315 582
316 dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); 583 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
317 dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); 584 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
318 dais = devm_kcalloc(dev, num * 2, sizeof(*dais), GFP_KERNEL); 585 dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL);
586 cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL);
319 if (!dai_props || !dai_link || !dais) 587 if (!dai_props || !dai_link || !dais)
320 return -ENOMEM; 588 return -ENOMEM;
321 589
@@ -325,7 +593,7 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
325 * see 593 * see
326 * soc-core.c :: snd_soc_init_multicodec() 594 * soc-core.c :: snd_soc_init_multicodec()
327 */ 595 */
328 for (i = 0; i < num; i++) { 596 for (i = 0; i < lnum; i++) {
329 dai_link[i].codecs = &dai_props[i].codecs; 597 dai_link[i].codecs = &dai_props[i].codecs;
330 dai_link[i].num_codecs = 1; 598 dai_link[i].num_codecs = 1;
331 dai_link[i].platform = &dai_props[i].platform; 599 dai_link[i].platform = &dai_props[i].platform;
@@ -341,16 +609,19 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
341 priv->dai_props = dai_props; 609 priv->dai_props = dai_props;
342 priv->dai_link = dai_link; 610 priv->dai_link = dai_link;
343 priv->dais = dais; 611 priv->dais = dais;
612 priv->codec_conf = cconf;
344 613
345 /* Init snd_soc_card */ 614 /* Init snd_soc_card */
346 card = graph_priv_to_card(priv); 615 card = graph_priv_to_card(priv);
347 card->owner = THIS_MODULE; 616 card->owner = THIS_MODULE;
348 card->dev = dev; 617 card->dev = dev;
349 card->dai_link = dai_link; 618 card->dai_link = dai_link;
350 card->num_links = num; 619 card->num_links = lnum;
351 card->dapm_widgets = asoc_graph_card_dapm_widgets; 620 card->dapm_widgets = asoc_graph_card_dapm_widgets;
352 card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets); 621 card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets);
353 card->probe = asoc_graph_soc_card_probe; 622 card->probe = asoc_graph_soc_card_probe;
623 card->codec_conf = cconf;
624 card->num_configs = cnum;
354 625
355 ret = asoc_graph_card_parse_of(priv); 626 ret = asoc_graph_card_parse_of(priv);
356 if (ret < 0) { 627 if (ret < 0) {
@@ -381,6 +652,7 @@ static int asoc_graph_card_remove(struct platform_device *pdev)
381 652
382static const struct of_device_id asoc_graph_of_match[] = { 653static const struct of_device_id asoc_graph_of_match[] = {
383 { .compatible = "audio-graph-card", }, 654 { .compatible = "audio-graph-card", },
655 { .compatible = "audio-graph-scu-card", },
384 {}, 656 {},
385}; 657};
386MODULE_DEVICE_TABLE(of, asoc_graph_of_match); 658MODULE_DEVICE_TABLE(of, asoc_graph_of_match);