audio: auge: fix drivers for tl1 [1/1]
authorXing Wang <xing.wang@amlogic.com>
Tue, 30 Oct 2018 07:38:34 +0000 (15:38 +0800)
committerBo Yang <bo.yang@amlogic.com>
Mon, 26 Nov 2018 17:24:54 +0000 (01:24 +0800)
PD#172587

Problem:
resample, eqdrc, dolby efuse, audio input (from atv, hdmirx)

Solution:
add drivers for them

Verify:
x301

Change-Id: I5187f9824d904283794f6e4be3dd9ce8463908e1
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
49 files changed:
MAINTAINERS
arch/arm/boot/dts/amlogic/mesontl1.dtsi
arch/arm/boot/dts/amlogic/tl1_pxp.dts
arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts
arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts
include/dt-bindings/clock/amlogic,tl1-audio-clk.h
include/linux/amlogic/media/frame_provider/tvin/tvin.h
include/linux/amlogic/media/sound/misc.h [new file with mode: 0644]
include/linux/amlogic/media/sound/spdif_info.h
sound/soc/amlogic/auge/Makefile
sound/soc/amlogic/auge/audio_controller.c
sound/soc/amlogic/auge/audio_utils.c
sound/soc/amlogic/auge/audio_utils.h
sound/soc/amlogic/auge/card.c
sound/soc/amlogic/auge/ddr_mngr.c
sound/soc/amlogic/auge/ddr_mngr.h
sound/soc/amlogic/auge/effects.c
sound/soc/amlogic/auge/effects_hw.c
sound/soc/amlogic/auge/effects_hw_v2.c [new file with mode: 0644]
sound/soc/amlogic/auge/effects_hw_v2.h [new file with mode: 0644]
sound/soc/amlogic/auge/effects_hw_v2_coeff.c [new file with mode: 0644]
sound/soc/amlogic/auge/effects_v2.c [new file with mode: 0644]
sound/soc/amlogic/auge/effects_v2.h [new file with mode: 0644]
sound/soc/amlogic/auge/extn.c
sound/soc/amlogic/auge/frhdmirx_hw.c
sound/soc/amlogic/auge/iomap.c
sound/soc/amlogic/auge/iomap.h
sound/soc/amlogic/auge/locker.c
sound/soc/amlogic/auge/pdm.c
sound/soc/amlogic/auge/pdm_hw.c
sound/soc/amlogic/auge/pdm_hw.h
sound/soc/amlogic/auge/regs.h
sound/soc/amlogic/auge/resample.c
sound/soc/amlogic/auge/resample.h
sound/soc/amlogic/auge/resample_hw.c
sound/soc/amlogic/auge/resample_hw.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
sound/soc/amlogic/auge/tl1,clocks.c
sound/soc/amlogic/common/Makefile
sound/soc/amlogic/common/misc.c [new file with mode: 0644]
sound/soc/amlogic/common/spdif_info.c
sound/soc/amlogic/meson/spdif_codec.c
sound/soc/amlogic/meson/tv.c
sound/soc/amlogic/meson/tv.h

index 6e0f854..a97d567 100644 (file)
@@ -14655,15 +14655,13 @@ M:    Luan Yuan <luan.yuan@amlogic.com>
 F:     arch/arm/boot/dts/amlogic/partition_mbox_p241_P.dtsi
 
 AMLOGIC TL1 SOUND CARD
