From da0fc7e205900e081b7f790da59549e181fc63fc Mon Sep 17 00:00:00 2001 From: Shuai Li Date: Sat, 6 Apr 2019 16:17:57 +0800 Subject: [PATCH] audio: add codec trigger mute for depop [1/1] PD#SWPL-6944 Problem: TV-3381 Speaker sometimes has clicking noise when playing DTV program. Solution: add codec trigger mute for depop Verify: Local verified. Change-Id: Ib15a6b90bd3a6cdda2255afaf86daeab68ba07e2 Signed-off-by: Shuai Li --- sound/soc/amlogic/auge/card.c | 2 +- sound/soc/amlogic/auge/ddr_mngr.c | 14 +++++++--- sound/soc/codecs/amlogic/tas5805.c | 43 ++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/sound/soc/amlogic/auge/card.c b/sound/soc/amlogic/auge/card.c index 6d71f8fcccef..3e7c82cd0ca2 100644 --- a/sound/soc/amlogic/auge/card.c +++ b/sound/soc/amlogic/auge/card.c @@ -648,7 +648,7 @@ static int aml_card_dai_link_of(struct device_node *node, dai_link->ops = &aml_card_ops; dai_link->init = aml_card_dai_init; - + dai_link->nonatomic = 1; dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt); dev_dbg(dev, "\tcpu : %s / %d\n", diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index ee76da9a38d0..9f6e9e324f88 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -67,6 +67,12 @@ static struct frddr_attach attach_aed; static void aml_check_aed(bool enable, int dst); static bool aml_check_aed_module(int dst); +static irqreturn_t aml_ddr_isr(int irq, void *devid) +{ + (void)devid; + return IRQ_WAKE_THREAD; +} + /* to DDRS */ static struct toddr *register_toddr_l(struct device *dev, struct aml_audio_controller *actrl, @@ -88,8 +94,8 @@ static struct toddr *register_toddr_l(struct device *dev, to = &toddrs[i]; /* irqs request */ - ret = request_irq(to->irq, handler, - 0, dev_name(dev), data); + ret = request_threaded_irq(to->irq, aml_ddr_isr, handler, + IRQF_SHARED, dev_name(dev), data); if (ret) { dev_err(dev, "failed to claim irq %u\n", to->irq); return NULL; @@ -834,8 +840,8 @@ static struct frddr *register_frddr_l(struct device *dev, 1<<31|1<irq, handler, - 0, dev_name(dev), data); + ret = request_threaded_irq(from->irq, aml_ddr_isr, handler, + IRQF_SHARED, dev_name(dev), data); if (ret) { dev_err(dev, "failed to claim irq %u\n", from->irq); return NULL; diff --git a/sound/soc/codecs/amlogic/tas5805.c b/sound/soc/codecs/amlogic/tas5805.c index 615320e73b89..c7c89f84f748 100644 --- a/sound/soc/codecs/amlogic/tas5805.c +++ b/sound/soc/codecs/amlogic/tas5805.c @@ -52,7 +52,9 @@ #define TAS5805M_REG_29 (0x29) #define TAS5805M_REG_2A (0x2a) #define TAS5805M_REG_2B (0x2b) +#define TAS5805M_SDOUT_SEL (0x30) #define TAS5805M_REG_35 (0x35) +#define TAS5805M_DIG_VAL_CTL (0x4c) #define TAS5805M_REG_7F (0x7f) #define TAS5805M_PAGE_00 (0x00) @@ -231,6 +233,7 @@ struct tas5805m_priv { struct tas5805m_platform_data *pdata; int vol; int mute; + struct snd_soc_codec *codec; }; const struct regmap_config tas5805m_regmap = { @@ -303,6 +306,7 @@ static void tas5805m_set_volume(struct snd_soc_codec *codec, int vol) uint8_t byte3; uint8_t byte2; uint8_t byte1; + pr_info("%s(), vol = %d\n", __func__, vol); index = get_volume_index(vol); volume_hex = tas5805m_volume[index]; @@ -340,7 +344,6 @@ static int tas5805m_vol_locked_put(struct snd_kcontrol *kcontrol, tas5805m->vol = ucontrol->value.integer.value[0]; tas5805m_set_volume(codec, tas5805m->vol); - return 0; } @@ -433,10 +436,13 @@ static int tas5805m_set_bias_level(struct snd_soc_codec *codec, static int tas5805m_snd_probe(struct snd_soc_codec *codec) { + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_add_codec_controls(codec, tas5805m_vol_control, 2); + ret = snd_soc_add_codec_controls(codec, tas5805m_vol_control, + ARRAY_SIZE(tas5805m_vol_control)); + tas5805m->codec = codec; return ret; } @@ -476,8 +482,41 @@ static struct snd_soc_codec_driver soc_codec_tas5805m = { .set_bias_level = tas5805m_set_bias_level, }; +static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *codec_dai) +{ + struct tas5805m_priv *tas5805m = snd_soc_dai_get_drvdata(codec_dai); + struct snd_soc_codec *codec = tas5805m->codec; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("%s(), start\n", __func__); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_00); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_DIG_VAL_CTL, 0x30); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("%s(), stop\n", __func__); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_00); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_DIG_VAL_CTL, 0xff); + break; + } + } + + return 0; +} + static const struct snd_soc_dai_ops tas5805m_dai_ops = { //.digital_mute = tas5805m_mute, + .trigger = tas5805m_trigger, }; static struct snd_soc_dai_driver tas5805m_dai = {