aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2014-05-08 20:44:49 -0400
committerMark Brown <broonie@linaro.org>2014-05-13 14:06:16 -0400
commitbff58ea4f43d9b4a9fd6fb05fabc8f50f68131f5 (patch)
tree75fd6981582c0206a5152a6c9d377e3295a2eebf
parent68b6af3656a1f3303cca094a19e26653fad1853a (diff)
ASoC: rsnd: add DVC support
This patch adds DVC (Digital Volume Controller) support which is member of CMD unit. 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.h10
-rw-r--r--sound/soc/sh/rcar/Makefile2
-rw-r--r--sound/soc/sh/rcar/adg.c18
-rw-r--r--sound/soc/sh/rcar/core.c20
-rw-r--r--sound/soc/sh/rcar/dvc.c273
-rw-r--r--sound/soc/sh/rcar/gen.c11
-rw-r--r--sound/soc/sh/rcar/rsnd.h40
-rw-r--r--sound/soc/sh/rcar/src.c4
8 files changed, 376 insertions, 2 deletions
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
index a03268ec59c3..f4a706f82cb7 100644
--- a/include/sound/rcar_snd.h
+++ b/include/sound/rcar_snd.h
@@ -56,9 +56,17 @@ struct rsnd_src_platform_info {
56 int dma_id; /* for Gen2 SCU */ 56 int dma_id; /* for Gen2 SCU */
57}; 57};
58 58
59/*
60 * flags
61 */
62struct rsnd_dvc_platform_info {
63 u32 flags;
64};
65
59struct rsnd_dai_path_info { 66struct rsnd_dai_path_info {
60 struct rsnd_ssi_platform_info *ssi; 67 struct rsnd_ssi_platform_info *ssi;
61 struct rsnd_src_platform_info *src; 68 struct rsnd_src_platform_info *src;
69 struct rsnd_dvc_platform_info *dvc;
62}; 70};
63 71
64struct rsnd_dai_platform_info { 72struct rsnd_dai_platform_info {
@@ -83,6 +91,8 @@ struct rcar_snd_info {
83 int ssi_info_nr; 91 int ssi_info_nr;
84 struct rsnd_src_platform_info *src_info; 92 struct rsnd_src_platform_info *src_info;
85 int src_info_nr; 93 int src_info_nr;
94 struct rsnd_dvc_platform_info *dvc_info;
95 int dvc_info_nr;
86 struct rsnd_dai_platform_info *dai_info; 96 struct rsnd_dai_platform_info *dai_info;
87 int dai_info_nr; 97 int dai_info_nr;
88 int (*start)(int id); 98 int (*start)(int id);
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 @@
1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o 1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file 2obj-$(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 41556b2ef21e..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
60int 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
60static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, 78static 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,
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 378985b028ef..1f6981a56354 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -645,6 +645,11 @@ static int rsnd_path_init(struct rsnd_priv *priv,
645 if (ret < 0) 645 if (ret < 0)
646 return ret; 646 return ret;
647 647
648 /* DVC */
649 ret = rsnd_path_parse(priv, io, dvc);
650 if (ret < 0)
651 return ret;
652
648 return ret; 653 return ret;
649} 654}
650 655
@@ -869,6 +874,20 @@ static struct snd_pcm_ops rsnd_pcm_ops = {
869 874
870static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) 875static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
871{ 876{
877 struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
878 struct rsnd_dai *rdai;
879 int i, ret;
880
881 for_each_rsnd_dai(rdai, priv, i) {
882 ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd);
883 if (ret)
884 return ret;
885
886 ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd);
887 if (ret)
888 return ret;
889 }
890
872 return snd_pcm_lib_preallocate_pages_for_all( 891 return snd_pcm_lib_preallocate_pages_for_all(
873 rtd->pcm, 892 rtd->pcm,
874 SNDRV_DMA_TYPE_DEV, 893 SNDRV_DMA_TYPE_DEV,
@@ -908,6 +927,7 @@ static int rsnd_probe(struct platform_device *pdev)
908 rsnd_gen_probe, 927 rsnd_gen_probe,
909 rsnd_ssi_probe, 928 rsnd_ssi_probe,
910 rsnd_src_probe, 929 rsnd_src_probe,
930 rsnd_dvc_probe,
911 rsnd_adg_probe, 931 rsnd_adg_probe,
912 rsnd_dai_probe, 932 rsnd_dai_probe,
913 }; 933 };
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
16struct 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
32static 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
46static 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 }