aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2017-06-07 15:30:32 -0400
committerMark Brown <broonie@kernel.org>2017-06-07 15:30:32 -0400
commit9bc3b4ff18d130da09ad608718d4afcda01b3e56 (patch)
tree46d214f42c10e8736d11bc36372d0c8c176fdca9
parent07b7acb51d283d8469696c906b91f1882696a4d4 (diff)
parente8a3ce1130134046e9da132aa4d043566df8237d (diff)
Merge branch 'fix/rcar' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-rcar
-rw-r--r--sound/soc/sh/rcar/adg.c6
-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.c18
-rw-r--r--sound/soc/sh/rcar/ssiu.c3
8 files changed, 86 insertions, 8 deletions
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 36bece8621b7..4a72fd74ddc2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -510,7 +510,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
510 rbga = rbgx; 510 rbga = rbgx;
511 adg->rbga_rate_for_441khz = rate / div; 511 adg->rbga_rate_for_441khz = rate / div;
512 ckr |= brg_table[i] << 20; 512 ckr |= brg_table[i] << 20;
513 if (req_441kHz_rate) 513 if (req_441kHz_rate &&
514 !(adg_mode_flags(adg) & AUDIO_OUT_48))
514 parent_clk_name = __clk_get_name(clk); 515 parent_clk_name = __clk_get_name(clk);
515 } 516 }
516 } 517 }
@@ -525,7 +526,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
525 rbgb = rbgx; 526 rbgb = rbgx;
526 adg->rbgb_rate_for_48khz = rate / div; 527 adg->rbgb_rate_for_48khz = rate / div;
527 ckr |= brg_table[i] << 16; 528 ckr |= brg_table[i] << 16;
528 if (req_48kHz_rate) 529 if (req_48kHz_rate &&
530 (adg_mode_flags(adg) & AUDIO_OUT_48))
529 parent_clk_name = __clk_get_name(clk); 531 parent_clk_name = __clk_get_name(clk);
530 } 532 }
531 } 533 }
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
index 98835e9d1d7d..9a136d86e2a9 100644
--- a/sound/soc/sh/rcar/cmd.c
+++ b/sound/soc/sh/rcar/cmd.c
@@ -92,6 +92,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
92 dev_dbg(dev, "ctu/mix path = 0x%08x", data); 92 dev_dbg(dev, "ctu/mix path = 0x%08x", data);
93 93
94 rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); 94 rsnd_mod_write(mod, CMD_ROUTE_SLCT, data);
95 rsnd_mod_write(mod, CMD_BUSIF_MODE, rsnd_get_busif_shift(io, mod) | 1);
95 rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); 96 rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
96 97
97 rsnd_adg_set_cmd_timsel_gen2(mod, io); 98 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 bc12c449857a..7a8c08933503 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 99f93a17511e..ee00e3516911 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -238,6 +238,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
238 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 238 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
239 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 239 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
240 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 240 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
241 RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20),
241 RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), 242 RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20),
242 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 243 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
243 RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 244 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 d4f89d5e6994..bd8def0bc212 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -74,6 +74,7 @@ enum rsnd_reg {
74 RSND_REG_SCU_SYS_INT_EN0, 74 RSND_REG_SCU_SYS_INT_EN0,
75 RSND_REG_SCU_SYS_INT_EN1, 75 RSND_REG_SCU_SYS_INT_EN1,
76 RSND_REG_CMD_CTRL, 76 RSND_REG_CMD_CTRL,
77 RSND_REG_CMD_BUSIF_MODE,
77 RSND_REG_CMD_BUSIF_DALIGN, 78 RSND_REG_CMD_BUSIF_DALIGN,
78 RSND_REG_CMD_ROUTE_SLCT, 79 RSND_REG_CMD_ROUTE_SLCT,
79 RSND_REG_CMDOUT_TIMSEL, 80 RSND_REG_CMDOUT_TIMSEL,
@@ -207,6 +208,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
207 u32 mask, u32 data); 208 u32 mask, u32 data);
208u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 209u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
209u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 210u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
211u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
210 212
211/* 213/*
212 * R-Car DMA 214 * R-Car DMA
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index e4bde0c8d93a..8dbe9ebcbff1 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -172,11 +172,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
172 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 172 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
173 struct device *dev = rsnd_priv_to_dev(priv); 173 struct device *dev = rsnd_priv_to_dev(priv);
174 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 174 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
175 int is_play = rsnd_io_is_play(io);
175 int use_src = 0; 176 int use_src = 0;
176 u32 fin, fout; 177 u32 fin, fout;
177 u32 ifscr, fsrate, adinr; 178 u32 ifscr, fsrate, adinr;
178 u32 cr, route; 179 u32 cr, route;
179 u32 bsdsr, bsisr; 180 u32 bsdsr, bsisr;
181 u32 i_busif, o_busif, tmp;
180 uint ratio; 182 uint ratio;
181 183
182 if (!runtime) 184 if (!runtime)
@@ -252,6 +254,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
252 break; 254 break;
253 } 255 }
254 256
257 /* BUSIF_MODE */
258 tmp = rsnd_get_busif_shift(io, mod);
259 i_busif = ( is_play ? tmp : 0) | 1;
260 o_busif = (!is_play ? tmp : 0) | 1;
261
255 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); 262 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
256 263
257 rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ 264 rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */
@@ -263,8 +270,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
263 rsnd_mod_write(mod, SRC_BSISR, bsisr); 270 rsnd_mod_write(mod, SRC_BSISR, bsisr);
264 rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ 271 rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
265 272
266 rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1); 273 rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
267 rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1); 274 rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);
275
268 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); 276 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
269 277
270 rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); 278 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 2363d0beeafd..59ca6e3f46bc 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -319,7 +319,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
319 * always use 32bit system word. 319 * always use 32bit system word.
320 * see also rsnd_ssi_master_clk_enable() 320 * see also rsnd_ssi_master_clk_enable()
321 */ 321 */
322 cr_own = FORCE | SWL_32 | PDTA; 322 cr_own = FORCE | SWL_32;
323 323
324 if (rdai->bit_clk_inv) 324 if (rdai->bit_clk_inv)
325 cr_own |= SCKP; 325 cr_own |= SCKP;
@@ -567,6 +567,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
567 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 567 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
568 u32 *buf = (u32 *)(runtime->dma_area + 568 u32 *buf = (u32 *)(runtime->dma_area +
569 rsnd_dai_pointer_offset(io, 0)); 569 rsnd_dai_pointer_offset(io, 0));
570 int shift = 0;
571
572 switch (runtime->sample_bits) {
573 case 32:
574 shift = 8;
575 break;
576 }
570 577
571 /* 578 /*
572 * 8/16/32 data can be assesse to TDR/RDR register 579 * 8/16/32 data can be assesse to TDR/RDR register
@@ -574,9 +581,9 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
574 * see rsnd_ssi_init() 581 * see rsnd_ssi_init()
575 */ 582 */
576 if (rsnd_io_is_play(io)) 583 if (rsnd_io_is_play(io))
577 rsnd_mod_write(mod, SSITDR, *buf); 584 rsnd_mod_write(mod, SSITDR, (*buf) << shift);
578 else 585 else
579 *buf = rsnd_mod_read(mod, SSIRDR); 586 *buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
580 587
581 elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); 588 elapsed = rsnd_dai_pointer_update(io, sizeof(*buf));
582 } 589 }
@@ -738,6 +745,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
738 struct rsnd_priv *priv) 745 struct rsnd_priv *priv)
739{ 746{
740 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 747 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
748 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
749
750 /* Do nothing for SSI parent mod */
751 if (ssi_parent_mod == mod)
752 return 0;
741 753
742 /* PIO will request IRQ again */ 754 /* PIO will request IRQ again */
743 free_irq(ssi->irq, mod); 755 free_irq(ssi->irq, mod);
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 13d648ef1ed6..bed2c9c0004b 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -145,7 +145,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
145 (rsnd_io_is_play(io) ? 145 (rsnd_io_is_play(io) ?
146 rsnd_runtime_channel_after_ctu(io) : 146 rsnd_runtime_channel_after_ctu(io) :
147 rsnd_runtime_channel_original(io))); 147 rsnd_runtime_channel_original(io)));
148 rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); 148 rsnd_mod_write(mod, SSI_BUSIF_MODE,
149 rsnd_get_busif_shift(io, mod) | 1);
149 rsnd_mod_write(mod, SSI_BUSIF_DALIGN, 150 rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
150 rsnd_get_dalign(mod, io)); 151 rsnd_get_dalign(mod, io));
151 } 152 }