summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorWilliam Wu <william.wu@rock-chips.com>2018-11-27 15:25:02 +0800
committerTao Huang <huangtao@rock-chips.com>2018-12-06 16:36:47 +0800
commit3099e13bdb21f68d673cf20ad25c0be1ce4578b2 (patch)
treed164abac7741e009334143d4db396ae91f92d6ab /drivers/usb/gadget
parentf025f3ea8387a2337bce413df515b21b3d278f17 (diff)
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>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/function/f_uvc.c3
-rw-r--r--drivers/usb/gadget/udc/core.c8
2 files changed, 8 insertions, 3 deletions
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index 523fbbc7b6f9..b1c755069451 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -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);
}
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index b7a3db148f64..d4ce9ca37f1d 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -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);