diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts index d81d163552ac..f46b8bae1772 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts @@ -1089,6 +1089,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 0 1 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_a.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_a.dts index 63222e765930..4af01f5b2edf 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_a.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_a.dts @@ -1083,6 +1083,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 0 1 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202.dts b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202.dts index c0cc5f9ed647..48d15b758eeb 100644 --- a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202.dts +++ b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202.dts @@ -1236,6 +1236,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 1 0 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts index b65c3ae63248..5409c0ac196c 100644 --- a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts +++ b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts @@ -1235,6 +1235,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 1 0 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts index 5d80550b5426..1c494d0015fe 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts @@ -1091,6 +1091,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 0 1 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_a.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_a.dts index 01ad8af9cd0a..f4588c978a94 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_a.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_a.dts @@ -1085,6 +1085,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 0 1 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202.dts b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202.dts index 8351d2f3323a..7cc45fa00daf 100644 --- a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202.dts +++ b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202.dts @@ -1232,6 +1232,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 1 0 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts index 57a4f6bbd268..fc96671cbb61 100644 --- a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts +++ b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac202_1g.dts @@ -1233,6 +1233,8 @@ datain_chmask = <0xf>; /* config which data pin for loopback */ datain-lane-mask-in = <1 1 0 0>; + /* define loopack with pdm mic. */ + mic-src = <&aml_pdm>; /* calc mclk for datalb */ mclk-fs = <256>; diff --git a/sound/soc/amlogic/auge/loopback.c b/sound/soc/amlogic/auge/loopback.c index 2dd0c77253b9..a63bd89c8e11 100644 --- a/sound/soc/amlogic/auge/loopback.c +++ b/sound/soc/amlogic/auge/loopback.c @@ -34,6 +34,7 @@ #include "resample.h" #include "vad.h" +#include "pdm.h" #define DRV_NAME "loopback" @@ -66,6 +67,7 @@ struct loopback { unsigned int datain_chmask; unsigned int datain_lane_mask; /* related with data lane */ + void *mic_src; /* * datalb */ @@ -633,6 +635,11 @@ static void datatin_pdm_cfg( unsigned int bit_depth = snd_pcm_format_width(runtime->format); unsigned int osr; struct pdm_info info; + struct aml_pdm *pdm = (struct aml_pdm *)p_loopback->mic_src; + int gain_index = 0; + + if (pdm) + gain_index = pdm->pdm_gain_index; info.bitdepth = bit_depth; info.channels = p_loopback->datain_chnum; @@ -645,7 +652,7 @@ static void datatin_pdm_cfg( /* filter for pdm */ osr = pdm_get_ors(p_loopback->dclk_idx, runtime->rate); - aml_pdm_filter_ctrl(osr, 1); + aml_pdm_filter_ctrl(gain_index, osr, 1); } static int loopback_dai_prepare( @@ -1452,6 +1459,8 @@ static int loopback_platform_probe(struct platform_device *pdev) struct loopback_chipinfo *p_chipinfo = NULL; struct device_node *node_prt = NULL; struct platform_device *pdev_parent = NULL; + struct device_node *np_src = NULL; + struct platform_device *dev_src = NULL; struct aml_audio_controller *actrl = NULL; int ret = 0; @@ -1461,6 +1470,14 @@ static int loopback_platform_probe(struct platform_device *pdev) if (!p_loopback) return -ENOMEM; + np_src = of_parse_phandle(node, "mic-src", 0); + if (np_src) { + dev_src = of_find_device_by_node(np_src); + of_node_put(np_src); + p_loopback->mic_src = platform_get_drvdata(dev_src); + pr_debug("%s(), mic_src found\n", __func__); + } + /* match data */ p_chipinfo = (struct loopback_chipinfo *) of_device_get_match_data(dev); diff --git a/sound/soc/amlogic/auge/pdm.c b/sound/soc/amlogic/auge/pdm.c index 18d23f63a62d..822541181435 100644 --- a/sound/soc/amlogic/auge/pdm.c +++ b/sound/soc/amlogic/auge/pdm.c @@ -38,9 +38,12 @@ #include "regs.h" #include "ddr_mngr.h" #include "vad.h" +#include "pdm_hw_coeff.h" /*#define __PTM_PDM_CLK__*/ +#define DRV_NAME "snd_pdm" + static struct snd_pcm_hardware aml_pdm_hardware = { .info = SNDRV_PCM_INFO_MMAP | @@ -269,7 +272,7 @@ static void pdm_set_lowpower_mode(struct aml_pdm *p_pdm, bool isLowPower) osr = 192; filter_mode = p_pdm->isLowPower ? 4 : p_pdm->filter_mode; - aml_pdm_filter_ctrl(osr, filter_mode); + aml_pdm_filter_ctrl(p_pdm->pdm_gain_index, osr, filter_mode); /* update sample count */ pdm_set_channel_ctrl( @@ -371,6 +374,33 @@ static int pdm_train_set_enum( return 0; } +/* set pdm gain index. */ +static int pdm_gain_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); + + ucontrol->value.integer.value[0] = p_pdm->pdm_gain_index; + + return 0; +} + +static int pdm_gain_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); + int value = ucontrol->value.integer.value[0]; + + if (value < 0 || value > (NUM_PDM_GAIN_INDEX - 1)) { + pr_info("%s, invalid value: %d [Range:0~48]", __func__, value); + return 0; + } + + p_pdm->pdm_gain_index = value; + + return 0; +} + static const struct snd_kcontrol_new snd_pdm_controls[] = { /* which set */ SOC_ENUM_EXT("PDM Filter Mode", @@ -403,6 +433,12 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = { pdm_bypass_enum, pdm_bypass_get_enum, pdm_bypass_set_enum), + /* index of pdm_gain_table[49], index: 0~48 */ + SOC_SINGLE_EXT("PDM Gain", + SND_SOC_NOPM, 0, + (NUM_PDM_GAIN_INDEX - 1), 0, + pdm_gain_get_enum, + pdm_gain_set_enum) }; #if 0 @@ -925,7 +961,7 @@ static int aml_pdm_dai_prepare( dclk_idx); aml_pdm_ctrl(&info); - aml_pdm_filter_ctrl(osr, filter_mode); + aml_pdm_filter_ctrl(p_pdm->pdm_gain_index, osr, filter_mode); if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data) pdm_init_truncate_data(runtime->rate); diff --git a/sound/soc/amlogic/auge/pdm.h b/sound/soc/amlogic/auge/pdm.h index e39153a030c4..30f8f57775c3 100644 --- a/sound/soc/amlogic/auge/pdm.h +++ b/sound/soc/amlogic/auge/pdm.h @@ -22,8 +22,6 @@ #include -#define DRV_NAME "snd_pdm" - #define DEFAULT_FS_RATIO 256 #define PDM_CHANNELS_MIN 1 @@ -97,6 +95,7 @@ struct aml_pdm { /* low power mode, for dclk_sycpll to 24m */ bool isLowPower; + int pdm_gain_index; }; #endif /*__AML_PDM_H__*/ diff --git a/sound/soc/amlogic/auge/pdm_hw.c b/sound/soc/amlogic/auge/pdm_hw.c index b05e84b132b5..d1db286bda35 100644 --- a/sound/soc/amlogic/auge/pdm_hw.c +++ b/sound/soc/amlogic/auge/pdm_hw.c @@ -159,13 +159,12 @@ void aml_pdm_arb_config(struct aml_audio_controller *actrl) } /* config for hcic, lpf1,2,3, hpf */ -static void aml_pdm_filters_config(int osr, +static void aml_pdm_filters_config(int pdm_gain_index, int osr, int lpf1_len, int lpf2_len, int lpf3_len) { int32_t hcic_dn_rate; int32_t hcic_tap_num; int32_t hcic_gain; - int32_t hcic_shift; int32_t f1_tap_num; int32_t f2_tap_num; int32_t f3_tap_num; @@ -183,62 +182,35 @@ static void aml_pdm_filters_config(int osr, switch (osr) { case 32: hcic_dn_rate = 0x4; - hcic_gain = 0x80; - hcic_shift = 0xe; - break; - case 40: - hcic_dn_rate = 0x5; - hcic_gain = 0x6b; - hcic_shift = 0x10; - break; - case 48: - hcic_dn_rate = 0x6; - hcic_gain = 0x78; - hcic_shift = 0x12; - break; - case 56: - hcic_dn_rate = 0x7; - hcic_gain = 0x51; - hcic_shift = 0x13; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_32]; break; case 64: hcic_dn_rate = 0x0008; - hcic_gain = 0x80; - hcic_shift = 0x15; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_64]; break; case 96: hcic_dn_rate = 0x000c; - hcic_gain = 0x78; - hcic_shift = 0x19; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_96]; break; case 128: hcic_dn_rate = 0x0010; - hcic_gain = 0x80; - hcic_shift = 0x1c; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_128]; break; case 192: hcic_dn_rate = 0x0018; - hcic_gain = 0x78; - hcic_shift = 0x20; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_192]; break; case 384: hcic_dn_rate = 0x0030; - hcic_gain = 0x78; - hcic_shift = 0x27; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_384]; break; default: pr_info("Not support osr:%d, translate to :192\n", osr); hcic_dn_rate = 0x0018; - hcic_gain = 0x78; - hcic_shift = 0x20; + hcic_gain = pdm_gain_table[pdm_gain_index][PDM_OSR_192]; break; } - /* TODO: fixed hcic_shift 'cause of Dmic */ - if (pdm_hcic_shift_gain) - hcic_shift -= 0x4; - - hcic_tap_num = 0x0007; f1_tap_num = lpf1_len; f2_tap_num = lpf2_len; @@ -259,8 +231,7 @@ static void aml_pdm_filters_config(int osr, (0x80000000 | hcic_tap_num | (hcic_dn_rate << 4) | - (hcic_gain << 16) | - (hcic_shift << 24)) + (hcic_gain << 16)) ); /* lpf */ @@ -347,7 +318,7 @@ static void aml_pdm_LPF_coeff( } -void aml_pdm_filter_ctrl(int osr, int mode) +void aml_pdm_filter_ctrl(int pdm_gain_index, int osr, int mode) { int lpf1_len, lpf2_len, lpf3_len; const int *lpf1_coeff, *lpf2_coeff, *lpf3_coeff; @@ -369,6 +340,7 @@ void aml_pdm_filter_ctrl(int osr, int mode) */ switch (osr) { + case 32: case 64: lpf2_coeff = lpf2_osr64; break; @@ -387,10 +359,6 @@ void aml_pdm_filter_ctrl(int osr, int mode) case 384: lpf2_coeff = lpf2_osr384; break; - case 32: - case 40: - case 48: - case 56: default: pr_info("osr :%d , lpf2 uses default parameters with osr64\n", osr); @@ -445,7 +413,9 @@ void aml_pdm_filter_ctrl(int osr, int mode) } /* config filter */ - aml_pdm_filters_config(osr, + aml_pdm_filters_config( + pdm_gain_index, + osr, lpf1_len, lpf2_len, lpf3_len); @@ -537,11 +507,11 @@ int pdm_dclkidx2rate(int idx) return rate; } -int pdm_get_sample_count(int isLowPower, int dclk_idx) +int pdm_get_sample_count(int is_low_power, int dclk_idx) { int count = 0; - if (isLowPower) + if (is_low_power) count = 0; else if (dclk_idx == 1) count = 38; @@ -576,12 +546,12 @@ int pdm_get_ors(int dclk_idx, int 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 == 24000) + osr = 128; else if (sample_rate == 16000) osr = 192; else if (sample_rate == 8000) diff --git a/sound/soc/amlogic/auge/pdm_hw.h b/sound/soc/amlogic/auge/pdm_hw.h index 2f0c89710aa5..3c6d5e04629d 100644 --- a/sound/soc/amlogic/auge/pdm_hw.h +++ b/sound/soc/amlogic/auge/pdm_hw.h @@ -41,7 +41,7 @@ extern void aml_pdm_arb_config(struct aml_audio_controller *actrl); extern int aml_pmd_set_HPF_filter_parameters(void *array); -extern void aml_pdm_filter_ctrl(int osr, int set); +void aml_pdm_filter_ctrl(int pdm_gain_index, int osr, int set); extern void pdm_enable(int is_enable); diff --git a/sound/soc/amlogic/auge/pdm_hw_coeff.h b/sound/soc/amlogic/auge/pdm_hw_coeff.h index 5b4195cbef48..ab45d54b4f24 100644 --- a/sound/soc/amlogic/auge/pdm_hw_coeff.h +++ b/sound/soc/amlogic/auge/pdm_hw_coeff.h @@ -278,4 +278,70 @@ static const int lpf3_mode4[] = { 0xffb7a1, 0xffd46b }; +#define NUM_PDM_GAIN_INDEX 49 +#define NUM_PDM_OSR_INDEX 6 + +enum { + PDM_OSR_384 = 0, + PDM_OSR_192, + PDM_OSR_128, + PDM_OSR_96, + PDM_OSR_64, + PDM_OSR_32 +}; + +/* min: 0 dB; max: 24 dB; step = 0.5 dB/step */ +static const int pdm_gain_table[NUM_PDM_GAIN_INDEX][NUM_PDM_OSR_INDEX] = { +/* osr: 384, 192, 128, 96, 64, 32 */ + { 0x2778, 0x2078, 0x1c80, 0x1978, 0x1580, 0xe80,}, // 0dB + { 0x277f, 0x207f, 0x1b44, 0x197f, 0x1444, 0xd44,}, // 0.5dB + { 0x2643, 0x1f43, 0x1b48, 0x1843, 0x1448, 0xd48,}, // 1dB + { 0x2647, 0x1f47, 0x1b4c, 0x1847, 0x144c, 0xd4c,}, // 1.5dB + { 0x264c, 0x1f4c, 0x1b51, 0x184c, 0x1451, 0xd51,}, // 2dB + { 0x2650, 0x1f50, 0x1b55, 0x1850, 0x1455, 0xd55,}, // 2.5dB + { 0x2655, 0x1f55, 0x1b5a, 0x1855, 0x145a, 0xd5a,}, // 3dB + { 0x265a, 0x1f5a, 0x1b60, 0x185a, 0x1460, 0xd60,}, // 3.5dB + { 0x265f, 0x1f5f, 0x1b65, 0x185f, 0x1465, 0xd65,}, // 4dB + { 0x2665, 0x1f65, 0x1b6b, 0x1865, 0x146b, 0xd6b,}, // 4.5dB + { 0x266b, 0x1f6b, 0x1b72, 0x186b, 0x1472, 0xd72,}, // 5dB + { 0x2671, 0x1f71, 0x1b79, 0x1871, 0x1479, 0xd79,}, // 5.5dB + { 0x2678, 0x1f78, 0x1b80, 0x1878, 0x1480, 0xd80,}, // 6dB + { 0x267f, 0x1f7f, 0x1a44, 0x187f, 0x1344, 0xc44,}, // 6.5dB + { 0x2543, 0x1e43, 0x1a48, 0x1743, 0x1348, 0xc48,}, // 7dB + { 0x2547, 0x1e47, 0x1a4c, 0x1747, 0x134c, 0xc4c,}, // 7.5dB + { 0x254b, 0x1e4b, 0x1a50, 0x174b, 0x1350, 0xc50,}, // 8dB + { 0x2550, 0x1e50, 0x1a55, 0x1750, 0x1355, 0xc55,}, // 8.5dB + { 0x2555, 0x1e55, 0x1a5a, 0x1755, 0x135a, 0xc5a,}, // 9dB + { 0x255a, 0x1e5a, 0x1a60, 0x175a, 0x1360, 0xc60,}, // 9.5dB + { 0x255f, 0x1e5f, 0x1a65, 0x175f, 0x1365, 0xc65,}, // 10dB + { 0x2564, 0x1e64, 0x1a6b, 0x1764, 0x136b, 0xc6b,}, // 10.5dB + { 0x256a, 0x1e6a, 0x1a72, 0x176a, 0x1372, 0xc72,}, // 11dB + { 0x2571, 0x1e71, 0x1a78, 0x1771, 0x1378, 0xc78,}, // 11.5dB + { 0x2577, 0x1e77, 0x1a7f, 0x1777, 0x137f, 0xc7f,}, // 12dB + { 0x257f, 0x1e7f, 0x1943, 0x177f, 0x1243, 0xb43,}, // 12.5dB + { 0x2443, 0x1d43, 0x1947, 0x1643, 0x1247, 0xb47,}, // 13dB + { 0x2447, 0x1d47, 0x194c, 0x1647, 0x124c, 0xb4c,}, // 13.5dB + { 0x244b, 0x1d4b, 0x1950, 0x164b, 0x1250, 0xb50,}, // 14dB + { 0x2450, 0x1d50, 0x1955, 0x1650, 0x1255, 0xb55,}, // 14.5dB + { 0x2454, 0x1d54, 0x195a, 0x1654, 0x125a, 0xb5a,}, // 15dB + { 0x2459, 0x1d59, 0x195f, 0x1659, 0x125f, 0xb5f,}, // 15.5dB + { 0x245f, 0x1d5f, 0x1965, 0x165f, 0x1265, 0xb65,}, // 16dB + { 0x2464, 0x1d64, 0x196b, 0x1664, 0x126b, 0xb6b,}, // 16.5dB + { 0x246a, 0x1d6a, 0x1971, 0x166a, 0x1271, 0xb71,}, // 17dB + { 0x2470, 0x1d70, 0x1978, 0x1670, 0x1278, 0xb78,}, // 17.5dB + { 0x2477, 0x1d77, 0x197f, 0x1677, 0x127f, 0xb7f,}, // 18dB + { 0x247e, 0x1d7e, 0x1843, 0x167e, 0x1143, 0xa43,}, // 18.5dB + { 0x2343, 0x1c43, 0x1847, 0x1543, 0x1147, 0xa47,}, // 19dB + { 0x2347, 0x1c47, 0x184c, 0x1547, 0x114c, 0xa4c,}, // 19.5dB + { 0x234b, 0x1c4b, 0x1850, 0x154b, 0x1150, 0xa50,}, // 20dB + { 0x234f, 0x1c4f, 0x1855, 0x154f, 0x1155, 0xa55,}, // 20.5dB + { 0x2354, 0x1c54, 0x185a, 0x1554, 0x115a, 0xa5a,}, // 21dB + { 0x2359, 0x1c59, 0x185f, 0x1559, 0x115f, 0xa5f,}, // 21.5dB + { 0x235e, 0x1c5e, 0x1865, 0x155e, 0x1165, 0xa65,}, // 22dB + { 0x2364, 0x1c64, 0x186b, 0x1564, 0x116b, 0xa6b,}, // 22.5dB + { 0x236a, 0x1c6a, 0x1871, 0x156a, 0x1171, 0xa71,}, // 23dB + { 0x2370, 0x1c70, 0x1878, 0x1570, 0x1178, 0xa78,}, // 23.5dB + { 0x2377, 0x1c77, 0x187f, 0x1577, 0x117f, 0xa7f,}, // 24dB +}; + #endif