mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
audio: add audio external loopback feature for axg chip
PD#159617: audio: add audio external loopback feature for axg chip For S400 & S420 board, please modify dts to enable external loopback please read following file: Documentation/devicetree/bindings/amlogic/axg-sound-loopback.txt Change-Id: Ie96d10eb8e6ae81aaff0b3e6965aa4e22f07f0b8 Signed-off-by: Peipeng Zhao <peipeng.zhao@amlogic.com>
This commit is contained in:
115
Documentation/devicetree/bindings/amlogic/axg-sound-loopback.txt
Normal file
115
Documentation/devicetree/bindings/amlogic/axg-sound-loopback.txt
Normal file
@@ -0,0 +1,115 @@
|
||||
Enable external loopback for S420 & S400 board
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts
|
||||
index 8038672..064de0f 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts
|
||||
@@ -562,12 +562,12 @@
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
- /*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
+ sound-dai = <&pdm_codec &tlv320adc3101_32>;
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
- sound-dai = <&pdm_codec>;
|
||||
+ /*sound-dai = <&pdm_codec>;*/
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1163,8 +1163,8 @@
|
||||
* external loopback clock config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
- /*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
- /*clock-names = "datalb_mpll";*/
|
||||
+ clocks = <&clkc CLKID_MPLL1>;
|
||||
+ clock-names = "datalb_mpll";
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
@@ -1182,7 +1182,7 @@
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <8>;
|
||||
- datain_chmask = <0x7f>;
|
||||
+ datain_chmask = <0x3f>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
@@ -1194,11 +1194,11 @@
|
||||
*/
|
||||
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
- datalb_src = <2>;
|
||||
+ datalb_src = <4>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
- /*datalb-lane-mask-in = <0 0 0 1>;*/
|
||||
- datalb_chmask = <0x1>;
|
||||
+ datalb-lane-mask-in = <0 0 0 1>;
|
||||
+ 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 aaf05de..bb5b173 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts
|
||||
@@ -427,12 +427,12 @@
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
- /*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
+ sound-dai = <&pdm_codec &tlv320adc3101_32>;
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
- sound-dai = <&pdm_codec>;
|
||||
+ /*sound-dai = <&pdm_codec>;*/
|
||||
};
|
||||
};
|
||||
|
||||
@@ -983,12 +983,13 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
+
|
||||
/*
|
||||
* external loopback clk config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
- /*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
- /*clock-names = "datalb_mpll";*/
|
||||
+ clocks = <&clkc CLKID_MPLL1>;
|
||||
+ clock-names = "datalb_mpll";
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
@@ -1005,7 +1006,7 @@
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <8>;
|
||||
- datain_chmask = <0x7f>;
|
||||
+ datain_chmask = <0x3f>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
@@ -1017,11 +1018,11 @@
|
||||
*/
|
||||
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
- datalb_src = <2>;
|
||||
+ datalb_src = <4>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
- /*datalb-lane-mask-in = <0 1>;*/
|
||||
- datalb_chmask = <0x1>;
|
||||
+ datalb-lane-mask-in = <0 1>;
|
||||
+ datalb_chmask = <0x3>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
@@ -14261,4 +14261,8 @@ F: drivers/amlogic/input/touchscreen/goodix_gt9xx/*
|
||||
|
||||
AMLOGIC ADD LCD_EXTERN P070ACB DRIVER
|
||||
M: Weiming Liu <weiming.liu@amlogic.com>
|
||||
F: drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c
|
||||
F: drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c
|
||||
|
||||
AMLOGIC ADD SOUND EXTERNAL LOOPBACK FEATURE
|
||||
M: Peipeng Zhao <peipeng.zhao@amlogic.com>
|
||||
F: Documentation/devicetree/bindings/amlogic/axg-sound-loopback.txt
|
||||
|
||||
@@ -556,6 +556,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
* enable external loopback
|
||||
* and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -1145,6 +1154,14 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
|
||||
/*
|
||||
* external loopback clock config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -1170,8 +1187,11 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 0 0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -558,6 +558,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -1149,10 +1158,19 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
|
||||
/*
|
||||
* external loopback clock config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
*/
|
||||
|
||||
lb_mode = <0>;
|
||||
|
||||
/* datain src
|
||||
@@ -1174,8 +1192,12 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 0 0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -552,6 +552,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -1020,6 +1029,13 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* external loopback clock config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -1045,8 +1061,11 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 0 0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -552,6 +552,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -1022,6 +1031,13 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* external loopback clock config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -1047,8 +1063,11 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 0 0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -420,6 +420,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -969,6 +978,13 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* external loopback clk config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -994,8 +1010,11 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <1>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -418,6 +418,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -843,6 +852,12 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* external loopback clk config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -868,8 +883,11 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -387,6 +387,7 @@
|
||||
dai-tdm-slot-rx-mask = <1 1>;
|
||||
dai-tdm-slot-num = <2>;
|
||||
dai-tdm-slot-width = <32>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&tlv320adc3101_32>;
|
||||
@@ -422,6 +423,15 @@
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
codec {
|
||||
/*
|
||||
*enable external loopback
|
||||
*and tlv320adc3101 as loopback
|
||||
*/
|
||||
/*sound-dai = <&pdm_codec &tlv320adc3101_32>;*/
|
||||
/*
|
||||
* enable internal loopback
|
||||
* or disable loopback
|
||||
*/
|
||||
sound-dai = <&pdm_codec>;
|
||||
};
|
||||
};
|
||||
@@ -973,6 +983,13 @@
|
||||
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* external loopback clk config
|
||||
* enable clk while pdm record data
|
||||
*/
|
||||
/*clocks = <&clkc CLKID_MPLL1>;*/
|
||||
/*clock-names = "datalb_mpll";*/
|
||||
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -998,8 +1015,12 @@
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
|
||||
/*if tdmin_lb >= 3, use external loopback*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <2>;
|
||||
/*config which data pin as loopback*/
|
||||
/*datalb-lane-mask-in = <0 1>;*/
|
||||
datalb_chmask = <0x1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "tdm_hw.h"
|
||||
#include "ddr_mngr.h"
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
struct snd_elem_info {
|
||||
struct soc_enum *ee;
|
||||
int reg;
|
||||
@@ -892,7 +894,26 @@ int snd_card_add_kcontrols(struct snd_soc_card *card)
|
||||
int loopback_parse_of(struct device_node *node,
|
||||
struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
int ret;
|
||||
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);
|
||||
@@ -945,7 +966,25 @@ int loopback_parse_of(struct device_node *node,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
loopback_datain = lb_cfg->datain_src;
|
||||
loopback_tdminlb = lb_cfg->datalb_src;
|
||||
|
||||
@@ -955,15 +994,77 @@ int loopback_parse_of(struct device_node *node,
|
||||
lb_cfg->datain_src,
|
||||
lb_cfg->datain_chnum,
|
||||
lb_cfg->datain_chmask);
|
||||
pr_info("\tdatalb_src:%d, datalb_chnum:%d, datalb_chumask:%x\n",
|
||||
pr_info("\tdatalb_src:%d, datalb_chnum:%d\n",
|
||||
lb_cfg->datalb_src,
|
||||
lb_cfg->datalb_chnum,
|
||||
lb_cfg->datalb_chnum);
|
||||
pr_info("\tdatalb_chswap:0x%x,datalb_chumask:%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 = ratio / 2;
|
||||
unsigned int clk_id = lb_cfg->datalb_src - 3;
|
||||
unsigned int mul = 2;
|
||||
unsigned int mpll_freq, offset, reg;
|
||||
|
||||
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 - EE_AUDIO_MCLK_A_CTRL;
|
||||
reg = EE_AUDIO_MCLK_A_CTRL + 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)
|
||||
@@ -1052,7 +1153,7 @@ int loopback_prepare(
|
||||
datain_config(&datain);
|
||||
datalb_config(&datalb);
|
||||
|
||||
datalb_ctrl(lb_cfg->datalb_src);
|
||||
datalb_ctrl(lb_cfg);
|
||||
lb_mode(lb_cfg->lb_mode);
|
||||
|
||||
return 0;
|
||||
@@ -1081,6 +1182,7 @@ void frddr_enable(int is_enable, int frddr_index)
|
||||
}
|
||||
|
||||
static void loopback_modules_disable(
|
||||
struct loopback_cfg *lb_cfg,
|
||||
int tdm_index,
|
||||
int frddr_index, int toddr_index)
|
||||
{
|
||||
@@ -1088,9 +1190,24 @@ static void loopback_modules_disable(
|
||||
tdmin_lb_fifo_enable(0);
|
||||
tdmin_lb_enable(tdm_index, 0);
|
||||
|
||||
/* pdmin */
|
||||
pdm_enable(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);
|
||||
|
||||
@@ -1112,6 +1229,7 @@ static void loopback_modules_disable(
|
||||
}
|
||||
|
||||
static void loopback_modules_enable(
|
||||
struct loopback_cfg *lb_cfg,
|
||||
int tdm_index,
|
||||
int frddr_index, int toddr_index)
|
||||
{
|
||||
@@ -1132,6 +1250,9 @@ static void loopback_modules_enable(
|
||||
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);
|
||||
@@ -1139,9 +1260,24 @@ static void loopback_modules_enable(
|
||||
/* loopback */
|
||||
lb_enable(1);
|
||||
|
||||
/* pdmin */
|
||||
pdm_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);
|
||||
@@ -1182,11 +1318,13 @@ int loopback_trigger(
|
||||
/*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);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#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>
|
||||
@@ -109,6 +110,7 @@ struct audio_data {
|
||||
|
||||
/**/
|
||||
struct loopback_cfg {
|
||||
struct clk *tdmin_mpll;
|
||||
/* lb_mode
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
@@ -122,6 +124,7 @@ struct loopback_cfg {
|
||||
|
||||
enum tdmin_lb_src datalb_src;
|
||||
unsigned int datalb_chnum;
|
||||
unsigned int datalb_chswap;
|
||||
unsigned int datalb_chmask;
|
||||
int frddr_index;
|
||||
};
|
||||
@@ -135,7 +138,12 @@ 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);
|
||||
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,
|
||||
|
||||
@@ -412,7 +412,7 @@ static int aml_card_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai_link *dai_link = aml_priv_to_link(priv, rtd->num);
|
||||
struct aml_dai_props *dai_props =
|
||||
aml_priv_to_props(priv, rtd->num);
|
||||
unsigned int mclk, mclk_fs = 0;
|
||||
unsigned int mclk = 0, mclk_fs = 0;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
if (priv->mclk_fs)
|
||||
@@ -442,6 +442,9 @@ static int aml_card_hw_params(struct snd_pcm_substream *substream,
|
||||
if (ret && ret != -ENOTSUPP)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (loopback_is_enable() && mclk)
|
||||
loopback_hw_params(substream, params, &priv->lb_cfg, mclk);
|
||||
return 0;
|
||||
err:
|
||||
return ret;
|
||||
|
||||
@@ -50,9 +50,9 @@ void datalb_config(struct data_lb *datalb)
|
||||
);
|
||||
}
|
||||
|
||||
void datalb_ctrl(int lb_src)
|
||||
void datalb_ctrl(struct loopback_cfg *lb_cfg)
|
||||
{
|
||||
int id = lb_src;
|
||||
int id = lb_cfg->datalb_src;
|
||||
int offset = 0;
|
||||
int reg, reg_base;
|
||||
|
||||
@@ -64,7 +64,7 @@ void datalb_ctrl(int lb_src)
|
||||
1 << 30 |
|
||||
1 << 29 |
|
||||
1 << 28 |
|
||||
lb_src << 20 |
|
||||
lb_cfg->datalb_src << 20 |
|
||||
3 << 16|
|
||||
31 << 0
|
||||
);
|
||||
@@ -74,8 +74,47 @@ void datalb_ctrl(int lb_src)
|
||||
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 */
|
||||
/*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_SWAP;
|
||||
offset = EE_AUDIO_TDMIN_B_SWAP - EE_AUDIO_TDMIN_A_SWAP;
|
||||
} else {
|
||||
@@ -95,19 +134,19 @@ void datalb_ctrl(int lb_src)
|
||||
EE_AUDIO_TDMIN_LB_MASK0,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 0 */
|
||||
/* mask 1 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK1,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 0 */
|
||||
/* mask 2 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK2,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 0 */
|
||||
/* mask 3 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK3,
|
||||
@@ -116,6 +155,8 @@ void datalb_ctrl(int lb_src)
|
||||
|
||||
void lb_mode(int mode)
|
||||
{
|
||||
// TODO:
|
||||
return;
|
||||
audiobus_update_bits(
|
||||
EE_AUDIO_LB_CTRL0,
|
||||
0x1 << 30,
|
||||
|
||||
@@ -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);
|
||||
extern void datalb_ctrl(struct loopback_cfg *lb_cfg);
|
||||
|
||||
extern int lb_is_enable(void);
|
||||
|
||||
|
||||
@@ -28,12 +28,16 @@
|
||||
|
||||
void pdm_enable(int is_enable)
|
||||
{
|
||||
if (is_enable)
|
||||
if (is_enable) {
|
||||
aml_pdm_update_bits(
|
||||
PDM_CTRL,
|
||||
0xffff,
|
||||
0xffff);
|
||||
aml_pdm_update_bits(
|
||||
PDM_CTRL,
|
||||
0x1 << 31,
|
||||
is_enable << 31);
|
||||
else {
|
||||
} else {
|
||||
aml_pdm_update_bits(
|
||||
PDM_CTRL,
|
||||
0x1 << 31 | 0x1 << 16,
|
||||
|
||||
Reference in New Issue
Block a user