usb: gadget: f_uvc: add suspend and resume function

This patch adds uvc_function_suspend and uvc_function_resume
for uvc function. With this patch, if usb bus enter suspend
or resume state, the usb controller driver will call the
uvc_function_suspend or uvc_function_resume to send event
to uvc app.

Change-Id: I9c584aae25298747c5a287243cb3efd71c8adfe6
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2021-03-17 18:37:18 +08:00
committed by Tao Huang
parent f8b5452aae
commit 241a5e5577
3 changed files with 38 additions and 1 deletions

View File

@@ -396,6 +396,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
usb_ep_enable(uvc->control_ep);
if (uvc->event_suspend) {
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_RESUME;
v4l2_event_queue(&uvc->vdev, &v4l2_event);
uvc->event_suspend = 0;
uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_RESUME\n");
}
if (uvc->state == UVC_STATE_DISCONNECTED) {
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_CONNECT;
@@ -516,6 +524,30 @@ uvc_function_disable(struct usb_function *f)
usb_ep_disable(uvc->control_ep);
}
static void uvc_function_suspend(struct usb_function *f)
{
struct uvc_device *uvc = to_uvc(f);
struct v4l2_event v4l2_event;
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_SUSPEND;
v4l2_event_queue(&uvc->vdev, &v4l2_event);
uvc->event_suspend = 1;
uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_SUSPEND\n");
}
static void uvc_function_resume(struct usb_function *f)
{
struct uvc_device *uvc = to_uvc(f);
struct v4l2_event v4l2_event;
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_RESUME;
v4l2_event_queue(&uvc->vdev, &v4l2_event);
uvc->event_suspend = 0;
uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_RESUME\n");
}
/* --------------------------------------------------------------------------
* Connection / disconnection
*/
@@ -1208,6 +1240,8 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
uvc->func.disable = uvc_function_disable;
uvc->func.setup = uvc_function_setup;
uvc->func.free_func = uvc_free;
uvc->func.suspend = uvc_function_suspend;
uvc->func.resume = uvc_function_resume;
uvc->func.bind_deactivated = true;
return &uvc->func;

View File

@@ -134,6 +134,7 @@ struct uvc_device {
/* Events */
unsigned int event_length;
unsigned int event_setup_out : 1;
unsigned int event_suspend : 1;
};
static inline struct uvc_device *to_uvc(struct usb_function *f)

View File

@@ -19,7 +19,9 @@
#define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3)
#define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4)
#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5)
#define UVC_EVENT_SUSPEND (V4L2_EVENT_PRIVATE_START + 6)
#define UVC_EVENT_RESUME (V4L2_EVENT_PRIVATE_START + 7)
#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 7)
struct uvc_request_data {
__s32 length;