Skip to content

Commit a0a4959

Browse files
Jorge Sanjuantiwai
authored andcommitted
ALSA: usb-audio: Operate UAC3 Power Domains in PCM callbacks
Make use of UAC3 Power Domains associated to an Audio Streaming path within the PCM's logic. This means, when there is no audio being transferred (pcm is closed), the host will set the Power Domain associated to that substream to state D1. When audio is being transferred (from hw_params onwards), the Power Domain will be set to D0 state. This is the way the host lets the device know which Terminal is going to be actively used and it is for the device to manage its own internal resources on that UAC3 Power Domain. Note the resume method now sets the Power Domain to D1 state as resuming the device doesn't mean audio streaming will occur. Signed-off-by: Jorge Sanjuan <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
1 parent 3f59aa1 commit a0a4959

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

sound/usb/pcm.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -748,11 +748,11 @@ int snd_usb_pcm_resume(struct snd_usb_stream *as)
748748
{
749749
int ret;
750750

751-
ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D0);
751+
ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D1);
752752
if (ret < 0)
753753
return ret;
754754

755-
ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D0);
755+
ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D1);
756756
if (ret < 0)
757757
return ret;
758758

@@ -803,16 +803,22 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
803803
ret = snd_usb_lock_shutdown(subs->stream->chip);
804804
if (ret < 0)
805805
return ret;
806+
807+
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
808+
if (ret < 0)
809+
goto unlock;
810+
806811
ret = set_format(subs, fmt);
807-
snd_usb_unlock_shutdown(subs->stream->chip);
808812
if (ret < 0)
809-
return ret;
813+
goto unlock;
810814

811815
subs->interface = fmt->iface;
812816
subs->altset_idx = fmt->altset_idx;
813817
subs->need_setup_ep = true;
814818

815-
return 0;
819+
unlock:
820+
snd_usb_unlock_shutdown(subs->stream->chip);
821+
return ret;
816822
}
817823

818824
/*
@@ -869,6 +875,10 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
869875
snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
870876
snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
871877

878+
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
879+
if (ret < 0)
880+
goto unlock;
881+
872882
ret = set_format(subs, subs->cur_audiofmt);
873883
if (ret < 0)
874884
goto unlock;
@@ -1313,6 +1323,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream)
13131323
int direction = substream->stream;
13141324
struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
13151325
struct snd_usb_substream *subs = &as->substream[direction];
1326+
int ret;
13161327

13171328
stop_endpoints(subs, true);
13181329

@@ -1321,7 +1332,10 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream)
13211332
!snd_usb_lock_shutdown(subs->stream->chip)) {
13221333
usb_set_interface(subs->dev, subs->interface, 0);
13231334
subs->interface = -1;
1335+
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D1);
13241336
snd_usb_unlock_shutdown(subs->stream->chip);
1337+
if (ret < 0)
1338+
return ret;
13251339
}
13261340

13271341
subs->pcm_substream = NULL;

sound/usb/stream.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,12 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
110110
if (fp->channels > subs->channels_max)
111111
subs->channels_max = fp->channels;
112112

113-
if (pd)
113+
if (pd) {
114114
subs->str_pd = pd;
115+
/* Initialize Power Domain to idle status D1 */
116+
snd_usb_power_domain_set(subs->stream->chip, pd,
117+
UAC3_PD_STATE_D1);
118+
}
115119

116120
snd_usb_preallocate_buffer(subs);
117121
}

0 commit comments

Comments
 (0)