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;
}
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;
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
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
*
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,