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 <sam...@sholland.org>
> ---
>  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" },

Reply via email to