diff options
Diffstat (limited to 'sound/soc/sh')
-rw-r--r-- | sound/soc/sh/rcar/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/adg.c | 57 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 168 | ||||
-rw-r--r-- | sound/soc/sh/rcar/dvc.c | 273 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 25 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 68 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 194 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 89 |
8 files changed, 537 insertions, 339 deletions
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index 7d0051ced838..9ac536429800 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o | 1 | snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o |
2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file | 2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file |
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 69c44269ebdb..fc41a0e8b09f 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -57,6 +57,24 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) | |||
57 | return (0x6 + ws) << 8; | 57 | return (0x6 + ws) << 8; |
58 | } | 58 | } |
59 | 59 | ||
60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | ||
61 | struct rsnd_mod *mod, | ||
62 | struct rsnd_dai_stream *io) | ||
63 | { | ||
64 | int id = rsnd_mod_id(mod); | ||
65 | int shift = (id % 2) ? 16 : 0; | ||
66 | u32 mask, val; | ||
67 | |||
68 | val = rsnd_adg_ssi_ws_timing_gen2(io); | ||
69 | |||
70 | val = val << shift; | ||
71 | mask = 0xffff << shift; | ||
72 | |||
73 | rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
60 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | 78 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, |
61 | struct rsnd_mod *mod, | 79 | struct rsnd_mod *mod, |
62 | struct rsnd_dai_stream *io, | 80 | struct rsnd_dai_stream *io, |
@@ -397,9 +415,8 @@ int rsnd_adg_probe(struct platform_device *pdev, | |||
397 | { | 415 | { |
398 | struct rsnd_adg *adg; | 416 | struct rsnd_adg *adg; |
399 | struct device *dev = rsnd_priv_to_dev(priv); | 417 | struct device *dev = rsnd_priv_to_dev(priv); |
400 | struct clk *clk, *clk_orig; | 418 | struct clk *clk; |
401 | int i; | 419 | int i; |
402 | bool use_old_style = false; | ||
403 | 420 | ||
404 | adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); | 421 | adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); |
405 | if (!adg) { | 422 | if (!adg) { |
@@ -407,45 +424,13 @@ int rsnd_adg_probe(struct platform_device *pdev, | |||
407 | return -ENOMEM; | 424 | return -ENOMEM; |
408 | } | 425 | } |
409 | 426 | ||
410 | clk_orig = devm_clk_get(dev, NULL); | ||
411 | adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); | 427 | adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); |
412 | adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); | 428 | adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); |
413 | adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); | 429 | adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); |
414 | adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); | 430 | adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); |
415 | 431 | ||
416 | /* | 432 | for_each_rsnd_clk(clk, adg, i) |
417 | * It request device dependent audio clock. | 433 | dev_dbg(dev, "clk %d : %p\n", i, clk); |
418 | * But above all clks will indicate rsnd module clock | ||
419 | * if platform doesn't it | ||
420 | */ | ||
421 | for_each_rsnd_clk(clk, adg, i) { | ||
422 | if (clk_orig == clk) { | ||
423 | dev_warn(dev, | ||
424 | "doesn't have device dependent clock, use independent clock\n"); | ||
425 | use_old_style = true; | ||
426 | break; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * note: | ||
432 | * these exist in order to keep compatible with | ||
433 | * platform which has device independent audio clock, | ||
434 | * but will be removed soon | ||
435 | */ | ||
436 | if (use_old_style) { | ||
437 | adg->clk[CLKA] = devm_clk_get(NULL, "audio_clk_a"); | ||
438 | adg->clk[CLKB] = devm_clk_get(NULL, "audio_clk_b"); | ||
439 | adg->clk[CLKC] = devm_clk_get(NULL, "audio_clk_c"); | ||
440 | adg->clk[CLKI] = devm_clk_get(NULL, "audio_clk_internal"); | ||
441 | } | ||
442 | |||
443 | for_each_rsnd_clk(clk, adg, i) { | ||
444 | if (IS_ERR(clk)) { | ||
445 | dev_err(dev, "Audio clock failed\n"); | ||
446 | return -EIO; | ||
447 | } | ||
448 | } | ||
449 | 434 | ||
450 | rsnd_adg_ssi_clk_init(priv, adg); | 435 | rsnd_adg_ssi_clk_init(priv, adg); |
451 | 436 | ||
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 215b668166be..964463dada87 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -197,13 +197,12 @@ static void rsnd_dma_complete(void *data) | |||
197 | * rsnd_dai_pointer_update() will be called twice, | 197 | * rsnd_dai_pointer_update() will be called twice, |
198 | * ant it will breaks io->byte_pos | 198 | * ant it will breaks io->byte_pos |
199 | */ | 199 | */ |
200 | |||
201 | rsnd_dai_pointer_update(io, io->byte_per_period); | ||
202 | |||
203 | if (dma->submit_loop) | 200 | if (dma->submit_loop) |
204 | rsnd_dma_continue(dma); | 201 | rsnd_dma_continue(dma); |
205 | 202 | ||
206 | rsnd_unlock(priv, flags); | 203 | rsnd_unlock(priv, flags); |
204 | |||
205 | rsnd_dai_pointer_update(io, io->byte_per_period); | ||
207 | } | 206 | } |
208 | 207 | ||
209 | static void __rsnd_dma_start(struct rsnd_dma *dma) | 208 | static void __rsnd_dma_start(struct rsnd_dma *dma) |
@@ -310,23 +309,49 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
310 | } | 309 | } |
311 | 310 | ||
312 | /* | 311 | /* |
312 | * settting function | ||
313 | */ | ||
314 | u32 rsnd_get_adinr(struct rsnd_mod *mod) | ||
315 | { | ||
316 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
317 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
318 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
319 | struct device *dev = rsnd_priv_to_dev(priv); | ||
320 | u32 adinr = runtime->channels; | ||
321 | |||
322 | switch (runtime->sample_bits) { | ||
323 | case 16: | ||
324 | adinr |= (8 << 16); | ||
325 | break; | ||
326 | case 32: | ||
327 | adinr |= (0 << 16); | ||
328 | break; | ||
329 | default: | ||
330 | dev_warn(dev, "not supported sample bits\n"); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | return adinr; | ||
335 | } | ||
336 | |||
337 | /* | ||
313 | * rsnd_dai functions | 338 | * rsnd_dai functions |
314 | */ | 339 | */ |
315 | #define __rsnd_mod_call(mod, func, rdai, io) \ | 340 | #define __rsnd_mod_call(mod, func, rdai...) \ |
316 | ({ \ | 341 | ({ \ |
317 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 342 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
318 | struct device *dev = rsnd_priv_to_dev(priv); \ | 343 | struct device *dev = rsnd_priv_to_dev(priv); \ |
319 | dev_dbg(dev, "%s [%d] %s\n", \ | 344 | dev_dbg(dev, "%s [%d] %s\n", \ |
320 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 345 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ |
321 | (mod)->ops->func(mod, rdai, io); \ | 346 | (mod)->ops->func(mod, rdai); \ |
322 | }) | 347 | }) |
323 | 348 | ||
324 | #define rsnd_mod_call(mod, func, rdai, io) \ | 349 | #define rsnd_mod_call(mod, func, rdai...) \ |
325 | (!(mod) ? -ENODEV : \ | 350 | (!(mod) ? -ENODEV : \ |
326 | !((mod)->ops->func) ? 0 : \ | 351 | !((mod)->ops->func) ? 0 : \ |
327 | __rsnd_mod_call(mod, func, (rdai), (io))) | 352 | __rsnd_mod_call(mod, func, rdai)) |
328 | 353 | ||
329 | #define rsnd_dai_call(rdai, io, fn) \ | 354 | #define rsnd_dai_call(fn, io, rdai...) \ |
330 | ({ \ | 355 | ({ \ |
331 | struct rsnd_mod *mod; \ | 356 | struct rsnd_mod *mod; \ |
332 | int ret = 0, i; \ | 357 | int ret = 0, i; \ |
@@ -334,7 +359,7 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
334 | mod = (io)->mod[i]; \ | 359 | mod = (io)->mod[i]; \ |
335 | if (!mod) \ | 360 | if (!mod) \ |
336 | continue; \ | 361 | continue; \ |
337 | ret = rsnd_mod_call(mod, fn, (rdai), (io)); \ | 362 | ret = rsnd_mod_call(mod, fn, rdai); \ |
338 | if (ret < 0) \ | 363 | if (ret < 0) \ |
339 | break; \ | 364 | break; \ |
340 | } \ | 365 | } \ |
@@ -468,10 +493,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
468 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); | 493 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); |
469 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 494 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
470 | struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); | 495 | struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); |
471 | struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv, | 496 | int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io)); |
472 | rsnd_dai_id(priv, rdai), | ||
473 | rsnd_dai_is_play(rdai, io)); | ||
474 | int ssi_id = rsnd_mod_id(mod); | ||
475 | int ret; | 497 | int ret; |
476 | unsigned long flags; | 498 | unsigned long flags; |
477 | 499 | ||
@@ -487,20 +509,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
487 | if (ret < 0) | 509 | if (ret < 0) |
488 | goto dai_trigger_end; | 510 | goto dai_trigger_end; |
489 | 511 | ||
490 | ret = rsnd_dai_call(rdai, io, init); | 512 | ret = rsnd_dai_call(init, io, rdai); |
491 | if (ret < 0) | 513 | if (ret < 0) |
492 | goto dai_trigger_end; | 514 | goto dai_trigger_end; |
493 | 515 | ||
494 | ret = rsnd_dai_call(rdai, io, start); | 516 | ret = rsnd_dai_call(start, io, rdai); |
495 | if (ret < 0) | 517 | if (ret < 0) |
496 | goto dai_trigger_end; | 518 | goto dai_trigger_end; |
497 | break; | 519 | break; |
498 | case SNDRV_PCM_TRIGGER_STOP: | 520 | case SNDRV_PCM_TRIGGER_STOP: |
499 | ret = rsnd_dai_call(rdai, io, stop); | 521 | ret = rsnd_dai_call(stop, io, rdai); |
500 | if (ret < 0) | 522 | if (ret < 0) |
501 | goto dai_trigger_end; | 523 | goto dai_trigger_end; |
502 | 524 | ||
503 | ret = rsnd_dai_call(rdai, io, quit); | 525 | ret = rsnd_dai_call(quit, io, rdai); |
504 | if (ret < 0) | 526 | if (ret < 0) |
505 | goto dai_trigger_end; | 527 | goto dai_trigger_end; |
506 | 528 | ||
@@ -579,15 +601,27 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { | |||
579 | .set_fmt = rsnd_soc_dai_set_fmt, | 601 | .set_fmt = rsnd_soc_dai_set_fmt, |
580 | }; | 602 | }; |
581 | 603 | ||
604 | #define rsnd_path_parse(priv, io, type) \ | ||
605 | ({ \ | ||
606 | struct rsnd_mod *mod; \ | ||
607 | int ret = 0; \ | ||
608 | int id = -1; \ | ||
609 | \ | ||
610 | if (rsnd_is_enable_path(io, type)) { \ | ||
611 | id = rsnd_info_id(priv, io, type); \ | ||
612 | if (id >= 0) { \ | ||
613 | mod = rsnd_##type##_mod_get(priv, id); \ | ||
614 | ret = rsnd_dai_connect(mod, io); \ | ||
615 | } \ | ||
616 | } \ | ||
617 | ret; \ | ||
618 | }) | ||
619 | |||
582 | static int rsnd_path_init(struct rsnd_priv *priv, | 620 | static int rsnd_path_init(struct rsnd_priv *priv, |
583 | struct rsnd_dai *rdai, | 621 | struct rsnd_dai *rdai, |
584 | struct rsnd_dai_stream *io) | 622 | struct rsnd_dai_stream *io) |
585 | { | 623 | { |
586 | struct rsnd_mod *mod; | ||
587 | struct rsnd_dai_platform_info *dai_info = rdai->info; | ||
588 | int ret; | 624 | int ret; |
589 | int ssi_id = -1; | ||
590 | int src_id = -1; | ||
591 | 625 | ||
592 | /* | 626 | /* |
593 | * Gen1 is created by SRU/SSI, and this SRU is base module of | 627 | * Gen1 is created by SRU/SSI, and this SRU is base module of |
@@ -599,38 +633,21 @@ static int rsnd_path_init(struct rsnd_priv *priv, | |||
599 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is | 633 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is |
600 | * using fixed path. | 634 | * using fixed path. |
601 | */ | 635 | */ |
602 | if (dai_info) { | ||
603 | if (rsnd_is_enable_path(io, ssi)) | ||
604 | ssi_id = rsnd_info_id(priv, io, ssi); | ||
605 | if (rsnd_is_enable_path(io, src)) | ||
606 | src_id = rsnd_info_id(priv, io, src); | ||
607 | } else { | ||
608 | /* get SSI's ID */ | ||
609 | mod = rsnd_ssi_mod_get_frm_dai(priv, | ||
610 | rsnd_dai_id(priv, rdai), | ||
611 | rsnd_dai_is_play(rdai, io)); | ||
612 | if (!mod) | ||
613 | return 0; | ||
614 | ssi_id = src_id = rsnd_mod_id(mod); | ||
615 | } | ||
616 | |||
617 | ret = 0; | ||
618 | 636 | ||
619 | /* SRC */ | 637 | /* SRC */ |
620 | if (src_id >= 0) { | 638 | ret = rsnd_path_parse(priv, io, src); |
621 | mod = rsnd_src_mod_get(priv, src_id); | 639 | if (ret < 0) |
622 | ret = rsnd_dai_connect(mod, io); | 640 | return ret; |
623 | if (ret < 0) | ||
624 | return ret; | ||
625 | } | ||
626 | 641 | ||
627 | /* SSI */ | 642 | /* SSI */ |
628 | if (ssi_id >= 0) { | 643 | ret = rsnd_path_parse(priv, io, ssi); |
629 | mod = rsnd_ssi_mod_get(priv, ssi_id); | 644 | if (ret < 0) |
630 | ret = rsnd_dai_connect(mod, io); | 645 | return ret; |
631 | if (ret < 0) | 646 | |
632 | return ret; | 647 | /* DVC */ |
633 | } | 648 | ret = rsnd_path_parse(priv, io, dvc); |
649 | if (ret < 0) | ||
650 | return ret; | ||
634 | 651 | ||
635 | return ret; | 652 | return ret; |
636 | } | 653 | } |
@@ -726,30 +743,15 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
726 | struct snd_soc_dai_driver *drv; | 743 | struct snd_soc_dai_driver *drv; |
727 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | 744 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); |
728 | struct rsnd_dai *rdai; | 745 | struct rsnd_dai *rdai; |
729 | struct rsnd_mod *pmod, *cmod; | 746 | struct rsnd_ssi_platform_info *pmod, *cmod; |
730 | struct device *dev = rsnd_priv_to_dev(priv); | 747 | struct device *dev = rsnd_priv_to_dev(priv); |
731 | int dai_nr; | 748 | int dai_nr; |
732 | int i; | 749 | int i; |
733 | 750 | ||
734 | rsnd_of_parse_dai(pdev, of_data, priv); | 751 | rsnd_of_parse_dai(pdev, of_data, priv); |
735 | 752 | ||
736 | /* | ||
737 | * dai_nr should be set via dai_info_nr, | ||
738 | * but allow it to keeping compatible | ||
739 | */ | ||
740 | dai_nr = info->dai_info_nr; | 753 | dai_nr = info->dai_info_nr; |
741 | if (!dai_nr) { | 754 | if (!dai_nr) { |
742 | /* get max dai nr */ | ||
743 | for (dai_nr = 0; dai_nr < 32; dai_nr++) { | ||
744 | pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1); | ||
745 | cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0); | ||
746 | |||
747 | if (!pmod && !cmod) | ||
748 | break; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | if (!dai_nr) { | ||
753 | dev_err(dev, "no dai\n"); | 755 | dev_err(dev, "no dai\n"); |
754 | return -EIO; | 756 | return -EIO; |
755 | } | 757 | } |
@@ -766,11 +768,10 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
766 | priv->rdai = rdai; | 768 | priv->rdai = rdai; |
767 | 769 | ||
768 | for (i = 0; i < dai_nr; i++) { | 770 | for (i = 0; i < dai_nr; i++) { |
769 | if (info->dai_info) | 771 | rdai[i].info = &info->dai_info[i]; |
770 | rdai[i].info = &info->dai_info[i]; | ||
771 | 772 | ||
772 | pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1); | 773 | pmod = rdai[i].info->playback.ssi; |
773 | cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0); | 774 | cmod = rdai[i].info->capture.ssi; |
774 | 775 | ||
775 | /* | 776 | /* |
776 | * init rsnd_dai | 777 | * init rsnd_dai |
@@ -788,8 +789,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
788 | drv[i].playback.channels_min = 2; | 789 | drv[i].playback.channels_min = 2; |
789 | drv[i].playback.channels_max = 2; | 790 | drv[i].playback.channels_max = 2; |
790 | 791 | ||
791 | if (info->dai_info) | 792 | rdai[i].playback.info = &info->dai_info[i].playback; |
792 | rdai[i].playback.info = &info->dai_info[i].playback; | ||
793 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); | 793 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); |
794 | } | 794 | } |
795 | if (cmod) { | 795 | if (cmod) { |
@@ -798,8 +798,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
798 | drv[i].capture.channels_min = 2; | 798 | drv[i].capture.channels_min = 2; |
799 | drv[i].capture.channels_max = 2; | 799 | drv[i].capture.channels_max = 2; |
800 | 800 | ||
801 | if (info->dai_info) | 801 | rdai[i].capture.info = &info->dai_info[i].capture; |
802 | rdai[i].capture.info = &info->dai_info[i].capture; | ||
803 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); | 802 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); |
804 | } | 803 | } |
805 | 804 | ||
@@ -874,6 +873,20 @@ static struct snd_pcm_ops rsnd_pcm_ops = { | |||
874 | 873 | ||
875 | static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | 874 | static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) |
876 | { | 875 | { |
876 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
877 | struct rsnd_dai *rdai; | ||
878 | int i, ret; | ||
879 | |||
880 | for_each_rsnd_dai(rdai, priv, i) { | ||
881 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd); | ||
882 | if (ret) | ||
883 | return ret; | ||
884 | |||
885 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd); | ||
886 | if (ret) | ||
887 | return ret; | ||
888 | } | ||
889 | |||
877 | return snd_pcm_lib_preallocate_pages_for_all( | 890 | return snd_pcm_lib_preallocate_pages_for_all( |
878 | rtd->pcm, | 891 | rtd->pcm, |
879 | SNDRV_DMA_TYPE_DEV, | 892 | SNDRV_DMA_TYPE_DEV, |
@@ -913,6 +926,7 @@ static int rsnd_probe(struct platform_device *pdev) | |||
913 | rsnd_gen_probe, | 926 | rsnd_gen_probe, |
914 | rsnd_ssi_probe, | 927 | rsnd_ssi_probe, |
915 | rsnd_src_probe, | 928 | rsnd_src_probe, |
929 | rsnd_dvc_probe, | ||
916 | rsnd_adg_probe, | 930 | rsnd_adg_probe, |
917 | rsnd_dai_probe, | 931 | rsnd_dai_probe, |
918 | }; | 932 | }; |
@@ -956,11 +970,11 @@ static int rsnd_probe(struct platform_device *pdev) | |||
956 | } | 970 | } |
957 | 971 | ||
958 | for_each_rsnd_dai(rdai, priv, i) { | 972 | for_each_rsnd_dai(rdai, priv, i) { |
959 | ret = rsnd_dai_call(rdai, &rdai->playback, probe); | 973 | ret = rsnd_dai_call(probe, &rdai->playback, rdai); |
960 | if (ret) | 974 | if (ret) |
961 | return ret; | 975 | return ret; |
962 | 976 | ||
963 | ret = rsnd_dai_call(rdai, &rdai->capture, probe); | 977 | ret = rsnd_dai_call(probe, &rdai->capture, rdai); |
964 | if (ret) | 978 | if (ret) |
965 | return ret; | 979 | return ret; |
966 | } | 980 | } |
@@ -1003,11 +1017,11 @@ static int rsnd_remove(struct platform_device *pdev) | |||
1003 | pm_runtime_disable(&pdev->dev); | 1017 | pm_runtime_disable(&pdev->dev); |
1004 | 1018 | ||
1005 | for_each_rsnd_dai(rdai, priv, i) { | 1019 | for_each_rsnd_dai(rdai, priv, i) { |
1006 | ret = rsnd_dai_call(rdai, &rdai->playback, remove); | 1020 | ret = rsnd_dai_call(remove, &rdai->playback, rdai); |
1007 | if (ret) | 1021 | if (ret) |
1008 | return ret; | 1022 | return ret; |
1009 | 1023 | ||
1010 | ret = rsnd_dai_call(rdai, &rdai->capture, remove); | 1024 | ret = rsnd_dai_call(remove, &rdai->capture, rdai); |
1011 | if (ret) | 1025 | if (ret) |
1012 | return ret; | 1026 | return ret; |
1013 | } | 1027 | } |
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c new file mode 100644 index 000000000000..74769b1be005 --- /dev/null +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Renesas R-Car DVC support | ||
3 | * | ||
4 | * Copyright (C) 2014 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include "rsnd.h" | ||
12 | |||
13 | #define RSND_DVC_NAME_SIZE 16 | ||
14 | #define RSND_DVC_VOLUME_MAX 100 | ||
15 | #define RSND_DVC_VOLUME_NUM 2 | ||
16 | struct rsnd_dvc { | ||
17 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ | ||
18 | struct rsnd_mod mod; | ||
19 | struct clk *clk; | ||
20 | long volume[RSND_DVC_VOLUME_NUM]; | ||
21 | }; | ||
22 | |||
23 | #define rsnd_mod_to_dvc(_mod) \ | ||
24 | container_of((_mod), struct rsnd_dvc, mod) | ||
25 | |||
26 | #define for_each_rsnd_dvc(pos, priv, i) \ | ||
27 | for ((i) = 0; \ | ||
28 | ((i) < rsnd_dvc_nr(priv)) && \ | ||
29 | ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ | ||
30 | i++) | ||
31 | |||
32 | static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | ||
33 | { | ||
34 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
35 | u32 max = (0x00800000 - 1); | ||
36 | u32 vol[RSND_DVC_VOLUME_NUM]; | ||
37 | int i; | ||
38 | |||
39 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
40 | vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; | ||
41 | |||
42 | rsnd_mod_write(mod, DVC_VOL0R, vol[0]); | ||
43 | rsnd_mod_write(mod, DVC_VOL1R, vol[1]); | ||
44 | } | ||
45 | |||
46 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | ||
47 | struct rsnd_dai *rdai) | ||
48 | { | ||
49 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod); | ||
50 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | ||
51 | struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod); | ||
52 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | ||
53 | struct device *dev = rsnd_priv_to_dev(priv); | ||
54 | int dvc_id = rsnd_mod_id(dvc_mod); | ||
55 | int src_id = rsnd_mod_id(src_mod); | ||
56 | u32 route[] = { | ||
57 | [0] = 0x30000, | ||
58 | [1] = 0x30001, | ||
59 | [2] = 0x40000, | ||
60 | [3] = 0x10000, | ||
61 | [4] = 0x20000, | ||
62 | [5] = 0x40100 | ||
63 | }; | ||
64 | |||
65 | if (src_id >= ARRAY_SIZE(route)) { | ||
66 | dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | |||
70 | clk_prepare_enable(dvc->clk); | ||
71 | |||
72 | /* | ||
73 | * fixme | ||
74 | * it doesn't support CTU/MIX | ||
75 | */ | ||
76 | rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]); | ||
77 | |||
78 | rsnd_mod_write(dvc_mod, DVC_SWRSR, 0); | ||
79 | rsnd_mod_write(dvc_mod, DVC_SWRSR, 1); | ||
80 | |||
81 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); | ||
82 | |||
83 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); | ||
84 | |||
85 | /* enable Volume */ | ||
86 | rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x100); | ||
87 | |||
88 | /* ch0/ch1 Volume */ | ||
89 | rsnd_dvc_volume_update(dvc_mod); | ||
90 | |||
91 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | ||
92 | |||
93 | rsnd_mod_write(dvc_mod, DVC_DVUER, 1); | ||
94 | |||
95 | rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | ||
101 | struct rsnd_dai *rdai) | ||
102 | { | ||
103 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
104 | |||
105 | clk_disable_unprepare(dvc->clk); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int rsnd_dvc_start(struct rsnd_mod *mod, | ||
111 | struct rsnd_dai *rdai) | ||
112 | { | ||
113 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | ||
119 | struct rsnd_dai *rdai) | ||
120 | { | ||
121 | rsnd_mod_write(mod, CMD_CTRL, 0); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, | ||
127 | struct snd_ctl_elem_info *uinfo) | ||
128 | { | ||
129 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
130 | uinfo->count = RSND_DVC_VOLUME_NUM; | ||
131 | uinfo->value.integer.min = 0; | ||
132 | uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, | ||
138 | struct snd_ctl_elem_value *ucontrol) | ||
139 | { | ||
140 | struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); | ||
141 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
142 | int i; | ||
143 | |||
144 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
145 | ucontrol->value.integer.value[i] = dvc->volume[i]; | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, | ||
151 | struct snd_ctl_elem_value *ucontrol) | ||
152 | { | ||
153 | struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); | ||
154 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
155 | int i, change = 0; | ||
156 | |||
157 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { | ||
158 | if (ucontrol->value.integer.value[i] < 0 || | ||
159 | ucontrol->value.integer.value[i] > RSND_DVC_VOLUME_MAX) | ||
160 | return -EINVAL; | ||
161 | |||
162 | change |= (ucontrol->value.integer.value[i] != dvc->volume[i]); | ||
163 | } | ||
164 | |||
165 | if (change) { | ||
166 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
167 | dvc->volume[i] = ucontrol->value.integer.value[i]; | ||
168 | |||
169 | rsnd_dvc_volume_update(mod); | ||
170 | } | ||
171 | |||
172 | return change; | ||
173 | } | ||
174 | |||
175 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | ||
176 | struct rsnd_dai *rdai, | ||
177 | struct snd_soc_pcm_runtime *rtd) | ||
178 | { | ||
179 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
180 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
181 | struct device *dev = rsnd_priv_to_dev(priv); | ||
182 | struct snd_card *card = rtd->card->snd_card; | ||
183 | struct snd_kcontrol *kctrl; | ||
184 | static struct snd_kcontrol_new knew = { | ||
185 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
186 | .name = "Playback Volume", | ||
187 | .info = rsnd_dvc_volume_info, | ||
188 | .get = rsnd_dvc_volume_get, | ||
189 | .put = rsnd_dvc_volume_put, | ||
190 | }; | ||
191 | int ret; | ||
192 | |||
193 | if (!rsnd_dai_is_play(rdai, io)) { | ||
194 | dev_err(dev, "DVC%d is connected to Capture DAI\n", | ||
195 | rsnd_mod_id(mod)); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | kctrl = snd_ctl_new1(&knew, mod); | ||
200 | if (!kctrl) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | ret = snd_ctl_add(card, kctrl); | ||
204 | if (ret < 0) | ||
205 | return ret; | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static struct rsnd_mod_ops rsnd_dvc_ops = { | ||
211 | .name = "dvc (gen2)", | ||
212 | .init = rsnd_dvc_init, | ||
213 | .quit = rsnd_dvc_quit, | ||
214 | .start = rsnd_dvc_start, | ||
215 | .stop = rsnd_dvc_stop, | ||
216 | .pcm_new = rsnd_dvc_pcm_new, | ||
217 | }; | ||
218 | |||
219 | struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) | ||
220 | { | ||
221 | if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) | ||
222 | id = 0; | ||
223 | |||
224 | return &((struct rsnd_dvc *)(priv->dvc) + id)->mod; | ||
225 | } | ||
226 | |||
227 | int rsnd_dvc_probe(struct platform_device *pdev, | ||
228 | const struct rsnd_of_data *of_data, | ||
229 | struct rsnd_priv *priv) | ||
230 | { | ||
231 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
232 | struct device *dev = rsnd_priv_to_dev(priv); | ||
233 | struct rsnd_dvc *dvc; | ||
234 | struct clk *clk; | ||
235 | char name[RSND_DVC_NAME_SIZE]; | ||
236 | int i, nr; | ||
237 | |||
238 | nr = info->dvc_info_nr; | ||
239 | if (!nr) | ||
240 | return 0; | ||
241 | |||
242 | /* This driver doesn't support Gen1 at this point */ | ||
243 | if (rsnd_is_gen1(priv)) { | ||
244 | dev_warn(dev, "CMD is not supported on Gen1\n"); | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); | ||
249 | if (!dvc) { | ||
250 | dev_err(dev, "CMD allocate failed\n"); | ||
251 | return -ENOMEM; | ||
252 | } | ||
253 | |||
254 | priv->dvc_nr = nr; | ||
255 | priv->dvc = dvc; | ||
256 | |||
257 | for_each_rsnd_dvc(dvc, priv, i) { | ||
258 | snprintf(name, RSND_DVC_NAME_SIZE, "dvc.%d", i); | ||
259 | |||
260 | clk = devm_clk_get(dev, name); | ||
261 | if (IS_ERR(clk)) | ||
262 | return PTR_ERR(clk); | ||
263 | |||
264 | dvc->info = &info->dvc_info[i]; | ||
265 | dvc->clk = clk; | ||
266 | |||
267 | rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i); | ||
268 | |||
269 | dev_dbg(dev, "CMD%d probed\n", i); | ||
270 | } | ||
271 | |||
272 | return 0; | ||
273 | } | ||
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 50a1ef3eb1c6..a1583b57bf8d 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -181,6 +181,8 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
181 | RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), | 181 | RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), |
182 | RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), | 182 | RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), |
183 | RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), | 183 | RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), |
184 | RSND_GEN2_M_REG(gen, SCU, CMD_ROUTE_SLCT, 0x18c, 0x20), | ||
185 | RSND_GEN2_M_REG(gen, SCU, CMD_CTRL, 0x190, 0x20), | ||
184 | RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), | 186 | RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), |
185 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), | 187 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), |
186 | RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), | 188 | RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), |
@@ -189,6 +191,14 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
189 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), | 191 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), |
190 | RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), | 192 | RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), |
191 | RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), | 193 | RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), |
194 | RSND_GEN2_M_REG(gen, SCU, DVC_SWRSR, 0xe00, 0x100), | ||
195 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUIR, 0xe04, 0x100), | ||
196 | RSND_GEN2_M_REG(gen, SCU, DVC_ADINR, 0xe08, 0x100), | ||
197 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUCR, 0xe10, 0x100), | ||
198 | RSND_GEN2_M_REG(gen, SCU, DVC_ZCMCR, 0xe14, 0x100), | ||
199 | RSND_GEN2_M_REG(gen, SCU, DVC_VOL0R, 0xe28, 0x100), | ||
200 | RSND_GEN2_M_REG(gen, SCU, DVC_VOL1R, 0xe2c, 0x100), | ||
201 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUER, 0xe48, 0x100), | ||
192 | 202 | ||
193 | RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), | 203 | RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), |
194 | RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), | 204 | RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), |
@@ -207,6 +217,7 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
207 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), | 217 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), |
208 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), | 218 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), |
209 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), | 219 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), |
220 | RSND_GEN2_S_REG(gen, ADG, CMDOUT_TIMSEL, 0x5c), | ||
210 | 221 | ||
211 | RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), | 222 | RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), |
212 | RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), | 223 | RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), |
@@ -252,13 +263,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev, | |||
252 | return ret; | 263 | return ret; |
253 | 264 | ||
254 | dev_dbg(dev, "Gen2 device probed\n"); | 265 | dev_dbg(dev, "Gen2 device probed\n"); |
255 | dev_dbg(dev, "SCU : %08x => %p\n", scu_res->start, | 266 | dev_dbg(dev, "SCU : %pap => %p\n", &scu_res->start, |
256 | gen->base[RSND_GEN2_SCU]); | 267 | gen->base[RSND_GEN2_SCU]); |
257 | dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, | 268 | dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, |
258 | gen->base[RSND_GEN2_ADG]); | 269 | gen->base[RSND_GEN2_ADG]); |
259 | dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start, | 270 | dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start, |
260 | gen->base[RSND_GEN2_SSIU]); | 271 | gen->base[RSND_GEN2_SSIU]); |
261 | dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, | 272 | dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, |
262 | gen->base[RSND_GEN2_SSI]); | 273 | gen->base[RSND_GEN2_SSI]); |
263 | 274 | ||
264 | return 0; | 275 | return 0; |
@@ -345,11 +356,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev, | |||
345 | return ret; | 356 | return ret; |
346 | 357 | ||
347 | dev_dbg(dev, "Gen1 device probed\n"); | 358 | dev_dbg(dev, "Gen1 device probed\n"); |
348 | dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, | 359 | dev_dbg(dev, "SRU : %pap => %p\n", &sru_res->start, |
349 | gen->base[RSND_GEN1_SRU]); | 360 | gen->base[RSND_GEN1_SRU]); |
350 | dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, | 361 | dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, |
351 | gen->base[RSND_GEN1_ADG]); | 362 | gen->base[RSND_GEN1_ADG]); |
352 | dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, | 363 | dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, |
353 | gen->base[RSND_GEN1_SSI]); | 364 | gen->base[RSND_GEN1_SSI]); |
354 | 365 | ||
355 | return 0; | 366 | return 0; |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 619d198c7d2e..5aa790170b01 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -44,6 +44,15 @@ enum rsnd_reg { | |||
44 | RSND_REG_SRC_IFSCR, | 44 | RSND_REG_SRC_IFSCR, |
45 | RSND_REG_SRC_IFSVR, | 45 | RSND_REG_SRC_IFSVR, |
46 | RSND_REG_SRC_SRCCR, | 46 | RSND_REG_SRC_SRCCR, |
47 | RSND_REG_CMD_ROUTE_SLCT, | ||
48 | RSND_REG_DVC_SWRSR, | ||
49 | RSND_REG_DVC_DVUIR, | ||
50 | RSND_REG_DVC_ADINR, | ||
51 | RSND_REG_DVC_DVUCR, | ||
52 | RSND_REG_DVC_ZCMCR, | ||
53 | RSND_REG_DVC_VOL0R, | ||
54 | RSND_REG_DVC_VOL1R, | ||
55 | RSND_REG_DVC_DVUER, | ||
47 | 56 | ||
48 | /* ADG */ | 57 | /* ADG */ |
49 | RSND_REG_BRRA, | 58 | RSND_REG_BRRA, |
@@ -79,6 +88,8 @@ enum rsnd_reg { | |||
79 | RSND_REG_SHARE17, | 88 | RSND_REG_SHARE17, |
80 | RSND_REG_SHARE18, | 89 | RSND_REG_SHARE18, |
81 | RSND_REG_SHARE19, | 90 | RSND_REG_SHARE19, |
91 | RSND_REG_SHARE20, | ||
92 | RSND_REG_SHARE21, | ||
82 | 93 | ||
83 | RSND_REG_MAX, | 94 | RSND_REG_MAX, |
84 | }; | 95 | }; |
@@ -114,6 +125,8 @@ enum rsnd_reg { | |||
114 | #define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17 | 125 | #define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17 |
115 | #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 | 126 | #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 |
116 | #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 | 127 | #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 |
128 | #define RSND_REG_CMD_CTRL RSND_REG_SHARE20 | ||
129 | #define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 | ||
117 | 130 | ||
118 | struct rsnd_of_data; | 131 | struct rsnd_of_data; |
119 | struct rsnd_priv; | 132 | struct rsnd_priv; |
@@ -136,6 +149,7 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |||
136 | enum rsnd_reg reg, u32 data); | 149 | enum rsnd_reg reg, u32 data); |
137 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | 150 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
138 | u32 mask, u32 data); | 151 | u32 mask, u32 data); |
152 | u32 rsnd_get_adinr(struct rsnd_mod *mod); | ||
139 | 153 | ||
140 | /* | 154 | /* |
141 | * R-Car DMA | 155 | * R-Car DMA |
@@ -165,29 +179,27 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
165 | enum rsnd_mod_type { | 179 | enum rsnd_mod_type { |
166 | RSND_MOD_SRC = 0, | 180 | RSND_MOD_SRC = 0, |
167 | RSND_MOD_SSI, | 181 | RSND_MOD_SSI, |
182 | RSND_MOD_DVC, | ||
168 | RSND_MOD_MAX, | 183 | RSND_MOD_MAX, |
169 | }; | 184 | }; |
170 | 185 | ||
171 | struct rsnd_mod_ops { | 186 | struct rsnd_mod_ops { |
172 | char *name; | 187 | char *name; |
173 | int (*probe)(struct rsnd_mod *mod, | 188 | int (*probe)(struct rsnd_mod *mod, |
174 | struct rsnd_dai *rdai, | 189 | struct rsnd_dai *rdai); |
175 | struct rsnd_dai_stream *io); | ||
176 | int (*remove)(struct rsnd_mod *mod, | 190 | int (*remove)(struct rsnd_mod *mod, |
177 | struct rsnd_dai *rdai, | 191 | struct rsnd_dai *rdai); |
178 | struct rsnd_dai_stream *io); | ||
179 | int (*init)(struct rsnd_mod *mod, | 192 | int (*init)(struct rsnd_mod *mod, |
180 | struct rsnd_dai *rdai, | 193 | struct rsnd_dai *rdai); |
181 | struct rsnd_dai_stream *io); | ||
182 | int (*quit)(struct rsnd_mod *mod, | 194 | int (*quit)(struct rsnd_mod *mod, |
183 | struct rsnd_dai *rdai, | 195 | struct rsnd_dai *rdai); |
184 | struct rsnd_dai_stream *io); | ||
185 | int (*start)(struct rsnd_mod *mod, | 196 | int (*start)(struct rsnd_mod *mod, |
186 | struct rsnd_dai *rdai, | 197 | struct rsnd_dai *rdai); |
187 | struct rsnd_dai_stream *io); | ||
188 | int (*stop)(struct rsnd_mod *mod, | 198 | int (*stop)(struct rsnd_mod *mod, |
189 | struct rsnd_dai *rdai, | 199 | struct rsnd_dai *rdai); |
190 | struct rsnd_dai_stream *io); | 200 | int (*pcm_new)(struct rsnd_mod *mod, |
201 | struct rsnd_dai *rdai, | ||
202 | struct snd_soc_pcm_runtime *rtd); | ||
191 | }; | 203 | }; |
192 | 204 | ||
193 | struct rsnd_dai_stream; | 205 | struct rsnd_dai_stream; |
@@ -228,6 +240,7 @@ struct rsnd_dai_stream { | |||
228 | }; | 240 | }; |
229 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) | 241 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) |
230 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) | 242 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) |
243 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) | ||
231 | 244 | ||
232 | struct rsnd_dai { | 245 | struct rsnd_dai { |
233 | char name[RSND_DAI_NAME_SIZE]; | 246 | char name[RSND_DAI_NAME_SIZE]; |
@@ -291,6 +304,9 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
291 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 304 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
292 | struct rsnd_dai *rdai, | 305 | struct rsnd_dai *rdai, |
293 | struct rsnd_dai_stream *io); | 306 | struct rsnd_dai_stream *io); |
307 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | ||
308 | struct rsnd_mod *mod, | ||
309 | struct rsnd_dai_stream *io); | ||
294 | 310 | ||
295 | /* | 311 | /* |
296 | * R-Car sound priv | 312 | * R-Car sound priv |
@@ -328,6 +344,12 @@ struct rsnd_priv { | |||
328 | int ssi_nr; | 344 | int ssi_nr; |
329 | 345 | ||
330 | /* | 346 | /* |
347 | * below value will be filled on rsnd_dvc_probe() | ||
348 | */ | ||
349 | void *dvc; | ||
350 | int dvc_nr; | ||
351 | |||
352 | /* | ||
331 | * below value will be filled on rsnd_dai_probe() | 353 | * below value will be filled on rsnd_dai_probe() |
332 | */ | 354 | */ |
333 | struct snd_soc_dai_driver *daidrv; | 355 | struct snd_soc_dai_driver *daidrv; |
@@ -364,11 +386,9 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
364 | struct rsnd_dai_stream *io, | 386 | struct rsnd_dai_stream *io, |
365 | struct snd_pcm_runtime *runtime); | 387 | struct snd_pcm_runtime *runtime); |
366 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | 388 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, |
367 | struct rsnd_dai *rdai, | 389 | struct rsnd_dai *rdai); |
368 | struct rsnd_dai_stream *io); | ||
369 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, | 390 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, |
370 | struct rsnd_dai *rdai, | 391 | struct rsnd_dai *rdai); |
371 | struct rsnd_dai_stream *io); | ||
372 | 392 | ||
373 | #define rsnd_src_nr(priv) ((priv)->src_nr) | 393 | #define rsnd_src_nr(priv) ((priv)->src_nr) |
374 | 394 | ||
@@ -379,9 +399,19 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
379 | const struct rsnd_of_data *of_data, | 399 | const struct rsnd_of_data *of_data, |
380 | struct rsnd_priv *priv); | 400 | struct rsnd_priv *priv); |
381 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); | 401 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
382 | struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, | ||
383 | int dai_id, int is_play); | ||
384 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); | 402 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); |
385 | int rsnd_ssi_is_play(struct rsnd_mod *mod); | 403 | |
404 | /* | ||
405 | * R-Car DVC | ||
406 | */ | ||
407 | int rsnd_dvc_probe(struct platform_device *pdev, | ||
408 | const struct rsnd_of_data *of_data, | ||
409 | struct rsnd_priv *priv); | ||
410 | void rsnd_dvc_remove(struct platform_device *pdev, | ||
411 | struct rsnd_priv *priv); | ||
412 | struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); | ||
413 | |||
414 | #define rsnd_dvc_nr(priv) ((priv)->dvc_nr) | ||
415 | |||
386 | 416 | ||
387 | #endif | 417 | #endif |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 6232b7d307aa..e3b078e7c3aa 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -18,21 +18,9 @@ struct rsnd_src { | |||
18 | 18 | ||
19 | #define RSND_SRC_NAME_SIZE 16 | 19 | #define RSND_SRC_NAME_SIZE 16 |
20 | 20 | ||
21 | /* | ||
22 | * ADINR | ||
23 | */ | ||
24 | #define OTBL_24 (0 << 16) | ||
25 | #define OTBL_22 (2 << 16) | ||
26 | #define OTBL_20 (4 << 16) | ||
27 | #define OTBL_18 (6 << 16) | ||
28 | #define OTBL_16 (8 << 16) | ||
29 | |||
30 | #define rsnd_src_mode_flags(p) ((p)->info->flags) | ||
31 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) | 21 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) |
32 | #define rsnd_mod_to_src(_mod) \ | 22 | #define rsnd_mod_to_src(_mod) \ |
33 | container_of((_mod), struct rsnd_src, mod) | 23 | container_of((_mod), struct rsnd_src, mod) |
34 | #define rsnd_src_hpbif_is_enable(src) \ | ||
35 | (rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF) | ||
36 | #define rsnd_src_dma_available(src) \ | 24 | #define rsnd_src_dma_available(src) \ |
37 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) | 25 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) |
38 | 26 | ||
@@ -80,34 +68,35 @@ struct rsnd_src { | |||
80 | * | 68 | * |
81 | * This driver request | 69 | * This driver request |
82 | * struct rsnd_src_platform_info { | 70 | * struct rsnd_src_platform_info { |
83 | * u32 flags; | ||
84 | * u32 convert_rate; | 71 | * u32 convert_rate; |
72 | * int dma_id; | ||
85 | * } | 73 | * } |
86 | * | 74 | * |
87 | * rsnd_src_hpbif_is_enable() will be true | ||
88 | * if flags had RSND_SRC_USE_HPBIF, | ||
89 | * and it controls whether SSIU is used or not. | ||
90 | * | ||
91 | * rsnd_src_convert_rate() indicates | 75 | * rsnd_src_convert_rate() indicates |
92 | * above convert_rate, and it controls | 76 | * above convert_rate, and it controls |
93 | * whether SRC is used or not. | 77 | * whether SRC is used or not. |
94 | * | 78 | * |
95 | * ex) doesn't use SRC | 79 | * ex) doesn't use SRC |
96 | * struct rsnd_src_platform_info info = { | 80 | * static struct rsnd_dai_platform_info rsnd_dai = { |
97 | * .flags = 0, | 81 | * .playback = { .ssi = &rsnd_ssi[0], }, |
98 | * .convert_rate = 0, | ||
99 | * }; | 82 | * }; |
100 | * | 83 | * |
101 | * ex) uses SRC | 84 | * ex) uses SRC |
102 | * struct rsnd_src_platform_info info = { | 85 | * static struct rsnd_src_platform_info rsnd_src[] = { |
103 | * .flags = RSND_SRC_USE_HPBIF, | 86 | * RSND_SCU(48000, 0), |
104 | * .convert_rate = 48000, | 87 | * ... |
88 | * }; | ||
89 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
90 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
105 | * }; | 91 | * }; |
106 | * | 92 | * |
107 | * ex) uses SRC bypass mode | 93 | * ex) uses SRC bypass mode |
108 | * struct rsnd_src_platform_info info = { | 94 | * static struct rsnd_src_platform_info rsnd_src[] = { |
109 | * .flags = RSND_SRC_USE_HPBIF, | 95 | * RSND_SCU(0, 0), |
110 | * .convert_rate = 0, | 96 | * ... |
97 | * }; | ||
98 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
99 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
111 | * }; | 100 | * }; |
112 | * | 101 | * |
113 | */ | 102 | */ |
@@ -116,27 +105,17 @@ struct rsnd_src { | |||
116 | * Gen1/Gen2 common functions | 105 | * Gen1/Gen2 common functions |
117 | */ | 106 | */ |
118 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | 107 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, |
119 | struct rsnd_dai *rdai, | 108 | struct rsnd_dai *rdai) |
120 | struct rsnd_dai_stream *io) | ||
121 | { | 109 | { |
122 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 110 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); |
123 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 111 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
124 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
125 | int ssi_id = rsnd_mod_id(ssi_mod); | 112 | int ssi_id = rsnd_mod_id(ssi_mod); |
126 | int has_src = 0; | ||
127 | 113 | ||
128 | /* | 114 | /* |
129 | * SSI_MODE0 | 115 | * SSI_MODE0 |
130 | */ | 116 | */ |
131 | if (info->dai_info) { | ||
132 | has_src = !!src_mod; | ||
133 | } else { | ||
134 | struct rsnd_src *src = rsnd_mod_to_src(src_mod); | ||
135 | has_src = rsnd_src_hpbif_is_enable(src); | ||
136 | } | ||
137 | |||
138 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), | 117 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), |
139 | has_src ? 0 : (1 << ssi_id)); | 118 | src_mod ? 0 : (1 << ssi_id)); |
140 | 119 | ||
141 | /* | 120 | /* |
142 | * SSI_MODE1 | 121 | * SSI_MODE1 |
@@ -166,8 +145,7 @@ int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | |||
166 | } | 145 | } |
167 | 146 | ||
168 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, | 147 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, |
169 | struct rsnd_dai *rdai, | 148 | struct rsnd_dai *rdai) |
170 | struct rsnd_dai_stream *io) | ||
171 | { | 149 | { |
172 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 150 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
173 | 151 | ||
@@ -203,13 +181,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
203 | } | 181 | } |
204 | 182 | ||
205 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | 183 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, |
206 | struct rsnd_dai *rdai, | 184 | struct rsnd_dai *rdai) |
207 | struct rsnd_dai_stream *io) | ||
208 | { | 185 | { |
186 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
209 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 187 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
210 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 188 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
211 | u32 convert_rate = rsnd_src_convert_rate(src); | 189 | u32 convert_rate = rsnd_src_convert_rate(src); |
212 | u32 adinr = runtime->channels; | ||
213 | u32 fsrate = 0; | 190 | u32 fsrate = 0; |
214 | 191 | ||
215 | if (convert_rate) | 192 | if (convert_rate) |
@@ -226,17 +203,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
226 | rsnd_mod_write(mod, SRC_SRCIR, 1); | 203 | rsnd_mod_write(mod, SRC_SRCIR, 1); |
227 | 204 | ||
228 | /* Set channel number and output bit length */ | 205 | /* Set channel number and output bit length */ |
229 | switch (runtime->sample_bits) { | 206 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); |
230 | case 16: | ||
231 | adinr |= OTBL_16; | ||
232 | break; | ||
233 | case 32: | ||
234 | adinr |= OTBL_24; | ||
235 | break; | ||
236 | default: | ||
237 | return -EIO; | ||
238 | } | ||
239 | rsnd_mod_write(mod, SRC_ADINR, adinr); | ||
240 | 207 | ||
241 | /* Enable the initial value of IFS */ | 208 | /* Enable the initial value of IFS */ |
242 | if (fsrate) { | 209 | if (fsrate) { |
@@ -253,30 +220,27 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
253 | } | 220 | } |
254 | 221 | ||
255 | static int rsnd_src_init(struct rsnd_mod *mod, | 222 | static int rsnd_src_init(struct rsnd_mod *mod, |
256 | struct rsnd_dai *rdai, | 223 | struct rsnd_dai *rdai) |
257 | struct rsnd_dai_stream *io) | ||
258 | { | 224 | { |
259 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 225 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
260 | 226 | ||
261 | clk_enable(src->clk); | 227 | clk_prepare_enable(src->clk); |
262 | 228 | ||
263 | return 0; | 229 | return 0; |
264 | } | 230 | } |
265 | 231 | ||
266 | static int rsnd_src_quit(struct rsnd_mod *mod, | 232 | static int rsnd_src_quit(struct rsnd_mod *mod, |
267 | struct rsnd_dai *rdai, | 233 | struct rsnd_dai *rdai) |
268 | struct rsnd_dai_stream *io) | ||
269 | { | 234 | { |
270 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 235 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
271 | 236 | ||
272 | clk_disable(src->clk); | 237 | clk_disable_unprepare(src->clk); |
273 | 238 | ||
274 | return 0; | 239 | return 0; |
275 | } | 240 | } |
276 | 241 | ||
277 | static int rsnd_src_start(struct rsnd_mod *mod, | 242 | static int rsnd_src_start(struct rsnd_mod *mod, |
278 | struct rsnd_dai *rdai, | 243 | struct rsnd_dai *rdai) |
279 | struct rsnd_dai_stream *io) | ||
280 | { | 244 | { |
281 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 245 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
282 | 246 | ||
@@ -294,8 +258,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, | |||
294 | 258 | ||
295 | 259 | ||
296 | static int rsnd_src_stop(struct rsnd_mod *mod, | 260 | static int rsnd_src_stop(struct rsnd_mod *mod, |
297 | struct rsnd_dai *rdai, | 261 | struct rsnd_dai *rdai) |
298 | struct rsnd_dai_stream *io) | ||
299 | { | 262 | { |
300 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 263 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
301 | 264 | ||
@@ -313,9 +276,9 @@ static struct rsnd_mod_ops rsnd_src_non_ops = { | |||
313 | * Gen1 functions | 276 | * Gen1 functions |
314 | */ | 277 | */ |
315 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | 278 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, |
316 | struct rsnd_dai *rdai, | 279 | struct rsnd_dai *rdai) |
317 | struct rsnd_dai_stream *io) | ||
318 | { | 280 | { |
281 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
319 | struct src_route_config { | 282 | struct src_route_config { |
320 | u32 mask; | 283 | u32 mask; |
321 | int shift; | 284 | int shift; |
@@ -351,9 +314,9 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
351 | } | 314 | } |
352 | 315 | ||
353 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | 316 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, |
354 | struct rsnd_dai *rdai, | 317 | struct rsnd_dai *rdai) |
355 | struct rsnd_dai_stream *io) | ||
356 | { | 318 | { |
319 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
357 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 320 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
358 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 321 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
359 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 322 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -410,12 +373,11 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | |||
410 | } | 373 | } |
411 | 374 | ||
412 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | 375 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, |
413 | struct rsnd_dai *rdai, | 376 | struct rsnd_dai *rdai) |
414 | struct rsnd_dai_stream *io) | ||
415 | { | 377 | { |
416 | int ret; | 378 | int ret; |
417 | 379 | ||
418 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 380 | ret = rsnd_src_set_convert_rate(mod, rdai); |
419 | if (ret < 0) | 381 | if (ret < 0) |
420 | return ret; | 382 | return ret; |
421 | 383 | ||
@@ -432,24 +394,23 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | |||
432 | } | 394 | } |
433 | 395 | ||
434 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 396 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
435 | struct rsnd_dai *rdai, | 397 | struct rsnd_dai *rdai) |
436 | struct rsnd_dai_stream *io) | ||
437 | { | 398 | { |
438 | int ret; | 399 | int ret; |
439 | 400 | ||
440 | ret = rsnd_src_init(mod, rdai, io); | 401 | ret = rsnd_src_init(mod, rdai); |
441 | if (ret < 0) | 402 | if (ret < 0) |
442 | return ret; | 403 | return ret; |
443 | 404 | ||
444 | ret = rsnd_src_set_route_gen1(mod, rdai, io); | 405 | ret = rsnd_src_set_route_gen1(mod, rdai); |
445 | if (ret < 0) | 406 | if (ret < 0) |
446 | return ret; | 407 | return ret; |
447 | 408 | ||
448 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io); | 409 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai); |
449 | if (ret < 0) | 410 | if (ret < 0) |
450 | return ret; | 411 | return ret; |
451 | 412 | ||
452 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io); | 413 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai); |
453 | if (ret < 0) | 414 | if (ret < 0) |
454 | return ret; | 415 | return ret; |
455 | 416 | ||
@@ -457,25 +418,23 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
457 | } | 418 | } |
458 | 419 | ||
459 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 420 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
460 | struct rsnd_dai *rdai, | 421 | struct rsnd_dai *rdai) |
461 | struct rsnd_dai_stream *io) | ||
462 | { | 422 | { |
463 | int id = rsnd_mod_id(mod); | 423 | int id = rsnd_mod_id(mod); |
464 | 424 | ||
465 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); | 425 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); |
466 | 426 | ||
467 | return rsnd_src_start(mod, rdai, io); | 427 | return rsnd_src_start(mod, rdai); |
468 | } | 428 | } |
469 | 429 | ||
470 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 430 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
471 | struct rsnd_dai *rdai, | 431 | struct rsnd_dai *rdai) |
472 | struct rsnd_dai_stream *io) | ||
473 | { | 432 | { |
474 | int id = rsnd_mod_id(mod); | 433 | int id = rsnd_mod_id(mod); |
475 | 434 | ||
476 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); | 435 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); |
477 | 436 | ||
478 | return rsnd_src_stop(mod, rdai, io); | 437 | return rsnd_src_stop(mod, rdai); |
479 | } | 438 | } |
480 | 439 | ||
481 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { | 440 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { |
@@ -490,17 +449,16 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { | |||
490 | * Gen2 functions | 449 | * Gen2 functions |
491 | */ | 450 | */ |
492 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | 451 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, |
493 | struct rsnd_dai *rdai, | 452 | struct rsnd_dai *rdai) |
494 | struct rsnd_dai_stream *io) | ||
495 | { | 453 | { |
496 | int ret; | 454 | int ret; |
497 | 455 | ||
498 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 456 | ret = rsnd_src_set_convert_rate(mod, rdai); |
499 | if (ret < 0) | 457 | if (ret < 0) |
500 | return ret; | 458 | return ret; |
501 | 459 | ||
502 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR)); | 460 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod)); |
503 | rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE)); | 461 | rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); |
504 | 462 | ||
505 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); | 463 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); |
506 | 464 | ||
@@ -511,9 +469,9 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
511 | } | 469 | } |
512 | 470 | ||
513 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | 471 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, |
514 | struct rsnd_dai *rdai, | 472 | struct rsnd_dai *rdai) |
515 | struct rsnd_dai_stream *io) | ||
516 | { | 473 | { |
474 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
517 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 475 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
518 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 476 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
519 | u32 convert_rate = rsnd_src_convert_rate(src); | 477 | u32 convert_rate = rsnd_src_convert_rate(src); |
@@ -530,25 +488,16 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | |||
530 | } | 488 | } |
531 | 489 | ||
532 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 490 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
533 | struct rsnd_dai *rdai, | 491 | struct rsnd_dai *rdai) |
534 | struct rsnd_dai_stream *io) | ||
535 | { | 492 | { |
536 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 493 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
537 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
538 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 494 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
539 | struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod)); | ||
540 | struct device *dev = rsnd_priv_to_dev(priv); | 495 | struct device *dev = rsnd_priv_to_dev(priv); |
541 | int ret; | 496 | int ret; |
542 | int is_play; | ||
543 | |||
544 | if (info->dai_info) | ||
545 | is_play = rsnd_info_is_playback(priv, src); | ||
546 | else | ||
547 | is_play = rsnd_ssi_is_play(ssi); | ||
548 | 497 | ||
549 | ret = rsnd_dma_init(priv, | 498 | ret = rsnd_dma_init(priv, |
550 | rsnd_mod_to_dma(mod), | 499 | rsnd_mod_to_dma(mod), |
551 | is_play, | 500 | rsnd_info_is_playback(priv, src), |
552 | src->info->dma_id); | 501 | src->info->dma_id); |
553 | if (ret < 0) | 502 | if (ret < 0) |
554 | dev_err(dev, "SRC DMA failed\n"); | 503 | dev_err(dev, "SRC DMA failed\n"); |
@@ -557,8 +506,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
557 | } | 506 | } |
558 | 507 | ||
559 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 508 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
560 | struct rsnd_dai *rdai, | 509 | struct rsnd_dai *rdai) |
561 | struct rsnd_dai_stream *io) | ||
562 | { | 510 | { |
563 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 511 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); |
564 | 512 | ||
@@ -566,20 +514,19 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | |||
566 | } | 514 | } |
567 | 515 | ||
568 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 516 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
569 | struct rsnd_dai *rdai, | 517 | struct rsnd_dai *rdai) |
570 | struct rsnd_dai_stream *io) | ||
571 | { | 518 | { |
572 | int ret; | 519 | int ret; |
573 | 520 | ||
574 | ret = rsnd_src_init(mod, rdai, io); | 521 | ret = rsnd_src_init(mod, rdai); |
575 | if (ret < 0) | 522 | if (ret < 0) |
576 | return ret; | 523 | return ret; |
577 | 524 | ||
578 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io); | 525 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai); |
579 | if (ret < 0) | 526 | if (ret < 0) |
580 | return ret; | 527 | return ret; |
581 | 528 | ||
582 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io); | 529 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai); |
583 | if (ret < 0) | 530 | if (ret < 0) |
584 | return ret; | 531 | return ret; |
585 | 532 | ||
@@ -587,22 +534,22 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
587 | } | 534 | } |
588 | 535 | ||
589 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 536 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
590 | struct rsnd_dai *rdai, | 537 | struct rsnd_dai *rdai) |
591 | struct rsnd_dai_stream *io) | ||
592 | { | 538 | { |
539 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
593 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 540 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
541 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
594 | 542 | ||
595 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); | 543 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); |
596 | 544 | ||
597 | rsnd_mod_write(mod, SSI_CTRL, 0x1); | 545 | rsnd_mod_write(mod, SSI_CTRL, 0x1); |
598 | rsnd_mod_write(mod, SRC_CTRL, 0x11); | 546 | rsnd_mod_write(mod, SRC_CTRL, val); |
599 | 547 | ||
600 | return rsnd_src_start(mod, rdai, io); | 548 | return rsnd_src_start(mod, rdai); |
601 | } | 549 | } |
602 | 550 | ||
603 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 551 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
604 | struct rsnd_dai *rdai, | 552 | struct rsnd_dai *rdai) |
605 | struct rsnd_dai_stream *io) | ||
606 | { | 553 | { |
607 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 554 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
608 | 555 | ||
@@ -611,7 +558,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | |||
611 | 558 | ||
612 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); | 559 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); |
613 | 560 | ||
614 | return rsnd_src_stop(mod, rdai, io); | 561 | return rsnd_src_stop(mod, rdai); |
615 | } | 562 | } |
616 | 563 | ||
617 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { | 564 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { |
@@ -699,11 +646,6 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
699 | snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i); | 646 | snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i); |
700 | 647 | ||
701 | clk = devm_clk_get(dev, name); | 648 | clk = devm_clk_get(dev, name); |
702 | if (IS_ERR(clk)) { | ||
703 | snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i); | ||
704 | clk = devm_clk_get(dev, name); | ||
705 | } | ||
706 | |||
707 | if (IS_ERR(clk)) | 649 | if (IS_ERR(clk)) |
708 | return PTR_ERR(clk); | 650 | return PTR_ERR(clk); |
709 | 651 | ||
@@ -711,12 +653,10 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
711 | src->clk = clk; | 653 | src->clk = clk; |
712 | 654 | ||
713 | ops = &rsnd_src_non_ops; | 655 | ops = &rsnd_src_non_ops; |
714 | if (rsnd_src_hpbif_is_enable(src)) { | 656 | if (rsnd_is_gen1(priv)) |
715 | if (rsnd_is_gen1(priv)) | 657 | ops = &rsnd_src_gen1_ops; |
716 | ops = &rsnd_src_gen1_ops; | 658 | if (rsnd_is_gen2(priv)) |
717 | if (rsnd_is_gen2(priv)) | 659 | ops = &rsnd_src_gen2_ops; |
718 | ops = &rsnd_src_gen2_ops; | ||
719 | } | ||
720 | 660 | ||
721 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); | 661 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); |
722 | 662 | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 4b7e20603dd7..36654bd4e428 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -171,7 +171,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
171 | u32 cr; | 171 | u32 cr; |
172 | 172 | ||
173 | if (0 == ssi->usrcnt) { | 173 | if (0 == ssi->usrcnt) { |
174 | clk_enable(ssi->clk); | 174 | clk_prepare_enable(ssi->clk); |
175 | 175 | ||
176 | if (rsnd_dai_is_clk_master(rdai)) { | 176 | if (rsnd_dai_is_clk_master(rdai)) { |
177 | if (rsnd_ssi_clk_from_parent(ssi)) | 177 | if (rsnd_ssi_clk_from_parent(ssi)) |
@@ -230,7 +230,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
230 | rsnd_ssi_master_clk_stop(ssi); | 230 | rsnd_ssi_master_clk_stop(ssi); |
231 | } | 231 | } |
232 | 232 | ||
233 | clk_disable(ssi->clk); | 233 | clk_disable_unprepare(ssi->clk); |
234 | } | 234 | } |
235 | 235 | ||
236 | dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); | 236 | dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); |
@@ -240,10 +240,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
240 | * SSI mod common functions | 240 | * SSI mod common functions |
241 | */ | 241 | */ |
242 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 242 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
243 | struct rsnd_dai *rdai, | 243 | struct rsnd_dai *rdai) |
244 | struct rsnd_dai_stream *io) | ||
245 | { | 244 | { |
246 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 245 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
246 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
248 | u32 cr; | 248 | u32 cr; |
249 | 249 | ||
@@ -287,14 +287,13 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
287 | ssi->cr_own = cr; | 287 | ssi->cr_own = cr; |
288 | ssi->err = -1; /* ignore 1st error */ | 288 | ssi->err = -1; /* ignore 1st error */ |
289 | 289 | ||
290 | rsnd_src_ssi_mode_init(mod, rdai, io); | 290 | rsnd_src_ssi_mode_init(mod, rdai); |
291 | 291 | ||
292 | return 0; | 292 | return 0; |
293 | } | 293 | } |
294 | 294 | ||
295 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 295 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
296 | struct rsnd_dai *rdai, | 296 | struct rsnd_dai *rdai) |
297 | struct rsnd_dai_stream *io) | ||
298 | { | 297 | { |
299 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 298 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
300 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 299 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -359,8 +358,7 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) | |||
359 | } | 358 | } |
360 | 359 | ||
361 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 360 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
362 | struct rsnd_dai *rdai, | 361 | struct rsnd_dai *rdai) |
363 | struct rsnd_dai_stream *io) | ||
364 | { | 362 | { |
365 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 363 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
366 | struct device *dev = rsnd_priv_to_dev(priv); | 364 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -379,15 +377,15 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | |||
379 | } | 377 | } |
380 | 378 | ||
381 | static int rsnd_ssi_pio_start(struct rsnd_mod *mod, | 379 | static int rsnd_ssi_pio_start(struct rsnd_mod *mod, |
382 | struct rsnd_dai *rdai, | 380 | struct rsnd_dai *rdai) |
383 | struct rsnd_dai_stream *io) | ||
384 | { | 381 | { |
385 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 382 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
383 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
386 | 384 | ||
387 | /* enable PIO IRQ */ | 385 | /* enable PIO IRQ */ |
388 | ssi->cr_etc = UIEN | OIEN | DIEN; | 386 | ssi->cr_etc = UIEN | OIEN | DIEN; |
389 | 387 | ||
390 | rsnd_src_enable_ssi_irq(mod, rdai, io); | 388 | rsnd_src_enable_ssi_irq(mod, rdai); |
391 | 389 | ||
392 | rsnd_ssi_hw_start(ssi, rdai, io); | 390 | rsnd_ssi_hw_start(ssi, rdai, io); |
393 | 391 | ||
@@ -395,8 +393,7 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, | |||
395 | } | 393 | } |
396 | 394 | ||
397 | static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, | 395 | static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, |
398 | struct rsnd_dai *rdai, | 396 | struct rsnd_dai *rdai) |
399 | struct rsnd_dai_stream *io) | ||
400 | { | 397 | { |
401 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 398 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
402 | 399 | ||
@@ -417,25 +414,17 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
417 | }; | 414 | }; |
418 | 415 | ||
419 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 416 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
420 | struct rsnd_dai *rdai, | 417 | struct rsnd_dai *rdai) |
421 | struct rsnd_dai_stream *io) | ||
422 | { | 418 | { |
423 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 419 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
424 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 420 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
425 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
426 | struct device *dev = rsnd_priv_to_dev(priv); | 421 | struct device *dev = rsnd_priv_to_dev(priv); |
427 | int dma_id = ssi->info->dma_id; | 422 | int dma_id = ssi->info->dma_id; |
428 | int is_play; | ||
429 | int ret; | 423 | int ret; |
430 | 424 | ||
431 | if (info->dai_info) | ||
432 | is_play = rsnd_info_is_playback(priv, ssi); | ||
433 | else | ||
434 | is_play = rsnd_ssi_is_play(&ssi->mod); | ||
435 | |||
436 | ret = rsnd_dma_init( | 425 | ret = rsnd_dma_init( |
437 | priv, rsnd_mod_to_dma(mod), | 426 | priv, rsnd_mod_to_dma(mod), |
438 | is_play, | 427 | rsnd_info_is_playback(priv, ssi), |
439 | dma_id); | 428 | dma_id); |
440 | 429 | ||
441 | if (ret < 0) | 430 | if (ret < 0) |
@@ -445,8 +434,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | |||
445 | } | 434 | } |
446 | 435 | ||
447 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 436 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
448 | struct rsnd_dai *rdai, | 437 | struct rsnd_dai *rdai) |
449 | struct rsnd_dai_stream *io) | ||
450 | { | 438 | { |
451 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 439 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); |
452 | 440 | ||
@@ -454,11 +442,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
454 | } | 442 | } |
455 | 443 | ||
456 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 444 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
457 | struct rsnd_dai *rdai, | 445 | struct rsnd_dai *rdai) |
458 | struct rsnd_dai_stream *io) | ||
459 | { | 446 | { |
460 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 447 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
461 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); | 448 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); |
449 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
462 | 450 | ||
463 | /* enable DMA transfer */ | 451 | /* enable DMA transfer */ |
464 | ssi->cr_etc = DMEN; | 452 | ssi->cr_etc = DMEN; |
@@ -475,8 +463,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | |||
475 | } | 463 | } |
476 | 464 | ||
477 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 465 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
478 | struct rsnd_dai *rdai, | 466 | struct rsnd_dai *rdai) |
479 | struct rsnd_dai_stream *io) | ||
480 | { | 467 | { |
481 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 468 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
482 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); | 469 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); |
@@ -512,41 +499,6 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = { | |||
512 | /* | 499 | /* |
513 | * ssi mod function | 500 | * ssi mod function |
514 | */ | 501 | */ |
515 | struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, | ||
516 | int dai_id, int is_play) | ||
517 | { | ||
518 | struct rsnd_dai_platform_info *dai_info = NULL; | ||
519 | struct rsnd_dai_path_info *path_info = NULL; | ||
520 | struct rsnd_ssi_platform_info *target_info = NULL; | ||
521 | struct rsnd_ssi *ssi; | ||
522 | int i, has_play; | ||
523 | |||
524 | if (priv->rdai) | ||
525 | dai_info = priv->rdai[dai_id].info; | ||
526 | if (dai_info) | ||
527 | path_info = (is_play) ? &dai_info->playback : &dai_info->capture; | ||
528 | if (path_info) | ||
529 | target_info = path_info->ssi; | ||
530 | |||
531 | is_play = !!is_play; | ||
532 | |||
533 | for_each_rsnd_ssi(ssi, priv, i) { | ||
534 | if (target_info == ssi->info) | ||
535 | return &ssi->mod; | ||
536 | |||
537 | /* for compatible */ | ||
538 | if (rsnd_ssi_dai_id(ssi) != dai_id) | ||
539 | continue; | ||
540 | |||
541 | has_play = rsnd_ssi_is_play(&ssi->mod); | ||
542 | |||
543 | if (is_play == has_play) | ||
544 | return &ssi->mod; | ||
545 | } | ||
546 | |||
547 | return NULL; | ||
548 | } | ||
549 | |||
550 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) | 502 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) |
551 | { | 503 | { |
552 | if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) | 504 | if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) |
@@ -562,13 +514,6 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) | |||
562 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); | 514 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); |
563 | } | 515 | } |
564 | 516 | ||
565 | int rsnd_ssi_is_play(struct rsnd_mod *mod) | ||
566 | { | ||
567 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
568 | |||
569 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY); | ||
570 | } | ||
571 | |||
572 | static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) | 517 | static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) |
573 | { | 518 | { |
574 | if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) | 519 | if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) |