audio: auge: add i2s to hdmix port
authorXing Wang <xing.wang@amlogic.com>
Thu, 15 Mar 2018 07:19:40 +0000 (15:19 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 16 Mar 2018 11:45:26 +0000 (03:45 -0800)
PD#161826: audio: auge: add i2s to hdmix port

Change-Id: I0aca7160342810385ea0e531ab8fe31c948a80b6
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
15 files changed:
arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts
arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts
arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts
arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts
sound/soc/amlogic/auge/audio_utils.c
sound/soc/amlogic/auge/ddr_mngr.c
sound/soc/amlogic/auge/ddr_mngr.h
sound/soc/amlogic/auge/sharebuffer.c
sound/soc/amlogic/auge/sharebuffer.h
sound/soc/amlogic/auge/spdif.c
sound/soc/amlogic/auge/spdif_hw.c
sound/soc/amlogic/auge/spdif_hw.h
sound/soc/amlogic/auge/tdm.c
sound/soc/amlogic/auge/tdm_hw.c
sound/soc/amlogic/auge/tdm_hw.h

index bace141..d18b67a 100644 (file)
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /* spdif_b to hdmi, only playback */
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        /* suffix-name, sync with android audio hal
                         * what's the dai link used for
                         */
-                       suffix-name = "alsaPORT-hdmi";
+                       suffix-name = "alsaPORT-spdifb2hdmi";
                        cpu {
                                sound-dai = <&aml_spdif_b>;
                                system-clock-frequency = <6144000>;
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /*
+                * dai link for i2s to hdmix,
+                * Notice to select a tdm lane not used by hw
+                */
+               aml-audio-card,dai-link@6 {
+                       format = "i2s";
+                       mclk-fs = <256>;
+                       //continuous-clock;
+                       //bitclock-inversion;
+                       //frame-inversion;
+                       bitclock-master = <&aml_i2s2hdmi>;
+                       frame-master = <&aml_i2s2hdmi>;
+                       /* suffix-name, sync with android audio hal
+                        * what's the dai link used for
+                        */
+                       suffix-name = "alsaPORT-i2s2hdmi";
+                       cpu {
+                               sound-dai = <&aml_i2s2hdmi>;
+                               dai-tdm-slot-tx-mask = <1 1>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                               system-clock-frequency = <12288000>;
+                       };
+                       codec {
+                               sound-dai = <&dummy_codec>;
+                       };
+               };
        };
        audiolocker: locker {
                compatible = "amlogic, audiolocker";
                pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>;
        };
 
+       /* copy a useless tdm to output for hdmi, no pinmux */
+       aml_i2s2hdmi: i2s2hdmi {
+               compatible = "amlogic, g12a-snd-tdmc";
+               #sound-dai-cells = <0>;
+               dai-tdm-lane-slot-mask-out = <1 1 1 1>;
+               dai-tdm-clk-sel = <2>;
+               clocks = <&clkaudio CLKID_AUDIO_MCLK_C
+                               &clkc CLKID_MPLL2>;
+               clock-names = "mclk", "clk_srcpll";
+
+               i2s2hdmi = <1>;
+
+               status = "okay";
+       };
+
        aml_spdif: spdif {
                compatible = "amlogic, g12a-snd-spdif-a";
                #sound-dai-cells = <0>;
index ae6fc62..4e97b28 100644 (file)
                                system-clock-frequency = <12288000>;
                        };
                        codec {
-                               sound-dai = <&dummy_codec &dummy_codec>;
+                               sound-dai = <&tlv320adc3101_32 &dummy_codec>;
                        };
                };
 
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /* spdif_b to hdmi, only playback */
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        /* suffix-name, sync with android audio hal
                         * what's the dai link used for
                         */
