Commit 3e8f5263 authored by Jyri Sarha's avatar Jyri Sarha Committed by Mark Brown

ASoC: tlv320aic3x: Improve tdm support

Before this patch the set_tdm_slots() callback did not store the value
of slot width anywhere. The tdm support only worked if selected slot
width was equal to the sample width. With this patch all sample widths
that fit into the slot width are supported. There unused bits are
filled unnecessarily in the capture direction, but the other end of
the i2s bus should be able to ignore them.
Signed-off-by: default avatarJyri Sarha <jsarha@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6ff33f39
......@@ -80,6 +80,7 @@ struct aic3x_priv {
unsigned int sysclk;
unsigned int dai_fmt;
unsigned int tdm_delay;
unsigned int slot_width;
struct list_head list;
int master;
int gpio_reset;
......@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
u16 d, pll_d = 1;
int clk;
int width = aic3x->slot_width;
if (!width)
width = params_width(params);
/* select data word length */
data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
switch (params_width(params)) {
switch (width) {
case 16:
break;
case 20:
......@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int delay = 0;
int width = aic3x->slot_width;
if (!width)
width = substream->runtime->sample_bits;
/* TDM slot selection only valid in DSP_A/_B mode */
if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A)
delay += (aic3x->tdm_delay + 1);
delay += (aic3x->tdm_delay*width + 1);
else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B)
delay += aic3x->tdm_delay;
delay += aic3x->tdm_delay*width;
/* Configure data delay */
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
......@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
aic3x->tdm_delay = lsb * slot_width;
switch (slot_width) {
case 16:
case 20:
case 24:
case 32:
break;
default:
dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
return -EINVAL;
}
aic3x->tdm_delay = lsb;
aic3x->slot_width = slot_width;
/* DOUT in high-impedance on inactive bit clocks */
snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
......
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