-M:      Xing Wang <xing.wang@amlogic.com
-F:     include/dt-bindings/clock/amlogic,tl1-audio-clk.h
-F:     sound/soc/amlogic/auge/*
-
 AMLOGIC TL1 AUDIO EXTERANL INPUT/OUTPUT DRIVERS
+AMLOGIC TL1 NEW EQDRC
+AMLOGIC TL1 MIXER CONTROLS
 M:     Xing Wang <xing.wang@amlogic.com
-F:     sound/soc/amlogic/auge/extn.c
-F:     sound/soc/amlogic/auge/frhdmirx_hw.c
-F:     sound/soc/amlogic/auge/frhdmirx_hw.h
+F:     arch/arm/boot/dts/amlogic/tl1_pxp.dts
+F:     include/dt-bindings/clock/amlogic,tl1-audio-clk.h
+F:     include/linux/amlogic/media/sound/misc.h
 F:     sound/soc/amlogic/auge/*
 
 AMLOGIC LCD DRIVERS
index e08b071..9f42817 100644 (file)
                        size = <16>;
                };
        };
+
+       audio_data: audio_data {
+               compatible = "amlogic, audio_data";
+               query_licence_cmd = <0x82000050>;
+               status = "disabled";
+       };
 }; /* end of / */
 
 &pinctrl_aobus {
index f2dac29..de44e5a 100644 (file)
                        /* suffix-name, sync with android audio hal used for */
                        suffix-name = "alsaPORT-spdif";
                        cpu {
-                               sound-dai = <&spdif_a>;
+                               sound-dai = <&spdifa>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        cpu {
-                               sound-dai = <&spdif_b>;
+                               sound-dai = <&spdifb>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
 };
 
 &audiobus {
-       tdma:tdm {
+       tdma:tdm@0 {
                compatible = "amlogic, tl1-snd-tdma";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       tdmb:tdm {
+       tdmb:tdm@1 {
                compatible = "amlogic, tl1-snd-tdmb";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       tdmc:tdm {
+       tdmc:tdm@2 {
                compatible = "amlogic, tl1-snd-tdmc";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       spdif_a:spdif {
+       spdifa:spdif@0 {
                compatible = "amlogic, tl1-snd-spdif-a";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0
                                &clkc CLKID_FCLK_DIV4
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFIN
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A
                                &clkaudio CLKID_AUDIO_SPDIFIN
-                               &clkaudio CLKID_AUDIO_SPDIFOUT
-                               &clkaudio CLKID_AUDIO_SPDIFIN_CTRL
-                               &clkaudio CLKID_AUDIO_SPDIFOUT_CTRL>;
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_A>;
                clock-names = "sysclk", "fixed_clk", "gate_spdifin",
                                "gate_spdifout", "clk_spdifin", "clk_spdifout";
 
                pinctrl-names = "spdif_pins";
                pinctrl-0 = <&spdifout_a &spdifin_a>;
 
+               /*
+                * whether do asrc for pcm and resample a or b
+                * if raw data, asrc is disabled automatically
+                * 0: "Disable",
+                * 1: "Enable:32K",
+                * 2: "Enable:44K",
+                * 3: "Enable:48K",
+                * 4: "Enable:88K",
+                * 5: "Enable:96K",
+                * 6: "Enable:176K",
+                * 7: "Enable:192K",
+                */
+               asrc_id = <0>;
+               auto_asrc = <0>;
+
                status = "okay";
        };
 
-       spdif_b:spdif {
+       spdifb:spdif@1 {
                compatible = "amlogic, tl1-snd-spdif-b";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB_CTRL>;
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_B>;
                clock-names = "sysclk",
                                "gate_spdifout", "clk_spdifout";
 
                compatible = "amlogic, tl1-snd-pdm";
                #sound-dai-cells = <0>;
 
-               clocks = <&clkaudio CLKID_AUDIO_PDM
+               clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
                        &clkc CLKID_FCLK_DIV3
                        &clkc CLKID_MPLL3
                        &clkaudio CLKID_AUDIO_PDMIN0
                status = "okay";
        };
 
+       aed:effect {
+               compatible = "amlogic, snd-effect-v2";
+               #sound-dai-cells = <0>;
+
+               clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC
+                       &clkc CLKID_FCLK_DIV5
+                       &clkaudio CLKID_AUDIO_EQDRC>;
+               clock-names = "gate", "clk_srcpll", "eqdrc";
+
+               eq_enable = <1>;
+               multiband_drc_enable = <0>;
+               fullband_drc_enable = <0>;
+               /*
+                * 0:tdmout_a
+                * 1:tdmout_b
+                * 2:tdmout_c
+                * 3:spdifout
+                * 4:spdifout_b
+                */
+               eqdrc_module = <1>;
+               /* max 0xf, each bit for one lane, usually one lane */
+               lane_mask = <0x1>;
+               /* max 0xff, each bit for one channel */
+               channel_mask = <0x3>;
+
+               status = "disabled";
+       };
+
+       asrca: resample@0 {
+               compatible = "amlogic, tl1-resample-a";
+               clocks = <&clkc CLKID_MPLL3
+                               &clkaudio CLKID_AUDIO_MCLK_F
+                               &clkaudio CLKID_AUDIO_RESAMPLE_A>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
+       asrcb: resample@1 {
+               compatible = "amlogic, tl1-resample-b";
+
+               clocks = <&clkc CLKID_MPLL3
+                       &clkaudio CLKID_AUDIO_MCLK_F
+                       &clkaudio CLKID_AUDIO_RESAMPLE_B>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
 }; /* end of audiobus */
 
 &pinctrl_periphs {
index be80c17..0087b40 100644 (file)
                aml-audio-card,name = "AML-AUGESOUND";
 
                aml-audio-card,dai-link@0 {
-                       format = "dsp_a";
-                       mclk-fs = <512>;
+                       format = "i2s";
+                       mclk-fs = <256>;
                        //continuous-clock;
                        //bitclock-inversion;
                        //frame-inversion;
                        tdmacpu: cpu {
                                sound-dai = <&tdma>;
                                dai-tdm-slot-tx-mask =
-                                                       <1 1 1 1 1 1 1 1>;
+                                                       <1 1>;
                                dai-tdm-slot-rx-mask =
-                                                       <1 1 1 1 1 1 1 1>;
-                               dai-tdm-slot-num = <8>;
+                                                       <1 1>;
+                               dai-tdm-slot-num = <2>;
                                dai-tdm-slot-width = <32>;
-                               system-clock-frequency = <24576000>;
+                               system-clock-frequency = <12288000>;
                        };
                        tdmacodec: codec {
                                sound-dai = <&dummy_codec>;
                        /* suffix-name, sync with android audio hal used for */
                        suffix-name = "alsaPORT-spdif";
                        cpu {
-                               sound-dai = <&spdif_a>;
+                               sound-dai = <&spdifa>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        cpu {
-                               sound-dai = <&spdif_b>;
+                               sound-dai = <&spdifb>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
 };
 
 &audiobus {
-       tdma:tdm {
+       tdma:tdm@0 {
                compatible = "amlogic, tl1-snd-tdma";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       tdmb:tdm {
+       tdmb:tdm@1 {
                compatible = "amlogic, tl1-snd-tdmb";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       tdmc:tdm {
+       tdmc:tdm@2 {
                compatible = "amlogic, tl1-snd-tdmc";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       spdif_a:spdif {
+       spdifa:spdif@0 {
                compatible = "amlogic, tl1-snd-spdif-a";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0
                                &clkc CLKID_FCLK_DIV4
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFIN
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A
                                &clkaudio CLKID_AUDIO_SPDIFIN
-                               &clkaudio CLKID_AUDIO_SPDIFOUT
-                               &clkaudio CLKID_AUDIO_SPDIFIN_CTRL
-                               &clkaudio CLKID_AUDIO_SPDIFOUT_CTRL>;
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_A>;
                clock-names = "sysclk", "fixed_clk", "gate_spdifin",
                                "gate_spdifout", "clk_spdifin", "clk_spdifout";
 
                pinctrl-names = "spdif_pins";
                pinctrl-0 = <&spdifout_a &spdifin_a>;
 
+               /*
+                * whether do asrc for pcm and resample a or b
+                * if raw data, asrc is disabled automatically
+                * 0: "Disable",
+                * 1: "Enable:32K",
+                * 2: "Enable:44K",
+                * 3: "Enable:48K",
+                * 4: "Enable:88K",
+                * 5: "Enable:96K",
+                * 6: "Enable:176K",
+                * 7: "Enable:192K",
+                */
+               asrc_id = <0>;
+               auto_asrc = <0>;
+
                status = "okay";
        };
 
-       spdif_b:spdif {
+       spdifb:spdif@1 {
                compatible = "amlogic, tl1-snd-spdif-b";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB_CTRL>;
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_B>;
                clock-names = "sysclk",
                                "gate_spdifout", "clk_spdifout";
 
                compatible = "amlogic, tl1-snd-pdm";
                #sound-dai-cells = <0>;
 
-               clocks = <&clkaudio CLKID_AUDIO_PDM
+               clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
                        &clkc CLKID_FCLK_DIV3
                        &clkc CLKID_MPLL3
                        &clkaudio CLKID_AUDIO_PDMIN0
                status = "okay";
        };
 
+       aed:effect {
+               compatible = "amlogic, snd-effect-v2";
+               #sound-dai-cells = <0>;
+
+               clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC
+                       &clkc CLKID_FCLK_DIV5
+                       &clkaudio CLKID_AUDIO_EQDRC>;
+               clock-names = "gate", "srcpll", "eqdrc";
+
+               eq_enable = <1>;
+               multiband_drc_enable = <0>;
+               fullband_drc_enable = <0>;
+               /*
+                * 0:tdmout_a
+                * 1:tdmout_b
+                * 2:tdmout_c
+                * 3:spdifout
+                * 4:spdifout_b
+                */
+               eqdrc_module = <0>;
+               /* max 0xf, each bit for one lane, usually one lane */
+               lane_mask = <0x1>;
+               /* max 0xff, each bit for one channel */
+               channel_mask = <0x3>;
+
+               status = "okay";
+       };
+
+       asrca: resample@0 {
+               compatible = "amlogic, tl1-resample-a";
+               clocks = <&clkc CLKID_MPLL3
+                               &clkaudio CLKID_AUDIO_MCLK_F
+                               &clkaudio CLKID_AUDIO_RESAMPLE_A>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
+       asrcb: resample@1 {
+               compatible = "amlogic, tl1-resample-b";
+
+               clocks = <&clkc CLKID_MPLL3
+                       &clkaudio CLKID_AUDIO_MCLK_F
+                       &clkaudio CLKID_AUDIO_RESAMPLE_B>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
 }; /* end of audiobus */
 
 &pinctrl_periphs {
                        function = "tdma_in";
                };
        };
-
+#if 0 //verify tdm/i2s in
+       tdmin_a: tdmin_a {
+               mux { /* GPIOZ_7 */
+                       groups = "tdma_din0_z";
+                       function = "tdma_in";
+               };
+       };
+#endif
        tdmout_c: tdmout_c {
                mux { /* GPIODV_7, GPIODV_8, GPIODV_9 */
                        groups = "tdmc_sclk",
        };
 
        pdmin: pdmin {
-               mux { /* GPIOZ_7, GPIOZ_8*/
+               mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */
                        groups = "pdm_dclk_z",
-                               "pdm_din0_z";
+                               "pdm_din0_z",
+                               "pdm_din2_z4";
                        function = "pdm";
                };
        };
        };
 };  /* end of pinctrl_aobus */
 
+&audio_data{
+       status = "okay";
+};
+
 &sd_emmc_c {
        status = "okay";
        emmc {
index 144772a..b8934ab 100644 (file)
                aml-audio-card,name = "AML-AUGESOUND";
 
                aml-audio-card,dai-link@0 {
-                       format = "dsp_a";
-                       mclk-fs = <512>;
+                       format = "i2s";
+                       mclk-fs = <256>;
                        //continuous-clock;
                        //bitclock-inversion;
                        //frame-inversion;
                         * frame-master = <&tdmacodec>;
                         */
                        /* suffix-name, sync with android audio hal used for */
-                       suffix-name = "alsaPORT-pcm";
+                       suffix-name = "alsaPORT-i2s";
                        tdmacpu: cpu {
                                sound-dai = <&tdma>;
                                dai-tdm-slot-tx-mask =
-                                                       <1 1 1 1 1 1 1 1>;
+                                                       <1 1>;
                                dai-tdm-slot-rx-mask =
-                                                       <1 1 1 1 1 1 1 1>;
-                               dai-tdm-slot-num = <8>;
+                                                       <1 1>;
+                               dai-tdm-slot-num = <2>;
                                dai-tdm-slot-width = <32>;
-                               system-clock-frequency = <24576000>;
+                               system-clock-frequency = <12288000>;
                        };
                        tdmacodec: codec {
-                               sound-dai = <&dummy_codec>;
+                               sound-dai = <&ad82584f>;
                        };
                };
 
                aml-audio-card,dai-link@1 {
+                       status = "disabled";
+
                        format = "i2s";
                        mclk-fs = <256>;
                        //continuous-clock;
                        //bitclock-master = <&tdmbcodec>;
                        //frame-master = <&tdmbcodec>;
                        /* suffix-name, sync with android audio hal used for */
-                       suffix-name = "alsaPORT-i2s";
+                       suffix-name = "alsaPORT-pcm";
                        cpu {
                                sound-dai = <&tdmb>;
                                dai-tdm-slot-tx-mask = <1 1>;
                };
 
                aml-audio-card,dai-link@2 {
+                       status = "disabled";
+
                        format = "i2s";
                        mclk-fs = <256>;
                        //continuous-clock;
                        /* suffix-name, sync with android audio hal used for */
                        suffix-name = "alsaPORT-spdif";
                        cpu {
-                               sound-dai = <&spdif_a>;
+                               sound-dai = <&spdifa>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
                aml-audio-card,dai-link@5 {
                        mclk-fs = <128>;
                        cpu {
-                               sound-dai = <&spdif_b>;
+                               sound-dai = <&spdifb>;
                                system-clock-frequency = <6144000>;
                        };
                        codec {
 
                aml-audio-card,dai-link@6 {
                        mclk-fs = <256>;
+                       suffix-name = "alsaPORT-tv";
                        cpu {
                                sound-dai = <&extn>;
                                system-clock-frequency = <12288000>;
 };
 
 &audiobus {
-       tdma:tdm {
+       tdma:tdm@0 {
                compatible = "amlogic, tl1-snd-tdma";
                #sound-dai-cells = <0>;
 
-               dai-tdm-lane-slot-mask-in = <1 0>;
-               dai-tdm-lane-slot-mask-out = <1 0>;
+               #dai-tdm-lane-slot-mask-in = <1 0>;
+               dai-tdm-lane-slot-mask-out = <1 1 1 1>;
                dai-tdm-clk-sel = <0>;
 
                clocks = <&clkaudio CLKID_AUDIO_MCLK_A
-                               &clkc CLKID_MPLL0>;
-               clock-names = "mclk", "clk_srcpll";
+                               &clkc CLKID_MPLL0
+                               &clkc CLKID_MPLL1>;
+               clock-names = "mclk", "clk_srcpll", "samesource_sysclk";
 
                pinctrl-names = "tdm_pins";
-               pinctrl-0 = <&tdma_mclk &tdmout_a &tdmin_a>;
+               pinctrl-0 = <&tdma_mclk &tdmout_a>;
+
+               /*
+                * 0: tdmout_a;
+                * 1: tdmout_b;
+                * 2: tdmout_c;
+                * 3: spdifout;
+                * 4: spdifout_b;
+                */
+               samesource_sel = <3>;
 
                status = "okay";
        };
 
-       tdmb:tdm {
+       tdmb:tdm@1 {
                compatible = "amlogic, tl1-snd-tdmb";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       tdmc:tdm {
+       tdmc:tdm@2 {
                compatible = "amlogic, tl1-snd-tdmc";
                #sound-dai-cells = <0>;
 
                status = "okay";
        };
 
-       spdif_a:spdif {
+       spdifa:spdif@0 {
                compatible = "amlogic, tl1-snd-spdif-a";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0
                                &clkc CLKID_FCLK_DIV4
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFIN
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A
                                &clkaudio CLKID_AUDIO_SPDIFIN
-                               &clkaudio CLKID_AUDIO_SPDIFOUT
-                               &clkaudio CLKID_AUDIO_SPDIFIN_CTRL
-                               &clkaudio CLKID_AUDIO_SPDIFOUT_CTRL>;
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_A>;
                clock-names = "sysclk", "fixed_clk", "gate_spdifin",
                                "gate_spdifout", "clk_spdifin", "clk_spdifout";
 
                interrupt-names = "irq_spdifin";
 
                pinctrl-names = "spdif_pins";
-               pinctrl-0 = <&spdifout_a &spdifin_a>;
+               pinctrl-0 = <&spdifout_a>;
+
+               /*
+                * whether do asrc for pcm and resample a or b
+                * if raw data, asrc is disabled automatically
+                * 0: "Disable",
+                * 1: "Enable:32K",
+                * 2: "Enable:44K",
+                * 3: "Enable:48K",
+                * 4: "Enable:88K",
+                * 5: "Enable:96K",
+                * 6: "Enable:176K",
+                * 7: "Enable:192K",
+                */
+               asrc_id = <0>;
+               auto_asrc = <0>;
 
                status = "okay";
        };
 
-       spdif_b:spdif {
+       spdifb:spdif@1 {
                compatible = "amlogic, tl1-snd-spdif-b";
                #sound-dai-cells = <0>;
 
                clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB
-                               &clkaudio CLKID_AUDIO_SPDIFOUTB_CTRL>;
+                               &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B
+                               &clkaudio CLKID_AUDIO_SPDIFOUT_B>;
                clock-names = "sysclk",
                                "gate_spdifout", "clk_spdifout";
 
                compatible = "amlogic, tl1-snd-pdm";
                #sound-dai-cells = <0>;
 
-               clocks = <&clkaudio CLKID_AUDIO_PDM
+               clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
                        &clkc CLKID_FCLK_DIV3
                        &clkc CLKID_MPLL3
                        &clkaudio CLKID_AUDIO_PDMIN0
                status = "okay";
        };
 
+       aed:effect {
+               compatible = "amlogic, snd-effect-v2";
+               #sound-dai-cells = <0>;
+
+               clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC
+                       &clkc CLKID_FCLK_DIV5
+                       &clkaudio CLKID_AUDIO_EQDRC>;
+               clock-names = "gate", "srcpll", "eqdrc";
+
+               eq_enable = <1>;
+               multiband_drc_enable = <0>;
+               fullband_drc_enable = <0>;
+               /*
+                * 0:tdmout_a
+                * 1:tdmout_b
+                * 2:tdmout_c
+                * 3:spdifout
+                * 4:spdifout_b
+                */
+               eqdrc_module = <0>;
+               /* max 0xf, each bit for one lane, usually one lane */
+               lane_mask = <0x1>;
+               /* max 0xff, each bit for one channel */
+               channel_mask = <0x3>;
+
+               status = "okay";
+       };
+
+       asrca: resample@0 {
+               compatible = "amlogic, tl1-resample-a";
+               clocks = <&clkc CLKID_MPLL3
+                               &clkaudio CLKID_AUDIO_MCLK_F
+                               &clkaudio CLKID_AUDIO_RESAMPLE_A>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
+       asrcb: resample@1 {
+               compatible = "amlogic, tl1-resample-b";
+
+               clocks = <&clkc CLKID_MPLL3
+                       &clkaudio CLKID_AUDIO_MCLK_F
+                       &clkaudio CLKID_AUDIO_RESAMPLE_B>;
+               clock-names = "resample_pll", "resample_src", "resample_clk";
+
+               /*same with toddr_src
+                *      TDMIN_A, 0
+                *      TDMIN_B, 1
+                *      TDMIN_C, 2
+                *      SPDIFIN, 3
+                *      PDMIN,  4
+                *      NONE,
+                *      TDMIN_LB, 6
+                *      LOOPBACK, 7
+                */
+               resample_module = <3>;
+
+               status = "disabled";
+       };
+
 }; /* end of audiobus */
 
 &pinctrl_periphs {
        };
 
        tdmout_a: tdmout_a {
-               mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3, GPIOZ_5, GPIOZ_6 */
+               mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3 */
                        groups = "tdma_sclk_z",
                                "tdma_fs_z",
-                               "tdma_dout0_z",
-                               "tdma_dout2_z",
-                               "tdma_dout3_z";
+                               "tdma_dout0_z";
                        function = "tdma_out";
                };
        };
        };
 
        pdmin: pdmin {
-               mux { /* GPIOZ_7, GPIOZ_8*/
+               mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */
                        groups = "pdm_dclk_z",
-                               "pdm_din0_z";
+                               "pdm_din0_z",
+                               "pdm_din2_z4";
                        function = "pdm";
                };
        };
 
 }; /* end of pinctrl_periphs */
 
-&pinctrl_aobus {
-       spdifout: spdifout {
-               mux { /* gpiao_10 */
-                       groups = "spdif_out_ao";
-                       function = "spdif_out_ao";
-               };
+&audio_data{
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+       pinctrl-names="default";
+       pinctrl-0=<&i2c2_z_pins>;
+       clock-frequency = <400000>;
+
+       ad82584f: ad82584f@62 {
+               compatible = "ESMT, ad82584f";
+               #sound-dai-cells = <0>;
+               reg = <0x31>;
+               status = "okay";
+               reset_pin = <&gpio_ao GPIOAO_6 0>;
        };
-};  /* end of pinctrl_aobus */
+
+};
 
 &sd_emmc_c {
        status = "okay";
index a000dee..c466c02 100644 (file)
  *
  */
 
-#ifndef __TL1_AUDIO_CLK_H
-#define __TL1_AUDIO_CLK_H
+#ifndef __TL1_AUDIO_CLK_H__
+#define __TL1_AUDIO_CLK_H__
 
 /*
  * CLKID audio index values
  */
 
-#define CLKID_AUDIO_DDR_ARB                     0
-#define CLKID_AUDIO_PDM                         1
-#define CLKID_AUDIO_TDMINA                      2
-#define CLKID_AUDIO_TDMINB                      3
-#define CLKID_AUDIO_TDMINC                      4
-#define CLKID_AUDIO_TDMINLB                     5
-#define CLKID_AUDIO_TDMOUTA                     6
-#define CLKID_AUDIO_TDMOUTB                     7
-#define CLKID_AUDIO_TDMOUTC                     8
-#define CLKID_AUDIO_FRDDRA                      9
-#define CLKID_AUDIO_FRDDRB                      10
-#define CLKID_AUDIO_FRDDRC                      11
-#define CLKID_AUDIO_TODDRA                      12
-#define CLKID_AUDIO_TODDRB                      13
-#define CLKID_AUDIO_TODDRC                      14
-#define CLKID_AUDIO_LOOPBACKA                   15
-#define CLKID_AUDIO_SPDIFIN                     16
-#define CLKID_AUDIO_SPDIFOUT                    17
-#define CLKID_AUDIO_RESAMPLEA                   18
-#define CLKID_AUDIO_RESERVED0                   19
-#define CLKID_AUDIO_RESERVED1                   20
-#define CLKID_AUDIO_SPDIFOUTB                   21
-#define CLKID_AUDIO_EQDRC                       22
-#define CLKID_AUDIO_RESAMPLEB                   23
-#define CLKID_AUDIO_TOVAD                       24
-#define CLKID_AUDIO_AUDIOLOCKER                 25
-#define CLKID_AUDIO_SPDIFIN_LB                  26
-#define CLKID_AUDIO_FRATV                       27
-#define CLKID_AUDIO_FRHDMIRX                    28
-#define CLKID_AUDIO_FRDDRD                      29
-#define CLKID_AUDIO_TODDRD                      30
-#define CLKID_AUDIO_LOOPBACKB                   31
+#define CLKID_AUDIO_GATE_DDR_ARB                0
+#define CLKID_AUDIO_GATE_PDM                    1
+#define CLKID_AUDIO_GATE_TDMINA                 2
+#define CLKID_AUDIO_GATE_TDMINB                 3
+#define CLKID_AUDIO_GATE_TDMINC                 4
+#define CLKID_AUDIO_GATE_TDMINLB                5
+#define CLKID_AUDIO_GATE_TDMOUTA                6
+#define CLKID_AUDIO_GATE_TDMOUTB                7
+#define CLKID_AUDIO_GATE_TDMOUTC                8
+#define CLKID_AUDIO_GATE_FRDDRA                 9
+#define CLKID_AUDIO_GATE_FRDDRB                 10
+#define CLKID_AUDIO_GATE_FRDDRC                 11
+#define CLKID_AUDIO_GATE_TODDRA                 12
+#define CLKID_AUDIO_GATE_TODDRB                 13
+#define CLKID_AUDIO_GATE_TODDRC                 14
+#define CLKID_AUDIO_GATE_LOOPBACKA              15
+#define CLKID_AUDIO_GATE_SPDIFIN                16
+#define CLKID_AUDIO_GATE_SPDIFOUT_A             17
+#define CLKID_AUDIO_GATE_RESAMPLEA              18
+#define CLKID_AUDIO_GATE_RESERVED0              19
+#define CLKID_AUDIO_GATE_RESERVED1              20
+#define CLKID_AUDIO_GATE_SPDIFOUT_B             21
+#define CLKID_AUDIO_GATE_EQDRC                  22
+#define CLKID_AUDIO_GATE_RESAMPLEB              23
+#define CLKID_AUDIO_GATE_TOVAD                  24
+#define CLKID_AUDIO_GATE_AUDIOLOCKER            25
+#define CLKID_AUDIO_GATE_SPDIFIN_LB             26
+#define CLKID_AUDIO_GATE_FRATV                  27
+#define CLKID_AUDIO_GATE_FRHDMIRX               28
+#define CLKID_AUDIO_GATE_FRDDRD                 29
+#define CLKID_AUDIO_GATE_TODDRD                 30
+#define CLKID_AUDIO_GATE_LOOPBACKB              31
 
 #define MCLK_BASE                               32
 #define CLKID_AUDIO_MCLK_A                      (MCLK_BASE + 0)
 #define CLKID_AUDIO_MCLK_E                      (MCLK_BASE + 4)
 #define CLKID_AUDIO_MCLK_F                      (MCLK_BASE + 5)
 
-#define CLKID_AUDIO_SPDIFIN_CTRL                (MCLK_BASE + 6)
-#define CLKID_AUDIO_SPDIFOUT_CTRL               (MCLK_BASE + 7)
-#define CLKID_AUDIO_PDMIN0                      (MCLK_BASE + 8)
-#define CLKID_AUDIO_PDMIN1                      (MCLK_BASE + 9)
-#define CLKID_AUDIO_SPDIFOUTB_CTRL              (MCLK_BASE + 10)
-#define CLKID_AUDIO_LOCKER_OUT                  (MCLK_BASE + 11)
-#define CLKID_AUDIO_LOCKER_IN                   (MCLK_BASE + 12)
-#define CLKID_AUDIO_RESAMPLE_CTRL               (MCLK_BASE + 13)
+#define CLKID_AUDIO_SPDIFIN                     (MCLK_BASE + 6)
+#define CLKID_AUDIO_SPDIFOUT_A                  (MCLK_BASE + 7)
+#define CLKID_AUDIO_RESAMPLE_A                  (MCLK_BASE + 8)
+#define CLKID_AUDIO_LOCKER_OUT                  (MCLK_BASE + 9)
+#define CLKID_AUDIO_LOCKER_IN                   (MCLK_BASE + 10)
+#define CLKID_AUDIO_PDMIN0                      (MCLK_BASE + 11)
+#define CLKID_AUDIO_PDMIN1                      (MCLK_BASE + 12)
+#define CLKID_AUDIO_SPDIFOUT_B                  (MCLK_BASE + 13)
+#define CLKID_AUDIO_RESAMPLE_B                  (MCLK_BASE + 14)
+#define CLKID_AUDIO_SPDIFIN_LB                  (MCLK_BASE + 15)
+#define CLKID_AUDIO_EQDRC                       (MCLK_BASE + 16)
+#define CLKID_AUDIO_VAD                         (MCLK_BASE + 17)
 
-#define NUM_AUDIO_CLKS                          (MCLK_BASE + 14)
-#endif /* __G12A_AUDIO_CLK_H */
+#define NUM_AUDIO_CLKS                          (MCLK_BASE + 18)
+#endif /* __TL1_AUDIO_CLK_H__ */
index 2127da5..3fa257f 100644 (file)
@@ -490,4 +490,6 @@ extern int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara);
 extern void tvafe_set_ddemod_default(void);/* add for dtv demod*/
 extern void rx_get_audio_status(struct rx_audio_stat_s *aud_sts);
 
+extern void rx_set_atmos_flag(bool en);
+extern bool rx_get_atmos_flag(void);
 #endif
diff --git a/include/linux/amlogic/media/sound/misc.h b/include/linux/amlogic/media/sound/misc.h
new file mode 100644 (file)
index 0000000..7f3edbf
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * include/linux/amlogic/media/sound/misc.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __MISC_H__
+#define __MISC_H__
+
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/control.h>
+
+#ifdef CONFIG_AMLOGIC_ATV_DEMOD
+extern const struct soc_enum atv_audio_status_enum;
+
+int aml_get_atv_audio_stable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+#endif
+
+#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
+extern int update_spdifin_audio_type(int audio_type);
+
+extern const struct soc_enum hdmi_in_status_enum[];
+
+extern int get_hdmi_sample_rate_index(void);
+
+extern int aml_get_hdmiin_audio_stable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int aml_get_hdmiin_audio_samplerate(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int aml_get_hdmiin_audio_channels(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int aml_get_hdmiin_audio_format(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int aml_set_atmos_audio_edid(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int aml_get_atmos_audio_edid(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+#endif
+
+#endif
index 68a11eb..e9fec17 100644 (file)
@@ -18,7 +18,9 @@
 #ifndef __SPDIF_INFO_H__
 #define __SPDIF_INFO_H__
 
+#include <sound/soc.h>
 #include <sound/pcm.h>
+#include <sound/control.h>
 
 struct iec958_chsts {
        unsigned short chstat0_l;
@@ -34,4 +36,13 @@ extern void spdif_get_channel_status_info(struct iec958_chsts *chsts,
 
 extern void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream);
 
+extern const struct soc_enum spdif_format_enum;
+
+extern int spdif_format_get_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
+
+extern int spdif_format_set_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol);
 #endif
index 6ebfb62..f7fbe5e 100644 (file)
@@ -23,6 +23,8 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE)    += audio_controller.o \
                                                resample_hw.o \
                                                effects.o \
                                                effects_hw.o \
+                                               effects_v2.o \
+                                               effects_hw_v2.o \
                                                pwrdet.o \
                                                pwrdet_hw.o \
                                                sharebuffer.o \
index c625269..1b50eac 100644 (file)
@@ -103,7 +103,7 @@ static int register_audio_controller(struct platform_device *pdev,
        platform_set_drvdata(pdev, actrl);
 
        /* gate on all clks on bringup stage, need gate separately */
-       aml_audiobus_write(actrl, EE_AUDIO_CLK_GATE_EN0, 0xffffff);
+       aml_audiobus_write(actrl, EE_AUDIO_CLK_GATE_EN0, 0xffffffff);
 
        return 0;
 }
index 53e8fb9..cae3be9 100644 (file)
@@ -24,7 +24,9 @@
 #include "tdm_hw.h"
 #include "ddr_mngr.h"
 #include "resample.h"
+#include "effects_v2.h"
 
+#include <linux/amlogic/iomap.h>
 #include <linux/amlogic/media/sound/auge_utils.h>
 
 #include <linux/of_platform.h>
@@ -943,6 +945,12 @@ int snd_card_add_kcontrols(struct snd_soc_card *card)
                return ret;
        }
 
+       ret = card_add_effect_v2_kcontrols(card);
+       if (ret < 0) {
+               pr_err("Failed to add AED v2 controls\n");
+               return ret;
+       }
+
        return snd_soc_add_card_controls(card,
                snd_auge_controls, ARRAY_SIZE(snd_auge_controls));
 
@@ -1505,3 +1513,10 @@ void fratv_src_select(int src)
 {
        audiobus_update_bits(EE_AUDIO_FRATV_CTRL0, 0x1 << 20, (bool)src << 20);
 }
+
+void cec_arc_enable(int src, bool enable)
+{
+       aml_hiubus_update_bits(HHI_HDMIRX_ARC_CNTL,
+               0x1f << 0,
+               src << 2 | enable << 1 | 0x0 << 0);
+}
index c08470f..d044447 100644 (file)
@@ -162,4 +162,6 @@ extern int audio_locker_get(void);
 
 extern void fratv_enable(bool enable);
 extern void fratv_src_select(int src);
+
+extern void cec_arc_enable(int src, bool enable);
 #endif
index 3a3d370..c4d4582 100644 (file)
@@ -976,12 +976,11 @@ static int aml_card_probe(struct platform_device *pdev)
        }
 
        if (priv->chipinfo && priv->chipinfo->eqdrc_fn) {
-               pr_info("eq/drc function enable\n");
+               pr_info("eq/drc v1 function enable\n");
                ret = card_add_effects_init(&priv->snd_card);
                if (ret < 0)
-                       pr_warn_once("Failed to add audio effects controls\n");
-       } else
-               pr_info("not support eq/drc function\n");
+                       pr_warn_once("Failed to add audio effects v1 controls\n");
+       }
 
        if (priv->hp_det_enable == 1 || priv->mic_det_enable == 1) {
                audio_jack_detect(priv);
index 6d3199f..d350436 100644 (file)
 #include "ddr_mngr.h"
 #include "audio_utils.h"
 
+#include "resample.h"
 #include "resample_hw.h"
 #include "effects_hw.h"
+#include "effects_hw_v2.h"
+#include "effects_v2.h"
 #include "pwrdet_hw.h"
 
 #define DRV_NAME "audio-ddr-manager"
@@ -64,6 +67,10 @@ struct ddr_chipinfo {
        bool same_src_fn;
        /* insert channel number */
        bool insert_chnum;
+
+       /* ddr bus in urgent */
+       bool ugt;
+
        /* source sel switch to ctrl1
         * for toddr, 0: source sel is controlled by ctrl0
         *            1: source sel is controlled by ctrl1
@@ -71,6 +78,16 @@ struct ddr_chipinfo {
         *            1: source sel is controlled by ctrl2
         */
        bool src_sel_ctrl;
+
+       /*
+        * resample source sel switch
+        * resample : from ctrl0 to ctrl3
+        * toddr : from ctrl0 to ctrl1
+        */
+       bool asrc_src_sel_ctrl;
+       /* spdif in 32bit, only support left justified */
+       bool asrc_only_left_j;
+
        /* toddr number max
         * 0: default, 3 toddr, axg, g12a, g12b
         * 4: 4 toddr, tl1
@@ -92,6 +109,8 @@ struct toddr {
        enum toddr_src src;
        unsigned int fifo_id;
 
+       unsigned int asrc_src_sel;
+
        int is_lb; /* check whether for loopback */
        int irq;
        bool in_use: 1;
@@ -107,6 +126,7 @@ enum status {
 
 struct toddr_attach {
        bool enable;
+       int id;
        int status;
        /* which module should be attached,
         * check which toddr in use should be attached
@@ -130,6 +150,10 @@ struct frddr {
        struct aml_audio_controller *actrl;
        unsigned int reg_base;
        unsigned int fifo_id;
+
+       unsigned int msb;
+       unsigned int type;
+
        int irq;
        bool in_use;
        struct ddr_chipinfo *chipinfo;
@@ -140,9 +164,9 @@ static struct frddr frddrs[DDRMAX];
 static struct toddr toddrs[DDRMAX];
 
 /* resample */
-static struct toddr_attach attach_resample;
-static void aml_check_resample(bool enable);
-static bool aml_check_resample_module(int src);
+static struct toddr_attach attach_resample_a;
+static struct toddr_attach attach_resample_b;
+static void aml_check_resample(struct toddr *to, bool enable);
 
 /* power detect */
 static struct toddr_attach attach_pwrdet;
@@ -357,8 +381,7 @@ void aml_toddr_enable(struct toddr *to, bool enable)
        aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31);
 
        /* check resample */
-       if (aml_check_resample_module(to->src))
-               aml_check_resample(enable);
+       aml_check_resample(to, enable);
 
        /* check power detect */
        if (aml_check_pwrdet_module(to->src))
@@ -381,7 +404,7 @@ void aml_toddr_select_src(struct toddr *to, enum toddr_src src)
        if (loopback_check_enable(src)) {
                loopback_set_status(1);
                to->is_lb = 1; /* in loopback */
-               src = LOOPBACK;
+               src = LOOPBACK_A;
        }
 
        if (to->chipinfo
@@ -414,6 +437,11 @@ void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh)
        }
 
        aml_audiobus_update_bits(actrl, reg, mask, val);
+
+       if (to->chipinfo && to->chipinfo->ugt) {
+               reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base);
+               aml_audiobus_update_bits(actrl, reg, 0x0 << 0, 0x1 << 0);
+       }
 }
 
 void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt)
@@ -477,13 +505,60 @@ void aml_toddr_set_resample(struct toddr *to, bool enable)
        aml_audiobus_update_bits(actrl, reg, 1<<30, enable<<30);
 }
 
-static void aml_set_resample(struct toddr *to,
+void aml_toddr_set_resample_ab(struct toddr *to, int asrc_src_sel, bool enable)
+{
+       struct aml_audio_controller *actrl = to->actrl;
+       unsigned int reg_base = to->reg_base;
+       unsigned int reg;
+
+       pr_info("toddr selects data to %s resample %c\n",
+               enable ? "enable" : "disable",
+               (asrc_src_sel == 0) ? 'a' : 'b');
+       reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base);
+       if (asrc_src_sel == 0)
+               aml_audiobus_update_bits(actrl, reg, 1 << 27, enable << 27);
+       else
+               aml_audiobus_update_bits(actrl, reg, 1 << 26, enable << 26);
+}
+
+static void aml_resample_enable(
+       struct toddr_attach *p_attach_resample,
        bool enable)
 {
+       struct toddr *to = fetch_toddr_by_src(p_attach_resample->attach_module);
+
+       if (!to)
+               return;
+
+       if (to->chipinfo
+                       && to->chipinfo->asrc_src_sel_ctrl) {
+               /* fix asrc_src_sel */
+               switch (p_attach_resample->attach_module) {
+               case LOOPBACK_A:
+                       to->asrc_src_sel = ASRC_LOOPBACK_A;
+                       break;
+               case LOOPBACK_B:
+                       to->asrc_src_sel = ASRC_LOOPBACK_B;
+                       break;
+               default:
+                       to->asrc_src_sel = to->fifo_id;
+                       break;
+               }
+       }
+
+       pr_info("Resample %d in running, module:%d, toddr:%d, asrc_src_sel:%d\n",
+               p_attach_resample->id,
+               p_attach_resample->attach_module,
+               to->fifo_id,
+               to->asrc_src_sel);
+
        if (enable) {
                int bitwidth = to->bitdepth;
                /* channels and bit depth for resample */
-               if ((to->src == SPDIFIN) && (bitwidth == 32)) {
+               if (to->chipinfo
+                       && to->chipinfo->asrc_only_left_j
+                       && (to->src == SPDIFIN)
+                       && (bitwidth == 32)) {
                        struct aml_audio_controller *actrl = to->actrl;
                        unsigned int reg_base = to->reg_base;
                        unsigned int reg;
@@ -502,85 +577,103 @@ static void aml_set_resample(struct toddr *to,
                                0x7 << 24 | 0x7 << 13,
                                endian << 24 | toddr_type << 13);
                }
-               resample_format_set(to->channels, bitwidth);
+
+               resample_format_set(p_attach_resample->id,
+                       to->channels, bitwidth);
 
                /* toddr index for resample */
-               resample_src_select(to->fifo_id);
+               if (to->chipinfo
+                       && to->chipinfo->asrc_src_sel_ctrl)
+                       resample_src_select_ab(p_attach_resample->id,
+                               to->asrc_src_sel);
+               else
+                       resample_src_select(to->fifo_id);
        }
 
        /* resample enable or not */
-       resample_enable(enable);
+       resample_enable(p_attach_resample->id, enable);
+
        /* select reample data */
-       aml_toddr_set_resample(to, enable);
+       if (to->chipinfo
+                       && to->chipinfo->asrc_src_sel_ctrl)
+               aml_toddr_set_resample_ab(to, p_attach_resample->id, enable);
+       else
+               aml_toddr_set_resample(to, enable);
 }
 
-void aml_resample_enable(bool enable, int resample_module)
+void aml_set_resample(int id, bool enable, int resample_module)
 {
-       attach_resample.enable = enable;
-       attach_resample.attach_module = resample_module;
+       struct toddr_attach *p_attach_resample;
 
-       aml_check_resample(enable);
-}
+       bool update_running = false;
 
-static bool aml_check_resample_module(int src)
-{
-       bool is_module_resample = false;
+       if (id == 0)
+               p_attach_resample = &attach_resample_a;
+       else
+               p_attach_resample = &attach_resample_b;
 
-       if (attach_resample.enable
-               && (src == attach_resample.attach_module))
-               is_module_resample = true;
+       p_attach_resample->enable        = enable;
+       p_attach_resample->id            = id;
+       p_attach_resample->attach_module = resample_module;
+
+       if (enable) {
+               if ((p_attach_resample->status == DISABLED)
+                       || (p_attach_resample->status == READY)) {
+                       struct toddr *to = fetch_toddr_by_src(
+                               p_attach_resample->attach_module);
 
-       return is_module_resample;
+                       if (!to) {
+                               p_attach_resample->status = READY;
+                       } else {
+                               p_attach_resample->status = RUNNING;
+                               update_running = true;
+                               pr_info("Capture with resample\n");
+                       }
+               }
+       } else {
+               if (p_attach_resample->status == RUNNING)
+                       update_running = true;
+
+               p_attach_resample->status = DISABLED;
+       }
+
+       if (update_running)
+               aml_resample_enable(p_attach_resample, enable);
 }
 
 /*
  * when try to enable resample, if toddr is not in used,
  * set resample status as ready
  */
-static void aml_check_resample(bool enable)
+static void aml_check_resample(struct toddr *to, bool enable)
 {
-       /* resample in enable */
-       if (attach_resample.enable) {
-               if (enable) {
-                       /* check whether ready ? */
-                       if ((attach_resample.status == DISABLED)
-                               || (attach_resample.status == READY)) {
-                               struct toddr *to = fetch_toddr_by_src(
-                                       attach_resample.attach_module);
-
-                               if (!to) {
-                                       attach_resample.status = READY;
-                                       pr_info("not in capture, Resample is ready\n");
-                               } else {
-                                       attach_resample.status = RUNNING;
-                                       aml_set_resample(to, enable);
-                                       pr_info("Resample in running, module:%d, toddr:%d\n",
-                                               attach_resample.attach_module,
-                                               to->fifo_id);
-                               }
-                       }
-               } else {
-                       if (attach_resample.status == RUNNING) {
-                               struct toddr *to = fetch_toddr_by_src(
-                                       attach_resample.attach_module);
+       struct toddr_attach *p_attach_resample;
+       bool is_module_resample;
+       bool resample_b_check = false;
 
-                               aml_set_resample(to, enable);
-                               attach_resample.status = DISABLED;
-                       }
-               }
-       } else {
-               /* ensure resample is disabled */
-               struct toddr *to = fetch_toddr_by_src(
-                       attach_resample.attach_module);
+       p_attach_resample = &attach_resample_a;
 
-               if (to) {
-                       pr_info("Resample in running, disable it\n");
+start_check:
+       is_module_resample = false;
+       if (p_attach_resample->enable
+               && (to->src == p_attach_resample->attach_module))
+               is_module_resample = true;
 
-                       /* select reample data */
-                       aml_toddr_set_resample(to, false);
-                       /* update resample status */
-                       attach_resample.status = DISABLED;
-               }
+       /* resample in enable */
+       if (is_module_resample) {
+               if (enable)
+                       p_attach_resample->status = RUNNING;
+               else
+                       p_attach_resample->status = DISABLED;
+
+               aml_resample_enable(p_attach_resample, enable);
+       }
+
+       if ((!resample_b_check)
+               && (get_resample_module_num() == 2)) {
+               p_attach_resample = &attach_resample_b;
+               resample_b_check = true;
+               goto start_check;
        }
 }
 
@@ -967,6 +1060,11 @@ void aml_frddr_set_fifos(struct frddr *fr,
        aml_audiobus_update_bits(actrl, reg,
                        0xffff<<16 | 0xf<<8,
                        (depth - 1)<<24 | (thresh - 1)<<16 | 2<<8);
+
+       if (fr->chipinfo && fr->chipinfo->ugt) {
+               reg = calc_toddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base);
+               aml_audiobus_update_bits(actrl, reg, 0x0 << 0, 0x1 << 0);
+       }
 }
 
 unsigned int aml_frddr_get_fifo_id(struct frddr *fr)
@@ -974,23 +1072,54 @@ unsigned int aml_frddr_get_fifo_id(struct frddr *fr)
        return fr->fifo_id;
 }
 
-static void aml_set_aed(struct frddr *fr, bool enable)
+void aml_frddr_set_format(struct frddr *fr,
+       unsigned int msb, unsigned int frddr_type)
 {
-       if (enable) {
-               /* frddr type and bit depth for AED */
-               aml_aed_format_set(fr->dest);
-       }
-       aed_src_select(enable, fr->dest, fr->fifo_id);
+       fr->msb  = msb;
+       fr->type = frddr_type;
 }
 
 
-void aml_aed_enable(bool enable, int aed_module)
+static void aml_aed_enable(struct frddr_attach *p_attach_aed, bool enable)
+{
+       struct frddr *fr = fetch_frddr_by_src(p_attach_aed->attach_module);
+
+
+       if (check_aed_v2()) {
+               if (fr->chipinfo
+                       && fr->chipinfo->src_sel_ctrl) {
+                       struct aml_audio_controller *actrl = fr->actrl;
+                       unsigned int reg_base = fr->reg_base;
+                       unsigned int reg;
+
+                       reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2,
+                               reg_base);
+                       aml_audiobus_update_bits(actrl,
+                               reg, 0x1 << 3, enable << 3);
+               }
+
+               aed_set_ctrl(enable, 0, p_attach_aed->attach_module);
+               aed_set_format(fr->msb, fr->type);
+               aed_enable(enable, fr->dest, fr->fifo_id);
+       } else {
+               if (enable) {
+                       /* frddr type and bit depth for AED */
+                       aml_aed_format_set(fr->dest);
+               }
+               aed_src_select(enable, fr->dest, fr->fifo_id);
+       }
+}
+
+void aml_set_aed(bool enable, int aed_module)
 {
+       bool update_running = false;
+
        /* when try to enable AED, if frddr is not in used,
         * set AED status as ready
         */
        attach_aed.enable = enable;
        attach_aed.attach_module = aed_module;
+
        if (enable) {
                if ((attach_aed.status == DISABLED)
                        || (attach_aed.status == READY)) {
@@ -998,20 +1127,21 @@ void aml_aed_enable(bool enable, int aed_module)
 
                        if (!fr) {
                                attach_aed.status = READY;
-                               pr_info("not in playback, AED is ready");
                        } else {
                                attach_aed.status = RUNNING;
-                               aml_set_aed(fr, enable);
+                               update_running = true;
+                               pr_info("Playback with AED\n");
                        }
                }
        } else {
-               if (attach_aed.status == RUNNING) {
-                       struct frddr *fr = fetch_frddr_by_src(aed_module);
+               if (attach_aed.status == RUNNING)
+                       update_running = true;
 
-                       aml_set_aed(fr, enable);
-               }
                attach_aed.status = DISABLED;
        }
+
+       if (update_running)
+               aml_aed_enable(&attach_aed, enable);
 }
 
 static bool aml_check_aed_module(int dst)
@@ -1033,14 +1163,12 @@ static void aml_check_aed(bool enable, int dst)
 
        /* AED in enable */
        if (attach_aed.enable) {
-               if (enable) {
-                       /* check whether ready ? */
-                       if (attach_aed.status == READY)
-                               aml_aed_enable(true, attach_aed.attach_module);
-               } else {
-                       if (attach_aed.status == RUNNING)
-                               attach_aed.status = READY;
-               }
+               if (enable)
+                       attach_aed.status = RUNNING;
+               else
+                       attach_aed.status = DISABLED;
+
+               aml_aed_enable(&attach_aed, enable);
        }
 }
 
@@ -1142,7 +1270,7 @@ static int toddr_src_enum_set(struct snd_kcontrol *kcontrol,
 static int frddr_src_idx = -1;
 
 static const char *const frddr_src_sel_texts[] = {
-       "TDMOUT_A", "TDMOUT_B", "TDMOUT_C", "SPDIFOUT", "SPDIFOUT_B"
+       "TDMOUT_A", "TDMOUT_B", "TDMOUT_C", "SPDIFOUT_A", "SPDIFOUT_B"
 };
 
 static const struct soc_enum frddr_output_source_enum =
@@ -1207,15 +1335,19 @@ int card_add_ddr_kcontrols(struct snd_soc_card *card)
 
 static struct ddr_chipinfo axg_ddr_chipinfo = {
        .int_start_same_addr   = true,
+       .asrc_only_left_j      = true,
 };
 
 static struct ddr_chipinfo g12a_ddr_chipinfo = {
        .same_src_fn           = true,
+       .asrc_only_left_j      = true,
 };
 
 static struct ddr_chipinfo tl1_ddr_chipinfo = {
        .same_src_fn           = true,
+       .ugt                   = true,
        .src_sel_ctrl          = true,
+       .asrc_src_sel_ctrl     = true,
        .fifo_num              = 4,
 };
 
index 461ee9f..30ed31c 100644 (file)
@@ -49,18 +49,27 @@ enum toddr_src {
        PDMIN,
        FRATV, /* NONE for axg, g12a, g12b */
        TDMIN_LB,
-       LOOPBACK,
+       LOOPBACK_A,
        FRHDMIRX, /* from tl1 chipset*/
        LOOPBACK_B,
        SPDIFIN_LB,
        VAD,
 };
 
+enum resample_src {
+       ASRC_TODDR_A,
+       ASRC_TODDR_B,
+       ASRC_TODDR_C,
+       ASRC_TODDR_D,      /* from tl1 chipset */
+       ASRC_LOOPBACK_A,
+       ASRC_LOOPBACK_B,
+};
+
 enum frddr_dest {
        TDMOUT_A,
        TDMOUT_B,
        TDMOUT_C,
-       SPDIFOUT,
+       SPDIFOUT_A,
        SPDIFOUT_B,
 };
 
@@ -94,7 +103,7 @@ unsigned int aml_toddr_read(struct toddr *to);
 void aml_toddr_write(struct toddr *to, unsigned int val);
 
 /* resample */
-void aml_resample_enable(bool enable, int resample_module);
+void aml_set_resample(int id, bool enable, int resample_module);
 /* power detect */
 void aml_pwrdet_enable(bool enable, int pwrdet_module);
 
@@ -120,8 +129,10 @@ int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel);
 void aml_frddr_set_fifos(struct frddr *fr,
                unsigned int depth, unsigned int thresh);
 unsigned int aml_frddr_get_fifo_id(struct frddr *fr);
+void aml_frddr_set_format(struct frddr *fr,
+       unsigned int msb, unsigned int frddr_type);
 /* audio eq drc */
-void aml_aed_enable(bool enable, int aed_module);
+void aml_set_aed(bool enable, int aed_module);
 
 void frddr_init_without_mngr(unsigned int frddr_index, unsigned int src0_sel);
 void frddr_deinit_without_mngr(unsigned int frddr_index);
index 5ce778d..dc37444 100644 (file)
@@ -65,7 +65,7 @@ static const char *const aed_req_module_texts[] = {
        "TDMOUT_A",
        "TDMOUT_B",
        "TDMOUT_C",
-       "SPDIFOUT",
+       "SPDIFOUT_A",
        "SPDIFOUT_B",
 };
 
@@ -145,7 +145,7 @@ static int mixer_set_EQ(struct snd_kcontrol *kcontrol,
        aed_set_eq(value, aml_EQ_param_length, &aml_EQ_param[0]);
 
        eqdrc_module = aed_get_req_sel(0);
-       aml_aed_enable(value, eqdrc_module);
+       aml_set_aed(value, eqdrc_module);
 
        return 0;
 }
@@ -160,7 +160,7 @@ static int mixer_set_DRC_params(struct snd_kcontrol *kcontrol,
                aml_DRC_param_length, &aml_drc_tko_table[0]);
 
        eqdrc_module = aed_get_req_sel(0);
-       aml_aed_enable(value, eqdrc_module);
+       aml_set_aed(value, eqdrc_module);
 
        return 0;
 }
@@ -198,15 +198,15 @@ static const struct snd_kcontrol_new snd_eqdrc_controls[] = {
                         mixer_eqdrc_read, mixer_eqdrc_write),
 
        SOC_SINGLE_EXT("EQ/DRC Channel Mask",
-                        AED_TOP_CTL, 18, 0xff, 0,
+                        AED_TOP_CTL_G12X, 18, 0xff, 0,
                         mixer_eqdrc_read, mixer_eqdrc_write),
 
        SOC_SINGLE_EXT("EQ/DRC Lane Mask",
-                        AED_TOP_CTL, 14, 0xf, 0,
+                        AED_TOP_CTL_G12X, 14, 0xf, 0,
                         mixer_eqdrc_read, mixer_eqdrc_write),
 
        SOC_SINGLE_EXT("EQ/DRC Req Module",
-                        AED_TOP_REQ_CTL, 0, 0x7, 0,
+                        AED_TOP_REQ_CTL_G12X, 0, 0x7, 0,
                         mixer_eqdrc_read, mixer_set_AED_req_ctrl),
 
        SOC_SINGLE_EXT("EQ enable",
@@ -243,8 +243,7 @@ int card_add_effects_init(struct snd_soc_card *card)
        audio_effect_np = of_parse_phandle(card->dev->of_node,
                "aml-audio-card,effect", 0);
        if (audio_effect_np == NULL) {
-               pr_err("error: failed to find node %s for eq/drc info!\n",
-                               "audio_effect");
+               pr_warn("no node %s for eq/drc info!\n", "audio_effect");
                return -EINVAL;
        }
 
index a2d2677..a54b893 100644 (file)
@@ -82,13 +82,13 @@ void aed_req_sel(bool enable, int sel, int req_module)
                return;
        }
 
-       eqdrc_update_bits(AED_TOP_REQ_CTL, mask_offset, val_offset);
+       eqdrc_update_bits(AED_TOP_REQ_CTL_G12X, mask_offset, val_offset);
 }
 
 /* get eq/drc module */
 int aed_get_req_sel(int sel)
 {
-       int val = eqdrc_read(AED_TOP_REQ_CTL);
+       int val = eqdrc_read(AED_TOP_REQ_CTL_G12X);
        int mask_off;
 
        switch (sel) {
@@ -170,7 +170,7 @@ int aml_aed_format_set(int frddr_dst)
                return -EINVAL;
        }
 
-       eqdrc_update_bits(AED_TOP_CTL, 0x7 << 11 | 0x1f << 6,
+       eqdrc_update_bits(AED_TOP_CTL_G12X, 0x7 << 11 | 0x1f << 6,
                frddr_type << 11 | width << 6);
 
        return 0;
@@ -192,17 +192,17 @@ void aed_src_select(bool enable, int frddr_dst, int fifo_id)
        aed_req_sel(enable, 0, frddr_dst);
 
        /* AED module, sel & enable */
-       eqdrc_update_bits(AED_TOP_CTL,
+       eqdrc_update_bits(AED_TOP_CTL_G12X,
                0x3 << 4 | 0x1 << 0,
                fifo_id << 4 | enable << 0);
 }
 
 void aed_set_lane(int lane_mask)
 {
-       eqdrc_update_bits(AED_TOP_CTL, 0xf << 14, lane_mask << 14);
+       eqdrc_update_bits(AED_TOP_CTL_G12X, 0xf << 14, lane_mask << 14);
 }
 
 void aed_set_channel(int channel_mask)
 {
-       eqdrc_update_bits(AED_TOP_CTL, 0xff << 18, channel_mask << 18);
+       eqdrc_update_bits(AED_TOP_CTL_G12X, 0xff << 18, channel_mask << 18);
 }
diff --git a/sound/soc/amlogic/auge/effects_hw_v2.c b/sound/soc/amlogic/auge/effects_hw_v2.c
new file mode 100644 (file)
index 0000000..6c1e1a6
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * sound/soc/amlogic/auge/effect_hw_v2.c
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/kernel.h>
+
+#include "effects_hw_v2.h"
+#include "regs.h"
+#include "iomap.h"
+
+#include "tdm_hw.h"
+#include "spdif_hw.h"
+
+void aed_set_ram_coeff(int len, int *params)
+{
+       int i, ctrl_v;
+
+       for (i = 0; i < len; i++) {
+               ctrl_v = (i << 2) | (0x1 << 1) | (0x1 << 0);
+               eqdrc_write(AED_COEF_RAM_DATA, params[i]);
+               eqdrc_write(AED_COEF_RAM_CNTL, ctrl_v);
+       }
+}
+
+void aed_set_multiband_drc_coeff(int len, int *params)
+{
+       int band_len = len / 3, i, j;
+       int offset = AED_MDRC_RMS_COEF10 - AED_MDRC_RMS_COEF00;
+       int reg = AED_MDRC_RMS_COEF00;
+
+       for (i = 0; i < 3; i++)
+               for (j = 0; j < band_len; j++)
+                       eqdrc_write(reg + i * offset + j,
+                               params[i * band_len + j]);
+
+       eqdrc_write(AED_MDRC_THD0, 0xf6000000);
+       eqdrc_write(AED_MDRC_K0, 0x20000);
+       eqdrc_write(AED_MDRC_OFFSET0, 0x200);
+       eqdrc_write(AED_MDRC_LOW_GAIN, 0x40000);
+
+       eqdrc_write(AED_MDRC_THD1, 0xfb000000);
+       eqdrc_write(AED_MDRC_K1, 0x26666);
+       eqdrc_write(AED_MDRC_OFFSET1, 0x200);
+       eqdrc_write(AED_MDRC_MID_GAIN, 0x40000);
+
+       eqdrc_write(AED_MDRC_THD2, 0xf1000000);
+       eqdrc_write(AED_MDRC_K2, 0x2cccc);
+       eqdrc_write(AED_MDRC_OFFSET2, 0x200);
+       eqdrc_write(AED_MDRC_HIGH_GAIN, 0x40000);
+}
+
+void aed_set_fullband_drc_coeff(int len, int *params)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               eqdrc_write(AED_DRC_RELEASE_COEF00 + i,
+                       params[i]);
+
+       eqdrc_write(AED_DRC_RMS_COEF0, 0x34ebb);
+       eqdrc_write(AED_DRC_RMS_COEF1, 0x7cb145);
+       eqdrc_write(AED_DRC_THD0, 0xf7000000);
+       eqdrc_write(AED_DRC_THD1, 0xf6000000);
+       eqdrc_write(AED_DRC_THD2, 0xec000000);
+       eqdrc_write(AED_DRC_THD3, 0xe2000000);
+       eqdrc_write(AED_DRC_THD4, 0xce000000);
+       eqdrc_write(AED_DRC_K0, 0x20000);
+       eqdrc_write(AED_DRC_K1, 0x46666);
+       eqdrc_write(AED_DRC_K2, 0x40000);
+       eqdrc_write(AED_DRC_K3, 0x39999);
+       eqdrc_write(AED_DRC_K4, 0x33333);
+       eqdrc_write(AED_DRC_K5, 0x4cccc);
+       eqdrc_write(AED_DRC_THD_OUT0, 0xf5e66667);
+       eqdrc_write(AED_DRC_THD_OUT1, 0xebe66667);
+       eqdrc_write(AED_DRC_THD_OUT2, 0xe2e66667);
+       eqdrc_write(AED_DRC_THD_OUT3, 0xd2e66667);
+       eqdrc_write(AED_DRC_OFFSET, 0x100);
+       eqdrc_write(AED_DRC_LOOPBACK_CNTL, (144 << 0));
+}
+
+static void aed_set_mixer_params(void)
+{
+       eqdrc_write(AED_MIX0_LL, 0x40000);
+       eqdrc_write(AED_MIX0_RL, 0x0);
+       eqdrc_write(AED_MIX0_LR, 0x0);
+       eqdrc_write(AED_MIX0_RR, 0x40000);
+       eqdrc_write(AED_CLIP_THD, 0x7fffff);
+}
+
+void aed_dc_enable(bool enable)
+{
+       eqdrc_write(AED_DC_EN, enable << 0);
+}
+
+void aed_nd_enable(bool enable)
+{
+       if (enable) {
+               eqdrc_write(AED_ND_LOW_THD, 0x100);
+               eqdrc_write(AED_ND_HIGH_THD, 0x200);
+               eqdrc_write(AED_ND_CNT_THD, 0x100);
+               eqdrc_write(AED_ND_SUM_NUM, 0x200);
+               eqdrc_write(AED_ND_CZ_NUM, 0x800);
+               eqdrc_write(AED_ND_SUM_THD0, 0x20000);
+               eqdrc_write(AED_ND_SUM_THD1, 0x30000);
+               eqdrc_write(AED_ND_CZ_THD0, 0x200);
+               eqdrc_write(AED_ND_CZ_THD1, 0x100);
+               eqdrc_write(AED_ND_COND_CNTL, 0x3f);
+               eqdrc_write(AED_ND_RELEASE_COEF0, 0x3263a);
+               eqdrc_write(AED_ND_RELEASE_COEF1, 0x7cd9c6);
+               eqdrc_write(AED_ND_ATTACK_COEF0, 0x5188);
+               eqdrc_write(AED_ND_ATTACK_COEF1, 0x7fae78);
+       }
+
+       eqdrc_write(AED_ND_CNTL, (enable << 0)|(3 << 1));
+}
+
+void aed_eq_enable(int idx, bool enable)
+{
+       eqdrc_update_bits(AED_EQ_EN, 0x1 << idx, enable << idx);
+       eqdrc_update_bits(AED_EQ_TAP_CNTL, 0x1f << (5 * idx), 10 << (5 * idx));
+}
+
+void aed_multiband_drc_enable(bool enable)
+{
+       eqdrc_write(AED_MDRC_CNTL,
+               (1 << 16)     |  /* mdrc_pow_sel */
+               (enable << 8) |  /* mdrc_all_en */
+               (7 << 3)      |  /* mdrc_rms_mode[2:0] */
+               (7 << 0)         /* mdrc_en[2:0] */
+       );
+}
+
+void aed_fullband_drc_enable(bool enable)
+{
+       eqdrc_write(AED_DRC_CNTL,
+               (5 << 3) |  /* drc_tap */
+               (enable << 0)   /* drc_en */
+       );
+}
+
+void aed_set_EQ_volume(
+       unsigned int master_vol,
+       unsigned int Lch_vol,
+       unsigned int Rch_vol)
+{
+       eqdrc_write(AED_EQ_VOLUME,
+               (0 << 30) |          /* volume step: 0.125dB */
+               (master_vol << 16) | /* master volume: 0dB */
+               (Rch_vol << 8) |     /* channel 2 volume: 0dB */
+               (Lch_vol << 0)       /* channel 1 volume: 0dB */
+       );
+       eqdrc_write(AED_EQ_VOLUME_SLEW_CNT, 0x40);
+       eqdrc_write(AED_MUTE, 0);
+}
+
+void aed_set_lane_and_channels(int lane_mask, int ch_mask)
+{
+       eqdrc_update_bits(AED_TOP_CTL,
+               0xff << 18 | 0xf << 14,
+               ch_mask << 18 | lane_mask << 14);
+}
+
+void aed_set_ctrl(bool enable, int sel, int module)
+{
+       int mask = 0, val = 0;
+
+       switch (sel) {
+       case 0: /* REQ_SEL0 */
+               mask = 0xf << 0;
+               val = 0x1 << 3 | module << 0;
+               break;
+       case 1: /* REQ_SEL1 */
+               mask = 0xf << 4;
+               val = 0x1 << 7 | module << 4;
+               break;
+       case 2: /* REQ_SEL2 */
+               mask = 0xf << 8;
+               val = 0x1 << 11 | module << 8;
+               break;
+       default:
+               pr_err("unknown AED req_sel:%d, module:%d\n",
+                       sel, module);
+               return;
+       }
+       eqdrc_update_bits(AED_TOP_REQ_CTL, mask, val);
+
+       /* Effect Module */
+       if (module >= 3) {
+               /* SPDIFOUT A/B */
+               aml_spdifout_select_aed(enable, module - 3);
+       } else if (module < 3 && module >= 0) {
+               /* TDMOUT A/B/C */
+               aml_tdmout_select_aed(enable, module);
+       } else
+               pr_err("unknown module:%d for AED\n", module);
+
+}
+
+void aed_set_format(int msb, int frddr_type)
+{
+       eqdrc_update_bits(AED_TOP_CTL,
+               0x7 << 11 | 0x1f << 6,
+               frddr_type << 11 | msb << 6);
+}
+
+void aed_enable(bool enable, int frddr_dst, int fifo_id)
+{
+       if (enable) {
+               eqdrc_write(AED_ED_CNTL, 0x1);
+               eqdrc_write(AED_ED_CNTL, 0x0);
+
+               eqdrc_update_bits(AED_TOP_CTL, 0x1 << 1, 0x1 << 1);
+               eqdrc_update_bits(AED_TOP_CTL, 0x1 << 2, 0x1 << 2);
+
+               aed_set_mixer_params();
+       } else
+               eqdrc_update_bits(AED_TOP_CTL, 0x3 << 1, 0x0 << 1);
+
+       eqdrc_update_bits(AED_TOP_CTL, 0x1 << 0, enable << 0);
+
+       /* start en */
+       if (enable)
+               eqdrc_update_bits(AED_TOP_CTL, 0x1 << 31, 0x1 << 31);
+}
diff --git a/sound/soc/amlogic/auge/effects_hw_v2.h b/sound/soc/amlogic/auge/effects_hw_v2.h
new file mode 100644 (file)
index 0000000..7c13e7f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * sound/soc/amlogic/auge/effects_hw_v2.h
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef __EFFECTS_HW_V2_H__
+#define __EFFECTS_HW_V2_H__
+#include <linux/types.h>
+
+void aed_set_ram_coeff(int len, int *params);
+void aed_set_multiband_drc_coeff(int len, int *params);
+void aed_set_fullband_drc_coeff(int len, int *params);
+void aed_dc_enable(bool enable);
+void aed_nd_enable(bool enable);
+void aed_eq_enable(int idx, bool enable);
+void aed_multiband_drc_enable(bool enable);
+void aed_fullband_drc_enable(bool enable);
+void aed_set_EQ_volume(
+               unsigned int master_volume,
+               unsigned int Lch_vol,
+               unsigned int Rch_vol);
+void aed_set_lane_and_channels(int lane_mask, int ch_mask);
+void aed_set_ctrl(bool enable, int sel, int module);
+void aed_set_format(int msb, int frddr_type);
+void aed_enable(bool enable, int frddr_dst, int fifo_id);
+#endif
diff --git a/sound/soc/amlogic/auge/effects_hw_v2_coeff.c b/sound/soc/amlogic/auge/effects_hw_v2_coeff.c
new file mode 100644 (file)
index 0000000..903883f
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * sound/soc/amlogic/auge/effects_hw_v2_coeff.c
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#define AED_EQ_LENGTH            225
+#define AED_MULTIBAND_DRC_LENGTH 18
+#define AED_FULLBAND_DRC_LENGTH  24
+
+static int eq_coeff[] = {
+       /* 0   */ 0x7fd51b,
+       /* 1   */ 0x30055c9,
+       /* 2   */ 0x7fd51b,
+       /* 3   */ 0x30055e6,
+       /* 4   */ 0x7faa53,
+       /* 5   */ 0x7ed219,
+       /* 6   */ 0x3025bce,
+       /* 7   */ 0x7ed219,
+       /* 8   */ 0x3025e96,
+       /* 9   */ 0x7da6fb,
+       /* 10  */ 0x7ed219,
+       /* 11  */ 0x3025bce,
+       /* 12  */ 0x7ed219,
+       /* 13  */ 0x3025e96,
+       /* 14  */ 0x7da6fb,
+       /* 15  */ 0xdf71e0,
+       /* 16  */ 0x2411c40,
+       /* 17  */ 0xdf71e0,
+       /* 18  */ 0x304bd12,
+       /* 19  */ 0x7b58fb,
+       /* 20  */ 0x7d8252,
+       /* 21  */ 0x30bb7df,
+       /* 22  */ 0x771ba1,
+       /* 23  */ 0x30bb7df,
+       /* 24  */ 0x749df4,
+       /* 25  */ 0x79f87b,
+       /* 26  */ 0x31971e4,
+       /* 27  */ 0x6ddabe,
+       /* 28  */ 0x31971e4,
+       /* 29  */ 0x67d339,
+       /* 30  */ 0x84f8f3,
+       /* 31  */ 0x31d2c91,
+       /* 32  */ 0x62ebbf,
+       /* 33  */ 0x31d2c91,
+       /* 34  */ 0x67e4b1,
+       /* 35  */ 0x711f0e,
+       /* 36  */ 0x3543f10,
+       /* 37  */ 0x4ae2f0,
+       /* 38  */ 0x3543f10,
+       /* 39  */ 0x3c01ff,
+       /* 40  */ 0xaaf457,
+       /* 41  */ 0x3831bd5,
+       /* 42  */ 0xfb150,
+       /* 43  */ 0x3831bd5,
+       /* 44  */ 0x3aa5a8,
+       /* 45  */ 0x65b5d1,
+       /* 46  */ 0xe3390,
+       /* 47  */ 0x2226c8,
+       /* 48  */ 0xe3390,
+       /* 49  */ 0x7dc99,
+       /* 50  */ 0x358660,
+       /* 51  */ 0x6b0cc1,
+       /* 52  */ 0x358660,
+       /* 53  */ 0x3b418e,
+       /* 54  */ 0x1ad7f4,
+       /* 55  */ 0x800000,
+       /* 56  */ 0x0,
+       /* 57  */ 0x0,
+       /* 58  */ 0x0,
+       /* 59  */ 0x0,
+       /* 60  */ 0x800000,
+       /* 61  */ 0x0,
+       /* 62  */ 0x0,
+       /* 63  */ 0x0,
+       /* 64  */ 0x0,
+       /* 65  */ 0x800000,
+       /* 66  */ 0x0,
+       /* 67  */ 0x0,
+       /* 68  */ 0x0,
+       /* 69  */ 0x0,
+       /* 70  */ 0x800000,
+       /* 71  */ 0x0,
+       /* 72  */ 0x0,
+       /* 73  */ 0x0,
+       /* 74  */ 0x0,
+       /* 75  */ 0x800000,
+       /* 76  */ 0x0,
+       /* 77  */ 0x0,
+       /* 78  */ 0x0,
+       /* 79  */ 0x0,
+       /* 80  */ 0x800000,
+       /* 81  */ 0x0,
+       /* 82  */ 0x0,
+       /* 83  */ 0x0,
+       /* 84  */ 0x0,
+       /* 85  */ 0x800000,
+       /* 86  */ 0x0,
+       /* 87  */ 0x0,
+       /* 88  */ 0x0,
+       /* 89  */ 0x0,
+       /* 90  */ 0x800000,
+       /* 91  */ 0x0,
+       /* 92  */ 0x0,
+       /* 93  */ 0x0,
+       /* 94  */ 0x0,
+       /* 95  */ 0x800000,
+       /* 96  */ 0x0,
+       /* 97  */ 0x0,
+       /* 98  */ 0x0,
+       /* 99  */ 0x0,
+       /* 100 */ 0x800000,
+       /* 101 */ 0x0,
+       /* 102 */ 0x0,
+       /* 103 */ 0x0,
+       /* 104 */ 0x0,
+       /* 105 */ 0x7ed219,
+       /* 106 */ 0x3025bce,
+       /* 107 */ 0x7ed219,
+       /* 108 */ 0x3025e96,
+       /* 109 */ 0x7da6fb,
+       /* 110 */ 0x7ed219,
+       /* 111 */ 0x3025bce,
+       /* 112 */ 0x7ed219,
+       /* 113 */ 0x3025e96,
+       /* 114 */ 0x7da6fb,
+       /* 115 */ 0xdf71e0,
+       /* 116 */ 0x2411c40,
+       /* 117 */ 0xdf71e0,
+       /* 118 */ 0x304bd12,
+       /* 119 */ 0x7b58fb,
+       /* 120 */ 0x7d8252,
+       /* 121 */ 0x30bb7df,
+       /* 122 */ 0x771ba1,
+       /* 123 */ 0x30bb7df,
+       /* 124 */ 0x749df4,
+       /* 125 */ 0x79f87b,
+       /* 126 */ 0x31971e4,
+       /* 127 */ 0x6ddabe,
+       /* 128 */ 0x31971e4,
+       /* 129 */ 0x67d339,
+       /* 130 */ 0x84f8f3,
+       /* 131 */ 0x31d2c91,
+       /* 132 */ 0x62ebbf,
+       /* 133 */ 0x31d2c91,
+       /* 134 */ 0x67e4b1,
+       /* 135 */ 0x711f0e,
+       /* 136 */ 0x3543f10,
+       /* 137 */ 0x4ae2f0,
+       /* 138 */ 0x3543f10,
+       /* 139 */ 0x3c01ff,
+       /* 140 */ 0xaaf457,
+       /* 141 */ 0x3831bd5,
+       /* 142 */ 0xfb150,
+       /* 143 */ 0x3831bd5,
+       /* 144 */ 0x3aa5a8,
+       /* 145 */ 0x65b5d1,
+       /* 146 */ 0xe3390,
+       /* 147 */ 0x2226c8,
+       /* 148 */ 0xe3390,
+       /* 149 */ 0x7dc99,
+       /* 150 */ 0x358660,
+       /* 151 */ 0x6b0cc1,
+       /* 152 */ 0x358660,
+       /* 153 */ 0x3b418e,
+       /* 154 */ 0x1ad7f4,
+       /* 155 */ 0x800000,
+       /* 156 */ 0x0,
+       /* 157 */ 0x0,
+       /* 158 */ 0x0,
+       /* 159 */ 0x0,
+       /* 160 */ 0x800000,
+       /* 161 */ 0x0,
+       /* 162 */ 0x0,
+       /* 163 */ 0x0,
+       /* 164 */ 0x0,
+       /* 165 */ 0x800000,
+       /* 166 */ 0x0,
+       /* 167 */ 0x0,
+       /* 168 */ 0x0,
+       /* 169 */ 0x0,
+       /* 170 */ 0x800000,
+       /* 171 */ 0x0,
+       /* 172 */ 0x0,
+       /* 173 */ 0x0,
+       /* 174 */ 0x0,
+       /* 175 */ 0x800000,
+       /* 176 */ 0x0,
+       /* 177 */ 0x0,
+       /* 178 */ 0x0,
+       /* 179 */ 0x0,
+       /* 180 */ 0x800000,
+       /* 181 */ 0x0,
+       /* 182 */ 0x0,
+       /* 183 */ 0x0,
+       /* 184 */ 0x0,
+       /* 185 */ 0x800000,
+       /* 186 */ 0x0,
+       /* 187 */ 0x0,
+       /* 188 */ 0x0,
+       /* 189 */ 0x0,
+       /* 190 */ 0x800000,
+       /* 191 */ 0x0,
+       /* 192 */ 0x0,
+       /* 193 */ 0x0,
+       /* 194 */ 0x0,
+       /* 195 */ 0x800000,
+       /* 196 */ 0x0,
+       /* 197 */ 0x0,
+       /* 198 */ 0x0,
+       /* 199 */ 0x0,
+       /* 200 */ 0x800000,
+       /* 201 */ 0x0,
+       /* 202 */ 0x0,
+       /* 203 */ 0x0,
+       /* 204 */ 0x0,
+       /* 205 */ 0x25b,
+       /* 206 */ 0x4b5,
+       /* 207 */ 0x25b,
+       /* 208 */ 0x3045701,
+       /* 209 */ 0x7bb269,
+       /* 210 */ 0x7dd6da,
+       /* 211 */ 0x304524c,
+       /* 212 */ 0x7dd6da,
+       /* 213 */ 0x3045701,
+       /* 214 */ 0x7bb269,
+       /* 215 */ 0x7f3ee,
+       /* 216 */ 0xfe7dc,
+       /* 217 */ 0x7f3ee,
+       /* 218 */ 0x37f9f4a,
+       /* 219 */ 0x20306d,
+       /* 220 */ 0x482449,
+       /* 221 */ 0x36fb76e,
+       /* 222 */ 0x482449,
+       /* 223 */ 0x37f9f4a,
+       /* 224 */ 0x20306d,
+};
+
+static int multiband_drc_coeff[] = {
+       0x34ebb,   /* Low SMS coeff0 */
+       0x7f54e0,  /* Low SMS coeff1 */
+       0x5188,    /* Low RELEASE coeff0 */
+       0x7fae78,  /* Low RELEASE coeff1 */
+       0x3263a,   /* Low ATTACK coeff0 */
+       0x7cd9c6,  /* Low ATTACK coeff1 */
+
+       0x34ebb,   /* Mid */
+       0x7f54e0,
+       0x5188,
+       0x7fae78,
+       0x3263a,
+       0x7cd9c6,
+
+       0x34ebb,   /* High */
+       0x7f54e0,
+       0x5188,
+       0x7fae78,
+       0x3263a,
+       0x7cd9c6,
+};
+
+static int fullband_drc_coeff[] = {
+       0x5188,     /* RELEASE_COEF00 */
+       0x7fae78,       /* RELEASE_COEF01 */
+       0x5188,
+       0x7fae78,
+       0x5188,
+       0x7fae78,
+       0x5188,
+       0x7fae78,
+       0x5188,
+       0x7fae78,
+       0x5188,     /* RELEASE_COEF50 */
+       0x7fae78,       /* RELEASE_COEF51 */
+       0x3263a,        /* ATTACK_COEF00 */
+       0x7cd9c6,       /* ATTACK_COEF01 */
+       0x3263a,
+       0x7cd9c6,
+       0x3263a,
+       0x7cd9c6,
+       0x3263a,
+       0x7cd9c6,
+       0x3263a,
+       0x7cd9c6,
+       0x3263a,        /* ATTACK_COEF50 */
+       0x7cd9c6,       /* ATTACK_COEF51 */
+};
diff --git a/sound/soc/amlogic/auge/effects_v2.c b/sound/soc/amlogic/auge/effects_v2.c
new file mode 100644 (file)
index 0000000..13e4184
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * sound/soc/amlogic/auge/effects_v2.c
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "effects_v2.h"
+#include "effects_hw_v2.h"
+#include "effects_hw_v2_coeff.c"
+#include "ddr_mngr.h"
+#include "regs.h"
+#include "iomap.h"
+
+#define DRV_NAME "Effects"
+
+/*
+ * AED Diagram
+ * DC -- ND -- MIX -- EQ -- Mutiband DRC -- LR Vol
+ *    -- Fullband DRC -- Master Volume
+ */
+
+enum {
+       AED_DC,
+       AED_ND,
+       AED_EQ,
+       AED_MDRC,
+       AED_FDRC
+};
+
+struct effect_chipinfo {
+       /* v1 is for G12X(g12a, g12b)
+        * v2 is for tl1
+        */
+       bool v2;
+};
+
+struct audioeffect {
+       struct device *dev;
+
+       /* gate */
+       struct clk *gate;
+       /* source mpll */
+       struct clk *srcpll;
+       /* eqdrc clk */
+       struct clk *clk;
+
+       struct effect_chipinfo *chipinfo;
+
+       bool dc_en;
+       bool nd_en;
+       bool eq_en;
+       bool multiband_drc_en;
+       bool fullband_drc_en;
+       int mask_en;
+
+       int lane_mask;
+       int ch_mask;
+
+       /*which module should be effected */
+       int effect_module;
+};
+
+struct audioeffect *s_effect;
+
+static struct audioeffect *get_audioeffects(void)
+{
+       if (!s_effect) {
+               pr_info("Not init audio effects\n");
+               return NULL;
+       }
+
+       return s_effect;
+}
+
+bool check_aed_v2(void)
+{
+       struct audioeffect *p_effect = get_audioeffects();
+
+       if (!p_effect)
+               return false;
+
+       if (p_effect->chipinfo && p_effect->chipinfo->v2)
+               return true;
+
+       return false;
+}
+
+static int eqdrc_clk_set(struct audioeffect *p_effect)
+{
+       int ret = 0;
+
+       ret = clk_prepare_enable(p_effect->clk);
+       if (ret) {
+               pr_err("Can't enable eqdrc clock: %d\n",
+                       ret);
+               return -EINVAL;
+       }
+
+       ret = clk_prepare_enable(p_effect->srcpll);
+       if (ret) {
+               pr_err("Can't enable eqdrc src pll clock: %d\n",
+                       ret);
+               return -EINVAL;
+       }
+
+       /* defaule clk */
+       clk_set_rate(p_effect->clk, 200000000);
+
+       pr_info("%s, src pll:%lu, clk:%lu\n",
+               __func__,
+               clk_get_rate(p_effect->srcpll),
+               clk_get_rate(p_effect->clk));
+
+       return 0;
+}
+
+static int mixer_aed_read(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+       unsigned int shift = mc->shift;
+       unsigned int max = mc->max;
+       unsigned int invert = mc->invert;
+       unsigned int value =
+                       (((unsigned int)eqdrc_read(reg)) >> shift) & max;
+
+       if (invert)
+               value = (~value) & max;
+       ucontrol->value.integer.value[0] = value;
+
+       return 0;
+}
+
+static int mixer_aed_write(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+       unsigned int shift = mc->shift;
+       unsigned int max = mc->max;
+       unsigned int invert = mc->invert;
+       unsigned int value = ucontrol->value.integer.value[0];
+       unsigned int new_val = (unsigned int)eqdrc_read(reg);
+
+       if (invert)
+               value = (~value) & max;
+       max = ~(max << shift);
+       new_val &= max;
+       new_val |= (value << shift);
+
+       eqdrc_write(reg, new_val);
+
+       return 0;
+}
+
+static void check_set_aed_top(
+       struct audioeffect *p_effect,
+       int mask_new, bool enable)
+{
+       int mask_last = p_effect->mask_en;
+       bool update_aed_top = false;
+
+       pr_info("%s, mask:0x%x\n", __func__, mask_new);
+
+       if (enable)
+               p_effect->mask_en |= mask_new;
+       else
+               p_effect->mask_en &= ~mask_new;
+
+       if (enable && (!mask_last) && p_effect->mask_en)
+               update_aed_top = true; /* to enable */
+       else if ((!enable) && mask_last && (!p_effect->mask_en))
+               update_aed_top = true; /* to disable */
+
+       if (update_aed_top)
+               aml_set_aed(enable, p_effect->effect_module);
+}
+
+static int mixer_aed_enable_DC(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+
+       p_effect->dc_en = ucontrol->value.integer.value[0];
+
+       aed_dc_enable(p_effect->dc_en);
+
+       check_set_aed_top(p_effect,
+               0x1 << AED_DC,
+               p_effect->dc_en);
+
+       return 0;
+}
+
+static int mixer_aed_enable_ND(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+
+       p_effect->nd_en = ucontrol->value.integer.value[0];
+
+       aed_nd_enable(p_effect->nd_en);
+
+       check_set_aed_top(p_effect,
+               0x1 << AED_ND,
+               p_effect->nd_en);
+
+       return 0;
+}
+
+static int mixer_aed_enable_EQ(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+       int *p_eq_coeff = eq_coeff;
+       int len = ARRAY_SIZE(eq_coeff);
+
+       p_effect->eq_en = ucontrol->value.integer.value[0];
+
+       aed_set_ram_coeff(len, p_eq_coeff);
+       aed_eq_enable(0, p_effect->eq_en);
+
+       check_set_aed_top(p_effect,
+               0x1 << AED_EQ,
+               p_effect->eq_en);
+
+       return 0;
+}
+
+static int mixer_aed_enable_multiband_DRC(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+       int *p_multiband_coeff = multiband_drc_coeff;
+       int len = ARRAY_SIZE(multiband_drc_coeff);
+
+       if (!p_effect)
+               return -EINVAL;
+
+       p_effect->multiband_drc_en = ucontrol->value.integer.value[0];
+
+       aed_set_multiband_drc_coeff(len, p_multiband_coeff);
+       aed_multiband_drc_enable(p_effect->multiband_drc_en);
+
+       check_set_aed_top(p_effect,
+               0x1 << AED_MDRC,
+               p_effect->multiband_drc_en);
+
+       return 0;
+}
+
+static int mixer_aed_enable_fullband_DRC(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+       int *p_fullband_coeff = fullband_drc_coeff;
+       int len = ARRAY_SIZE(fullband_drc_coeff);
+
+       if (!p_effect)
+               return -EINVAL;
+
+       p_effect->fullband_drc_en = ucontrol->value.integer.value[0];
+
+       aed_set_fullband_drc_coeff(len, p_fullband_coeff);
+       aed_fullband_drc_enable(p_effect->fullband_drc_en);
+
+       check_set_aed_top(p_effect,
+               0x1 << AED_FDRC,
+               p_effect->fullband_drc_en);
+
+       return 0;
+}
+
+static int mixer_get_EQ_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int *val = (int *)ucontrol->value.bytes.data;
+       int *p = &eq_coeff[0];
+
+       memcpy(val, p, AED_EQ_LENGTH);
+
+       return 0;
+}
+
+
+static int mixer_set_EQ_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+       void *data;
+       int *val, *p = &eq_coeff[0];
+
+       data = kmemdup(ucontrol->value.bytes.data,
+               params->max, GFP_KERNEL | GFP_DMA);
+       if (!data)
+               return -ENOMEM;
+
+       val = (int *)data;
+       memcpy(p, val, params->max / sizeof(int));
+
+       kfree(data);
+
+       return 0;
+}
+
+static int mixer_get_multiband_DRC_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int *val = (int *)ucontrol->value.bytes.data;
+       int *p = &multiband_drc_coeff[0];
+
+       memcpy(val, p, AED_MULTIBAND_DRC_LENGTH);
+
+       return 0;
+}
+
+static int mixer_set_multiband_DRC_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+       void *data;
+       int *val, *p = &multiband_drc_coeff[0];
+
+       data = kmemdup(ucontrol->value.bytes.data,
+               params->max, GFP_KERNEL | GFP_DMA);
+       if (!data)
+               return -ENOMEM;
+
+       val = (int *)data;
+       memcpy(p, val, params->max / sizeof(int));
+
+       kfree(data);
+
+       return 0;
+}
+
+static int mixer_get_fullband_DRC_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int *val = (int *)ucontrol->value.bytes.data;
+       int *p = &fullband_drc_coeff[0];
+
+       memcpy(val, p, AED_FULLBAND_DRC_LENGTH);
+
+       return 0;
+}
+
+static int mixer_set_fullband_DRC_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+       void *data;
+       int *val, *p = &fullband_drc_coeff[0];
+
+       data = kmemdup(ucontrol->value.bytes.data,
+               params->max, GFP_KERNEL | GFP_DMA);
+       if (!data)
+               return -ENOMEM;
+
+       val = (int *)data;
+       memcpy(p, val, params->max / sizeof(int));
+
+       kfree(data);
+
+       return 0;
+}
+
+/* aed module
+ * check to sync with enum frddr_dest in ddr_mngr.h
+ */
+static const char *const aed_module_texts[] = {
+       "TDMOUT_A",
+       "TDMOUT_B",
+       "TDMOUT_C",
+       "SPDIFIN",
+       "SPDIFOUT_A",
+       "SPDIFOUT_B",
+};
+
+static const struct soc_enum aed_module_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(aed_module_texts),
+                       aed_module_texts);
+
+static int aed_module_get_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+
+       if (!p_effect)
+               return -EINVAL;
+
+       ucontrol->value.enumerated.item[0] = p_effect->effect_module;
+
+       return 0;
+}
+
+static int aed_module_set_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
+
+       if (!p_effect)
+               return -EINVAL;
+
+       p_effect->effect_module = ucontrol->value.enumerated.item[0];
+
+       /* update info to ddr and modules */
+       aed_set_ctrl(
+               p_effect->eq_en |
+               p_effect->multiband_drc_en |
+               p_effect->fullband_drc_en,
+               0,
+               p_effect->effect_module);
+
+       return 0;
+}
+
+static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12276, 12, 1);
+static const DECLARE_TLV_DB_SCALE(lr_vol_tlv, -12750, 50, 1);
+
+static const struct snd_kcontrol_new snd_effect_controls[] = {
+
+       SOC_SINGLE_EXT("AED DC cut enable",
+               AED_DC_EN, 0, 0x1, 0,
+               mixer_aed_read, mixer_aed_enable_DC),
+
+       SOC_SINGLE_EXT("AED Noise Detect enable",
+               AED_ND_CNTL, 0, 0x1, 0,
+               mixer_aed_read, mixer_aed_enable_ND),
+
+       SOC_SINGLE_EXT("AED EQ enable",
+               AED_EQ_EN, 0, 0x1, 0,
+               mixer_aed_read, mixer_aed_enable_EQ),
+
+       SOC_SINGLE_EXT("AED Multi-band DRC enable",
+               AED_MDRC_CNTL, 8, 0x1, 0,
+               mixer_aed_read, mixer_aed_enable_multiband_DRC),
+
+       SOC_SINGLE_EXT("AED Full-band DRC enable",
+               AED_DRC_CNTL, 0, 0x1, 0,
+               mixer_aed_read, mixer_aed_enable_fullband_DRC),
+
+       SND_SOC_BYTES_EXT("AED EQ Parameters",
+               AED_EQ_LENGTH,
+               mixer_get_EQ_params,
+               mixer_set_EQ_params),
+
+       SND_SOC_BYTES_EXT("AED Multi-band DRC Parameters",
+               AED_MULTIBAND_DRC_LENGTH,
+               mixer_get_multiband_DRC_params,
+               mixer_set_multiband_DRC_params),
+
+       SND_SOC_BYTES_EXT("AED Full-band DRC Parameters",
+               AED_FULLBAND_DRC_LENGTH,
+               mixer_get_fullband_DRC_params,
+               mixer_set_fullband_DRC_params),
+
+       SOC_ENUM_EXT("AED module",
+               aed_module_enum,
+               aed_module_get_enum,
+               aed_module_set_enum),
+
+       SOC_SINGLE_EXT("AED Lane mask",
+               AED_TOP_CTL, 14, 0xF, 0,
+               mixer_aed_read, mixer_aed_write),
+
+       SOC_SINGLE_EXT("AED Channel mask",
+               AED_TOP_CTL, 18, 0xFF, 0,
+               mixer_aed_read, mixer_aed_write),
+
+       SOC_SINGLE_EXT_TLV("AED Lch volume",
+               AED_EQ_VOLUME, 0, 0xFF, 1,
+               mixer_aed_read, mixer_aed_write,
+               lr_vol_tlv),
+
+       SOC_SINGLE_EXT_TLV("AED Rch volume",
+               AED_EQ_VOLUME, 8, 0xFF, 1,
+               mixer_aed_read, mixer_aed_write,
+               lr_vol_tlv),
+
+       SOC_SINGLE_EXT_TLV("AED master volume",
+               AED_EQ_VOLUME, 16, 0x3FF, 1,
+               mixer_aed_read, mixer_aed_write,
+               master_vol_tlv),
+};
+
+int card_add_effect_v2_kcontrols(struct snd_soc_card *card)
+{
+       unsigned int idx;
+       int err;
+
+       if (!s_effect) {
+               pr_info("effect_v2 is not init\n");
+               return 0;
+       }
+
+       for (idx = 0; idx < ARRAY_SIZE(snd_effect_controls); idx++) {
+               err = snd_ctl_add(card->snd_card,
+                               snd_ctl_new1(&snd_effect_controls[idx],
+                                       s_effect));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+#if 0
+static const struct snd_soc_component_driver effect_component_drv = {
+       .name               = DRV_NAME,
+
+       .controls                   = snd_effect_controls,
+       .num_controls           = ARRAY_SIZE(snd_effect_controls),
+};
+#endif
+
+static struct effect_chipinfo tl1_effect_chipinfo = {
+       .v2 = true,
+};
+
+static const struct of_device_id effect_device_id[] = {
+       {
+               .compatible = "amlogic, snd-effect-v1"
+       },
+       {
+               .compatible = "amlogic, snd-effect-v2",
+               .data       = &tl1_effect_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-effect",
+               .data       = &tl1_effect_chipinfo,
+       },
+       {}
+};
+MODULE_DEVICE_TABLE(of, effect_device_id);
+
+static int effect_platform_probe(struct platform_device *pdev)
+{
+       struct audioeffect *p_effect;
+       struct device *dev = &pdev->dev;
+       struct effect_chipinfo *p_chipinfo;
+       bool eq_enable = false;
+       bool multiband_drc_enable = false;
+       bool fullband_drc_enable = false;
+       int lane_mask = -1, channel_mask = -1, eqdrc_module = -1;
+
+       int ret;
+
+       pr_info("%s, line:%d\n", __func__, __LINE__);
+
+       p_effect = devm_kzalloc(&pdev->dev,
+                       sizeof(struct audioeffect),
+                       GFP_KERNEL);
+       if (!p_effect) {
+               dev_err(&pdev->dev, "Can't allocate pcm_p\n");
+               return -ENOMEM;
+       }
+
+       /* match data */
+       p_chipinfo = (struct effect_chipinfo *)
+               of_device_get_match_data(dev);
+       if (!p_chipinfo)
+               dev_warn_once(dev, "check whether to update effect chipinfo\n");
+       p_effect->chipinfo = p_chipinfo;
+
+       p_effect->gate = devm_clk_get(&pdev->dev, "gate");
+       if (IS_ERR(p_effect->gate)) {
+               dev_err(&pdev->dev,
+                       "Can't retrieve eqdrc gate clock\n");
+               ret = PTR_ERR(p_effect->gate);
+               return ret;
+       }
+
+       p_effect->srcpll = devm_clk_get(&pdev->dev, "srcpll");
+       if (IS_ERR(p_effect->srcpll)) {
+               dev_err(&pdev->dev,
+                       "Can't retrieve source mpll clock\n");
+               ret = PTR_ERR(p_effect->srcpll);
+               return ret;
+       }
+
+       p_effect->clk = devm_clk_get(&pdev->dev, "eqdrc");
+       if (IS_ERR(p_effect->clk)) {
+               dev_err(&pdev->dev,
+                       "Can't retrieve eqdrc clock\n");
+               ret = PTR_ERR(p_effect->clk);
+               return ret;
+       }
+
+       ret = clk_set_parent(p_effect->clk, p_effect->srcpll);
+       if (ret) {
+               dev_err(&pdev->dev,
+                       "Can't set eqdrc clock parent clock\n");
+               ret = PTR_ERR(p_effect->clk);
+               return ret;
+       }
+
+       eqdrc_clk_set(p_effect);
+
+       eq_enable = of_property_read_bool(pdev->dev.of_node,
+                       "eq_enable");
+
+       multiband_drc_enable = of_property_read_bool(pdev->dev.of_node,
+                       "multiband_drc_enable");
+
+       fullband_drc_enable = of_property_read_bool(pdev->dev.of_node,
+                       "fullband_drc_enable");
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                       "eqdrc_module",
+                       &eqdrc_module);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Can't retrieve eqdrc_module\n");
+               return -EINVAL;
+       }
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                       "lane_mask",
+                       &lane_mask);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Can't retrieve lane_mask\n");
+               return -EINVAL;
+       }
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                       "channel_mask",
+                       &channel_mask);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Can't retrieve channel_mask\n");
+               return -EINVAL;
+       }
+
+       pr_info("%s \t eq_en:%d, multi-band drc en:%d, full-band drc en:%d, module:%d, lane_mask:%d, ch_mask:%d\n",
+               __func__,
+               eq_enable,
+               multiband_drc_enable,
+               fullband_drc_enable,
+               eqdrc_module,
+               lane_mask,
+               channel_mask
+               );
+
+       /* config from dts */
+       p_effect->eq_en            = eq_enable;
+       p_effect->multiband_drc_en = multiband_drc_enable;
+       p_effect->fullband_drc_en  = fullband_drc_enable;
+       p_effect->lane_mask        = lane_mask;
+       p_effect->ch_mask          = channel_mask;
+       p_effect->effect_module    = eqdrc_module;
+
+       aed_set_lane_and_channels(lane_mask, channel_mask);
+       aed_set_EQ_volume(0xc0, 0x30, 0x30);
+
+       p_effect->dev = dev;
+       s_effect = p_effect;
+       dev_set_drvdata(&pdev->dev, p_effect);
+
+       return 0;
+}
+
+static struct platform_driver effect_platform_driver = {
+       .driver = {
+               .name           = DRV_NAME,
+               .owner          = THIS_MODULE,
+               .of_match_table = of_match_ptr(effect_device_id),
+       },
+       .probe  = effect_platform_probe,
+};
+module_platform_driver(effect_platform_driver);
+
+MODULE_AUTHOR("AMLogic, Inc.");
+MODULE_DESCRIPTION("Amlogic Audio Effects driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amlogic/auge/effects_v2.h b/sound/soc/amlogic/auge/effects_v2.h
new file mode 100644 (file)
index 0000000..9c5051a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * sound/soc/amlogic/auge/effects_v2.h
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef __EFFECTS_V2_H__
+#define __EFFECTS_V2_H__
+
+extern bool check_aed_v2(void);
+extern int card_add_effect_v2_kcontrols(struct snd_soc_card *card);
+
+#endif
index c437e9f..c0fe616 100644 (file)
 #include "audio_utils.h"
 #include "frhdmirx_hw.h"
 
+#include <linux/amlogic/media/sound/misc.h>
+
 #define DRV_NAME "EXTN"
 
 struct extn {
        struct aml_audio_controller *actrl;
        struct device *dev;
-       unsigned int sysclk_freq;
-
-       int irq_frhdmirx;
 
        struct toddr *tddr;
        struct frddr *fddr;
+
+       int sysclk_freq;
+
+       int irq_frhdmirx;
+
+       /*
+        * 0: select spdif lane;
+        * 1: select PAO mode;
+        */
+       int hdmirx_mode;
+
+       /*
+        * arc source sel:
+        * 0: hi_hdmirx_arc_cntl[5]
+        * 1: audio_spdif_a
+        * 2: audio_spdif_b
+        * 4: hdmir_aud_spdif
+        */
+       int arc_src;
+       int arc_en;
+
 };
 
-#define PREALLOC_BUFFER                (32 * 1024)
+#define PREALLOC_BUFFER                (128 * 1024)
 #define PREALLOC_BUFFER_MAX    (256 * 1024)
 
 #define EXTN_RATES      (SNDRV_PCM_RATE_8000_192000)
@@ -320,37 +340,58 @@ static int extn_dai_prepare(
                aml_frddr_set_fifos(fr, 0x40, 0x20);
        } else {
                struct toddr *to = p_extn->tddr;
-               unsigned int msb = 32 - 1;
-               unsigned int lsb = 32 - bit_depth;
-               unsigned int toddr_type;
+               unsigned int msb = 0, lsb = 0, toddr_type = 0;
                unsigned int src = toddr_src_get();
                struct toddr_fmt fmt;
 
-               switch (bit_depth) {
-               case 8:
-               case 16:
-               case 32:
-                       toddr_type = 0;
-                       break;
-               case 24:
+               if (bit_depth == 24)
                        toddr_type = 4;
-                       break;
-               default:
-                       pr_err("invalid bit_depth: %d\n", bit_depth);
-                       return -EINVAL;
-               }
+               else
+                       toddr_type = 0;
 
                pr_info("%s Expected toddr src:%s\n",
                        __func__,
                        toddr_src_get_str(src));
 
-               if (src == FRATV)
-                       fratv_src_select(0);
-               else if (src == FRHDMIRX) {
-                       frhdmirx_ctrl(runtime->channels, 0);
-                       frhdmirx_src_select(0);
+               if (src == FRATV) {
+                       /* Now tv supports 48k, 16bits */
+                       if ((bit_depth != 16) || (runtime->rate != 48000)) {
+                               pr_err("not support sample rate:%d, bits:%d\n",
+                                       runtime->rate, bit_depth);
+                               return -EINVAL;
+                       }
+
+                       msb = 15;
+                       lsb = 0;
+
+                       fratv_src_select(1);
+               } else if (src == FRHDMIRX) {
+                       if (p_extn->hdmirx_mode) { /* PAO */
+
+                               if (bit_depth == 32)
+                                       toddr_type = 3;
+                               else if (bit_depth == 24)
+                                       toddr_type = 4;
+                               else
+                                       toddr_type = 0;
+
+                               msb = 28 - 1 - 4;
+                               if (bit_depth == 16)
+                                       lsb = 24 - bit_depth;
+                               else
+                                       lsb = 4;
+                       }
+
+                       frhdmirx_ctrl(runtime->channels, p_extn->hdmirx_mode);
+                       frhdmirx_src_select(p_extn->hdmirx_mode);
+               } else {
+                       pr_info("Not support toddr src:%s\n",
+                               toddr_src_get_str(src));
+                       return -EINVAL;
                }
 
+               pr_info("%s m:%d, n:%d\n", __func__, msb, lsb);
+
                fmt.type      = toddr_type;
                fmt.msb       = msb;
                fmt.lsb       = lsb;
@@ -486,7 +527,150 @@ static struct snd_soc_dai_driver extn_dai[] = {
        },
 };
 
+static const char *const arc_src_txt[] = {
+       "HI_HDMIRX_ARC_CNTL[5]",
+       "AUDIO_SPDIF_A",
+       "AUDIO_SPDIF_B",
+       "HDMIR_AUD_SPDIF",
+};
+
+const struct soc_enum arc_src_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(arc_src_txt),
+                       arc_src_txt);
+
+static int arc_get_src(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       ucontrol->value.integer.value[0] = p_extn->arc_src;
+
+       return 0;
+}
+
+static int arc_set_src(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       p_extn->arc_src = ucontrol->value.integer.value[0];
+
+       cec_arc_enable(p_extn->arc_src, p_extn->arc_en);
+
+       return 0;
+}
+
+static int arc_get_enable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       ucontrol->value.integer.value[0] = p_extn->arc_en;
+
+       return 0;
+}
+
+static int arc_set_enable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       p_extn->arc_en = ucontrol->value.integer.value[0];
+
+       cec_arc_enable(p_extn->arc_src, p_extn->arc_en);
+
+       return 0;
+}
+
+static int frhdmirx_get_mode(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       ucontrol->value.integer.value[0] = p_extn->hdmirx_mode;
+
+       return 0;
+}
+
+static int frhdmirx_set_mode(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct extn *p_extn = dev_get_drvdata(component->dev);
+
+       p_extn->hdmirx_mode = ucontrol->value.integer.value[0];
+
+       return 0;
+}
+
+static const struct snd_kcontrol_new extn_controls[] = {
+       /* Out */
+       SOC_ENUM_EXT("HDMI ARC Source",
+               arc_src_enum,
+               arc_get_src,
+               arc_set_src),
+
+       SOC_SINGLE_BOOL_EXT("HDMI ARC Switch",
+               0,
+               arc_get_enable,
+               arc_set_enable),
+
+       /* In */
+       SOC_SINGLE_BOOL_EXT("SPDIFIN PAO",
+               0,
+               frhdmirx_get_mode,
+               frhdmirx_set_mode),
+
+#ifdef CONFIG_AMLOGIC_ATV_DEMOD
+       SOC_ENUM_EXT("ATV audio stable",
+               atv_audio_status_enum,
+               aml_get_atv_audio_stable,
+               NULL),
+#endif
+
+#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
+       SOC_ENUM_EXT("HDMIIN audio stable",
+               hdmi_in_status_enum[0],
+               aml_get_hdmiin_audio_stable,
+               NULL),
+
+       SOC_ENUM_EXT("HDMIIN audio samplerate",
+               hdmi_in_status_enum[1],
+               aml_get_hdmiin_audio_samplerate,
+                       NULL),
+
+       SOC_ENUM_EXT("HDMIIN audio channels",
+               hdmi_in_status_enum[2],
+               aml_get_hdmiin_audio_channels,
+               NULL),
+
+       SOC_ENUM_EXT("HDMIIN audio format",
+               hdmi_in_status_enum[3],
+               aml_get_hdmiin_audio_format,
+               NULL),
+
+       SOC_SINGLE_BOOL_EXT("HDMI ATMOS EDID Switch",
+               0,
+               aml_get_atmos_audio_edid,
+               aml_set_atmos_audio_edid),
+#endif
+
+};
+
 static const struct snd_soc_component_driver extn_component = {
+       .controls       = extn_controls,
+       .num_controls   = ARRAY_SIZE(extn_controls),
        .name           = DRV_NAME,
 };
 
@@ -506,16 +690,16 @@ static int extn_platform_probe(struct platform_device *pdev)
        struct platform_device *pdev_parent;
        struct device *dev = &pdev->dev;
        struct aml_audio_controller *actrl = NULL;
-       struct extn *extn = NULL;
+       struct extn *p_extn = NULL;
        int ret = 0;
 
 
-       extn = devm_kzalloc(dev, sizeof(struct extn), GFP_KERNEL);
-       if (!extn)
+       p_extn = devm_kzalloc(dev, sizeof(struct extn), GFP_KERNEL);
+       if (!p_extn)
                return -ENOMEM;
 
-       extn->dev = dev;
-       dev_set_drvdata(dev, extn);
+       p_extn->dev = dev;
+       dev_set_drvdata(dev, p_extn);
 
        /* get audio controller */
        node_prt = of_get_parent(node);
@@ -526,16 +710,22 @@ static int extn_platform_probe(struct platform_device *pdev)
        of_node_put(node_prt);
        actrl = (struct aml_audio_controller *)
                                platform_get_drvdata(pdev_parent);
-       extn->actrl = actrl;
+       p_extn->actrl = actrl;
 
        /* irqs */
-       extn->irq_frhdmirx = platform_get_irq_byname(pdev, "irq_frhdmirx");
-       if (extn->irq_frhdmirx < 0) {
+       p_extn->irq_frhdmirx = platform_get_irq_byname(pdev, "irq_frhdmirx");
+       if (p_extn->irq_frhdmirx < 0) {
                dev_err(dev, "Failed to get irq_frhdmirx:%d\n",
-                       extn->irq_frhdmirx);
+                       p_extn->irq_frhdmirx);
                return -ENXIO;
        }
 
+       /* Default ARC SRC */
+       p_extn->arc_src = 1;
+
+       /* Default: PAO mode */
+       p_extn->hdmirx_mode = 1;
+
        ret = snd_soc_register_component(&pdev->dev,
                                &extn_component,
                                extn_dai,
index ca24d6a..c46f6df 100644 (file)
@@ -81,6 +81,13 @@ void frhdmirx_ctrl(int channels, int src)
 {
        int lane, lane_mask = 0, i;
 
+       /* PAO mode */
+       if (src) {
+               audiobus_write(EE_AUDIO_FRHDMIRX_CTRL0,
+                       0x1 << 23 | 0x1 << 22 | 0x1 << 7);
+               return;
+       }
+
        if (channels % 2)
                lane = channels / 2 + 1;
        else
@@ -90,9 +97,10 @@ void frhdmirx_ctrl(int channels, int src)
                lane_mask |= (1 << i);
 
        audiobus_update_bits(EE_AUDIO_FRHDMIRX_CTRL0,
-               0x1 << 30 | 0xf << 24 | 0x3 << 11,
+               0x1 << 30 | 0xf << 24 | 0x1 << 22 | 0x3 << 11,
                0x1 << 30 | /* chnum_sel */
                lane_mask << 24 | /* chnum_sel */
+               0x1 << 22 | /* clk_inv */
                0x0 << 11 /* req_sel, Sync 4 spdifin by which */
                );
 
index f3aa05e..58bef78 100644 (file)
@@ -204,6 +204,33 @@ void audioreset_update_bits(unsigned int reg,
 }
 EXPORT_SYMBOL(audioreset_update_bits);
 
+int vad_read(unsigned int reg)
+{
+       int ret, val = 0;
+
+       ret = aml_snd_read(IO_VAD, reg, &val);
+
+       if (ret) {
+               pr_err("read audio reg %x error %d\n", reg, ret);
+               return -1;
+       }
+       return val;
+}
+EXPORT_SYMBOL(vad_read);
+
+void vad_write(unsigned int reg, unsigned int val)
+{
+       aml_snd_write(IO_VAD, reg, val);
+}
+EXPORT_SYMBOL(vad_write);
+
+void vad_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val)
+{
+       aml_snd_update_bits(IO_VAD, reg, mask, val);
+}
+EXPORT_SYMBOL(vad_update_bits);
+
 static int snd_iomap_probe(struct platform_device *pdev)
 {
        struct resource res;
index 574fd2e..ae3c928 100644 (file)
@@ -24,6 +24,7 @@ enum{
        IO_AUDIO_LOCKER,
        IO_EQDRC_BUS,
        IO_RESET,
+       IO_VAD,
 
        IO_MAX,
 };
@@ -52,4 +53,9 @@ extern int audioreset_read(unsigned int reg);
 extern void audioreset_write(unsigned int reg, unsigned int val);
 extern void audioreset_update_bits(unsigned int reg,
        unsigned int mask, unsigned int val);
+
+extern int vad_read(unsigned int reg);
+extern void vad_write(unsigned int reg, unsigned int val);
+extern void vad_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val);
 #endif
index bfbe007..bc53b6a 100644 (file)
@@ -181,7 +181,7 @@ static DEVICE_ATTR(locker_enable, 0644,
 void audio_locker_set(int enable)
 {
        if (!s_locker) {
-               pr_err("audio locker is not init\n");
+               pr_debug("audio locker is not init\n");
                return;
        }
 
index e05c24b..e29228d 100644 (file)
@@ -676,6 +676,9 @@ static int aml_pdm_dai_prepare(
                }
                p_pdm->filter_mode = s_pdm_filter_mode;
                aml_pdm_filter_ctrl(osr, p_pdm->filter_mode);
+
+               if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data)
+                       pdm_init_truncate_data(runtime->rate);
        }
 
        return 0;
@@ -874,7 +877,7 @@ static struct pdm_chipinfo g12a_pdm_chipinfo = {
 
 static struct pdm_chipinfo tl1_pdm_chipinfo = {
        .mute_fn         = true,
-       .truncate_data   = true,
+       .truncate_data   = false,
 };
 
 static const struct of_device_id aml_pdm_device_id[] = {
index 585d271..d870dd0 100644 (file)
@@ -452,3 +452,13 @@ void pdm_set_mute_channel(int mute_chmask)
                (0xff << 20 | 0x1 << 17),
                (mute_chmask << 20 | mute_en << 17));
 }
+
+void pdm_init_truncate_data(int freq)
+{
+       int mask_val;
+
+       /* assume mask 1.05ms */
+       mask_val = ((freq / 1000) * 1050) / 1000 - 1;
+
+       aml_pdm_write(PDM_MASK_NUM, mask_val);
+}
index a7461d6..b7d19c0 100644 (file)
@@ -38,6 +38,8 @@ extern void pdm_set_mute_value(int val);
 extern int pdm_get_mute_channel(void);
 extern void pdm_set_mute_channel(int mute_chmask);
 
+extern void pdm_init_truncate_data(int freq);
+
 extern int pdm_hcic_shift_gain;
 extern int pdm_dclk;
 
index f3394be..7bf3d4e 100644 (file)
@@ -270,16 +270,27 @@ enum clk_sel {
 #define EE_AUDIO_SPDIFIN_STAT2             0x109
 #define EE_AUDIO_SPDIFIN_MUTE_VAL          0x10a
 
-#define EE_AUDIO_RESAMPLE_CTRL0            0x110
-#define EE_AUDIO_RESAMPLE_CTRL1            0x111
-#define EE_AUDIO_RESAMPLE_CTRL2            0x112
-#define EE_AUDIO_RESAMPLE_CTRL3            0x113
-#define EE_AUDIO_RESAMPLE_COEF0            0x114
-#define EE_AUDIO_RESAMPLE_COEF1            0x115
-#define EE_AUDIO_RESAMPLE_COEF2            0x116
-#define EE_AUDIO_RESAMPLE_COEF3            0x117
-#define EE_AUDIO_RESAMPLE_COEF4            0x118
-#define EE_AUDIO_RESAMPLE_STATUS1          0x119
+#define EE_AUDIO_RESAMPLEA_CTRL0           0x110
+#define EE_AUDIO_RESAMPLEA_CTRL1           0x111
+#define EE_AUDIO_RESAMPLEA_CTRL2           0x112
+#define EE_AUDIO_RESAMPLEA_CTRL3           0x113
+#define EE_AUDIO_RESAMPLEA_COEF0           0x114
+#define EE_AUDIO_RESAMPLEA_COEF1           0x115
+#define EE_AUDIO_RESAMPLEA_COEF2           0x116
+#define EE_AUDIO_RESAMPLEA_COEF3           0x117
+#define EE_AUDIO_RESAMPLEA_COEF4           0x118
+#define EE_AUDIO_RESAMPLEA_STATUS1         0x119
+
+#define EE_AUDIO_RESAMPLEB_CTRL0           0x1e0
+#define EE_AUDIO_RESAMPLEB_CTRL1           0x1e1
+#define EE_AUDIO_RESAMPLEB_CTRL2           0x1e2
+#define EE_AUDIO_RESAMPLEB_CTRL3           0x1e3
+#define EE_AUDIO_RESAMPLEB_COEF0           0x1e4
+#define EE_AUDIO_RESAMPLEB_COEF1           0x1e5
+#define EE_AUDIO_RESAMPLEB_COEF2           0x1e6
+#define EE_AUDIO_RESAMPLEB_COEF3           0x1e7
+#define EE_AUDIO_RESAMPLEB_COEF4           0x1e8
+#define EE_AUDIO_RESAMPLEB_STATUS1         0x1e9
 
 #define EE_AUDIO_SPDIFOUT_STAT             0x120
 #define EE_AUDIO_SPDIFOUT_GAIN0            0x121
@@ -404,6 +415,11 @@ enum clk_sel {
 #define EE_RESET1                          0x002
 
 /*
+ *     HIU, ARC
+ */
+#define HHI_HDMIRX_ARC_CNTL                0xe8
+
+/*
  *     AUDIO MUX CONTROLS
  */
 #define EE_AUDIO_TOACODEC_CTRL0            0x1d0
@@ -411,17 +427,6 @@ enum clk_sel {
 #define EE_AUDIO_TOVAD_CTRL0               0x1d2
 #define EE_AUDIO_FRATV_CTRL0               0x1d3
 
-#define EE_AUDIO_RESAMPLEB_CTRL0           0x1e0
-#define EE_AUDIO_RESAMPLEB_CTRL1           0x1e1
-#define EE_AUDIO_RESAMPLEB_CTRL2           0x1e2
-#define EE_AUDIO_RESAMPLEB_CTRL3           0x1e3
-#define EE_AUDIO_RESAMPLEB_COEF0           0x1e4
-#define EE_AUDIO_RESAMPLEB_COEF1           0x1e5
-#define EE_AUDIO_RESAMPLEB_COEF2           0x1e6
-#define EE_AUDIO_RESAMPLEB_COEF3           0x1e7
-#define EE_AUDIO_RESAMPLEB_COEF4           0x1e8
-#define EE_AUDIO_RESAMPLEB_STATUS1         0x1e9
-
 #define EE_AUDIO_SPDIFIN_LB_CTRL0          0x1f0
 #define EE_AUDIO_SPDIFIN_LB_CTRL1          0x1f1
 #define EE_AUDIO_SPDIFIN_LB_CTRL6          0x1f6
@@ -507,7 +512,7 @@ enum clk_sel {
 #define RO_AUD_LOCK_INT_STATUS             0x01b
 
 /*
- * EQ DRC, g12a, g12b
+ * EQ DRC, G12X means g12a, g12b
  */
 #define AED_EQ_CH1_COEF00                  0x00
 #define AED_EQ_CH1_COEF01                  0x01
@@ -645,6 +650,10 @@ enum clk_sel {
 #define AED_DRC_AD_1M_H                    0x85
 #define AED_NG_CNT                         0x86
 #define AED_NG_STEP                        0x87
+
+#define AED_TOP_CTL_G12X                   0x88
+#define AED_TOP_REQ_CTL_G12X               0x89
+
 /*
  * EQ DRC, New ARCH, from tl1
  */
@@ -780,8 +789,9 @@ enum clk_sel {
 #define AED_MASTER_VOLUME_STATE            0x81
 #define AED_MASTER_VOLUME_GAIN             0x82
 
-#define AED_TOP_CTL                        0x88
-#define AED_TOP_REQ_CTL                    0x89
+#define AED_TOP_CTL                        0x83
+#define AED_TOP_REQ_CTL                    0x84
+
 
 /*
  * VAD, Voice activity detection
index e8812c5..326ebaa 100644 (file)
 
 #define CLK_RATIO     256
 
+/*#define __PTM_RESAMPLE_CLK__*/
+
+#define RESAMPLE_A    0
+#define RESAMPLE_B    1
+
 struct resample_chipinfo {
+       int num;    /* support resample a/b */
+       int id;
+
        bool dividor_fn;
 };
 
@@ -50,18 +58,46 @@ struct audioresample {
 
        struct resample_chipinfo *chipinfo;
 
+       int id;
+
        /*which module should be resampled */
        int resample_module;
        /*  resample to the rate */
        int out_rate;
 
        /* sync with auge_resample_texts */
-       int asr_idx;
+       int asrc_rate_idx;
 
        bool enable;
 };
 
-struct audioresample *s_resample;
+struct audioresample *s_resample_a;
+
+struct audioresample *s_resample_b;
+
+static struct audioresample *get_audioresample(int id)
+{
+       struct audioresample *p_resample;
+
+       p_resample = ((id == 0) ? s_resample_a : s_resample_b);
+
+       if (!p_resample) {
+               pr_info("Not init audio resample\n");
+               return NULL;
+       }
+
+       return p_resample;
+}
+
+int get_resample_module_num(void)
+{
+       struct audioresample *p_resample = get_audioresample(0);
+
+       if (p_resample && p_resample->chipinfo)
+               return p_resample->chipinfo->num;
+
+       return 1;
+}
 
 static int resample_clk_set(struct audioresample *p_resample)
 {
@@ -84,8 +120,13 @@ static int resample_clk_set(struct audioresample *p_resample)
                }
 
                if (p_resample->out_rate) {
+#ifdef __PTM_RESAMPLE_CLK__
+                       clk_set_rate(p_resample->pll,
+                               p_resample->out_rate * CLK_RATIO * 2 * 14);
+#else
                        clk_set_rate(p_resample->pll,
                                p_resample->out_rate * CLK_RATIO * 2);
+#endif
                        clk_set_rate(p_resample->sclk,
                                p_resample->out_rate * CLK_RATIO);
                        clk_set_rate(p_resample->clk,
@@ -121,20 +162,20 @@ static void audio_resample_init(struct audioresample *p_resample)
 {
        resample_clk_set(p_resample);
 
-       aml_resample_enable(p_resample->enable,
+       aml_set_resample(p_resample->id, p_resample->enable,
                p_resample->resample_module);
 }
 
-static int audio_resample_set(int enable, int rate)
+static int audio_resample_set(
+       struct audioresample *p_resample,
+       bool enable, int rate)
 {
-       if (!s_resample) {
-               pr_err("audio resample is not init\n");
-               return -EINVAL;
-       }
+       if (!p_resample)
+               return 0;
 
-       s_resample->enable = (bool)enable;
-       s_resample->out_rate = rate;
-       audio_resample_init(s_resample);
+       p_resample->enable = enable;
+       p_resample->out_rate = rate;
+       audio_resample_init(p_resample);
 
        return 0;
 }
@@ -186,41 +227,40 @@ static int resample_get_enum(
 
        if (!p_resample) {
                pr_info("audio resample is not init\n");
-               return -EINVAL;
+               return 0;
        }
 
-       ucontrol->value.enumerated.item[0] = p_resample->asr_idx;
+       ucontrol->value.enumerated.item[0] = p_resample->asrc_rate_idx;
 
        return 0;
 }
 
-int resample_set(int index)
+int resample_set(int id, int index)
 {
        int resample_rate = resample_idx2rate(index);
+       struct audioresample *p_resample = get_audioresample(id);
 
-       if (!s_resample) {
-               pr_info("audio resample is not init\n");
-               return -EINVAL;
-       }
+       if (!p_resample)
+               return 0;
 
-       if (index == s_resample->asr_idx)
+       if (index == p_resample->asrc_rate_idx)
                return 0;
 
-       s_resample->asr_idx = index;
+       p_resample->asrc_rate_idx = index;
 
        pr_info("%s %s\n",
                __func__,
                auge_resample_texts[index]);
 
-       if (audio_resample_set(index, resample_rate))
+       if (audio_resample_set(p_resample, (bool)index, resample_rate))
                return 0;
 
        if ((index == 0) || (resample_rate == 0))
-               resample_disable();
+               resample_disable(p_resample->id);
        else {
-               resample_init(resample_rate);
+               resample_init(p_resample->id, resample_rate);
 
-               resample_set_hw_param(index - 1);
+               resample_set_hw_param(p_resample->id, index - 1);
        }
 
        return 0;
@@ -230,9 +270,15 @@ static int resample_set_enum(
        struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
+       struct audioresample *p_resample = snd_kcontrol_chip(kcontrol);
        int index = ucontrol->value.enumerated.item[0];
 
-       resample_set(index);
+       if (!p_resample) {
+               pr_info("audio resample is not init\n");
+               return 0;
+       }
+
+       resample_set(p_resample->id, index);
 
        return 0;
 }
@@ -289,9 +335,13 @@ static const char *const auge_resample_module_texts[] = {
        "TDMIN_C",
        "SPDIFIN",
        "PDMIN",
-       "NONE",
+       "FRATV", /* NONE for axg, g12a, g12b */
        "TDMIN_LB",
-       "LOOPBACK",
+       "LOOPBACK_A",
+       "FRHDMIRX", /* from tl1 chipset*/
+       "LOOPBACK_B",
+       "SPDIFIN_LB",
+       "VAD",
 };
 
 static const struct soc_enum auge_resample_module_enum =
@@ -306,7 +356,7 @@ static int resample_module_get_enum(
 
        if (!p_resample) {
                pr_info("audio resample is not init\n");
-               return -EINVAL;
+               return 0;
        }
 
        ucontrol->value.enumerated.item[0] = p_resample->resample_module;
@@ -322,32 +372,52 @@ static int resample_module_set_enum(
 
        if (!p_resample) {
                pr_info("audio resample is not init\n");
-               return -EINVAL;
+               return 0;
        }
 
        p_resample->resample_module = ucontrol->value.enumerated.item[0];
 
        /* update info to ddr */
-       aml_resample_enable(p_resample->enable,
+       aml_set_resample(p_resample->id,
+               p_resample->enable,
                p_resample->resample_module);
 
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_resample_controls[] = {
+static const struct snd_kcontrol_new asrc_a_controls[] = {
        SOC_ENUM_EXT("Hardware resample enable",
                     auge_resample_enum,
                     resample_get_enum,
                     resample_set_enum),
        SOC_SINGLE_EXT_TLV("Hw resample pause enable",
-                        EE_AUDIO_RESAMPLE_CTRL2, 24, 0x1, 0,
+                        EE_AUDIO_RESAMPLEA_CTRL2, 24, 0x1, 0,
                         mixer_audiobus_read, mixer_audiobus_write,
                         NULL),
        SOC_SINGLE_EXT_TLV("Hw resample pause thd",
-                        EE_AUDIO_RESAMPLE_CTRL2, 0, 0xffffff, 0,
+                        EE_AUDIO_RESAMPLEA_CTRL2, 0, 0xffffff, 0,
+                        mixer_audiobus_read, mixer_audiobus_write,
+                        NULL),
+       SOC_ENUM_EXT("Hw resample module",
+                    auge_resample_module_enum,
+                    resample_module_get_enum,
+                    resample_module_set_enum),
+};
+
+static const struct snd_kcontrol_new asrc_b_controls[] = {
+       SOC_ENUM_EXT("Hardware resample b enable",
+                    auge_resample_enum,
+                    resample_get_enum,
+                    resample_set_enum),
+       SOC_SINGLE_EXT_TLV("Hw resample b pause enable",
+                        EE_AUDIO_RESAMPLEB_CTRL2, 24, 0x1, 0,
+                        mixer_audiobus_read, mixer_audiobus_write,
+                        NULL),
+       SOC_SINGLE_EXT_TLV("Hw resample b pause thd",
+                        EE_AUDIO_RESAMPLEB_CTRL2, 0, 0xffffff, 0,
                         mixer_audiobus_read, mixer_audiobus_write,
                         NULL),
-       SOC_ENUM_EXT("Hardware resample module",
+       SOC_ENUM_EXT("Hw resample b module",
                     auge_resample_module_enum,
                     resample_module_get_enum,
                     resample_module_set_enum),
@@ -358,12 +428,24 @@ int card_add_resample_kcontrols(struct snd_soc_card *card)
        unsigned int idx;
        int err;
 
-       for (idx = 0; idx < ARRAY_SIZE(snd_resample_controls); idx++) {
-               err = snd_ctl_add(card->snd_card,
-                               snd_ctl_new1(&snd_resample_controls[idx],
-                                       s_resample));
-               if (err < 0)
-                       return err;
+       if (s_resample_a) {
+               for (idx = 0; idx < ARRAY_SIZE(asrc_a_controls); idx++) {
+                       err = snd_ctl_add(card->snd_card,
+                                       snd_ctl_new1(&asrc_a_controls[idx],
+                                               s_resample_a));
+                       if (err < 0)
+                               return err;
+               }
+       }
+
+       if (s_resample_b) {
+               for (idx = 0; idx < ARRAY_SIZE(asrc_b_controls); idx++) {
+                       err = snd_ctl_add(card->snd_card,
+                                       snd_ctl_new1(&asrc_b_controls[idx],
+                                               s_resample_b));
+                       if (err < 0)
+                               return err;
+               }
        }
 
        return 0;
@@ -373,6 +455,18 @@ static struct resample_chipinfo g12a_resample_chipinfo = {
        .dividor_fn = true,
 };
 
+static struct resample_chipinfo tl1_resample_a_chipinfo = {
+       .num        = 2,
+       .id         = RESAMPLE_A,
+       .dividor_fn = true,
+};
+
+static struct resample_chipinfo tl1_resample_b_chipinfo = {
+       .num        = 2,
+       .id         = RESAMPLE_B,
+       .dividor_fn = true,
+};
+
 static const struct of_device_id resample_device_id[] = {
        {
                .compatible = "amlogic, axg-resample",
@@ -381,6 +475,14 @@ static const struct of_device_id resample_device_id[] = {
                .compatible = "amlogic, g12a-resample",
                .data = &g12a_resample_chipinfo,
        },
+       {
+               .compatible = "amlogic, tl1-resample-a",
+               .data = &tl1_resample_a_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-resample-b",
+               .data = &tl1_resample_b_chipinfo,
+       },
        {}
 };
 MODULE_DEVICE_TABLE(of, resample_device_id);
@@ -408,6 +510,9 @@ static int resample_platform_probe(struct platform_device *pdev)
                of_device_get_match_data(dev);
        if (!p_chipinfo)
                dev_warn_once(dev, "check whether to update resample chipinfo\n");
+       else
+               p_resample->id = p_chipinfo->id;
+
        p_resample->chipinfo = p_chipinfo;
 
        ret = of_property_read_u32(pdev->dev.of_node, "resample_module",
@@ -458,8 +563,11 @@ static int resample_platform_probe(struct platform_device *pdev)
        }
 
        p_resample->dev = dev;
-       s_resample = p_resample;
-       dev_set_drvdata(&pdev->dev, p_resample);
+
+       if (p_chipinfo && p_chipinfo->id == 1)
+               s_resample_b = p_resample;
+       else
+               s_resample_a = p_resample;
 
        return 0;
 }
index d0bb722..a86c8c0 100644 (file)
@@ -19,5 +19,8 @@
 
 extern int card_add_resample_kcontrols(struct snd_soc_card *card);
 
-extern int resample_set(int index);
+extern int resample_set(int id, int index);
+
+extern int get_resample_module_num(void);
+
 #endif
index 0c40fea..0425c60 100644 (file)
@@ -40,35 +40,43 @@ static u32 resample_coef_parameters_table[7][5] = {
        {0x00800000, 0x0, 0x0, 0x0, 0x0},
 };
 
-void resample_enable(bool enable)
+void resample_enable(int id, bool enable)
 {
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0,
+       int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
+
+       audiobus_update_bits(reg,
                0x1 << 31,
                1 << 31);
 
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0,
+       audiobus_update_bits(reg,
                0x1 << 31,
                0 << 31);
 
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0,
+       audiobus_update_bits(reg,
                0x1 << 28,
                enable << 28);
 }
 
-int resample_init(int input_sr)
+int resample_init(int id, int input_sr)
 {
        u16 Avg_cnt_init = 0;
        unsigned int clk_rate = 167000000;//clk81;
+       int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
 
        if (input_sr)
                Avg_cnt_init = (u16)(clk_rate * 4 / input_sr);
        else
                pr_err("unsupport input sample rate:%d\n", input_sr);
 
-       pr_info("clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n",
-               clk_rate, input_sr, Avg_cnt_init);
+       pr_info("resample id:%d, clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n",
+               id,
+               clk_rate,
+               input_sr,
+               Avg_cnt_init);
 
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0,
+       audiobus_update_bits(reg,
                0x3 << 26 | 0x3ff << 16 | 0xffff << 0,
                0x0 << 26 | /* method0 */
                RESAMPLE_CNT_CONTROL << 16 |
@@ -77,23 +85,30 @@ int resample_init(int input_sr)
        return 0;
 }
 
-int resample_disable(void)
+int resample_disable(int id)
 {
-       audiobus_write(EE_AUDIO_RESAMPLE_CTRL0, 0);
+       int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
+
+       audiobus_write(reg, 0);
 
        return 0;
 }
 
-int resample_set_hw_param(int index)
+int resample_set_hw_param(int id, int index)
 {
-       int i;
+       int i, reg, offset;
 
+       offset = EE_AUDIO_RESAMPLEB_COEF0 - EE_AUDIO_RESAMPLEA_COEF0;
+       reg = EE_AUDIO_RESAMPLEA_COEF0 + offset * id;
        for (i = 0; i < 5; i++) {
-               audiobus_write((EE_AUDIO_RESAMPLE_COEF0 + i),
+               audiobus_write((reg + i),
                        resample_coef_parameters_table[index][i]);
        }
 
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL2,
+       offset = EE_AUDIO_RESAMPLEB_CTRL2 - EE_AUDIO_RESAMPLEA_CTRL2;
+       reg = EE_AUDIO_RESAMPLEA_CTRL2 + offset * id;
+       audiobus_update_bits(reg,
                        1 << 25, 1 << 25);
 
        return 0;
@@ -101,23 +116,42 @@ int resample_set_hw_param(int index)
 
 void resample_src_select(int src)
 {
-       audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0,
+       audiobus_update_bits(EE_AUDIO_RESAMPLEA_CTRL0,
                0x3 << 29,
                src << 29);
 }
 
-void resample_format_set(int ch_num, int bits)
+void resample_src_select_ab(int id, int src)
 {
-       audiobus_write(EE_AUDIO_RESAMPLE_CTRL3,
+       int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id;
+
+       audiobus_update_bits(reg,
+               0x7 << 16,
+               src << 16);
+}
+
+void resample_format_set(int id, int ch_num, int bits)
+{
+       int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id;
+
+       audiobus_write(reg,
                ch_num << 8 | (bits - 1) << 0);
 }
 
-int resample_ctrl_read(int idx)
+int resample_ctrl_read(int id)
 {
-       return audiobus_read(EE_AUDIO_RESAMPLE_CTRL0);
+       int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
+
+       return audiobus_read(reg);
 }
 
-void resample_ctrl_write(int idx, int value)
+void resample_ctrl_write(int id, int value)
 {
-       audiobus_write(EE_AUDIO_RESAMPLE_CTRL0, value);
+       int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
+       int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
+
+       audiobus_write(reg, value);
 }
index e78be73..1ec4b16 100644 (file)
 #ifndef __AML_AUDIO_RESAMPLE_HW_H__
 #define __AML_AUDIO_RESAMPLE_HW_H__
 
-extern void resample_enable(bool enable);
-extern int resample_init(int input_sr);
-extern int resample_disable(void);
-extern int resample_set_hw_param(int index);
+extern void resample_enable(int id, bool enable);
+extern int resample_init(int id, int input_sr);
+extern int resample_disable(int id);
+extern int resample_set_hw_param(int id, int index);
 extern void resample_src_select(int src);
-extern void resample_format_set(int ch_num, int bits);
+extern void resample_src_select_ab(int id, int src);
+extern void resample_format_set(int id, int ch_num, int bits);
 
-extern int resample_ctrl_read(int idx);
-extern void resample_ctrl_write(int idx, int value);
+extern int resample_ctrl_read(int id);
+extern void resample_ctrl_write(int id, int value);
 
 #endif
index 2aa663b..ce5a88b 100644 (file)
@@ -68,6 +68,8 @@ struct spdif_chipinfo {
        bool hold_start;
        /* eq/drc */
        bool eq_drc_en;
+       /* pc, pd interrupt is separated. */
+       bool pcpd_separated;
 };
 
 struct aml_spdif {
@@ -93,10 +95,15 @@ struct aml_spdif {
        struct spdif_chipinfo *chipinfo;
        unsigned int clk_cont; /* CONTINUOUS CLOCK */
 
+       /*
+        * resample a/b do asrc for spdif in
+        */
+       unsigned int asrc_id;
        /* spdif in do asrc for pcm,
         * if raw data, disable it automatically.
         */
-        unsigned int auto_asrc;
+       unsigned int auto_asrc;
+
        /* check spdifin channel status for pcm or nonpcm */
        struct timer_list timer;
        struct work_struct work;
@@ -113,6 +120,9 @@ struct aml_spdif {
        int is_reset;
        int last_sample_rate_mode;
 
+       /* last value for pc, pd */
+       int pc_last;
+       int pd_last;
 };
 
 static const struct snd_pcm_hardware aml_spdif_hardware = {
@@ -226,7 +236,7 @@ static int spdifin_check_audio_type(void)
                }
        }
 
-       pr_info("%s audio type:%d\n", __func__, audio_type);
+       pr_debug("%s audio type:%d\n", __func__, audio_type);
 
        return audio_type;
 }
@@ -241,9 +251,27 @@ static int spdifin_audio_type_get_enum(
        return 0;
 }
 
+/* For fake */
+static bool is_mute;
+static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       is_mute =
+                       ucontrol->value.integer.value[0];
+       return 0;
+}
+
+static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.integer.value[0] = is_mute;
+
+       return 0;
+}
+
 static const struct snd_kcontrol_new snd_spdif_controls[] = {
 
-       SOC_ENUM_EXT("SPDIFIN Sample Rate", spdifin_sample_rate_enum,
+       SOC_ENUM_EXT("SPDIFIN audio samplerate", spdifin_sample_rate_enum,
                                spdifin_samplerate_get_enum,
                                NULL),
 
@@ -251,6 +279,16 @@ static const struct snd_kcontrol_new snd_spdif_controls[] = {
                         spdif_audio_type_enum,
                         spdifin_audio_type_get_enum,
                         NULL),
+
+       SOC_ENUM_EXT("Audio spdif format",
+                               spdif_format_enum,
+                               spdif_format_get_enum,
+                               spdif_format_set_enum),
+
+       SOC_SINGLE_BOOL_EXT("Audio spdif mute",
+                               0, aml_audio_get_spdif_mute,
+                               aml_audio_set_spdif_mute),
+
 };
 
 static bool spdifin_check_audiotype_by_sw(struct aml_spdif *p_spdif)
@@ -296,12 +334,16 @@ static void spdifin_audio_type_work_func(struct work_struct *work)
        if (!p_spdif->auto_asrc)
                return;
 
+#ifdef __PTM_SPDIF_CLK__
+       return;
+#endif
+
        if (val & 0x2)
                /* nonpcm, resample disable */
-               resample_set(0);
+               resample_set(p_spdif->asrc_id, 0);
        else
                /* pcm, resample which rate ? */
-               resample_set(p_spdif->auto_asrc);
+               resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
 }
 
 static void spdifin_audio_type_detect_init(struct aml_spdif *p_spdif)
@@ -334,13 +376,13 @@ static void spdifin_fast_reset(struct aml_spdif *p_spdif)
 
        /* resample disable and reset */
        if (p_spdif->auto_asrc) {
-               asr_ctrl_val = resample_ctrl_read(0);
+               asr_ctrl_val = resample_ctrl_read(p_spdif->asrc_id);
                asr_ctrl_val &= ~(1 << 28);
-               resample_ctrl_write(0, asr_ctrl_val);
+               resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val);
                asr_ctrl_val |= (1 << 31);
-               resample_ctrl_write(0, asr_ctrl_val);
+               resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val);
                asr_ctrl_val &= ~(1 << 31);
-               resample_ctrl_write(0, asr_ctrl_val);
+               resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val);
        }
 
        /* spdif in disable and reset */
@@ -364,7 +406,7 @@ static void spdifin_fast_reset(struct aml_spdif *p_spdif)
        /* resample enable */
        if (p_spdif->auto_asrc) {
                asr_ctrl_val |= (1 << 28);
-               resample_ctrl_write(0, asr_ctrl_val);
+               resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val);
        }
 
        /* spdif in enable */
@@ -485,7 +527,8 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
 
                                /* resample enable, by hw */
                                if (!spdifin_check_audiotype_by_sw(p_spdif))
-                                       resample_set(p_spdif->auto_asrc);
+                                       resample_set(p_spdif->asrc_id,
+                                               p_spdif->auto_asrc);
 
                                extcon_set_state(p_spdif->edev,
                                        EXTCON_SPDIFIN_SAMPLERATE, 1);
@@ -495,18 +538,42 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
 
        }
 
-       if (intrpt_status & 0x8) {
-               pr_info("Pc changed, try to read spdifin audio type\n");
+       if (p_spdif->chipinfo
+               && p_spdif->chipinfo->pcpd_separated) {
+               if (intrpt_status & 0x8) {
+                       pr_info("Pc changed, try to read spdifin audio type\n");
 
-               extcon_set_state(p_spdif->edev,
-                       EXTCON_SPDIFIN_AUDIOTYPE, 1);
+                       extcon_set_state(p_spdif->edev,
+                               EXTCON_SPDIFIN_AUDIOTYPE, 1);
 
-               /* resample disable, by hw */
-               if (!spdifin_check_audiotype_by_sw(p_spdif))
-                       resample_set(0);
+#ifdef __PTM_SPDIF_CLK__
+                       /* resample disable, by hw */
+                       if (!spdifin_check_audiotype_by_sw(p_spdif))
+                               resample_set(p_spdif->asrc_id, 0);
+#endif
+               }
+               if (intrpt_status & 0x10)
+                       pr_info("Pd changed\n");
+       } else {
+               if (intrpt_status & 0x8)
+                       pr_info("CH status changed\n");
+
+               if (intrpt_status & 0x10) {
+                       int val = spdifin_get_ch_status0to31();
+                       int pc_v = (val >> 16) & 0xffff;
+                       int pd_v = val & 0xffff;
+
+                       if (pc_v != p_spdif->pc_last) {
+                               p_spdif->pc_last = pc_v;
+                               pr_info("Pc changed\n");
+                       }
+                       if (pd_v != p_spdif->pd_last) {
+                               p_spdif->pd_last = pd_v;
+                               pr_info("Pd changed\n");
+                       }
+               }
        }
-       if (intrpt_status & 0x10)
-               pr_info("Pd changed\n");
+
        if (intrpt_status & 0x20) {
                pr_info("nonpcm to pcm\n");
                extcon_set_state(p_spdif->edev,
@@ -514,7 +581,7 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
 
                /* resample to 48k, by hw */
                if (!spdifin_check_audiotype_by_sw(p_spdif))
-                       resample_set(p_spdif->auto_asrc);
+                       resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
        }
        if (intrpt_status & 0x40)
                pr_info("valid changed\n");
@@ -814,10 +881,6 @@ static int aml_dai_spdif_startup(
        struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
        int ret;
 
-       pr_info("%s stream:%d\n",
-               __func__,
-               substream->stream);
-
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 
                if (p_spdif->clk_cont) {
@@ -873,7 +936,7 @@ static int aml_dai_spdif_startup(
                }
                /* resample to 48k in default, by hw */
                if (!spdifin_check_audiotype_by_sw(p_spdif))
-                       resample_set(p_spdif->auto_asrc);
+                       resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
        }
 
        return 0;
@@ -888,10 +951,6 @@ static void aml_dai_spdif_shutdown(
 {
        struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
 
-       pr_info("%s, stream:%d\n",
-               __func__,
-               substream->stream);
-
        /* disable clock and gate */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                if (p_spdif->clk_cont) {
@@ -906,7 +965,7 @@ static void aml_dai_spdif_shutdown(
        } else {
                /* resample disabled, by hw */
                if (!spdifin_check_audiotype_by_sw(p_spdif))
-                       resample_set(0);
+                       resample_set(p_spdif->asrc_id, 0);
 
                clk_disable_unprepare(p_spdif->clk_spdifin);
                clk_disable_unprepare(p_spdif->fixed_clk);
@@ -933,7 +992,7 @@ static int aml_dai_spdif_prepare(
 
                switch (p_spdif->id) {
                case 0:
-                       dst = SPDIFOUT;
+                       dst = SPDIFOUT_A;
                        break;
                case 1:
                        dst = SPDIFOUT_B;
@@ -944,6 +1003,8 @@ static int aml_dai_spdif_prepare(
                }
 
                fifo_id = aml_frddr_get_fifo_id(fr);
+               aml_frddr_set_format(fr, bit_depth - 1,
+                       spdifout_get_frddr_type(bit_depth));
                aml_frddr_select_dst(fr, dst);
                aml_frddr_set_fifos(fr, 0x40, 0x20);
 
@@ -1119,10 +1180,6 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
 {
        unsigned int mpll_freq = 0;
 
-       pr_info("%s, sys freq:%d\n",
-               __func__,
-               p_spdif->sysclk_freq);
-
        if (p_spdif->sysclk_freq) {
                unsigned int mul = 4;
                int ret;
@@ -1136,12 +1193,9 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
                mpll_freq = p_spdif->sysclk_freq * mul;
 
 #ifdef __PTM_SPDIF_CLK__
-               mpll_freq = p_spdif->sysclk_freq * 58;
+               /* mpll_freq = p_spdif->sysclk_freq * 58; */ /* 48k */
+               mpll_freq = p_spdif->sysclk_freq * 58 / 2; /* 96k */
 #endif
-               pr_info("\t finally sys freq:%d, mpll freq:%d\n",
-                       p_spdif->sysclk_freq,
-                       mpll_freq);
-
                clk_set_rate(p_spdif->sysclk, mpll_freq);
                clk_set_rate(p_spdif->clk_spdifout,
                        p_spdif->sysclk_freq);
@@ -1156,18 +1210,18 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
                        pr_err("Can't enable clk_spdifout clock: %d\n", ret);
                        return;
                }
+               pr_info("\t set spdifout clk:%d, mpll:%d\n",
+                       p_spdif->sysclk_freq,
+                       mpll_freq);
+               pr_info("\t get spdifout clk:%lu, mpll:%lu\n",
+                       clk_get_rate(p_spdif->clk_spdifout),
+                       clk_get_rate(p_spdif->sysclk));
        }
 }
 
 static int aml_dai_set_spdif_sysclk(struct snd_soc_dai *cpu_dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       pr_info("%s, clk_id:%d, freq:%d, dir:%d\n",
-               __func__,
-               clk_id,
-               freq,
-               dir);
-
        if (clk_id == 0) {
                struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
 
@@ -1298,11 +1352,18 @@ static int aml_spdif_parse_of(struct platform_device *pdev)
                        pr_err("SPDIF IN extcon failed to register!!, ignore it\n");
 
                ret = of_property_read_u32(pdev->dev.of_node,
+                                       "asrc_id", &p_spdif->asrc_id);
+               if (ret < 0)
+                       p_spdif->asrc_id = 0;
+
+               ret = of_property_read_u32(pdev->dev.of_node,
                                        "auto_asrc", &p_spdif->auto_asrc);
                if (ret < 0)
                        p_spdif->auto_asrc = 0;
-               pr_info("SPDIF id %d auto_asrc:%d\n",
+
+               pr_info("SPDIF id %d asrc_id:%d auto_asrc:%d\n",
                        p_spdif->id,
+                       p_spdif->asrc_id,
                        p_spdif->auto_asrc);
        }
 
@@ -1333,20 +1394,23 @@ struct spdif_chipinfo axg_spdif_chipinfo = {
        .id               = SPDIF_A,
        .irq_no_papb      = true,
        .clr_irq_all_bits = true,
+       .pcpd_separated   = true,
 };
 
 struct spdif_chipinfo g12a_spdif_a_chipinfo = {
-       .id           = SPDIF_A,
-       .chnum_en     = true,
-       .hold_start   = true,
-       .eq_drc_en    = true,
+       .id             = SPDIF_A,
+       .chnum_en       = true,
+       .hold_start     = true,
+       .eq_drc_en      = true,
+       .pcpd_separated = true,
 };
 
 struct spdif_chipinfo g12a_spdif_b_chipinfo = {
-       .id           = SPDIF_B,
-       .chnum_en     = true,
-       .hold_start   = true,
-       .eq_drc_en    = true,
+       .id             = SPDIF_B,
+       .chnum_en       = true,
+       .hold_start     = true,
+       .eq_drc_en      = true,
+       .pcpd_separated = true,
 };
 
 struct spdif_chipinfo tl1_spdif_a_chipinfo = {
index fedbac2..496036d 100644 (file)
@@ -179,6 +179,32 @@ void aml_spdif_fifo_reset(
        }
 }
 
+int spdifout_get_frddr_type(int bitwidth)
+{
+       unsigned int frddr_type = 0;
+
+       switch (bitwidth) {
+       case 8:
+               frddr_type = 0;
+               break;
+       case 16:
+               frddr_type = 1;
+               break;
+       case 24:
+               frddr_type = 4;
+               break;
+       case 32:
+               frddr_type = 3;
+               break;
+       default:
+               pr_err("runtime format invalid bitwidth: %d\n",
+                       bitwidth);
+               break;
+       }
+
+       return frddr_type;
+}
+
 void aml_spdif_fifo_ctrl(
        struct aml_audio_controller *actrl,
        int bitwidth,
@@ -186,23 +212,20 @@ void aml_spdif_fifo_ctrl(
        int index,
        unsigned int fifo_id)
 {
-       unsigned int frddr_type, toddr_type;
+       unsigned int toddr_type;
+       unsigned int frddr_type = spdifout_get_frddr_type(bitwidth);
 
        switch (bitwidth) {
        case 8:
-               frddr_type = 0;
                toddr_type = 0;
                break;
        case 16:
-               frddr_type = 1;
                toddr_type = 1;
                break;
        case 24:
-               frddr_type = 4;
                toddr_type = 4;
                break;
        case 32:
-               frddr_type = 3;
                toddr_type = 3;
                break;
        default:
@@ -336,7 +359,7 @@ void aml_spdifout_select_aed(bool enable, int spdifout_id)
        /* select eq_drc output */
        offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
        reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdifout_id;
-       audiobus_update_bits(reg, 0x1 << 31, enable << 31);
+       audiobus_update_bits(reg, 0x1 << 21, enable << 21);
 }
 
 void aml_spdifout_get_aed_info(int spdifout_id,
@@ -382,28 +405,9 @@ void spdifout_clk_ctrl(int spdif_id, bool is_enable)
 
 void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth)
 {
-       unsigned int frddr_type;
+       unsigned int frddr_type = spdifout_get_frddr_type(bitwidth);
        unsigned int offset, reg;
 
-       switch (bitwidth) {
-       case 8:
-               frddr_type = 0;
-               break;
-       case 16:
-               frddr_type = 1;
-               break;
-       case 24:
-               frddr_type = 4;
-               break;
-       case 32:
-               frddr_type = 3;
-               break;
-       default:
-               pr_err("runtime format invalid bitwidth: %d\n",
-                       bitwidth);
-               return;
-       }
-
        pr_info("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n",
                (spdif_id == 0) ? "a":"b",
                fifo_id,
index c2e529c..51d5e0b 100644 (file)
@@ -51,6 +51,8 @@ extern void aml_spdif_fifo_reset(
        struct aml_audio_controller *actrl,
        int stream, int index);
 
+extern int spdifout_get_frddr_type(int bitwidth);
+
 extern void aml_spdif_fifo_ctrl(
        struct aml_audio_controller *actrl,
        int bitwidth,
index d0d803a..50b0799 100644 (file)
@@ -349,7 +349,7 @@ static struct snd_pcm_ops aml_tdm_ops = {
        .mmap = aml_tdm_mmap,
 };
 
-#define PREALLOC_BUFFER                (32 * 1024)
+#define PREALLOC_BUFFER                (128 * 1024)
 #define PREALLOC_BUFFER_MAX    (256 * 1024)
 static int aml_tdm_new(struct snd_soc_pcm_runtime *rtd)
 {
@@ -444,6 +444,8 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream,
                                        p_tdm->id);
                        return -EINVAL;
                }
+               aml_frddr_set_format(fr, bit_depth - 1,
+                       tdmout_get_frddr_type(bit_depth));
                aml_frddr_select_dst(fr, dst);
                aml_frddr_set_fifos(fr, 0x40, 0x20);
        } else {
@@ -808,9 +810,6 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai,
        struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
        unsigned int ratio = aml_mpll_mclk_ratio(freq);
 
-       pr_info("aml_dai_set_tdm_sysclk freq(%d), mpll/mclk(%d)\n",
-               freq, ratio);
-
        p_tdm->setting.sysclk = freq;
 
 #ifdef __PTM_TDM_CLK__
@@ -825,6 +824,12 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai,
        clk_set_rate(p_tdm->clk, freq * ratio);
        clk_set_rate(p_tdm->mclk, freq);
 
+       pr_info("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n",
+               freq,
+               freq * ratio,
+               clk_get_rate(p_tdm->mclk),
+               clk_get_rate(p_tdm->clk));
+
        return 0;
 }
 
@@ -1066,7 +1071,7 @@ static struct snd_soc_dai_driver aml_tdm_dai[] = {
 };
 
 static const struct snd_soc_component_driver aml_tdm_component = {
-       .name        = DRV_NAME,
+       .name              = DRV_NAME,
 };
 
 struct tdm_chipinfo axg_tdma_chipinfo = {
index c720947..d1f23af 100644 (file)
@@ -141,13 +141,9 @@ void tdm_fifo_enable(int tdm_index, int is_enable)
        }
 }
 
-void aml_tdm_fifo_ctrl(
-       struct aml_audio_controller *actrl,
-       int bitwidth, int stream,
-       int index, unsigned int fifo_id)
+int tdmout_get_frddr_type(int bitwidth)
 {
-       unsigned int frddr_type;
-       unsigned int reg, offset;
+       unsigned int frddr_type = 0;
 
        switch (bitwidth) {
        case 8:
@@ -163,9 +159,20 @@ void aml_tdm_fifo_ctrl(
        default:
                pr_err("invalid bit_depth: %d\n",
                        bitwidth);
-               return;
+               break;
        }
 
+       return frddr_type;
+}
+
+void aml_tdm_fifo_ctrl(
+       struct aml_audio_controller *actrl,
+       int bitwidth, int stream,
+       int index, unsigned int fifo_id)
+{
+       unsigned int frddr_type = tdmout_get_frddr_type(bitwidth);
+       unsigned int reg, offset;
+
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                pr_debug("tdm prepare----playback\n");
                // from ddr, 63bit split into 2 samples
index fc5bcab..a7625b1 100644 (file)
@@ -72,6 +72,8 @@ extern void aml_tdm_fifo_reset(
        struct aml_audio_controller *actrl,
        int stream, int index);
 
+extern int tdmout_get_frddr_type(int bitwidth);
+
 extern void aml_tdm_fifo_ctrl(
        struct aml_audio_controller *actrl,
        int bitwidth, int stream,
index c4e9817..f8d4c7d 100644 (file)
@@ -24,8 +24,9 @@
 
 static spinlock_t aclk_lock;
 
-static const char *const mclk_parent_names[] = {"mpll0", "mpll1",
-       "mpll2", "mpll3", "hifi_pll", "fclk_div3", "fclk_div4", "gp0_pll"};
+static const char *const mclk_parent_names[] = {
+       "mpll0", "mpll1", "mpll2", "mpll3", "hifi_pll",
+       "fclk_div3", "fclk_div4", "fclk_div5"};
 
 static const char *const audioclk_parent_names[] = {
        "mclk_a", "mclk_b", "mclk_c", "mclk_d", "mclk_e",
@@ -105,38 +106,38 @@ static struct clk_gate *tl1_audio_clk_gates[] = {
 
 /* Array of all clocks provided by this provider */
 static struct clk_hw *tl1_audio_clk_hws[] = {
-       [CLKID_AUDIO_DDR_ARB]    = &audio_ddr_arb.hw,
-       [CLKID_AUDIO_PDM]        = &audio_pdm.hw,
-       [CLKID_AUDIO_TDMINA]     = &audio_tdmina.hw,
-       [CLKID_AUDIO_TDMINB]     = &audio_tdminb.hw,
-       [CLKID_AUDIO_TDMINC]     = &audio_tdminc.hw,
-       [CLKID_AUDIO_TDMINLB]    = &audio_tdminlb.hw,
-       [CLKID_AUDIO_TDMOUTA]    = &audio_tdmouta.hw,
-       [CLKID_AUDIO_TDMOUTB]    = &audio_tdmoutb.hw,
-       [CLKID_AUDIO_TDMOUTC]    = &audio_tdmoutc.hw,
-       [CLKID_AUDIO_FRDDRA]     = &audio_frddra.hw,
-       [CLKID_AUDIO_FRDDRB]     = &audio_frddrb.hw,
-       [CLKID_AUDIO_FRDDRC]     = &audio_frddrc.hw,
-       [CLKID_AUDIO_TODDRA]     = &audio_toddra.hw,
-       [CLKID_AUDIO_TODDRB]     = &audio_toddrb.hw,
-       [CLKID_AUDIO_TODDRC]     = &audio_toddrc.hw,
-       [CLKID_AUDIO_LOOPBACKA]  = &audio_loopbacka.hw,
-       [CLKID_AUDIO_SPDIFIN]    = &audio_spdifin.hw,
-       [CLKID_AUDIO_SPDIFOUT]   = &audio_spdifout.hw,
-       [CLKID_AUDIO_RESAMPLEA]  = &audio_resamplea.hw,
-       [CLKID_AUDIO_RESERVED0]  = &audio_reserved0.hw,
-       [CLKID_AUDIO_RESERVED1]  = &audio_reserved1.hw,
-       [CLKID_AUDIO_SPDIFOUTB]  = &audio_spdifoutb.hw,
-       [CLKID_AUDIO_EQDRC]      = &audio_eqdrc.hw,
-       [CLKID_AUDIO_RESAMPLEB]  = &audio_resampleb.hw,
-       [CLKID_AUDIO_TOVAD]      = &audio_tovad.hw,
-       [CLKID_AUDIO_AUDIOLOCKER] = &audio_audiolocker.hw,
-       [CLKID_AUDIO_SPDIFIN_LB] = &audio_spdifin_lb.hw,
-       [CLKID_AUDIO_FRATV]      = &audio_fratv.hw,
-       [CLKID_AUDIO_FRHDMIRX]   = &audio_frhdmirx.hw,
-       [CLKID_AUDIO_FRDDRD]     = &audio_frddrd.hw,
-       [CLKID_AUDIO_TODDRD]     = &audio_toddrd.hw,
-       [CLKID_AUDIO_LOOPBACKB]  = &audio_loopbackb.hw,
+       [CLKID_AUDIO_GATE_DDR_ARB]     = &audio_ddr_arb.hw,
+       [CLKID_AUDIO_GATE_PDM]         = &audio_pdm.hw,
+       [CLKID_AUDIO_GATE_TDMINA]      = &audio_tdmina.hw,
+       [CLKID_AUDIO_GATE_TDMINB]      = &audio_tdminb.hw,
+       [CLKID_AUDIO_GATE_TDMINC]      = &audio_tdminc.hw,
+       [CLKID_AUDIO_GATE_TDMINLB]     = &audio_tdminlb.hw,
+       [CLKID_AUDIO_GATE_TDMOUTA]     = &audio_tdmouta.hw,
+       [CLKID_AUDIO_GATE_TDMOUTB]     = &audio_tdmoutb.hw,
+       [CLKID_AUDIO_GATE_TDMOUTC]     = &audio_tdmoutc.hw,
+       [CLKID_AUDIO_GATE_FRDDRA]      = &audio_frddra.hw,
+       [CLKID_AUDIO_GATE_FRDDRB]      = &audio_frddrb.hw,
+       [CLKID_AUDIO_GATE_FRDDRC]      = &audio_frddrc.hw,
+       [CLKID_AUDIO_GATE_TODDRA]      = &audio_toddra.hw,
+       [CLKID_AUDIO_GATE_TODDRB]      = &audio_toddrb.hw,
+       [CLKID_AUDIO_GATE_TODDRC]      = &audio_toddrc.hw,
+       [CLKID_AUDIO_GATE_LOOPBACKA]   = &audio_loopbacka.hw,
+       [CLKID_AUDIO_GATE_SPDIFIN]     = &audio_spdifin.hw,
+       [CLKID_AUDIO_GATE_SPDIFOUT_A]  = &audio_spdifout.hw,
+       [CLKID_AUDIO_GATE_RESAMPLEA]   = &audio_resamplea.hw,
+       [CLKID_AUDIO_GATE_RESERVED0]   = &audio_reserved0.hw,
+       [CLKID_AUDIO_GATE_RESERVED1]   = &audio_reserved1.hw,
+       [CLKID_AUDIO_GATE_SPDIFOUT_B]  = &audio_spdifoutb.hw,
+       [CLKID_AUDIO_GATE_EQDRC]       = &audio_eqdrc.hw,
+       [CLKID_AUDIO_GATE_RESAMPLEB]   = &audio_resampleb.hw,
+       [CLKID_AUDIO_GATE_TOVAD]       = &audio_tovad.hw,
+       [CLKID_AUDIO_GATE_AUDIOLOCKER] = &audio_audiolocker.hw,
+       [CLKID_AUDIO_GATE_SPDIFIN_LB]  = &audio_spdifin_lb.hw,
+       [CLKID_AUDIO_GATE_FRATV]       = &audio_fratv.hw,
+       [CLKID_AUDIO_GATE_FRHDMIRX]    = &audio_frhdmirx.hw,
+       [CLKID_AUDIO_GATE_FRDDRD]      = &audio_frddrd.hw,
+       [CLKID_AUDIO_GATE_TODDRD]      = &audio_toddrd.hw,
+       [CLKID_AUDIO_GATE_LOOPBACKB]   = &audio_loopbackb.hw,
 };
 
 static int tl1_clk_gates_init(struct clk **clks, void __iomem *iobase)
@@ -189,6 +190,19 @@ CLOCK_COM_GATE(spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFIN_CTRL), 31);
 CLOCK_COM_MUX(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0x7, 24);
 CLOCK_COM_DIV(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0, 10);
 CLOCK_COM_GATE(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 31);
+/* audio resample_a */
+CLOCK_COM_MUX(resample_a,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0xf, 24);
+CLOCK_COM_DIV(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0, 8);
+CLOCK_COM_GATE(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 31);
+/* audio locker_out */
+CLOCK_COM_MUX(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24);
+CLOCK_COM_DIV(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 16, 8);
+CLOCK_COM_GATE(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31);
+/* audio locker_in */
+CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8);
+CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8);
+CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15);
 /* pdmin0 */
 CLOCK_COM_MUX(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0x7, 24);
 CLOCK_COM_DIV(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0, 16);
@@ -202,18 +216,24 @@ CLOCK_COM_MUX(spdifout_b,
        AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x7, 24);
 CLOCK_COM_DIV(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 10);
 CLOCK_COM_GATE(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31);
-/* audio locker_out */
-CLOCK_COM_MUX(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24);
-CLOCK_COM_DIV(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 16, 8);
-CLOCK_COM_GATE(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31);
-/* audio locker_in */
-CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8);
-CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8);
-CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15);
-/* audio resample */
-CLOCK_COM_MUX(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0xf, 24);
-CLOCK_COM_DIV(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0, 8);
-CLOCK_COM_GATE(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 31);
+/* audio resample_b */
+CLOCK_COM_MUX(resample_b,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0xf, 24);
+CLOCK_COM_DIV(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0, 8);
+CLOCK_COM_GATE(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 31);
+/* spdifin_lb, div is a fake */
+CLOCK_COM_MUX(spdifin_lb,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x1, 30);
+CLOCK_COM_DIV(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 29);
+CLOCK_COM_GATE(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31);
+/* audio eqdrc  */
+CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24);
+CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16);
+CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31);
+/* audio vad  */
+CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31);
 
 static int tl1_clks_init(struct clk **clks, void __iomem *iobase)
 {
@@ -242,12 +262,24 @@ static int tl1_clks_init(struct clk **clks, void __iomem *iobase)
        WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_F]));
 
        IOMAP_COM_CLK(spdifin, iobase);
-       clks[CLKID_AUDIO_SPDIFIN_CTRL] = REGISTER_CLK_COM(spdifin);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN_CTRL]));
+       clks[CLKID_AUDIO_SPDIFIN] = REGISTER_CLK_COM(spdifin);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN]));
 
        IOMAP_COM_CLK(spdifout, iobase);
-       clks[CLKID_AUDIO_SPDIFOUT_CTRL] = REGISTER_CLK_COM(spdifout);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_CTRL]));
+       clks[CLKID_AUDIO_SPDIFOUT_A] = REGISTER_CLK_COM(spdifout);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_A]));
+
+       IOMAP_COM_CLK(resample_a, iobase);
+       clks[CLKID_AUDIO_RESAMPLE_A] = REGISTER_AUDIOCLK_COM(resample_a);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_A]));
+
+       IOMAP_COM_CLK(locker_out, iobase);
+       clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT]));
+
+       IOMAP_COM_CLK(locker_in, iobase);
+       clks[CLKID_AUDIO_LOCKER_IN] = REGISTER_AUDIOCLK_COM(locker_in);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_IN]));
 
        IOMAP_COM_CLK(pdmin0, iobase);
        clks[CLKID_AUDIO_PDMIN0] = REGISTER_CLK_COM(pdmin0);
@@ -258,20 +290,24 @@ static int tl1_clks_init(struct clk **clks, void __iomem *iobase)
        WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_PDMIN1]));
 
        IOMAP_COM_CLK(spdifout_b, iobase);
-       clks[CLKID_AUDIO_SPDIFOUTB_CTRL] = REGISTER_CLK_COM(spdifout_b);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUTB_CTRL]));
+       clks[CLKID_AUDIO_SPDIFOUT_B] = REGISTER_CLK_COM(spdifout_b);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_B]));
 
-       IOMAP_COM_CLK(locker_out, iobase);
-       clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT]));
+       IOMAP_COM_CLK(resample_b, iobase);
+       clks[CLKID_AUDIO_RESAMPLE_B] = REGISTER_AUDIOCLK_COM(resample_b);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_B]));
 
-       IOMAP_COM_CLK(locker_in, iobase);
-       clks[CLKID_AUDIO_LOCKER_IN] = REGISTER_AUDIOCLK_COM(locker_in);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_IN]));
+       IOMAP_COM_CLK(spdifin_lb, iobase);
+       clks[CLKID_AUDIO_SPDIFIN_LB] = REGISTER_CLK_COM(spdifin_lb);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN_LB]));
+
+       IOMAP_COM_CLK(eqdrc, iobase);
+       clks[CLKID_AUDIO_EQDRC] = REGISTER_CLK_COM(eqdrc);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_EQDRC]));
 
