audio: bringup a new resample module on SM1/TM2 [1/1]

PD#SWPL-5644

Problem:
bringup new hw resample modules on SM1/TM2

Solution:
bringup new hw resample modules on SM1/TM2
1) resample A is used for HDMIRX/SPDIFIN
2) resample B is used for LOOPBACK anti-aliasing
   if capture loopback data with 16KHz, enable it in dts.

Verify:
AB301

Change-Id: I0c2e403ff089a28e8d5695d854d13358ecffa313
Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
This commit is contained in:
Zhe Wang
2019-04-06 18:27:24 +08:00
committed by Luke Go
parent 3e9e16b616
commit 15c9b6da19
39 changed files with 3159 additions and 305 deletions

View File

@@ -14025,6 +14025,7 @@ F: include/linux/amlogic/aml_sd_emmc_v3.h
AMLOGIC Asoc driver
M: shuai li <shuai.li@amlogic.com>
M: xing wang <xing.wang@amlogic.com>
M: Zhe Wang <zhe.wang@amlogic.com>
F: sound/soc/amlogic/meson/*
F: sound/soc/amlogic/auge/*
F: sound/soc/codecs/amlogic/*

View File

@@ -1258,7 +1258,7 @@
* 6: "Enable:176K",
* 7: "Enable:192K",
*/
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};
aml_pdm: pdm {

View File

@@ -1301,7 +1301,7 @@
* 6: "Enable:176K",
* 7: "Enable:192K",
*/
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};
aml_pdm: pdm {

View File

@@ -801,6 +801,82 @@
};
};/* end of audiobus*/
/* eARC */
audio_earc: bus@ff663000 {
compatible = "simple-bus";
reg = <0xff663000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xff663000 0x1000>;
earc: earc@0 {
compatible = "amlogic, sm1-snd-earc";
#sound-dai-cells = <0>;
status = "disabled";
reg =
<0x800 0x400>,
<0xc00 0x200>,
<0xe00 0x200>;
reg-names =
"rx_cmdc",
"rx_dmac",
"rx_top";
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_MPLL1
>;
clock-names =
"rx_cmdc",
"rx_dmac",
"rx_cmdc_srcpll",
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "earc_rx";
};
};
/* Sound iomap */
aml_snd_iomap {
compatible = "amlogic, snd-iomap";
status = "okay";
#address-cells=<1>;
#size-cells=<1>;
ranges;
pdm_bus {
reg = <0xFF661000 0x400>;
};
audiobus_base {
reg = <0xFF660000 0x1000>;
};
audiolocker_base {
reg = <0xFF661400 0x400>;
};
eqdrc_base {
reg = <0xFF662000 0x1000>;
};
reset_base {
reg = <0xFFD01000 0x1000>;
};
vad_base {
reg = <0xFF661800 0x400>;
};
resampleA_base {
reg = <0xFF661c00 0x104>;
};
resampleB_base {
reg = <0xFF664000 0x104>;
};
};
}; /* end of soc*/
remote:rc@0xff808040 {

View File

@@ -684,6 +684,58 @@
};
};/* end of audiobus*/
audio_earc: bus@ff603000 {
compatible = "simple-bus";
reg = <0xff603000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xff603000 0x1000>;
earc: earc@0 {
compatible = "amlogic, tm2-snd-earc";
#sound-dai-cells = <0>;
status = "disabled";
reg = <0x0 0x400>,
<0x400 0x200>,
<0x600 0x200>,
<0x800 0x400>,
<0xc00 0x200>,
<0xe00 0x200>;
reg-names = "tx_cmdc",
"tx_dmac",
"tx_top",
"rx_cmdc",
"rx_dmac",
"rx_top";
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_MPLL1
>;
clock-names =
"rx_cmdc",
"rx_dmac",
"rx_cmdc_srcpll",
"rx_dmac_srcpll",
"tx_cmdc",
"tx_dmac",
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "earc_rx", "earc_tx";
};
};
/* Sound iomap */
aml_snd_iomap {
compatible = "amlogic, snd-iomap";
@@ -709,14 +761,11 @@
vad_base {
reg = <0xFF601800 0x400>;
};
earcrx_cdmc_base {
reg = <0xFF603800 0x30>;
resampleA_base {
reg = <0xFF601C00 0x104>;
};
earcrx_dmac_base {
reg = <0xFF603C00 0x20>;
};
earcrx_top_base {
reg = <0xFF603E00 0x10>;
resampleB_base {
reg = <0xFF604000 0x104>;
};
};

View File

@@ -1227,22 +1227,38 @@
};
asrca: resample@0 {
compatible = "amlogic, sm1-resample";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
compatible = "amlogic, sm1-resample-a";
clocks = <&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
*/
resample_module = <4>;
resample_module = <3>;
status = "okay";
};
asrcb: resample@1 {
compatible = "amlogic, sm1-resample-b";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_B>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*this resample is only used for loopback_A.*/
status = "disabled";
};

View File

@@ -1225,22 +1225,38 @@
};
asrca: resample@0 {
compatible = "amlogic, sm1-resample";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
compatible = "amlogic, sm1-resample-a";
clocks = <&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
*/
resample_module = <4>;
resample_module = <3>;
status = "okay";
};
asrcb: resample@1 {
compatible = "amlogic, sm1-resample-b";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_B>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*this resample is only used for loopback_A.*/
status = "disabled";
};

View File

@@ -1428,7 +1428,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};

View File

@@ -1121,7 +1121,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};
@@ -1200,21 +1200,25 @@
};
asrca: resample@0 {
compatible = "amlogic, tl1-resample-a";
compatible = "amlogic, sm1-resample-a";
clocks = <&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
* FRHDMIRX, 8
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* FRATV, 5
* TDMIN_LB, 6
* LOOPBACK_A, 7
* FRHDMIRX, 8
* LOOPBACK_B, 9
* SPDIFIN_LB, 10
* EARC_RX, 11
*/
resample_module = <8>;
@@ -1222,26 +1226,15 @@
};
asrcb: resample@1 {
compatible = "amlogic, tl1-resample-b";
compatible = "amlogic, sm1-resample-b";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_B>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
*/
resample_module = <3>;
/*this resample is only used for loopback_A.*/
status = "disabled";
status = "okay";
};
vad:vad {

View File

@@ -1686,7 +1686,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};

View File