-                       suffix-name = "alsaPORT-hdmi";
+                       suffix-name = "alsaPORT-spdifb2hdmi";
                        cpu {
                                sound-dai = <&aml_spdif_b>;
                                system-clock-frequency = <6144000>;
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /*
+                * dai link for i2s to hdmix,
+                * Notice to select a tdm lane not used by hw
+                */
+               aml-audio-card,dai-link@6 {
+                       format = "i2s";
+                       mclk-fs = <256>;
+                       //continuous-clock;
+                       //bitclock-inversion;
+                       //frame-inversion;
+                       bitclock-master = <&aml_i2s2hdmi>;
+                       frame-master = <&aml_i2s2hdmi>;
+                       /* suffix-name, sync with android audio hal
+                        * what's the dai link used for
+                        */
+                       suffix-name = "alsaPORT-i2s2hdmi";
+                       cpu {
+                               sound-dai = <&aml_i2s2hdmi>;
+                               dai-tdm-slot-tx-mask = <1 1>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                               system-clock-frequency = <12288000>;
+                       };
+                       codec {
+                               sound-dai = <&dummy_codec>;
+                       };
+               };
        };
        audiolocker: locker {
                compatible = "amlogic, audiolocker";
                reset_pin = <&gpio GPIOA_5 0>;
        };
 
