aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2017-05-15 21:51:41 -0400
committerMark Brown <broonie@kernel.org>2017-05-17 05:49:45 -0400
commit90431eb49bff6d79814cbf0c96e13597ad53095c (patch)
tree7a2cfea7a451f35924a87020654943a2a5cd355c
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (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.c1
-rw-r--r--sound/soc/sh/rcar/core.c51
-rw-r--r--sound/soc/sh/rcar/gen.c1
-rw-r--r--sound/soc/sh/rcar/rsnd.h2
-rw-r--r--sound/soc/sh/rcar/src.c12
-rw-r--r--sound/soc/sh/rcar/ssi.c2
-rw-r--r--sound/soc/sh/rcar/ssiu.c3
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
346u32 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);
205u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 206u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
206u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 207u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
208u32 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 }