From patchwork Tue Nov 5 14:32:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227975 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1C4721747 for ; Tue, 5 Nov 2019 14:35:55 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 97A7921928 for ; Tue, 5 Nov 2019 14:35:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="Ks1wxmn9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 97A7921928 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 294D816E6; Tue, 5 Nov 2019 15:35:02 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 294D816E6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964552; bh=kFFn8ISQ0kW31uPYPk751hKhq7lg8Upm/GPI9ZRh71o=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Ks1wxmn9fL76c7bljZwfbtRKl9xw6KzikzdBn9A0ZB1CQsQkaZbmpNfm3MZQpQyWQ ApTIzL+UL2c9eWEHu3acBD1sftVUPXf5mEpu35fQBRJkuy4+XmDsPMs4tccNsF9Ilm STf9XxukqhMYRxiYTmw0SeP5U8Nav2maPQ4z5/Ks= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BFC87F8053B; Tue, 5 Nov 2019 15:34:07 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id A7DA2F805AE; Tue, 5 Nov 2019 15:34:06 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id EF765F8015B for ; Tue, 5 Nov 2019 15:34:02 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz EF765F8015B IronPort-SDR: S4Hn+J5hRlF3r5Zh7D5HQ7wFEifFQZGlGN5gQOqIi6uENL1kvuieFH/6Hf65rHey+tbgkROr0h FqBgjJZezYeQaWimN1nAgXQHsmahKNwjOSz18vufJaYKbDW7W8QFIQzx09ap8om1Q3Mwz2iT3o zq20yES3QEctWAb69Qs7dAMRnuym8965TLc9mzBW+EJelbSz0KOQOqugx0ce8UTwUZKxnyj92v N/X5tRP8V1KXDzWcvxU3wL+0XVqg5Tmw2L23RTqSyT4FD/+sbmxACnNKZlXUDiaKbXOX5zDsbl bz4= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="44730617" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:33:58 -0800 IronPort-SDR: qjebKaLnrsPkMpPO+bqlb4ZUFikKKsuV6qLx0X33fJ9CyK6rnqiKzlpyIn4NfiQsDDJ1ZRjJU1 yoTEvNcyJq7KB2W16812TynYTQ5p4KVtd2zTeJqDtnET7JITaLxqqRMf6hlCYRJXAplcE+X1nx 1A2F6vGsvo566KlHPTXupHTditAVIXn/uXbl4J4F0hlHrQTm26gR+NKMYZbseSXKrPeqoPxZdP 6TV5zSKr1mjCxXEYZtmPKjbgdrly7aJLtW+r+zIB5pHtY/ZZp5jb7NymgvBbxvolbjsCIAZUW1 PQc= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:11 -0600 Message-ID: <20191105143218.5948-2-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-1-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-06.mgc.mentorg.com (139.181.222.6) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 1/8] ALSA: aloop: Describe units of variables X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer Describe the unit of the variables used to calculate the hw pointer depending on jiffies ticks. Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 9ccdad89c288..1f5982e09025 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -102,8 +102,10 @@ struct loopback_pcm { /* flags */ unsigned int period_update_pending :1; /* timer stuff */ - unsigned int irq_pos; /* fractional IRQ position */ - unsigned int period_size_frac; + unsigned int irq_pos; /* fractional IRQ position in jiffies + * ticks + */ + unsigned int period_size_frac; /* period size in jiffies ticks */ unsigned int last_drift; unsigned long last_jiffies; struct timer_list timer; From patchwork Tue Nov 5 14:32:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227981 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C70D51747 for ; Tue, 5 Nov 2019 14:38:15 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5898321929 for ; Tue, 5 Nov 2019 14:38:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="V8aEwLBd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5898321929 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 81FC616A6; Tue, 5 Nov 2019 15:37:23 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 81FC616A6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964693; bh=Ypwf0Dx12+4SwDM9r0KkURmtMTw/gvvkRjVpSFArrpc=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=V8aEwLBddnbiHM2Zrb3d+/OT2S2WyF89MqOJ+tTycKeepSMAF5p2mQgyNRouVhLH/ paVrGrxr5Jp0hjDuwWRArXDzClLlvfNB7ibpO6I232MP6GvXmF+4ONFBTRwgaSOhWk D2Cm7IacB+39NiZ33Tp5mEnftNb9cfzbE9jOaGWE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 14ADDF8063E; Tue, 5 Nov 2019 15:34:45 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7F8AAF80633; Tue, 5 Nov 2019 15:34:43 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 810CDF80633 for ; Tue, 5 Nov 2019 15:34:39 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 810CDF80633 IronPort-SDR: lA8e6SteEa0q/p3rBocxQ6wVWsEQuivBcXd4/idrxjMvmdhrR/+Rbx3soZWfJ/UyDCEkBwcRFR v4J6DBrdYbJ8tNeB1Huh9KNMSTXu0IC25kZBDMq7V/lT5SVWST61LlNKN9f7gbXLbsJwBWKmFs k8JhJP4EmKR/aJcp2XOHUiIXM48ZYf4fckEMzOAuWHGyxi/7R6dy/1hBmo8FOBkm6iUU6voLhM 3LLgYipgrxqrNxkuKdbxN8bbS1IOAyWNJIEY/vef/yw/emjh8SA8yAo0ZkXbsy2Ya1b1JUbB5Z Flc= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="42819841" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:05 -0800 IronPort-SDR: C+x4olymjgc2C+OpQIjlrJCdlRcsjL5Qltv+InIzFQSDaGcSotgp+iVYPcOBybqZL4SVUUohGU sp9etVIgA2GjOchVZi4pNLZ0XAP2R6thP0bMa03hbxXuTdVrar3MFlnM3YjZmGhvN5TAjq7/YP xd0Resb3aRxSy0fUeWF6XFRkxw7RhHNNqdqKlfPJOf5l+crB3yJ/pm2auDZUdakosmpAx3G1fr hUvIJKtdH3kUJ1ZAThKUEko4W5fJMRrBUOjJeoFh5JjlSaJ3pooZ5BgxqwLiU7BGaSzkVPh50f wag= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:12 -0600 Message-ID: <20191105143218.5948-3-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-2-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-06.mgc.mentorg.com (139.181.222.6) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 2/8] ALSA: aloop: loopback_timer_start: Support return of error code X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer This is required for additional timer implementations which could detect errors and want to throw them. Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 1f5982e09025..b9ee5b72a996 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -155,7 +155,7 @@ static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm) } /* call in cable->lock */ -static void loopback_timer_start(struct loopback_pcm *dpcm) +static int loopback_timer_start(struct loopback_pcm *dpcm) { unsigned long tick; unsigned int rate_shift = get_rate_shift(dpcm); @@ -171,6 +171,8 @@ static void loopback_timer_start(struct loopback_pcm *dpcm) tick = dpcm->period_size_frac - dpcm->irq_pos; tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps; mod_timer(&dpcm->timer, jiffies + tick); + + return 0; } /* call in cable->lock */ @@ -251,7 +253,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_pcm_runtime *runtime = substream->runtime; struct loopback_pcm *dpcm = runtime->private_data; struct loopback_cable *cable = dpcm->cable; - int err, stream = 1 << substream->stream; + int err = 0, stream = 1 << substream->stream; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -264,7 +266,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); cable->running |= stream; cable->pause &= ~stream; - loopback_timer_start(dpcm); + err = loopback_timer_start(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -292,7 +294,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); dpcm->last_jiffies = jiffies; cable->pause &= ~stream; - loopback_timer_start(dpcm); + err = loopback_timer_start(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -300,7 +302,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) default: return -EINVAL; } - return 0; + return err; } static void params_change(struct snd_pcm_substream *substream) From patchwork Tue Nov 5 14:32:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227983 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9D4BC14E5 for ; Tue, 5 Nov 2019 14:38:41 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2D1A521929 for ; Tue, 5 Nov 2019 14:38:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="IRHfedPH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2D1A521929 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 5FA8C16F1; Tue, 5 Nov 2019 15:37:49 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 5FA8C16F1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964719; bh=K/Sqr1WiNh0tVOj5GCJQRMDN9Z6jECPYDIAe9kiv5iE=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=IRHfedPHI9/h1LwjYg1Cq6TZUB6d5Dhiu0CyQPEKTxXj9gjoSJLoKAsbHHwX9T8mu f1FzaEyffRZRL4fwVakGBaCGRzZsLxD5sfPJEfitu8TW1CzFyG0OQXCNG9dJMi8Wu5 bnx2kSUwcu2A4iDxvIsFfAsfsN8wtCD4if83tLac= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 51402F80659; Tue, 5 Nov 2019 15:34:47 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 69777F8064C; Tue, 5 Nov 2019 15:34:45 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 0EC78F80446 for ; Tue, 5 Nov 2019 15:34:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 0EC78F80446 IronPort-SDR: EwOfBElxxxzC8XqinLv7j9rgXDecLXNzXXXf/SHuPU7LtZzalJLJXviWHYVGaDyNgXEnRbAioR NJ3owLcqxbJnHhHKOKSdl5dStfcIXAl2AFAdqaf2F+IoYUoKmBrAqVdRZ/VzlNtFuRHEyctgH6 izPQ2N/Rug+dfROwsx49eISQtkPN9gPHg0BYbs8jUtQUH+GKM/za/QG7/QLH9wtz4ycrbHzEyL tHJsSnOjSxVHB/ZqMLRmr+2suGW3TK4RDKP53c/v5RXVfIjUu9JCII9hr2CdHQinzE850PftBQ YMY= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="42819844" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:08 -0800 IronPort-SDR: +0Dq2ZhvKabs6yLKH6f9Hk78ZSJXcEVKqw0emzKUvB3M+5tKequoYgsy8DfFRq1SRJ8SaXdsjI Yv7Vew4tTs9fOZD0cxRRPemCXDPDW1CkKeFjhmrbBS3vMMBAUNLVAIgADPm+0o9OD4gYUT2LZH sFbYC8jF1ZiUANkn1nN1hhGyyaqxxzRwJwq2/bSSTebA0qloGF0Eu9lnlszR45UkGH21TZ6aul jl0gh662jJvbRF0QqsTJdH7FObrpQOL+zRNJ9sasbQvl4mKFcoE+KRRtgiSgwdr2i3rAR5YAWi BaE= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:13 -0600 Message-ID: <20191105143218.5948-4-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-3-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-06.mgc.mentorg.com (139.181.222.6) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 3/8] ALSA: aloop: loopback_timer_stop: Support return of error code X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer This is required for additional timer implementations which could detect errors and want to throw them. Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index b9ee5b72a996..dc9154662d5b 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -176,15 +176,19 @@ static int loopback_timer_start(struct loopback_pcm *dpcm) } /* call in cable->lock */ -static inline void loopback_timer_stop(struct loopback_pcm *dpcm) +static inline int loopback_timer_stop(struct loopback_pcm *dpcm) { del_timer(&dpcm->timer); dpcm->timer.expires = 0; + + return 0; } -static inline void loopback_timer_stop_sync(struct loopback_pcm *dpcm) +static inline int loopback_timer_stop_sync(struct loopback_pcm *dpcm) { del_timer_sync(&dpcm->timer); + + return 0; } #define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK) @@ -275,7 +279,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); cable->running &= ~stream; cable->pause &= ~stream; - loopback_timer_stop(dpcm); + err = loopback_timer_stop(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -284,7 +288,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_SUSPEND: spin_lock(&cable->lock); cable->pause |= stream; - loopback_timer_stop(dpcm); + err = loopback_timer_stop(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -323,9 +327,11 @@ static int loopback_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct loopback_pcm *dpcm = runtime->private_data; struct loopback_cable *cable = dpcm->cable; - int bps, salign; + int err, bps, salign; - loopback_timer_stop_sync(dpcm); + err = loopback_timer_stop_sync(dpcm); + if (err < 0) + return err; salign = (snd_pcm_format_physical_width(runtime->format) * runtime->channels) / 8; From patchwork Tue Nov 5 14:32:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227985 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F3D014E5 for ; Tue, 5 Nov 2019 14:39:21 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A28BF21A4A for ; Tue, 5 Nov 2019 14:39:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="UvaI3Ay0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A28BF21A4A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B95CA16ED; Tue, 5 Nov 2019 15:38:28 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B95CA16ED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964758; bh=NLcPmm6s4l3J8FFEZNkFLsOA9X6bL6lI1k9RxmkUwF8=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=UvaI3Ay0QD4EW+QDis0sGbEmwN4PGtHUFmKs75yeIkJXWcO6aCsRtHx0KmWhq1Hn2 0hTqn8pyvtymaBdFqx/AMv6QGRRHlcyaiCVpNVY9IG7PIW8eHGqktgoNV5qJlXf6dY 7bALvrRf9dvLDIhU2thCg42hZreScB57dudISw14= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 12532F80446; Tue, 5 Nov 2019 15:34:49 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id F1E20F8065A; Tue, 5 Nov 2019 15:34:46 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 6C3DBF80636 for ; Tue, 5 Nov 2019 15:34:42 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6C3DBF80636 IronPort-SDR: TCnou1u9Scrt8RI5YlFMgKFgeNITD6CRTaTgV1jtS660k3IhskXNrTzFOBOglWTywnmIMmR74u nFBJdbX4VJSlegPfWNNJBnh1FWmnUMmFMmsV4esp+3E8YdIXxCLgHQpMXfzH2AQ96CkNsi+7aA EiLFBHyWqYIwYoPY8yDGSq/hp2ZlJEkPMlT1BizLniK4x0DLfPMBT88qM57b7F4wpttEcyCeyv O5ADoIleq/ptyREFNNr6JzN7arO2R9nX01Rg6G5ptot/urYHzlJJzNFjWPt5j09pITYpz/edTe 1No= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="42819850" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:11 -0800 IronPort-SDR: KONV3XTLOdfwgoq9SofcJ0b59z6wRF8fnriv2zFf1bK18oh4JDmqs8b6VUK6UCCevb82/0M2ZI exERENKxjULi6OoWHLguYW4uPfZn43QomdqFHKj0/svmV+lXiGJ2glaI/hxb5/VVFqzOG6yvK5 KnAitfMndM6UqsJYkAAYR9vPe1OKqUN99sZzn3WYKqlytxAOFdJuQbrjXMkeINLr/k1zEfJ+O9 rKvvqslLXiPXNXKUO115C98C9cyHSpSmOJg6AAEC5MRVhal3M0iveQlFE13LP5RPkxFjirc+Mv 7ok= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:14 -0600 Message-ID: <20191105143218.5948-5-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-4-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> <20191105143218.5948-4-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-06.mgc.mentorg.com (139.181.222.6) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 4/8] ALSA: aloop: Use callback functions for timer specific implementations X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer This commit only refactors the implementation. It does not change the behaviour. It is required to support other timers (e.g sound timer). Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 113 +++++++++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 19 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index dc9154662d5b..92134e9c6ea7 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -55,8 +55,39 @@ MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels change #define NO_PITCH 100000 +struct loopback_cable; struct loopback_pcm; +struct loopback_ops { + /* optional + * call in loopback->cable_lock + */ + int (*open)(struct loopback_pcm *dpcm); + /* required + * call in cable->lock + */ + int (*start)(struct loopback_pcm *dpcm); + /* required + * call in cable->lock + */ + int (*stop)(struct loopback_pcm *dpcm); + /* optional */ + int (*stop_sync)(struct loopback_pcm *dpcm); + /* optional */ + int (*close_substream)(struct loopback_pcm *dpcm); + /* optional + * call in loopback->cable_lock + */ + int (*close_cable)(struct loopback_pcm *dpcm); + /* optional + * call in cable->lock + */ + unsigned int (*pos_update)(struct loopback_cable *cable); + /* optional */ + void (*dpcm_info)(struct loopback_pcm *dpcm, + struct snd_info_buffer *buffer); +}; + struct loopback_cable { spinlock_t lock; struct loopback_pcm *streams[2]; @@ -65,6 +96,8 @@ struct loopback_cable { unsigned int valid; unsigned int running; unsigned int pause; + /* timer specific */ + struct loopback_ops *ops; }; struct loopback_setup { @@ -270,7 +303,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); cable->running |= stream; cable->pause &= ~stream; - err = loopback_timer_start(dpcm); + err = cable->ops->start(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -279,7 +312,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); cable->running &= ~stream; cable->pause &= ~stream; - err = loopback_timer_stop(dpcm); + err = cable->ops->stop(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -288,7 +321,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_SUSPEND: spin_lock(&cable->lock); cable->pause |= stream; - err = loopback_timer_stop(dpcm); + err = cable->ops->stop(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -298,7 +331,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&cable->lock); dpcm->last_jiffies = jiffies; cable->pause &= ~stream; - err = loopback_timer_start(dpcm); + err = cable->ops->start(dpcm); spin_unlock(&cable->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) loopback_active_notify(dpcm); @@ -329,9 +362,11 @@ static int loopback_prepare(struct snd_pcm_substream *substream) struct loopback_cable *cable = dpcm->cable; int err, bps, salign; - err = loopback_timer_stop_sync(dpcm); - if (err < 0) - return err; + if (cable->ops->stop_sync) { + err = cable->ops->stop_sync(dpcm); + if (err < 0) + return err; + } salign = (snd_pcm_format_physical_width(runtime->format) * runtime->channels) / 8; @@ -539,6 +574,18 @@ static void loopback_timer_function(struct timer_list *t) spin_unlock_irqrestore(&dpcm->cable->lock, flags); } +static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm, + struct snd_info_buffer *buffer) +{ + snd_iprintf(buffer, " update_pending:\t%u\n", + dpcm->period_update_pending); + snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); + snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); + snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n", + dpcm->last_jiffies, jiffies); + snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); +} + static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -546,7 +593,8 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t pos; spin_lock(&dpcm->cable->lock); - loopback_pos_update(dpcm->cable); + if (dpcm->cable->ops->pos_update) + dpcm->cable->ops->pos_update(dpcm->cable); pos = dpcm->buf_pos; spin_unlock(&dpcm->cable->lock); return bytes_to_frames(runtime, pos); @@ -672,12 +720,33 @@ static void free_cable(struct snd_pcm_substream *substream) cable->streams[substream->stream] = NULL; spin_unlock_irq(&cable->lock); } else { + struct loopback_pcm *dpcm = substream->runtime->private_data; + + if (cable->ops && cable->ops->close_cable && dpcm) + cable->ops->close_cable(dpcm); /* free the cable */ loopback->cables[substream->number][dev] = NULL; kfree(cable); } } +static int loopback_jiffies_timer_open(struct loopback_pcm *dpcm) +{ + timer_setup(&dpcm->timer, loopback_timer_function, 0); + + return 0; +} + +static struct loopback_ops loopback_jiffies_timer_ops = { + .open = loopback_jiffies_timer_open, + .start = loopback_timer_start, + .stop = loopback_timer_stop, + .stop_sync = loopback_timer_stop_sync, + .close_substream = loopback_timer_stop_sync, + .pos_update = loopback_pos_update, + .dpcm_info = loopback_jiffies_timer_dpcm_info, +}; + static int loopback_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -695,7 +764,6 @@ static int loopback_open(struct snd_pcm_substream *substream) } dpcm->loopback = loopback; dpcm->substream = substream; - timer_setup(&dpcm->timer, loopback_timer_function, 0); cable = loopback->cables[substream->number][dev]; if (!cable) { @@ -706,9 +774,17 @@ static int loopback_open(struct snd_pcm_substream *substream) } spin_lock_init(&cable->lock); cable->hw = loopback_pcm_hardware; + cable->ops = &loopback_jiffies_timer_ops; loopback->cables[substream->number][dev] = cable; } dpcm->cable = cable; + runtime->private_data = dpcm; + + if (cable->ops->open) { + err = cable->ops->open(dpcm); + if (err < 0) + goto unlock; + } snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -734,7 +810,9 @@ static int loopback_open(struct snd_pcm_substream *substream) if (err < 0) goto unlock; - runtime->private_data = dpcm; + /* loopback_runtime_free() has not to be called if kfree(dpcm) was + * already called here. Otherwise it will end up with a double free. + */ runtime->private_free = loopback_runtime_free; if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; @@ -758,12 +836,14 @@ static int loopback_close(struct snd_pcm_substream *substream) { struct loopback *loopback = substream->private_data; struct loopback_pcm *dpcm = substream->runtime->private_data; + int err = 0; - loopback_timer_stop_sync(dpcm); + if (dpcm->cable->ops->close_substream) + err = dpcm->cable->ops->close_substream(dpcm); mutex_lock(&loopback->cable_lock); free_cable(substream); mutex_unlock(&loopback->cable_lock); - return 0; + return err; } static const struct snd_pcm_ops loopback_pcm_ops = { @@ -1086,13 +1166,8 @@ static void print_dpcm_info(struct snd_info_buffer *buffer, snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps); snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign); snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift); - snd_iprintf(buffer, " update_pending:\t%u\n", - dpcm->period_update_pending); - snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); - snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); - snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n", - dpcm->last_jiffies, jiffies); - snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); + if (dpcm->cable->ops->dpcm_info) + dpcm->cable->ops->dpcm_info(dpcm, buffer); } static void print_substream_info(struct snd_info_buffer *buffer, From patchwork Tue Nov 5 14:32:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227977 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 01F9514E5 for ; Tue, 5 Nov 2019 14:36:49 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 85C8221928 for ; Tue, 5 Nov 2019 14:36:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="uPBd3ChD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 85C8221928 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id AA54416E1; Tue, 5 Nov 2019 15:35:56 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AA54416E1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964606; bh=uq1qC5PvNIq7saKCbyjF8Wkl3q+cUzcmbb29zOgAEfQ=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uPBd3ChDHI58VS+I2wlIK5L/1tvvCgy9eDg6A8T/DDpEzIRvnJdLvESHPUKCs/0UQ rDgivwQu0eHqZgn4bd7ppJAoNr2bSNB+ze0aq42vfeM+qLl06wtDOtNUwCJQL3nOkb +7hubuetxLpw5Lx1Mph8UZi88MpO3ZSZ++5QtXlk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 6D705F80612; Tue, 5 Nov 2019 15:34:39 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7843EF80633; Tue, 5 Nov 2019 15:34:37 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CDDDBF80610 for ; Tue, 5 Nov 2019 15:34:33 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CDDDBF80610 IronPort-SDR: 3YEm+0umkDiAxROHH5iyTdNeouo1g2Itt14TUlFHDXfpStHaKQuO8Pxr0du1kqzDJ2csyIejD7 t+tMS+eFjoqTsVR3BRWAIuuqUjCKWmz8lNouKpNJu5XTb0OpHktctuZbj3AFdWOpPznjQ1YTig b7RsOYz5XSNVidINCo7XQbRkOlBHoxaeimB+V9pUljjkgtNDPG6FX5sHWLQEEG7PWQz1IorV2I QM0rEfd5mHUM/eA9JK9aDC8AMWQG1rU/7AiLD5WJFsko4EnYo2/25UkEBfkobIbeDILWwO2G7f xoI= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="42878542" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:31 -0800 IronPort-SDR: ivTcNRoZqcAx0GOcM23pubI0ZZ3SSMV0aEjNmuNj7UiFhAKUaeXfdYiagSsfkEkcaox5dYXLA9 U3lV4vHiI7zqTM16wIA0m5boJ3r+GlH/eRn5RJ2Q6yyXDNP60GQts9RHRBpY9yhHj5MGYzH9fX zQREtmjAKLLLW/Ad7Dp/LSPNaaZ0S5NgdaMkFcb8CSvE1BYBekmwSWQf8KWK5k+bnHbtuXJQRt JQgGHbeNrXMUgE2dyL9v3EVevUf3GnYppDYfcPOTN9ZNCY3kvVQaDElvuBSzYWDnMdSvd8sSTF 4Zc= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:15 -0600 Message-ID: <20191105143218.5948-6-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-5-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> <20191105143218.5948-4-andrew_gabbasov@mentor.com> <20191105143218.5948-5-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-07.mgc.mentorg.com (139.181.222.7) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 5/8] ALSA: aloop: Rename all jiffies timer specific functions X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer This commit does not change the behaviour. It only separates the jiffies timer specific implementation from the generic part. Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 92134e9c6ea7..178f7260a650 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -188,7 +188,7 @@ static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm) } /* call in cable->lock */ -static int loopback_timer_start(struct loopback_pcm *dpcm) +static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm) { unsigned long tick; unsigned int rate_shift = get_rate_shift(dpcm); @@ -209,7 +209,7 @@ static int loopback_timer_start(struct loopback_pcm *dpcm) } /* call in cable->lock */ -static inline int loopback_timer_stop(struct loopback_pcm *dpcm) +static inline int loopback_jiffies_timer_stop(struct loopback_pcm *dpcm) { del_timer(&dpcm->timer); dpcm->timer.expires = 0; @@ -217,7 +217,7 @@ static inline int loopback_timer_stop(struct loopback_pcm *dpcm) return 0; } -static inline int loopback_timer_stop_sync(struct loopback_pcm *dpcm) +static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm) { del_timer_sync(&dpcm->timer); @@ -502,7 +502,8 @@ static inline void bytepos_finish(struct loopback_pcm *dpcm, } /* call in cable->lock */ -static unsigned int loopback_pos_update(struct loopback_cable *cable) +static unsigned int loopback_jiffies_timer_pos_update + (struct loopback_cable *cable) { struct loopback_pcm *dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; @@ -555,14 +556,15 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable) return running; } -static void loopback_timer_function(struct timer_list *t) +static void loopback_jiffies_timer_function(struct timer_list *t) { struct loopback_pcm *dpcm = from_timer(dpcm, t, timer); unsigned long flags; spin_lock_irqsave(&dpcm->cable->lock, flags); - if (loopback_pos_update(dpcm->cable) & (1 << dpcm->substream->stream)) { - loopback_timer_start(dpcm); + if (loopback_jiffies_timer_pos_update(dpcm->cable) & + (1 << dpcm->substream->stream)) { + loopback_jiffies_timer_start(dpcm); if (dpcm->period_update_pending) { dpcm->period_update_pending = 0; spin_unlock_irqrestore(&dpcm->cable->lock, flags); @@ -732,18 +734,18 @@ static void free_cable(struct snd_pcm_substream *substream) static int loopback_jiffies_timer_open(struct loopback_pcm *dpcm) { - timer_setup(&dpcm->timer, loopback_timer_function, 0); + timer_setup(&dpcm->timer, loopback_jiffies_timer_function, 0); return 0; } static struct loopback_ops loopback_jiffies_timer_ops = { .open = loopback_jiffies_timer_open, - .start = loopback_timer_start, - .stop = loopback_timer_stop, - .stop_sync = loopback_timer_stop_sync, - .close_substream = loopback_timer_stop_sync, - .pos_update = loopback_pos_update, + .start = loopback_jiffies_timer_start, + .stop = loopback_jiffies_timer_stop, + .stop_sync = loopback_jiffies_timer_stop_sync, + .close_substream = loopback_jiffies_timer_stop_sync, + .pos_update = loopback_jiffies_timer_pos_update, .dpcm_info = loopback_jiffies_timer_dpcm_info, }; From patchwork Tue Nov 5 14:32:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227979 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 90CC714E5 for ; Tue, 5 Nov 2019 14:37:33 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 227C521A4A for ; Tue, 5 Nov 2019 14:37:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="kVXb07L3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 227C521A4A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 39ED516ED; Tue, 5 Nov 2019 15:36:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 39ED516ED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964651; bh=5qtaS+RqEhFPDCNLyPm0lnDcpfMV7raz5PKWGoOcJ7M=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=kVXb07L3wYJqNJtdpEps5d0rqInfASIQqWDWoALf7ZrXSncvA1WAeJbeOz0tD+phb 18H0Di3ZV9YLAwJ+z0FvAlaBrrK0OB1rolPDHStyAtaccdIhxuKMvlshW3xymS0l1o Jv4Kt+bVfU8s/wlBqx6go/KJ1lFANEllKjCIxTEs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5C9D1F80638; Tue, 5 Nov 2019 15:34:43 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 93FB1F80446; Tue, 5 Nov 2019 15:34:41 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id ABA2CF80446 for ; Tue, 5 Nov 2019 15:34:35 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz ABA2CF80446 IronPort-SDR: Pp5a2m71i0L9YrlAxC8qORBDbOGsjwAuXmY//QNL9CfsvlMBfoAhVKA6zYML/iOdz+7/wyDvOn SZjUoo07Zg/9sKM/tDXgjMCMHrok2Egj0hr2x+W49zA+0Cj/H3k7tQ08oiAnPm6shXqnoi9j48 su7c473LGSYBNH9DuxEX9MKuvQKrMmtgT/YsoLU16JWINEDmnvT4ybvIPZs1eezoUlhm4Z7WLS 4T4uhuMmPzUCFSnZzsrH++K30m11GO0QF7jk9AP3XqehXmgMKO5AsCNxgmnwctXMHZDoffvaiG mkU= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="42878545" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:35 -0800 IronPort-SDR: 8egWQg81+5LreDHcOpMRCtMBtLfLF7C3VhqcTXg8LFfHs+8opw5R3oJoVoKs02F1ltrBDje42a WyR1E/Rm0VJvhFkIwvz0iveAfAsz/UQ81ttlwYvhKggKbavm8H5WqAdGYhiW1qm6VL5reNA6Gv AVs1dT61nwmqEno5qq9SCXC+qUfSLv2VZzJxTHyWkL9BVE8INzaL6Am5OqOixmTKyj5AZ1OZTK KwDFV7De1lmrMJhEfGPeqriYuCMLiVYpest6A3+lZI98d9ZUX0+iSDF/XheVdroIr3KYHr2mS4 luI= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:16 -0600 Message-ID: <20191105143218.5948-7-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-6-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> <20191105143218.5948-4-andrew_gabbasov@mentor.com> <20191105143218.5948-5-andrew_gabbasov@mentor.com> <20191105143218.5948-6-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-07.mgc.mentorg.com (139.181.222.7) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 6/8] ALSA: aloop: Move CABLE_VALID_BOTH to the top of file X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer so all functions can use the same. Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 178f7260a650..313d7ffe6c91 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -55,6 +55,10 @@ MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels change #define NO_PITCH 100000 +#define CABLE_VALID_PLAYBACK BIT(SNDRV_PCM_STREAM_PLAYBACK) +#define CABLE_VALID_CAPTURE BIT(SNDRV_PCM_STREAM_CAPTURE) +#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK | CABLE_VALID_CAPTURE) + struct loopback_cable; struct loopback_pcm; @@ -224,10 +228,6 @@ static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm) return 0; } -#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK) -#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE) -#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE) - static int loopback_check_format(struct loopback_cable *cable, int stream) { struct snd_pcm_runtime *runtime, *cruntime; From patchwork Tue Nov 5 14:32:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227989 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AA4521747 for ; Tue, 5 Nov 2019 14:40:58 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3B3F721929 for ; Tue, 5 Nov 2019 14:40:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="mAQ4zzTg" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3B3F721929 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 63F4D16AF; Tue, 5 Nov 2019 15:40:06 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 63F4D16AF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964856; bh=k8HFCY5Gmc8CfuR1PqySX7ejzJsV5WQ8587SMPC3MoE=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=mAQ4zzTg8kuHbE1mG1ito4JMP84X7MVZMtbA7KrMs/tCbPg0L6SGnbv2PKF8fwKWH 2x7qYPbazIU05nDdRvHr6bwrdDOwfdLcK/J2zD1JJq6Ydvbd+D9SJ2cQQ4TCOVRq/r KXrHKc8t2v0VomfIE8bgQujla0YpflAlJcahNybU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 29215F8068A; Tue, 5 Nov 2019 15:34:53 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0AC10F8065E; Tue, 5 Nov 2019 15:34:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B3C62F8063C for ; Tue, 5 Nov 2019 15:34:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B3C62F8063C IronPort-SDR: rgC8yoKK9XRp5sgXov/Uvy02NagEg8/WMwHU6J3LB3MSkEzkJPEr1ZBVPyZO1iwTXPf8aLA5u4 jq7zYHKQdzF1eSzp/UFWrusMM7NKdpLVGBpoW164ziP7FmJtss3F2MYRVzGSU09g3fGZE878as navvytH3tQNazVtPFIM/2zkMqENl6TddrDIwEYU6W9c1aaU8nwvudnD/+Eql7ObwJKKu0Wcsm2 +Jln7SinHA6C+b6cgG0KvpSbmw/L4p+o/JGyfeW/MJP9mr4ZHPFuso/05JybG6TKPKOGrM8G0H kRg= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="44730653" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:40 -0800 IronPort-SDR: CbPe0mca+udKp534fzrSpiq2pssf2ioI5A1Ar7syclAC7rNqR5I8cANBRoG2vJNOEybLzTLOn6 Ia6UkbatgEOvmEV/imfFaN/JXgTGHhMFJZ+uGxvo5IY8WLm2oVfTPRFQTvvc/r04f3sKTrtbfd y5koEiLAQytC4tUaYrzHilX4LyDnirdJ8555eIV5gHiXhEjympXa3cIsLuNLiUewlV6C63Yg81 +Ze8EP4xF68peKwPYPIpDtN8PVBJzc4/UDhqh2L05zVqNYpuBy83yUL4GGZjRqL4DrApbvhLeh NeA= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:17 -0600 Message-ID: <20191105143218.5948-8-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-7-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> <20191105143218.5948-4-andrew_gabbasov@mentor.com> <20191105143218.5948-5-andrew_gabbasov@mentor.com> <20191105143218.5948-6-andrew_gabbasov@mentor.com> <20191105143218.5948-7-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-07.mgc.mentorg.com (139.181.222.7) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 7/8] ALSA: aloop: Support selection of snd_timer instead of jiffies X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" From: Timo Wischer to do synchronous audio forwarding between hardware sound card and aloop devices. Such an audio route could look like the following: Sound card -> Loopback application -> ALSA loop device -> arecord In this case the loopback device should use the sound timer of the sound card. Without this patch the loopback application has to implement an adaptive sample rate converter to align the different clocks of the different ALSA devices. The used timer can be selected by referring to a sound card, its device and subdevice, when loading the module: $ modprobe snd_aloop enable=1 timer_source=[[.[.]]] is the name (id) of the sound card or a card number. and are device and subdevice numbers (defaults are 0). Empty string as a value of timer_source= parameter enables previous functionality (using jiffies timer). Signed-off-by: Timo Wischer Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 466 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 465 insertions(+), 1 deletion(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 313d7ffe6c91..6db70ebd46f6 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -28,6 +28,7 @@ #include #include #include +#include MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("A loopback soundcard"); @@ -41,6 +42,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; static int pcm_notify[SNDRV_CARDS]; +static char *timer_source[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for loopback soundcard."); @@ -52,6 +54,8 @@ module_param_array(pcm_substreams, int, NULL, 0444); MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver."); module_param_array(pcm_notify, int, NULL, 0444); MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes."); +module_param_array(timer_source, charp, NULL, 0444); +MODULE_PARM_DESC(timer_source, "Sound card name or number and device/subdevice number of timer to be used. Empty string for jiffies timer [default]."); #define NO_PITCH 100000 @@ -102,6 +106,13 @@ struct loopback_cable { unsigned int pause; /* timer specific */ struct loopback_ops *ops; + /* If sound timer is used */ + struct { + int owner; + struct snd_timer_id id; + struct tasklet_struct event_tasklet; + struct snd_timer_instance *instance; + } snd_timer; }; struct loopback_setup { @@ -122,6 +133,7 @@ struct loopback { struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2]; struct snd_pcm *pcm[2]; struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2]; + char *timer_source; }; struct loopback_pcm { @@ -145,6 +157,7 @@ struct loopback_pcm { unsigned int period_size_frac; /* period size in jiffies ticks */ unsigned int last_drift; unsigned long last_jiffies; + /* If jiffies timer is used */ struct timer_list timer; }; @@ -212,6 +225,34 @@ static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm) return 0; } +/* call in cable->lock */ +static int loopback_snd_timer_start(struct loopback_pcm *dpcm) +{ + int err; + + /* Loopback device has to use same period as timer card. Therefore + * wake up for each snd_pcm_period_elapsed() call of timer card. + */ + err = snd_timer_start(dpcm->cable->snd_timer.instance, 1); + if (err < 0) { + /* do not report error if trying to start but already + * running. For example called by opposite substream + * of the same cable + */ + if (err == -EBUSY) + return 0; + + pcm_err(dpcm->substream->pcm, + "snd_timer_start(%d,%d,%d) failed with %d", + dpcm->cable->snd_timer.id.card, + dpcm->cable->snd_timer.id.device, + dpcm->cable->snd_timer.id.subdevice, + err); + } + + return err; +} + /* call in cable->lock */ static inline int loopback_jiffies_timer_stop(struct loopback_pcm *dpcm) { @@ -221,6 +262,28 @@ static inline int loopback_jiffies_timer_stop(struct loopback_pcm *dpcm) return 0; } +/* call in cable->lock */ +static int loopback_snd_timer_stop(struct loopback_pcm *dpcm) +{ + int err; + + /* only stop if both devices (playback and capture) are not running */ + if (dpcm->cable->running) + return 0; + + err = snd_timer_stop(dpcm->cable->snd_timer.instance); + if (err < 0) { + pcm_err(dpcm->substream->pcm, + "snd_timer_stop(%d,%d,%d) failed with %d", + dpcm->cable->snd_timer.id.card, + dpcm->cable->snd_timer.id.device, + dpcm->cable->snd_timer.id.subdevice, + err); + } + + return err; +} + static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm) { del_timer_sync(&dpcm->timer); @@ -228,6 +291,37 @@ static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm) return 0; } +/* call in loopback->cable_lock */ +static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm) +{ + int err; + + /* snd_timer was not opened */ + if (!dpcm->cable->snd_timer.instance) + return 0; + + /* wait till drain tasklet has finished if requested */ + tasklet_kill(&dpcm->cable->snd_timer.event_tasklet); + + /* will only be called from free_cable() when other stream was + * already closed. Other stream cannot be reopened as long as + * loopback->cable_lock is locked. Therefore no need to lock + * cable->lock; + */ + err = snd_timer_close(dpcm->cable->snd_timer.instance); + if (err < 0) { + pcm_err(dpcm->substream->pcm, + "snd_timer_close(%d,%d,%d) failed with %d", + dpcm->cable->snd_timer.id.card, + dpcm->cable->snd_timer.id.device, + dpcm->cable->snd_timer.id.subdevice, + err); + } + memset(&dpcm->cable->snd_timer, 0, sizeof(dpcm->cable->snd_timer)); + + return err; +} + static int loopback_check_format(struct loopback_cable *cable, int stream) { struct snd_pcm_runtime *runtime, *cruntime; @@ -353,6 +447,13 @@ static void params_change(struct snd_pcm_substream *substream) cable->hw.rate_max = runtime->rate; cable->hw.channels_min = runtime->channels; cable->hw.channels_max = runtime->channels; + + if (cable->snd_timer.instance) { + cable->hw.period_bytes_min = + frames_to_bytes(runtime, runtime->period_size); + cable->hw.period_bytes_max = cable->hw.period_bytes_min; + } + } static int loopback_prepare(struct snd_pcm_substream *substream) @@ -576,6 +677,164 @@ static void loopback_jiffies_timer_function(struct timer_list *t) spin_unlock_irqrestore(&dpcm->cable->lock, flags); } +/* call in cable->lock */ +static int loopback_snd_timer_check_resolution(struct snd_pcm_runtime *runtime, + unsigned long resolution) +{ + if (resolution != runtime->timer_resolution) { + struct loopback_pcm *dpcm = runtime->private_data; + struct loopback_cable *cable = dpcm->cable; + /* Worst case estimation of possible values for resolution + * resolution <= (512 * 1024) frames / 8kHz in nsec + * resolution <= 65.536.000.000 nsec + * + * period_size <= 65.536.000.000 nsec / 1000nsec/usec * 192kHz + + * 500.000 + * period_size <= 12.582.912.000.000 <64bit + * / 1.000.000 usec/sec + */ + const snd_pcm_uframes_t period_size_usec = resolution / 1000 * + runtime->rate; + /* round to nearest sample rate */ + const snd_pcm_uframes_t period_size = (period_size_usec + 500 * + 1000) / (1000 * 1000); + + pcm_err(dpcm->substream->pcm, + "Period size (%lu frames) of loopback device is not corresponding to timer resolution (%lu nsec = %lu frames) of card timer %d,%d,%d. Use period size of %lu frames for loopback device.", + runtime->period_size, resolution, period_size, + cable->snd_timer.id.card, + cable->snd_timer.id.device, + cable->snd_timer.id.subdevice, + period_size); + return -EINVAL; + } + return 0; +} + +static void loopback_snd_timer_period_elapsed( + struct loopback_cable * const cable, + const int event, const unsigned long resolution) +{ + struct loopback_pcm *dpcm_play = + cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; + struct loopback_pcm *dpcm_capt = + cable->streams[SNDRV_PCM_STREAM_CAPTURE]; + struct snd_pcm_runtime *valid_runtime; + unsigned int running, elapsed_bytes; + unsigned long flags; + + spin_lock_irqsave(&cable->lock, flags); + running = cable->running ^ cable->pause; + /* no need to do anything if no stream is running */ + if (!running) { + spin_unlock_irqrestore(&cable->lock, flags); + return; + } + + if (event == SNDRV_TIMER_EVENT_MSTOP) { + if (!dpcm_play || !dpcm_play->substream || + !dpcm_play->substream->runtime || + !dpcm_play->substream->runtime->status || + dpcm_play->substream->runtime->status->state != + SNDRV_PCM_STATE_DRAINING) { + spin_unlock_irqrestore(&cable->lock, flags); + return; + } + } + + valid_runtime = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? + dpcm_play->substream->runtime : + dpcm_capt->substream->runtime; + + /* resolution is only valid for SNDRV_TIMER_EVENT_TICK events */ + if (event == SNDRV_TIMER_EVENT_TICK) { + /* The hardware rules guarantee that playback and capture period + * are the same. Therefore only one device has to be checked + * here. + */ + if (loopback_snd_timer_check_resolution(valid_runtime, + resolution) < 0) { + spin_unlock_irqrestore(&cable->lock, flags); + if (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) + snd_pcm_stop_xrun(dpcm_play->substream); + if (cable->running & (1 << SNDRV_PCM_STREAM_CAPTURE)) + snd_pcm_stop_xrun(dpcm_capt->substream); + return; + } + } + + elapsed_bytes = frames_to_bytes(valid_runtime, + valid_runtime->period_size); + /* The same timer interrupt is used for playback and capture device */ + if ((running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) && + (running & (1 << SNDRV_PCM_STREAM_CAPTURE))) { + copy_play_buf(dpcm_play, dpcm_capt, elapsed_bytes); + bytepos_finish(dpcm_play, elapsed_bytes); + bytepos_finish(dpcm_capt, elapsed_bytes); + } else if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) { + bytepos_finish(dpcm_play, elapsed_bytes); + } else if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) { + clear_capture_buf(dpcm_capt, elapsed_bytes); + bytepos_finish(dpcm_capt, elapsed_bytes); + } + spin_unlock_irqrestore(&cable->lock, flags); + + if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) + snd_pcm_period_elapsed(dpcm_play->substream); + if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) + snd_pcm_period_elapsed(dpcm_capt->substream); +} + +static void loopback_snd_timer_function(struct snd_timer_instance *timeri, + unsigned long resolution, + unsigned long ticks) +{ + struct loopback_cable *cable = timeri->callback_data; + + loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_TICK, + resolution); +} + +static void loopback_snd_timer_tasklet(unsigned long arg) +{ + struct snd_timer_instance *timeri = (struct snd_timer_instance *)arg; + struct loopback_cable *cable = timeri->callback_data; + + loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_MSTOP, 0); +} + +static void loopback_snd_timer_event(struct snd_timer_instance * const timeri, + const int event, + struct timespec * const tstamp, + const unsigned long resolution) +{ + /* Do not lock cable->lock here because timer->lock is already hold. + * There are other functions which first lock cable->lock and than + * timer->lock e.g. + * loopback_trigger() + * spin_lock(&cable->lock) + * loopback_snd_timer_start() + * snd_timer_start() + * spin_lock(&timer->lock) + * Therefore when using the oposit order of locks here it could result + * in a deadlock. + */ + + if (event == SNDRV_TIMER_EVENT_MSTOP) { + struct loopback_cable *cable = timeri->callback_data; + + /* sound card of the timer was stopped. Therefore there will not + * be any further timer callbacks. Due to this forward audio + * data from here if in draining state. When still in running + * state the streaming will be aborted by the usual timeout. It + * should not be aborted here because may be the timer sound + * card does only a recovery and the timer is back soon. + * This tasklet triggers loopback_snd_timer_tasklet() + */ + tasklet_schedule(&cable->snd_timer.event_tasklet); + } +} + static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm, struct snd_info_buffer *buffer) { @@ -588,6 +847,18 @@ static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm, snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); } +static void loopback_snd_timer_dpcm_info(struct loopback_pcm *dpcm, + struct snd_info_buffer *buffer) +{ + snd_iprintf(buffer, " sound timer:\thw:%d,%d,%d\n", + dpcm->cable->snd_timer.id.card, + dpcm->cable->snd_timer.id.device, + dpcm->cable->snd_timer.id.subdevice); + snd_iprintf(buffer, " owner:\t\t%s\n", + (dpcm->cable->snd_timer.owner == SNDRV_PCM_STREAM_CAPTURE) ? + "capture" : "playback"); +} + static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -707,6 +978,23 @@ static int rule_channels(struct snd_pcm_hw_params *params, return snd_interval_refine(hw_param_interval(params, rule->var), &t); } +static int rule_period_bytes(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct loopback_pcm *dpcm = rule->private; + struct loopback_cable *cable = dpcm->cable; + struct snd_interval t; + + mutex_lock(&dpcm->loopback->cable_lock); + t.min = cable->hw.period_bytes_min; + t.max = cable->hw.period_bytes_max; + mutex_unlock(&dpcm->loopback->cable_lock); + t.openmin = 0; + t.openmax = 0; + t.integer = 0; + return snd_interval_refine(hw_param_interval(params, rule->var), &t); +} + static void free_cable(struct snd_pcm_substream *substream) { struct loopback *loopback = substream->private_data; @@ -749,6 +1037,152 @@ static struct loopback_ops loopback_jiffies_timer_ops = { .dpcm_info = loopback_jiffies_timer_dpcm_info, }; +static int loopback_parse_timer_id(const char * const str, + struct snd_timer_id *tid) +{ + /* [:](|)[{.,}[{.,}]] */ + const char * const sep_dev = ".,"; + const char * const sep_pref = ":"; + const char *name = str; + char save, *sep; + int card = 0, device = 0, subdevice = 0; + int err; + + sep = strpbrk(str, sep_pref); + if (sep) + name = sep + 1; + sep = strpbrk(name, sep_dev); + if (sep) { + save = *sep; + *sep = '\0'; + } + err = kstrtoint(name, 0, &card); + if (err == -EINVAL) { + /* Must be the name, not number */ + for (card = 0; card < snd_ecards_limit; card++) { + if (snd_cards[card] && + !strcmp(snd_cards[card]->id, name)) { + err = 0; + break; + } + } + } + if (!err && sep) { + char save2, *sep2; + sep2 = strpbrk(sep + 1, sep_dev); + if (sep2) { + save2 = *sep2; + *sep2 = '\0'; + } + err = kstrtoint(sep + 1, 0, &device); + if (!err && sep2) { + err = kstrtoint(sep2 + 1, 0, &subdevice); + } + if (sep2) + *sep2 = save2; + } + if (!err && tid) { + tid->card = card; + tid->device = device; + tid->subdevice = subdevice; + } + if (sep) + *sep = save; + return err; +} + +/* call in loopback->cable_lock */ +static int loopback_snd_timer_open(struct loopback_pcm *dpcm) +{ + int err = 0; + unsigned long flags; + struct snd_timer_id tid = { + .dev_class = SNDRV_TIMER_CLASS_PCM, + .dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION, + }; + struct snd_timer_instance *timer = NULL; + + spin_lock_irqsave(&dpcm->cable->lock, flags); + + /* check if timer was already opened. It is only opened once + * per playback and capture subdevice (aka cable). + */ + if (dpcm->cable->snd_timer.instance) + goto unlock; + + err = loopback_parse_timer_id(dpcm->loopback->timer_source, &tid); + if (err < 0) { + pcm_err(dpcm->substream->pcm, + "Parsing timer source \'%s\' failed with %d", + dpcm->loopback->timer_source, err); + goto unlock; + } + + dpcm->cable->snd_timer.owner = dpcm->substream->stream; + dpcm->cable->snd_timer.id = tid; + + /* snd_timer_close() and snd_timer_open() should not be called with + * locked spinlock because both functions can block on a mutex. The + * mutex loopback->cable_lock is kept locked. Therefore snd_timer_open() + * cannot be called a second time by the other device of the same cable. + * Therefore the following issue cannot happen: + * [proc1] Call loopback_timer_open() -> + * Unlock cable->lock for snd_timer_close/open() call + * [proc2] Call loopback_timer_open() -> snd_timer_open(), + * snd_timer_start() + * [proc1] Call snd_timer_open() and overwrite running timer + * instance + */ + spin_unlock_irqrestore(&dpcm->cable->lock, flags); + err = snd_timer_open(&timer, dpcm->loopback->card->id, + &dpcm->cable->snd_timer.id, + current->pid); + if (err < 0) { + pcm_err(dpcm->substream->pcm, + "snd_timer_open (%d,%d,%d) failed with %d", + dpcm->cable->snd_timer.id.card, + dpcm->cable->snd_timer.id.device, + dpcm->cable->snd_timer.id.subdevice, + err); + return err; + } + spin_lock_irqsave(&dpcm->cable->lock, flags); + + /* The callback has to be called from another tasklet. If + * SNDRV_TIMER_IFLG_FAST is specified it will be called from the + * snd_pcm_period_elapsed() call of the selected sound card. + * snd_pcm_period_elapsed() helds snd_pcm_stream_lock_irqsave(). + * Due to our callback loopback_snd_timer_function() also calls + * snd_pcm_period_elapsed() which calls snd_pcm_stream_lock_irqsave(). + * This would end up in a dead lock. + */ + timer->flags |= SNDRV_TIMER_IFLG_AUTO; + timer->callback = loopback_snd_timer_function; + timer->callback_data = (void *)dpcm->cable; + timer->ccallback = loopback_snd_timer_event; + dpcm->cable->snd_timer.instance = timer; + + /* initialise a tasklet used for draining */ + tasklet_init(&dpcm->cable->snd_timer.event_tasklet, + loopback_snd_timer_tasklet, (unsigned long)timer); + +unlock: + spin_unlock_irqrestore(&dpcm->cable->lock, flags); + + return err; +} + +/* stop_sync() is not required for sound timer because it does not need to be + * restarted in loopback_prepare() on Xrun recovery + */ +static struct loopback_ops loopback_snd_timer_ops = { + .open = loopback_snd_timer_open, + .start = loopback_snd_timer_start, + .stop = loopback_snd_timer_stop, + .close_cable = loopback_snd_timer_close_cable, + .dpcm_info = loopback_snd_timer_dpcm_info, +}; + static int loopback_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -776,7 +1210,10 @@ static int loopback_open(struct snd_pcm_substream *substream) } spin_lock_init(&cable->lock); cable->hw = loopback_pcm_hardware; - cable->ops = &loopback_jiffies_timer_ops; + if (loopback->timer_source) + cable->ops = &loopback_snd_timer_ops; + else + cable->ops = &loopback_jiffies_timer_ops; loopback->cables[substream->number][dev] = cable; } dpcm->cable = cable; @@ -812,6 +1249,19 @@ static int loopback_open(struct snd_pcm_substream *substream) if (err < 0) goto unlock; + /* In case of sound timer the period time of both devices of the same + * loop has to be the same. + * This rule only takes effect if a sound timer was chosen + */ + if (cable->snd_timer.instance) { + err = snd_pcm_hw_rule_add(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + rule_period_bytes, dpcm, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); + if (err < 0) + goto unlock; + } + /* loopback_runtime_free() has not to be called if kfree(dpcm) was * already called here. Otherwise it will end up with a double free. */ @@ -1214,6 +1664,18 @@ static int loopback_proc_new(struct loopback *loopback, int cidx) print_cable_info); } +static void loopback_set_timer_source(struct loopback *loopback, + const char *value) +{ + if (loopback->timer_source) { + devm_kfree(loopback->card->dev, loopback->timer_source); + loopback->timer_source = NULL; + } + if (value && *value) + loopback->timer_source = devm_kstrdup(loopback->card->dev, + value, GFP_KERNEL); +} + static int loopback_probe(struct platform_device *devptr) { struct snd_card *card; @@ -1233,6 +1695,8 @@ static int loopback_probe(struct platform_device *devptr) pcm_substreams[dev] = MAX_PCM_SUBSTREAMS; loopback->card = card; + loopback_set_timer_source(loopback, timer_source[dev]); + mutex_init(&loopback->cable_lock); err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]); From patchwork Tue Nov 5 14:32:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabbasov, Andrew" X-Patchwork-Id: 11227987 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D380314E5 for ; Tue, 5 Nov 2019 14:40:06 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 660B221929 for ; Tue, 5 Nov 2019 14:40:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="GnbOw+Mc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 660B221929 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mentor.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8FE7616EE; Tue, 5 Nov 2019 15:39:14 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8FE7616EE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1572964804; bh=GwzsQ761T6Uu8BMO08ClBR+zQa68nDV4LEwpQPoI7ek=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=GnbOw+McbCex8axMA42o3wEq33stsMTHP4D6fCaHGbikLQHs6F9YN25IZfylxlGRb lnadU1iefKXM/UCdmRiaFVKeW02EgvQqNqmzO/rx2dy88BUW9+Qus/ndj/HYAwU2qj rySUto09C8m9ib0ViSmzGqWo0du94KO/4wadS5sQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7EE50F80671; Tue, 5 Nov 2019 15:34:51 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8A3D1F8065E; Tue, 5 Nov 2019 15:34:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_NONE,SPF_PASS, SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BDFEAF80446 for ; Tue, 5 Nov 2019 15:34:44 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BDFEAF80446 IronPort-SDR: BWshZGUL+WC6s3yxPF+rC3AjcjPhIHL6e+nCDAZ2NJEBlVC7UfvEvuBb+h6ysTgqH9fR9PoTWV R86ngn+MVequ62PimCLBm+EZwJ4zIKMmatKjdewmpmhMfphZOhvCzpm6r3rhwmxdtbIpopL+Zl VIxZvV5sBy9/y3rregBRYleHrwYsA1edR048GRCOa60lRJ7M44KXXtr5PTB/KYNoIfufW1OvI7 qfZ3PgU9wFtVe8tmcHteiF3yPHOSPhcYnGDq/6U9YvNGF7zhkSQ8BC637Po58op8sN85ZDf6LO tH8= X-IronPort-AV: E=Sophos;i="5.68,271,1569312000"; d="scan'208";a="44730656" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 05 Nov 2019 06:34:43 -0800 IronPort-SDR: tcZgpC/pYlyvFflaFhrt2xaVVmdwpIyGNC28cR40IEDaNgeZcNKj4qd+wXAHt/PY/xppI+5Nxw vqatF4DztGGuX0IlfQuPrMLozaOGpLfHAl72b2dV9Wv0nRNpV1eae8fhSg3ttgj5laxMSA8Ljl FLQAmHh+iKpVa/95j2Wlqr1jSjSaFcM0awnw+T25ylv2R0lpKZJ5S+b392vB2PL4qhYgSudsQM w3iZulI7vbYcoiFr1KgyiE2RvW1ePzfqJoqtEdOXUvuSJQ9b5E+ddh/+ltbWYqS63Jgd2+opnU DGc= From: Andrew Gabbasov To: , , Jaroslav Kysela , Takashi Iwai , Timo Wischer , Andrew Gabbasov Date: Tue, 5 Nov 2019 08:32:18 -0600 Message-ID: <20191105143218.5948-9-andrew_gabbasov@mentor.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105143218.5948-8-andrew_gabbasov@mentor.com> References: <20191105143218.5948-1-andrew_gabbasov@mentor.com> <20191105143218.5948-2-andrew_gabbasov@mentor.com> <20191105143218.5948-3-andrew_gabbasov@mentor.com> <20191105143218.5948-4-andrew_gabbasov@mentor.com> <20191105143218.5948-5-andrew_gabbasov@mentor.com> <20191105143218.5948-6-andrew_gabbasov@mentor.com> <20191105143218.5948-7-andrew_gabbasov@mentor.com> <20191105143218.5948-8-andrew_gabbasov@mentor.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-07.mgc.mentorg.com (139.181.222.7) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Subject: [alsa-devel] [PATCH v2 8/8] ALSA: aloop: Support runtime change of snd_timer via info interface X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" Show and change sound card timer source with read-write info file in proc filesystem. Initial string can still be set as module parameter. The timer source string value can be changed at any time, but it is latched by PCM substream open callback (the first one for a particular cable). At this point it is actually used, that is the string is parsed, and the timer is looked up and opened. The timer source is set for a loopback card (the same as initial setting by module parameter), but every cable uses the value, current at the moment of open. Setting the value to empty string switches the timer to jiffies. Signed-off-by: Andrew Gabbasov --- sound/drivers/aloop.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 6db70ebd46f6..16444a34d4b9 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -1655,7 +1655,7 @@ static void print_cable_info(struct snd_info_entry *entry, mutex_unlock(&loopback->cable_lock); } -static int loopback_proc_new(struct loopback *loopback, int cidx) +static int loopback_cable_proc_new(struct loopback *loopback, int cidx) { char name[32]; @@ -1676,6 +1676,40 @@ static void loopback_set_timer_source(struct loopback *loopback, value, GFP_KERNEL); } +static void print_timer_source_info(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct loopback *loopback = entry->private_data; + + snd_iprintf(buffer, "%s\n", + loopback->timer_source ? loopback->timer_source : ""); +} + +static void change_timer_source_info(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct loopback *loopback = entry->private_data; + char line[64]; + + if (!snd_info_get_line(buffer, line, sizeof(line))) + loopback_set_timer_source(loopback, strim(line)); +} + +static int loopback_timer_source_proc_new(struct loopback *loopback) +{ + struct snd_info_entry *entry; + int err; + + err = snd_card_proc_new(loopback->card, "timer_source", &entry); + if (err < 0) + return err; + + snd_info_set_text_ops(entry, loopback, print_timer_source_info); + entry->mode |= S_IWUSR; + entry->c.text.write = change_timer_source_info; + return 0; +} + static int loopback_probe(struct platform_device *devptr) { struct snd_card *card; @@ -1708,8 +1742,9 @@ static int loopback_probe(struct platform_device *devptr) err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0); if (err < 0) goto __nodev; - loopback_proc_new(loopback, 0); - loopback_proc_new(loopback, 1); + loopback_cable_proc_new(loopback, 0); + loopback_cable_proc_new(loopback, 1); + loopback_timer_source_proc_new(loopback); strcpy(card->driver, "Loopback"); strcpy(card->shortname, "Loopback"); sprintf(card->longname, "Loopback %i", dev + 1);