Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp5093329imm; Tue, 31 Jul 2018 05:30:33 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcARh//Hr8J8U8TLXDXME1jO7XDJzs55lKzK5k7zWzbptYodKqwCoOeWOMtX7UVzcuZynuJ X-Received: by 2002:a62:cd3:: with SMTP id 80-v6mr22290123pfm.184.1533040232994; Tue, 31 Jul 2018 05:30:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533040232; cv=none; d=google.com; s=arc-20160816; b=X8pBxNzeqgvjrgmwuOWaL8kT30oVeyw5rLwSlKblp77eajGnzUhl8mXuLi8YIUq7eb BdzJPoE9hU9Ac3odOAoR+ElZ3+TKeg5MmEXmTm1j80Ru3fKBcgFxFBxJPHLbz4sAG3AB CzDdyUzt3JolecrwGbKSoDNDNGUnmGvXz89ZDBIR13u5IlZwmt9TIVE+VVQv6LKiVmkB AF/rkwkw0XR06DnJtehLXHptKN//9A3ZmN8WqiYK+V3ez01mBQI9EOm99DvW23vTuCpJ df3ag0Fc+KilMJJzLgZeDcyhMIYDFNv+qM9E1O9nlQpp/pUN1qgFNGpcP8Bqcuzr3DLK +4sg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=4f2va1oofRnlUJhTu+9xUT29UCA9YOXxCOu9+TZSgKU=; b=pZl9l5oQw7rxa6Z272mX7tAzDQL3dwnTq3KTlYDbKWzEbRMh3iF5D2GF12TMoEej5K KjvitUumNbVUMZzS2vSPB+XBYE6rdw0Q+6H0uq2NDVRDjFVo6+mEmPeFxckMCv7Fj6Tp fbC2ihY2A1MdtCKMuP/KcLv3pnNsSrHG2PHTNjKMAfAFCIdWzn8DBoBD+GN1FUfiw31p 9jzwnqBKFpNrjbDX3Py6ihwmvPPAG7RnP6Zq8kuTi2W+kA99PYqj4Vr36oLFwdMyQojn gEAPTLrION4gY4lYKikVY8r3v7aTykkSrHWzA7mL+s3iS6/Hh2dmu7ugntzBLkehMqnu pcbA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codethink.co.uk Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o25-v6si14348103pfi.279.2018.07.31.05.30.18; Tue, 31 Jul 2018 05:30:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codethink.co.uk Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732181AbeGaOI7 (ORCPT + 99 others); Tue, 31 Jul 2018 10:08:59 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:34910 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732109AbeGaOI7 (ORCPT ); Tue, 31 Jul 2018 10:08:59 -0400 Received: from [148.252.241.226] (helo=ct-lt-1121.office.codethink.co.uk) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1fkTlh-0000tp-Rx; Tue, 31 Jul 2018 13:28:50 +0100 From: Jorge Sanjuan To: tiwai@suse.de Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/4] ALSA: usb-audio: Add UAC3 Power Domains to suspend/resume Date: Tue, 31 Jul 2018 13:28:44 +0100 Message-Id: <20180731122845.4859-4-jorge.sanjuan@codethink.co.uk> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180731122845.4859-1-jorge.sanjuan@codethink.co.uk> References: <20180719112215.4219-1-jorge.sanjuan@codethink.co.uk> <20180731122845.4859-1-jorge.sanjuan@codethink.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Set the UAC3 Power Domain state for an Audio Streaming interface to D2 state before suspending the device (usb_driver callback). This lets the device know there is no intention to use any of the Units in the Audio Function and that the host is not going to even listen for wake-up events (interrupts) on the units. When the usb_driver gets resumed, the state D0 (fully powered) will be set. This ties up the UAC3 Power Domains to the runtime PM. Signed-off-by: Jorge Sanjuan --- sound/usb/card.c | 9 +++++++++ sound/usb/pcm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ sound/usb/pcm.h | 2 ++ 3 files changed, 59 insertions(+) diff --git a/sound/usb/card.c b/sound/usb/card.c index a1ed798a1c6b..2bfe4e80a6b9 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -809,6 +809,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) if (!chip->num_suspended_intf++) { list_for_each_entry(as, &chip->pcm_list, list) { snd_pcm_suspend_all(as->pcm); + snd_usb_pcm_suspend(as); as->substream[0].need_setup_ep = as->substream[1].need_setup_ep = true; } @@ -824,6 +825,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) { struct snd_usb_audio *chip = usb_get_intfdata(intf); + struct snd_usb_stream *as; struct usb_mixer_interface *mixer; struct list_head *p; int err = 0; @@ -834,6 +836,13 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) return 0; atomic_inc(&chip->active); /* avoid autopm */ + + list_for_each_entry(as, &chip->pcm_list, list) { + err = snd_usb_pcm_resume(as); + if (err < 0) + goto err_out; + } + /* * ALSA leaves material resumption to user space * we just notify and restart the mixers diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 4b930fa47277..99ec9d5caa58 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -711,6 +711,54 @@ static int configure_endpoint(struct snd_usb_substream *subs) return ret; } +static int snd_usb_pcm_change_state(struct snd_usb_substream *subs, int state) +{ + int ret; + + if (!subs->str_pd) + return 0; + + ret = snd_usb_power_domain_set(subs->stream->chip, subs->str_pd, state); + if (ret < 0) { + dev_err(&subs->dev->dev, + "Cannot change Power Domain ID: %d to state: %d. Err: %d\n", + subs->str_pd->pd_id, state, ret); + return ret; + } + + return 0; +} + +int snd_usb_pcm_suspend(struct snd_usb_stream *as) +{ + int ret; + + ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D2); + if (ret < 0) + return ret; + + ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D2); + if (ret < 0) + return ret; + + return 0; +} + +int snd_usb_pcm_resume(struct snd_usb_stream *as) +{ + int ret; + + ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D0); + if (ret < 0) + return ret; + + ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D0); + if (ret < 0) + return ret; + + return 0; +} + /* * hw_params callback * diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h index f77ec58bf1a1..9833627c1eca 100644 --- a/sound/usb/pcm.h +++ b/sound/usb/pcm.h @@ -6,6 +6,8 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, unsigned int rate); void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); +int snd_usb_pcm_suspend(struct snd_usb_stream *as); +int snd_usb_pcm_resume(struct snd_usb_stream *as); int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, struct usb_host_interface *alts, -- 2.11.0