audio: fix tdm audio format
authorXing Wang <xing.wang@amlogic.com>
Fri, 21 Jul 2017 08:12:36 +0000 (16:12 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 28 Jul 2017 08:37:43 +0000 (01:37 -0700)
PD#146334: audio: fix tdm bclk and fclk revert and skew issue

Change-Id: I1dcb6f8559b3c04a2ddbb7c13a6115001c249c18
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts
arch/arm64/boot/dts/amlogic/axg_s400.dts
arch/arm64/boot/dts/amlogic/axg_s420.dts
sound/soc/amlogic/auge/tdm.c
sound/soc/amlogic/auge/tdm_hw.c
sound/soc/amlogic/auge/tdm_hw.h

index cd01809..232c6f1 100644 (file)
                        format = "i2s";
                        mclk-fs = <256>;
                        continuous-clock;
-                       bitclock-inversion;
-                       frame-inversion;
+                       //bitclock-inversion;
+                       //frame-inversion;
                        //bitclock-master = <&aml_tdmb>;
                        //frame-master = <&aml_tdmb>;
                        cpu {
                        format = "i2s";
                        mclk-fs = <256>;
                        continuous-clock;
-                       bitclock-inversion;
-                       frame-inversion;
+                       //bitclock-inversion;
+                       //frame-inversion;
                        //bitclock-master = <&aml_tdmc>;
                        //frame-master = <&aml_tdmc>;
                        cpu {
                };
 
                aml-audio-card,dai-link@3 {
-                       format = "i2s";
                        mclk-fs = <256>;
-                       continuous-clock;
-                       //bitclock-inversion;
-                       //frame-inversion;
-                       bitclock-master = <&aml_pdm>;
-                       frame-master = <&aml_pdm>;
                        cpu {
                                sound-dai = <&aml_pdm>;
                        };
                };
 
                aml-audio-card,dai-link@4 {
-                       //format = "i2s";
                        mclk-fs = <128>;
-                       continuous-clock;
                        cpu {
                                sound-dai = <&aml_spdif>;
-                               system-clock-frequency = <12288000>;
                        };
                        codec {
                                sound-dai = <&dummy_codec>;
index c6f55dd..fd66b34 100644 (file)
                        mclk-fs = <256>;
                        continuous-clock;
                        //bitclock-inversion;
-                       frame-inversion;
+                       //frame-inversion;
                        bitclock-master = <&aml_tdmb>;
                        frame-master = <&aml_tdmb>;
                        cpu {
                        mclk-fs = <256>;
                        continuous-clock;
                        //bitclock-inversion;
-                       frame-inversion;
+                       //frame-inversion;
                        //bitclock-master = <&aml_tdmc>;
                        //frame-master = <&aml_tdmc>;
                        cpu {
        aml_tdma: tdma {
                compatible = "amlogic, snd-tdma";
                #sound-dai-cells = <0>;
-               dai-tdm-lane-slot-mask-in = <1>;
-               dai-tdm-lane-slot-mask-out = <1>;
+               dai-tdm-lane-slot-mask-in = <1 0>;
+               dai-tdm-lane-slot-mask-out = <1>;
                dai-tdm-clk-sel = <0>;
                tdm_from_ddr = <0>;
                tdm_to_ddr = <0>;
index ac0b8a7..6f87f8b 100644 (file)
                        mclk-fs = <256>;
                        continuous-clock;
                        //bitclock-inversion;
-                       frame-inversion;
+                       //frame-inversion;
                        bitclock-master = <&aml_tdmb>;
                        frame-master = <&aml_tdmb>;
                        cpu {
                        continuous-clock;
                        /* tdmb clk using tdmc so no bclk-inv */
                        //bitclock-inversion;
-                       frame-inversion;
+                       //frame-inversion;
                        bitclock-master = <&aml_tdmc>;
                        frame-master = <&aml_tdmc>;
                        cpu {
                dai-tdm-clk-sel = <0>;
                tdm_from_ddr = <0>;
                tdm_to_ddr = <0>;
-               clocks = <&clkc CLKID_MPLL2>;
+               clocks = <&clkc CLKID_MPLL0>;
                                        //&clkaudio CLKID_AUDIO_TDMOUTA
                                        //&clkaudio CLKID_AUDIO_MCLK_A>;
                clock-names = "mpll0", "gate", "mclk";
index 9e5d337..6dbd44a 100644 (file)
@@ -336,8 +336,6 @@ static int aml_dai_tdm_startup(struct snd_pcm_substream *substream,
        struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
        int ret;
 
-       aml_tdm_fifo_reset(p_tdm->actrl, substream->stream, p_tdm->id);
-
        ret = clk_prepare_enable(p_tdm->clk);
        if (ret) {
                pr_err("Can't enable mpll clock: %d\n", ret);
@@ -624,7 +622,9 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
                fmt, p_tdm, p_tdm->id, p_tdm->clk_sel);
 
        aml_tdm_set_format(p_tdm->actrl,
-               &(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt);
+               &(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt,
+               cpu_dai->capture_active,
+               cpu_dai->playback_active);
 
        return 0;
 }
index 06af3d7..95279c4 100644 (file)
 
 #include "tdm_hw.h"
 
+#define MST_CLK_INVERT_PH0_PAD_BCLK       (1 << 0)
+#define MST_CLK_INVERT_PH0_PAD_FCLK       (1 << 1)
+#define MST_CLK_INVERT_PH1_TDMIN_BCLK     (1 << 2)
+#define MST_CLK_INVERT_PH1_TDMIN_FCLK     (1 << 3)
+#define MST_CLK_INVERT_PH2_TDMOUT_BCLK    (1 << 4)
+#define MST_CLK_INVERT_PH2_TDMOUT_FCLK    (1 << 5)
+
 void aml_tdm_enable(
        struct aml_audio_controller *actrl,
        int stream, int index,
@@ -80,22 +87,19 @@ void aml_tdm_fifo_ctrl(
        int bitwidth, int stream,
        int index)
 {
-       unsigned int frddr_type, toddr_type;
+       unsigned int frddr_type;
        unsigned int reg, offset;
 
        switch (bitwidth) {
        case 8:
                frddr_type = 0;
-               toddr_type = 0;
                break;
        case 16:
                frddr_type = 2;
-               toddr_type = 2;
                break;
        case 24:
        case 32:
                frddr_type = 4;
-               toddr_type = 4;
                break;
        default:
                pr_err("invalid bit_depth: %d\n",
@@ -123,20 +127,26 @@ void aml_tdm_set_format(
        struct pcm_setting *p_config,
        unsigned int clk_sel,
        unsigned int index,
-       unsigned int fmt)
+       unsigned int fmt,
+       unsigned int capture_active,
+       unsigned int playback_active)
 {
        unsigned int binv, finv, id;
        unsigned int valb, valf;
        unsigned int reg_in, reg_out, off_set;
        int bclkin_skew, bclkout_skew;
        int master_mode;
+       unsigned int clkctl = 0;
 
        id = index;
 
+       binv = 0;
+       finv = 0;
+
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
                valb = SLAVE_A + id;
-               valf = SLAVE_A;
+               valf = SLAVE_A + id;
                master_mode = 0;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -162,28 +172,47 @@ void aml_tdm_set_format(
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
+               bclkout_skew = 1;
+               bclkin_skew = 3;
+
+               clkctl |= MST_CLK_INVERT_PH0_PAD_FCLK;
+               if (!master_mode)
+                       finv = 1;
+
                if (master_mode) {
-                       bclkout_skew = 1;
-                       bclkin_skew = 3;
+                       clkctl |= MST_CLK_INVERT_PH0_PAD_BCLK;
+                       if (capture_active)
+                               binv |= 1;
                } else {
-                       bclkout_skew = 2;
-                       bclkin_skew = 3;
+                       if (playback_active)
+                               binv |= 1;
                }
+
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               if (master_mode) {
-                       bclkout_skew = 1;
-                       bclkin_skew = 4;
-               } else {
-                       bclkout_skew = 2;
-                       bclkin_skew = 3;
-               }
+               /*
+                * Frame high, 1clk before data, one bit for frame sync,
+                * frame sync starts one serial clock cycle earlier,
+                * that is, together with the last bit of the previous
+                * data word.
+                */
+               bclkout_skew = 1;
+               bclkin_skew = 3;
+
+               if (capture_active)
+                       binv |= 1;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
        case SND_SOC_DAIFMT_DSP_B:
-               //TODO: need test
+               /*
+                * Frame high, one bit for frame sync,
+                * frame sync asserts with the first bit of the frame.
+                */
                bclkout_skew = 2;
                bclkin_skew = 2;
+
+               if (capture_active)
+                       binv |= 1;
                break;
        default:
                return;
@@ -191,69 +220,91 @@ void aml_tdm_set_format(
 
        p_config->pcm_mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
+       pr_info("pad clk ctl value:%x\n", clkctl);
        /* set lrclk/bclk invertion */
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_IB_IF:
                /* Invert both clocks */
-               binv = 1;
-               finv = 1;
+               if (!master_mode)
+                       binv ^= 1;
+
+               finv |= 1;
+               clkctl ^= MST_CLK_INVERT_PH0_PAD_BCLK;
+               clkctl ^= MST_CLK_INVERT_PH0_PAD_FCLK;
                break;
        case SND_SOC_DAIFMT_IB_NF:
                /* Invert bit clock */
-               binv = 1;
-               finv = 0;
+               if (!master_mode)
+                       binv ^= 1;
+               clkctl ^= MST_CLK_INVERT_PH0_PAD_BCLK;
                break;
        case SND_SOC_DAIFMT_NB_IF:
                /* Invert frame clock */
-               binv = 0;
-               finv = 1;
+               finv ^= 1;
+               clkctl ^= MST_CLK_INVERT_PH0_PAD_FCLK;
                break;
        case SND_SOC_DAIFMT_NB_NF:
                /* normal cases */
-               binv = 0;
-               finv = 0;
                break;
        default:
                return;
        }
+       pr_info("sclk_ph0 (pad) clk ctl set:%x\n", clkctl);
+       /* clk ctrl: delay line and invert clk */
+       /*clkctl |= 0x88880000;*/
+       if (master_mode) {
+               off_set = EE_AUDIO_MST_B_SCLK_CTRL1 - EE_AUDIO_MST_A_SCLK_CTRL1;
+               reg_out = EE_AUDIO_MST_A_SCLK_CTRL1 + off_set * id;
+
+               aml_audiobus_update_bits(actrl, reg_out, 0x3f, clkctl);
+       }
 
        pr_info("master_mode(%d), binv(%d), finv(%d) out_skew(%d), in_skew(%d)\n",
                        master_mode, binv, finv, bclkout_skew, bclkin_skew);
 
        /* TDM out */
-       reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id;
-       aml_audiobus_update_bits(actrl, reg_out,
-               0x3<<30|0x1<<29, 0x3<<30/*|binv<<29*/);
-       // sclk_ph0 (pad) invert
-       off_set = EE_AUDIO_MST_B_SCLK_CTRL1 - EE_AUDIO_MST_A_SCLK_CTRL1;
-       reg_out = EE_AUDIO_MST_A_SCLK_CTRL1 + off_set * id;
-       aml_audiobus_update_bits(actrl, reg_out, 0x3f, !binv);
-       if (!binv)
-               bclkin_skew = 4;
-
-       off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0;
-       reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id;
-       aml_audiobus_update_bits(actrl, reg_out, 0x1f<<15, bclkout_skew<<15);
-
-       off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1;
-       reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id;
-       aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28);
+       if (playback_active) {
 
-       /* TDM in */
-       reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id;
-       aml_audiobus_update_bits(actrl, reg_in,
-                               0x3<<30|0x1<<29, 0x3<<30|binv<<29);
+               reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id;
+               aml_audiobus_update_bits(actrl, reg_out,
+                       0x3<<30, 0x3<<30);
+
+               aml_audiobus_update_bits(actrl, reg_out,
+                       0x1<<29, binv<<29);
+
+               off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1;
+               reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id;
+               aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28);
+
+               off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0;
+               reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id;
+               aml_audiobus_update_bits(actrl, reg_out,
+                       0x1f<<15, bclkout_skew<<15);
+       }
 
-       off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL;
-       reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * id;
-       if (p_config->pcm_mode == SND_SOC_DAIFMT_I2S)
+       /* TDM in */
+       if (capture_active) {
+               reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id;
                aml_audiobus_update_bits(actrl, reg_in,
-                       1<<30|3<<26|0x1<<25|0x7<<16,
-                       1<<30|3<<26|1<<25|bclkin_skew<<16);
-       else
+                       0x3<<30, 0x3<<30);
+
+               if (master_mode)
+                       aml_audiobus_update_bits(actrl, reg_in,
+                               0x1<<29, binv<<29);
+
+               off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL;
+               reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * id;
                aml_audiobus_update_bits(actrl, reg_in,
                        3<<26|0x7<<16, 3<<26|bclkin_skew<<16);
 
+               aml_audiobus_update_bits(actrl, reg_in,
+                       0x1<<25, finv<<25);
+
+               if (p_config->pcm_mode == SND_SOC_DAIFMT_I2S)
+                       aml_audiobus_update_bits(actrl, reg_in,
+                               1<<30,
+                               1<<30);
+       }
 }
 
 void aml_tdm_set_slot(
index b093b6d..966cf16 100644 (file)
@@ -59,7 +59,9 @@ extern void aml_tdm_set_format(
        struct pcm_setting *p_config,
        unsigned int clk_sel,
        unsigned int index,
-       unsigned int fmt);
+       unsigned int fmt,
+       unsigned int capture_active,
+       unsigned int playback_active);
 
 extern void aml_tdm_set_slot(
        struct aml_audio_controller *actrl,