ASoC: rockchip: rk817-codec: Fix capture noise issue

This commit is contained in:
baiywt 2024-04-26 10:34:37 +08:00
parent 38dd4d9d9a
commit 338a0b10ac
2 changed files with 131 additions and 52 deletions

167
sound/soc/codecs/rk817_codec.c Normal file → Executable file
View File

@ -238,15 +238,21 @@ static int rk817_codec_ctl_gpio(struct rk817_codec_priv *rk817,
{ {
if ((gpio & CODEC_SET_SPK) && if ((gpio & CODEC_SET_SPK) &&
rk817->spk_ctl_gpio) { rk817->spk_ctl_gpio) {
if (level && rk817->spk_mute_delay)
msleep(rk817->spk_mute_delay);
gpiod_set_value(rk817->spk_ctl_gpio, level); gpiod_set_value(rk817->spk_ctl_gpio, level);
DBG("%s set spk clt %d\n", __func__, level); DBG("%s set spk clt %d\n", __func__, level);
if (!level && rk817->spk_mute_delay)
msleep(rk817->spk_mute_delay); msleep(rk817->spk_mute_delay);
} }
if ((gpio & CODEC_SET_HP) && if ((gpio & CODEC_SET_HP) &&
rk817->hp_ctl_gpio) { rk817->hp_ctl_gpio) {
if (level && rk817->hp_mute_delay)
msleep(rk817->hp_mute_delay);
gpiod_set_value(rk817->hp_ctl_gpio, level); gpiod_set_value(rk817->hp_ctl_gpio, level);
DBG("%s set hp clt %d\n", __func__, level); DBG("%s set hp clt %d\n", __func__, level);
if (!level && rk817->hp_mute_delay)
msleep(rk817->hp_mute_delay); msleep(rk817->hp_mute_delay);
} }
@ -267,12 +273,12 @@ static int rk817_reset(struct snd_soc_component *component)
snd_soc_component_write(component, RK817_CODEC_APLL_CFG5, 0x00); snd_soc_component_write(component, RK817_CODEC_APLL_CFG5, 0x00);
snd_soc_component_write(component, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00); snd_soc_component_write(component, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00);
if (rk817->chip_ver <= 0x4) { if (rk817->chip_ver <= 0x4) {
DBG("%s (%d): SMIC TudorAG and previous versions\n", DBG("%s (%d): 0x4 and previous versions\n",
__func__, __LINE__); __func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
} else { } else {
DBG("%s (%d): SMIC TudorAG version later\n", DBG("%s (%d): 0x4 version later\n",
__func__, __LINE__); __func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
@ -282,6 +288,77 @@ static int rk817_reset(struct snd_soc_component *component)
return 0; return 0;
} }
static int rk817_restart_dac_digital_clk(struct snd_soc_component *component)
{
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_MASK, PWD_DACBIAS_ON);
return 0;
}
static int rk817_restart_dac_digital_clk_and_apll(struct snd_soc_component *component)
{
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
PLL_PW_DOWN, PLL_PW_DOWN);
usleep_range(50, 60);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
PLL_PW_DOWN, PLL_PW_UP);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_MASK, PWD_DACBIAS_ON);
return 0;
}
static int rk817_restart_adc_digital_clk(struct snd_soc_component *component)
{
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
return 0;
}
static int rk817_restart_adc_digital_clk_and_apll(struct snd_soc_component *component)
{
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
usleep_range(500, 600);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
PLL_PW_DOWN, PLL_PW_DOWN);
usleep_range(50, 60);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
PLL_PW_DOWN, PLL_PW_UP);
usleep_range(500, 600);
return 0;
}
static struct rk817_reg_val_typ playback_power_up_list[] = { static struct rk817_reg_val_typ playback_power_up_list[] = {
{RK817_CODEC_AREF_RTCFG1, 0x40}, {RK817_CODEC_AREF_RTCFG1, 0x40},
{RK817_CODEC_DDAC_POPD_DACST, 0x02}, {RK817_CODEC_DDAC_POPD_DACST, 0x02},
@ -380,22 +457,16 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type)
/* configure APLL CFG0/4 */ /* configure APLL CFG0/4 */
if (rk817->chip_ver <= 0x4) { if (rk817->chip_ver <= 0x4) {
DBG("%s (%d): SMIC TudorAG and previous versions\n", DBG("%s (%d): 0x4 and previous versions\n",
__func__, __LINE__); __func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
} else { } else {
DBG("%s: SMIC TudorAG version later\n", __func__); DBG("%s: 0x4 version later\n", __func__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
} }
rk817_restart_dac_digital_clk(component);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
usleep_range(2000, 2500);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
} }
if (type & RK817_CODEC_CAPTURE) { if (type & RK817_CODEC_CAPTURE) {
@ -411,22 +482,17 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type)
/* configure APLL CFG0/4 */ /* configure APLL CFG0/4 */
if (rk817->chip_ver <= 0x4) { if (rk817->chip_ver <= 0x4) {
DBG("%s (%d): SMIC TudorAG and previous versions\n", DBG("%s (%d): 0x4 and previous versions\n",
__func__, __LINE__); __func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
} else { } else {
DBG("%s: SMIC TudorAG version later\n", __func__); DBG("%s: 0x4 version later\n", __func__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
} }
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, rk817_restart_adc_digital_clk(component);
ADC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
usleep_range(2000, 2500);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
if (rk817->mic_in_differential) if (rk817->mic_in_differential)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
@ -872,7 +938,7 @@ static int rk817_resume_path_get(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
DBG("%s : resume_path %ld\n", __func__, rk817->resume_path); DBG("%s : resume_path %d\n", __func__, rk817->resume_path);
ucontrol->value.integer.value[0] = rk817->resume_path; ucontrol->value.integer.value[0] = rk817->resume_path;
@ -948,25 +1014,19 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
unsigned int rate = params_rate(params); unsigned int rate = params_rate(params);
unsigned char apll_cfg3_val; unsigned char apll_cfg3_val;
unsigned char dtop_digen_sr_lmt0; unsigned char dtop_digen_sr_lmt0;
unsigned char dtop_digen_clke;
DBG("%s : sample rate = %dHz\n", __func__, rate); DBG("%s : sample rate = %dHz\n", __func__, rate);
if (rk817->chip_ver <= 0x4) { if (rk817->chip_ver <= 0x4) {
DBG("%s: SMIC TudorAG and previous versions\n", __func__); DBG("%s: 0x4 and previous versions\n", __func__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
} else { } else {
DBG("%s: SMIC TudorAG version later\n", __func__); DBG("%s: 0x4 version later\n", __func__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
} }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dtop_digen_clke = DAC_DIG_CLK_EN;
else
dtop_digen_clke = ADC_DIG_CLK_EN;
switch (rate) { switch (rate) {
case 8000: case 8000:
apll_cfg3_val = 0x03; apll_cfg3_val = 0x03;
@ -998,19 +1058,12 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
*/ */
if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) { if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) {
snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val);
/* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
dtop_digen_clke, 0x00);
snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0,
DACSRT_MASK, dtop_digen_sr_lmt0); DACSRT_MASK, dtop_digen_sr_lmt0);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dtop_digen_clke, dtop_digen_clke); rk817_restart_dac_digital_clk_and_apll(component);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, else
PLL_PW_DOWN, PLL_PW_DOWN); rk817_restart_adc_digital_clk_and_apll(component);
usleep_range(50, 60);
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
PLL_PW_DOWN, PLL_PW_UP);
usleep_range(500, 600);
} }
switch (params_format(params)) { switch (params_format(params)) {
@ -1034,7 +1087,7 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream) static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
@ -1048,15 +1101,12 @@ static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RK817_CODEC_DDAC_MUTE_MIXCTL, RK817_CODEC_DDAC_MUTE_MIXCTL,
DACMT_ENABLE, DACMT_ENABLE); DACMT_ENABLE, DACMT_ENABLE);
snd_soc_component_write(component, RK817_CODEC_ADAC_CFG1, rk817_restart_dac_digital_clk(component);
PWD_DACBIAS_DOWN | PWD_DACD_DOWN |
PWD_DACL_DOWN | PWD_DACR_DOWN);
/* Reset DAC DTOP_DIGEN_CLKE for playback stopped */
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS); I2SRX_EN_MASK, I2SRX_DIS);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_EN, DAC_DIG_CLK_EN);
} else { } else {
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
I2SRX_EN_MASK, I2SRX_EN);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RK817_CODEC_DDAC_MUTE_MIXCTL, RK817_CODEC_DDAC_MUTE_MIXCTL,
DACMT_ENABLE, DACMT_DISABLE); DACMT_ENABLE, DACMT_DISABLE);
@ -1106,6 +1156,28 @@ static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
return 0; return 0;
} }
static int rk817_digital_mute_adc(struct snd_soc_dai *dai, int mute, int stream)
{
struct snd_soc_component *component = dai->component;
if (mute)
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
I2STX_EN_MASK, I2STX_DIS);
else
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
I2STX_EN_MASK, I2STX_EN);
return 0;
}
static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
return rk817_digital_mute_dac(dai, mute, stream);
else
return rk817_digital_mute_adc(dai, mute, stream);
}
#define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ #define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
SNDRV_PCM_RATE_16000 | \ SNDRV_PCM_RATE_16000 | \
SNDRV_PCM_RATE_32000 | \ SNDRV_PCM_RATE_32000 | \
@ -1150,7 +1222,6 @@ static struct snd_soc_dai_ops rk817_dai_ops = {
.set_sysclk = rk817_set_dai_sysclk, .set_sysclk = rk817_set_dai_sysclk,
.mute_stream = rk817_digital_mute, .mute_stream = rk817_digital_mute,
.shutdown = rk817_codec_shutdown, .shutdown = rk817_codec_shutdown,
.no_capture_mute = 1,
}; };
static struct snd_soc_dai_driver rk817_dai[] = { static struct snd_soc_dai_driver rk817_dai[] = {

12
sound/soc/codecs/rk817_codec.h Normal file → Executable file
View File

@ -81,7 +81,7 @@
#define ADC_DIG_CLK_MASK (0xf << 4) #define ADC_DIG_CLK_MASK (0xf << 4)
#define ADC_DIG_CLK_SFT 4 #define ADC_DIG_CLK_SFT 4
#define ADC_DIG_CLK_DIS (0x0 << 4) #define ADC_DIG_CLK_DIS (0x0 << 4)
#define ADC_DIG_CLK_EN (0xf << 4) #define ADC_DIG_CLK_EN (0xe << 4)
#define I2STX_CKE_EN (0x1 << 6) #define I2STX_CKE_EN (0x1 << 6)
#define I2STX_CKE_DIS (0x0 << 6) #define I2STX_CKE_DIS (0x0 << 6)
@ -89,7 +89,15 @@
#define DAC_DIG_CLK_MASK (0xf << 0) #define DAC_DIG_CLK_MASK (0xf << 0)
#define DAC_DIG_CLK_SFT 0 #define DAC_DIG_CLK_SFT 0
#define DAC_DIG_CLK_DIS (0x0 << 0) #define DAC_DIG_CLK_DIS (0x0 << 0)
#define DAC_DIG_CLK_EN (0xf << 0) #define DAC_DIG_CLK_EN (0xe << 0)
#define I2STX_EN_MASK BIT(4)
#define I2STX_EN BIT(4)
#define I2STX_DIS 0
#define I2SRX_EN_MASK BIT(0)
#define I2SRX_EN BIT(0)
#define I2SRX_DIS 0
/* RK817_CODEC_APLL_CFG5 */ /* RK817_CODEC_APLL_CFG5 */
#define PLL_PW_DOWN (0x01 << 0) #define PLL_PW_DOWN (0x01 << 0)