-       IOMAP_COM_CLK(resample, iobase);
-       clks[CLKID_AUDIO_RESAMPLE_CTRL] = REGISTER_AUDIOCLK_COM(resample);
-       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_CTRL]));
+       IOMAP_COM_CLK(vad, iobase);
+       clks[CLKID_AUDIO_VAD] = REGISTER_CLK_COM(vad);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_VAD]));
 
        return 0;
 }
index aea732a..41087df 100644 (file)
@@ -1 +1,3 @@
-obj-y += notify.o spdif_info.o
+obj-y += notify.o \
+       spdif_info.o \
+       misc.o
diff --git a/sound/soc/amlogic/common/misc.c b/sound/soc/amlogic/common/misc.c
new file mode 100644 (file)
index 0000000..42d7e23
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * sound/soc/amlogic/common/misc.c
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/amlogic/media/sound/misc.h>
+
+#ifdef CONFIG_AMLOGIC_ATV_DEMOD
+#include <linux/amlogic/aml_atvdemod.h>
+#endif
+
+#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
+#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#endif
+
+static const char *const audio_is_stable[] = {
+       "false",
+       "true"
+};
+
+#ifdef CONFIG_AMLOGIC_ATV_DEMOD
+
+const struct soc_enum atv_audio_status_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(audio_is_stable),
+                       audio_is_stable);
+
+int aml_get_atv_audio_stable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int state = 0;
+
+       aml_fe_get_atvaudio_state(&state);
+       ucontrol->value.integer.value[0] = state;
+       return 0;
+}
+#endif /* CONFIG_AMLOGIC_ATV_DEMOD */
+
+#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
+int hdmiin_fifo_disable_count;
+
+int get_hdmi_sample_rate_index(void)
+{
+       struct rx_audio_stat_s aud_sts;
+       int val = 0;
+
+       rx_get_audio_status(&aud_sts);
+       switch (aud_sts.aud_sr) {
+       case 0:
+               val = 0;
+               break;
+       case 32000:
+               val = 1;
+               break;
+       case 44100:
+               val = 2;
+               break;
+       case 48000:
+               val = 3;
+               break;
+       case 88200:
+               val = 4;
+               break;
+       case 96000:
+               val = 5;
+               break;
+       case 176400:
+               val = 6;
+               break;
+       case 192000:
+               val = 7;
+               break;
+       default:
+               pr_err("HDMIRX samplerate not support: %d\n",
+                       aud_sts.aud_sr);
+               break;
+       }
+       return val;
+}
+
+int update_spdifin_audio_type(int audio_type)
+{
+       struct rx_audio_stat_s aud_sts;
+
+       rx_get_audio_status(&aud_sts);
+       if (aud_sts.afifo_thres_pass == true)
+               hdmiin_fifo_disable_count = 0;
+       else
+               hdmiin_fifo_disable_count++;
+       if (hdmiin_fifo_disable_count > 200)
+               audio_type = 6/*PAUSE*/;
+
+       return audio_type;
+}
+
+static const char *const hdmi_in_samplerate[] = {
+       "N/A",
+       "32000",
+       "44100",
+       "48000",
+       "88200",
+       "96000",
+       "176400",
+       "192000"
+};
+
+static const char *const hdmi_in_channels[] = {
+       "NONE",
+       "2",
+       "3",
+       "4",
+       "5",
+       "6",
+       "7",
+       "8"
+};
+
+enum HDMIIN_format {
+       REFER_TO_HEADER = 0,
+       LPCM = 1,
+       AC3,
+       MPEG1,
+       MP3,
+       MPEG2,
+       AAC,
+       DTS,
+       ATRAC,
+       ONE_BIT_AUDIO,
+       DDP,
+       DTS_HD,
+       MAT,
+       DST,
+       WMA_PRO
+};
+
+static const char * const hdmi_in_format[] = {
+       "REFER_TO_HEADER",
+       "LPCM",
+       "AC3",
+       "MPEG1",
+       "MP3",
+       "MPEG2",
+       "AAC",
+       "DTS",
+       "ATRAC",
+       "ONE_BIT_AUDIO",
+       "DDP",
+       "DTS_HD",
+       "MAT",
+       "DST",
+       "WMA_PRO"
+};
+
+const struct soc_enum hdmi_in_status_enum[] = {
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(audio_is_stable),
+                       audio_is_stable),
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_samplerate),
+                       hdmi_in_samplerate),
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_channels),
+                       hdmi_in_channels),
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_format),
+                       hdmi_in_format)
+};
+
+int aml_get_hdmiin_audio_stable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct rx_audio_stat_s aud_sts;
+
+       rx_get_audio_status(&aud_sts);
+       ucontrol->value.integer.value[0] = aud_sts.aud_rcv_flag;
+
+       return 0;
+}
+
+int aml_get_hdmiin_audio_samplerate(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int val = get_hdmi_sample_rate_index();
+
+       ucontrol->value.integer.value[0] = val;
+
+       return 0;
+}
+
+int aml_get_hdmiin_audio_channels(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct rx_audio_stat_s aud_sts;
+
+       rx_get_audio_status(&aud_sts);
+       if (aud_sts.aud_channel_cnt <= 7)
+               ucontrol->value.integer.value[0] = aud_sts.aud_channel_cnt;
+
+       return 0;
+}
+
+int aml_get_hdmiin_audio_format(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct rx_audio_stat_s aud_sts;
+
+       rx_get_audio_status(&aud_sts);
+       if (aud_sts.aud_type <= 14)
+               ucontrol->value.integer.value[0] = aud_sts.aud_type;
+
+       return 0;
+}
+
+/* call HDMI CEC API to enable arc audio */
+int aml_set_atmos_audio_edid(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       bool enable = ucontrol->value.integer.value[0];
+
+       rx_set_atmos_flag(enable);
+
+       return 0;
+}
+
+int aml_get_atmos_audio_edid(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       bool flag = rx_get_atmos_flag();
+
+       ucontrol->value.integer.value[0] = flag;
+
+       return 0;
+}
+
+#endif
index 32830a0..c900c5f 100644 (file)
@@ -158,3 +158,35 @@ void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream)
                                substream);
        }
 }
