.. | .. |
---|
1 | | -/* |
---|
2 | | - * Copyright (C) 2015 - 2016 Samsung Electronics Co., Ltd. |
---|
3 | | - * |
---|
4 | | - * Authors: Inha Song <ideal.song@samsung.com> |
---|
5 | | - * Sylwester Nawrocki <s.nawrocki@samsung.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify it |
---|
8 | | - * under the terms of the GNU General Public License as published by the |
---|
9 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
10 | | - * option) any later version. |
---|
11 | | - */ |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
| 2 | +// |
---|
| 3 | +// Copyright (C) 2015 - 2016 Samsung Electronics Co., Ltd. |
---|
| 4 | +// |
---|
| 5 | +// Authors: Inha Song <ideal.song@samsung.com> |
---|
| 6 | +// Sylwester Nawrocki <s.nawrocki@samsung.com> |
---|
12 | 7 | |
---|
13 | 8 | #include <linux/clk.h> |
---|
14 | 9 | #include <linux/gpio.h> |
---|
.. | .. |
---|
97 | 92 | static int tm2_aif1_hw_params(struct snd_pcm_substream *substream, |
---|
98 | 93 | struct snd_pcm_hw_params *params) |
---|
99 | 94 | { |
---|
100 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
101 | | - struct snd_soc_component *component = rtd->codec_dai->component; |
---|
| 95 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 96 | + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
102 | 97 | struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
---|
103 | 98 | |
---|
104 | 99 | switch (params_rate(params)) { |
---|
.. | .. |
---|
138 | 133 | static int tm2_aif2_hw_params(struct snd_pcm_substream *substream, |
---|
139 | 134 | struct snd_pcm_hw_params *params) |
---|
140 | 135 | { |
---|
141 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
142 | | - struct snd_soc_component *component = rtd->codec_dai->component; |
---|
| 136 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 137 | + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
143 | 138 | unsigned int asyncclk_rate; |
---|
144 | 139 | int ret; |
---|
145 | 140 | |
---|
.. | .. |
---|
192 | 187 | |
---|
193 | 188 | static int tm2_aif2_hw_free(struct snd_pcm_substream *substream) |
---|
194 | 189 | { |
---|
195 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
196 | | - struct snd_soc_component *component = rtd->codec_dai->component; |
---|
| 190 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 191 | + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
197 | 192 | int ret; |
---|
198 | 193 | |
---|
199 | 194 | /* disable FLL2 */ |
---|
.. | .. |
---|
213 | 208 | static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream, |
---|
214 | 209 | struct snd_pcm_hw_params *params) |
---|
215 | 210 | { |
---|
216 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
217 | | - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
---|
| 211 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 212 | + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
---|
218 | 213 | unsigned int bfs; |
---|
219 | 214 | int bitwidth, ret; |
---|
220 | 215 | |
---|
.. | .. |
---|
287 | 282 | { |
---|
288 | 283 | struct snd_soc_pcm_runtime *rtd; |
---|
289 | 284 | |
---|
290 | | - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); |
---|
| 285 | + rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); |
---|
291 | 286 | |
---|
292 | | - if (dapm->dev != rtd->codec_dai->dev) |
---|
| 287 | + if (dapm->dev != asoc_rtd_to_codec(rtd, 0)->dev) |
---|
293 | 288 | return 0; |
---|
294 | 289 | |
---|
295 | 290 | switch (level) { |
---|
.. | .. |
---|
312 | 307 | static int tm2_late_probe(struct snd_soc_card *card) |
---|
313 | 308 | { |
---|
314 | 309 | struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); |
---|
315 | | - struct snd_soc_dai_link_component dlc = { 0 }; |
---|
316 | 310 | unsigned int ch_map[] = { 0, 1 }; |
---|
317 | 311 | struct snd_soc_dai *amp_pdm_dai; |
---|
318 | 312 | struct snd_soc_pcm_runtime *rtd; |
---|
.. | .. |
---|
320 | 314 | struct snd_soc_dai *aif2_dai; |
---|
321 | 315 | int ret; |
---|
322 | 316 | |
---|
323 | | - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF1].name); |
---|
324 | | - aif1_dai = rtd->codec_dai; |
---|
325 | | - priv->component = rtd->codec_dai->component; |
---|
| 317 | + rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[TM2_DAI_AIF1]); |
---|
| 318 | + aif1_dai = asoc_rtd_to_codec(rtd, 0); |
---|
| 319 | + priv->component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
326 | 320 | |
---|
327 | 321 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); |
---|
328 | 322 | if (ret < 0) { |
---|
.. | .. |
---|
330 | 324 | return ret; |
---|
331 | 325 | } |
---|
332 | 326 | |
---|
333 | | - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF2].name); |
---|
334 | | - aif2_dai = rtd->codec_dai; |
---|
| 327 | + rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[TM2_DAI_AIF2]); |
---|
| 328 | + aif2_dai = asoc_rtd_to_codec(rtd, 0); |
---|
335 | 329 | |
---|
336 | 330 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); |
---|
337 | 331 | if (ret < 0) { |
---|
.. | .. |
---|
339 | 333 | return ret; |
---|
340 | 334 | } |
---|
341 | 335 | |
---|
342 | | - dlc.of_node = tm2_speaker_amp_dev.codec_of_node; |
---|
343 | | - amp_pdm_dai = snd_soc_find_dai(&dlc); |
---|
| 336 | + amp_pdm_dai = snd_soc_find_dai(&tm2_speaker_amp_dev.dlc); |
---|
344 | 337 | if (!amp_pdm_dai) |
---|
345 | 338 | return -ENODEV; |
---|
346 | 339 | |
---|
.. | .. |
---|
432 | 425 | }, |
---|
433 | 426 | }; |
---|
434 | 427 | |
---|
| 428 | +SND_SOC_DAILINK_DEFS(aif1, |
---|
| 429 | + DAILINK_COMP_ARRAY(COMP_CPU(SAMSUNG_I2S_DAI)), |
---|
| 430 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm5110-aif1")), |
---|
| 431 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 432 | + |
---|
| 433 | +SND_SOC_DAILINK_DEFS(voice, |
---|
| 434 | + DAILINK_COMP_ARRAY(COMP_CPU(SAMSUNG_I2S_DAI)), |
---|
| 435 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm5110-aif2")), |
---|
| 436 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 437 | + |
---|
| 438 | +SND_SOC_DAILINK_DEFS(bt, |
---|
| 439 | + DAILINK_COMP_ARRAY(COMP_CPU(SAMSUNG_I2S_DAI)), |
---|
| 440 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm5110-aif3")), |
---|
| 441 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 442 | + |
---|
| 443 | +SND_SOC_DAILINK_DEFS(hdmi, |
---|
| 444 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 445 | + DAILINK_COMP_ARRAY(COMP_EMPTY()), |
---|
| 446 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
---|
| 447 | + |
---|
435 | 448 | static struct snd_soc_dai_link tm2_dai_links[] = { |
---|
436 | 449 | { |
---|
437 | 450 | .name = "WM5110 AIF1", |
---|
438 | 451 | .stream_name = "HiFi Primary", |
---|
439 | | - .cpu_dai_name = SAMSUNG_I2S_DAI, |
---|
440 | | - .codec_dai_name = "wm5110-aif1", |
---|
441 | 452 | .ops = &tm2_aif1_ops, |
---|
442 | 453 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
443 | 454 | SND_SOC_DAIFMT_CBM_CFM, |
---|
| 455 | + SND_SOC_DAILINK_REG(aif1), |
---|
444 | 456 | }, { |
---|
445 | 457 | .name = "WM5110 Voice", |
---|
446 | 458 | .stream_name = "Voice call", |
---|
447 | | - .cpu_dai_name = SAMSUNG_I2S_DAI, |
---|
448 | | - .codec_dai_name = "wm5110-aif2", |
---|
449 | 459 | .ops = &tm2_aif2_ops, |
---|
450 | 460 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
451 | 461 | SND_SOC_DAIFMT_CBM_CFM, |
---|
452 | 462 | .ignore_suspend = 1, |
---|
| 463 | + SND_SOC_DAILINK_REG(voice), |
---|
453 | 464 | }, { |
---|
454 | 465 | .name = "WM5110 BT", |
---|
455 | 466 | .stream_name = "Bluetooth", |
---|
456 | | - .cpu_dai_name = SAMSUNG_I2S_DAI, |
---|
457 | | - .codec_dai_name = "wm5110-aif3", |
---|
458 | 467 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
459 | 468 | SND_SOC_DAIFMT_CBM_CFM, |
---|
460 | 469 | .ignore_suspend = 1, |
---|
| 470 | + SND_SOC_DAILINK_REG(bt), |
---|
461 | 471 | }, { |
---|
462 | 472 | .name = "HDMI", |
---|
463 | 473 | .stream_name = "i2s1", |
---|
464 | 474 | .ops = &tm2_hdmi_ops, |
---|
465 | 475 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
466 | 476 | SND_SOC_DAIFMT_CBS_CFS, |
---|
| 477 | + SND_SOC_DAILINK_REG(hdmi), |
---|
467 | 478 | } |
---|
468 | 479 | }; |
---|
469 | 480 | |
---|
.. | .. |
---|
491 | 502 | struct snd_soc_card *card = &tm2_card; |
---|
492 | 503 | struct tm2_machine_priv *priv; |
---|
493 | 504 | struct of_phandle_args args; |
---|
| 505 | + struct snd_soc_dai_link *dai_link; |
---|
494 | 506 | int num_codecs, ret, i; |
---|
495 | 507 | |
---|
496 | 508 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
---|
.. | .. |
---|
518 | 530 | return ret; |
---|
519 | 531 | } |
---|
520 | 532 | |
---|
521 | | - card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node, |
---|
| 533 | + card->aux_dev[0].dlc.of_node = of_parse_phandle(dev->of_node, |
---|
522 | 534 | "audio-amplifier", 0); |
---|
523 | | - if (!card->aux_dev[0].codec_of_node) { |
---|
| 535 | + if (!card->aux_dev[0].dlc.of_node) { |
---|
524 | 536 | dev_err(dev, "audio-amplifier property invalid or missing\n"); |
---|
525 | 537 | return -EINVAL; |
---|
526 | 538 | } |
---|
.. | .. |
---|
558 | 570 | } |
---|
559 | 571 | |
---|
560 | 572 | /* Initialize WM5110 - I2S and HDMI - I2S1 DAI links */ |
---|
561 | | - for (i = 0; i < card->num_links; i++) { |
---|
| 573 | + for_each_card_prelinks(card, i, dai_link) { |
---|
562 | 574 | unsigned int dai_index = 0; /* WM5110 */ |
---|
563 | 575 | |
---|
564 | | - card->dai_link[i].cpu_name = NULL; |
---|
565 | | - card->dai_link[i].platform_name = NULL; |
---|
| 576 | + dai_link->cpus->name = NULL; |
---|
| 577 | + dai_link->platforms->name = NULL; |
---|
566 | 578 | |
---|
567 | 579 | if (num_codecs > 1 && i == card->num_links - 1) |
---|
568 | 580 | dai_index = 1; /* HDMI */ |
---|
569 | 581 | |
---|
570 | | - card->dai_link[i].codec_of_node = codec_dai_node[dai_index]; |
---|
571 | | - card->dai_link[i].cpu_of_node = cpu_dai_node[dai_index]; |
---|
572 | | - card->dai_link[i].platform_of_node = cpu_dai_node[dai_index]; |
---|
| 582 | + dai_link->codecs->of_node = codec_dai_node[dai_index]; |
---|
| 583 | + dai_link->cpus->of_node = cpu_dai_node[dai_index]; |
---|
| 584 | + dai_link->platforms->of_node = cpu_dai_node[dai_index]; |
---|
573 | 585 | } |
---|
574 | 586 | |
---|
575 | 587 | if (num_codecs > 1) { |
---|
.. | .. |
---|
583 | 595 | goto dai_node_put; |
---|
584 | 596 | } |
---|
585 | 597 | |
---|
586 | | - ret = snd_soc_get_dai_name(&args, &card->dai_link[i].codec_dai_name); |
---|
| 598 | + ret = snd_soc_get_dai_name(&args, &card->dai_link[i].codecs->dai_name); |
---|
587 | 599 | if (ret) { |
---|
588 | 600 | dev_err(dev, "Unable to get codec_dai_name\n"); |
---|
589 | 601 | goto dai_node_put; |
---|
.. | .. |
---|
599 | 611 | |
---|
600 | 612 | ret = devm_snd_soc_register_card(dev, card); |
---|
601 | 613 | if (ret < 0) { |
---|
602 | | - dev_err(dev, "Failed to register card: %d\n", ret); |
---|
| 614 | + dev_err_probe(dev, ret, "Failed to register card\n"); |
---|
603 | 615 | goto dai_node_put; |
---|
604 | 616 | } |
---|
605 | 617 | |
---|
.. | .. |
---|
609 | 621 | of_node_put(cpu_dai_node[i]); |
---|
610 | 622 | } |
---|
611 | 623 | |
---|
612 | | - of_node_put(card->aux_dev[0].codec_of_node); |
---|
| 624 | + of_node_put(card->aux_dev[0].dlc.of_node); |
---|
613 | 625 | |
---|
614 | 626 | return ret; |
---|
615 | 627 | } |
---|