xref: /OK3568_Linux_fs/kernel/drivers/usb/gadget/function/uvc_video.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *	uvc_video.c  --  USB Video Class Gadget driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *	Copyright (C) 2009-2010
6*4882a593Smuzhiyun  *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <linux/usb/ch9.h>
13*4882a593Smuzhiyun #include <linux/usb/gadget.h>
14*4882a593Smuzhiyun #include <linux/usb/video.h>
15*4882a593Smuzhiyun #include <linux/pm_qos.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <media/v4l2-dev.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include "uvc.h"
20*4882a593Smuzhiyun #include "uvc_queue.h"
21*4882a593Smuzhiyun #include "uvc_video.h"
22*4882a593Smuzhiyun #include "u_uvc.h"
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
uvc_using_zero_copy(struct uvc_video * video)25*4882a593Smuzhiyun static bool uvc_using_zero_copy(struct uvc_video *video)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	struct uvc_device *uvc = container_of(video, struct uvc_device, video);
28*4882a593Smuzhiyun 	struct f_uvc_opts *opts = fi_to_f_uvc_opts(uvc->func.fi);
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	if (opts && opts->uvc_zero_copy && video->fcc != V4L2_PIX_FMT_YUYV)
31*4882a593Smuzhiyun 		return true;
32*4882a593Smuzhiyun 	else
33*4882a593Smuzhiyun 		return false;
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
uvc_wait_req_complete(struct uvc_video * video,struct uvc_request * ureq)36*4882a593Smuzhiyun static void uvc_wait_req_complete(struct uvc_video *video, struct uvc_request *ureq)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	unsigned long flags;
39*4882a593Smuzhiyun 	struct usb_request *req;
40*4882a593Smuzhiyun 	int ret;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	spin_lock_irqsave(&video->req_lock, flags);
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	list_for_each_entry(req, &video->req_free, list) {
45*4882a593Smuzhiyun 		if (req == ureq->req)
46*4882a593Smuzhiyun 			break;
47*4882a593Smuzhiyun 	}
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if (req != ureq->req) {
50*4882a593Smuzhiyun 		reinit_completion(&ureq->req_done);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 		spin_unlock_irqrestore(&video->req_lock, flags);
53*4882a593Smuzhiyun 		ret = wait_for_completion_timeout(&ureq->req_done,
54*4882a593Smuzhiyun 						  msecs_to_jiffies(500));
55*4882a593Smuzhiyun 		if (ret == 0)
56*4882a593Smuzhiyun 			uvcg_warn(&video->uvc->func,
57*4882a593Smuzhiyun 				  "timed out waiting for req done\n");
58*4882a593Smuzhiyun 		return;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	spin_unlock_irqrestore(&video->req_lock, flags);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun #else
uvc_using_zero_copy(struct uvc_video * video)64*4882a593Smuzhiyun static inline bool uvc_using_zero_copy(struct uvc_video *video)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	return false;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
uvc_wait_req_complete(struct uvc_video * video,struct uvc_request * ureq)69*4882a593Smuzhiyun static inline void uvc_wait_req_complete(struct uvc_video *video, struct uvc_request *ureq)
70*4882a593Smuzhiyun { }
71*4882a593Smuzhiyun #endif
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /* --------------------------------------------------------------------------
74*4882a593Smuzhiyun  * Video codecs
75*4882a593Smuzhiyun  */
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun static int
uvc_video_encode_header(struct uvc_video * video,struct uvc_buffer * buf,u8 * data,int len)78*4882a593Smuzhiyun uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
79*4882a593Smuzhiyun 		u8 *data, int len)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	if (uvc_using_zero_copy(video)) {
82*4882a593Smuzhiyun 		u8 *mem;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 		mem = buf->mem + video->queue.buf_used +
85*4882a593Smuzhiyun 		      (video->queue.buf_used / (video->req_size - 2)) * 2;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 		mem[0] = 2;
88*4882a593Smuzhiyun 		mem[1] = UVC_STREAM_EOH | video->fid;
89*4882a593Smuzhiyun 		if (buf->bytesused - video->queue.buf_used <= len - 2)
90*4882a593Smuzhiyun 			mem[1] |= UVC_STREAM_EOF;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		return 2;
93*4882a593Smuzhiyun 	}
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	data[0] = 2;
96*4882a593Smuzhiyun 	data[1] = UVC_STREAM_EOH | video->fid;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (buf->bytesused - video->queue.buf_used <= len - 2)
99*4882a593Smuzhiyun 		data[1] |= UVC_STREAM_EOF;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	return 2;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun static int
uvc_video_encode_data(struct uvc_video * video,struct uvc_buffer * buf,u8 * data,int len)105*4882a593Smuzhiyun uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
106*4882a593Smuzhiyun 		u8 *data, int len)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	struct uvc_video_queue *queue = &video->queue;
109*4882a593Smuzhiyun 	unsigned int nbytes;
110*4882a593Smuzhiyun 	void *mem;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	/* Copy video data to the USB buffer. */
113*4882a593Smuzhiyun 	mem = buf->mem + queue->buf_used;
114*4882a593Smuzhiyun 	nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	if (!uvc_using_zero_copy(video))
117*4882a593Smuzhiyun 		memcpy(data, mem, nbytes);
118*4882a593Smuzhiyun 	queue->buf_used += nbytes;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	return nbytes;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun static void
uvc_video_encode_bulk(struct usb_request * req,struct uvc_video * video,struct uvc_buffer * buf)124*4882a593Smuzhiyun uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
125*4882a593Smuzhiyun 		struct uvc_buffer *buf)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	void *mem = req->buf;
128*4882a593Smuzhiyun 	int len = video->req_size;
129*4882a593Smuzhiyun 	int ret;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	/* Add a header at the beginning of the payload. */
132*4882a593Smuzhiyun 	if (video->payload_size == 0) {
133*4882a593Smuzhiyun 		ret = uvc_video_encode_header(video, buf, mem, len);
134*4882a593Smuzhiyun 		video->payload_size += ret;
135*4882a593Smuzhiyun 		mem += ret;
136*4882a593Smuzhiyun 		len -= ret;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Process video data. */
140*4882a593Smuzhiyun 	len = min((int)(video->max_payload_size - video->payload_size), len);
141*4882a593Smuzhiyun 	ret = uvc_video_encode_data(video, buf, mem, len);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	video->payload_size += ret;
144*4882a593Smuzhiyun 	len -= ret;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	req->length = video->req_size - len;
147*4882a593Smuzhiyun 	req->zero = video->payload_size == video->max_payload_size;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	if (buf->bytesused == video->queue.buf_used) {
150*4882a593Smuzhiyun 		video->queue.buf_used = 0;
151*4882a593Smuzhiyun 		buf->state = UVC_BUF_STATE_DONE;
152*4882a593Smuzhiyun 		uvcg_queue_next_buffer(&video->queue, buf);
153*4882a593Smuzhiyun 		video->fid ^= UVC_STREAM_FID;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 		video->payload_size = 0;
156*4882a593Smuzhiyun 		req->zero = 1;
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (video->payload_size == video->max_payload_size ||
160*4882a593Smuzhiyun 	    buf->bytesused == video->queue.buf_used)
161*4882a593Smuzhiyun 		video->payload_size = 0;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun static void
uvc_video_encode_isoc(struct usb_request * req,struct uvc_video * video,struct uvc_buffer * buf)165*4882a593Smuzhiyun uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
166*4882a593Smuzhiyun 		struct uvc_buffer *buf)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	void *mem = req->buf;
169*4882a593Smuzhiyun 	int len = video->req_size;
170*4882a593Smuzhiyun 	int ret;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	if (uvc_using_zero_copy(video))
173*4882a593Smuzhiyun 		req->buf = buf->mem + video->queue.buf_used +
174*4882a593Smuzhiyun 			   (video->queue.buf_used / (video->req_size - 2)) * 2;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	/* Add the header. */
177*4882a593Smuzhiyun 	ret = uvc_video_encode_header(video, buf, mem, len);
178*4882a593Smuzhiyun 	mem += ret;
179*4882a593Smuzhiyun 	len -= ret;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	/* Process video data. */
182*4882a593Smuzhiyun 	ret = uvc_video_encode_data(video, buf, mem, len);
183*4882a593Smuzhiyun 	len -= ret;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	req->length = video->req_size - len;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	if (buf->bytesused == video->queue.buf_used) {
188*4882a593Smuzhiyun 		video->queue.buf_used = 0;
189*4882a593Smuzhiyun 		buf->state = UVC_BUF_STATE_DONE;
190*4882a593Smuzhiyun 		uvcg_queue_next_buffer(&video->queue, buf);
191*4882a593Smuzhiyun 		video->fid ^= UVC_STREAM_FID;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /* --------------------------------------------------------------------------
196*4882a593Smuzhiyun  * Request handling
197*4882a593Smuzhiyun  */
198*4882a593Smuzhiyun 
uvcg_video_ep_queue(struct uvc_video * video,struct usb_request * req)199*4882a593Smuzhiyun static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	int ret;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
204*4882a593Smuzhiyun 	if (ret < 0) {
205*4882a593Smuzhiyun 		uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n",
206*4882a593Smuzhiyun 			 ret);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 		/* If the endpoint is disabled the descriptor may be NULL. */
209*4882a593Smuzhiyun 		if (video->ep->desc) {
210*4882a593Smuzhiyun 			/* Isochronous endpoints can't be halted. */
211*4882a593Smuzhiyun 			if (usb_endpoint_xfer_bulk(video->ep->desc))
212*4882a593Smuzhiyun 				usb_ep_set_halt(video->ep);
213*4882a593Smuzhiyun 		}
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	return ret;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun static void
uvc_video_complete(struct usb_ep * ep,struct usb_request * req)220*4882a593Smuzhiyun uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct uvc_request *ureq = req->context;
223*4882a593Smuzhiyun 	struct uvc_video *video = ureq->video;
224*4882a593Smuzhiyun 	struct uvc_video_queue *queue = &video->queue;
225*4882a593Smuzhiyun 	struct uvc_device *uvc = video->uvc;
226*4882a593Smuzhiyun 	unsigned long flags;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	switch (req->status) {
229*4882a593Smuzhiyun 	case 0:
230*4882a593Smuzhiyun 		break;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	case -ESHUTDOWN:	/* disconnect from host. */
233*4882a593Smuzhiyun 		uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
234*4882a593Smuzhiyun 		uvcg_queue_cancel(queue, 1);
235*4882a593Smuzhiyun 		break;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	default:
238*4882a593Smuzhiyun 		uvcg_warn(&video->uvc->func,
239*4882a593Smuzhiyun 			  "VS request completed with status %d.\n",
240*4882a593Smuzhiyun 			  req->status);
241*4882a593Smuzhiyun 		uvcg_queue_cancel(queue, 0);
242*4882a593Smuzhiyun 	}
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	spin_lock_irqsave(&video->req_lock, flags);
245*4882a593Smuzhiyun 	list_add_tail(&req->list, &video->req_free);
246*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
247*4882a593Smuzhiyun 	complete(&ureq->req_done);
248*4882a593Smuzhiyun #endif
249*4882a593Smuzhiyun 	spin_unlock_irqrestore(&video->req_lock, flags);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	if (uvc->state == UVC_STATE_STREAMING)
252*4882a593Smuzhiyun 		schedule_work(&video->pump);
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun static int
uvc_video_free_requests(struct uvc_video * video)256*4882a593Smuzhiyun uvc_video_free_requests(struct uvc_video *video)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	unsigned int i;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	if (video->ureq) {
261*4882a593Smuzhiyun 		for (i = 0; i < video->uvc_num_requests; ++i) {
262*4882a593Smuzhiyun 			if (video->ureq[i].req) {
263*4882a593Smuzhiyun 				uvc_wait_req_complete(video, &video->ureq[i]);
264*4882a593Smuzhiyun 				usb_ep_free_request(video->ep, video->ureq[i].req);
265*4882a593Smuzhiyun 				video->ureq[i].req = NULL;
266*4882a593Smuzhiyun 			}
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 			if (video->ureq[i].req_buffer) {
269*4882a593Smuzhiyun 				kfree(video->ureq[i].req_buffer);
270*4882a593Smuzhiyun 				video->ureq[i].req_buffer = NULL;
271*4882a593Smuzhiyun 			}
272*4882a593Smuzhiyun 		}
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		kfree(video->ureq);
275*4882a593Smuzhiyun 		video->ureq = NULL;
276*4882a593Smuzhiyun 	}
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	INIT_LIST_HEAD(&video->req_free);
279*4882a593Smuzhiyun 	video->req_size = 0;
280*4882a593Smuzhiyun 	return 0;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun static int
uvc_video_alloc_requests(struct uvc_video * video)284*4882a593Smuzhiyun uvc_video_alloc_requests(struct uvc_video *video)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	unsigned int req_size;
287*4882a593Smuzhiyun 	unsigned int i;
288*4882a593Smuzhiyun 	int ret = -ENOMEM;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	BUG_ON(video->req_size);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	if (!usb_endpoint_xfer_bulk(video->ep->desc)) {
293*4882a593Smuzhiyun 		req_size = video->ep->maxpacket
294*4882a593Smuzhiyun 			 * max_t(unsigned int, video->ep->maxburst, 1)
295*4882a593Smuzhiyun 			 * (video->ep->mult);
296*4882a593Smuzhiyun 	} else {
297*4882a593Smuzhiyun 		req_size = video->ep->maxpacket
298*4882a593Smuzhiyun 			 * max_t(unsigned int, video->ep->maxburst, 1);
299*4882a593Smuzhiyun 	}
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	video->ureq = kcalloc(video->uvc_num_requests, sizeof(struct uvc_request), GFP_KERNEL);
302*4882a593Smuzhiyun 	if (video->ureq == NULL)
303*4882a593Smuzhiyun 		return -ENOMEM;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	for (i = 0; i < video->uvc_num_requests; ++i) {
306*4882a593Smuzhiyun 		video->ureq[i].req_buffer = kmalloc(req_size, GFP_KERNEL);
307*4882a593Smuzhiyun 		if (video->ureq[i].req_buffer == NULL)
308*4882a593Smuzhiyun 			goto error;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		video->ureq[i].req = usb_ep_alloc_request(video->ep, GFP_KERNEL);
311*4882a593Smuzhiyun 		if (video->ureq[i].req == NULL)
312*4882a593Smuzhiyun 			goto error;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 		video->ureq[i].req->buf = video->ureq[i].req_buffer;
315*4882a593Smuzhiyun 		video->ureq[i].req->length = 0;
316*4882a593Smuzhiyun 		video->ureq[i].req->complete = uvc_video_complete;
317*4882a593Smuzhiyun 		video->ureq[i].req->context = &video->ureq[i];
318*4882a593Smuzhiyun 		video->ureq[i].video = video;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
321*4882a593Smuzhiyun 		init_completion(&video->ureq[i].req_done);
322*4882a593Smuzhiyun #endif
323*4882a593Smuzhiyun 		list_add_tail(&video->ureq[i].req->list, &video->req_free);
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	video->req_size = req_size;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	return 0;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun error:
331*4882a593Smuzhiyun 	uvc_video_free_requests(video);
332*4882a593Smuzhiyun 	return ret;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun /* --------------------------------------------------------------------------
336*4882a593Smuzhiyun  * Video streaming
337*4882a593Smuzhiyun  */
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun /*
340*4882a593Smuzhiyun  * uvcg_video_pump - Pump video data into the USB requests
341*4882a593Smuzhiyun  *
342*4882a593Smuzhiyun  * This function fills the available USB requests (listed in req_free) with
343*4882a593Smuzhiyun  * video data from the queued buffers.
344*4882a593Smuzhiyun  */
uvcg_video_pump(struct work_struct * work)345*4882a593Smuzhiyun static void uvcg_video_pump(struct work_struct *work)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	struct uvc_video *video = container_of(work, struct uvc_video, pump);
348*4882a593Smuzhiyun 	struct uvc_video_queue *queue = &video->queue;
349*4882a593Smuzhiyun 	struct usb_request *req = NULL;
350*4882a593Smuzhiyun 	struct uvc_buffer *buf;
351*4882a593Smuzhiyun 	unsigned long flags;
352*4882a593Smuzhiyun 	int ret;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	while (video->ep->enabled) {
355*4882a593Smuzhiyun 		/* Retrieve the first available USB request, protected by the
356*4882a593Smuzhiyun 		 * request lock.
357*4882a593Smuzhiyun 		 */
358*4882a593Smuzhiyun 		spin_lock_irqsave(&video->req_lock, flags);
359*4882a593Smuzhiyun 		if (list_empty(&video->req_free)) {
360*4882a593Smuzhiyun 			spin_unlock_irqrestore(&video->req_lock, flags);
361*4882a593Smuzhiyun 			return;
362*4882a593Smuzhiyun 		}
363*4882a593Smuzhiyun 		req = list_first_entry(&video->req_free, struct usb_request,
364*4882a593Smuzhiyun 					list);
365*4882a593Smuzhiyun 		list_del(&req->list);
366*4882a593Smuzhiyun 		spin_unlock_irqrestore(&video->req_lock, flags);
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 		/* Retrieve the first available video buffer and fill the
369*4882a593Smuzhiyun 		 * request, protected by the video queue irqlock.
370*4882a593Smuzhiyun 		 */
371*4882a593Smuzhiyun 		spin_lock_irqsave(&queue->irqlock, flags);
372*4882a593Smuzhiyun 		buf = uvcg_queue_head(queue);
373*4882a593Smuzhiyun 		if (buf == NULL) {
374*4882a593Smuzhiyun 			spin_unlock_irqrestore(&queue->irqlock, flags);
375*4882a593Smuzhiyun 			break;
376*4882a593Smuzhiyun 		}
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 		video->encode(req, video, buf);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 		/* Queue the USB request */
381*4882a593Smuzhiyun 		ret = uvcg_video_ep_queue(video, req);
382*4882a593Smuzhiyun 		spin_unlock_irqrestore(&queue->irqlock, flags);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		if (ret < 0) {
385*4882a593Smuzhiyun 			uvcg_queue_cancel(queue, 0);
386*4882a593Smuzhiyun 			break;
387*4882a593Smuzhiyun 		}
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 		/* Endpoint now owns the request */
390*4882a593Smuzhiyun 		req = NULL;
391*4882a593Smuzhiyun 	}
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	if (!req)
394*4882a593Smuzhiyun 		return;
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	spin_lock_irqsave(&video->req_lock, flags);
397*4882a593Smuzhiyun 	list_add_tail(&req->list, &video->req_free);
398*4882a593Smuzhiyun 	spin_unlock_irqrestore(&video->req_lock, flags);
399*4882a593Smuzhiyun 	return;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun /*
403*4882a593Smuzhiyun  * Enable or disable the video stream.
404*4882a593Smuzhiyun  */
uvcg_video_enable(struct uvc_video * video,int enable)405*4882a593Smuzhiyun int uvcg_video_enable(struct uvc_video *video, int enable)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	unsigned int i;
408*4882a593Smuzhiyun 	int ret;
409*4882a593Smuzhiyun 	struct uvc_device *uvc;
410*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (video->ep == NULL) {
413*4882a593Smuzhiyun 		uvcg_info(&video->uvc->func,
414*4882a593Smuzhiyun 			  "Video enable failed, device is uninitialized.\n");
415*4882a593Smuzhiyun 		return -ENODEV;
416*4882a593Smuzhiyun 	}
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	uvc = container_of(video, struct uvc_device, video);
419*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(uvc->func.fi);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (!enable) {
422*4882a593Smuzhiyun 		cancel_work_sync(&video->pump);
423*4882a593Smuzhiyun 		uvcg_queue_cancel(&video->queue, 0);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 		for (i = 0; i < video->uvc_num_requests; ++i)
426*4882a593Smuzhiyun 			if (video->ureq && video->ureq[i].req)
427*4882a593Smuzhiyun 				usb_ep_dequeue(video->ep, video->ureq[i].req);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 		uvc_video_free_requests(video);
430*4882a593Smuzhiyun 		uvcg_queue_enable(&video->queue, 0);
431*4882a593Smuzhiyun 		if (cpu_latency_qos_request_active(&uvc->pm_qos))
432*4882a593Smuzhiyun 			cpu_latency_qos_remove_request(&uvc->pm_qos);
433*4882a593Smuzhiyun 		return 0;
434*4882a593Smuzhiyun 	}
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	cpu_latency_qos_add_request(&uvc->pm_qos, opts->pm_qos_latency);
437*4882a593Smuzhiyun 	if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
438*4882a593Smuzhiyun 		return ret;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	if ((ret = uvc_video_alloc_requests(video)) < 0)
441*4882a593Smuzhiyun 		return ret;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	if (video->max_payload_size) {
444*4882a593Smuzhiyun 		video->encode = uvc_video_encode_bulk;
445*4882a593Smuzhiyun 		video->payload_size = 0;
446*4882a593Smuzhiyun 	} else
447*4882a593Smuzhiyun 		video->encode = uvc_video_encode_isoc;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	schedule_work(&video->pump);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return ret;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun /*
455*4882a593Smuzhiyun  * Initialize the UVC video stream.
456*4882a593Smuzhiyun  */
uvcg_video_init(struct uvc_video * video,struct uvc_device * uvc)457*4882a593Smuzhiyun int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun 	INIT_LIST_HEAD(&video->req_free);
460*4882a593Smuzhiyun 	spin_lock_init(&video->req_lock);
461*4882a593Smuzhiyun 	INIT_WORK(&video->pump, uvcg_video_pump);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	video->uvc = uvc;
464*4882a593Smuzhiyun 	video->fcc = V4L2_PIX_FMT_YUYV;
465*4882a593Smuzhiyun 	video->bpp = 16;
466*4882a593Smuzhiyun 	video->width = 320;
467*4882a593Smuzhiyun 	video->height = 240;
468*4882a593Smuzhiyun 	video->imagesize = 320 * 240 * 2;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	/* Initialize the video buffers queue. */
471*4882a593Smuzhiyun 	uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT,
472*4882a593Smuzhiyun 			&video->mutex);
473*4882a593Smuzhiyun 	return 0;
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun 
476