+       tlv320adc3101_32: tlv320adc3101_32@32 {
+               compatible = "ti,tlv320adc3101";
+               #sound-dai-cells = <0>;
+               reg = <0x19>;
+               differential_pair = <1>;
+               status = "okay";
+       };
+
        tas5707_36: tas5707_36@36 {
                compatible = "ti,tas5707";
                #sound-dai-cells = <0>;
        aml_tdmc: tdmc {
                compatible = "amlogic, g12a-snd-tdmc";
                #sound-dai-cells = <0>;
-               dai-tdm-lane-slot-mask-in = <0 1 0 0>;
+               dai-tdm-lane-slot-mask-in = <1 0 0 0>;
                #dai-tdm-lane-slot-mask-out = <1 0 1 1>;
                #dai-tdm-lane-oe-slot-mask-in = <0 0 0 0>;
-               dai-tdm-lane-oe-slot-mask-out = <1 0 0 0>;
+               #dai-tdm-lane-oe-slot-mask-out = <1 0 0 0>;
                dai-tdm-clk-sel = <2>;
                clocks = <&clkaudio CLKID_AUDIO_MCLK_C
                                &clkc CLKID_MPLL2>;
                pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>;
        };
 
+       /* copy a useless tdm to output for hdmi, no pinmux */
+       aml_i2s2hdmi: i2s2hdmi {
+               compatible = "amlogic, g12a-snd-tdmc";
+               #sound-dai-cells = <0>;
+               dai-tdm-lane-slot-mask-out = <1 1 1 1>;
+               dai-tdm-clk-sel = <2>;
+               clocks = <&clkaudio CLKID_AUDIO_MCLK_C
+                               &clkc CLKID_MPLL2>;
+               clock-names = "mclk", "clk_srcpll";
+
+               i2s2hdmi = <1>;
+
+               status = "okay";
+       };
+
        aml_spdif: spdif {
                compatible = "amlogic, g12a-snd-spdif-a";
                #sound-dai-cells = <0>;
        };
 
        tdmout_c:tdmout_c {
-               mux { /* GPIOA_12, GPIOA_13, GPIOA_10, GPIOA_8, GPIOA_7*/
+               mux { /* GPIOA_12, GPIOA_13, GPIOA_8, GPIOA_7*/
                        groups = "tdmc_sclk_a",
                                "tdmc_fs_a",
                                "tdmc_dout0_a"
        };
 
        tdmin_c:tdmin_c {
-               mux { /* GPIOA_9 */
-                       groups = "tdmc_din1_a";
+               mux { /* GPIOA_10 */
+                       groups = "tdmc_din0_a";
                        function = "tdmc_in";
                };
        };
index 08b006e..4ed56e2 100644 (file)
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /* spdif_b to hdmi, only playback */
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        /* suffix-name, sync with android audio hal
                         * what's the dai link used for
                         */
-                       suffix-name = "alsaPORT-hdmi";
+                       suffix-name = "alsaPORT-spdifb2hdmi";
                        cpu {
                                sound-dai = <&aml_spdif_b>;
                                system-clock-frequency = <6144000>;
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /*
+                * dai link for i2s to hdmix,
+                * Notice to select a tdm lane not used by hw
+                */
+               aml-audio-card,dai-link@6 {
+                       format = "i2s";
+                       mclk-fs = <256>;
+                       //continuous-clock;
+                       //bitclock-inversion;
+                       //frame-inversion;
+                       bitclock-master = <&aml_i2s2hdmi>;
+                       frame-master = <&aml_i2s2hdmi>;
+                       /* suffix-name, sync with android audio hal
+                        * what's the dai link used for
+                        */
+                       suffix-name = "alsaPORT-i2s2hdmi";
+                       cpu {
+                               sound-dai = <&aml_i2s2hdmi>;
+                               dai-tdm-slot-tx-mask = <1 1>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                               system-clock-frequency = <12288000>;
+                       };
+                       codec {
+                               sound-dai = <&dummy_codec>;
+                       };
+               };
        };
        audiolocker: locker {
                compatible = "amlogic, audiolocker";
                pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>;
        };
 
+       /* copy a useless tdm to output for hdmi, no pinmux */
+       aml_i2s2hdmi: i2s2hdmi {
+               compatible = "amlogic, g12a-snd-tdmc";
+               #sound-dai-cells = <0>;
+               dai-tdm-lane-slot-mask-out = <1 1 1 1>;
+               dai-tdm-clk-sel = <2>;
+               clocks = <&clkaudio CLKID_AUDIO_MCLK_C
+                               &clkc CLKID_MPLL2>;
+               clock-names = "mclk", "clk_srcpll";
+
+               i2s2hdmi = <1>;
+
+               status = "okay";
+       };
+
        aml_spdif: spdif {
                compatible = "amlogic, g12a-snd-spdif-a";
                #sound-dai-cells = <0>;
index 4e87719..797ca30 100644 (file)
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /* spdif_b to hdmi, only playback */
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        /* suffix-name, sync with android audio hal
                         * what's the dai link used for
                         */
-                       suffix-name = "alsaPORT-hdmi";
+                       suffix-name = "alsaPORT-spdifb2hdmi";
                        cpu {
                                sound-dai = <&aml_spdif_b>;
                                system-clock-frequency = <6144000>;
                                sound-dai = <&dummy_codec>;
                        };
                };
+               /*
+                * dai link for i2s to hdmix,
+                * Notice to select a tdm lane not used by hw
+                */
+               aml-audio-card,dai-link@6 {
+                       format = "i2s";
+                       mclk-fs = <256>;
+                       //continuous-clock;
+                       //bitclock-inversion;
+                       //frame-inversion;
+                       bitclock-master = <&aml_i2s2hdmi>;
+                       frame-master = <&aml_i2s2hdmi>;
+                       /* suffix-name, sync with android audio hal
+                        * what's the dai link used for
+                        */
+                       suffix-name = "alsaPORT-i2s2hdmi";
+                       cpu {
+                               sound-dai = <&aml_i2s2hdmi>;
+                               dai-tdm-slot-tx-mask = <1 1>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                               system-clock-frequency = <12288000>;
+                       };
+                       codec {
+                               sound-dai = <&dummy_codec>;
+                       };
+               };
        };
        audiolocker: locker {
                compatible = "amlogic, audiolocker";
                pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>;
        };
 
+       /* copy a useless tdm to output for hdmi, no pinmux */
+       aml_i2s2hdmi: i2s2hdmi {
+               compatible = "amlogic, g12a-snd-tdmc";
+               #sound-dai-cells = <0>;
+               dai-tdm-lane-slot-mask-out = <1 1 1 1>;
+               dai-tdm-clk-sel = <2>;
+               clocks = <&clkaudio CLKID_AUDIO_MCLK_C
+                               &clkc CLKID_MPLL2>;
+               clock-names = "mclk", "clk_srcpll";
+
+               i2s2hdmi = <1>;
+
+               status = "okay";
+       };
+
        aml_spdif: spdif {
                compatible = "amlogic, g12a-snd-spdif-a";
                #sound-dai-cells = <0>;
index d261072..bc723cc 100644 (file)
@@ -163,10 +163,11 @@ static int snd_int_get(struct snd_kcontrol *kcontrol,
        val = audiobus_read(reg);
        ucontrol->value.integer.value[0] = val;
 
-       pr_info("%s:reg:0x%x, val:0x%x\n",
-               __func__,
-               reg,
-               val);
+       /*      pr_info("%s:reg:0x%x, val:0x%x\n",
+        *              __func__,
+        *              reg,
+        *              val);
+        */
 
        return 0;
 }
@@ -177,10 +178,11 @@ static int snd_int_set(struct snd_kcontrol *kcontrol,
        int val  = (int)ucontrol->value.integer.value[0];
        unsigned int reg = kcontrol->private_value;
 
-       pr_info("%s:reg:0x%x, val:0x%x\n",
-               __func__,
-               reg,
-               val);
+       /*      pr_info("%s:reg:0x%x, val:0x%x\n",
+        *              __func__,
+        *              reg,
+        *              val);
+        */
 
        audiobus_write(reg, val);
 
@@ -220,11 +222,12 @@ static int snd_byte_get(struct snd_kcontrol *kcontrol,
 
        ucontrol->value.integer.value[0] = val;
 
-       pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n",
-               __func__,
-               einfo->reg,
-               einfo->mask,
-               val);
+       /*      pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n",
+        *              __func__,
+        *              einfo->reg,
+        *              einfo->mask,
+        *              val);
+        */
 
        return 0;
 }
@@ -240,11 +243,12 @@ static int snd_byte_set(struct snd_kcontrol *kcontrol,
        if (val > 255)
                val = 255;
 
-       pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n",
-               __func__,
-               einfo->reg,
-               einfo->mask,
-               val);
+       /*      pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n",
+        *              __func__,
+        *              einfo->reg,
+        *              einfo->mask,
+        *              val);
+        */
 
        audiobus_update_bits(
                einfo->reg,
@@ -284,17 +288,18 @@ static int snd_enum_get(struct snd_kcontrol *kcontrol,
        int val;
        struct snd_elem_info *einfo = (void *)kcontrol->private_value;
 
-       pr_info("%s:reg:0x%x, mask:0x%x",
-               __func__,
-               einfo->reg,
-               einfo->mask);
+       /* pr_info("%s:reg:0x%x, mask:0x%x",
+        *              __func__,
+        *              einfo->reg,
+        *              einfo->mask);
+        */
 
        val = audiobus_read(einfo->reg);
        val >>= einfo->shift;
        val &= einfo->mask;
        ucontrol->value.integer.value[0] = val;
 
-       pr_info("\t val:0x%x\n", val);
+       /* pr_info("\t val:0x%x\n", val); */
 
        return 0;
 }
@@ -305,12 +310,12 @@ static int snd_enum_set(struct snd_kcontrol *kcontrol,
        struct snd_elem_info *einfo = (void *)kcontrol->private_value;
        int val  = (int)ucontrol->value.integer.value[0];
 
-       pr_info("%s:reg:0x%x, swap mask:0x%x, val:0x%x\n",
-               __func__,
-               einfo->reg,
-               einfo->mask,
-               val);
-
+       /*      pr_info("%s:reg:0x%x, swap mask:0x%x, val:0x%x\n",
+        *              __func__,
+        *              einfo->reg,
+        *              einfo->mask,
+        *              val);
+        */
        audiobus_update_bits(
                einfo->reg,
                einfo->mask << einfo->shift,
@@ -481,20 +486,21 @@ static int spdif_channel_status_info(struct snd_kcontrol *kcontrol,
 static int spdifin_channel_status_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       /* struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; */
        int reg, status;
 
-       pr_info("set which channel status you wanted to get firstly\n");
+       /* pr_info("set which channel status you wanted to get firstly\n"); */
        reg = SPDIFIN_CHSTS_REG;
        status = spdif_get_channel_status(reg);
 
        ucontrol->value.enumerated.item[0] = status;
 
        /*channel status value in printk information*/
-       pr_info("%s: 0x%x\n",
-               e->texts[spdifin_channel_status],
-               status
-               );
+       /*      pr_info("%s: 0x%x\n",
+        *              e->texts[spdifin_channel_status],
+        *              status
+        *              );
+        */
        return 0;
 }
 
@@ -518,8 +524,9 @@ static int spdifin_channel_status_set(
        valid_bits = (chst >= 6) ? (chst - 6) : chst;
 
        spdifin_channel_status = chst;
-       pr_info("%s\n",
-               e->texts[spdifin_channel_status]);
+       /*      pr_info("%s\n",
+        *              e->texts[spdifin_channel_status]);
+        */
 
        spdifin_set_channel_status(ch, valid_bits);
 
@@ -529,21 +536,22 @@ static int spdifin_channel_status_set(
 static int spdifout_channel_status_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       /* struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; */
        int reg, status;
 
-       pr_info("set which channel status you wanted to get firstly\n");
+       /* pr_info("set which channel status you wanted to get firstly\n"); */
        reg = SPDIFOUT_CHSTS_REG(spdifout_channel_status);
        status = spdif_get_channel_status(reg);
 
        ucontrol->value.enumerated.item[0] = status;
 
        /*channel status value in printk information*/
-       pr_info("%s: reg:0x%x, status:0x%x\n",
-               e->texts[spdifout_channel_status],
-               reg,
-               status
-               );
+       /*      pr_info("%s: reg:0x%x, status:0x%x\n",
+        *              e->texts[spdifout_channel_status],
+        *              reg,
+        *              status
+        *              );
+        */
        return 0;
 }
 
@@ -564,9 +572,9 @@ static int spdifout_channel_status_set(
        }
 
        spdifout_channel_status = chst;
-       pr_info("%s\n",
-               e->texts[chst]);
-
+       /*      pr_info("%s\n",
+        *              e->texts[chst]);
+        */
        return 0;
 }
 
index 2ac4139..5412f65 100644 (file)
@@ -746,33 +746,34 @@ void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst)
  * sel 1 is for reg_frddr_src_sel2
  * sel 2 is for reg_frddr_src_sel3
  */
-void aml_frddr_select_dst_ss(struct frddr *fr, enum frddr_dest dst, int sel)
+void aml_frddr_select_dst_ss(struct frddr *fr,
+       enum frddr_dest dst, int sel, bool enable)
 {
        struct aml_audio_controller *actrl = fr->actrl;
        unsigned int reg_base = fr->reg_base;
        unsigned int reg;
 
-       if (dst == fr->dest) {
-               pr_warn_once("same source sel is same with frddr->dest\r");
-               return;
-       }
-
        reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base);
        /* same source en */
        if (fr->chipinfo
                && fr->chipinfo->same_src_fn) {
-
-               if (sel == 1)
-                       aml_audiobus_update_bits(actrl, reg,
-                               0xf << 4,
-                               dst << 4 | 1 << 7);
-               else if (sel == 2)
-                       aml_audiobus_update_bits(actrl, reg,
-                               0xf << 8,
-                               dst << 8 | 1 << 11);
-               else
-                       pr_warn_once("sel :%d is not supported for same source\n",
-                               sel);
+               int s_v = 0, s_m = 0;
+
+                       switch (sel) {
+                       case 1:
+                               s_m = 0xf << 4;
+                               s_v = enable ? (dst << 4 | 1 << 7) : 0 << 4;
+                               break;
+                       case 2:
+                               s_m = 0xf << 8;
+                               s_v = enable ? (dst << 8 | 1 << 11) : 0 << 8;
+                               break;
+                       default:
+                               pr_warn_once("sel :%d is not supported for same source\n",
+                                       sel);
+                               break;
+                       }
+                       aml_audiobus_update_bits(actrl, reg, s_m, s_v);
        }
 }
 
index 8fcb91d..e5762a7 100644 (file)
@@ -93,7 +93,7 @@ unsigned int aml_frddr_get_position(struct frddr *fr);
 void aml_frddr_enable(struct frddr *fr, bool enable);
 void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest);
 extern void aml_frddr_select_dst_ss(struct frddr *fr,
-       enum frddr_dest dst, int sel);
+       enum frddr_dest dst, int sel, bool enable);
 void aml_frddr_set_fifos(struct frddr *fr,
                unsigned int depth, unsigned int thresh);
 unsigned int aml_frddr_get_fifo_id(struct frddr *fr);
index 6d1392b..99cca7a 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "spdif_hw.h"
 
-int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
+static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
        struct frddr *fr, int spdif_id)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
@@ -37,13 +37,28 @@ int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
 
        /* spdif b, notify hdmitx audio */
        if (spdif_id == 1) {
-               spdifoutb_to_hdmitx_ctrl();
+               spdifoutb_to_hdmitx_ctrl(spdif_id);
                aout_notifier_call_chain(0x1, substream);
        }
 
        return 0;
 }
 
+static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream,
+       struct frddr *fr, int spdif_id)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       int bit_depth;
+
+       bit_depth = snd_pcm_format_width(runtime->format);
+
+       spdifout_samesource_set(spdif_id,
+               aml_frddr_get_fifo_id(fr),
+               bit_depth, false);
+
+       return 0;
+}
+
 void sharebuffer_enable(int sel, bool enable)
 {
        if (sel < 0) {
@@ -74,11 +89,34 @@ int sharebuffer_prepare(struct snd_pcm_substream *substream,
        }
 
        /* frddr, share buffer, src_sel1 */
-       aml_frddr_select_dst_ss(fr, samesource_sel, 1);
+       aml_frddr_select_dst_ss(fr, samesource_sel, 1, true);
 
        return 0;
 }
 
+int sharebuffer_free(struct snd_pcm_substream *substream,
+       void *pfrddr, int samesource_sel)
+{
+       struct frddr *fr = (struct frddr *)pfrddr;
+
+       /* each module prepare, clocks and controls */
+       if (samesource_sel < 0) {
+               pr_err("Not support same source\n");
+               return -EINVAL;
+       } else if (samesource_sel < 3) {
+               // TODO: same with tdm
+       } else if (samesource_sel < 5) {
+               /* same source with spdif a/b */
+               sharebuffer_spdifout_free(substream, fr, samesource_sel - 3);
+       }
+
+       /* frddr, share buffer, src_sel1 */
+       aml_frddr_select_dst_ss(fr, samesource_sel, 1, false);
+
+       return 0;
+}
+
+
 int sharebuffer_trigger(int cmd, int samesource_sel)
 {
        switch (cmd) {
index fa2823b..25dca7d 100644 (file)
@@ -19,6 +19,8 @@
 
 extern int sharebuffer_prepare(struct snd_pcm_substream *substream,
        void *pfrddr, int samesource_sel);
+extern int sharebuffer_free(struct snd_pcm_substream *substream,
+               void *pfrddr, int samesource_sel);
 extern int sharebuffer_trigger(int cmd, int samesource_sel);
 
 extern void sharebuffer_get_mclk_fs_ratio(int samesource_sel,
index 111bf90..3e8df70 100644 (file)
@@ -418,7 +418,7 @@ static int aml_dai_spdif_prepare(
 
                /* TOHDMITX_CTRL0 */
                if (p_spdif->id == 1) {
-                       spdifoutb_to_hdmitx_ctrl();
+                       spdifoutb_to_hdmitx_ctrl(p_spdif->id);
                        aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,
                                substream);
                }
index 9accf28..017f6d7 100644 (file)
@@ -270,14 +270,15 @@ void aml_spdifout_get_aed_info(int spdifout_id,
                *frddrtype = (val >> 4) & 0x7;
 }
 
-void spdifoutb_to_hdmitx_ctrl(void)
+/*value for spdif_index is only 0, 1 */
+void spdifoutb_to_hdmitx_ctrl(int spdif_index)
 {
        audiobus_write(EE_AUDIO_TOHDMITX_CTRL0,
                1 << 31
                | 1 << 3 /* spdif_clk_cap_inv */
                | 0 << 2 /* spdif_clk_inv */
-               | 1 << 1 /* spdif_out_b */
-               | 1 << 0 /* spdif_clk_b */
+               | spdif_index << 1 /* spdif_out_b */
+               | spdif_index << 0 /* spdif_clk_b */
        );
 }
 
@@ -364,6 +365,9 @@ void spdifout_samesource_set(int spdif_index, int fifo_id,
        else
                spdif_id = 0;
 
-       spdifout_clk_ctrl(spdif_id, true);
-       spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth);
+       if (is_enable) {
+               spdifout_clk_ctrl(spdif_id, true);
+               spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth);
+       } else
+               spdifout_clk_ctrl(spdif_id, false);
 }
index d3a9e48..c332bfb 100644 (file)
@@ -53,7 +53,7 @@ extern void aml_spdifout_select_aed(bool enable, int spdifout_id);
 extern void aml_spdifout_get_aed_info(int spdifout_id,
        int *bitwidth, int *frddrtype);
 
-extern void spdifoutb_to_hdmitx_ctrl(void);
+extern void spdifoutb_to_hdmitx_ctrl(int spdif_index);
 
 extern void spdifout_samesource_set(int spdif_index, int fifo_id,
        int bitwidth, bool is_enable);
index 9977187..9b72816 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/amlogic/clk_measure.h>
 #include <linux/amlogic/cpu_version.h>
 
+#include <linux/amlogic/media/sound/aout_notify.h>
+
 #include "ddr_mngr.h"
 #include "tdm_hw.h"
 
@@ -107,6 +109,8 @@ struct aml_tdm {
        struct tdm_chipinfo *chipinfo;
        /* share buffer with module */
        int samesource_sel;
+       /* virtual link for i2s to hdmitx */
+       int i2s2hdmitx;
 };
 
 static const struct snd_pcm_hardware aml_tdm_hardware = {
@@ -401,6 +405,13 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream,
                                        fr, p_tdm->samesource_sel);
                }
 
+               /* i2s source to hdmix */
+               if (p_tdm->i2s2hdmitx) {
+                       i2s_to_hdmitx_ctrl(p_tdm->id);
+                       aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,
+                               substream);
+               }
+
                fifo_id = aml_frddr_get_fifo_id(fr);
                aml_tdm_fifo_ctrl(p_tdm->actrl,
                        bit_depth,
@@ -681,12 +692,21 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *cpu_dai)
 {
        struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
+       struct frddr *fr = p_tdm->fddr;
        int i;
 
        for (i = 0; i < 4; i++)
                aml_tdm_set_channel_mask(p_tdm->actrl,
                        substream->stream, p_tdm->id, i, 0);
 
+       /* share buffer free */
+       if (p_tdm->chipinfo &&
+               p_tdm->chipinfo->same_src_fn && fr) {
+               if (p_tdm->samesource_sel >= 0)
+                       sharebuffer_free(substream,
+                               fr, p_tdm->samesource_sel);
+       }
+
        return 0;
 }
 
