@@ -1436,6 +1436,14 @@ afunc_disable(struct usb_function *fn)
usb_ep_disable(uac2->int_ep);
}
+static void
+afunc_suspend(struct usb_function *fn)
+{
+ struct f_uac2 *uac2 = func_to_uac2(fn);
+
+ u_audio_suspend(&uac2->g_audio);
+}
+
static int
in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
{
@@ -2107,6 +2115,7 @@ static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
uac2->g_audio.func.set_alt = afunc_set_alt;
uac2->g_audio.func.get_alt = afunc_get_alt;
uac2->g_audio.func.disable = afunc_disable;
+ uac2->g_audio.func.suspend = afunc_suspend;
uac2->g_audio.func.setup = afunc_setup;
uac2->g_audio.func.free_func = afunc_free;
When USB cable gets disconnected, the undergoing playback/capture stalls, without any notification to u_audio about the change. Experiments with a dwc2 gadget revealed that Suspend interrupt is thrown at cable disconnection, which the gadget framework translates to calling suspend callback of a function, if it is defined. Add the suspend callback to f_uac2 function, calling corresponding method of u_audio in order to stop the respective PCM streams and to notify subscribed clients at cable disconnection. Signed-off-by: Pavel Hofman <pavel.hofman@ivitera.com> --- v3: fixed commit title and msg --- drivers/usb/gadget/function/f_uac2.c | 9 +++++++++ 1 file changed, 9 insertions(+)