From f8225ed348477cf3c304cbf0e1fdb1c8cdca0b2e Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Thu, 31 Aug 2017 00:00:35 +0800 Subject: [PATCH] audio: fix loopback channel map PD#149869: audio: fix tdmin_lb channel mask and swap for loopback Change-Id: I1bf2dd42a2869ca2404b72e1f0e57a267f365e23 Signed-off-by: Xing Wang --- arch/arm64/boot/dts/amlogic/axg_s400.dts | 2 +- arch/arm64/boot/dts/amlogic/axg_s400_v03.dts | 16 ++--- arch/arm64/boot/dts/amlogic/axg_s420_v03.dts | 36 ++++++++++++ sound/soc/amlogic/auge/audio_utils.c | 2 +- sound/soc/amlogic/auge/loopback_hw.c | 62 +++++++++++++++++--- sound/soc/amlogic/auge/loopback_hw.h | 2 +- 6 files changed, 101 insertions(+), 19 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index 24efa573e1bd..86a068d972f4 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -1050,7 +1050,7 @@ * 5: PAD_tdminC */ datalb_src = <2>; - datalb_chnum = <8>; + datalb_chnum = <2>; datalb_chmask = <0x3>; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts index 23167e377d72..a59ad1076dbf 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts @@ -505,13 +505,15 @@ dai-tdm-slot-width = <32>; }; codec { + /* + * prefix-names = "3101_A", "3101_B", + * "3101_C", "3101_D"; + * sound-dai = <&tlv320adc3101_32 + * &tlv320adc3101_30 + * &tlv320adc3101_34 + * &tlv320adc3101_36>; + */ sound-dai = <&tlv320adc3101_32 &dummy_codec>; - /*prefix-names = "3101_A", "3101_B",*/ - /*"3101_C", "3101_D";*/ - /*sound-dai = <&tlv320adc3101_32*/ - /*&tlv320adc3101_30*/ - /*&tlv320adc3101_34*/ - /*&tlv320adc3101_36>;*/ }; }; @@ -1048,7 +1050,7 @@ * 5: PAD_tdminC */ datalb_src = <2>; - datalb_chnum = <8>; + datalb_chnum = <2>; datalb_chmask = <0x3>; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts index 92c43e90ff1e..25a21cb6225c 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts @@ -344,6 +344,8 @@ aml-audio-card,name = "AML-AXGSOUND"; //aml-audio-card,mclk-fs = <256>; + aml-audio-card,loopback = <&aml_loopback>; + aml-audio-card,dai-link@0 { format = "dsp_a"; mclk-fs = <256>;//512 @@ -855,6 +857,40 @@ filter_mode = <1>; /* mode 0~4, defalut:1 */ status = "okay"; }; + + aml_loopback: loopback { + compatible = "amlogic, snd-loopback"; + /* + * 0: out rate = in data rate; + * 1: out rate = loopback data rate; + */ + lb_mode = <0>; + + /* datain src + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + */ + datain_src = <4>; + datain_chnum = <8>; + datain_chmask = <0xfc>; + + /* tdmin_lb src + * 0: tdmoutA + * 1: tdmoutB + * 2: tdmoutC + * 3: PAD_tdminA + * 4: PAD_tdminB + * 5: PAD_tdminC + */ + datalb_src = <2>; + datalb_chnum = <2>; + datalb_chmask = <0x3>; + + status = "okay"; + }; }; /* end of audiobus */ &pinctrl_periphs { diff --git a/sound/soc/amlogic/auge/audio_utils.c b/sound/soc/amlogic/auge/audio_utils.c index 5007b89e8fa0..0ac6e0916849 100644 --- a/sound/soc/amlogic/auge/audio_utils.c +++ b/sound/soc/amlogic/auge/audio_utils.c @@ -1047,7 +1047,7 @@ int loopback_prepare( datain_config(&datain); datalb_config(&datalb); - datalb_ctrl(lb_cfg->datalb_src, bitwidth); + datalb_ctrl(lb_cfg->datalb_src); lb_enable_ex(lb_cfg->lb_mode, true); return 0; diff --git a/sound/soc/amlogic/auge/loopback_hw.c b/sound/soc/amlogic/auge/loopback_hw.c index ecff8a9ac94c..7101f121b561 100644 --- a/sound/soc/amlogic/auge/loopback_hw.c +++ b/sound/soc/amlogic/auge/loopback_hw.c @@ -47,16 +47,19 @@ void datalb_config(struct data_lb *datalb) ); } -void datalb_ctrl(int lb_src, int bitdepth) +void datalb_ctrl(int lb_src) { + int id = lb_src; + int offset = 0; + int reg, reg_base; + //tdmin lb, same as tdm out audiobus_update_bits( EE_AUDIO_CLK_TDMIN_LB_CTRL, - 0x3 << 30 | 0 << 29 | 0xf << 24 | 0xf << 20, - 0x3 << 30 | 0 << 29 | 2 << 24 | 2 << 20 + 0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20, + 0x3 << 30 | 1 << 29 | 2 << 24 | 2 << 20 ); - //tdmin ctrl, from tdmout - //reset + audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 3<<28, 0); audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 1<<29, 1<<29); audiobus_update_bits(EE_AUDIO_TDMIN_LB_CTRL, 1<<28, 1<<28); @@ -64,17 +67,58 @@ void datalb_ctrl(int lb_src, int bitdepth) audiobus_write( EE_AUDIO_TDMIN_LB_CTRL, 1 << 31 | - 0 << 30 | /*0:tdm mode; 1: i2s mode;*/ + /*0:tdm mode; 1: i2s mode;*/ + 1 << 30 | 1 << 29 | 1 << 28 | lb_src << 20| - 4 << 16| - (bitdepth - 1) << 0 + 3 << 16| + 31 << 0 ); + + if (id >= 0 && id <= 2) { + /* tdmout_a, tdmout_b, tdmout_c */ + reg_base = EE_AUDIO_TDMOUT_A_SWAP; + offset = EE_AUDIO_TDMOUT_B_SWAP - EE_AUDIO_TDMOUT_A_SWAP; + } else if (id < 6) { + /* pad from tdmin_a, tdmin_b, tdmin_c */ + id -= 3; /*id offset from tdmin_a */ + reg_base = EE_AUDIO_TDMIN_A_SWAP; + offset = EE_AUDIO_TDMIN_B_SWAP - EE_AUDIO_TDMIN_A_SWAP; + } else { + pr_err("unsupport datalb_src\n"); + return; + } + + /*swap same as tdmout */ + reg = reg_base + offset * id; + audiobus_write(EE_AUDIO_TDMIN_LB_SWAP, + audiobus_read(reg)); + + /*mask same as datalb*/ + /* mask 0 */ + reg += 1; audiobus_write( EE_AUDIO_TDMIN_LB_MASK0, - 0xff); + audiobus_read(reg)); + /* mask 0 */ + reg += 1; + audiobus_write( + EE_AUDIO_TDMIN_LB_MASK1, + audiobus_read(reg)); + + /* mask 0 */ + reg += 1; + audiobus_write( + EE_AUDIO_TDMIN_LB_MASK2, + audiobus_read(reg)); + + /* mask 0 */ + reg += 1; + audiobus_write( + EE_AUDIO_TDMIN_LB_MASK3, + audiobus_read(reg)); } void lb_enable_ex(int mode, bool is_enable) diff --git a/sound/soc/amlogic/auge/loopback_hw.h b/sound/soc/amlogic/auge/loopback_hw.h index 3d42d95b0596..7c744fb86333 100644 --- a/sound/soc/amlogic/auge/loopback_hw.h +++ b/sound/soc/amlogic/auge/loopback_hw.h @@ -57,7 +57,7 @@ extern void datain_config(struct data_in *datain); extern void datalb_config(struct data_lb *datalb); -extern void datalb_ctrl(int lb_src, int bitdepth); +extern void datalb_ctrl(int lb_src); extern void lb_enable_ex(int mode, bool is_enable);