From patchwork Wed Feb 14 23:51:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Kaehlcke X-Patchwork-Id: 10220081 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 08990601C2 for ; Wed, 14 Feb 2018 23:52:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EEC9E274D0 for ; Wed, 14 Feb 2018 23:52:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E36C02846D; Wed, 14 Feb 2018 23:52:46 +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=unavailable 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 006A0274D0 for ; Wed, 14 Feb 2018 23:52:45 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 651C7267BB5; Thu, 15 Feb 2018 00:52:41 +0100 (CET) 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 11C11267BBC; Thu, 15 Feb 2018 00:52:40 +0100 (CET) Received: from mail-pg0-f68.google.com (mail-pg0-f68.google.com [74.125.83.68]) by alsa0.perex.cz (Postfix) with ESMTP id 8E565266F0D for ; Thu, 15 Feb 2018 00:52:36 +0100 (CET) Received: by mail-pg0-f68.google.com with SMTP id o1so2851056pgn.4 for ; Wed, 14 Feb 2018 15:52:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=1f975NJNQt/NemX2xsydmQwWfB8MOk9JVnhiApPNW9E=; b=GI0r2jwtPKAkEXRX4d5obdpLbWz50QHiswE166vHZNbt6sfaZlzLrjNBlNvi/GIVZD cvsaDdl4/Jl57iGDLB488MjRHYUu1rDtyhYibbduxc8cY1d2xfZn+LOQMSBmNhLp9l2w 8tzy9Zp3idVoJYOFGt8xDsFEb5EMV1OZfaaDMMN4vQEmd/XAFESoVa5k+f34ON7O6dGe VjQGYiwObQTn1ksjuBc9qu4KXAk9rN3CjaUAauB1V1gwSM7FP+zjfRjgnlSHwKSdImv1 PaQghmZvroRS8lfehtmQcY9pfUoKmHZkLB/zgIV7I4ZRhnh55/Rq0eizmTlpc5lhg4q+ lh3Q== X-Gm-Message-State: APf1xPDVSv2E7PNOlYSLD05IrGh/AkdQZbUuwhPveJqmYzVFsk+P3wez j3O+Grboh6D+ZAnhy6PIvJ482A== X-Google-Smtp-Source: AH8x2242E6PBpEK8eAFHRyZIuzA1+ghpH/rPhmfW1dqpq9HPBU4JQdgayyaenmeV8vKRKORrVTrNyQ== X-Received: by 10.99.122.74 with SMTP id j10mr580743pgn.84.1518652354520; Wed, 14 Feb 2018 15:52:34 -0800 (PST) Received: from mka.mtv.corp.google.com ([2620:0:1000:1501:9f72:a769:d80e:13c2]) by smtp.gmail.com with ESMTPSA id x4sm37749677pgo.15.2018.02.14.15.52.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Feb 2018 15:52:33 -0800 (PST) From: Matthias Kaehlcke To: Liam Girdwood , Mark Brown , Rob Herring , Mark Rutland , Jaroslav Kysela , Takashi Iwai Date: Wed, 14 Feb 2018 15:51:56 -0800 Message-Id: <20180214235156.81589-1-mka@chromium.org> X-Mailer: git-send-email 2.16.1.291.g4437f3f132-goog Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, huang lin , Brian Norris , linux-kernel@vger.kernel.org, Matthias Kaehlcke , Dylan Reid Subject: [alsa-devel] [PATCH] ASoC: dmic: Add optional wakeup delay 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP On some systems a delay is needed after switching on the clocks, to allow the DMIC output to stabilize and avoid a popping noise at the beginning of the recording. Add the optional device tree property 'wakeup-delay-ms' and apply the specified delay in the new dmic_daiops_prepare(). Signed-off-by: Matthias Kaehlcke --- .../devicetree/bindings/sound/dmic.txt | 2 + sound/soc/codecs/dmic.c | 54 ++++++++++++++----- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/dmic.txt b/Documentation/devicetree/bindings/sound/dmic.txt index 54c8ef6498a8..de741c6609d0 100644 --- a/Documentation/devicetree/bindings/sound/dmic.txt +++ b/Documentation/devicetree/bindings/sound/dmic.txt @@ -7,10 +7,12 @@ Required properties: Optional properties: - dmicen-gpios: GPIO specifier for dmic to control start and stop + - wakeup-delay-ms: Delay (in ms) after enabling the DMIC Example node: dmic_codec: dmic@0 { compatible = "dmic-codec"; dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + wakeup-delay-ms <50>; }; diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index b88a1ee66f80..11f6abf11074 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include @@ -29,24 +30,38 @@ #include #include +struct dmic { + struct gpio_desc *gpio_en; + int wakeup_delay; +}; + +static int dmic_daiops_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct dmic *dmic = snd_soc_dai_get_drvdata(dai); + + if (dmic->gpio_en) + gpiod_set_value(dmic->gpio_en, 1); + + if (dmic->wakeup_delay) + msleep(dmic->wakeup_delay); + + return 0; +} + static int dmic_daiops_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai); + struct dmic *dmic = snd_soc_dai_get_drvdata(dai); - if (!dmic_en) + if (!dmic->gpio_en) return 0; switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - gpiod_set_value(dmic_en, 1); - break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - gpiod_set_value(dmic_en, 0); + gpiod_set_value(dmic->gpio_en, 0); break; } @@ -54,6 +69,7 @@ static int dmic_daiops_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops dmic_dai_ops = { + .prepare = dmic_daiops_prepare, .trigger = dmic_daiops_trigger, }; @@ -73,14 +89,24 @@ static struct snd_soc_dai_driver dmic_dai = { static int dmic_codec_probe(struct snd_soc_codec *codec) { - struct gpio_desc *dmic_en; + struct dmic *dmic; + int err; + + dmic = devm_kzalloc(codec->dev, sizeof(*dmic), GFP_KERNEL); + if (!dmic) + return -ENOMEM; + + dmic->gpio_en = devm_gpiod_get_optional(codec->dev, + "dmicen", GPIOD_OUT_LOW); + if (IS_ERR(dmic->gpio_en)) + return PTR_ERR(dmic->gpio_en); - dmic_en = devm_gpiod_get_optional(codec->dev, - "dmicen", GPIOD_OUT_LOW); - if (IS_ERR(dmic_en)) - return PTR_ERR(dmic_en); + err = device_property_read_u32(codec->dev, "wakeup-delay-ms", + &dmic->wakeup_delay); + if (err && (err != -EINVAL)) + return err; - snd_soc_codec_set_drvdata(codec, dmic_en); + snd_soc_codec_set_drvdata(codec, dmic); return 0; }