mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
usb: gadget: f_uvc: support uvc and adb use independently
If we use usb gadget as uvc and adb composite function, the adb will be disconnected if the uvc camera apk is closed. I can reproduce this issue by the following steps on rk3399/rk3288 platforms. 1. Set usb gadget as uvc and adb composite function, and open uvc camera apk on rk3399/rk3288 platforms. 2. Connect usb to PC, and use adb shell; 3. Close the uvc camera apk; And then, the adb will also be disconnected. It's because that when close the uvc camera apk, the userspace calls v4l2_release -> uvc_v4l2_release -> uvc_function_disconnect -> usb_gadget_deactivate -> usb_gadget_disconnect -> pullup(gadget, 0), this cause usb controller disconnect the usb connection. This patch adds a uvc_enabled flag to indicate that usb is connected, don't call pullup(gadget, 0) to disconnet usb if we only close uvc camera apk but not plug out usb cable. Change-Id: I0cc5ce8a24e8e06e0dc9215dfd1b92ef702e4311 Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
@@ -381,6 +381,7 @@ uvc_function_disable(struct usb_function *f)
|
||||
v4l2_event_queue(&uvc->vdev, &v4l2_event);
|
||||
|
||||
uvc->state = UVC_STATE_DISCONNECTED;
|
||||
f->config->cdev->gadget->uvc_enabled = false;
|
||||
|
||||
usb_ep_disable(uvc->video.ep);
|
||||
usb_ep_disable(uvc->control_ep);
|
||||
@@ -396,6 +397,8 @@ uvc_function_connect(struct uvc_device *uvc)
|
||||
struct usb_composite_dev *cdev = uvc->func.config->cdev;
|
||||
int ret;
|
||||
|
||||
cdev->gadget->uvc_enabled = true;
|
||||
|
||||
if ((ret = usb_function_activate(&uvc->func)) < 0)
|
||||
INFO(cdev, "UVC connect failed with %d\n", ret);
|
||||
}
|
||||
|
||||
@@ -682,9 +682,11 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = gadget->ops->pullup(gadget, 0);
|
||||
if (!ret)
|
||||
gadget->connected = 0;
|
||||
if (!gadget->uvc_enabled) {
|
||||
ret = gadget->ops->pullup(gadget, 0);
|
||||
if (!ret)
|
||||
gadget->connected = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
trace_usb_gadget_disconnect(gadget, ret);
|
||||
|
||||
@@ -347,6 +347,7 @@ struct usb_gadget_ops {
|
||||
* @deactivated: True if gadget is deactivated - in deactivated state it cannot
|
||||
* be connected.
|
||||
* @connected: True if gadget is connected.
|
||||
* @uvc_enabled: True if uvc function is enabled.
|
||||
*
|
||||
* Gadgets have a mostly-portable "gadget driver" implementing device
|
||||
* functions, handling all usb configurations and interfaces. Gadget
|
||||
@@ -396,6 +397,7 @@ struct usb_gadget {
|
||||
unsigned is_selfpowered:1;
|
||||
unsigned deactivated:1;
|
||||
unsigned connected:1;
|
||||
unsigned uvc_enabled:1;
|
||||
};
|
||||
#define work_to_gadget(w) (container_of((w), struct usb_gadget, work))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user