@@ -1134,6 +1154,14 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
                        p_tdm->samesource_sel);
        }
 
+       ret = of_property_read_u32(node, "i2s2hdmi",
+                       &p_tdm->i2s2hdmitx);
+       if (ret < 0)
+               p_tdm->i2s2hdmitx = 0;
+       pr_info("TDM id %d i2s2hdmi:%d\n",
+               p_tdm->id,
+               p_tdm->i2s2hdmitx);
+
        /* get tdm lanes info. if not, set to default 1 */
        ret = of_parse_tdm_lane_slot_in(node,
                        &p_tdm->setting.lane_mask_in);
index 358a0a2..3ace5a7 100644 (file)
@@ -587,3 +587,15 @@ void aml_tdm_clk_pad_select(
                mask_offset, val_offset);
 
 }
+
+void i2s_to_hdmitx_ctrl(int tdm_index)
+{
+       audiobus_write(EE_AUDIO_TOHDMITX_CTRL0,
+               1 << 31
+               | tdm_index << 12 /* dat_sel */
+               | tdm_index << 8 /* lrclk_sel */
+               | 1 << 7 /* Bclk_cap_inv */
+               | 0 << 6 /* Bclk_o_inv */
+               | tdm_index << 4 /* Bclk_sel */
+       );
+}
index 506c016..896bdf2 100644 (file)
@@ -109,4 +109,6 @@ extern void aml_tdm_clk_pad_select(
        struct aml_audio_controller *actrl,
        int mpad, int mclk_sel,
        int tdm_index, int clk_sel);
+
+extern void i2s_to_hdmitx_ctrl(int tdm_index);
 #endif