From patchwork Thu Aug 18 22:20:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrej Krutak X-Patchwork-Id: 9288667 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 78172600CB for ; Thu, 18 Aug 2016 22:23:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 657B9291D5 for ; Thu, 18 Aug 2016 22:23:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59D76291E1; Thu, 18 Aug 2016 22:23:32 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=no 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 4EC2A291D5 for ; Thu, 18 Aug 2016 22:23:31 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 453C0266B22; Fri, 19 Aug 2016 00:23:30 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 01109266B22; Fri, 19 Aug 2016 00:22:19 +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 A9A99266B20; Fri, 19 Aug 2016 00:22:17 +0200 (CEST) Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by alsa0.perex.cz (Postfix) with ESMTP id 045D62664BB for ; Fri, 19 Aug 2016 00:21:41 +0200 (CEST) Received: by mail-wm0-f67.google.com with SMTP id i138so1270702wmf.3 for ; Thu, 18 Aug 2016 15:21:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=/tx4yVM2XbjGWlxJuTfiDbyGOaC3/LKtEqbCuiCykFU=; b=e2lB2lejBFg6a60I3H0vvw+oSzuBbALMqNmyKacsX7ylrPO5/lijChIaB0/08FgPm0 aA6qCJU+dVlHXNlhckiwzGopGFGApzDb8XhFeuPKm2lxugVfCHbce86D8G67a3R0ukhJ MSji6nI7765keZpCzsefBAIkDdzPQ6ENrRa2+gZHSLorawpt2/nW+Nr7hdoHqS6a7pde aFBJutpefSgq9JP0451piOlNsjlThfE6BuN+XGVV/Mus2o/ZUIBhPD7a7piuLYdiOjaR 66+qYbVCn72vsB38m1/M6LS436K3LzMSvd7Kfz5F4wFX9bXuwxCtYMhVhepVjc/QBtV9 mG1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=/tx4yVM2XbjGWlxJuTfiDbyGOaC3/LKtEqbCuiCykFU=; b=FeFG7T1MyqH+ryvTp7whVf5gS9UwUqJ1H2YNcv/vLgg1Q2cbk0CH/G8L5SyojZEjz8 VHHavofDSi3HOI/WmQHFVXY7MQF4iVxrFKZooDV75a1I62MDsYM4J54a8MiXAU3ZjVwR IihiFcqLYdoDimkglC9UDMhLbWBeEUZK+1JNDlzWPG7MyWtvCjjNyZVF8UpxX1aa/AdU RVf3v1d7e0Mitf3P1yfthtKpms9jPjM4SH9X2ewGz9kBv1jhJZs2sW7bXdtHsnwCTPDt 9fgs8XEy1+3i31yFGP36f8FWciyWbJt6vPPU6KtwGbwwDe3Ao9MWkhzbhTNUftxCf08H APRg== X-Gm-Message-State: AEkoouveseq9whUhWUn9rJNYkKtgRSfM6CB+VENV5FYkW0tQsRlRefM0vyRARav+9Olq0A== X-Received: by 10.28.168.150 with SMTP id r144mr1229437wme.66.1471558900661; Thu, 18 Aug 2016 15:21:40 -0700 (PDT) Received: from andree.lan ([217.30.74.231]) by smtp.gmail.com with ESMTPSA id jv9sm4122380wjb.45.2016.08.18.15.21.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Aug 2016 15:21:39 -0700 (PDT) From: Andrej Krutak To: tiwai@suse.com, perex@perex.cz, stefanha@gmail.com, grabner@icg.tugraz.at, alsa-devel@alsa-project.org Date: Fri, 19 Aug 2016 00:20:32 +0200 Message-Id: <1471558839-14120-3-git-send-email-dev@andree.sk> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1471558839-14120-1-git-send-email-dev@andree.sk> References: <1470942147-19848-1-git-send-email-dev@andree.sk> <1471558839-14120-1-git-send-email-dev@andree.sk> Cc: Andrej Krutak Subject: [alsa-devel] [PATCH v2 2/9] ALSA: line6: Add LINE6_CAP_IN_NEEDS_OUT, a void playback stream during capture 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 E.g. POD X3 seems to require playback data to be sent to it to generate capture data. Otherwise the device stalls and doesn't send any more capture data until it's reset. Signed-off-by: Andrej Krutak --- sound/usb/line6/capture.c | 5 +++++ sound/usb/line6/driver.h | 4 +++- sound/usb/line6/pcm.c | 37 ++++++++++++++++++++++++++++--------- sound/usb/line6/pcm.h | 4 +++- sound/usb/line6/toneport.c | 4 ++-- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 91d1562..37c9e94 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -232,6 +232,8 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream) if (err < 0) return err; + line6_pcm_acquire(line6pcm, LINE6_STREAM_CAPTURE_HELPER, false); + runtime->hw = line6pcm->properties->capture_hw; return 0; } @@ -239,6 +241,9 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream) /* close capture callback */ static int snd_line6_capture_close(struct snd_pcm_substream *substream) { + struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); + + line6_pcm_release(line6pcm, LINE6_STREAM_CAPTURE_HELPER); return 0; } diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 2d32139..69658dc 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -100,8 +100,10 @@ enum { LINE6_CAP_CONTROL = 1 << 0, /* device supports PCM input/output via USB */ LINE6_CAP_PCM = 1 << 1, - /* device support hardware monitoring */ + /* device supports hardware monitoring */ LINE6_CAP_HWMON = 1 << 2, + /* device requires output data when input is read */ + LINE6_CAP_IN_NEEDS_OUT = 1 << 4, }; /* diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index e1913d3..18424a2 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -52,7 +52,7 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol, line6pcm->impulse_volume = value; if (value > 0) { - err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE); + err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE, true); if (err < 0) { line6pcm->impulse_volume = 0; return err; @@ -242,6 +242,15 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: + if ((s->stream == SNDRV_PCM_STREAM_CAPTURE) && + (line6pcm->line6->properties->capabilities & + LINE6_CAP_IN_NEEDS_OUT) + ) { + err = line6_stream_start(line6pcm, SNDRV_PCM_STREAM_PLAYBACK, + LINE6_STREAM_CAPTURE_HELPER); + if (err < 0) + return err; + } err = line6_stream_start(line6pcm, s->stream, LINE6_STREAM_PCM); if (err < 0) @@ -250,6 +259,13 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: + if ((s->stream == SNDRV_PCM_STREAM_CAPTURE) && + (line6pcm->line6->properties->capabilities & + LINE6_CAP_IN_NEEDS_OUT) + ) { + line6_stream_stop(line6pcm, SNDRV_PCM_STREAM_PLAYBACK, + LINE6_STREAM_CAPTURE_HELPER); + } line6_stream_stop(line6pcm, s->stream, LINE6_STREAM_PCM); break; @@ -283,27 +299,30 @@ snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream) return pstr->pos_done; } -/* Acquire and start duplex streams: +/* Acquire and optionally start duplex streams: * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR */ -int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type) +int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, bool start) { struct line6_pcm_stream *pstr; int ret = 0, dir; + /* TODO: We should assert SNDRV_PCM_STREAM_PLAYBACK/CAPTURE == 0/1 */ mutex_lock(&line6pcm->state_mutex); for (dir = 0; dir < 2; dir++) { pstr = get_stream(line6pcm, dir); - ret = line6_buffer_acquire(line6pcm, pstr, type); + ret = line6_buffer_acquire(line6pcm, pstr, dir, type); if (ret < 0) goto error; if (!pstr->running) line6_wait_clear_audio_urbs(line6pcm, pstr); } - for (dir = 0; dir < 2; dir++) { - ret = line6_stream_start(line6pcm, dir, type); - if (ret < 0) - goto error; + if (start) { + for (dir = 0; dir < 2; dir++) { + ret = line6_stream_start(line6pcm, dir, type); + if (ret < 0) + goto error; + } } error: mutex_unlock(&line6pcm->state_mutex); @@ -339,7 +358,7 @@ int snd_line6_hw_params(struct snd_pcm_substream *substream, struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream); mutex_lock(&line6pcm->state_mutex); - ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM); + ret = line6_buffer_acquire(line6pcm, pstr, substream->stream, LINE6_STREAM_PCM); if (ret < 0) goto error; diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 58d36f9..5f796ef8 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h @@ -72,6 +72,7 @@ enum { LINE6_STREAM_PCM, LINE6_STREAM_MONITOR, LINE6_STREAM_IMPULSE, + LINE6_STREAM_CAPTURE_HELPER, }; /* misc bit flags for PCM operation */ @@ -190,7 +191,8 @@ extern int snd_line6_hw_params(struct snd_pcm_substream *substream, extern int snd_line6_hw_free(struct snd_pcm_substream *substream); extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream); extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); -extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type); +extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, + bool start); extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type); #endif diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index da76e03..8e22f43 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -177,7 +177,7 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol, line6pcm->volume_monitor = ucontrol->value.integer.value[0]; if (line6pcm->volume_monitor > 0) { - err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR); + err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR, true); if (err < 0) { line6pcm->volume_monitor = 0; line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR); @@ -246,7 +246,7 @@ static void toneport_start_pcm(unsigned long arg) struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; struct usb_line6 *line6 = &toneport->line6; - line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR); + line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR, true); } /* control definition */