+
+static const char *const spdif_format_texts[10] = {
+       "2 CH PCM", "DTS RAW Mode", "Dolby Digital", "DTS",
+       "DD+", "DTS-HD", "Multi-channel LPCM", "TrueHD", "DTS-HD MA",
+       "HIGH SR Stereo LPCM"
+};
+
+const struct soc_enum spdif_format_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_format_texts),
+                       spdif_format_texts);
+
+int spdif_format_get_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.enumerated.item[0] = IEC958_mode_codec;
+       return 0;
+}
+
+int spdif_format_set_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       int index = ucontrol->value.enumerated.item[0];
+
+       if (index >= 10) {
+               pr_err("bad parameter for spdif format set\n");
+               return -1;
+       }
+       IEC958_mode_codec = index;
+       return 0;
+}
index 6dc6751..299c46c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_ext.h>
 #endif
 #include "spdif_dai.h"
+#include <linux/amlogic/media/sound/spdif_info.h>
 
 #define DRV_NAME "spdif-dit"
 
@@ -164,38 +165,6 @@ static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const char *const spdif_format_texts[10] = {
-       "2 CH PCM", "DTS RAW Mode", "Dolby Digital", "DTS",
-       "DD+", "DTS-HD", "Multi-channel LPCM", "TrueHD", "DTS-HD MA",
-       "HIGH SR Stereo LPCM"
-};
-
-static const struct soc_enum spdif_format_enum =
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_format_texts),
-                       spdif_format_texts);
-
-static int spdif_format_get_enum(
-       struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       ucontrol->value.enumerated.item[0] = IEC958_mode_codec;
-       return 0;
-}
-
-static int spdif_format_set_enum(
-       struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       int index = ucontrol->value.enumerated.item[0];
-
-       if (index >= 10) {
-               pr_err("bad parameter for spdif format set\n");
-               return -1;
-       }
-       IEC958_mode_codec = index;
-       return 0;
-}
-
 #ifdef CONFIG_AMLOGIC_HDMITX
 /* call HDMITX API to enable/disable internal audio out */
 static int aml_get_hdmi_out_audio(struct snd_kcontrol *kcontrol,
index 137c178..6c184fd 100644 (file)
@@ -50,9 +50,8 @@
 #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
 #include <linux/amlogic/media/frame_provider/tvin/tvin.h>
 #endif
-#ifdef CONFIG_AMLOGIC_ATV_DEMOD
-#include <linux/amlogic/aml_atvdemod.h>
-#endif
+
+#include <linux/amlogic/media/sound/misc.h>
 
 #include "i2s.h"
 #include "audio_hw.h"
 #define AML_EQ_PARAM_LENGTH 100
 #define AML_DRC_PARAM_LENGTH 12
 #define AML_REG_BYTES 4
-#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
-static int hdmiin_fifo_disable_count;
-
-/* copy from drivers/amlogic/tvin/hdmirx/hdmirx_drv.h */
-struct hdmi_in_audio_status {
-       /*audio packets received*/
-       bool aud_rcv_flag;
-       /*audio stable status*/
-       bool aud_stb_flag;
-       /*audio sample rate*/
-       int aud_sr;
-       /*audio channel count*/
-       /*0: refer to stream header,*/
-       /*1: 2ch, 2: 3ch, 3: 4ch, 4: 5ch,*/
-       /*5: 6ch, 6: 7ch, 7: 8ch*/
-       int aud_channel_cnt;
-       /*audio coding type*/
-       /*0: refer to stream header, 1: IEC60958 PCM,*/
-       /*2: AC-3, 3: MPEG1 (Layers 1 and 2),*/
-       /*4: MP3 (MPEG1 Layer 3), 5: MPEG2 (multichannel),*/
-       /*6: AAC, 7: DTS, 8: ATRAC, 9: One Bit Audio,*/
-       /*10: Dolby Digital Plus, 11: DTS-HD,*/
-       /*12: MAT (MLP), 13: DST, 14: WMA Pro*/
-       int aud_type;
-       /* indicate if audio FIFO start threshold is crossed */
-       bool afifo_thres_pass;
-};
-#endif
 
 static u32 aml_EQ_table[AML_EQ_PARAM_LENGTH] = {
        /*channel 1 param*/
@@ -189,48 +160,6 @@ static int get_spdif_sample_rate_index(void)
        return index;
 }
 
-#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
-static int get_hdmi_sample_rate_index(void)
-{
-       struct hdmi_in_audio_status aud_sts;
-       struct rx_audio_stat_s *rx_aud_sts;
-       int val = 0;
-
-       rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
-       rx_get_audio_status(rx_aud_sts);
-       switch (aud_sts.aud_sr) {
-       case 0:
-               val = 0;
-               break;
-       case 32000:
-               val = 1;
-               break;
-       case 44100:
-               val = 2;
-               break;
-       case 48000:
-               val = 3;
-               break;
-       case 88200:
-               val = 4;
-               break;
-       case 96000:
-               val = 5;
-               break;
-       case 176400:
-               val = 6;
-               break;
-       case 192000:
-               val = 7;
-               break;
-       default:
-               pr_err("HDMIRX samplerate not support: %d\n", aud_sts.aud_sr);
-               break;
-       }
-       return val;
-}
-#endif
-
 static const char *const audio_in_source_texts[] = {
        "LINEIN", "ATV", "HDMI", "SPDIFIN" };
 
@@ -372,18 +301,9 @@ static int aml_get_spdif_audio_type(
        /* HDMI in,also check the hdmirx  fifo status*/
 #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
        if (audio_in_source == 2) {
-               struct hdmi_in_audio_status aud_sts;
-               struct rx_audio_stat_s *rx_aud_sts;
                int index = 0;
 
-               rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
-               rx_get_audio_status(rx_aud_sts);
-               if (aud_sts.afifo_thres_pass == true)
-                       hdmiin_fifo_disable_count = 0;
-               else
-                       hdmiin_fifo_disable_count++;
-               if (hdmiin_fifo_disable_count > 200)
-                       audio_type = 6/*PAUSE*/;
+               update_spdifin_audio_type(audio_type);
 
                index = get_hdmi_sample_rate_index();
                if (p_aml_audio &&
@@ -642,161 +562,6 @@ static int aml_set_arc_audio(struct snd_kcontrol *kcontrol,
 }
 #endif
 
-#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
-/* call HDMI CEC API to enable arc audio */
-static int aml_set_atmos_audio_edid(struct snd_kcontrol *kcontrol,
-                         struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-       struct aml_audio_private_data *p_aml_audio;
-       bool enable = ucontrol->value.integer.value[0];
-
-       p_aml_audio = snd_soc_card_get_drvdata(card);
-       rx_set_atmos_flag(enable);
-       p_aml_audio->atmos_edid_enable = enable;
-       return 0;
-}
-static int aml_get_atmos_audio_edid(struct snd_kcontrol *kcontrol,
-                         struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-       struct aml_audio_private_data *p_aml_audio;
-
-       p_aml_audio = snd_soc_card_get_drvdata(card);
-       ucontrol->value.integer.value[0] = p_aml_audio->atmos_edid_enable;
-       return 0;
-}
-;
-static const char *const hdmi_in_is_stable[] = {
-       "false",
-       "true"
-};
-static const char *const hdmi_in_samplerate[] = {
-       "N/A",
-       "32000",
-       "44100",
-       "48000",
-       "88200",
-       "96000",
-       "176400",
-       "192000"
-};
-static const char *const hdmi_in_channels[] = {
-       "NONE",
-       "2",
-       "3",
-       "4",
-       "5",
-       "6",
-       "7",
-       "8"
-};
-enum HDMIIN_format {
-       REFER_TO_HEADER = 0,
-       LPCM = 1,
-       AC3,
-       MPEG1,
-       MP3,
-       MPEG2,
-       AAC,
-       DTS,
-       ATRAC,
-       ONE_BIT_AUDIO,
-       DDP,
-       DTS_HD,
-       MAT,
-       DST,
-       WMA_PRO
-};
-static const char * const hdmi_in_format[] = {
-       "REFER_TO_HEADER",
-       "LPCM",
-       "AC3",
-       "MPEG1",
-       "MP3",
-       "MPEG2",
-       "AAC",
-       "DTS",
-       "ATRAC",
-       "ONE_BIT_AUDIO",
-       "DDP",
-       "DTS_HD",
-       "MAT",
-       "DST",
-       "WMA_PRO"
-};
-static const struct soc_enum hdmi_in_status_enum[] = {
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_is_stable),
-                       hdmi_in_is_stable),
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_samplerate),
-                       hdmi_in_samplerate),
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_channels),
-                       hdmi_in_channels),
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_format),
-                       hdmi_in_format)
-};
-static int aml_get_hdmiin_audio_stable(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
-{
-       struct hdmi_in_audio_status aud_sts;
-       struct rx_audio_stat_s *rx_aud_sts;
-
-       rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
-       rx_get_audio_status(rx_aud_sts);
-       ucontrol->value.integer.value[0] = aud_sts.aud_rcv_flag;
-       return 0;
-}
-static int aml_get_hdmiin_audio_samplerate(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
-{
-       int val = get_hdmi_sample_rate_index();
-       ucontrol->value.integer.value[0] = val;
-       return 0;
-}
-static int aml_get_hdmiin_audio_channels(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
-{
-       struct rx_audio_stat_s *rx_aud_sts;
-       struct hdmi_in_audio_status aud_sts;
-
-       rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
-       rx_get_audio_status(rx_aud_sts);
-       if (aud_sts.aud_channel_cnt <= 7)
-               ucontrol->value.integer.value[0] = aud_sts.aud_channel_cnt;
-       return 0;
-}
-static int aml_get_hdmiin_audio_format(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
-{
-       struct rx_audio_stat_s *rx_aud_sts;
-       struct hdmi_in_audio_status aud_sts;
-
-       rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
-       rx_get_audio_status(rx_aud_sts);
-       if (aud_sts.aud_type <= 14)
-               ucontrol->value.integer.value[0] = aud_sts.aud_type;
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_AMLOGIC_ATV_DEMOD
-static const char *const atv_audio_is_stable[] = {
-       "false",
-       "true"
-};
-static const struct soc_enum atv_audio_status_enum =
-       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(atv_audio_is_stable),
-                       atv_audio_is_stable);
-static int aml_get_atv_audio_stable(struct snd_kcontrol *kcontrol,
-                       struct snd_ctl_elem_value *ucontrol)
-{
-       int state = 0;
-
-       aml_fe_get_atvaudio_state(&state);
-       ucontrol->value.integer.value[0] = state;
-       return 0;
-}
-#endif /* CONFIG_AMLOGIC_ATV_DEMOD */
 #ifdef CONFIG_TVIN_VDIN
 static const char *const av_audio_is_stable[] = {
        "false",
index cdd6017..401f75e 100644 (file)
@@ -71,9 +71,6 @@ struct aml_audio_private_data {
 #ifdef CONFIG_AMLOGIC_AO_CEC
        int arc_enable;
 #endif
-#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
-       int atmos_edid_enable;
-#endif
        int Hardware_resample_enable;
        int spdif_sample_rate_index;
        int hdmi_sample_rate_index;
@@ -100,6 +97,4 @@ extern int External_Mute(int mute_flag);
 #else
 int External_Mute(int mute_flag) { return 0; }
 #endif
-extern void rx_set_atmos_flag(bool en);
-extern void rx_get_atmos_flag(void);
 #endif