@@ -1245,7 +1245,7 @@
* 6: "Enable:176K",
* 7: "Enable:192K",
*/
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};
aml_pdm: pdm {

View File

@@ -1251,7 +1251,7 @@
* 6: "Enable:176K",
* 7: "Enable:192K",
*/
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};
aml_pdm: pdm {

View File

@@ -801,6 +801,82 @@
};
};/* end of audiobus*/
/* eARC */
audio_earc: bus@ff663000 {
compatible = "simple-bus";
reg = <0x0 0xff663000 0x0 0x1000>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xff663000 0x0 0x1000>;
earc: earc@0 {
compatible = "amlogic, sm1-snd-earc";
#sound-dai-cells = <0>;
status = "disabled";
reg =
<0x0 0x800 0x0 0x400>,
<0x0 0xc00 0x0 0x200>,
<0x0 0xe00 0x0 0x200>;
reg-names =
"rx_cmdc",
"rx_dmac",
"rx_top";
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_MPLL1
>;
clock-names =
"rx_cmdc",
"rx_dmac",
"rx_cmdc_srcpll",
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "earc_rx";
};
};
/* Sound iomap */
aml_snd_iomap {
compatible = "amlogic, snd-iomap";
status = "okay";
#address-cells=<2>;
#size-cells=<2>;
ranges;
pdm_bus {
reg = <0x0 0xFF661000 0x0 0x400>;
};
audiobus_base {
reg = <0x0 0xFF660000 0x0 0x1000>;
};
audiolocker_base {
reg = <0x0 0xFF661400 0x0 0x400>;
};
eqdrc_base {
reg = <0x0 0xFF662000 0x0 0x1000>;
};
reset_base {
reg = <0x0 0xFFD01000 0x0 0x1000>;
};
vad_base {
reg = <0x0 0xFF661800 0x0 0x400>;
};
resampleA_base {
reg = <0x0 0xFF661c00 0x0 0x104>;
};
resampleB_base {
reg = <0x0 0xFF664000 0x0 0x104>;
};
};
}; /* end of soc*/
remote:rc@0xff808040 {

View File

@@ -664,6 +664,59 @@
};
};/* end of audiobus*/
/* eARC */
audio_earc: bus@ff603000 {
compatible = "simple-bus";
reg = <0x0 0xff603000 0x0 0x1000>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xff603000 0x0 0x1000>;
earc: earc@0 {
compatible = "amlogic, tm2-snd-earc";
#sound-dai-cells = <0>;
status = "disabled";
reg = <0x0 0x0 0x0 0x400>,
<0x0 0x400 0x0 0x200>,
<0x0 0x600 0x0 0x200>,
<0x0 0x800 0x0 0x400>,
<0x0 0xc00 0x0 0x200>,
<0x0 0xe00 0x0 0x200>;
reg-names = "tx_cmdc",
"tx_dmac",
"tx_top",
"rx_cmdc",
"rx_dmac",
"rx_top";
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV4
&clkc CLKID_MPLL1
>;
clock-names =
"rx_cmdc",
"rx_dmac",
"rx_cmdc_srcpll",
"rx_dmac_srcpll",
"tx_cmdc",
"tx_dmac",
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "earc_rx", "earc_tx";
};
};
/* Sound iomap */
aml_snd_iomap {
compatible = "amlogic, snd-iomap";
@@ -689,14 +742,11 @@
vad_base {
reg = <0x0 0xFF601800 0x0 0x400>;
};
earcrx_cdmc_base {
reg = <0x0 0xFF603800 0x0 0x30>;
resampleA_base {
reg = <0x0 0xFF601C00 0x0 0x104>;
};
earcrx_dmac_base {
reg = <0x0 0xFF603C00 0x0 0x20>;
};
earcrx_top_base {
reg = <0x0 0xFF603E00 0x0 0x10>;
resampleB_base {
reg = <0x0 0xFF601C00 0x0 0x104>;
};
};

View File

@@ -1227,22 +1227,38 @@
};
asrca: resample@0 {
compatible = "amlogic, sm1-resample";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
compatible = "amlogic, sm1-resample-a";
clocks = <&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
*/
resample_module = <4>;
resample_module = <3>;
status = "okay";
};
asrcb: resample@1 {
compatible = "amlogic, sm1-resample-b";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_B>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*this resample is only used for loopback_A.*/
status = "disabled";
};

View File

@@ -1223,22 +1223,38 @@
};
asrca: resample@0 {
compatible = "amlogic, sm1-resample";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
compatible = "amlogic, sm1-resample-a";
clocks = <&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A
&clkaudio CLKID_AUDIO_RESAMPLE_A>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*same with toddr_src
* TDMIN_A, 0
* TDMIN_B, 1
* TDMIN_C, 2
* SPDIFIN, 3
* PDMIN, 4
* PDMIN, 4
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
*/
resample_module = <4>;
resample_module = <3>;
status = "okay";
};
asrcb: resample@1 {
compatible = "amlogic, sm1-resample-b";
clocks = <&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_MCLK_F
&clkaudio CLKID_AUDIO_RESAMPLE_B>;
clock-names = "resample_pll", "resample_src", "resample_clk";
/*this resample is only used for loopback_A.*/
status = "disabled";
};

View File

@@ -1619,7 +1619,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};

View File

@@ -1494,7 +1494,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};

View File

@@ -1488,7 +1488,7 @@
* 7: "Enable:192K",
*/
asrc_id = <0>;
auto_asrc = <3>;
auto_asrc = <0>;
status = "okay";
};

View File

@@ -13,7 +13,6 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE) += audio_controller.o \
spdif_hw.o \
pdm.o \
pdm_hw.o \
pdm_hw_coeff.o \
iomap.o \
ddr_mngr.o \
loopback.o \

View File

