Skip to content

Commit

Permalink
ASoC: rsnd: don't use PDTA bit for 24bit on SSI
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Kuninori Morimoto <[email protected]>
Tested-by: Hiroyuki Yokoyama <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
morimoto authored and broonie committed May 17, 2017
1 parent 2ea659a commit 90431eb
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
1 change: 1 addition & 0 deletions sound/soc/sh/rcar/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
dev_dbg(dev, "ctu/mix path = 0x%08x", 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_adg_set_cmd_timsel_gen2(mod, io);
Expand Down
51 changes: 51 additions & 0 deletions sound/soc/sh/rcar/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
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
*/
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sh/rcar/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
RSND_GEN_M_REG(SRC_CTRL, 0x10, 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_ROUTE_SLCT, 0x18c, 0x20),
RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sh/rcar/rsnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum rsnd_reg {
RSND_REG_SCU_SYS_INT_EN0,
RSND_REG_SCU_SYS_INT_EN1,
RSND_REG_CMD_CTRL,
RSND_REG_CMD_BUSIF_MODE,
RSND_REG_CMD_BUSIF_DALIGN,
RSND_REG_CMD_ROUTE_SLCT,
RSND_REG_CMDOUT_TIMSEL,
Expand Down Expand Up @@ -204,6 +205,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
u32 mask, u32 data);
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_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);

/*
* R-Car DMA
Expand Down
12 changes: 10 additions & 2 deletions sound/soc/sh/rcar/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv);
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
int is_play = rsnd_io_is_play(io);
int use_src = 0;
u32 fin, fout;
u32 ifscr, fsrate, adinr;
u32 cr, route;
u32 bsdsr, bsisr;
u32 i_busif, o_busif, tmp;
uint ratio;

if (!runtime)
Expand Down Expand Up @@ -270,6 +272,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
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_SRCIR, 1); /* initialize */
Expand All @@ -281,8 +288,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_SRCIR, 0); /* cancel initialize */

rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1);
rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1);
rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);

rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));

rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sh/rcar/ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
* always use 32bit system word.
* see also rsnd_ssi_master_clk_enable()
*/
cr_own = FORCE | SWL_32 | PDTA;
cr_own = FORCE | SWL_32;

if (rdai->bit_clk_inv)
cr_own |= SCKP;
Expand Down
3 changes: 2 additions & 1 deletion sound/soc/sh/rcar/ssiu.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
(rsnd_io_is_play(io) ?
rsnd_runtime_channel_after_ctu(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_get_dalign(mod, io));
}
Expand Down

0 comments on commit 90431eb

Please sign in to comment.