Merge "ASoC: codecs: sdm660_cdc: Fix pop noise issue at DMIC"

This commit is contained in:
Linux Build Service Account 2017-10-25 09:56:56 -07:00 committed by Gerrit - the friendly Code Review server
commit 73780981b5
2 changed files with 50 additions and 63 deletions

View file

@ -55,6 +55,11 @@ static unsigned long tx_digital_gain_reg[] = {
MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN,
};
#define SDM660_TX_UNMUTE_DELAY_MS 40
static int tx_unmute_delay = SDM660_TX_UNMUTE_DELAY_MS;
module_param(tx_unmute_delay, int, 0664);
MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
struct snd_soc_codec *registered_digcodec;
@ -924,6 +929,9 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
/* enable HPF */
snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00);
schedule_delayed_work(
&msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork,
msecs_to_jiffies(tx_unmute_delay));
if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
CF_MIN_3DB_150HZ) {
@ -937,20 +945,14 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
snd_soc_read(codec,
tx_digital_gain_reg[w->shift + offset])
);
if (pdata->lb_mode) {
pr_debug("%s: loopback mode unmute the DEC\n",
__func__);
snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
}
snd_soc_update_bits(codec, tx_vol_ctl_reg,
0x01, 0x00);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
msleep(20);
snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
cancel_delayed_work_sync(
&msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
@ -1191,6 +1193,35 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
}
EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry);
static void sdm660_tx_mute_update_callback(struct work_struct *work)
{
struct tx_mute_work *tx_mute_dwork;
struct snd_soc_codec *codec = NULL;
struct msm_dig_priv *dig_cdc;
struct delayed_work *delayed_work;
u16 tx_vol_ctl_reg = 0;
u8 decimator = 0, i;
delayed_work = to_delayed_work(work);
tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
dig_cdc = tx_mute_dwork->dig_cdc;
codec = dig_cdc->codec;
for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
if (dig_cdc->dec_active[i])
decimator = i + 1;
if (decimator && decimator < NUM_DECIMATORS) {
/* unmute decimators corresponding to Tx DAI's*/
tx_vol_ctl_reg =
MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
32 * (decimator - 1);
snd_soc_update_bits(codec, tx_vol_ctl_reg,
0x01, 0x00);
}
decimator = 0;
}
}
static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
{
struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
@ -1207,6 +1238,10 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
tx_hpf_work[i].decimator = i + 1;
INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
tx_hpf_corner_freq_callback);
msm_dig_cdc->tx_mute_dwork[i].dig_cdc = msm_dig_cdc;
msm_dig_cdc->tx_mute_dwork[i].decimator = i + 1;
INIT_DELAYED_WORK(&msm_dig_cdc->tx_mute_dwork[i].dwork,
sdm660_tx_mute_update_callback);
}
for (i = 0; i < MSM89XX_RX_MAX; i++)
@ -1891,63 +1926,8 @@ static const struct snd_kcontrol_new msm_dig_snd_controls[] = {
MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0),
};
static int msm_dig_cdc_digital_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = NULL;
u16 tx_vol_ctl_reg = 0;
u8 decimator = 0, i;
struct msm_dig_priv *dig_cdc;
pr_debug("%s: Digital Mute val = %d\n", __func__, mute);
if (!dai || !dai->codec) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
codec = dai->codec;
dig_cdc = snd_soc_codec_get_drvdata(codec);
if (dai->id == AIF1_PB) {
dev_dbg(codec->dev, "%s: Not capture use case skip\n",
__func__);
return 0;
}
mute = (mute) ? 1 : 0;
if (!mute) {
/*
* 15 ms is an emperical value for the mute time
* that was arrived by checking the pop level
* to be inaudible
*/
usleep_range(15000, 15010);
}
if (dai->id == AIF3_SVA) {
snd_soc_update_bits(codec,
MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x01, mute);
goto ret;
}
for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
if (dig_cdc->dec_active[i])
decimator = i + 1;
if (decimator && decimator < NUM_DECIMATORS) {
/* mute/unmute decimators corresponding to Tx DAI's */
tx_vol_ctl_reg =
MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
32 * (decimator - 1);
snd_soc_update_bits(codec, tx_vol_ctl_reg,
0x01, mute);
}
decimator = 0;
}
ret:
return 0;
}
static struct snd_soc_dai_ops msm_dig_dai_ops = {
.hw_params = msm_dig_cdc_hw_params,
.digital_mute = msm_dig_cdc_digital_mute,
};

View file

@ -32,6 +32,12 @@ enum {
MSM89XX_RX_MAX,
};
struct tx_mute_work {
struct msm_dig_priv *dig_cdc;
u32 decimator;
struct delayed_work dwork;
};
struct msm_dig_priv {
struct snd_soc_codec *codec;
u32 comp_enabled[MSM89XX_RX_MAX];
@ -54,6 +60,7 @@ struct msm_dig_priv {
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
};
struct dig_ctrl_platform_data {