diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2014-03-03 23:50:00 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-03-05 01:07:52 -0500 |
commit | 389933d9f6e55a1ef3a71549c36f6283b9f8c145 (patch) | |
tree | 3e18c692e135d01620e6f225bdf36d9e2169de04 | |
parent | 78f13d0c5a2888564b2bed7f8433c8ec889997ff (diff) |
ASoC: rsnd: Get correct SCU ID
Current rsnd driver is assuming that SCU/SRU ID is
same as SSIU/SSI ID, because Gen1 can't select it.
But, Gen2 can select it.
The SCU/SRU/SSIU/SSI pair depends on the platform.
This patch get correct SCU ID from platform info.
To keep compatible, it still assuming SCU ID = SSI ID
if platform doesn't have info
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | include/sound/rcar_snd.h | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 47 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 14 | ||||
-rw-r--r-- | sound/soc/sh/rcar/scu.c | 21 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 9 |
5 files changed, 72 insertions, 20 deletions
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h index 698f7b5fc76d..1d8c68323f49 100644 --- a/include/sound/rcar_snd.h +++ b/include/sound/rcar_snd.h | |||
@@ -70,6 +70,7 @@ struct rsnd_scu_platform_info { | |||
70 | 70 | ||
71 | struct rsnd_dai_path_info { | 71 | struct rsnd_dai_path_info { |
72 | struct rsnd_ssi_platform_info *ssi; | 72 | struct rsnd_ssi_platform_info *ssi; |
73 | struct rsnd_scu_platform_info *scu; | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | struct rsnd_dai_platform_info { | 76 | struct rsnd_dai_platform_info { |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 450472633eb1..7316d10e4649 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -107,6 +107,11 @@ | |||
107 | (!(priv->info->func) ? 0 : \ | 107 | (!(priv->info->func) ? 0 : \ |
108 | priv->info->func(param)) | 108 | priv->info->func(param)) |
109 | 109 | ||
110 | #define rsnd_is_enable_path(io, name) \ | ||
111 | ((io)->info ? (io)->info->name : NULL) | ||
112 | #define rsnd_info_id(priv, io, name) \ | ||
113 | ((io)->info->name - priv->info->name##_info) | ||
114 | |||
110 | /* | 115 | /* |
111 | * rsnd_mod functions | 116 | * rsnd_mod functions |
112 | */ | 117 | */ |
@@ -572,8 +577,10 @@ static int rsnd_path_init(struct rsnd_priv *priv, | |||
572 | struct rsnd_dai_stream *io) | 577 | struct rsnd_dai_stream *io) |
573 | { | 578 | { |
574 | struct rsnd_mod *mod; | 579 | struct rsnd_mod *mod; |
580 | struct rsnd_dai_platform_info *dai_info = rdai->info; | ||
575 | int ret; | 581 | int ret; |
576 | int id; | 582 | int ssi_id = -1; |
583 | int scu_id = -1; | ||
577 | 584 | ||
578 | /* | 585 | /* |
579 | * Gen1 is created by SRU/SSI, and this SRU is base module of | 586 | * Gen1 is created by SRU/SSI, and this SRU is base module of |
@@ -584,29 +591,35 @@ static int rsnd_path_init(struct rsnd_priv *priv, | |||
584 | * | 591 | * |
585 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is | 592 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is |
586 | * using fixed path. | 593 | * using fixed path. |
587 | * | ||
588 | * Then, SSI id = SCU id here | ||
589 | */ | 594 | */ |
590 | /* get SSI's ID */ | 595 | if (dai_info) { |
591 | mod = rsnd_ssi_mod_get_frm_dai(priv, | 596 | if (rsnd_is_enable_path(io, ssi)) |
592 | rsnd_dai_id(priv, rdai), | 597 | ssi_id = rsnd_info_id(priv, io, ssi); |
593 | rsnd_dai_is_play(rdai, io)); | 598 | if (rsnd_is_enable_path(io, scu)) |
594 | if (!mod) | 599 | scu_id = rsnd_info_id(priv, io, scu); |
595 | return 0; | 600 | } else { |
596 | id = rsnd_mod_id(mod); | 601 | /* get SSI's ID */ |
602 | mod = rsnd_ssi_mod_get_frm_dai(priv, | ||
603 | rsnd_dai_id(priv, rdai), | ||
604 | rsnd_dai_is_play(rdai, io)); | ||
605 | if (!mod) | ||
606 | return 0; | ||
607 | ssi_id = scu_id = rsnd_mod_id(mod); | ||
608 | } | ||
609 | |||
597 | ret = 0; | 610 | ret = 0; |
598 | 611 | ||
599 | /* SCU */ | 612 | /* SCU */ |
600 | mod = rsnd_scu_mod_get(priv, id); | 613 | if (scu_id >= 0) { |
601 | if (mod) { | 614 | mod = rsnd_scu_mod_get(priv, scu_id); |
602 | ret = rsnd_dai_connect(mod, io); | 615 | ret = rsnd_dai_connect(mod, io); |
603 | if (ret < 0) | 616 | if (ret < 0) |
604 | return ret; | 617 | return ret; |
605 | } | 618 | } |
606 | 619 | ||
607 | /* SSI */ | 620 | /* SSI */ |
608 | mod = rsnd_ssi_mod_get(priv, id); | 621 | if (ssi_id >= 0) { |
609 | if (mod) { | 622 | mod = rsnd_ssi_mod_get(priv, ssi_id); |
610 | ret = rsnd_dai_connect(mod, io); | 623 | ret = rsnd_dai_connect(mod, io); |
611 | if (ret < 0) | 624 | if (ret < 0) |
612 | return ret; | 625 | return ret; |
@@ -699,6 +712,9 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
699 | drv[i].playback.formats = RSND_FMTS; | 712 | drv[i].playback.formats = RSND_FMTS; |
700 | drv[i].playback.channels_min = 2; | 713 | drv[i].playback.channels_min = 2; |
701 | drv[i].playback.channels_max = 2; | 714 | drv[i].playback.channels_max = 2; |
715 | |||
716 | if (info->dai_info) | ||
717 | rdai[i].playback.info = &info->dai_info[i].playback; | ||
702 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); | 718 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); |
703 | } | 719 | } |
704 | if (cmod) { | 720 | if (cmod) { |
@@ -706,6 +722,9 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
706 | drv[i].capture.formats = RSND_FMTS; | 722 | drv[i].capture.formats = RSND_FMTS; |
707 | drv[i].capture.channels_min = 2; | 723 | drv[i].capture.channels_min = 2; |
708 | drv[i].capture.channels_max = 2; | 724 | drv[i].capture.channels_max = 2; |
725 | |||
726 | if (info->dai_info) | ||
727 | rdai[i].capture.info = &info->dai_info[i].capture; | ||
709 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); | 728 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); |
710 | } | 729 | } |
711 | 730 | ||
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index d5afdee6b6f2..3472631c7b35 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -211,6 +211,7 @@ char *rsnd_mod_name(struct rsnd_mod *mod); | |||
211 | struct rsnd_dai_stream { | 211 | struct rsnd_dai_stream { |
212 | struct snd_pcm_substream *substream; | 212 | struct snd_pcm_substream *substream; |
213 | struct rsnd_mod *mod[RSND_MOD_MAX]; | 213 | struct rsnd_mod *mod[RSND_MOD_MAX]; |
214 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ | ||
214 | int byte_pos; | 215 | int byte_pos; |
215 | int period_pos; | 216 | int period_pos; |
216 | int byte_per_period; | 217 | int byte_per_period; |
@@ -328,6 +329,19 @@ struct rsnd_priv { | |||
328 | #define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) | 329 | #define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) |
329 | #define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) | 330 | #define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) |
330 | 331 | ||
332 | #define rsnd_info_is_playback(priv, type) \ | ||
333 | ({ \ | ||
334 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); \ | ||
335 | int i, is_play = 0; \ | ||
336 | for (i = 0; i < info->dai_info_nr; i++) { \ | ||
337 | if (info->dai_info[i].playback.type == (type)->info) { \ | ||
338 | is_play = 1; \ | ||
339 | break; \ | ||
340 | } \ | ||
341 | } \ | ||
342 | is_play; \ | ||
343 | }) | ||
344 | |||
331 | /* | 345 | /* |
332 | * R-Car SCU | 346 | * R-Car SCU |
333 | */ | 347 | */ |
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c index 1073d35486e3..b517300f32ce 100644 --- a/sound/soc/sh/rcar/scu.c +++ b/sound/soc/sh/rcar/scu.c | |||
@@ -620,6 +620,9 @@ int rsnd_scu_probe(struct platform_device *pdev, | |||
620 | * init SCU | 620 | * init SCU |
621 | */ | 621 | */ |
622 | nr = info->scu_info_nr; | 622 | nr = info->scu_info_nr; |
623 | if (!nr) | ||
624 | return 0; | ||
625 | |||
623 | scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL); | 626 | scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL); |
624 | if (!scu) { | 627 | if (!scu) { |
625 | dev_err(dev, "SCU allocate failed\n"); | 628 | dev_err(dev, "SCU allocate failed\n"); |
@@ -644,11 +647,19 @@ int rsnd_scu_probe(struct platform_device *pdev, | |||
644 | if (rsnd_is_gen1(priv)) | 647 | if (rsnd_is_gen1(priv)) |
645 | ops = &rsnd_scu_gen1_ops; | 648 | ops = &rsnd_scu_gen1_ops; |
646 | if (rsnd_is_gen2(priv)) { | 649 | if (rsnd_is_gen2(priv)) { |
647 | struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i); | 650 | int ret; |
648 | int ret = rsnd_dma_init(priv, | 651 | int is_play; |
649 | rsnd_mod_to_dma(&scu->mod), | 652 | |
650 | rsnd_ssi_is_play(ssi), | 653 | if (info->dai_info) { |
651 | scu->info->dma_id); | 654 | is_play = rsnd_info_is_playback(priv, scu); |
655 | } else { | ||
656 | struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i); | ||
657 | is_play = rsnd_ssi_is_play(ssi); | ||
658 | } | ||
659 | ret = rsnd_dma_init(priv, | ||
660 | rsnd_mod_to_dma(&scu->mod), | ||
661 | is_play, | ||
662 | scu->info->dma_id); | ||
652 | if (ret < 0) | 663 | if (ret < 0) |
653 | return ret; | 664 | return ret; |
654 | 665 | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 34234813f742..9162c2bb6cc5 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -567,9 +567,16 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
567 | * SSI DMA case | 567 | * SSI DMA case |
568 | */ | 568 | */ |
569 | if (pinfo->dma_id > 0) { | 569 | if (pinfo->dma_id > 0) { |
570 | int is_play; | ||
571 | |||
572 | if (info->dai_info) | ||
573 | is_play = rsnd_info_is_playback(priv, ssi); | ||
574 | else | ||
575 | is_play = rsnd_ssi_is_play(&ssi->mod); | ||
576 | |||
570 | ret = rsnd_dma_init( | 577 | ret = rsnd_dma_init( |
571 | priv, rsnd_mod_to_dma(&ssi->mod), | 578 | priv, rsnd_mod_to_dma(&ssi->mod), |
572 | rsnd_ssi_is_play(&ssi->mod), | 579 | is_play, |
573 | pinfo->dma_id); | 580 | pinfo->dma_id); |
574 | if (ret < 0) | 581 | if (ret < 0) |
575 | dev_info(dev, "SSI DMA failed. try PIO transter\n"); | 582 | dev_info(dev, "SSI DMA failed. try PIO transter\n"); |