mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
audio: auge: add loopback driver [1/1]
PD#SWPL-7240 Problem: limit of current loopback add loopback b for tl1 add tdmin_lb Solution: 1. merge sm1, tm2 audio bringup code 2. optimize loopback driver Verify: s400, u200, x301, ac200, ab301 Change-Id: I0b01208fe8a213766e5563fa91b66e93c748d843 Signed-off-by: Lei Qian <lei.qian@amlogic.com>
This commit is contained in:
@@ -319,6 +319,51 @@
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
#if 0
|
||||
aml-audio-card,dai-link@7 {
|
||||
format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
//continuous-clock;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&tdmlb>;
|
||||
frame-master = <&tdmlb>;
|
||||
cpu {
|
||||
sound-dai = <&tdmlb>;
|
||||
dai-tdm-slot-rx-mask = <1 1>;
|
||||
dai-tdm-slot-num = <2>;
|
||||
dai-tdm-slot-width = <32>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
aml-audio-card,dai-link@8 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
aml-audio-card,dai-link@9 {
|
||||
mclk-fs = <256>;
|
||||
suffix-name = "alsaPORT-loopbackb";
|
||||
cpu {
|
||||
sound-dai = <&loopbackb>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Audio Related end */
|
||||
@@ -975,6 +1020,8 @@
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
/* !!!For --TV platform-- ONLY */
|
||||
@@ -996,6 +1043,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1014,6 +1063,57 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1209,10 +1309,120 @@
|
||||
* 0: in user space
|
||||
* 1: in kernel space
|
||||
*/
|
||||
level = <0>;
|
||||
level = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -423,6 +423,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
aml-audio-card,dai-link@8 {
|
||||
mclk-fs = <256>;
|
||||
suffix-name = "alsaPORT-loopbackb";
|
||||
cpu {
|
||||
sound-dai = <&loopbackb>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1273,6 +1296,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -1295,6 +1319,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1313,9 +1339,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1475,6 +1552,151 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vad:vad {
|
||||
compatible = "amlogic, snd-vad";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD
|
||||
&clkc CLKID_FCLK_DIV5
|
||||
&clkaudio CLKID_AUDIO_VAD>;
|
||||
clock-names = "gate", "pll", "clk";
|
||||
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_EDGE_RISING
|
||||
GIC_SPI 47 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "irq_wakeup", "irq_frame_sync";
|
||||
|
||||
/*
|
||||
* Data src sel:
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
* 5: loopback_b;
|
||||
* 6: tdmin_lb;
|
||||
* 7: loopback_a;
|
||||
*/
|
||||
src = <4>;
|
||||
|
||||
/*
|
||||
* deal with hot word in user space or kernel space
|
||||
* 0: in user space
|
||||
* 1: in kernel space
|
||||
*/
|
||||
level = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -323,6 +323,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -977,6 +989,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -999,6 +1012,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1017,9 +1032,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1213,6 +1279,116 @@
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -443,6 +443,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1542,6 +1554,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -1564,6 +1577,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1582,9 +1597,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1777,6 +1843,116 @@
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -433,6 +433,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
aml-audio-card,dai-link@8 {
|
||||
mclk-fs = <256>;
|
||||
suffix-name = "alsaPORT-loopbackb";
|
||||
cpu {
|
||||
sound-dai = <&loopbackb>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1464,6 +1487,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -1486,6 +1510,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1504,9 +1530,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1665,6 +1742,151 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vad:vad {
|
||||
compatible = "amlogic, snd-vad";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD
|
||||
&clkc CLKID_FCLK_DIV5
|
||||
&clkaudio CLKID_AUDIO_VAD>;
|
||||
clock-names = "gate", "pll", "clk";
|
||||
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_EDGE_RISING
|
||||
GIC_SPI 47 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "irq_wakeup", "irq_frame_sync";
|
||||
|
||||
/*
|
||||
* Data src sel:
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
* 5: loopback_b;
|
||||
* 6: tdmin_lb;
|
||||
* 7: loopback_a;
|
||||
*/
|
||||
src = <4>;
|
||||
|
||||
/*
|
||||
* deal with hot word in user space or kernel space
|
||||
* 0: in user space
|
||||
* 1: in kernel space
|
||||
*/
|
||||
level = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -440,6 +440,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1350,6 +1362,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -1372,6 +1385,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1390,9 +1405,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1550,6 +1616,151 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vad:vad {
|
||||
compatible = "amlogic, snd-vad";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD
|
||||
&clkc CLKID_FCLK_DIV5
|
||||
&clkaudio CLKID_AUDIO_VAD>;
|
||||
clock-names = "gate", "pll", "clk";
|
||||
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_EDGE_RISING
|
||||
GIC_SPI 47 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "irq_wakeup", "irq_frame_sync";
|
||||
|
||||
/*
|
||||
* Data src sel:
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
* 5: loopback_b;
|
||||
* 6: tdmin_lb;
|
||||
* 7: loopback_a;
|
||||
*/
|
||||
src = <4>;
|
||||
|
||||
/*
|
||||
* deal with hot word in user space or kernel space
|
||||
* 0: in user space
|
||||
* 1: in kernel space
|
||||
*/
|
||||
level = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -434,6 +434,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@7 {
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
suffix-name = "alsaPORT-loopback";
|
||||
cpu {
|
||||
sound-dai = <&loopbacka>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1344,6 +1356,7 @@
|
||||
|
||||
/* In for ACODEC_ADC */
|
||||
acodec_adc = <1>;
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -1366,6 +1379,8 @@
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1384,9 +1399,60 @@
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmout_c &tdmin_c>;
|
||||
|
||||
mclk_pad = <0>; /* 0: mclk_0; 1: mclk_1 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
tdmlb:tdm@3 {
|
||||
compatible = "amlogic, tl1-snd-tdmlb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
dai-tdm-lane-lb-slot-mask-in = <1 0 0 0>;
|
||||
dai-tdm-clk-sel = <1>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_B
|
||||
&clkc CLKID_MPLL1>;
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
|
||||
/*
|
||||
* select tdmin_lb src;
|
||||
* AXG
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA
|
||||
* 4: PAD_TDMINB
|
||||
* 5: PAD_TDMINC
|
||||
*
|
||||
* G12A/G12B
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*, oe pin
|
||||
* 7: PAD_TDMINB_D*, oe pin
|
||||
*
|
||||
* TL1
|
||||
* 0: TDMOUTA
|
||||
* 1: TDMOUTB
|
||||
* 2: TDMOUTC
|
||||
* 3: PAD_TDMINA_DIN*
|
||||
* 4: PAD_TDMINB_DIN*
|
||||
* 5: PAD_TDMINC_DIN*
|
||||
* 6: PAD_TDMINA_D*
|
||||
* 7: PAD_TDMINB_D*
|
||||
* 8: PAD_TDMINC_D*
|
||||
* 9: HDMIRX_I2S
|
||||
* 10: ACODEC_ADC
|
||||
*/
|
||||
lb-src-sel = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdifa:spdif@0 {
|
||||
compatible = "amlogic, tl1-snd-spdif-a";
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -1545,6 +1611,151 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vad:vad {
|
||||
compatible = "amlogic, snd-vad";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD
|
||||
&clkc CLKID_FCLK_DIV5
|
||||
&clkaudio CLKID_AUDIO_VAD>;
|
||||
clock-names = "gate", "pll", "clk";
|
||||
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_EDGE_RISING
|
||||
GIC_SPI 47 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "irq_wakeup", "irq_frame_sync";
|
||||
|
||||
/*
|
||||
* Data src sel:
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
* 5: loopback_b;
|
||||
* 6: tdmin_lb;
|
||||
* 7: loopback_a;
|
||||
*/
|
||||
src = <4>;
|
||||
|
||||
/*
|
||||
* deal with hot word in user space or kernel space
|
||||
* 0: in user space
|
||||
* 1: in kernel space
|
||||
*/
|
||||
level = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
loopbacka:loopback@0 {
|
||||
compatible = "amlogic, tl1-loopbacka";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* calc mclk for datalb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <0>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
loopbackb:loopback@1 {
|
||||
compatible = "amlogic, tl1-loopbackb";
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
clocks = <&clkaudio CLKID_AUDIO_GATE_PDM
|
||||
&clkc CLKID_FCLK_DIV3
|
||||
&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_PDMIN0
|
||||
&clkaudio CLKID_AUDIO_PDMIN1
|
||||
&clkc CLKID_MPLL0
|
||||
&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "pdm_gate",
|
||||
"pdm_sysclk_srcpll",
|
||||
"pdm_dclk_srcpll",
|
||||
"pdm_dclk",
|
||||
"pdm_sysclk",
|
||||
"tdminlb_mpll",
|
||||
"tdminlb_mclk";
|
||||
|
||||
/* calc mclk for datain_lb */
|
||||
mclk-fs = <256>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <4>;
|
||||
datain_chmask = <0xf>;
|
||||
/* config which data pin for loopback */
|
||||
datain-lane-mask-in = <1 0 1 0>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_TDMINA_DIN*, refer to core pinmux
|
||||
* 4: PAD_TDMINB_DIN*, refer to core pinmux
|
||||
* 5: PAD_TDMINC_DIN*, refer to core pinmux
|
||||
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
|
||||
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
|
||||
*/
|
||||
/* if tdmin_lb >= 3, use external loopback */
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
datalb_chmask = <0x3>;
|
||||
/* config which data pin as loopback */
|
||||
datalb-lane-mask-in = <1 0 0 0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
&pinctrl_periphs {
|
||||
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE) += audio_controller.o \
|
||||
pdm_hw_coeff.o \
|
||||
iomap.o \
|
||||
ddr_mngr.o \
|
||||
loopback.o \
|
||||
loopback_hw.o \
|
||||
audio_utils.o \
|
||||
locker.o \
|
||||
|
||||
@@ -14,24 +14,18 @@
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "audio_utils.h"
|
||||
#include "regs.h"
|
||||
#include "iomap.h"
|
||||
#include "loopback_hw.h"
|
||||
#include "spdif_hw.h"
|
||||
#include "pdm_hw.h"
|
||||
#include "tdm_hw.h"
|
||||
#include "ddr_mngr.h"
|
||||
#include "resample.h"
|
||||
#include "effects_v2.h"
|
||||
#include "vad.h"
|
||||
#include "ddr_mngr.h"
|
||||
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include <linux/amlogic/media/sound/auge_utils.h>
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
struct snd_elem_info {
|
||||
struct soc_enum *ee;
|
||||
int reg;
|
||||
@@ -39,132 +33,8 @@ struct snd_elem_info {
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
static unsigned int loopback_enable;
|
||||
static unsigned int loopback_is_running;
|
||||
static unsigned int datain_datalb_total;
|
||||
static unsigned int audio_inskew;
|
||||
|
||||
static const char *const loopback_enable_texts[] = {
|
||||
"Disable",
|
||||
"Enable",
|
||||
};
|
||||
|
||||
static const struct soc_enum loopback_enable_enum =
|
||||
SOC_ENUM_SINGLE(EE_AUDIO_LB_CTRL0,
|
||||
31,
|
||||
ARRAY_SIZE(loopback_enable_texts),
|
||||
loopback_enable_texts);
|
||||
|
||||
|
||||
static int loopback_enable_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = loopback_enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_enable_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
loopback_enable = ucontrol->value.enumerated.item[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int datain_datalb_total_get_param(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.bytes.data[0] = datain_datalb_total;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int datain_datalb_total_set_param(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
datain_datalb_total = ucontrol->value.bytes.data[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int loopback_datain;
|
||||
|
||||
static const char *const loopback_datain_texts[] = {
|
||||
"TDMIN_A",
|
||||
"TDMIN_B",
|
||||
"TDMIN_C",
|
||||
"SPDIFIN",
|
||||
"PDMIN",
|
||||
};
|
||||
|
||||
static const struct soc_enum loopback_datain_enum =
|
||||
SOC_ENUM_SINGLE(EE_AUDIO_LB_CTRL0, 0, ARRAY_SIZE(loopback_datain_texts),
|
||||
loopback_datain_texts);
|
||||
|
||||
|
||||
static int loopback_datain_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = loopback_datain;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_datain_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
loopback_datain = ucontrol->value.enumerated.item[0];
|
||||
audiobus_update_bits(EE_AUDIO_LB_CTRL0, 0, loopback_datain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int loopback_tdminlb;
|
||||
|
||||
static const char *const loopback_tdminlb_texts[] = {
|
||||
"TDMOUT_A",
|
||||
"TDMOUT_B",
|
||||
"TDMOUT_C",
|
||||
"TDMIN_A",
|
||||
"TDMIN_B",
|
||||
"TDMIN_C",
|
||||
};
|
||||
|
||||
static const struct soc_enum loopback_tdminlb_enum =
|
||||
SOC_ENUM_SINGLE(EE_AUDIO_TDMIN_LB_CTRL,
|
||||
20,
|
||||
ARRAY_SIZE(loopback_tdminlb_texts),
|
||||
loopback_tdminlb_texts);
|
||||
|
||||
|
||||
static int loopback_tdminlb_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = loopback_tdminlb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_tdminlb_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
loopback_tdminlb = ucontrol->value.enumerated.item[0];
|
||||
audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL,
|
||||
0xf << 20,
|
||||
loopback_datain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int snd_int_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
@@ -726,27 +596,6 @@ static int tdmout_c_binv_set_enum(
|
||||
SND_BYTE(xname, type, func, xshift, xmask)
|
||||
|
||||
static const struct snd_kcontrol_new snd_auge_controls[] = {
|
||||
/* loopback enable */
|
||||
SOC_ENUM_EXT("Loopback Enable",
|
||||
loopback_enable_enum,
|
||||
loopback_enable_get_enum,
|
||||
loopback_enable_set_enum),
|
||||
|
||||
SND_SOC_BYTES_EXT("datain_datalb_total", 1,
|
||||
datain_datalb_total_get_param,
|
||||
datain_datalb_total_set_param),
|
||||
|
||||
/* loopback data in source */
|
||||
SOC_ENUM_EXT("Loopback datain source",
|
||||
loopback_datain_enum,
|
||||
loopback_datain_get_enum,
|
||||
loopback_datain_set_enum),
|
||||
|
||||
/* loopback data tdmin lb */
|
||||
SOC_ENUM_EXT("Loopback tmdin lb source",
|
||||
loopback_tdminlb_enum,
|
||||
loopback_tdminlb_get_enum,
|
||||
loopback_tdminlb_set_enum),
|
||||
#if 0
|
||||
/*TDMIN_A swap*/
|
||||
SND_SWAP("TDMIN_A Ch0 Swap", TDMIN_A, in_swap_channel_enum, 0, 0x7),
|
||||
@@ -1058,519 +907,6 @@ int snd_card_add_kcontrols(struct snd_soc_card *card)
|
||||
|
||||
}
|
||||
|
||||
int loopback_parse_of(struct device_node *node,
|
||||
struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
const __be32 *of_slot_mask;
|
||||
unsigned int lane_mask = 0;
|
||||
int i, ret, set_num = 0;
|
||||
u32 val;
|
||||
|
||||
pdev = of_find_device_by_node(node);
|
||||
if (!pdev) {
|
||||
dev_err(&pdev->dev, "failed to find platform device\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*mpll used for tdmin*/
|
||||
lb_cfg->tdmin_mpll = devm_clk_get(&pdev->dev, "datalb_mpll");
|
||||
if (IS_ERR(lb_cfg->tdmin_mpll)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Can't retrieve tdmin_mpll clock\n");
|
||||
lb_cfg->tdmin_mpll = NULL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "lb_mode",
|
||||
&lb_cfg->lb_mode);
|
||||
if (ret) {
|
||||
pr_err("failed to get lb_mode, set it default\n");
|
||||
lb_cfg->lb_mode = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "datain_src",
|
||||
&lb_cfg->datain_src);
|
||||
if (ret) {
|
||||
pr_err("failed to get datain_src\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
ret = of_property_read_u32(node, "datain_chnum",
|
||||
&lb_cfg->datain_chnum);
|
||||
if (ret) {
|
||||
pr_err("failed to get datain_chnum\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
ret = of_property_read_u32(node, "datain_chmask",
|
||||
&lb_cfg->datain_chmask);
|
||||
if (ret) {
|
||||
pr_err("failed to get datain_chmask\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "datalb_src",
|
||||
&lb_cfg->datalb_src);
|
||||
if (ret) {
|
||||
pr_err("failed to get datalb_src\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
ret = of_property_read_u32(node, "datalb_chnum",
|
||||
&lb_cfg->datalb_chnum);
|
||||
if (ret) {
|
||||
pr_err("failed to get datalb_chnum\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
ret = of_property_read_u32(node, "datalb_chmask",
|
||||
&lb_cfg->datalb_chmask);
|
||||
if (ret) {
|
||||
pr_err("failed to get datalb_chmask\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
of_slot_mask = of_get_property(node, "datalb-lane-mask-in", &val);
|
||||
if (!of_slot_mask) {
|
||||
pr_err("if use extern loopback, pls set datalb-lane-mask-in\n");
|
||||
} else {
|
||||
val /= sizeof(u32);
|
||||
for (i = 0; i < val; i++)
|
||||
if (be32_to_cpup(&of_slot_mask[i]))
|
||||
lane_mask |= (1 << i);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((1 << i) & lane_mask) {
|
||||
/*each lane only L/R masked*/
|
||||
lb_cfg->datalb_chswap |=
|
||||
(i * 2) << (set_num++ * 4);
|
||||
lb_cfg->datalb_chswap |=
|
||||
(i * 2 + 1) << (set_num++ * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = of_property_read_u32(node, "datalb_clk",
|
||||
&lb_cfg->datalb_clk);
|
||||
if (ret) {
|
||||
pr_err("if no datalb_clk on dts, it equal is datalb_src\n");
|
||||
lb_cfg->datalb_clk = lb_cfg->datalb_src;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "datain_datalb_total",
|
||||
&lb_cfg->datain_datalb_total);
|
||||
if (ret) {
|
||||
pr_err("no register datain_datalb_total,it also can work\n");
|
||||
lb_cfg->datain_datalb_total = 0;
|
||||
} else {
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
lb_cfg->datain_chnum = 8;
|
||||
lb_cfg->datain_chmask = 0xff;
|
||||
lb_cfg->datalb_chnum = 8;
|
||||
lb_cfg->datalb_chmask = 0xff;
|
||||
lb_cfg->datalb_chswap = 0x76543210;
|
||||
}
|
||||
}
|
||||
datain_datalb_total = lb_cfg->datain_datalb_total;
|
||||
|
||||
loopback_datain = lb_cfg->datain_src;
|
||||
loopback_tdminlb = lb_cfg->datalb_src;
|
||||
|
||||
pr_info("parse loopback:, \tlb mode:%d\n",
|
||||
lb_cfg->lb_mode);
|
||||
pr_info("\tdatain_src:%d, datain_chnum:%d, datain_chumask:%x\n",
|
||||
lb_cfg->datain_src,
|
||||
lb_cfg->datain_chnum,
|
||||
lb_cfg->datain_chmask);
|
||||
pr_info("\tdatalb_src:%d, datalb_chnum:%d\n",
|
||||
lb_cfg->datalb_src,
|
||||
lb_cfg->datalb_chnum);
|
||||
pr_info("\tdatalb_chswap:0x%x,datalb_chmask:%x\n",
|
||||
lb_cfg->datalb_chswap,
|
||||
lb_cfg->datalb_chmask);
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int loopback_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct loopback_cfg *lb_cfg,
|
||||
unsigned int mclk)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned int bclk_sel, fsclk_sel;
|
||||
int bit_depth;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
bit_depth = snd_pcm_format_width(runtime->format);
|
||||
|
||||
if (lb_cfg->datalb_src >= 3) {
|
||||
/*tdm in*/
|
||||
/*for i2s mode*/
|
||||
unsigned int sclk_div = 4 - 1;
|
||||
unsigned int ratio = params_channels(params) * bit_depth - 1;
|
||||
unsigned int fsclk_hi;
|
||||
unsigned int clk_id = lb_cfg->datalb_src - 3;
|
||||
unsigned int mul = 2;
|
||||
unsigned int mpll_freq, offset, reg;
|
||||
|
||||
/*lrclk sclk depend on default 8ch setting,*/
|
||||
/* so if num of channels is 4, to change ratio*/
|
||||
if (params_channels(params) == 4)
|
||||
ratio = ratio*2;
|
||||
|
||||
fsclk_hi = ratio/2;
|
||||
|
||||
pr_info("%s, channels:%d, format:%d, ratio:%d\n",
|
||||
__func__,
|
||||
params_channels(params),
|
||||
bit_depth,
|
||||
ratio);
|
||||
|
||||
bclk_sel = clk_id;
|
||||
fsclk_sel = clk_id;
|
||||
|
||||
/*mclk*/
|
||||
mpll_freq = mclk * mul;
|
||||
clk_set_rate(lb_cfg->tdmin_mpll, mpll_freq);
|
||||
pr_info("mpll freq:%d, %lu\n", mpll_freq,
|
||||
clk_get_rate(lb_cfg->tdmin_mpll));
|
||||
offset = EE_AUDIO_MCLK_B_CTRL(0) - EE_AUDIO_MCLK_A_CTRL(0);
|
||||
reg = EE_AUDIO_MCLK_A_CTRL(0) + offset * clk_id;
|
||||
audiobus_write(reg,
|
||||
1 << 31 | /*clk enable*/
|
||||
clk_id << 24 | /*clk src*/
|
||||
(mul - 1)); /*clk_div mclk*/
|
||||
|
||||
/*sclk, lrclk*/
|
||||
offset = EE_AUDIO_MST_B_SCLK_CTRL0 - EE_AUDIO_MST_A_SCLK_CTRL0;
|
||||
reg = EE_AUDIO_MST_A_SCLK_CTRL0 + offset * clk_id;
|
||||
audiobus_update_bits(reg,
|
||||
0x3 << 30 | 0x3ff << 20 | 0x3ff<<10 | 0x3ff,
|
||||
0x3 << 30 | sclk_div << 20 | fsclk_hi << 10
|
||||
| ratio);
|
||||
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_CLK_TDMIN_LB_CTRL,
|
||||
0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20,
|
||||
0x3 << 30 | 1 << 29 | bclk_sel << 24 | fsclk_sel << 20);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loopback_prepare(
|
||||
struct snd_pcm_substream *substream,
|
||||
struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned int bitwidth;
|
||||
unsigned int datain_toddr_type, datalb_toddr_type;
|
||||
unsigned int datain_msb, datain_lsb, datalb_msb, datalb_lsb;
|
||||
struct lb_cfg datain_cfg;
|
||||
struct lb_cfg datalb_cfg;
|
||||
struct audio_data ddrdata;
|
||||
struct data_in datain;
|
||||
struct data_lb datalb;
|
||||
|
||||
if (!lb_cfg)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
bitwidth = snd_pcm_format_width(runtime->format);
|
||||
switch (lb_cfg->datain_src) {
|
||||
case DATAIN_TDMA:
|
||||
case DATAIN_TDMB:
|
||||
case DATAIN_TDMC:
|
||||
case DATAIN_PDM:
|
||||
datain_toddr_type = 0;
|
||||
datain_msb = 32 - 1;
|
||||
datain_lsb = 0;
|
||||
break;
|
||||
case DATAIN_SPDIF:
|
||||
datain_toddr_type = 3;
|
||||
datain_msb = 27;
|
||||
datain_lsb = 4;
|
||||
if (bitwidth <= 24)
|
||||
datain_lsb = 28 - bitwidth;
|
||||
else
|
||||
datain_lsb = 4;
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupport data in source:%d\n",
|
||||
lb_cfg->datain_src);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (lb_cfg->datalb_src) {
|
||||
case TDMINLB_TDMOUTA:
|
||||
case TDMINLB_TDMOUTB:
|
||||
case TDMINLB_TDMOUTC:
|
||||
case TDMINLB_PAD_TDMINA:
|
||||
case TDMINLB_PAD_TDMINB:
|
||||
case TDMINLB_PAD_TDMINC:
|
||||
if (bitwidth == 24) {
|
||||
datalb_toddr_type = 4;
|
||||
datalb_msb = 32 - 1;
|
||||
datalb_lsb = 32 - bitwidth;
|
||||
} else {
|
||||
datalb_toddr_type = 0;
|
||||
datalb_msb = 32 - 1;
|
||||
datalb_lsb = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupport data lb source:%d\n",
|
||||
lb_cfg->datalb_src);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
datain_cfg.ext_signed = 0;
|
||||
datain_cfg.chnum = lb_cfg->datain_chnum;
|
||||
datain_cfg.chmask = lb_cfg->datain_chmask;
|
||||
ddrdata.combined_type = datain_toddr_type;
|
||||
ddrdata.msb = datain_msb;
|
||||
ddrdata.lsb = datain_lsb;
|
||||
ddrdata.src = lb_cfg->datain_src;
|
||||
datain.config = &datain_cfg;
|
||||
datain.ddrdata = &ddrdata;
|
||||
|
||||
datalb_cfg.ext_signed = 0;
|
||||
datalb_cfg.chnum = lb_cfg->datalb_chnum;
|
||||
datalb_cfg.chmask = lb_cfg->datalb_chmask;
|
||||
datalb.config = &datalb_cfg;
|
||||
datalb.ddr_type = datalb_toddr_type;
|
||||
datalb.msb = datalb_msb;
|
||||
datalb.lsb = datalb_lsb;
|
||||
|
||||
datain_config(&datain);
|
||||
datalb_config(&datalb);
|
||||
|
||||
lb_cfg->datain_datalb_total = datain_datalb_total;
|
||||
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
lb_cfg->datain_chnum = 8;
|
||||
lb_cfg->datain_chmask = 0xff;
|
||||
lb_cfg->datalb_chnum = 8;
|
||||
lb_cfg->datalb_chmask = 0xff;
|
||||
lb_cfg->datalb_chswap = 0x76543210;
|
||||
}
|
||||
datalb_ctrl(lb_cfg);
|
||||
lb_mode(lb_cfg->lb_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void toddr_enable(int is_enable, int toddr_index)
|
||||
{
|
||||
int offset = EE_AUDIO_TODDR_B_CTRL0 - EE_AUDIO_TODDR_A_CTRL0;
|
||||
int reg = EE_AUDIO_TODDR_A_CTRL0 + offset * toddr_index;
|
||||
|
||||
audiobus_update_bits(
|
||||
reg,
|
||||
0x1 << 31,
|
||||
is_enable << 31);
|
||||
}
|
||||
|
||||
void frddr_enable(int is_enable, int frddr_index)
|
||||
{
|
||||
int offset = EE_AUDIO_FRDDR_B_CTRL0 - EE_AUDIO_FRDDR_A_CTRL0;
|
||||
int reg = EE_AUDIO_FRDDR_A_CTRL0 + offset * frddr_index;
|
||||
|
||||
audiobus_update_bits(
|
||||
reg,
|
||||
0x1 << 31,
|
||||
is_enable << 31);
|
||||
}
|
||||
|
||||
static void loopback_modules_disable(
|
||||
struct loopback_cfg *lb_cfg,
|
||||
int tdm_index,
|
||||
int frddr_index, int toddr_index)
|
||||
{
|
||||
/* tdminLB */
|
||||
tdmin_lb_fifo_enable(0);
|
||||
tdmin_lb_enable(tdm_index, 0);
|
||||
|
||||
/* datain src */
|
||||
switch (lb_cfg->datain_src) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
/*tdm in*/
|
||||
break;
|
||||
case 3:
|
||||
/*spdif in*/
|
||||
break;
|
||||
case 4:
|
||||
/*pdm in*/
|
||||
pdm_enable(0);
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupport datain source!!\n");
|
||||
return;
|
||||
}
|
||||
/* loopback */
|
||||
lb_enable(0);
|
||||
|
||||
/* toddr */
|
||||
if (toddr_index >= 0)
|
||||
toddr_enable(0, toddr_index);
|
||||
|
||||
/* frddr */
|
||||
if (frddr_index >= 3)
|
||||
toddr_enable(0, frddr_index - 3);
|
||||
else if (frddr_index >= 0)
|
||||
frddr_enable(0, frddr_index);
|
||||
|
||||
/* tdmout */
|
||||
if (frddr_index >= 0) {
|
||||
tdm_fifo_enable(tdm_index, 0);
|
||||
tdm_enable(tdm_index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void loopback_modules_enable(
|
||||
struct loopback_cfg *lb_cfg,
|
||||
int tdm_index,
|
||||
int frddr_index, int toddr_index)
|
||||
{
|
||||
/*
|
||||
* Loopback enable in sequence:
|
||||
* tdmout->frddr->toddr->loopback->pdmin->tdminLB
|
||||
*/
|
||||
|
||||
/* tdmout */
|
||||
if (frddr_index >= 0) {
|
||||
tdm_fifo_enable(tdm_index, 1);
|
||||
tdm_enable(tdm_index, 1);
|
||||
}
|
||||
|
||||
/* frddr */
|
||||
if (frddr_index >= 3)
|
||||
toddr_enable(1, frddr_index - 3);
|
||||
else if (frddr_index >= 0)
|
||||
frddr_enable(1, frddr_index);
|
||||
|
||||
tdm_fifo_enable(tdm_index, 1);
|
||||
tdm_enable(tdm_index, 1);
|
||||
frddr_enable(1, frddr_index);
|
||||
/* toddr */
|
||||
if (toddr_index >= 0)
|
||||
toddr_enable(1, toddr_index);
|
||||
|
||||
/* loopback */
|
||||
lb_enable(1);
|
||||
|
||||
/* datain src */
|
||||
switch (lb_cfg->datain_src) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
/*tdm in*/
|
||||
break;
|
||||
case 3:
|
||||
/*spdif in*/
|
||||
break;
|
||||
case 4:
|
||||
/*pdm in*/
|
||||
pdm_enable(1);
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupport datain source!!\n");
|
||||
return;
|
||||
}
|
||||
/*tdminLB*/
|
||||
tdmin_lb_fifo_enable(1);
|
||||
tdmin_lb_enable(tdm_index, 1);
|
||||
}
|
||||
|
||||
int loopback_trigger(
|
||||
struct snd_pcm_substream *substream,
|
||||
int cmd,
|
||||
struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
if (loopback_enable && loopback_is_running) {
|
||||
pr_info("loopback enable\n");
|
||||
|
||||
/*
|
||||
* toddr/frdd is selected in dai_prepare already.
|
||||
* check toddr index of datain
|
||||
* check frddr index of datalb
|
||||
*/
|
||||
lb_cfg->toddr_index = fetch_toddr_index_by_src(
|
||||
lb_cfg->datain_src);
|
||||
/* check datalb is from tdmout or tdmin */
|
||||
if (lb_cfg->datalb_src >= 3)
|
||||
lb_cfg->frddr_index = fetch_toddr_index_by_src(
|
||||
lb_cfg->datalb_src - 3);
|
||||
else
|
||||
lb_cfg->frddr_index = fetch_frddr_index_by_src(
|
||||
lb_cfg->datalb_src);
|
||||
|
||||
pr_info("loopback toddr index:%d, frddr index:%d\n",
|
||||
lb_cfg->toddr_index,
|
||||
lb_cfg->frddr_index);
|
||||
|
||||
pr_info("loopback modules in sequence!\n");
|
||||
/*if pdm overrun, re-set up the sequence*/
|
||||
if (lb_cfg->frddr_index >= 0)
|
||||
loopback_modules_disable(
|
||||
lb_cfg,
|
||||
lb_cfg->datalb_src,
|
||||
lb_cfg->frddr_index,
|
||||
lb_cfg->toddr_index);
|
||||
|
||||
loopback_modules_enable(
|
||||
lb_cfg,
|
||||
lb_cfg->datalb_src,
|
||||
lb_cfg->frddr_index,
|
||||
lb_cfg->toddr_index);
|
||||
}
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
if (loopback_enable) {
|
||||
pr_info("loopback disable\n");
|
||||
lb_enable(0);
|
||||
tdmin_lb_enable(lb_cfg->datalb_src, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void loopback_set_status(int is_running)
|
||||
{
|
||||
loopback_is_running = is_running;
|
||||
}
|
||||
|
||||
int loopback_is_enable(void)
|
||||
{
|
||||
return (loopback_enable == 1);
|
||||
}
|
||||
|
||||
int loopback_check_enable(int src)
|
||||
{
|
||||
return (src <= PDMIN)
|
||||
&& (loopback_datain == src)
|
||||
&& (loopback_enable == 1);
|
||||
}
|
||||
|
||||
void auge_acodec_reset(void)
|
||||
{
|
||||
audioreset_update_bits(EE_RESET1, 1 << 29, 1 << 29);
|
||||
|
||||
@@ -18,144 +18,10 @@
|
||||
#ifndef __AML_AUDIO_UTILS_H__
|
||||
#define __AML_AUDIO_UTILS_H__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/types.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/* datain src
|
||||
* [4]: pdmin;
|
||||
* [3]: spdifin;
|
||||
* [2]: tdmin_c;
|
||||
* [1]: tdmin_b;
|
||||
* [0]: tdmin_a;
|
||||
*/
|
||||
enum datain_src {
|
||||
DATAIN_TDMA = 0,
|
||||
DATAIN_TDMB,
|
||||
DATAIN_TDMC,
|
||||
DATAIN_SPDIF,
|
||||
DATAIN_PDM,
|
||||
};
|
||||
|
||||
/* datalb src/tdmlb src
|
||||
* [0]: tdmoutA
|
||||
* [1]: tdmoutB
|
||||
* [2]: tdmoutC
|
||||
* [3]: PAD_tdminA
|
||||
* [4]: PAD_tdminB
|
||||
* [5]: PAD_tdminC
|
||||
*/
|
||||
enum tdmin_lb_src {
|
||||
TDMINLB_TDMOUTA = 0,
|
||||
TDMINLB_TDMOUTB,
|
||||
TDMINLB_TDMOUTC,
|
||||
TDMINLB_PAD_TDMINA,
|
||||
TDMINLB_PAD_TDMINB,
|
||||
TDMINLB_PAD_TDMINC,
|
||||
};
|
||||
|
||||
/* toddr_src_sel
|
||||
* [7]: loopback;
|
||||
* [6]: tdmin_lb;
|
||||
* [5]: reserved;
|
||||
* [4]: pdmin;
|
||||
* [3]: spdifin;
|
||||
* [2]: tdmin_c;
|
||||
* [1]: tdmin_b;
|
||||
* [0]: tdmin_a;
|
||||
*/
|
||||
enum fifoin_src {
|
||||
FIFOIN_TDMINA = 0,
|
||||
FIFOIN_TDMINB = 1,
|
||||
FIFOIN_TDMINC = 2,
|
||||
FIFOIN_SPDIF = 3,
|
||||
FIFOIN_PDM = 4,
|
||||
FIFOIN_TDMINLB = 6,
|
||||
FIFOIN_LOOPBACK = 7
|
||||
};
|
||||
|
||||
/* audio data selected to ddr */
|
||||
struct audio_data {
|
||||
unsigned int resample;
|
||||
/* reg_dat_sel
|
||||
* 0: combined data[m:n] without gap;
|
||||
* like S0[m:n],S1[m:n],S2[m:n],
|
||||
* 1: combined data[m:n] as 16bits;
|
||||
* like {S0[11:0],4'd0},{S1[11:0],4'd0}
|
||||
* 2: combined data[m:n] as 16bits;
|
||||
* like {4'd0,S0[11:0]},{4'd0,{S1[11:0]}
|
||||
* 3: combined data[m:n] as 32bits;
|
||||
* like {S0[27:4],8'd0},{S1[27:4],8'd0}
|
||||
* 4: combined data[m:n] as 32bits;
|
||||
* like {8'd0,S0[27:4]},{8'd0,{S1[27:4]}
|
||||
*/
|
||||
unsigned int combined_type;
|
||||
/* the msb positioin in data */
|
||||
unsigned int msb;
|
||||
/* the lsb position in data */
|
||||
unsigned int lsb;
|
||||
/* toddr_src_sel
|
||||
* [7]: loopback;
|
||||
* [6]: tdmin_lb;
|
||||
* [5]: reserved;
|
||||
* [4]: pdmin;
|
||||
* [3]: spdifin;
|
||||
* [2]: tdmin_c;
|
||||
* [1]: tdmin_b;
|
||||
* [0]: tdmin_a;
|
||||
*/
|
||||
unsigned int src;
|
||||
};
|
||||
|
||||
/**/
|
||||
struct loopback_cfg {
|
||||
struct clk *tdmin_mpll;
|
||||
/* lb_mode
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
*/
|
||||
unsigned int lb_mode;
|
||||
|
||||
enum datain_src datain_src;
|
||||
unsigned int datain_chnum;
|
||||
unsigned int datain_chmask;
|
||||
int toddr_index;
|
||||
|
||||
enum tdmin_lb_src datalb_src;
|
||||
enum tdmin_lb_src datalb_clk;
|
||||
unsigned int datalb_chnum;
|
||||
unsigned int datalb_chswap;
|
||||
unsigned int datalb_chmask;
|
||||
int frddr_index;
|
||||
unsigned int datain_datalb_total;
|
||||
};
|
||||
|
||||
extern void loopback_set_status(int is_running);
|
||||
|
||||
extern int loopback_is_enable(void);
|
||||
|
||||
extern int loopback_check_enable(int src);
|
||||
|
||||
extern int snd_card_add_kcontrols(struct snd_soc_card *card);
|
||||
|
||||
extern int loopback_parse_of(struct device_node *node,
|
||||
struct loopback_cfg *lb_cfg);
|
||||
|
||||
extern int loopback_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct loopback_cfg *lb_cfg,
|
||||
unsigned int mclk);
|
||||
|
||||
extern int loopback_prepare(
|
||||
struct snd_pcm_substream *substream,
|
||||
struct loopback_cfg *lb_cfg);
|
||||
|
||||
extern int loopback_trigger(
|
||||
struct snd_pcm_substream *substream,
|
||||
int cmd,
|
||||
struct loopback_cfg *lb_cfg);
|
||||
|
||||
extern void audio_locker_set(int enable);
|
||||
|
||||
extern int audio_locker_get(void);
|
||||
|
||||
@@ -69,7 +69,6 @@ struct aml_card_data {
|
||||
int spk_mute_gpio;
|
||||
bool spk_mute_active_low;
|
||||
struct gpio_desc *avout_mute_desc;
|
||||
struct loopback_cfg lb_cfg;
|
||||
struct timer_list timer;
|
||||
struct work_struct work;
|
||||
struct work_struct init_work;
|
||||
@@ -466,8 +465,6 @@ static int aml_card_hw_params(struct snd_pcm_substream *substream,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (loopback_is_enable() && mclk)
|
||||
loopback_hw_params(substream, params, &priv->lb_cfg, mclk);
|
||||
return 0;
|
||||
err:
|
||||
return ret;
|
||||
@@ -475,23 +472,11 @@ err:
|
||||
|
||||
int aml_card_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct aml_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||
|
||||
if (loopback_is_enable())
|
||||
loopback_prepare(substream, &priv->lb_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aml_card_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct aml_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||
|
||||
if (loopback_is_enable())
|
||||
loopback_trigger(substream, cmd, &priv->lb_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -802,7 +787,6 @@ static int aml_card_parse_of(struct device_node *node,
|
||||
{
|
||||
struct device *dev = aml_priv_to_dev(priv);
|
||||
struct device_node *dai_link;
|
||||
struct device_node *lb_link;
|
||||
int ret;
|
||||
|
||||
if (!node)
|
||||
@@ -829,14 +813,6 @@ static int aml_card_parse_of(struct device_node *node,
|
||||
/* Factor to mclk, used in hw_params() */
|
||||
of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);
|
||||
|
||||
/* Loopback */
|
||||
lb_link = of_parse_phandle(node, PREFIX "loopback", 0);
|
||||
if (lb_link) {
|
||||
ret = loopback_parse_of(lb_link, &priv->lb_cfg);
|
||||
if (ret < 0)
|
||||
pr_err("failed parse loopback, ignore it\n");
|
||||
}
|
||||
|
||||
/* Single/Muti DAI link(s) & New style of DT node */
|
||||
if (dai_link) {
|
||||
struct device_node *np = NULL;
|
||||
@@ -867,12 +843,10 @@ static int aml_card_parse_of(struct device_node *node,
|
||||
|
||||
card_parse_end:
|
||||
of_node_put(dai_link);
|
||||
of_node_put(lb_link);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct aml_chipset_info g12a_chipset_info = {
|
||||
.spdif_b = true,
|
||||
.eqdrc_fn = true,
|
||||
@@ -922,6 +896,13 @@ static int aml_card_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* chipset related */
|
||||
priv->chipinfo = (struct aml_chipset_info *)
|
||||
of_device_get_match_data(&pdev->dev);
|
||||
|
||||
if (!priv->chipinfo)
|
||||
pr_warn_once("check whether to update sound card init data\n");
|
||||
|
||||
dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
|
||||
dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
|
||||
if (!dai_props || !dai_link)
|
||||
@@ -979,13 +960,6 @@ static int aml_card_probe(struct platform_device *pdev)
|
||||
sizeof(priv->dai_props->codec_dai));
|
||||
}
|
||||
|
||||
|
||||
priv->chipinfo = (struct aml_chipset_info *)
|
||||
of_device_get_match_data(&pdev->dev);
|
||||
|
||||
if (!priv->chipinfo)
|
||||
pr_warn_once("check whether to update sound card init data\n");
|
||||
|
||||
snd_soc_card_set_drvdata(&priv->snd_card, priv);
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "regs.h"
|
||||
#include "ddr_mngr.h"
|
||||
#include "audio_utils.h"
|
||||
|
||||
#include "resample.h"
|
||||
#include "resample_hw.h"
|
||||
@@ -134,12 +133,6 @@ static int unregister_toddr_l(struct device *dev, void *data)
|
||||
|
||||
to = &toddrs[i];
|
||||
|
||||
/* check for loopback */
|
||||
if (to->is_lb) {
|
||||
loopback_set_status(0);
|
||||
to->is_lb = 0;
|
||||
}
|
||||
|
||||
/* disable audio ddr arb */
|
||||
mask_bit = i;
|
||||
actrl = to->actrl;
|
||||
@@ -366,13 +359,6 @@ void aml_toddr_select_src(struct toddr *to, enum toddr_src src)
|
||||
/* store to check toddr num */
|
||||
to->src = src;
|
||||
|
||||
/* check whether loopback enable */
|
||||
if (loopback_check_enable(src)) {
|
||||
loopback_set_status(1);
|
||||
to->is_lb = 1; /* in loopback */
|
||||
src = LOOPBACK_A;
|
||||
}
|
||||
|
||||
if (to->chipinfo
|
||||
&& to->chipinfo->src_sel_ctrl) {
|
||||
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base);
|
||||
@@ -456,6 +442,29 @@ void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt)
|
||||
fmt->msb << 8 | fmt->lsb << 3);
|
||||
}
|
||||
|
||||
unsigned int aml_toddr_get_status(struct toddr *to)
|
||||
{
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
unsigned int reg_base = to->reg_base;
|
||||
unsigned int reg;
|
||||
|
||||
reg = calc_toddr_address(EE_AUDIO_TODDR_A_STATUS1, reg_base);
|
||||
|
||||
return aml_audiobus_read(actrl, reg);
|
||||
}
|
||||
|
||||
void aml_toddr_ack_irq(struct toddr *to, int status)
|
||||
{
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
unsigned int reg_base = to->reg_base;
|
||||
unsigned int reg;
|
||||
|
||||
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base);
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg, MEMIF_INT_MASK, status);
|
||||
aml_audiobus_update_bits(actrl, reg, MEMIF_INT_MASK, 0);
|
||||
}
|
||||
|
||||
void aml_toddr_insert_chanum(struct toddr *to)
|
||||
{
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
#include <sound/soc.h>
|
||||
#include "audio_io.h"
|
||||
|
||||
#define MEMIF_INT_ADDR_FINISH BIT(0)
|
||||
#define MEMIF_INT_ADDR_INT BIT(1)
|
||||
#define MEMIF_INT_COUNT_REPEAT BIT(2)
|
||||
#define MEMIF_INT_COUNT_ONCE BIT(3)
|
||||
#define MEMIF_INT_FIFO_ZERO BIT(4)
|
||||
#define MEMIF_INT_FIFO_DEPTH BIT(5)
|
||||
#define MEMIF_INT_MASK GENMASK(7, 0)
|
||||
|
||||
enum ddr_num {
|
||||
DDR_A,
|
||||
DDR_B,
|
||||
@@ -104,27 +112,6 @@ struct toddr_fmt {
|
||||
unsigned int rate;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct ddr_desc {
|
||||
/* start address of DDR */
|
||||
unsigned int start;
|
||||
/* finish address of DDR */
|
||||
unsigned int finish;
|
||||
/* interrupt address or counts of DDR blocks */
|
||||
unsigned int intrpt;
|
||||
/* fifo total counts */
|
||||
unsigned int fifo_depth;
|
||||
/* fifo start threshold */
|
||||
unsigned int fifo_thr;
|
||||
enum ddr_types data_type;
|
||||
unsigned int edian;
|
||||
unsigned int pp_mode;
|
||||
//unsigned int reg_base;
|
||||
struct clk *ddr;
|
||||
struct clk *ddr_arb;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ddr_chipinfo {
|
||||
/* INT and Start address is same or separated */
|
||||
bool int_start_same_addr;
|
||||
@@ -170,7 +157,6 @@ struct ddr_chipinfo {
|
||||
};
|
||||
|
||||
struct toddr {
|
||||
//struct ddr_desc dscrpt;
|
||||
struct device *dev;
|
||||
unsigned int resample: 1;
|
||||
unsigned int ext_signed: 1;
|
||||
@@ -222,7 +208,6 @@ struct frddr_attach {
|
||||
};
|
||||
|
||||
struct frddr {
|
||||
//struct ddr_desc dscrpt;
|
||||
struct device *dev;
|
||||
enum frddr_dest dest;
|
||||
|
||||
@@ -244,7 +229,6 @@ struct frddr {
|
||||
};
|
||||
|
||||
/* to ddrs */
|
||||
int fetch_toddr_index_by_src(int toddr_src);
|
||||
struct toddr *fetch_toddr_by_src(int toddr_src);
|
||||
struct toddr *aml_audio_register_toddr(struct device *dev,
|
||||
struct aml_audio_controller *actrl,
|
||||
@@ -264,6 +248,10 @@ void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh);
|
||||
void aml_toddr_update_fifos_rd_th(struct toddr *to, int th);
|
||||
void aml_toddr_force_finish(struct toddr *to);
|
||||
void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt);
|
||||
|
||||
unsigned int aml_toddr_get_status(struct toddr *to);
|
||||
void aml_toddr_ack_irq(struct toddr *to, int status);
|
||||
|
||||
void aml_toddr_insert_chanum(struct toddr *to);
|
||||
unsigned int aml_toddr_read(struct toddr *to);
|
||||
void aml_toddr_write(struct toddr *to, unsigned int val);
|
||||
@@ -280,7 +268,6 @@ void aml_pwrdet_enable(bool enable, int pwrdet_module);
|
||||
void aml_set_vad(bool enable, int module);
|
||||
|
||||
/* from ddrs */
|
||||
int fetch_frddr_index_by_src(int frddr_src);
|
||||
struct frddr *fetch_frddr_by_src(int frddr_src);
|
||||
|
||||
struct frddr *aml_audio_register_frddr(struct device *dev,
|
||||
|
||||
1433
sound/soc/amlogic/auge/loopback.c
Normal file
1433
sound/soc/amlogic/auge/loopback.c
Normal file
File diff suppressed because it is too large
Load Diff
61
sound/soc/amlogic/auge/loopback.h
Normal file
61
sound/soc/amlogic/auge/loopback.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* sound/soc/amlogic/auge/loopback.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 __AML_AUDIO_LOOPBACK_H__
|
||||
#define __AML_AUDIO_LOOPBACK_H__
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/* datain src
|
||||
* [4]: pdmin;
|
||||
* [3]: spdifin;
|
||||
* [2]: tdmin_c;
|
||||
* [1]: tdmin_b;
|
||||
* [0]: tdmin_a;
|
||||
*/
|
||||
enum datain_src {
|
||||
DATAIN_TDMA = 0,
|
||||
DATAIN_TDMB,
|
||||
DATAIN_TDMC,
|
||||
DATAIN_SPDIF,
|
||||
DATAIN_PDM,
|
||||
DATAIN_LOOPBACK,
|
||||
};
|
||||
|
||||
/* datalb src
|
||||
* /tdmin_lb src
|
||||
* [0]: tdmoutA
|
||||
* [1]: tdmoutB
|
||||
* [2]: tdmoutC
|
||||
* [3]: PAD_tdminA
|
||||
* [4]: PAD_tdminB
|
||||
* [5]: PAD_tdminC
|
||||
* /spdifin_lb src
|
||||
* spdifout_a
|
||||
* spdifout_b
|
||||
*/
|
||||
enum datalb_src {
|
||||
TDMINLB_TDMOUTA = 0,
|
||||
TDMINLB_TDMOUTB,
|
||||
TDMINLB_TDMOUTC,
|
||||
TDMINLB_PAD_TDMINA,
|
||||
TDMINLB_PAD_TDMINB,
|
||||
TDMINLB_PAD_TDMINC,
|
||||
|
||||
SPDIFINLB_SPDIFOUTA,
|
||||
SPDIFINLB_SPDIFOUTB,
|
||||
};
|
||||
#endif
|
||||
@@ -14,193 +14,80 @@
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
#include <sound/soc.h>
|
||||
#define DEBUG
|
||||
|
||||
#include "linux/kernel.h"
|
||||
|
||||
#include "regs.h"
|
||||
#include "loopback_hw.h"
|
||||
#include "regs.h"
|
||||
#include "iomap.h"
|
||||
|
||||
void datain_config(struct data_in *datain)
|
||||
{
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_LB_CTRL0,
|
||||
1 << 29 | 0x7 << 24 | 0xff << 16 |
|
||||
0x7 << 13 | 0x1f << 8 | 0x1f << 3 |
|
||||
0x7 << 0,
|
||||
datain->config->ext_signed << 29 |
|
||||
(datain->config->chnum - 1) << 24 |
|
||||
datain->config->chmask << 16 |
|
||||
datain->ddrdata->combined_type << 13 |
|
||||
datain->ddrdata->msb << 8 |
|
||||
datain->ddrdata->lsb << 3 |
|
||||
datain->ddrdata->src << 0
|
||||
);
|
||||
}
|
||||
|
||||
void datalb_config(struct data_lb *datalb)
|
||||
void tdminlb_set_clk(int datatlb_src, int sclk_div, int ratio, bool enable)
|
||||
{
|
||||
audiobus_write(
|
||||
EE_AUDIO_LB_CTRL1,
|
||||
datalb->config->ext_signed << 29 |
|
||||
(datalb->config->chnum - 1) << 24 |
|
||||
datalb->config->chmask << 16 |
|
||||
datalb->ddr_type << 13 |
|
||||
datalb->msb << 8 |
|
||||
datalb->lsb << 3
|
||||
);
|
||||
}
|
||||
unsigned int bclk_sel, fsclk_sel;
|
||||
unsigned int tdmin_src;
|
||||
|
||||
void datalb_ctrl(struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
int id = lb_cfg->datalb_src;
|
||||
int offset = 0;
|
||||
int reg, reg_base;
|
||||
/* config for external codec */
|
||||
if (datatlb_src >= 3) {
|
||||
unsigned int clk_id = datatlb_src - 3;
|
||||
unsigned int offset, reg;
|
||||
unsigned int fsclk_hi;
|
||||
|
||||
fsclk_hi = ratio / 2;
|
||||
bclk_sel = clk_id;
|
||||
fsclk_sel = clk_id;
|
||||
|
||||
/*sclk, lrclk*/
|
||||
offset = EE_AUDIO_MST_B_SCLK_CTRL0 - EE_AUDIO_MST_A_SCLK_CTRL0;
|
||||
reg = EE_AUDIO_MST_A_SCLK_CTRL0 + offset * clk_id;
|
||||
audiobus_update_bits(reg,
|
||||
0x3 << 30 | 0x3ff << 20 | 0x3ff<<10 | 0x3ff,
|
||||
(enable ? 0x3 : 0x0) << 30
|
||||
| sclk_div << 20 | fsclk_hi << 10
|
||||
| ratio);
|
||||
|
||||
|
||||
tdmin_src = datatlb_src - 3;
|
||||
} else
|
||||
tdmin_src = datatlb_src;
|
||||
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_TDMIN_LB_CTRL,
|
||||
0xf << 28 | 0xf << 20 | 0x7 << 16 | 0x1f << 0,
|
||||
1 << 31 |
|
||||
/*0:tdm mode; 1: i2s mode;*/
|
||||
1 << 30 |
|
||||
1 << 29 |
|
||||
1 << 28 |
|
||||
lb_cfg->datalb_src << 20 |
|
||||
3 << 16|
|
||||
31 << 0
|
||||
);
|
||||
|
||||
if (id >= 0 && id <= 2) {
|
||||
/* tdmout_a, tdmout_b, tdmout_c */
|
||||
reg_base = EE_AUDIO_TDMOUT_A_SWAP0;
|
||||
offset = EE_AUDIO_TDMOUT_B_SWAP0 - EE_AUDIO_TDMOUT_A_SWAP0;
|
||||
} else if (id < 6) {
|
||||
/*lb_cfg->datalb_src for pad tdm in,
|
||||
*pad from tdmin_a, tdmin_b, tdmin_c
|
||||
*/
|
||||
/* id offset from tdmin_a */
|
||||
id -= 3;
|
||||
|
||||
reg_base = EE_AUDIO_TDMIN_A_CTRL;
|
||||
offset = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL;
|
||||
reg = reg_base + offset * id;
|
||||
audiobus_update_bits(reg, 3<<28, 0);
|
||||
audiobus_update_bits(reg, 1<<29, 1<<29);
|
||||
audiobus_update_bits(reg, 1<<28, 1<<28);
|
||||
|
||||
/* just assume lb from tdm in is i2s mode */
|
||||
audiobus_update_bits(
|
||||
reg,
|
||||
0xf << 28 | 0xf << 20 | 0x7 << 16 | 0x1f << 0,
|
||||
1 << 31 |
|
||||
/* 0:tdm mode; 1: i2s mode */
|
||||
1 << 30 |
|
||||
1 << 29 |
|
||||
1 << 28 |
|
||||
id << 20 |
|
||||
3 << 16|
|
||||
31 << 0
|
||||
);
|
||||
|
||||
pr_info("reg:0x%x, EE_AUDIO_TDMIN_A_CTRL:0x%x\n",
|
||||
reg,
|
||||
audiobus_read(EE_AUDIO_TDMIN_A_CTRL));
|
||||
/* swap */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
reg,
|
||||
lb_cfg->datalb_chswap);
|
||||
|
||||
/* mask 0 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
reg,
|
||||
lb_cfg->datalb_chmask);
|
||||
reg_base = EE_AUDIO_TDMIN_A_SWAP0;
|
||||
offset = EE_AUDIO_TDMIN_B_SWAP0 - EE_AUDIO_TDMIN_A_SWAP0;
|
||||
} else {
|
||||
pr_err("unsupport datalb_src\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_SWAP0,
|
||||
lb_cfg->datalb_chswap);
|
||||
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK0, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK1, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK2, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK3, 3);
|
||||
} else {
|
||||
/*swap same as tdmout */
|
||||
reg = reg_base + offset * id;
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_SWAP0,
|
||||
audiobus_read(reg));
|
||||
|
||||
/*mask same as datalb*/
|
||||
/* mask 0 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK0,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 1 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK1,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 2 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK2,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 3 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK3,
|
||||
audiobus_read(reg));
|
||||
}
|
||||
EE_AUDIO_CLK_TDMIN_LB_CTRL,
|
||||
0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20,
|
||||
(enable ? 0x3 : 0x0) << 30 |
|
||||
1 << 29 | tdmin_src << 24 | tdmin_src << 20
|
||||
);
|
||||
}
|
||||
|
||||
void lb_mode(int mode)
|
||||
void tdminlb_enable(int tdm_index, int is_enable)
|
||||
{
|
||||
// TODO:
|
||||
return;
|
||||
#if 0
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_LB_CTRL0,
|
||||
0x1 << 30,
|
||||
mode << 30
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tdmin_lb_clk_enalbe(int tdm_src, int is_enable)
|
||||
{
|
||||
if (tdm_src <= 2)
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_CLK_TDMIN_LB_CTRL,
|
||||
0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20,
|
||||
0x3 << 30 | 1 << 29 | tdm_src << 24 | tdm_src << 20
|
||||
);
|
||||
else
|
||||
pr_warn_once("pad from tdmin_a, tdmin_b, tdmin_c needs clks\n");
|
||||
}
|
||||
|
||||
void tdmin_lb_enable(int tdm_index, int is_enable)
|
||||
{
|
||||
if (is_enable)
|
||||
tdmin_lb_clk_enalbe(tdm_index, is_enable);
|
||||
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_TDMIN_LB_CTRL,
|
||||
0x1 << 31,
|
||||
is_enable << 31);
|
||||
}
|
||||
|
||||
void tdmin_lb_fifo_enable(int is_enable)
|
||||
void tdminlb_set_format(int i2s_fmt)
|
||||
{
|
||||
audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL,
|
||||
0x1 << 30,
|
||||
i2s_fmt << 30 /* 0:tdm mode; 1: i2s mode; */
|
||||
);
|
||||
}
|
||||
|
||||
void tdminlb_set_ctrl(int src)
|
||||
{
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_TDMIN_LB_CTRL,
|
||||
0xf << 20 | 0x7 << 16 | 0x1f << 0,
|
||||
src << 20 | /* in src */
|
||||
3 << 16 | /* skew */
|
||||
31 << 0 /* bit width */
|
||||
);
|
||||
}
|
||||
|
||||
void tdminlb_fifo_enable(int is_enable)
|
||||
{
|
||||
if (is_enable) {
|
||||
audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 1<<29, 1<<29);
|
||||
@@ -209,39 +96,123 @@ void tdmin_lb_fifo_enable(int is_enable)
|
||||
audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 3<<28, 0);
|
||||
}
|
||||
|
||||
|
||||
void lb_set_datain_src(int src)
|
||||
static void tdminlb_set_lane_mask(int lane, int mask)
|
||||
{
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK0 + lane, mask);
|
||||
}
|
||||
|
||||
void lb_set_tdminlb_src(int src)
|
||||
void tdminlb_set_lanemask_and_chswap(int swap, int lane_mask)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int i;
|
||||
|
||||
pr_debug("tdmin_lb lane swap:0x%x mask:0x%x\n", swap, lane_mask);
|
||||
|
||||
mask = 0x3; /* i2s format */
|
||||
|
||||
/* channel swap */
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_SWAP0, swap);
|
||||
|
||||
/* lane mask */
|
||||
for (i = 0; i < 4; i++)
|
||||
if ((1 << i) & lane_mask)
|
||||
tdminlb_set_lane_mask(i, mask);
|
||||
}
|
||||
|
||||
void lb_set_tdminlb_enable(bool is_enable)
|
||||
void tdminlb_set_src(int src)
|
||||
{
|
||||
audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 0xf << 20, src);
|
||||
}
|
||||
|
||||
int lb_is_enable(void)
|
||||
void lb_set_datain_src(int id, int src)
|
||||
{
|
||||
return (audiobus_read(EE_AUDIO_LB_CTRL0) & 0x80000000) >> 31;
|
||||
int offset = EE_AUDIO_LB_B_CTRL0 - EE_AUDIO_LB_A_CTRL0;
|
||||
int reg = EE_AUDIO_LB_A_CTRL0 + offset * id;
|
||||
|
||||
audiobus_update_bits(reg, 0x7 << 0, src);
|
||||
}
|
||||
|
||||
void lb_enable(bool is_enable)
|
||||
void lb_set_datain_cfg(int id, struct data_cfg *datain_cfg)
|
||||
{
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_LB_CTRL0,
|
||||
0x1 << 31,
|
||||
is_enable << 31
|
||||
int offset = EE_AUDIO_LB_B_CTRL0 - EE_AUDIO_LB_A_CTRL0;
|
||||
int reg = EE_AUDIO_LB_A_CTRL0 + offset * id;
|
||||
|
||||
if (!datain_cfg)
|
||||
return;
|
||||
|
||||
if (datain_cfg->ch_ctrl_switch) {
|
||||
audiobus_update_bits(reg,
|
||||
1 << 29 | 0x7 << 13 | 0x1f << 8 | 0x1f << 3 | 0x7 << 0,
|
||||
datain_cfg->ext_signed << 29 |
|
||||
datain_cfg->type << 13 |
|
||||
datain_cfg->m << 8 |
|
||||
datain_cfg->n << 3 |
|
||||
datain_cfg->src << 0
|
||||
);
|
||||
|
||||
/* channel and mask */
|
||||
offset = EE_AUDIO_LB_B_CTRL2 - EE_AUDIO_LB_A_CTRL2;
|
||||
reg = EE_AUDIO_LB_A_CTRL2 + offset * id;
|
||||
audiobus_write(reg,
|
||||
(datain_cfg->chnum - 1) << 16 |
|
||||
datain_cfg->chmask << 0
|
||||
);
|
||||
} else
|
||||
audiobus_update_bits(reg,
|
||||
1 << 29 | 0x7 << 24 | 0xff << 16 |
|
||||
0x7 << 13 | 0x1f << 8 | 0x1f << 3 |
|
||||
0x7 << 0,
|
||||
datain_cfg->ext_signed << 29 |
|
||||
(datain_cfg->chnum - 1) << 24 |
|
||||
datain_cfg->chmask << 16 |
|
||||
datain_cfg->type << 13 |
|
||||
datain_cfg->m << 8 |
|
||||
datain_cfg->n << 3 |
|
||||
datain_cfg->src << 0
|
||||
);
|
||||
}
|
||||
|
||||
void lb_set_mode(int mode)
|
||||
void lb_set_datalb_cfg(int id, struct data_cfg *datalb_cfg)
|
||||
{
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_LB_CTRL0,
|
||||
0x1 << 30,
|
||||
mode << 30
|
||||
int offset = EE_AUDIO_LB_B_CTRL1 - EE_AUDIO_LB_A_CTRL1;
|
||||
int reg = EE_AUDIO_LB_A_CTRL1 + offset * id;
|
||||
|
||||
if (!datalb_cfg)
|
||||
return;
|
||||
|
||||
if (datalb_cfg->ch_ctrl_switch) {
|
||||
audiobus_update_bits(reg,
|
||||
0x1 << 29 | 0x7 << 13 | 0x1f << 8
|
||||
| 0x1f << 3 | 0x1 << 1,
|
||||
datalb_cfg->ext_signed << 29 |
|
||||
datalb_cfg->type << 13 |
|
||||
datalb_cfg->m << 8 |
|
||||
datalb_cfg->n << 3 |
|
||||
datalb_cfg->datalb_src << 0
|
||||
);
|
||||
|
||||
/* channel and mask */
|
||||
offset = EE_AUDIO_LB_B_CTRL3 - EE_AUDIO_LB_A_CTRL3;
|
||||
reg = EE_AUDIO_LB_A_CTRL3 + offset * id;
|
||||
audiobus_write(reg,
|
||||
(datalb_cfg->chnum - 1) << 16 |
|
||||
datalb_cfg->chmask << 0
|
||||
);
|
||||
} else
|
||||
audiobus_write(reg,
|
||||
datalb_cfg->ext_signed << 29 |
|
||||
(datalb_cfg->chnum - 1) << 24 |
|
||||
datalb_cfg->chmask << 16 |
|
||||
datalb_cfg->type << 13 |
|
||||
datalb_cfg->m << 8 |
|
||||
datalb_cfg->n << 3
|
||||
);
|
||||
}
|
||||
|
||||
void lb_enable(int id, bool enable)
|
||||
{
|
||||
int offset = EE_AUDIO_LB_B_CTRL0 - EE_AUDIO_LB_A_CTRL0;
|
||||
int reg = EE_AUDIO_LB_A_CTRL0 + offset * id;
|
||||
|
||||
audiobus_update_bits(reg, 0x1 << 31, enable << 31);
|
||||
}
|
||||
|
||||
@@ -18,54 +18,55 @@
|
||||
#ifndef __AML_LOOPBACK_HW_H__
|
||||
#define __AML_LOOPBACK_HW_H__
|
||||
|
||||
#include "audio_utils.h"
|
||||
#include <linux/types.h>
|
||||
|
||||
struct lb_cfg {
|
||||
struct data_cfg {
|
||||
/*
|
||||
* 0: extend bits as "0"
|
||||
* 1: extend bits as "msb"
|
||||
*/
|
||||
unsigned int ext_signed;
|
||||
/* total channel number */
|
||||
/* channel number */
|
||||
unsigned int chnum;
|
||||
/* which channel is selected for loopback */
|
||||
/* channel selected */
|
||||
unsigned int chmask;
|
||||
/* combined data */
|
||||
unsigned int type;
|
||||
/* the msb positioin in data */
|
||||
unsigned int m;
|
||||
/* the lsb position in data */
|
||||
unsigned int n;
|
||||
|
||||
/* loopback datalb src */
|
||||
unsigned int src;
|
||||
|
||||
unsigned int datalb_src;
|
||||
|
||||
/* channel and mask in new ctrol register */
|
||||
bool ch_ctrl_switch;
|
||||
};
|
||||
|
||||
struct data_in {
|
||||
struct lb_cfg *config;
|
||||
struct audio_data *ddrdata;
|
||||
};
|
||||
extern void tdminlb_set_clk(int datatlb_src,
|
||||
int sclk_div, int ratio, bool enable);
|
||||
|
||||
struct data_lb {
|
||||
struct lb_cfg *config;
|
||||
unsigned int ddr_type;
|
||||
unsigned int msb;
|
||||
unsigned int lsb;
|
||||
};
|
||||
extern void tdminlb_set_format(int i2s_fmt);
|
||||
|
||||
struct loopback {
|
||||
struct device *dev;
|
||||
unsigned int lb_mode;
|
||||
extern void tdminlb_set_ctrl(int src);
|
||||
|
||||
struct data_in *datain;
|
||||
struct data_lb *datalb;
|
||||
};
|
||||
extern void tdminlb_enable(int tdm_index, int in_enable);
|
||||
|
||||
extern void tdminlb_fifo_enable(int is_enable);
|
||||
|
||||
extern void tdminlb_set_format(int i2s_fmt);
|
||||
extern void tdminlb_set_lanemask_and_chswap(int swap, int lane_mask);
|
||||
|
||||
|
||||
extern void datain_config(struct data_in *datain);
|
||||
extern void tdminlb_set_src(int src);
|
||||
extern void lb_set_datain_src(int id, int src);
|
||||
|
||||
extern void datalb_config(struct data_lb *datalb);
|
||||
extern void lb_set_datain_cfg(int id, struct data_cfg *datain_cfg);
|
||||
extern void lb_set_datalb_cfg(int id, struct data_cfg *datalb_cfg);
|
||||
|
||||
extern void datalb_ctrl(struct loopback_cfg *lb_cfg);
|
||||
extern void lb_enable(int id, bool enable);
|
||||
|
||||
extern int lb_is_enable(void);
|
||||
|
||||
extern void lb_enable(bool is_enable);
|
||||
|
||||
extern void lb_mode(int mode);
|
||||
|
||||
extern void tdmin_lb_enable(int tdm_index, int in_enable);
|
||||
|
||||
extern void tdmin_lb_fifo_enable(int is_enable);
|
||||
#endif
|
||||
|
||||
104
sound/soc/amlogic/auge/loopback_match_table.c
Normal file
104
sound/soc/amlogic/auge/loopback_match_table.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* sound/soc/amlogic/auge/loopback_match_table.c
|
||||
*
|
||||
* Copyright (C) 2019 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 LOOPBACKA 0
|
||||
#define LOOPBACKB 1
|
||||
|
||||
struct loopback_chipinfo {
|
||||
unsigned int id;
|
||||
|
||||
/* reset all modules, after g12a
|
||||
* it has reset bits control for modules
|
||||
*/
|
||||
bool is_reset_all;
|
||||
|
||||
/* channel and mask switch to ctrl2, ctrl3 from tl1
|
||||
* for datain, 0: channel and mask is controlled by ctrl0
|
||||
* 1: channel and mask is controlled by ctrl2
|
||||
* for datalb, 0: channel and mask is controlled by ctrl1
|
||||
* 1: channel and mask is controlled by ctrl3
|
||||
*/
|
||||
bool ch_ctrl;
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo tl1_loopbacka_chipinfo = {
|
||||
.id = LOOPBACKA,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo tl1_loopbackb_chipinfo = {
|
||||
.id = LOOPBACKB,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo sm1_loopbacka_chipinfo = {
|
||||
.id = LOOPBACKA,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo sm1_loopbackb_chipinfo = {
|
||||
.id = LOOPBACKB,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo tm2_loopbacka_chipinfo = {
|
||||
.id = LOOPBACKA,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static struct loopback_chipinfo tm2_loopbackb_chipinfo = {
|
||||
.id = LOOPBACKB,
|
||||
.ch_ctrl = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id loopback_device_id[] = {
|
||||
{
|
||||
.compatible = "amlogic, snd-loopback",
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, axg-loopback",
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, g12a-loopback",
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tl1-loopbacka",
|
||||
.data = &tl1_loopbacka_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tl1-loopbackb",
|
||||
.data = &tl1_loopbackb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-loopbacka",
|
||||
.data = &sm1_loopbacka_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-loopbackb",
|
||||
.data = &sm1_loopbackb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-loopbacka",
|
||||
.data = &tm2_loopbacka_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-loopbackb",
|
||||
.data = &tm2_loopbackb_chipinfo,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, loopback_device_id);
|
||||
@@ -76,8 +76,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
|
||||
.mask = 0
|
||||
};
|
||||
|
||||
static int s_pdm_filter_mode;
|
||||
|
||||
static const char *const pdm_filter_mode_texts[] = {
|
||||
"Filter Mode 0",
|
||||
"Filter Mode 1",
|
||||
@@ -94,7 +92,13 @@ static int aml_pdm_filter_mode_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = s_pdm_filter_mode;
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = p_pdm->filter_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -103,7 +107,13 @@ static int aml_pdm_filter_mode_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
s_pdm_filter_mode = ucontrol->value.enumerated.item[0];
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
p_pdm->filter_mode = ucontrol->value.enumerated.item[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -137,8 +147,6 @@ static int pdm_hcic_shift_gain_set_enum(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pdm_dclk;
|
||||
|
||||
static const char *const pdm_dclk_texts[] = {
|
||||
"PDM Dclk 3.072m, support 8k/16k/32k/48k/64k/96k",
|
||||
"PDM Dclk 1.024m, support 8k/16k",
|
||||
@@ -153,7 +161,13 @@ static int pdm_dclk_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = pdm_dclk;
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = p_pdm->dclk_idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -162,7 +176,56 @@ static int pdm_dclk_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
pdm_dclk = ucontrol->value.enumerated.item[0];
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
p_pdm->dclk_idx = ucontrol->value.enumerated.item[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *const pdm_bypass_texts[] = {
|
||||
"PCM Data",
|
||||
"Raw Data/Bypass Data",
|
||||
};
|
||||
|
||||
static const struct soc_enum pdm_bypass_enum =
|
||||
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(pdm_bypass_texts),
|
||||
pdm_bypass_texts);
|
||||
|
||||
static int pdm_bypass_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = p_pdm->bypass;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pdm_bypass_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
p_pdm->bypass = ucontrol->value.enumerated.item[0];
|
||||
|
||||
if (p_pdm->clk_on)
|
||||
pdm_set_bypass_data((bool)p_pdm->bypass);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -180,8 +243,11 @@ static int pdm_train_get_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm)
|
||||
return 0;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = p_pdm->train_en;
|
||||
|
||||
@@ -192,10 +258,11 @@ static int pdm_train_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
|
||||
|
||||
if (!p_pdm->chipinfo ||
|
||||
if (!p_pdm ||
|
||||
!p_pdm->chipinfo ||
|
||||
!p_pdm->chipinfo->train ||
|
||||
(p_pdm->train_en == ucontrol->value.enumerated.item[0]))
|
||||
return 0;
|
||||
@@ -230,6 +297,11 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = {
|
||||
pdm_train_enum,
|
||||
pdm_train_get_enum,
|
||||
pdm_train_set_enum),
|
||||
|
||||
SOC_ENUM_EXT("PDM Bypass",
|
||||
pdm_bypass_enum,
|
||||
pdm_bypass_get_enum,
|
||||
pdm_bypass_set_enum),
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -252,7 +324,7 @@ static int pdm_mute_val_get(struct snd_kcontrol *kcontrol,
|
||||
val = pdm_get_mute_value();
|
||||
ucontrol->value.integer.value[0] = val;
|
||||
|
||||
pr_info("%s:get mute_val:0x%x\n",
|
||||
pr_info("%s, get mute_val:0x%x\n",
|
||||
__func__,
|
||||
val);
|
||||
|
||||
@@ -264,7 +336,7 @@ static int pdm_mute_val_set(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
int val = (int)ucontrol->value.integer.value[0];
|
||||
|
||||
pr_info("%s:set mute_val:0x%x\n",
|
||||
pr_info("%s, set mute_val:0x%x\n",
|
||||
__func__,
|
||||
val);
|
||||
|
||||
@@ -302,7 +374,7 @@ static int pdm_mute_chmask_get(struct snd_kcontrol *kcontrol,
|
||||
|
||||
ucontrol->value.integer.value[0] = val;
|
||||
|
||||
pr_info("%s:get pdm channel mask val:0x%x\n",
|
||||
pr_info("%s, get pdm channel mask val:0x%x\n",
|
||||
__func__,
|
||||
val);
|
||||
|
||||
@@ -319,7 +391,7 @@ static int pdm_mute_chmask_set(struct snd_kcontrol *kcontrol,
|
||||
if (val > 255)
|
||||
val = 255;
|
||||
|
||||
pr_info("%s:set pdm channel mask val:0x%x\n",
|
||||
pr_info("%s, set pdm channel mask val:0x%x\n",
|
||||
__func__,
|
||||
val);
|
||||
|
||||
@@ -379,11 +451,25 @@ static irqreturn_t aml_pdm_isr_handler(int irq, void *data)
|
||||
{
|
||||
struct snd_pcm_substream *substream =
|
||||
(struct snd_pcm_substream *)data;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct device *dev = rtd->platform->dev;
|
||||
struct aml_pdm *p_pdm = (struct aml_pdm *)dev_get_drvdata(dev);
|
||||
unsigned int status;
|
||||
int train_sts = pdm_train_sts();
|
||||
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
snd_pcm_period_elapsed(substream);
|
||||
if (!snd_pcm_running(substream))
|
||||
return IRQ_NONE;
|
||||
|
||||
status = aml_toddr_get_status(p_pdm->tddr) & MEMIF_INT_MASK;
|
||||
if (status & MEMIF_INT_COUNT_REPEAT) {
|
||||
snd_pcm_period_elapsed(substream);
|
||||
|
||||
aml_toddr_ack_irq(p_pdm->tddr, MEMIF_INT_COUNT_REPEAT);
|
||||
} else
|
||||
dev_dbg(dev, "unexpected irq - STS 0x%02x\n",
|
||||
status);
|
||||
|
||||
if (train_sts) {
|
||||
pr_debug("%s train result:0x%x\n",
|
||||
@@ -392,7 +478,7 @@ static irqreturn_t aml_pdm_isr_handler(int irq, void *data)
|
||||
pdm_train_clr();
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
return !status ? IRQ_NONE : IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int aml_pdm_open(struct snd_pcm_substream *substream)
|
||||
@@ -404,7 +490,7 @@ static int aml_pdm_open(struct snd_pcm_substream *substream)
|
||||
dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
pr_info("%s, stream:%d\n",
|
||||
pr_debug("%s, stream:%d\n",
|
||||
__func__, substream->stream);
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream, &aml_pdm_hardware);
|
||||
@@ -453,7 +539,7 @@ static int aml_pdm_close(struct snd_pcm_substream *substream)
|
||||
struct device *dev = rtd->platform->dev;
|
||||
struct aml_pdm *p_pdm = (struct aml_pdm *)dev_get_drvdata(dev);
|
||||
|
||||
pr_info("enter %s type: %d\n",
|
||||
pr_debug("enter %s type: %d\n",
|
||||
__func__, substream->stream);
|
||||
|
||||
aml_audio_unregister_toddr(p_pdm->dev, substream);
|
||||
@@ -469,7 +555,7 @@ static int aml_pdm_hw_params(
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int ret = 0;
|
||||
|
||||
pr_info("enter %s\n", __func__);
|
||||
pr_debug("enter %s\n", __func__);
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = params_buffer_bytes(params);
|
||||
@@ -480,7 +566,7 @@ static int aml_pdm_hw_params(
|
||||
|
||||
static int aml_pdm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
pr_debug("%s\n", __func__);
|
||||
snd_pcm_lib_free_pages(substream);
|
||||
|
||||
return 0;
|
||||
@@ -547,7 +633,7 @@ static int aml_pdm_silence(
|
||||
unsigned char *ppos = NULL;
|
||||
ssize_t n;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
n = frames_to_bytes(runtime, count);
|
||||
ppos = runtime->dma_area + frames_to_bytes(runtime, pos);
|
||||
@@ -564,7 +650,7 @@ static int aml_pdm_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
|
||||
int size = aml_pdm_hardware.buffer_bytes_max;
|
||||
int ret = -EINVAL;
|
||||
|
||||
pr_info("%s dai->name: %s dai->id: %d\n",
|
||||
pr_debug("%s dai->name: %s dai->id: %d\n",
|
||||
__func__, dai->name, dai->id);
|
||||
|
||||
/* only capture for PDM */
|
||||
@@ -586,7 +672,7 @@ static void aml_pdm_pcm_free(struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
|
||||
if (substream) {
|
||||
@@ -611,7 +697,7 @@ static struct snd_pcm_ops aml_pdm_ops = {
|
||||
|
||||
static int aml_pdm_probe(struct snd_soc_platform *platform)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -638,7 +724,6 @@ static int aml_pdm_dai_set_fmt(
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int aml_pdm_dai_prepare(
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
@@ -652,6 +737,8 @@ static int aml_pdm_dai_prepare(
|
||||
&& pm_audio_is_suspend())
|
||||
return 0;
|
||||
|
||||
p_pdm->rate = runtime->rate;
|
||||
|
||||
/* set bclk */
|
||||
bitwidth = snd_pcm_format_width(runtime->format);
|
||||
lsb = 32 - bitwidth;
|
||||
@@ -670,17 +757,16 @@ static int aml_pdm_dai_prepare(
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_info("%s rate:%d, bits:%d, channels:%d\n",
|
||||
pr_debug("%s rate:%d, bits:%d, channels:%d\n",
|
||||
__func__,
|
||||
runtime->rate,
|
||||
bitwidth,
|
||||
runtime->channels);
|
||||
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
struct toddr *to = p_pdm->tddr;
|
||||
struct toddr_fmt fmt;
|
||||
unsigned int osr = 192;
|
||||
unsigned int osr = 192, filter_mode;
|
||||
struct pdm_info info;
|
||||
|
||||
/* to ddr pdmin */
|
||||
@@ -698,49 +784,27 @@ static int aml_pdm_dai_prepare(
|
||||
info.bitdepth = bitwidth;
|
||||
info.channels = runtime->channels;
|
||||
info.lane_masks = p_pdm->lane_mask_in;
|
||||
info.dclk_idx = pdm_dclk;
|
||||
info.dclk_idx = p_pdm->dclk_idx;
|
||||
info.bypass = p_pdm->bypass;
|
||||
info.sample_count = pdm_get_sample_count(p_pdm->isLowPower,
|
||||
p_pdm->dclk_idx);
|
||||
aml_pdm_ctrl(&info);
|
||||
|
||||
filter_mode = p_pdm->filter_mode;
|
||||
|
||||
/* filter for pdm */
|
||||
if (pdm_dclk == 1) {
|
||||
if (runtime->rate == 16000)
|
||||
osr = 64;
|
||||
else if (runtime->rate == 8000)
|
||||
osr = 128;
|
||||
else {
|
||||
pr_err("Not support rate:%d\n", runtime->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (pdm_dclk == 2) {
|
||||
if (runtime->rate == 16000)
|
||||
osr = 48;
|
||||
else if (runtime->rate == 8000)
|
||||
osr = 96;
|
||||
else {
|
||||
pr_err("Not support rate:%d\n", runtime->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (runtime->rate == 96000)
|
||||
osr = 32;
|
||||
else if (runtime->rate == 64000)
|
||||
osr = 48;
|
||||
else if (runtime->rate == 48000)
|
||||
osr = 64;
|
||||
else if (runtime->rate == 32000)
|
||||
osr = 96;
|
||||
else if (runtime->rate == 16000)
|
||||
osr = 192;
|
||||
else if (runtime->rate == 8000)
|
||||
osr = 384;
|
||||
else {
|
||||
pr_err("Not support rate:%d\n", runtime->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
p_pdm->filter_mode = s_pdm_filter_mode;
|
||||
aml_pdm_filter_ctrl(osr, p_pdm->filter_mode);
|
||||
osr = pdm_get_ors(p_pdm->dclk_idx, runtime->rate);
|
||||
if (!osr)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("%s, pdm_dclk:%d, osr:%d, rate:%d filter mode:%d\n",
|
||||
__func__,
|
||||
pdm_dclkidx2rate(p_pdm->dclk_idx),
|
||||
osr,
|
||||
runtime->rate,
|
||||
p_pdm->filter_mode);
|
||||
|
||||
aml_pdm_filter_ctrl(osr, filter_mode);
|
||||
|
||||
if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data)
|
||||
pdm_init_truncate_data(runtime->rate);
|
||||
@@ -755,7 +819,7 @@ static int aml_pdm_dai_trigger(
|
||||
{
|
||||
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
|
||||
pr_info("%s, cmd:%d\n", __func__, cmd);
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
@@ -773,7 +837,7 @@ static int aml_pdm_dai_trigger(
|
||||
pdm_fifo_reset();
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
dev_info(substream->pcm->card->dev, "pdm capture start\n");
|
||||
dev_info(substream->pcm->card->dev, "PDM Capture start\n");
|
||||
aml_toddr_enable(p_pdm->tddr, 1);
|
||||
pdm_enable(1);
|
||||
}
|
||||
@@ -820,37 +884,21 @@ static int aml_pdm_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
|
||||
|
||||
if (dclk_srcpll_freq == 0)
|
||||
clk_set_rate(p_pdm->dclk_srcpll, 24576000);
|
||||
else
|
||||
pr_info("pdm dclk_srcpll:%lu\n",
|
||||
clk_get_rate(p_pdm->dclk_srcpll));
|
||||
#endif
|
||||
if (pdm_dclk == 1)
|
||||
clk_set_rate(p_pdm->clk_pdm_dclk, 1024000);
|
||||
else if (pdm_dclk == 2)
|
||||
clk_set_rate(p_pdm->clk_pdm_dclk, 768000);
|
||||
else
|
||||
clk_set_rate(p_pdm->clk_pdm_dclk, 3072000);
|
||||
clk_set_rate(p_pdm->clk_pdm_dclk,
|
||||
pdm_dclkidx2rate(p_pdm->dclk_idx));
|
||||
|
||||
pr_info("pdm pdm_sysclk:%lu clk_pdm_dclk:%lu\n",
|
||||
pr_info("\n%s, pdm_sysclk:%lu pdm_dclk:%lu, dclk_srcpll:%lu\n",
|
||||
__func__,
|
||||
clk_get_rate(p_pdm->clk_pdm_sysclk),
|
||||
clk_get_rate(p_pdm->clk_pdm_dclk));
|
||||
clk_get_rate(p_pdm->clk_pdm_dclk),
|
||||
clk_get_rate(p_pdm->dclk_srcpll));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_pdm_dai_probe(struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = snd_soc_add_dai_controls(cpu_dai, snd_pdm_controls,
|
||||
ARRAY_SIZE(snd_pdm_controls));
|
||||
if (ret < 0) {
|
||||
pr_err("%s, failed add snd pdm controls\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -919,6 +967,7 @@ void aml_pdm_dai_shutdown(struct snd_pcm_substream *substream,
|
||||
#endif
|
||||
|
||||
p_pdm->clk_on = false;
|
||||
p_pdm->rate = 0;
|
||||
|
||||
/* disable clock and gate */
|
||||
clk_disable_unprepare(p_pdm->clk_pdm_dclk);
|
||||
@@ -955,6 +1004,8 @@ EXPORT_SYMBOL_GPL(aml_pdm_dai);
|
||||
|
||||
static const struct snd_soc_component_driver aml_pdm_component = {
|
||||
.name = DRV_NAME,
|
||||
.controls = snd_pdm_controls,
|
||||
.num_controls = ARRAY_SIZE(snd_pdm_controls),
|
||||
};
|
||||
|
||||
static int snd_soc_of_get_slot_mask(
|
||||
@@ -1094,9 +1145,6 @@ static int aml_pdm_platform_probe(struct platform_device *pdev)
|
||||
/* defulat set 1 */
|
||||
p_pdm->filter_mode = 1;
|
||||
}
|
||||
s_pdm_filter_mode = p_pdm->filter_mode;
|
||||
pr_info("%s pdm filter mode from dts:%d\n",
|
||||
__func__, p_pdm->filter_mode);
|
||||
|
||||
p_pdm->dev = dev;
|
||||
dev_set_drvdata(&pdev->dev, p_pdm);
|
||||
@@ -1126,10 +1174,10 @@ err:
|
||||
|
||||
static int aml_pdm_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct aml_pdm *pdm_priv = dev_get_drvdata(&pdev->dev);
|
||||
struct aml_pdm *p_pdm = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
clk_disable_unprepare(pdm_priv->sysclk_srcpll);
|
||||
clk_disable_unprepare(pdm_priv->clk_pdm_dclk);
|
||||
clk_disable_unprepare(p_pdm->sysclk_srcpll);
|
||||
clk_disable_unprepare(p_pdm->clk_pdm_dclk);
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
/* 8ch pdm in, 8 ch tdmin_lb */
|
||||
#define PDM_CHANNELS_LB_MAX (PDM_CHANNELS_MAX + 8)
|
||||
|
||||
|
||||
#define PDM_RATES (SNDRV_PCM_RATE_96000 |\
|
||||
SNDRV_PCM_RATE_64000 |\
|
||||
SNDRV_PCM_RATE_48000 |\
|
||||
@@ -70,6 +69,8 @@ struct aml_pdm {
|
||||
struct clk *clk_pdm_sysclk;
|
||||
struct clk *clk_pdm_dclk;
|
||||
struct toddr *tddr;
|
||||
/* sample rate */
|
||||
int rate;
|
||||
/*
|
||||
* filter mode:0~4,
|
||||
* from mode 0 to 4, the performance is from high to low,
|
||||
@@ -90,6 +91,9 @@ struct aml_pdm {
|
||||
/* train */
|
||||
bool train_en;
|
||||
|
||||
/* low power mode, for dclk_sycpll to 24m */
|
||||
bool isLowPower;
|
||||
|
||||
struct pdm_chipinfo *chipinfo;
|
||||
struct snd_kcontrol *controls[PDM_RUN_MAX];
|
||||
};
|
||||
|
||||
@@ -70,22 +70,28 @@ void pdm_fifo_reset(void)
|
||||
0x1 << 16);
|
||||
}
|
||||
|
||||
void pdm_set_channel_ctrl(int sample_count)
|
||||
{
|
||||
aml_pdm_write(PDM_CHAN_CTRL, ((sample_count << 24) |
|
||||
(sample_count << 16) |
|
||||
(sample_count << 8) |
|
||||
(sample_count << 0)
|
||||
));
|
||||
aml_pdm_write(PDM_CHAN_CTRL1, ((sample_count << 24) |
|
||||
(sample_count << 16) |
|
||||
(sample_count << 8) |
|
||||
(sample_count << 0)
|
||||
));
|
||||
}
|
||||
|
||||
void aml_pdm_ctrl(struct pdm_info *info)
|
||||
{
|
||||
int mode, i, ch_mask = 0, sample_count;
|
||||
int mode, i, ch_mask = 0;
|
||||
int pdm_chs, lane_chs = 0;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
/* sameple count */
|
||||
if (info->dclk_idx == 1)
|
||||
sample_count = 38;
|
||||
else if (info->dclk_idx == 2)
|
||||
sample_count = 48;
|
||||
else
|
||||
sample_count = 18;
|
||||
|
||||
if (info->bitdepth == 32)
|
||||
mode = 0;
|
||||
else
|
||||
@@ -124,7 +130,6 @@ void aml_pdm_ctrl(struct pdm_info *info)
|
||||
/* must be sure that clk and pdm is enable */
|
||||
aml_pdm_update_bits(PDM_CTRL,
|
||||
(0x7 << 28 | 0xff << 8 | 0xff << 0),
|
||||
/*(1 << 31) |*/
|
||||
/* invert the PDM_DCLK or not */
|
||||
(0 << 30) |
|
||||
/* output mode: 1: 24bits. 0: 32 bits */
|
||||
@@ -139,16 +144,7 @@ void aml_pdm_ctrl(struct pdm_info *info)
|
||||
(ch_mask << 0)
|
||||
);
|
||||
|
||||
aml_pdm_write(PDM_CHAN_CTRL, ((sample_count << 24) |
|
||||
(sample_count << 16) |
|
||||
(sample_count << 8) |
|
||||
(sample_count << 0)
|
||||
));
|
||||
aml_pdm_write(PDM_CHAN_CTRL1, ((sample_count << 24) |
|
||||
(sample_count << 16) |
|
||||
(sample_count << 8) |
|
||||
(sample_count << 0)
|
||||
));
|
||||
pdm_set_channel_ctrl(info->sample_count);
|
||||
}
|
||||
|
||||
void aml_pdm_arb_config(struct aml_audio_controller *actrl)
|
||||
@@ -351,9 +347,6 @@ void aml_pdm_filter_ctrl(int osr, int mode)
|
||||
int lpf1_len, lpf2_len, lpf3_len;
|
||||
const int *lpf1_coeff, *lpf2_coeff, *lpf3_coeff;
|
||||
|
||||
pr_info("%s, osr:%d, mode:%d\n",
|
||||
__func__, osr, mode);
|
||||
|
||||
/* select LPF coefficent
|
||||
* For filter 1 and filter 3,
|
||||
* it's only relative with coefficent mode
|
||||
@@ -489,6 +482,11 @@ void pdm_set_mute_channel(int mute_chmask)
|
||||
(mute_chmask << 20 | mute_en << 17));
|
||||
}
|
||||
|
||||
void pdm_set_bypass_data(bool bypass)
|
||||
{
|
||||
aml_pdm_update_bits(PDM_CTRL, 0x1 << 28, bypass << 28);
|
||||
}
|
||||
|
||||
void pdm_init_truncate_data(int freq)
|
||||
{
|
||||
int mask_val;
|
||||
@@ -519,3 +517,71 @@ int pdm_train_sts(void)
|
||||
|
||||
return ((val >> 4) & 0xff);
|
||||
}
|
||||
|
||||
int pdm_dclkidx2rate(int idx)
|
||||
{
|
||||
int rate;
|
||||
|
||||
if (idx == 2)
|
||||
rate = 768000;
|
||||
else if (idx == 1)
|
||||
rate = 1024000;
|
||||
else
|
||||
rate = 3072000;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
int pdm_get_sample_count(int isLowPower, int dclk_idx)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (isLowPower)
|
||||
count = 0;
|
||||
else if (dclk_idx == 1)
|
||||
count = 38;
|
||||
else if (dclk_idx == 2)
|
||||
count = 48;
|
||||
else
|
||||
count = 18;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int pdm_get_ors(int dclk_idx, int sample_rate)
|
||||
{
|
||||
int osr = 0;
|
||||
|
||||
if (dclk_idx == 1) {
|
||||
if (sample_rate == 16000)
|
||||
osr = 64;
|
||||
else if (sample_rate == 8000)
|
||||
osr = 128;
|
||||
else
|
||||
pr_err("Not support rate:%d\n", sample_rate);
|
||||
} else if (dclk_idx == 2) {
|
||||
if (sample_rate == 16000)
|
||||
osr = 48;
|
||||
else if (sample_rate == 8000)
|
||||
osr = 96;
|
||||
else
|
||||
pr_err("Not support rate:%d\n", sample_rate);
|
||||
} else {
|
||||
if (sample_rate == 96000)
|
||||
osr = 32;
|
||||
else if (sample_rate == 64000)
|
||||
osr = 48;
|
||||
else if (sample_rate == 48000)
|
||||
osr = 64;
|
||||
else if (sample_rate == 32000)
|
||||
osr = 96;
|
||||
else if (sample_rate == 16000)
|
||||
osr = 192;
|
||||
else if (sample_rate == 8000)
|
||||
osr = 384;
|
||||
else
|
||||
pr_err("Not support rate:%d\n", sample_rate);
|
||||
}
|
||||
|
||||
return osr;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ struct pdm_info {
|
||||
|
||||
int dclk_idx; /* mapping for dclk value */
|
||||
int bypass; /* bypass all filter, capture raw data */
|
||||
int sample_count;
|
||||
};
|
||||
|
||||
extern void aml_pdm_ctrl(struct pdm_info *info);
|
||||
@@ -47,14 +48,20 @@ extern int pdm_get_mute_value(void);
|
||||
extern void pdm_set_mute_value(int val);
|
||||
extern int pdm_get_mute_channel(void);
|
||||
extern void pdm_set_mute_channel(int mute_chmask);
|
||||
|
||||
extern void pdm_set_bypass_data(bool bypass);
|
||||
extern void pdm_init_truncate_data(int freq);
|
||||
extern void pdm_train_en(bool en);
|
||||
extern void pdm_train_clr(void);
|
||||
extern int pdm_train_sts(void);
|
||||
|
||||
extern int pdm_dclkidx2rate(int idx);
|
||||
extern int pdm_get_sample_count(int isLowPower, int dclk_idx);
|
||||
extern int pdm_get_ors(int dclk_idx, int sample_rate);
|
||||
|
||||
extern void pdm_train_en(bool en);
|
||||
extern void pdm_train_clr(void);
|
||||
extern int pdm_train_sts(void);
|
||||
|
||||
extern int pdm_hcic_shift_gain;
|
||||
extern int pdm_dclk;
|
||||
|
||||
#endif /*__AML_PDM_HW_H__*/
|
||||
|
||||
@@ -197,16 +197,41 @@ enum clk_sel {
|
||||
#define EE_AUDIO_ARB_CTRL 0x0a0
|
||||
|
||||
/*
|
||||
* AUDIO TDM
|
||||
* AUDIO LOOPBACK
|
||||
*/
|
||||
#define EE_AUDIO_LB_CTRL0 0x0b0
|
||||
#define EE_AUDIO_LB_CTRL1 0x0b1
|
||||
#define EE_AUDIO_DAT_ID0 0x0b2
|
||||
#define EE_AUDIO_DAT_ID1 0x0b3
|
||||
#define EE_AUDIO_LB_ID0 0x0b4
|
||||
#define EE_AUDIO_LB_ID1 0x0b5
|
||||
#define EE_AUDIO_LB_STS 0x0b6
|
||||
|
||||
#define EE_AUDIO_LB_A_CTRL0 0xb0
|
||||
#define EE_AUDIO_LB_A_CTRL1 0xb1
|
||||
#define EE_AUDIO_LB_A_CTRL2 0xb2
|
||||
#define EE_AUDIO_LB_A_CTRL3 0xb3
|
||||
#define EE_AUDIO_LB_A_DAT_CH_ID0 0xb4
|
||||
#define EE_AUDIO_LB_A_DAT_CH_ID1 0xb5
|
||||
#define EE_AUDIO_LB_A_DAT_CH_ID2 0xb6
|
||||
#define EE_AUDIO_LB_A_DAT_CH_ID3 0xb7
|
||||
#define EE_AUDIO_LB_A_LB_CH_ID0 0xb8
|
||||
#define EE_AUDIO_LB_A_LB_CH_ID1 0xb9
|
||||
#define EE_AUDIO_LB_A_LB_CH_ID2 0xba
|
||||
#define EE_AUDIO_LB_A_LB_CH_ID3 0xbb
|
||||
#define EE_AUDIO_LB_A_STS 0xbc
|
||||
|
||||
#define EE_AUDIO_LB_B_CTRL0 0x230
|
||||
#define EE_AUDIO_LB_B_CTRL1 0x231
|
||||
#define EE_AUDIO_LB_B_CTRL2 0x232
|
||||
#define EE_AUDIO_LB_B_CTRL3 0x233
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID0 0x234
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID1 0x235
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID2 0x236
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID3 0x237
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID0 0x238
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID1 0x239
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID2 0x23a
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID3 0x23b
|
||||
#define EE_AUDIO_LB_B_STS 0x23c
|
||||
|
||||
/*
|
||||
* AUDIO TDM
|
||||
*/
|
||||
#define EE_AUDIO_TDMIN_A_CTRL 0x0c0
|
||||
#define EE_AUDIO_TDMIN_A_SWAP0 0x0c1
|
||||
#define EE_AUDIO_TDMIN_A_SWAP1 0x260
|
||||
@@ -544,20 +569,6 @@ enum clk_sel {
|
||||
#define EE_AUDIO_FRDDR_D_INIT_ADDR 0x229
|
||||
#define EE_AUDIO_FRDDR_D_CTRL2 0x22a
|
||||
|
||||
#define EE_AUDIO_LB_B_CTRL0 0x230
|
||||
#define EE_AUDIO_LB_B_CTRL1 0x231
|
||||
#define EE_AUDIO_LB_B_CTRL2 0x232
|
||||
#define EE_AUDIO_LB_B_CTRL3 0x233
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID0 0x234
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID1 0x235
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID2 0x236
|
||||
#define EE_AUDIO_LB_B_DAT_CH_ID3 0x237
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID0 0x238
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID1 0x239
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID2 0x23a
|
||||
#define EE_AUDIO_LB_B_LB_CH_ID3 0x23b
|
||||
#define EE_AUDIO_LB_B_STS 0x23c
|
||||
|
||||
/*
|
||||
* AUDIO LOCKER
|
||||
*/
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "ddr_mngr.h"
|
||||
#include "spdif_hw.h"
|
||||
#include "spdif_match_table.c"
|
||||
#include "audio_utils.h"
|
||||
#include "resample.h"
|
||||
#include "resample_hw.h"
|
||||
|
||||
@@ -1163,50 +1162,30 @@ static int aml_dai_spdif_prepare(
|
||||
struct toddr_fmt fmt;
|
||||
unsigned int msb, lsb, toddr_type;
|
||||
|
||||
if (loopback_is_enable()) {
|
||||
switch (bit_depth) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
toddr_type = 0;
|
||||
break;
|
||||
case 24:
|
||||
toddr_type = 4;
|
||||
break;
|
||||
default:
|
||||
pr_err(
|
||||
"runtime format invalid bit_depth: %d\n",
|
||||
bit_depth);
|
||||
return -EINVAL;
|
||||
}
|
||||
msb = 32 - 1;
|
||||
lsb = 32 - bit_depth;
|
||||
} else {
|
||||
switch (bit_depth) {
|
||||
case 8:
|
||||
case 16:
|
||||
toddr_type = 0;
|
||||
break;
|
||||
case 24:
|
||||
toddr_type = 4;
|
||||
break;
|
||||
case 32:
|
||||
toddr_type = 3;
|
||||
break;
|
||||
default:
|
||||
dev_err(p_spdif->dev,
|
||||
"runtime format invalid bit_depth: %d\n",
|
||||
bit_depth);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msb = 28 - 1;
|
||||
if (bit_depth <= 24)
|
||||
lsb = 28 - bit_depth;
|
||||
else
|
||||
lsb = 4;
|
||||
switch (bit_depth) {
|
||||
case 8:
|
||||
case 16:
|
||||
toddr_type = 0;
|
||||
break;
|
||||
case 24:
|
||||
toddr_type = 4;
|
||||
break;
|
||||
case 32:
|
||||
toddr_type = 3;
|
||||
break;
|
||||
default:
|
||||
dev_err(p_spdif->dev,
|
||||
"runtime format invalid bit_depth: %d\n",
|
||||
bit_depth);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msb = 28 - 1;
|
||||
if (bit_depth <= 24)
|
||||
lsb = 28 - bit_depth;
|
||||
else
|
||||
lsb = 4;
|
||||
|
||||
// to ddr spdifin
|
||||
fmt.type = toddr_type;
|
||||
fmt.msb = msb;
|
||||
|
||||
@@ -107,6 +107,9 @@ struct aml_tdm {
|
||||
|
||||
bool en_share;
|
||||
unsigned int lane_cnt;
|
||||
|
||||
/* tdmin_lb src sel */
|
||||
int tdmin_lb_src;
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hardware aml_tdm_hardware = {
|
||||
@@ -537,6 +540,9 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream,
|
||||
case 2:
|
||||
src = TDMIN_C;
|
||||
break;
|
||||
case 3:
|
||||
src = TDMIN_LB;
|
||||
break;
|
||||
default:
|
||||
dev_err(p_tdm->dev, "invalid id: %d\n",
|
||||
p_tdm->id);
|
||||
@@ -935,7 +941,7 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream,
|
||||
struct frddr *fr = p_tdm->fddr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < p_tdm->lane_cnt; i++)
|
||||
aml_tdm_set_channel_mask(p_tdm->actrl,
|
||||
substream->stream, p_tdm->id, i, 0);
|
||||
|
||||
@@ -1178,20 +1184,15 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai,
|
||||
oe_val = p_tdm->setting.lane_oe_mask_out;
|
||||
}
|
||||
|
||||
if (lanes_lb_cnt) {
|
||||
in_src = p_tdm->id + 6;
|
||||
if (in_src > 7) {
|
||||
pr_err("unknown src(%d) for tdmin\n", in_src);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (lanes_lb_cnt)
|
||||
in_src = p_tdm->tdmin_lb_src;
|
||||
if (lanes_oe_in_cnt)
|
||||
in_src = p_tdm->id + 3;
|
||||
if (lanes_in_cnt)
|
||||
in_src = p_tdm->id;
|
||||
} else {
|
||||
if (lanes_lb_cnt)
|
||||
in_src = p_tdm->id + 3;
|
||||
in_src = p_tdm->tdmin_lb_src;
|
||||
if (lanes_in_cnt && lanes_in_cnt <= 4)
|
||||
in_src = p_tdm->id;
|
||||
if (in_src > 5) {
|
||||
@@ -1310,69 +1311,85 @@ static struct snd_soc_dai_ops aml_dai_tdm_ops = {
|
||||
|
||||
static struct snd_soc_dai_driver aml_tdm_dai[] = {
|
||||
{
|
||||
.name = "TDM-A",
|
||||
.id = 1,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
.name = "TDM-A",
|
||||
.id = 1,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
},
|
||||
{
|
||||
.name = "TDM-B",
|
||||
.id = 2,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
|
||||
.name = "TDM-B",
|
||||
.id = 2,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
},
|
||||
{
|
||||
.name = "TDM-C",
|
||||
.id = 3,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
.name = "TDM-C",
|
||||
.id = 3,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
},
|
||||
{
|
||||
.name = "TDMIN-LB",
|
||||
.id = 4,
|
||||
.probe = aml_dai_tdm_probe,
|
||||
.remove = aml_dai_tdm_remove,
|
||||
|
||||
.capture = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
.rates = AML_DAI_TDM_RATES,
|
||||
.formats = AML_DAI_TDM_FORMATS,
|
||||
},
|
||||
.ops = &aml_dai_tdm_ops,
|
||||
.symmetric_rates = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver aml_tdm_component = {
|
||||
.name = DRV_NAME,
|
||||
.name = DRV_NAME,
|
||||
};
|
||||
|
||||
static int check_channel_mask(const char *str)
|
||||
@@ -1520,9 +1537,23 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
|
||||
&p_tdm->i2s2hdmitx);
|
||||
if (ret < 0)
|
||||
p_tdm->i2s2hdmitx = 0;
|
||||
pr_info("TDM id %d i2s2hdmi:%d\n",
|
||||
p_tdm->id,
|
||||
p_tdm->i2s2hdmitx);
|
||||
else
|
||||
pr_info("TDM id %d i2s2hdmi:%d\n",
|
||||
p_tdm->id,
|
||||
p_tdm->i2s2hdmitx);
|
||||
|
||||
if (p_tdm->id == TDM_LB) {
|
||||
ret = of_property_read_u32(node, "lb-src-sel",
|
||||
&p_tdm->tdmin_lb_src);
|
||||
if (ret < 0 || (p_tdm->tdmin_lb_src > 7)) {
|
||||
dev_err(&pdev->dev, "invalid lb-src-sel:%d\n",
|
||||
p_tdm->tdmin_lb_src);
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_info("TDM id %d lb-src-sel:%d\n",
|
||||
p_tdm->id,
|
||||
p_tdm->tdmin_lb_src);
|
||||
}
|
||||
|
||||
/* get tdm lanes info. if not, set to default 0 */
|
||||
ret = of_parse_tdm_lane_slot_in(node,
|
||||
@@ -1594,6 +1625,12 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
|
||||
/*set default clk for output*/
|
||||
aml_set_default_tdm_clk(p_tdm);
|
||||
|
||||
/* mclk pad ctrl */
|
||||
ret = of_property_read_u32(node, "mclk_pad",
|
||||
&p_tdm->mclk_pad);
|
||||
if (ret < 0)
|
||||
p_tdm->mclk_pad = -1; /* not use mclk in defalut. */
|
||||
|
||||
p_tdm->dev = dev;
|
||||
/* For debug to disable share buffer */
|
||||
p_tdm->en_share = 1;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define TDM_A 0
|
||||
#define TDM_B 1
|
||||
#define TDM_C 2
|
||||
#define TDM_LB 3
|
||||
|
||||
#define LANE_MAX0 2
|
||||
#define LANE_MAX1 4
|
||||
|
||||
@@ -60,6 +60,11 @@ struct tdm_chipinfo axg_tdmc_chipinfo = {
|
||||
.no_mclkpad_ctrl = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo axg_tdminlb_chipinfo = {
|
||||
.id = TDM_LB,
|
||||
.no_mclkpad_ctrl = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo g12a_tdma_chipinfo = {
|
||||
.id = TDM_A,
|
||||
.sclk_ws_inv = true,
|
||||
@@ -84,6 +89,14 @@ struct tdm_chipinfo g12a_tdmc_chipinfo = {
|
||||
.mclkpad_no_offset = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo g12a_tdminlb_chipinfo = {
|
||||
.id = TDM_LB,
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.same_src_fn = true,
|
||||
.mclkpad_no_offset = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo tl1_tdma_chipinfo = {
|
||||
.id = TDM_A,
|
||||
.sclk_ws_inv = true,
|
||||
@@ -108,6 +121,14 @@ struct tdm_chipinfo tl1_tdmc_chipinfo = {
|
||||
.adc_fn = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo tl1_tdminlb_chipinfo = {
|
||||
.id = TDM_LB,
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.same_src_fn = true,
|
||||
.adc_fn = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo sm1_tdma_chipinfo = {
|
||||
.id = TDM_A,
|
||||
.sclk_ws_inv = true,
|
||||
@@ -132,6 +153,14 @@ struct tdm_chipinfo sm1_tdmc_chipinfo = {
|
||||
.lane_cnt = LANE_MAX1,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo sm1_tdminlb_chipinfo = {
|
||||
.id = TDM_LB,
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.same_src_fn = true,
|
||||
.lane_cnt = LANE_MAX3,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo tm2_tdma_chipinfo = {
|
||||
.id = TDM_A,
|
||||
.sclk_ws_inv = true,
|
||||
@@ -159,6 +188,14 @@ struct tdm_chipinfo tm2_tdmc_chipinfo = {
|
||||
.lane_cnt = LANE_MAX1,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo tm2_tdminlb_chipinfo = {
|
||||
.id = TDM_LB,
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.same_src_fn = true,
|
||||
.lane_cnt = LANE_MAX3,
|
||||
};
|
||||
|
||||
static const struct of_device_id aml_tdm_device_id[] = {
|
||||
{
|
||||
.compatible = "amlogic, axg-snd-tdma",
|
||||
@@ -172,6 +209,10 @@ static const struct of_device_id aml_tdm_device_id[] = {
|
||||
.compatible = "amlogic, axg-snd-tdmc",
|
||||
.data = &axg_tdmc_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, axg-snd-tdmlb",
|
||||
.data = &axg_tdminlb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, g12a-snd-tdma",
|
||||
.data = &g12a_tdma_chipinfo,
|
||||
@@ -184,6 +225,10 @@ static const struct of_device_id aml_tdm_device_id[] = {
|
||||
.compatible = "amlogic, g12a-snd-tdmc",
|
||||
.data = &g12a_tdmc_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, g12a-snd-tdmlb",
|
||||
.data = &g12a_tdminlb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tl1-snd-tdma",
|
||||
.data = &tl1_tdma_chipinfo,
|
||||
@@ -196,29 +241,41 @@ static const struct of_device_id aml_tdm_device_id[] = {
|
||||
.compatible = "amlogic, tl1-snd-tdmc",
|
||||
.data = &tl1_tdmc_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tl1-snd-tdmlb",
|
||||
.data = &tl1_tdminlb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-snd-tdma",
|
||||
.data = &sm1_tdma_chipinfo,
|
||||
.data = &sm1_tdma_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-snd-tdmb",
|
||||
.data = &sm1_tdmb_chipinfo,
|
||||
.data = &sm1_tdmb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-snd-tdmc",
|
||||
.data = &sm1_tdmc_chipinfo,
|
||||
.data = &sm1_tdmc_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, sm1-snd-tdmlb",
|
||||
.data = &sm1_tdminlb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-snd-tdma",
|
||||
.data = &tm2_tdma_chipinfo,
|
||||
.data = &tm2_tdma_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-snd-tdmb",
|
||||
.data = &tm2_tdmb_chipinfo,
|
||||
.data = &tm2_tdmb_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-snd-tdmc",
|
||||
.data = &tm2_tdmc_chipinfo,
|
||||
.data = &tm2_tdmc_chipinfo,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic, tm2-snd-tdmlb",
|
||||
.data = &tm2_tdminlb_chipinfo,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
@@ -34,18 +34,19 @@ static void ad82584f_early_suspend(struct early_suspend *h);
|
||||
static void ad82584f_late_resume(struct early_suspend *h);
|
||||
#endif
|
||||
|
||||
#define AD82584F_RATES (SNDRV_PCM_RATE_32000 | \
|
||||
SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_64000 | \
|
||||
SNDRV_PCM_RATE_88200 | \
|
||||
SNDRV_PCM_RATE_96000 | \
|
||||
SNDRV_PCM_RATE_176400 | \
|
||||
SNDRV_PCM_RATE_192000)
|
||||
#define AD82584F_RATES (SNDRV_PCM_RATE_16000 | \
|
||||
SNDRV_PCM_RATE_32000 | \
|
||||
SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_64000 | \
|
||||
SNDRV_PCM_RATE_88200 | \
|
||||
SNDRV_PCM_RATE_96000 | \
|
||||
SNDRV_PCM_RATE_176400 | \
|
||||
SNDRV_PCM_RATE_192000)
|
||||
|
||||
#define AD82584F_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(mvol_tlv, -10300, 50, 1);
|
||||
static const DECLARE_TLV_DB_SCALE(chvol_tlv, -10300, 50, 1);
|
||||
|
||||
Reference in New Issue
Block a user