diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-05-15 21:51:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-05-17 05:49:45 -0400 |
commit | 90431eb49bff6d79814cbf0c96e13597ad53095c (patch) | |
tree | 7a2cfea7a451f35924a87020654943a2a5cd355c | |
parent | 2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff) |
ASoC: rsnd: don't use PDTA bit for 24bit on SSI
Current SSI uses PDTA bit which indicates data that Input/Output
data are Right-Aligned. But, 24bit sound should be Left-Aligned
in this HW. Because Linux is using Right-Aligned data, and HW uses
Left-Aligned data, current 24bit data is missing lower 8bit.
To fix this issue, this patch removes PDTA bit, and shift 8bit
in necessary module
Reported-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sh/rcar/cmd.c | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 51 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 12 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssiu.c | 3 |
7 files changed, 68 insertions, 4 deletions
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index 7d92a24b7cfa..d879c010cf03 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c | |||
@@ -89,6 +89,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod, | |||
89 | dev_dbg(dev, "ctu/mix path = 0x%08x", data); | 89 | dev_dbg(dev, "ctu/mix path = 0x%08x", data); |
90 | 90 | ||
91 | rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); | 91 | rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); |
92 | rsnd_mod_write(mod, CMD_BUSIF_MODE, rsnd_get_busif_shift(io, mod) | 1); | ||
92 | rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); | 93 | rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); |
93 | 94 | ||
94 | rsnd_adg_set_cmd_timsel_gen2(mod, io); | 95 | rsnd_adg_set_cmd_timsel_gen2(mod, io); |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1744015408c3..8c1f4e2e0c4f 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) | |||
343 | return 0x76543210; | 343 | return 0x76543210; |
344 | } | 344 | } |
345 | 345 | ||
346 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) | ||
347 | { | ||
348 | enum rsnd_mod_type playback_mods[] = { | ||
349 | RSND_MOD_SRC, | ||
350 | RSND_MOD_CMD, | ||
351 | RSND_MOD_SSIU, | ||
352 | }; | ||
353 | enum rsnd_mod_type capture_mods[] = { | ||
354 | RSND_MOD_CMD, | ||
355 | RSND_MOD_SRC, | ||
356 | RSND_MOD_SSIU, | ||
357 | }; | ||
358 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
359 | struct rsnd_mod *tmod = NULL; | ||
360 | enum rsnd_mod_type *mods = | ||
361 | rsnd_io_is_play(io) ? | ||
362 | playback_mods : capture_mods; | ||
363 | int i; | ||
364 | |||
365 | /* | ||
366 | * This is needed for 24bit data | ||
367 | * We need to shift 8bit | ||
368 | * | ||
369 | * Linux 24bit data is located as 0x00****** | ||
370 | * HW 24bit data is located as 0x******00 | ||
371 | * | ||
372 | */ | ||
373 | switch (runtime->sample_bits) { | ||
374 | case 16: | ||
375 | return 0; | ||
376 | case 32: | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | for (i = 0; i < ARRAY_SIZE(playback_mods); i++) { | ||
381 | tmod = rsnd_io_to_mod(io, mods[i]); | ||
382 | if (tmod) | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | if (tmod != mod) | ||
387 | return 0; | ||
388 | |||
389 | if (rsnd_io_is_play(io)) | ||
390 | return (0 << 20) | /* shift to Left */ | ||
391 | (8 << 16); /* 8bit */ | ||
392 | else | ||
393 | return (1 << 20) | /* shift to Right */ | ||
394 | (8 << 16); /* 8bit */ | ||
395 | } | ||
396 | |||
346 | /* | 397 | /* |
347 | * rsnd_dai functions | 398 | * rsnd_dai functions |
348 | */ | 399 | */ |
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 63b6d3c28021..4b0980728e13 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -236,6 +236,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) | |||
236 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), | 236 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), |
237 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), | 237 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), |
238 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), | 238 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), |
239 | RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20), | ||
239 | RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), | 240 | RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), |
240 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), | 241 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), |
241 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), | 242 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index dbf4163427e8..323af41ecfcb 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -73,6 +73,7 @@ enum rsnd_reg { | |||
73 | RSND_REG_SCU_SYS_INT_EN0, | 73 | RSND_REG_SCU_SYS_INT_EN0, |
74 | RSND_REG_SCU_SYS_INT_EN1, | 74 | RSND_REG_SCU_SYS_INT_EN1, |
75 | RSND_REG_CMD_CTRL, | 75 | RSND_REG_CMD_CTRL, |
76 | RSND_REG_CMD_BUSIF_MODE, | ||
76 | RSND_REG_CMD_BUSIF_DALIGN, | 77 | RSND_REG_CMD_BUSIF_DALIGN, |
77 | RSND_REG_CMD_ROUTE_SLCT, | 78 | RSND_REG_CMD_ROUTE_SLCT, |
78 | RSND_REG_CMDOUT_TIMSEL, | 79 | RSND_REG_CMDOUT_TIMSEL, |
@@ -204,6 +205,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | |||
204 | u32 mask, u32 data); | 205 | u32 mask, u32 data); |
205 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 206 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
206 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 207 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
208 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod); | ||
207 | 209 | ||
208 | /* | 210 | /* |
209 | * R-Car DMA | 211 | * R-Car DMA |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 20b5b2ec625e..76a477a3ccb5 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -190,11 +190,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
190 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 190 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
191 | struct device *dev = rsnd_priv_to_dev(priv); | 191 | struct device *dev = rsnd_priv_to_dev(priv); |
192 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 192 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
193 | int is_play = rsnd_io_is_play(io); | ||
193 | int use_src = 0; | 194 | int use_src = 0; |
194 | u32 fin, fout; | 195 | u32 fin, fout; |
195 | u32 ifscr, fsrate, adinr; | 196 | u32 ifscr, fsrate, adinr; |
196 | u32 cr, route; | 197 | u32 cr, route; |
197 | u32 bsdsr, bsisr; | 198 | u32 bsdsr, bsisr; |
199 | u32 i_busif, o_busif, tmp; | ||
198 | uint ratio; | 200 | uint ratio; |
199 | 201 | ||
200 | if (!runtime) | 202 | if (!runtime) |
@@ -270,6 +272,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
270 | break; | 272 | break; |
271 | } | 273 | } |
272 | 274 | ||
275 | /* BUSIF_MODE */ | ||
276 | tmp = rsnd_get_busif_shift(io, mod); | ||
277 | i_busif = ( is_play ? tmp : 0) | 1; | ||
278 | o_busif = (!is_play ? tmp : 0) | 1; | ||
279 | |||
273 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); | 280 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); |
274 | 281 | ||
275 | rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ | 282 | rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ |
@@ -281,8 +288,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
281 | rsnd_mod_write(mod, SRC_BSISR, bsisr); | 288 | rsnd_mod_write(mod, SRC_BSISR, bsisr); |
282 | rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ | 289 | rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ |
283 | 290 | ||
284 | rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1); | 291 | rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif); |
285 | rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1); | 292 | rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif); |
293 | |||
286 | rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); | 294 | rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); |
287 | 295 | ||
288 | rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); | 296 | rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 135c5669f796..e43277a5068c 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -302,7 +302,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, | |||
302 | * always use 32bit system word. | 302 | * always use 32bit system word. |
303 | * see also rsnd_ssi_master_clk_enable() | 303 | * see also rsnd_ssi_master_clk_enable() |
304 | */ | 304 | */ |
305 | cr_own = FORCE | SWL_32 | PDTA; | 305 | cr_own = FORCE | SWL_32; |
306 | 306 | ||
307 | if (rdai->bit_clk_inv) | 307 | if (rdai->bit_clk_inv) |
308 | cr_own |= SCKP; | 308 | cr_own |= SCKP; |
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 14fafdaf1395..512d238b79e2 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c | |||
@@ -144,7 +144,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, | |||
144 | (rsnd_io_is_play(io) ? | 144 | (rsnd_io_is_play(io) ? |
145 | rsnd_runtime_channel_after_ctu(io) : | 145 | rsnd_runtime_channel_after_ctu(io) : |
146 | rsnd_runtime_channel_original(io))); | 146 | rsnd_runtime_channel_original(io))); |
147 | rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); | 147 | rsnd_mod_write(mod, SSI_BUSIF_MODE, |
148 | rsnd_get_busif_shift(io, mod) | 1); | ||
148 | rsnd_mod_write(mod, SSI_BUSIF_DALIGN, | 149 | rsnd_mod_write(mod, SSI_BUSIF_DALIGN, |
149 | rsnd_get_dalign(mod, io)); | 150 | rsnd_get_dalign(mod, io)); |
150 | } | 151 | } |