diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2016-02-25 00:54:58 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-03-04 23:27:27 -0500 |
commit | eed76bb811cd143119b4bdeca88606685222e687 (patch) | |
tree | 184d6bdd8bec79e9e0fab8ce178e470e01810bc4 /sound/soc/sh/rcar | |
parent | 8a3a2211e97395694827f12552bbad7f2caf11ef (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.c | 69 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ctu.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/dvc.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/mix.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 8 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 15 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssiu.c | 6 |
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 | ||
227 | int rsnd_get_slot_width(struct rsnd_dai_stream *io) | 227 | int 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 | |||
234 | int 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 | |||
249 | int 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 | ||
266 | int 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 | |||
276 | int 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 | ||
264 | u32 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, | |||
193 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | 193 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
194 | u32 mask, u32 data); | 194 | u32 mask, u32 data); |
195 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 195 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
196 | u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | ||
197 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 196 | u32 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, | |||
356 | void rsnd_set_slot(struct rsnd_dai *rdai, | 355 | void rsnd_set_slot(struct rsnd_dai *rdai, |
357 | int slots, int slots_total); | 356 | int slots, int slots_total); |
358 | int rsnd_get_slot(struct rsnd_dai_stream *io); | 357 | int rsnd_get_slot(struct rsnd_dai_stream *io); |
359 | int rsnd_get_slot_width(struct rsnd_dai_stream *io); | ||
360 | int rsnd_get_slot_num(struct rsnd_dai_stream *io); | 358 | int rsnd_get_slot_num(struct rsnd_dai_stream *io); |
361 | 359 | ||
360 | int rsnd_runtime_channel_original(struct rsnd_dai_stream *io); | ||
361 | int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io); | ||
362 | int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io); | ||
363 | int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io); | ||
364 | int 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 | ||
181 | u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io) | 181 | u32 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)); |