audio: add kcontrol of pdm hareware gain [1/1]

PD#SWPL-44152

Problem:
Pdm mic level is low. The noise level gets worse
when add software gain.

Solution:
1) remove software gain
2) add kcontrol of pdm hw gain, this gain range is 0-24dB.
   0.5dB/step.
3) if user uses pdm mic of loopback,
   add "mic-src = <&pdm>;" in dts.

Verify:
T5

Signed-off-by: chunlong.cao <chunlong.cao@amlogic.com>
Change-Id: Icd0915cc63f5dd302979e741354baf62d04d6daa
This commit is contained in:
chunlong.cao
2021-09-08 17:07:00 +08:00
committed by Chris
parent d93a456063
commit 710cb430f8
14 changed files with 158 additions and 54 deletions

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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);

View File

@@ -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);

View File

@@ -22,8 +22,6 @@
#include <linux/pinctrl/consumer.h>
#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__*/

View File

@@ -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)

View File

@@ -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);

View File

@@ -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