From patchwork Wed Sep 14 07:47:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AS50 KCHsu0 X-Patchwork-Id: 9330723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B90826077F for ; Wed, 14 Sep 2016 07:50:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABE4F299FB for ; Wed, 14 Sep 2016 07:50:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9FB6C29A3A; Wed, 14 Sep 2016 07:50:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4295E299FB for ; Wed, 14 Sep 2016 07:50:23 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 63E6E261A8B; Wed, 14 Sep 2016 09:50:22 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id EF04F261A8B; Wed, 14 Sep 2016 09:47:53 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id BDB7E265598; Wed, 14 Sep 2016 09:47:44 +0200 (CEST) Received: from maillog.nuvoton.com (maillog.nuvoton.com [202.39.227.15]) by alsa0.perex.cz (Postfix) with ESMTP id 7EFFE261A5E for ; Wed, 14 Sep 2016 09:47:39 +0200 (CEST) Received: from nthcims03.nuvoton.com (nthcims03.nuvoton.com [10.1.8.100]) by maillog.nuvoton.com (Postfix) with ESMTP id DE4DC1C80430; Wed, 14 Sep 2016 15:47:34 +0800 (CST) Received: from localhost.localdomain (10.4.36.27) by nthcims03.nuvoton.com (10.1.8.100) with Microsoft SMTP Server id 8.3.327.1; Wed, 14 Sep 2016 15:47:34 +0800 From: John Hsu To: Date: Wed, 14 Sep 2016 15:47:32 +0800 Message-ID: <1473839252-18868-1-git-send-email-KCHSU0@nuvoton.com> X-Mailer: git-send-email 2.6.4 MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, anatol.pomozov@gmail.com, YHCHuang@nuvoton.com, WTLI@nuvoton.com, John Hsu , lgirdwood@gmail.com, benzh@chromium.org, CTLIN0@nuvoton.com, mhkuo@nuvoton.com, yong.zhi@intel.com Subject: [alsa-devel] [PATCH] ASoC: nau8825: erase pop noise by soft mute X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP The patch is a solution to fix the following issue. Chrome OS Issue 54078: Chell_headphone pop back from S3 When the system resume from S3 and playing music, there is a pop noise happened. It looks like system changes the sound immediately from maximum volume to the volume configured by user in playback beginning. The sound signal changes sharply, and there is a DC offset in the signal to make pop noise. Therefore, the driver introduces the soft mute to avoid the side effect of the unstable signal. Signed-off-by: John Hsu --- sound/soc/codecs/nau8825.c | 52 +++++++++++++++++++++++++++++++++++++++++++++- sound/soc/codecs/nau8825.h | 3 +++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index e643be9..3bcba14 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -754,8 +754,9 @@ static void nau8825_xtalk_measure(struct nau8825 *nau8825) nau8825->imp_rms[NAU8825_XTALK_HPR_R2L], nau8825->imp_rms[NAU8825_XTALK_HPL_R2L]); dev_dbg(nau8825->dev, "cross talk sidetone: %x\n", sidetone); + nau8825->sidetone = (sidetone << 8) | sidetone; regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL, - (sidetone << 8) | sidetone); + nau8825->sidetone); nau8825_xtalk_clean(nau8825); nau8825->xtalk_state = NAU8825_XTALK_DONE; break; @@ -1334,6 +1335,50 @@ int nau8825_enable_jack_detect(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect); +/** + * nau8825_soft_mute - provide soft mute function + * + * @component: codec component + * @mute: 1 for mute; 0 for unmute + * + * Enable soft mute to gradually lower DAC volume to zero; + * Soft unmute will gradually increase DAC volume to volume setting. + * We found that signal at beginning is not stable in some application. + * That signal changes sharply will make pop noise; but the steps of soft + * mute is not enough in codec to cover the change period. Thus, the driver + * deffers 20ms to do soft unmute for the pop noise issue. + */ +int nau8825_soft_mute(struct snd_soc_codec *codec, int mute) +{ + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); + + if (mute) { + cancel_delayed_work(&nau8825->softmute_work); + /* Disable sidetone to avoid it affect the mute function */ + regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL, 0); + regmap_update_bits(nau8825->regmap, NAU8825_REG_MUTE_CTRL, + NAU8825_DAC_SOFT_MUTE, NAU8825_DAC_SOFT_MUTE); + } else { + /* Defer 20ms to do soft unmute to skip the unstable signal */ + schedule_delayed_work(&nau8825->softmute_work, + msecs_to_jiffies(20)); + } + + return 0; +} +EXPORT_SYMBOL_GPL(nau8825_soft_mute); + +static void nau8825_unmute_deferred(struct work_struct *work) +{ + struct nau8825 *nau8825 = container_of(work, + struct nau8825, softmute_work.work); + + /* Restore sidetone */ + regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL, + nau8825->sidetone); + regmap_update_bits(nau8825->regmap, NAU8825_REG_MUTE_CTRL, + NAU8825_DAC_SOFT_MUTE, 0); +} static bool nau8825_is_jack_inserted(struct regmap *regmap) { @@ -2150,6 +2195,7 @@ static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id, static int nau8825_resume_setup(struct nau8825 *nau8825) { + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(nau8825->dapm); struct regmap *regmap = nau8825->regmap; /* Close clock when jack type detection at manual mode */ @@ -2169,6 +2215,8 @@ static int nau8825_resume_setup(struct nau8825 *nau8825) NAU8825_JACK_DET_DB_BYPASS, NAU8825_JACK_DET_DB_BYPASS); regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, NAU8825_IRQ_INSERT_DIS | NAU8825_IRQ_EJECT_DIS, 0); + /* Enable codec soft mute */ + nau8825_soft_mute(codec, 1); return 0; } @@ -2393,8 +2441,10 @@ static int nau8825_i2c_probe(struct i2c_client *i2c, */ nau8825->xtalk_state = NAU8825_XTALK_DONE; nau8825->xtalk_protect = false; + nau8825->sidetone = 0; sema_init(&nau8825->xtalk_sem, 1); INIT_WORK(&nau8825->xtalk_work, nau8825_xtalk_work); + INIT_DELAYED_WORK(&nau8825->softmute_work, nau8825_unmute_deferred); nau8825_print_device_properties(nau8825); diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h index 1c63e2a..e15ea5c 100644 --- a/sound/soc/codecs/nau8825.h +++ b/sound/soc/codecs/nau8825.h @@ -433,6 +433,7 @@ struct nau8825 { struct snd_soc_dapm_context *dapm; struct snd_soc_jack *jack; struct clk *mclk; + struct delayed_work softmute_work; struct work_struct xtalk_work; struct semaphore xtalk_sem; int irq; @@ -459,10 +460,12 @@ struct nau8825 { int xtalk_event_mask; bool xtalk_protect; int imp_rms[NAU8825_XTALK_IMM]; + int sidetone; }; int nau8825_enable_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); +int nau8825_soft_mute(struct snd_soc_codec *codec, int mute); #endif /* __NAU8825_H__ */