Commit 9bc3b4ff authored by Mark Brown's avatar Mark Brown

Merge branch 'fix/rcar' of...

Merge branch 'fix/rcar' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-rcar
parents 07b7acb5 e8a3ce11
...@@ -510,7 +510,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, ...@@ -510,7 +510,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
rbga = rbgx; rbga = rbgx;
adg->rbga_rate_for_441khz = rate / div; adg->rbga_rate_for_441khz = rate / div;
ckr |= brg_table[i] << 20; ckr |= brg_table[i] << 20;
if (req_441kHz_rate) if (req_441kHz_rate &&
!(adg_mode_flags(adg) & AUDIO_OUT_48))
parent_clk_name = __clk_get_name(clk); parent_clk_name = __clk_get_name(clk);
} }
} }
...@@ -525,7 +526,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, ...@@ -525,7 +526,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
rbgb = rbgx; rbgb = rbgx;
adg->rbgb_rate_for_48khz = rate / div; adg->rbgb_rate_for_48khz = rate / div;
ckr |= brg_table[i] << 16; ckr |= brg_table[i] << 16;
if (req_48kHz_rate) if (req_48kHz_rate &&
(adg_mode_flags(adg) & AUDIO_OUT_48))
parent_clk_name = __clk_get_name(clk); parent_clk_name = __clk_get_name(clk);
} }
} }
......
...@@ -92,6 +92,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod, ...@@ -92,6 +92,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
dev_dbg(dev, "ctu/mix path = 0x%08x", data); dev_dbg(dev, "ctu/mix path = 0x%08x", data);
rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); rsnd_mod_write(mod, CMD_ROUTE_SLCT, data);
rsnd_mod_write(mod, CMD_BUSIF_MODE, rsnd_get_busif_shift(io, mod) | 1);
rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
rsnd_adg_set_cmd_timsel_gen2(mod, io); rsnd_adg_set_cmd_timsel_gen2(mod, io);
......
...@@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) ...@@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
return 0x76543210; return 0x76543210;
} }
u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
{
enum rsnd_mod_type playback_mods[] = {
RSND_MOD_SRC,
RSND_MOD_CMD,
RSND_MOD_SSIU,
};
enum rsnd_mod_type capture_mods[] = {
RSND_MOD_CMD,
RSND_MOD_SRC,
RSND_MOD_SSIU,
};
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
struct rsnd_mod *tmod = NULL;
enum rsnd_mod_type *mods =
rsnd_io_is_play(io) ?
playback_mods : capture_mods;
int i;
/*
* This is needed for 24bit data
* We need to shift 8bit
*
* Linux 24bit data is located as 0x00******
* HW 24bit data is located as 0x******00
*
*/
switch (runtime->sample_bits) {
case 16:
return 0;
case 32:
break;
}
for (i = 0; i < ARRAY_SIZE(playback_mods); i++) {
tmod = rsnd_io_to_mod(io, mods[i]);
if (tmod)
break;
}
if (tmod != mod)
return 0;
if (rsnd_io_is_play(io))
return (0 << 20) | /* shift to Left */
(8 << 16); /* 8bit */
else
return (1 << 20) | /* shift to Right */
(8 << 16); /* 8bit */
}
/* /*
* rsnd_dai functions * rsnd_dai functions
*/ */
......
...@@ -238,6 +238,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) ...@@ -238,6 +238,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20),
RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20),
RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
......
...@@ -74,6 +74,7 @@ enum rsnd_reg { ...@@ -74,6 +74,7 @@ enum rsnd_reg {
RSND_REG_SCU_SYS_INT_EN0, RSND_REG_SCU_SYS_INT_EN0,
RSND_REG_SCU_SYS_INT_EN1, RSND_REG_SCU_SYS_INT_EN1,
RSND_REG_CMD_CTRL, RSND_REG_CMD_CTRL,
RSND_REG_CMD_BUSIF_MODE,
RSND_REG_CMD_BUSIF_DALIGN, RSND_REG_CMD_BUSIF_DALIGN,
RSND_REG_CMD_ROUTE_SLCT, RSND_REG_CMD_ROUTE_SLCT,
RSND_REG_CMDOUT_TIMSEL, RSND_REG_CMDOUT_TIMSEL,
...@@ -207,6 +208,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, ...@@ -207,6 +208,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
u32 mask, u32 data); u32 mask, u32 data);
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
/* /*
* R-Car DMA * R-Car DMA
......
...@@ -172,11 +172,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, ...@@ -172,11 +172,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
int is_play = rsnd_io_is_play(io);
int use_src = 0; int use_src = 0;
u32 fin, fout; u32 fin, fout;
u32 ifscr, fsrate, adinr; u32 ifscr, fsrate, adinr;
u32 cr, route; u32 cr, route;
u32 bsdsr, bsisr; u32 bsdsr, bsisr;
u32 i_busif, o_busif, tmp;
uint ratio; uint ratio;
if (!runtime) if (!runtime)
...@@ -252,6 +254,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, ...@@ -252,6 +254,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
break; break;
} }
/* BUSIF_MODE */
tmp = rsnd_get_busif_shift(io, mod);
i_busif = ( is_play ? tmp : 0) | 1;
o_busif = (!is_play ? tmp : 0) | 1;
rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ 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,8 +270,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
rsnd_mod_write(mod, SRC_BSISR, bsisr); rsnd_mod_write(mod, SRC_BSISR, bsisr);
rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1); rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1); rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);
rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
......
...@@ -319,7 +319,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, ...@@ -319,7 +319,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
* always use 32bit system word. * always use 32bit system word.
* see also rsnd_ssi_master_clk_enable() * see also rsnd_ssi_master_clk_enable()
*/ */
cr_own = FORCE | SWL_32 | PDTA; cr_own = FORCE | SWL_32;
if (rdai->bit_clk_inv) if (rdai->bit_clk_inv)
cr_own |= SCKP; cr_own |= SCKP;
...@@ -567,6 +567,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, ...@@ -567,6 +567,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
u32 *buf = (u32 *)(runtime->dma_area + u32 *buf = (u32 *)(runtime->dma_area +
rsnd_dai_pointer_offset(io, 0)); rsnd_dai_pointer_offset(io, 0));
int shift = 0;
switch (runtime->sample_bits) {
case 32:
shift = 8;
break;
}
/* /*
* 8/16/32 data can be assesse to TDR/RDR register * 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,9 +581,9 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
* see rsnd_ssi_init() * see rsnd_ssi_init()
*/ */
if (rsnd_io_is_play(io)) if (rsnd_io_is_play(io))
rsnd_mod_write(mod, SSITDR, *buf); rsnd_mod_write(mod, SSITDR, (*buf) << shift);
else else
*buf = rsnd_mod_read(mod, SSIRDR); *buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); elapsed = rsnd_dai_pointer_update(io, sizeof(*buf));
} }
...@@ -738,6 +745,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, ...@@ -738,6 +745,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
struct rsnd_priv *priv) struct rsnd_priv *priv)
{ {
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
/* Do nothing for SSI parent mod */
if (ssi_parent_mod == mod)
return 0;
/* PIO will request IRQ again */ /* PIO will request IRQ again */
free_irq(ssi->irq, mod); free_irq(ssi->irq, mod);
......
...@@ -145,7 +145,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, ...@@ -145,7 +145,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
(rsnd_io_is_play(io) ? (rsnd_io_is_play(io) ?
rsnd_runtime_channel_after_ctu(io) : rsnd_runtime_channel_after_ctu(io) :
rsnd_runtime_channel_original(io))); rsnd_runtime_channel_original(io)));
rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); rsnd_mod_write(mod, SSI_BUSIF_MODE,
rsnd_get_busif_shift(io, mod) | 1);
rsnd_mod_write(mod, SSI_BUSIF_DALIGN, rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
rsnd_get_dalign(mod, io)); rsnd_get_dalign(mod, io));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment