ASoC: fsl_ssi: Fix bclk calculation for mono channel

For mono channel, SSI will switch to Normal mode.

In Normal mode and Network mode, the Word Length Control bits
control the word length divider in clock generator, which is
different with I2S Master mode (the word length is fixed to
32bit), it should be the value of params_width(hw_params).

The condition "slots == 2" is not good for I2S Master mode,
because for Network mode and Normal mode, the slots can also
be 2. Then we need to use (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK)
to check if it is I2S Master mode.

So we refine the formula for mono channel, otherwise there
will be sound issue for S24_LE.

Fixes: b0a7043d5c ("ASoC: fsl_ssi: Caculate bit clock rate using slot number and width")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Nicolin Chen <nicoleotsuka@gmail.com>
Link: https://lore.kernel.org/r/034eff1435ff6ce300b6c781130cefd9db22ab9a.1592276147.git.shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Shengjiu Wang 2020-06-16 10:53:48 +08:00 committed by Mark Brown
parent 4036d05c38
commit ed1220df6e
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -678,8 +678,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
struct regmap *regs = ssi->regs;
u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
unsigned long clkrate, baudrate, tmprate;
unsigned int slots = params_channels(hw_params);
unsigned int slot_width = 32;
unsigned int channels = params_channels(hw_params);
unsigned int slot_width = params_width(hw_params);
unsigned int slots = 2;
u64 sub, savesub = 100000;
unsigned int freq;
bool baudclk_is_used;
@ -688,10 +689,14 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
/* Override slots and slot_width if being specifically set... */
if (ssi->slots)
slots = ssi->slots;
/* ...but keep 32 bits if slots is 2 -- I2S Master mode */
if (ssi->slot_width && slots != 2)
if (ssi->slot_width)
slot_width = ssi->slot_width;
/* ...but force 32 bits for stereo audio using I2S Master Mode */
if (channels == 2 &&
(ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) == SSI_SCR_I2S_MODE_MASTER)
slot_width = 32;
/* Generate bit clock based on the slot number and slot width */
freq = slots * slot_width * params_rate(hw_params);