aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
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 /sound/soc/sh
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>
Diffstat (limited to 'sound/soc/sh')
-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
7 files changed, 366 insertions, 2 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 @@
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 }
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
100static 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
110static 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
118static 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
126static 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
137static 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
150static 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
175static 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
210static 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
219struct 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
227int 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..a135d4c9d080 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),
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 6156ceebd58b..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
118struct rsnd_of_data; 131struct rsnd_of_data;
119struct rsnd_priv; 132struct rsnd_priv;
@@ -166,6 +179,7 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
166enum rsnd_mod_type { 179enum rsnd_mod_type {
167 RSND_MOD_SRC = 0, 180 RSND_MOD_SRC = 0,
168 RSND_MOD_SSI, 181 RSND_MOD_SSI,
182 RSND_MOD_DVC,
169 RSND_MOD_MAX, 183 RSND_MOD_MAX,
170}; 184};
171 185
@@ -183,6 +197,9 @@ struct rsnd_mod_ops {
183 struct rsnd_dai *rdai); 197 struct rsnd_dai *rdai);
184 int (*stop)(struct rsnd_mod *mod, 198 int (*stop)(struct rsnd_mod *mod,
185 struct rsnd_dai *rdai); 199 struct rsnd_dai *rdai);
200 int (*pcm_new)(struct rsnd_mod *mod,
201 struct rsnd_dai *rdai,
202 struct snd_soc_pcm_runtime *rtd);
186}; 203};
187 204
188struct rsnd_dai_stream; 205struct rsnd_dai_stream;
@@ -223,6 +240,7 @@ struct rsnd_dai_stream {
223}; 240};
224#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])
225#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])
226 244
227struct rsnd_dai { 245struct rsnd_dai {
228 char name[RSND_DAI_NAME_SIZE]; 246 char name[RSND_DAI_NAME_SIZE];
@@ -286,6 +304,9 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
286int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, 304int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
287 struct rsnd_dai *rdai, 305 struct rsnd_dai *rdai,
288 struct rsnd_dai_stream *io); 306 struct rsnd_dai_stream *io);
307int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
308 struct rsnd_mod *mod,
309 struct rsnd_dai_stream *io);
289 310
290/* 311/*
291 * R-Car sound priv 312 * R-Car sound priv
@@ -323,6 +344,12 @@ struct rsnd_priv {
323 int ssi_nr; 344 int ssi_nr;
324 345
325 /* 346 /*
347 * below value will be filled on rsnd_dvc_probe()
348 */
349 void *dvc;
350 int dvc_nr;
351
352 /*
326 * below value will be filled on rsnd_dai_probe() 353 * below value will be filled on rsnd_dai_probe()
327 */ 354 */
328 struct snd_soc_dai_driver *daidrv; 355 struct snd_soc_dai_driver *daidrv;
@@ -374,4 +401,17 @@ int rsnd_ssi_probe(struct platform_device *pdev,
374struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 401struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
375int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 402int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
376 403
404/*
405 * R-Car DVC
406 */
407int rsnd_dvc_probe(struct platform_device *pdev,
408 const struct rsnd_of_data *of_data,
409 struct rsnd_priv *priv);
410void rsnd_dvc_remove(struct platform_device *pdev,
411 struct rsnd_priv *priv);
412struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
413
414#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
415
416
377#endif 417#endif
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 035eda2de239..7da87cde0bc3 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -536,12 +536,14 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
536static int rsnd_src_start_gen2(struct rsnd_mod *mod, 536static int rsnd_src_start_gen2(struct rsnd_mod *mod,
537 struct rsnd_dai *rdai) 537 struct rsnd_dai *rdai)
538{ 538{
539 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
539 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;
540 542
541 rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); 543 rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
542 544
543 rsnd_mod_write(mod, SSI_CTRL, 0x1); 545 rsnd_mod_write(mod, SSI_CTRL, 0x1);
544 rsnd_mod_write(mod, SRC_CTRL, 0x11); 546 rsnd_mod_write(mod, SRC_CTRL, val);
545 547
546 return rsnd_src_start(mod, rdai); 548 return rsnd_src_start(mod, rdai);
547} 549}