ASoC: tas2764: Fix and extend FSYNC polarity handling
authorMartin Povišer <povik+lin@cutebit.org>
Thu, 30 Jun 2022 07:51:33 +0000 (09:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Jul 2022 19:24:18 +0000 (21:24 +0200)
[ Upstream commit d1a10f1b48202e2d183cce144c218a211e98d906 ]

Fix setting of FSYNC polarity in case of LEFT_J and DSP_A/B formats.
Do NOT set the SCFG field as was previously done, because that is not
correct and is also in conflict with the "ASI1 Source" control which
sets the same SCFG field!

Also add support for explicit polarity inversion.

Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764")
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
Link: https://lore.kernel.org/r/20220630075135.2221-2-povik+lin@cutebit.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/codecs/tas2764.c
sound/soc/codecs/tas2764.h

index edc66ff..46c8156 100644 (file)
@@ -135,7 +135,8 @@ static const char * const tas2764_ASI1_src[] = {
 };
 
 static SOC_ENUM_SINGLE_DECL(
-       tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, 4, tas2764_ASI1_src);
+       tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT,
+       tas2764_ASI1_src);
 
 static const struct snd_kcontrol_new tas2764_asi1_mux =
        SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum);
@@ -333,20 +334,22 @@ static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        struct snd_soc_component *component = dai->component;
        struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
-       u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
-       int iface;
+       u8 tdm_rx_start_slot = 0, asi_cfg_0 = 0, asi_cfg_1 = 0;
        int ret;
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_IF:
+               asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
+               fallthrough;
        case SND_SOC_DAIFMT_NB_NF:
                asi_cfg_1 = TAS2764_TDM_CFG1_RX_RISING;
                break;
+       case SND_SOC_DAIFMT_IB_IF:
+               asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
+               fallthrough;
        case SND_SOC_DAIFMT_IB_NF:
                asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING;
                break;
-       default:
-               dev_err(tas2764->dev, "ASI format Inverse is not found\n");
-               return -EINVAL;
        }
 
        ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
@@ -357,13 +360,13 @@ static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
+               asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
+               fallthrough;
        case SND_SOC_DAIFMT_DSP_A:
-               iface = TAS2764_TDM_CFG2_SCFG_I2S;
                tdm_rx_start_slot = 1;
                break;
        case SND_SOC_DAIFMT_DSP_B:
        case SND_SOC_DAIFMT_LEFT_J:
-               iface = TAS2764_TDM_CFG2_SCFG_LEFT_J;
                tdm_rx_start_slot = 0;
                break;
        default:
@@ -372,14 +375,15 @@ static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
-                                           TAS2764_TDM_CFG1_MASK,
-                                           (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT));
+       ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0,
+                                           TAS2764_TDM_CFG0_FRAME_START,
+                                           asi_cfg_0);
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2,
-                                           TAS2764_TDM_CFG2_SCFG_MASK, iface);
+       ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
+                                           TAS2764_TDM_CFG1_MASK,
+                                           (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT));
        if (ret < 0)
                return ret;
 
index 67d6fd9..f015f22 100644 (file)
@@ -47,6 +47,7 @@
 #define TAS2764_TDM_CFG0_MASK          GENMASK(3, 1)
 #define TAS2764_TDM_CFG0_44_1_48KHZ    BIT(3)
 #define TAS2764_TDM_CFG0_88_2_96KHZ    (BIT(3) | BIT(1))
+#define TAS2764_TDM_CFG0_FRAME_START   BIT(0)
 
 /* TDM Configuration Reg1 */
 #define TAS2764_TDM_CFG1               TAS2764_REG(0X0, 0x09)
 #define TAS2764_TDM_CFG2_RXS_16BITS    0x0
 #define TAS2764_TDM_CFG2_RXS_24BITS    BIT(0)
 #define TAS2764_TDM_CFG2_RXS_32BITS    BIT(1)
-#define TAS2764_TDM_CFG2_SCFG_MASK     GENMASK(5, 4)
-#define TAS2764_TDM_CFG2_SCFG_I2S      0x0
-#define TAS2764_TDM_CFG2_SCFG_LEFT_J   BIT(4)
-#define TAS2764_TDM_CFG2_SCFG_RIGHT_J  BIT(5)
+#define TAS2764_TDM_CFG2_SCFG_SHIFT    4
 
 /* TDM Configuration Reg3 */
 #define TAS2764_TDM_CFG3               TAS2764_REG(0X0, 0x0c)