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
size = <16>;
};
};
+
+ audio_data: audio_data {
+ compatible = "amlogic, audio_data";
+ query_licence_cmd = <0x82000050>;
+ status = "disabled";
+ };
}; /* end of / */
&pinctrl_aobus {
/* 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 {
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 {
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";
*
*/
-#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__ */
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
--- /dev/null
+/*
+ * 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
#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;
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
resample_hw.o \
effects.o \
effects_hw.o \
+ effects_v2.o \
+ effects_hw_v2.o \
pwrdet.o \
pwrdet_hw.o \
sharebuffer.o \
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;
}
#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>
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));
{
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);
+}
extern void fratv_enable(bool enable);
extern void fratv_src_select(int src);
+
+extern void cec_arc_enable(int src, bool enable);
#endif
}
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);
#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"
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
* 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
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;
struct toddr_attach {
bool enable;
+ int id;
int status;
/* which module should be attached,
* check which toddr in use should be attached
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;
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;
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))
if (loopback_check_enable(src)) {
loopback_set_status(1);
to->is_lb = 1; /* in loopback */
- src = LOOPBACK;
+ src = LOOPBACK_A;
}
if (to->chipinfo
}
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)
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;
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;
}
}
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)
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)) {
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)
/* 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);
}
}
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 =
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,
};
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,
};
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);
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);
"TDMOUT_A",
"TDMOUT_B",
"TDMOUT_C",
- "SPDIFOUT",
+ "SPDIFOUT_A",
"SPDIFOUT_B",
};
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;
}
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;
}
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",
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;
}
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) {
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;
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);
}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 */
+};
--- /dev/null
+/*
+ * 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);
--- /dev/null
+/*
+ * 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
#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)
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;
},
};
+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,
};
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);
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,
{
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
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 */
);
}
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;
IO_AUDIO_LOCKER,
IO_EQDRC_BUS,
IO_RESET,
+ IO_VAD,
IO_MAX,
};
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
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;
}
}
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;
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[] = {
(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);
+}
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;
#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
#define EE_RESET1 0x002
/*
+ * HIU, ARC
+ */
+#define HHI_HDMIRX_ARC_CNTL 0xe8
+
+/*
* AUDIO MUX CONTROLS
*/
#define EE_AUDIO_TOACODEC_CTRL0 0x1d0
#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
#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
#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
*/
#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
#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;
};
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)
{
}
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,
{
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;
}
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;
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;
}
"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 =
if (!p_resample) {
pr_info("audio resample is not init\n");
- return -EINVAL;
+ return 0;
}
ucontrol->value.enumerated.item[0] = p_resample->resample_module;
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),
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;
.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",
.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);
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",
}
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;
}
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
{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 |
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;
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);
}
#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
bool hold_start;
/* eq/drc */
bool eq_drc_en;
+ /* pc, pd interrupt is separated. */
+ bool pcpd_separated;
};
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;
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 = {
}
}
- pr_info("%s audio type:%d\n", __func__, audio_type);
+ pr_debug("%s audio type:%d\n", __func__, audio_type);
return audio_type;
}
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),
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)
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)
/* 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 */
/* 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 */
/* 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);
}
- 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,
/* 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");
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) {
}
/* 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;
{
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) {
} 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);
switch (p_spdif->id) {
case 0:
- dst = SPDIFOUT;
+ dst = SPDIFOUT_A;
break;
case 1:
dst = SPDIFOUT_B;
}
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);
{
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;
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);
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);
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);
}
.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 = {
}
}
+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,
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:
/* 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,
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,
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,
.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)
{
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 {
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__
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;
}
};
static const struct snd_soc_component_driver aml_tdm_component = {
- .name = DRV_NAME,
+ .name = DRV_NAME,
};
struct tdm_chipinfo axg_tdma_chipinfo = {
}
}
-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:
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
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,
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",
/* 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)
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);
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)
{
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);
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;
}
-obj-y += notify.o spdif_info.o
+obj-y += notify.o \
+ spdif_info.o \
+ misc.o
--- /dev/null
+/*
+ * 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
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;
+}
#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"
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,
#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*/
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" };
/* 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 &&
}
#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",
#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;
#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