aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2016-02-25 00:54:58 -0500
committerMark Brown <broonie@kernel.org>2016-03-04 23:27:27 -0500
commiteed76bb811cd143119b4bdeca88606685222e687 (patch)
tree184d6bdd8bec79e9e0fab8ce178e470e01810bc4 /sound/soc/sh/rcar
parent8a3a2211e97395694827f12552bbad7f2caf11ef (diff)
ASoC: rsnd: add rsnd_runtime_channel_xxx()
Current SSI is supporting Normal SSI/Multi mode SSI/TDM mode SSI and its behavior is based on input channels. This input channel might be converted by CTU, and SSI needs to be Multi SSI mode / TDM SSI mode if 6ch input EX) 6ch input, CTU for 2ch, playback 6ch 6ch 2ch 2ch 2ch 2ch -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI EX) 6ch input, no CTU, Multi SSI, playback 6ch 6ch 6ch 6ch 6ch 2ch -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI0/SSI1/SSI2 Current driver is using rsnd_get_adinr_chan() / rsnd_get_slot_width() for this purpose, but it is complicated enough without meaning. This patch adds new rsnd_runtime_channel_xxx() which is caring CTU/Multi SSI. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar')
-rw-r--r--sound/soc/sh/rcar/core.c69
-rw-r--r--sound/soc/sh/rcar/ctu.c2
-rw-r--r--sound/soc/sh/rcar/dvc.c2
-rw-r--r--sound/soc/sh/rcar/mix.c2
-rw-r--r--sound/soc/sh/rcar/rsnd.h8
-rw-r--r--sound/soc/sh/rcar/src.c2
-rw-r--r--sound/soc/sh/rcar/ssi.c15
-rw-r--r--sound/soc/sh/rcar/ssiu.c6
8 files changed, 62 insertions, 44 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 3a3dc2ff18c9..3351a701c60e 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -224,13 +224,36 @@ int rsnd_get_slot_num(struct rsnd_dai_stream *io)
224 return rdai->slots_num; 224 return rdai->slots_num;
225} 225}
226 226
227int rsnd_get_slot_width(struct rsnd_dai_stream *io) 227int rsnd_runtime_channel_original(struct rsnd_dai_stream *io)
228{ 228{
229 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 229 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
230 int chan = runtime->channels;
231 230
232 /* Multi channel Mode */ 231 return runtime->channels;
233 if (rsnd_ssi_multi_slaves_runtime(io)) 232}
233
234int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io)
235{
236 int chan = rsnd_runtime_channel_original(io);
237 struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io);
238
239 if (ctu_mod) {
240 u32 converted_chan = rsnd_ctu_converted_channel(ctu_mod);
241
242 if (converted_chan)
243 return converted_chan;
244 }
245
246 return chan;
247}
248
249int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io)
250{
251 int chan = rsnd_io_is_play(io) ?
252 rsnd_runtime_channel_after_ctu(io) :
253 rsnd_runtime_channel_original(io);
254
255 /* Use Multi SSI */
256 if (rsnd_runtime_is_ssi_multi(io))
234 chan /= rsnd_get_slot_num(io); 257 chan /= rsnd_get_slot_num(io);
235 258
236 /* TDM Extend Mode needs 8ch */ 259 /* TDM Extend Mode needs 8ch */
@@ -240,6 +263,21 @@ int rsnd_get_slot_width(struct rsnd_dai_stream *io)
240 return chan; 263 return chan;
241} 264}
242 265
266int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io)
267{
268 int slots = rsnd_get_slot_num(io);
269 int chan = rsnd_io_is_play(io) ?
270 rsnd_runtime_channel_after_ctu(io) :
271 rsnd_runtime_channel_original(io);
272
273 return (chan >= 6) && (slots > 1);
274}
275
276int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io)
277{
278 return rsnd_runtime_channel_for_ssi(io) >= 6;
279}
280
243/* 281/*
244 * ADINR function 282 * ADINR function
245 */ 283 */
@@ -261,29 +299,6 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
261 return 0; 299 return 0;
262} 300}
263 301
264u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
265{
266 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
268 struct device *dev = rsnd_priv_to_dev(priv);
269 u32 chan = runtime->channels;
270
271 switch (chan) {
272 case 1:
273 case 2:
274 case 4:
275 case 6:
276 case 8:
277 break;
278 default:
279 dev_warn(dev, "not supported channel\n");
280 chan = 0;
281 break;
282 }
283
284 return chan;
285}
286
287/* 302/*
288 * DALIGN function 303 * DALIGN function
289 */ 304 */
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 784515afefaf..b326966ea407 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -60,7 +60,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
60{ 60{
61 rsnd_mod_write(mod, CTU_CTUIR, 1); 61 rsnd_mod_write(mod, CTU_CTUIR, 1);
62 62
63 rsnd_mod_write(mod, CTU_ADINR, rsnd_get_adinr_chan(mod, io)); 63 rsnd_mod_write(mod, CTU_ADINR, rsnd_runtime_channel_original(io));
64 64
65 rsnd_mod_write(mod, CTU_CPMDR, 0); 65 rsnd_mod_write(mod, CTU_CPMDR, 0);
66 rsnd_mod_write(mod, CTU_SCMDR, 0); 66 rsnd_mod_write(mod, CTU_SCMDR, 0);
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index d757f1316385..93b11e1c5d7f 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -116,7 +116,7 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
116 u32 vrdbr = 0; 116 u32 vrdbr = 0;
117 117
118 adinr = rsnd_get_adinr_bit(mod, io) | 118 adinr = rsnd_get_adinr_bit(mod, io) |
119 rsnd_get_adinr_chan(mod, io); 119 rsnd_runtime_channel_after_ctu(io);
120 120
121 /* Enable Digital Volume, Zero Cross Mute Mode */ 121 /* Enable Digital Volume, Zero Cross Mute Mode */
122 dvucr |= 0x101; 122 dvucr |= 0x101;
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index e0e337ad4206..195fc7bb22af 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -51,7 +51,7 @@ static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
51 rsnd_mod_write(mod, MIX_MIXIR, 1); 51 rsnd_mod_write(mod, MIX_MIXIR, 1);
52 52
53 /* General Information */ 53 /* General Information */
54 rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io)); 54 rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));
55 55
56 /* volume step */ 56 /* volume step */
57 rsnd_mod_write(mod, MIX_MIXMR, 0); 57 rsnd_mod_write(mod, MIX_MIXMR, 0);
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index bbc89bd1e918..ff53f96e5006 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -193,7 +193,6 @@ void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
193void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, 193void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
194 u32 mask, u32 data); 194 u32 mask, u32 data);
195u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 195u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
196u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
197u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 196u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
198 197
199/* 198/*
@@ -356,9 +355,14 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai,
356void rsnd_set_slot(struct rsnd_dai *rdai, 355void rsnd_set_slot(struct rsnd_dai *rdai,
357 int slots, int slots_total); 356 int slots, int slots_total);
358int rsnd_get_slot(struct rsnd_dai_stream *io); 357int rsnd_get_slot(struct rsnd_dai_stream *io);
359int rsnd_get_slot_width(struct rsnd_dai_stream *io);
360int rsnd_get_slot_num(struct rsnd_dai_stream *io); 358int rsnd_get_slot_num(struct rsnd_dai_stream *io);
361 359
360int rsnd_runtime_channel_original(struct rsnd_dai_stream *io);
361int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io);
362int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io);
363int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io);
364int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);
365
362/* 366/*
363 * R-Car sound DAI 367 * R-Car sound DAI
364 */ 368 */
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 03c6314871ff..8e1177aea6b1 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -205,7 +205,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
205 * SRC_ADINR 205 * SRC_ADINR
206 */ 206 */
207 adinr = rsnd_get_adinr_bit(mod, io) | 207 adinr = rsnd_get_adinr_bit(mod, io) |
208 rsnd_get_adinr_chan(mod, io); 208 rsnd_runtime_channel_original(io);
209 209
210 /* 210 /*
211 * SRC_IFSCR / SRC_IFSVR 211 * SRC_IFSCR / SRC_IFSVR
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 0979db8af8f9..540489755367 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -180,11 +180,8 @@ static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
180 180
181u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io) 181u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io)
182{ 182{
183 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 183 if (rsnd_runtime_is_ssi_multi(io))
184 u32 mask = rsnd_ssi_multi_slaves(io); 184 return rsnd_ssi_multi_slaves(io);
185
186 if (mask && (runtime->channels >= 6))
187 return mask;
188 185
189 return 0; 186 return 0;
190} 187}
@@ -198,7 +195,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
198 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 195 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
199 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 196 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
200 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); 197 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
201 int slots = rsnd_get_slot_width(io); 198 int chan = rsnd_runtime_channel_for_ssi(io);
202 int j, ret; 199 int j, ret;
203 int ssi_clk_mul_table[] = { 200 int ssi_clk_mul_table[] = {
204 1, 2, 4, 8, 16, 6, 12, 201 1, 2, 4, 8, 16, 6, 12,
@@ -231,10 +228,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
231 228
232 /* 229 /*
233 * this driver is assuming that 230 * this driver is assuming that
234 * system word is 32bit x slots 231 * system word is 32bit x chan
235 * see rsnd_ssi_init() 232 * see rsnd_ssi_init()
236 */ 233 */
237 main_rate = rate * 32 * slots * ssi_clk_mul_table[j]; 234 main_rate = rate * 32 * chan * ssi_clk_mul_table[j];
238 235
239 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); 236 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
240 if (0 == ret) { 237 if (0 == ret) {
@@ -289,7 +286,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
289 u32 wsr; 286 u32 wsr;
290 int is_tdm; 287 int is_tdm;
291 288
292 is_tdm = (rsnd_get_slot_width(io) >= 6) ? 1 : 0; 289 is_tdm = rsnd_runtime_is_ssi_tdm(io);
293 290
294 /* 291 /*
295 * always use 32bit system word. 292 * always use 32bit system word.
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 0d964a0a3e31..6f9b388ec5a8 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -105,7 +105,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
105 if (ret < 0) 105 if (ret < 0)
106 return ret; 106 return ret;
107 107
108 if (rsnd_get_slot_width(io) >= 6) { 108 if (rsnd_runtime_is_ssi_tdm(io)) {
109 /* 109 /*
110 * TDM Extend Mode 110 * TDM Extend Mode
111 * see 111 * see
@@ -117,7 +117,9 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
117 if (rsnd_ssi_use_busif(io)) { 117 if (rsnd_ssi_use_busif(io)) {
118 rsnd_mod_write(mod, SSI_BUSIF_ADINR, 118 rsnd_mod_write(mod, SSI_BUSIF_ADINR,
119 rsnd_get_adinr_bit(mod, io) | 119 rsnd_get_adinr_bit(mod, io) |
120 rsnd_get_adinr_chan(mod, io)); 120 (rsnd_io_is_play(io) ?
121 rsnd_runtime_channel_after_ctu(io) :
122 rsnd_runtime_channel_original(io)));
121 rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); 123 rsnd_mod_write(mod, SSI_BUSIF_MODE, 1);
122 rsnd_mod_write(mod, SSI_BUSIF_DALIGN, 124 rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
123 rsnd_get_dalign(mod, io)); 125 rsnd_get_dalign(mod, io));