On 10/14/20 1:19 AM, Samuel Holland wrote: > AIF3 has some differences from AIF1 and AIF2: > - It supports one channel only > - It supports master mode only > - It is not directly connected to any of the mixers; instead all audio > goes through a mux with AIF2. > - It does not have its own clock dividers; instead it reuses AIF2 BCLK > and LRCK. This means that when both AIF2 and AIF3 are active, they > must use the same sample rate and total frame width. Since AIF2 and > AIF3 are only used for codec2codec DAI links, constraints are not > applicable here; the only thing we can do when the rates don't match > is report an error. > > Make the necessary adjustments to support this AIF. > > Signed-off-by: Samuel Holland <samuel@xxxxxxxxxxxx> > --- > sound/soc/sunxi/sun8i-codec.c | 138 ++++++++++++++++++++++++++++++++-- > 1 file changed, 130 insertions(+), 8 deletions(-) > > diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c > index 6a8232e07983..180442c62be1 100644 > --- a/sound/soc/sunxi/sun8i-codec.c > +++ b/sound/soc/sunxi/sun8i-codec.c [snip] > @@ -263,19 +273,30 @@ static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) > break; > case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */ > value = 0x0; > break; > default: > return -EINVAL; > } > > - regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), > - BIT(SUN8I_AIF_CLK_CTRL_MSTR_MOD), > - value << SUN8I_AIF_CLK_CTRL_MSTR_MOD); > + if (dai->id == SUN8I_CODEC_AIF3) { > + /* AIF3 only supports master mode. */ > + if (value) > + return -EINVAL; > + > + /* Use the AIF2 BCLK and LRCK for AIF3. */ > + regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), > + SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK, > + SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2); Since the AIF3 clock source is set to AIF2 here... > + } else { > + regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), > + BIT(SUN8I_AIF_CLK_CTRL_MSTR_MOD), > + value << SUN8I_AIF_CLK_CTRL_MSTR_MOD); > + } > > /* DAI format */ > switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { > case SND_SOC_DAIFMT_I2S: > format = 0x0; > break; > case SND_SOC_DAIFMT_LEFT_J: > format = 0x1; [snip] > @@ -908,16 +1016,22 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { > { "CLK AIF2", NULL, "AIF2CLK" }, > { "CLK AIF2", NULL, "SYSCLK" }, > { "RST AIF2", NULL, "CLK AIF2" }, > { "AIF2 ADCL", NULL, "RST AIF2" }, > { "AIF2 ADCR", NULL, "RST AIF2" }, > { "AIF2 DACL", NULL, "RST AIF2" }, > { "AIF2 DACR", NULL, "RST AIF2" }, > > + { "CLK AIF3", NULL, "AIF1CLK" }, ^^^^^^^ ...this should be "AIF2CLK". I will fix it in the next version. > + { "CLK AIF3", NULL, "SYSCLK" }, > + { "RST AIF3", NULL, "CLK AIF3" }, > + { "AIF3 ADC", NULL, "RST AIF3" }, > + { "AIF3 DAC", NULL, "RST AIF3" }, > + > { "CLK ADC", NULL, "SYSCLK" }, > { "RST ADC", NULL, "CLK ADC" }, > { "ADC", NULL, "RST ADC" }, > { "ADCL", NULL, "ADC" }, > { "ADCR", NULL, "ADC" }, > > { "CLK DAC", NULL, "SYSCLK" }, > { "RST DAC", NULL, "CLK DAC" },