@@ -538,6 +538,7 @@ static void aml_toddr_set_resample(struct toddr *to, bool enable)
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base);
aml_audiobus_update_bits(actrl, reg, 1<<30, !!enable<<30);
}
/* tl1 after */
static void aml_toddr_set_resample_ab(struct toddr *to,
enum resample_idx index, bool enable)
@@ -549,8 +550,7 @@ static void aml_toddr_set_resample_ab(struct toddr *to,
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base);
if (index == RESAMPLE_A)
aml_audiobus_update_bits(actrl, reg, 1 << 27, !!enable << 27);
else if (index == RESAMPLE_B)
aml_audiobus_update_bits(actrl, reg, 1 << 26, !!enable << 26);
}
static void aml_resample_enable(
@@ -563,25 +563,6 @@ static void aml_resample_enable(
return;
}
if (to->chipinfo
&& to->chipinfo->asrc_src_sel_ctrl) {
/* fix asrc_src_sel */
/*
switch (p_attach_resample->attach_module) {
case LOOPBACK_A:
to->asrc_src_sel = ASRC_LOOPBACK_A;
break;
case LOOPBACK_B:
to->asrc_src_sel = ASRC_LOOPBACK_B;
break;
default:
to->asrc_src_sel = to->fifo_id;
break;
}
*/
to->asrc_src_sel = p_attach_resample->attach_module;
}
pr_info("toddr %d selects data to %s resample_%c for module:%s\n",
to->fifo_id,
enable ? "enable" : "disable",
@@ -616,16 +597,23 @@ static void aml_resample_enable(
endian << 24 | toddr_type << 13);
}
resample_format_set(p_attach_resample->id,
to->channels, bitwidth);
/* toddr index for resample */
if (to->chipinfo
&& to->chipinfo->asrc_src_sel_ctrl)
resample_src_select_ab(p_attach_resample->id,
to->asrc_src_sel);
else
resample_src_select(to->fifo_id);
if (p_attach_resample->resample_version == 1) {
new_resample_set_format(p_attach_resample->id,
to->channels, bitwidth);
new_resample_src_select(p_attach_resample->id,
to->fifo_id);
} else if (p_attach_resample->resample_version == 0) {
/* toddr index for resample */
if (to->chipinfo &&
to->chipinfo->asrc_src_sel_ctrl) {
resample_src_select_ab(p_attach_resample->id,
to->fifo_id);
} else {
resample_src_select(to->fifo_id);
}
resample_format_set(p_attach_resample->id,
to->channels, bitwidth);
}
}
/* resample enable or not */
@@ -637,6 +625,12 @@ static void aml_resample_enable(
aml_toddr_set_resample_ab(to, p_attach_resample->id, enable);
else
aml_toddr_set_resample(to, enable);
/* resample enable or disable */
if (p_attach_resample->resample_version == 1)
new_resample_enable(p_attach_resample->id, enable);
else if (p_attach_resample->resample_version == 0)
resample_enable(p_attach_resample->id, enable);
}
void aml_set_resample(enum resample_idx id,
@@ -654,6 +648,7 @@ void aml_set_resample(enum resample_idx id,
p_attach_resample->enable = enable;
p_attach_resample->id = id;
p_attach_resample->attach_module = resample_module;
p_attach_resample->resample_version = get_resample_version_id(id);
to = fetch_toddr_by_src(
p_attach_resample->attach_module);
@@ -688,32 +683,24 @@ void aml_set_resample(enum resample_idx id,
static void aml_check_resample(struct toddr *to, bool enable)
{
struct toddr_attach *p_attach_resample;
bool is_module_resample;
bool resample_b_check = false;
int i;
p_attach_resample = &attach_resample_a;
start_check:
is_module_resample = false;
if (p_attach_resample->enable
&& (to->src == p_attach_resample->attach_module))
is_module_resample = true;
for (i = 0; i < get_resample_module_num(); i++) {
if (to->src == p_attach_resample->attach_module) {
/* save toddr status */
if (enable)
p_attach_resample->status = RUNNING;
else
p_attach_resample->status = DISABLED;
/* resample in enable */
if (is_module_resample) {
if (enable)
p_attach_resample->status = RUNNING;
else
p_attach_resample->status = DISABLED;
aml_resample_enable(to, p_attach_resample, enable);
}
if ((!resample_b_check)
&& (get_resample_module_num() == 2)) {
/*if disable toddr, disable attached resampler*/
if (p_attach_resample->enable)
aml_resample_enable(to, p_attach_resample,
enable);
}
p_attach_resample = &attach_resample_b;
resample_b_check = true;
goto start_check;
}
}

View File

@@ -175,8 +175,6 @@ struct toddr {
enum toddr_src src;
unsigned int fifo_id;
enum toddr_src asrc_src_sel;
int is_lb; /* check whether for loopback */
int irq;
bool in_use: 1;
@@ -198,6 +196,7 @@ struct toddr_attach {
* check which toddr in use should be attached
*/
enum toddr_src attach_module;
int resample_version;
};
struct frddr_attach {

View File

@@ -437,7 +437,7 @@ static int extn_dai_startup(
struct snd_soc_dai *cpu_dai)
{
if (get_audioresample(RESAMPLE_A))
resample_set_inner_rate(RESAMPLE_A);
resample_set(RESAMPLE_A, RATE_48K);
return 0;
}
@@ -446,7 +446,6 @@ static void extn_dai_shutdown(
struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
//resample_set(RESAMPLE_A, RATE_OFF);
}
static int extn_dai_prepare(

View File

@@ -20,6 +20,7 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "regs.h"
#include "iomap.h"
#define DEV_NAME "auge_snd_iomap"
@@ -50,9 +51,8 @@ static void aml_snd_write(u32 base_type, unsigned int reg, unsigned int val)
pr_err("write snd reg %x error\n", reg);
}
static void aml_snd_update_bits(u32 base_type,
unsigned int reg, unsigned int mask,
unsigned int val)
static void aml_snd_update_bits(u32 base_type, unsigned int reg,
unsigned int mask, unsigned int val)
{
if (base_type < IO_MAX) {
unsigned int tmp, orig;
@@ -89,8 +89,8 @@ void aml_pdm_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(aml_pdm_write);
void aml_pdm_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void aml_pdm_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_PDM_BUS, reg, mask, val);
}
@@ -116,8 +116,8 @@ void audiobus_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(audiobus_write);
void audiobus_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void audiobus_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_AUDIO_BUS, reg, mask, val);
}
@@ -143,8 +143,8 @@ void audiolocker_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(audiolocker_write);
void audiolocker_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void audiolocker_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_AUDIO_LOCKER, reg, mask, val);
}
@@ -170,8 +170,8 @@ void eqdrc_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(eqdrc_write);
void eqdrc_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void eqdrc_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_EQDRC_BUS, reg, mask, val);
}
@@ -197,8 +197,8 @@ void audioreset_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(audioreset_write);
void audioreset_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void audioreset_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_RESET, reg, mask, val);
}
@@ -224,13 +224,48 @@ void vad_write(unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL(vad_write);
void vad_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
void vad_update_bits(unsigned int reg, unsigned int mask,
unsigned int val)
{
aml_snd_update_bits(IO_VAD, reg, mask, val);
}
EXPORT_SYMBOL(vad_update_bits);
unsigned int new_resample_read(enum resample_idx id, unsigned int reg)
{
unsigned int val = 0;
if (id == RESAMPLE_A)
val = readl((aml_snd_reg_map[IO_RESAMPLEA] +
(reg << 2)));
else if (id == RESAMPLE_B)
val = readl((aml_snd_reg_map[IO_RESAMPLEB] +
(reg << 2)));
return val;
}
void new_resample_write(enum resample_idx id, unsigned int reg,
unsigned int val)
{
if (id == RESAMPLE_A)
writel(val, (aml_snd_reg_map[IO_RESAMPLEA] + (reg << 2)));
else if (id == RESAMPLE_B)
writel(val, (aml_snd_reg_map[IO_RESAMPLEB] + (reg << 2)));
}
void new_resample_update_bits(enum resample_idx id, unsigned int reg,
unsigned int mask, unsigned int val)
{
unsigned int tmp, orig;
orig = new_resample_read(id, reg);
tmp = orig & ~mask;
tmp |= val & mask;
new_resample_write(id, reg, tmp);
}
static int snd_iomap_probe(struct platform_device *pdev)
{
struct resource res;

View File

@@ -18,6 +18,8 @@
#ifndef __AML_SND_IOMAP_H__
#define __AML_SND_IOMAP_H__
#include "ddr_mngr.h"
enum{
IO_PDM_BUS = 0,
IO_AUDIO_BUS,
@@ -25,37 +27,45 @@ enum{
IO_EQDRC_BUS,
IO_RESET,
IO_VAD,
IO_RESAMPLEA,
IO_RESAMPLEB,
IO_MAX,
};
extern int aml_pdm_read(unsigned int reg);
extern void aml_pdm_write(unsigned int reg, unsigned int val);
extern void aml_pdm_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
int aml_pdm_read(unsigned int reg);
void aml_pdm_write(unsigned int reg, unsigned int val);
void aml_pdm_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
extern int audiobus_read(unsigned int reg);
extern void audiobus_write(unsigned int reg, unsigned int val);
extern void audiobus_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
int audiobus_read(unsigned int reg);
void audiobus_write(unsigned int reg, unsigned int val);
void audiobus_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
extern int audiolocker_read(unsigned int reg);
extern void audiolocker_write(unsigned int reg, unsigned int val);
extern void audiolocker_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
int audiolocker_read(unsigned int reg);
void audiolocker_write(unsigned int reg, unsigned int val);
void audiolocker_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
extern int eqdrc_read(unsigned int reg);
extern void eqdrc_write(unsigned int reg, unsigned int val);
extern void eqdrc_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
int eqdrc_read(unsigned int reg);
void eqdrc_write(unsigned int reg, unsigned int val);
void eqdrc_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
extern int audioreset_read(unsigned int reg);
extern void audioreset_write(unsigned int reg, unsigned int val);
extern void audioreset_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
int audioreset_read(unsigned int reg);
void audioreset_write(unsigned int reg, unsigned int val);
void audioreset_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
int vad_read(unsigned int reg);
void vad_write(unsigned int reg, unsigned int val);
void vad_update_bits(unsigned int reg, unsigned int mask,
unsigned int val);
unsigned int new_resample_read(enum resample_idx id, unsigned int reg);
void new_resample_write(enum resample_idx id, unsigned int reg,
unsigned int val);
void new_resample_update_bits(enum resample_idx id, unsigned int reg,
unsigned int mask, unsigned int val);
extern int vad_read(unsigned int reg);
extern void vad_write(unsigned int reg, unsigned int val);
extern void vad_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
#endif

View File

@@ -31,6 +31,7 @@
#include "ddr_mngr.h"
#include "tdm_hw.h"
#include "pdm_hw.h"
#include "resample.h"
#include "vad.h"
@@ -590,7 +591,10 @@ static int loopback_set_ctrl(struct loopback *p_loopback, int bitwidth)
datalb_cfg.type = datalb_toddr_type;
datalb_cfg.m = datalb_msb;
datalb_cfg.n = datalb_lsb;
datalb_cfg.datalb_src = p_loopback->datalb_src;
datalb_cfg.datalb_src = 0; /* todo: tdmin_LB */
/* get resample B status */
datalb_cfg.resample_enable =
(unsigned int)get_resample_enable(RESAMPLE_B);
if (p_loopback->chipinfo) {
datain_cfg.ch_ctrl_switch = p_loopback->chipinfo->ch_ctrl;

View File

@@ -22,8 +22,7 @@
#include "regs.h"
#include "iomap.h"
static unsigned int
get_tdmin_id_from_lb_src(enum datalb_src lb_src)
static unsigned int get_tdmin_id_from_lb_src(enum datalb_src lb_src)
{
return lb_src % TDMINLB_PAD_TDMINA;
}
@@ -186,8 +185,9 @@ void lb_set_datalb_cfg(int id, struct data_cfg *datalb_cfg)
if (datalb_cfg->ch_ctrl_switch) {
audiobus_update_bits(reg,
0x1 << 29 | 0x7 << 13 | 0x1f << 8
| 0x1f << 3 | 0x1 << 1,
0x3 << 30 | 0x1 << 29 | 0x7 << 13 |
0x1f << 8 | 0x1f << 3 | 0x1 << 1,
datalb_cfg->resample_enable << 30 |
datalb_cfg->ext_signed << 29 |
datalb_cfg->type << 13 |
datalb_cfg->m << 8 |

View File

@@ -45,6 +45,9 @@ struct data_cfg {
/* channel and mask in new ctrol register */
bool ch_ctrl_switch;
/* enable resample B for loopback*/
unsigned int resample_enable;
};
void tdminlb_set_clk(enum datalb_src lb_src,

View File

@@ -24,7 +24,7 @@
#include "pdm_hw.h"
#include "regs.h"
#include "iomap.h"
#include "pdm_hw_coeff.c"
#include "pdm_hw_coeff.h"
static DEFINE_SPINLOCK(pdm_lock);
static unsigned long pdm_enable_cnt;

View File

@@ -1,5 +1,5 @@
/*
* sound/soc/amlogic/auge/pdm_hw_coeff.c
* sound/soc/amlogic/auge/pdm_hw_coeff.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
@@ -20,6 +20,9 @@
* For filter 2, it's only relative with osr and hcic stage number
*/
#ifndef __PDM_HW_COEFF_H__
#define __PDM_HW_COEFF_H__
static const int lpf2_osr64[] = {
0x00050a, 0xfff004, 0x0002c1, 0x003c12, 0xffa818,
0xffc87d, 0x010aef, 0xff5223, 0xfebd93, 0x028f41,
@@ -274,3 +277,5 @@ static const int lpf3_mode4[] = {
0x018208, 0xfedaef, 0xff25e9, 0x009ddb, 0x006ded,
0xffb7a1, 0xffd46b
};
#endif

View File

@@ -1117,5 +1117,38 @@ enum clk_sel {
#define EARCTX_ANA_CTRL1 0x006
#define EARCTX_ANA_CTRL2 0x007
#define EARCTX_ANA_STAT0 0x008
/* new resample */
#define AUDIO_RSAMP_CTRL0 0x000
#define AUDIO_RSAMP_CTRL1 0x001
#define AUDIO_RSAMP_CTRL2 0x002
#define AUDIO_RSAMP_PHSINIT 0x003
#define AUDIO_RSAMP_PHSSTEP 0x004
#define AUDIO_RSAMP_SHIFT 0x005
#define AUDIO_RSAMP_ADJ_CTRL0 0x006
#define AUDIO_RSAMP_ADJ_CTRL1 0x007
#define AUDIO_RSAMP_ADJ_SFT 0x008
#define AUDIO_RSAMP_ADJ_IDET_LEN 0x009
#define AUDIO_RSAMP_ADJ_FORCE 0x00a
#define AUDIO_RSAMP_ADJ_KI_FORCE 0x00b
#define AUDIO_RSAMP_RO_STATUS 0x010
#define AUDIO_RSAMP_RO_ADJ_FREQ 0x011
#define AUDIO_RSAMP_RO_ADJ_DIFF_BAK 0x012
#define AUDIO_RSAMP_RO_ADJ_DIFF_DLT 0x013
#define AUDIO_RSAMP_RO_ADJ_PHS_ERR 0x014
#define AUDIO_RSAMP_RO_ADJ_KI_OUT 0x015
#define AUDIO_RSAMP_RO_IN_CNT 0x016
#define AUDIO_RSAMP_RO_OUT_CNT 0x017
#define AUDIO_RSAMP_POST_COEF0 0x020
#define AUDIO_RSAMP_POST_COEF1 0x021
#define AUDIO_RSAMP_POST_COEF2 0x022
#define AUDIO_RSAMP_POST_COEF3 0x023
#define AUDIO_RSAMP_POST_COEF4 0x024
#define AUDIO_RSAMP_AA_COEF_ADDR 0x030
#define AUDIO_RSAMP_AA_COEF_DATA 0x031
#define AUDIO_RSAMP_SINC_COEF_ADDR 0x040
#define AUDIO_RSAMP_SINC_COEF_DATA 0x041
/*HHI bus*/
#define HHI_AUDIO_MEM_PD_REG0 0x045
#endif

View File

@@ -23,12 +23,15 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/amlogic/iomap.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "resample.h"
#include "regs.h"
#include "iomap.h"
#include "resample.h"
#include "resample_hw.h"
#define DRV_NAME "audioresample"
@@ -36,14 +39,12 @@
/*#define __PTM_RESAMPLE_CLK__*/
//#define RESAMPLE_A 0
//#define RESAMPLE_B 1
struct resample_chipinfo {
int num; /* support resample a/b */
int num; /* support resample a/b */
enum resample_idx id;
bool dividor_fn;
int resample_version;
};
struct audioresample {
@@ -60,13 +61,13 @@ struct audioresample {
enum resample_idx id;
/*which module should be resampled */
/* which module should be resampled */
enum toddr_src resample_module;
/* resample to the rate */
/* resample to the rate */
int out_rate;
/* sync with auge_resample_texts */
enum samplerate_index asrc_rate_idx;
enum samplerate_index asrc_in_sr_idx;
bool enable;
};
@@ -99,50 +100,58 @@ int get_resample_module_num(void)
return 1;
}
int get_resample_version_id(enum resample_idx id)
{
struct audioresample *p_resample;
p_resample = ((id == RESAMPLE_A) ? s_resample_a : s_resample_b);
if (!p_resample || !p_resample->chipinfo) {
pr_debug("Not init audio resample\n");
return -1;
}
return p_resample->chipinfo->resample_version;
}
bool get_resample_enable(enum resample_idx id)
{
struct audioresample *p_resample;
p_resample = ((id == RESAMPLE_A) ? s_resample_a : s_resample_b);
if (!p_resample) {
pr_debug("Not init audio resample\n");
return 0;
}
return p_resample->enable;
}
int set_resample_source(enum resample_idx id, enum toddr_src src)
{
struct audioresample *p_resample = get_audioresample(id);
(void)p_resample;
(void)src;
//p_resample->resample_module = src;
return 0;
}
static int set_resample_rate_index(
enum resample_idx id, enum samplerate_index index)
{
struct audioresample *p_resample = get_audioresample(id);
p_resample->asrc_rate_idx = index;
return 0;
}
static enum samplerate_index get_resample_rate_index(
enum resample_idx id)
{
struct audioresample *p_resample = get_audioresample(id);
return p_resample->asrc_rate_idx;
}
static int resample_clk_set(struct audioresample *p_resample)
static int resample_clk_set(struct audioresample *p_resample, int output_sr)
{
int ret = 0;
/* enable clock */
if (p_resample->enable) {
/* defaule tdm out mclk to resample clk */
clk_set_rate(p_resample->pll, output_sr * CLK_RATIO * 2);
clk_set_rate(p_resample->sclk, output_sr * CLK_RATIO);
clk_set_rate(p_resample->clk, output_sr * CLK_RATIO);
/* defaule tdm out mclk to resample clk */
clk_set_rate(p_resample->pll, 48000 * CLK_RATIO * 2);
clk_set_rate(p_resample->sclk, 48000 * CLK_RATIO);
clk_set_rate(p_resample->clk, 48000 * CLK_RATIO);
pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n",
__func__,
clk_get_rate(p_resample->pll),
clk_get_rate(p_resample->sclk),
clk_get_rate(p_resample->clk));
}
pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n",
__func__,
clk_get_rate(p_resample->pll),
clk_get_rate(p_resample->sclk),
clk_get_rate(p_resample->clk));
return ret;
}
@@ -176,6 +185,7 @@ static const char *const auge_resample_texts[] = {
"Enable:96K",
"Enable:176K",
"Enable:192K",
"Enable:16K",
};
static int resample_idx2rate(enum samplerate_index index)
@@ -198,6 +208,8 @@ static int resample_idx2rate(enum samplerate_index index)
rate = 176400;
else if (index == RATE_192K)
rate = 192000;
else if (index == RATE_16K)
rate = 16000;
return rate;
}
@@ -211,63 +223,72 @@ static int resample_get_enum(
struct snd_ctl_elem_value *ucontrol)
{
struct audioresample *p_resample = snd_kcontrol_chip(kcontrol);
int resample_enable = 0;
if (!p_resample) {
if (!p_resample || !p_resample->chipinfo) {
pr_debug("audio resample is not init\n");
return 0;
}
ucontrol->value.enumerated.item[0] = p_resample->asrc_rate_idx;
if (p_resample->chipinfo->resample_version == 1)
resample_enable = new_resample_get_status(p_resample->id);
else if (p_resample->chipinfo->resample_version == 0)
resample_enable = resample_get_status(p_resample->id);
if (resample_enable)
ucontrol->value.enumerated.item[0] = p_resample->asrc_in_sr_idx;
else
ucontrol->value.enumerated.item[0] = RATE_OFF;
return 0;
}
/* force set to new rate index whatever the resampler holds */
int resample_set(enum resample_idx id, enum samplerate_index index)
{
int resample_rate = 0;
struct audioresample *p_resample = get_audioresample(id);
int ret = 0;
if (!p_resample)
if (!p_resample || !p_resample->chipinfo)
return 0;
if (index < RATE_OFF || index >= RATE_MAX) {
pr_err("%s(), invalid index %d\n", __func__, index);
return 0;
}
p_resample->asrc_in_sr_idx = index;
pr_info("%s resample_%c to %s, last %s\n",
__func__,
(id == RESAMPLE_A) ? 'a' : 'b',
auge_resample_texts[index],
auge_resample_texts[p_resample->asrc_rate_idx]);
#if 0
if (index == p_resample->asrc_rate_idx)
return 0;
#endif
p_resample->asrc_rate_idx = index;
auge_resample_texts[p_resample->asrc_in_sr_idx]);
resample_rate = resample_idx2rate(index);
ret = audio_resample_set(p_resample, (bool)index, resample_rate);
if (ret)
return ret;
if (index == RATE_OFF)
resample_disable(p_resample->id);
else {
resample_init(p_resample->id, resample_rate);
resample_set_hw_param(p_resample->id, index);
if (index == RATE_OFF) {
if (p_resample->chipinfo->resample_version == 1)
new_resample_enable(p_resample->id, false);
else if (p_resample->chipinfo->resample_version == 0)
resample_enable(p_resample->id, false);
} else {
if (p_resample->chipinfo->resample_version == 1) {
new_resample_set_ratio(id, resample_rate,
DEFAULT_SPK_SAMPLERATE);
} else if (p_resample->chipinfo->resample_version == 0) {
resample_init(p_resample->id, resample_rate);
resample_set_hw_param(p_resample->id, index);
}
}
return 0;
}
int resample_set_inner_rate(enum resample_idx id)
{
enum samplerate_index index = get_resample_rate_index(id);
pr_debug("%s() index %d\n", __func__, id);
return resample_set(id, index);
}
static int resample_set_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -280,8 +301,10 @@ static int resample_set_enum(
return 0;
}
set_resample_rate_index(p_resample->id, index);
resample_set_inner_rate(p_resample->id);
if (index == p_resample->asrc_in_sr_idx)
return 0;
resample_set(p_resample->id, index);
return 0;
}
@@ -391,6 +414,7 @@ static int resample_module_set_enum(
return 0;
}
static const struct snd_kcontrol_new asrc_a_controls[] = {
SOC_ENUM_EXT("Hardware resample enable",
auge_resample_enum,
@@ -429,26 +453,53 @@ static const struct snd_kcontrol_new asrc_b_controls[] = {
resample_module_set_enum),
};
static const struct snd_kcontrol_new rsamp_a_controls[] = {
SOC_ENUM_EXT("Hardware resample enable",
auge_resample_enum,
resample_get_enum,
resample_set_enum),
SOC_ENUM_EXT("Hw resample module",
auge_resample_module_enum,
resample_module_get_enum,
resample_module_set_enum),
};
int card_add_resample_kcontrols(struct snd_soc_card *card)
{
unsigned int idx;
int err;
int err = 0;
if (s_resample_a) {
for (idx = 0; idx < ARRAY_SIZE(asrc_a_controls); idx++) {
err = snd_ctl_add(card->snd_card,
if (s_resample_a && s_resample_a->chipinfo) {
if (s_resample_a->chipinfo->resample_version == 1) {
for (idx = 0; idx < ARRAY_SIZE(rsamp_a_controls);
idx++) {
err = snd_ctl_add(
card->snd_card,
snd_ctl_new1(&rsamp_a_controls[idx],
s_resample_a));
}
} else if (s_resample_a->chipinfo->resample_version == 0) {
for (idx = 0; idx < ARRAY_SIZE(asrc_a_controls);
idx++) {
err = snd_ctl_add(
card->snd_card,
snd_ctl_new1(&asrc_a_controls[idx],
s_resample_a));
if (err < 0)
return err;
s_resample_a));
}
}
if (err < 0)
return err;
}
if (s_resample_b) {
for (idx = 0; idx < ARRAY_SIZE(asrc_b_controls); idx++) {
err = snd_ctl_add(card->snd_card,
if (s_resample_b && s_resample_b->chipinfo) {
if (s_resample_b->chipinfo->resample_version == 0) {
for (idx = 0; idx < ARRAY_SIZE(asrc_b_controls);
idx++) {
err = snd_ctl_add(
card->snd_card,
snd_ctl_new1(&asrc_b_controls[idx],
s_resample_b));
s_resample_b));
}
if (err < 0)
return err;
}
@@ -457,20 +508,69 @@ int card_add_resample_kcontrols(struct snd_soc_card *card)
return 0;
}
static int new_resample_init(struct audioresample *p_resample)
{
if (!p_resample)
return -ENOMEM;
pr_info("%s: Start init new resample %s parameters!\n",
__func__, (p_resample->id == RESAMPLE_A) ? "A" : "B");
p_resample->enable = 1;
new_resample_init_param(p_resample->id);
if (p_resample->id == RESAMPLE_A) {
/* default resample A for tv input source */
new_resample_set_ratio(p_resample->id,
DEFAULT_SPK_SAMPLERATE,
DEFAULT_SPK_SAMPLERATE);
/*set resample clk to default 256fs mclk.*/
/*the same clk source with tdm*/
resample_clk_set(p_resample, DEFAULT_SPK_SAMPLERATE);
} else if (p_resample->id == RESAMPLE_B) {
/* default resample B for loopback downsample */
new_resample_set_ratio(p_resample->id,
DEFAULT_SPK_SAMPLERATE,
DEFAULT_MIC_SAMPLERATE);
/*set resample clk to default 256fs mclk.*/
/*the same clk source with TDMINLB*/
resample_clk_set(p_resample, DEFAULT_MIC_SAMPLERATE);
}
return 0;
}
static struct resample_chipinfo g12a_resample_chipinfo = {
.dividor_fn = true,
.resample_version = 0,
};
static struct resample_chipinfo tl1_resample_a_chipinfo = {
.num = 2,
.id = RESAMPLE_A,
.dividor_fn = true,
.resample_version = 0,
};
static struct resample_chipinfo tl1_resample_b_chipinfo = {
.num = 2,
.id = RESAMPLE_B,
.dividor_fn = true,
.resample_version = 0,
};
static struct resample_chipinfo sm1_resample_a_chipinfo = {
.num = 2,
.id = RESAMPLE_A,
.dividor_fn = true,
.resample_version = 1,
};
static struct resample_chipinfo sm1_resample_b_chipinfo = {
.num = 2,
.id = RESAMPLE_B,
.dividor_fn = true,
.resample_version = 1,
};
static const struct of_device_id resample_device_id[] = {
@@ -489,6 +589,14 @@ static const struct of_device_id resample_device_id[] = {
.compatible = "amlogic, tl1-resample-b",
.data = &tl1_resample_b_chipinfo,
},
{
.compatible = "amlogic, sm1-resample-a",
.data = &sm1_resample_a_chipinfo,
},
{
.compatible = "amlogic, sm1-resample-b",
.data = &sm1_resample_b_chipinfo,
},
{}
};
MODULE_DEVICE_TABLE(of, resample_device_id);
@@ -521,11 +629,15 @@ static int resample_platform_probe(struct platform_device *pdev)
p_resample->chipinfo = p_chipinfo;
ret = of_property_read_u32(pdev->dev.of_node, "resample_module",
&resample_module);
if (ret < 0) {
dev_err(&pdev->dev, "Can't retrieve resample_module\n");
return -EINVAL;
if (p_chipinfo->id == 0) {
ret = of_property_read_u32(pdev->dev.of_node, "resample_module",
&resample_module);
if (ret < 0) {
dev_err(&pdev->dev, "Can't retrieve resample_module\n");
return -EINVAL;
}
} else {
resample_module = LOOPBACK_A;
}
/* config from dts */
@@ -575,10 +687,6 @@ static int resample_platform_probe(struct platform_device *pdev)
return ret;
}
/*set resample clk to default 256fs mclk.*/
/*the same clk source with tdm*/
resample_clk_set(p_resample);
p_resample->dev = dev;
if (p_chipinfo && p_chipinfo->id == 1)
@@ -586,10 +694,21 @@ static int resample_platform_probe(struct platform_device *pdev)
else
s_resample_a = p_resample;
if (p_chipinfo && p_chipinfo->resample_version == 1)
new_resample_init(p_resample);
else if (p_chipinfo && p_chipinfo->resample_version == 0)
resample_clk_set(p_resample, DEFAULT_SPK_SAMPLERATE);
aml_set_resample(p_resample->id, p_resample->enable,
p_resample->resample_module);
pr_info("resample id = %d, new resample = %d, resample_module = %d\n",
p_chipinfo->id, p_chipinfo->resample_version,
p_resample->resample_module);
return 0;
}
static struct platform_driver resample_platform_driver = {
.driver = {
.name = DRV_NAME,

View File

@@ -19,16 +19,18 @@
#include "resample_hw.h"
extern int card_add_resample_kcontrols(struct snd_soc_card *card);
int card_add_resample_kcontrols(struct snd_soc_card *card);
extern int resample_set(enum resample_idx id, enum samplerate_index index);
int resample_set(enum resample_idx id, enum samplerate_index index);
extern int get_resample_module_num(void);
int get_resample_module_num(void);
int set_resample_source(enum resample_idx id, enum toddr_src src);
int resample_set_inner_rate(enum resample_idx id);
struct audioresample *get_audioresample(enum resample_idx id);
int get_resample_version_id(enum resample_idx id);
bool get_resample_enable(enum resample_idx id);
#endif

View File

@@ -15,13 +15,18 @@
*
*/
#include <linux/clk.h>
#include <linux/amlogic/iomap.h>
#include <linux/math64.h>
#include "resample_hw.h"
#include "resample_hw_coeff.h"
#include "regs.h"
#include "iomap.h"
/*Cnt_ctrl = mclk/fs_out-1 ; fest 256fs */
#define RESAMPLE_CNT_CONTROL 255
#define RESAMPLE_CNT_CONTROL (255)
#define SINC8_FILTER_COEF_ADDR (0)
#define AA_FILTER_COEF_ADDR (129 * 32)
static u32 resample_coef_parameters_table[7][5] = {
/*coef of 32K, fc = 9000, Q:0.55, G= 14.00, */
@@ -40,22 +45,228 @@ static u32 resample_coef_parameters_table[7][5] = {
{0x00800000, 0x0, 0x0, 0x0, 0x0},
};
void new_resample_set_ram_coeff_aa(enum resample_idx id, int len,
unsigned int *params)
{
int i;
unsigned int *p = params;
new_resample_write(id, AUDIO_RSAMP_AA_COEF_ADDR, AA_FILTER_COEF_ADDR);
for (i = 0; i < len; i++, p++)
new_resample_write(id, AUDIO_RSAMP_AA_COEF_DATA, *p);
}
void new_resample_set_ram_coeff_sinc(enum resample_idx id, int len,
unsigned int *params)
{
int i;
unsigned int *p = params;
new_resample_write(id, AUDIO_RSAMP_SINC_COEF_ADDR,
SINC8_FILTER_COEF_ADDR);
for (i = 0; i < len; i++, p++)
new_resample_write(id, AUDIO_RSAMP_SINC_COEF_DATA, *p);
}
void new_resample_init_param(enum resample_idx id)
{
new_resample_write(id, AUDIO_RSAMP_CTRL0, 7);
new_resample_write(id, AUDIO_RSAMP_CTRL0, 0);
/*enable memory power*/
aml_write_hiubus(HHI_AUDIO_MEM_PD_REG0, 0x0);
/* filter tap of AA and sinc filter */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0xff << 8, 0x3f << 8);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0xff, 0x3f);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1 << 12, 0x1 << 12);
if (id == RESAMPLE_A) {
/*write resample A filter in ram*/
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
&sinc8_coef[0]);
} else {
/*write resample B filter in ram*/
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
&sinc_coef[0]);
}
}
void new_resample_enable(enum resample_idx id, bool enable)
{
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1,
0x1 << 11, enable << 11);
}
bool new_resample_get_status(enum resample_idx id)
{
unsigned int val = new_resample_read(id, AUDIO_RSAMP_CTRL1);
return ((val >> 11) & 0x1);
}
static int new_resample_status_check(enum resample_idx id)
{
int check_times = 20;
unsigned int val;
/* wait resample status to bypass, then change config, max 20us */
while (check_times--) {
val = new_resample_read(id, AUDIO_RSAMP_RO_STATUS);
val = (val >> 11) & 0x7;
if (val == 1)
break;
udelay(1);
}
if (check_times == 0) {
pr_err("%s(), check resample status error!", __func__);
return -1;
}
return 0;
}
void new_resample_set_format(enum resample_idx id, int channel, int bits)
{
int reg_val = bits - 1;
if (channel > 8 || channel == 0 || bits < 16)
return;
/* resample B is always 2 channel for loopback */
if (id == RESAMPLE_B) {
channel = 2;
reg_val = 31;
}
new_resample_enable(id, false);
new_resample_status_check(id);
new_resample_write(id, AUDIO_RSAMP_PHSINIT, 0x0);
/* channel num */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0x3f << 24,
channel << 24);
/* bit width */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1f << 13,
reg_val << 13);
/* enable auto adjust module */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2,
0x1 << 2);
new_resample_update_bits(id, AUDIO_RSAMP_ADJ_CTRL1, 0xffff << 16,
(256 / channel) << 16);
new_resample_write(id, AUDIO_RSAMP_ADJ_SFT, 0x1f020604);
new_resample_write(id, AUDIO_RSAMP_ADJ_IDET_LEN, 0x22710);
new_resample_write(id, AUDIO_RSAMP_ADJ_FORCE, 0x0);
new_resample_write(id, AUDIO_RSAMP_ADJ_CTRL0, 0x1);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2, 0x0 << 2);
new_resample_enable(id, true);
pr_info("%s(), channel = %d, bits = %d", __func__, channel, bits);
}
void new_resample_src_select(enum resample_idx id, enum resample_src src)
{
/* resample B is always for loopbackA */
if (id == RESAMPLE_B)
src = ASRC_LOOPBACK_A;
new_resample_enable(id, false);
new_resample_status_check(id);
/* resample source select */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0xf, src);
new_resample_enable(id, true);
}
void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr)
{
u32 down_ratio = 1;
u32 input_sample_rate = (u32)input_sr;
u32 output_sample_rate = (u32)output_sr;
u64 phase_step = (u64)input_sample_rate;
new_resample_enable(id, false);
new_resample_status_check(id);
if (input_sample_rate <= output_sample_rate) { /* upsample*/
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0x3 << 16,
0 << 16);
/* disable AA filter */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1 << 10,
0 << 10);
} else { /* downsample*/
int rate = input_sample_rate * 10 / output_sample_rate;
/* enable AA filter */
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1 << 10,
1 << 10);
if (id == RESAMPLE_A) {
if (rate <= 30) {
new_resample_set_ram_coeff_aa(
id, AA_FILTER_COEF_SIZE,
&aa_coef_a_half[0]);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
0x3 << 16, 1 << 16);
down_ratio = 2;
} else {
new_resample_set_ram_coeff_aa(
id, AA_FILTER_COEF_SIZE,
&aa_coef_a_quarter[0]);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
0x3 << 16, 2 << 16);
down_ratio = 4;
}
} else {
new_resample_set_ram_coeff_aa(
id, AA_FILTER_COEF_SIZE,
&aa_coef_one_third[0]);
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
0x3 << 16, 0 << 16);
down_ratio = 3;
}
}
output_sample_rate *= down_ratio;
phase_step *= (1 << 28);
phase_step = div_u64(phase_step, output_sample_rate);
new_resample_write(id, AUDIO_RSAMP_PHSSTEP, (u32)phase_step);
new_resample_enable(id, true);
pr_info("%s(), down_ratio = %d, phase_step = 0x%x", __func__,
down_ratio, (u32)phase_step);
}
void resample_enable(enum resample_idx id, bool enable)
{
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
audiobus_update_bits(reg,
0x1 << 31,
1 << 31);
if (enable == 1) {
/*don't change this flow*/
audiobus_update_bits(
reg, 0x1 << 31 | 0x1 << 28,
0 << 31 | 0x0 << 28);
audiobus_update_bits(reg,
0x1 << 31,
0 << 31);
audiobus_update_bits(reg, 0x1 << 31, 1 << 31);
audiobus_update_bits(reg,
0x1 << 28,
enable << 28);
audiobus_update_bits(reg, 0x1 << 31, 0 << 31);
}
audiobus_update_bits(reg, 0x1 << 28, enable << 28);
}
bool resample_get_status(enum resample_idx id)
{
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
bool enable = (audiobus_read(reg) >> 28) & 0x1;
return enable;
}
int resample_init(enum resample_idx id, int input_sr)
@@ -85,16 +296,6 @@ int resample_init(enum resample_idx id, int input_sr)
return 0;
}
int resample_disable(enum resample_idx id)
{
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
audiobus_write(reg, 0);
return 0;
}
int resample_set_hw_param(enum resample_idx id,
enum samplerate_index rate_index)
{
@@ -129,8 +330,9 @@ void resample_src_select(int src)
0x3 << 29,
src << 29);
}
/* for tl1 and after */
void resample_src_select_ab(enum resample_idx id, enum toddr_src src)
void resample_src_select_ab(enum resample_idx id, enum resample_src src)
{
int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3;
int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id;

View File

@@ -28,19 +28,34 @@ enum samplerate_index {
RATE_96K,
RATE_176K,
RATE_192K,
RATE_16K,
RATE_MAX,
};
extern void resample_enable(enum resample_idx id, bool enable);
extern int resample_init(enum resample_idx id, int input_sr);
extern int resample_disable(enum resample_idx id);
extern int resample_set_hw_param(enum resample_idx id,
enum samplerate_index rate_index);
extern void resample_src_select(int src);
extern void resample_src_select_ab(enum resample_idx id, enum toddr_src src);
extern void resample_format_set(enum resample_idx id, int ch_num, int bits);
#define DEFAULT_SPK_SAMPLERATE 48000
#define DEFAULT_MIC_SAMPLERATE 16000
extern int resample_ctrl_read(enum resample_idx id);
extern void resample_ctrl_write(enum resample_idx id, int value);
bool resample_get_status(enum resample_idx id);
void resample_enable(enum resample_idx id, bool enable);
int resample_init(enum resample_idx id, int input_sr);
int resample_set_hw_param(enum resample_idx id,
enum samplerate_index rate_index);
void resample_src_select(int src);
void resample_src_select_ab(enum resample_idx id, enum resample_src src);
void resample_format_set(enum resample_idx id, int ch_num, int bits);
int resample_ctrl_read(enum resample_idx id);
void resample_ctrl_write(enum resample_idx id, int value);
int resample_set_hw_pause_thd(enum resample_idx id, unsigned int thd);
void new_resample_set_ram_coeff_aa(enum resample_idx id, int len,
unsigned int *params);
void new_resample_set_ram_coeff_sinc(enum resample_idx id, int len,
unsigned int *params);
void new_resample_init_param(enum resample_idx id);
void new_resample_enable(enum resample_idx id, bool enable);
void new_resample_set_format(enum resample_idx id, int source, int channel);
void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr);
bool new_resample_get_status(enum resample_idx id);
void new_resample_src_select(enum resample_idx id, enum resample_src src);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -757,7 +757,8 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
#ifdef __SPDIFIN_AUDIO_TYPE_HW__
/* resample to 48k, by hw */
if (!spdifin_check_audiotype_by_sw(p_spdif))
resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
resample_set(p_spdif->asrc_id,
p_spdif->auto_asrc);
#endif
}
if (intrpt_status & 0x40)
@@ -1115,7 +1116,8 @@ static int aml_dai_spdif_startup(
#ifdef __SPDIFIN_AUDIO_TYPE_HW__
/* resample to 48k in default, by hw */
if (!spdifin_check_audiotype_by_sw(p_spdif))
resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
resample_set(p_spdif->asrc_id,
p_spdif->auto_asrc);
#endif
}

View File

@@ -43,7 +43,7 @@
#include <linux/input.h>
#include <linux/amlogic/vad_api.h>
#include "vad_hw_coeff.c"
#include "vad_hw_coeff.h"
#include "vad_hw.h"
#include "vad.h"

View File

@@ -1,5 +1,5 @@
/*
* sound/soc/amlogic/auge/vad_hw_coeff.c
* sound/soc/amlogic/auge/vad_hw_coeff.h
*
* Copyright (C) 2018 Amlogic, Inc. All rights reserved.
*
@@ -15,6 +15,9 @@
*
*/
#ifndef __VAD_HW_COEFF_H__
#define __VAD_HW_COEFF_H__
/* parameters for downsample and emphasis filter */
static int vad_de_coeff[] = {
0x31007f05,
@@ -165,3 +168,4 @@ static int vad_ram_coeff[] = {
0x00000FFF
};
#endif