• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3  * Description: LiteOS USB Driver Video Stream
4  * Author: huangjieliang
5  * Create: 2017-04-17
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  * conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14  * to endorse or promote products derived from this software without specific prior written
15  * permission.
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29  * Notice of Export Control Law
30  * ===============================================
31  * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32  * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33  * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34  * applicable export control laws and regulations.
35  * --------------------------------------------------------------------------- */
36 
37 #include <los_mux.h>
38 #include "gadget/f_uvc.h"
39 #include "implementation/global_implementation.h"
40 #ifdef LOSCFG_DRIVERS_USB2_DEVICE_CONTROLLER
41 #include "controller/usb_device/dwc_otgreg.h"
42 #include "controller/usb_device/dwc_otg_pcd.h"
43 #endif
44 #ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER
45 #include "controller/usb_device/pcd.h"
46 #endif
47 
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif /* __cplusplus */
52 #endif /* __cplusplus */
53 
54 /*
55  * module local variables
56  */
57 
58 uint32_t g_uvc_mutex = UVC_INVALID_HANDLE;
59 
60 /* private pointer to the UVC handle structure */
61 
62 static struct uvc_handle *volatile g_uvc = (struct uvc_handle *)UVC_INVALID_HANDLE;
63 
64 /* private pointer to the F_UVC structure */
65 
66 struct uvc_dev_s *volatile g_f_uvc = (struct uvc_dev_s *)UVC_INVALID_HANDLE;
67 
68 static int uvc_copy_continue(struct uvc_handle *uvc, struct uvc_isoc_transfer *tran);
69 static int uvc_nocp_continue(struct uvc_handle *uvc, struct uvc_isoc_transfer *tran);
70 
uvc_release_mutex(void)71 static void uvc_release_mutex(void)
72 {
73   uint32_t ret;
74   ret = LOS_MuxPost(g_uvc_mutex);
75   if (ret != LOS_OK)
76     {
77       usb_err("Failed to unlock mutex: %#x\n", ret);
78     }
79 }
80 
uvc_delete_mutex(void)81 void uvc_delete_mutex(void)
82 {
83   (void)LOS_MuxDelete(g_uvc_mutex);
84   g_uvc_mutex = UVC_INVALID_HANDLE;
85 }
86 
uvc_is_running(void)87 bool uvc_is_running(void)
88 {
89   return (g_uvc == (struct uvc_handle *)UVC_INVALID_HANDLE) ? false : true;
90 }
91 
92 /*
93  * Check the UVC handle provided by external source
94  */
95 
uvc_check_handle(uvc_t hdl)96 static int uvc_check_handle(uvc_t hdl)
97 {
98   uint32_t ret;
99   struct uvc_handle *uvc;
100 
101   /* catch NULL pointer */
102 
103   if (hdl == NULL)
104     {
105       return UVC_ERROR_PTR;
106     }
107 
108   ret = LOS_MuxPend(g_uvc_mutex, LOS_WAIT_FOREVER);
109   if (ret != LOS_OK)
110     {
111       usb_err("Failed to acquire UVC mutex: %#x, %p\n", ret, __builtin_return_address(0));
112       return UVC_ERROR_VALUE;
113     }
114 
115   /* check whether the provided handle matches the one privated stored */
116 
117   uvc = g_uvc;
118   if (uvc == (struct uvc_handle *)UVC_INVALID_HANDLE ||
119       hdl != (uvc_t)uvc)
120     {
121       uvc_release_mutex();
122       return UVC_ERROR_HANDLE;
123     }
124 
125   return UVC_OK;
126 }
127 
uvc_format_status_check(void)128 enum format_switch_status uvc_format_status_check(void)
129 {
130   struct uvc_dev_s *fuvc = g_f_uvc;
131 
132   if (fuvc == (struct uvc_dev_s *)UVC_INVALID_HANDLE)
133     {
134       usb_err("uvc is not initialization\n");
135       return FORMAT_SWITCH_FINISH;
136     }
137 
138   return (enum format_switch_status)fuvc->format_info.status;
139 }
140 
uvc_format_info_get(struct uvc_format_info * info)141 int uvc_format_info_get(struct uvc_format_info *info)
142 {
143   struct uvc_format_info *format_info;
144   struct uvc_dev_s *fuvc = g_f_uvc;
145 
146   if (info == NULL)
147     {
148       usb_err("the info is NULL\n");
149       return UVC_ERROR_PTR;
150     }
151 
152   if (fuvc == (struct uvc_dev_s *)UVC_INVALID_HANDLE)
153     {
154       usb_err("uvc is not initialization\n");
155       return UVC_ERROR_PTR;
156     }
157 
158   format_info = &fuvc->format_info;
159   if (format_info->status == FORMAT_SWITCH_PENDING)
160     {
161       if (format_info->format != V4L2_PIX_FMT_YUYV &&
162           format_info->format != V4L2_PIX_FMT_H264 &&
163           format_info->format != V4L2_PIX_FMT_MJPEG)
164         {
165           return UVC_ERROR_NOMATCH;
166         }
167 
168       info->height = format_info->height;
169       info->width  = format_info->width;
170       info->format = format_info->format;
171 
172       fuvc->format_info.status = FORMAT_SWITCH_FINISH;
173 
174       return UVC_OK;
175     }
176   else
177     {
178       usb_err("the uvc format status is not update\n");
179       return UVC_ERROR_NOMATCH;
180     }
181 }
182 
uvc_wait_host_sub(uvc_t hdl,int * connected)183 static int uvc_wait_host_sub(uvc_t hdl, int *connected)
184 {
185   int ret;
186   struct uvc_handle *uvc;
187   struct uvc_dev_s *fuvc;
188 
189   ret = uvc_check_handle(hdl);
190   if (ret != UVC_OK)
191     {
192       return ret;
193     }
194   uvc = (struct uvc_handle *)hdl;
195 
196   fuvc = uvc->fuvc;
197   if (fuvc == NULL || fuvc != g_f_uvc)
198     {
199       uvc_release_mutex();
200       return UVC_ERROR_PTR;
201     }
202 
203   if ((*connected = fuvc_host_connected(fuvc)) != 0)
204     {
205       if (uvc->state == UVC_STATE_IDLE)
206         {
207           uvc->state = UVC_STATE_CONN;
208         }
209     }
210 
211   uvc_release_mutex();
212   return ret;
213 }
214 
uvc_wait_host(uvc_t hdl,int wait_option,int * connected)215 int uvc_wait_host(uvc_t hdl, int wait_option, int *connected)
216 {
217   int ret;
218 
219   if (connected == NULL)
220     {
221       return UVC_ERROR_PTR;
222     }
223 
224   switch (wait_option)
225     {
226     case UVC_WAIT_HOST_NOP:
227       ret = uvc_wait_host_sub(hdl, connected);
228       break;
229 
230     case UVC_WAIT_HOST_FOREVER:
231       while (1)
232         {
233           ret = uvc_wait_host_sub(hdl, connected);
234           if (ret != UVC_OK || *connected)
235             {
236               break;
237             }
238           (void) LOS_TaskDelay(10);
239         }
240       break;
241 
242     default:
243       ret = UVC_ERROR_VALUE;
244     }
245 
246   return ret;
247 }
248 
uvc_open_device(uvc_t * hdl,struct uvc_open_param * param)249 int uvc_open_device(uvc_t *hdl, struct uvc_open_param *param)
250 {
251   uint32_t rval;
252   struct uvc_handle *uvc;
253   struct uvc_dev_s *fuvc;
254 
255   /* NULL pointers are not allowed */
256 
257   if (hdl == NULL || param == NULL)
258     {
259       return UVC_ERROR_PTR;
260     }
261 
262   /* check the function input video parameter */
263 
264   if (param->vid_width <= 0x1 || param->vid_width > UVC_VIDEO_WIDTH_MAX)
265     {
266       return UVC_ERROR_VALUE;
267     }
268   if (param->vid_height <= 0x1 || param->vid_height > UVC_VIDEO_HEIGHT_MAX)
269     {
270       return UVC_ERROR_VALUE;
271     }
272   if (param->vid_format != UVC_VFF_YUY2 &&
273       param->vid_format != UVC_VFF_H264 &&
274       param->vid_format != UVC_VFF_MJPG)
275     {
276       return UVC_ERROR_VALUE;
277     }
278 
279   rval = LOS_MuxPend(g_uvc_mutex, LOS_WAIT_FOREVER);
280   if (rval != LOS_OK)
281     {
282       usb_err("Failed to lock UVC mutex: %#x\n", rval);
283       return UVC_ERROR_VALUE;
284     }
285 
286   uvc = g_uvc;
287   if (uvc != (struct uvc_handle *)UVC_INVALID_HANDLE)
288     {
289       uvc_release_mutex();
290       return UVC_ERROR_HANDLE; /* already opened */
291     }
292 
293   /* check whether F_UVC module has been initialized */
294 
295   fuvc = g_f_uvc;
296   if (fuvc == (struct uvc_dev_s *)UVC_INVALID_HANDLE)
297     {
298       uvc_release_mutex();
299       return UVC_ERROR_VALUE;
300     }
301 
302   /* allocate memory for uvc_handle structure */
303 
304   uvc = calloc(0x1, sizeof(struct uvc_handle));
305   if (uvc == NULL)
306     {
307       uvc_release_mutex();
308       return UVC_ERROR_MEMORY;
309     }
310 
311   /* initialize the UVC handle */
312 
313   uvc->vid_w       = param->vid_width;
314   uvc->vid_h       = param->vid_height;
315   uvc->vid_f       = param->vid_format;
316   uvc->state       = UVC_STATE_IDLE;
317   uvc->fuvc        = fuvc;
318   fuvc->uvc_handle = (void *)uvc;
319 
320   fuvc->bulk_size = param->bulk_size;
321   fuvc->imgsize   = param->imgsize;
322 
323   /* store a private copy of UVC handle */
324 
325   g_uvc = uvc;
326 
327   /* return the UVC handle */
328 
329   *hdl = (uvc_t)uvc;
330   uvc_release_mutex();
331   return UVC_OK;
332 }
333 
334 /*
335  * local function to stop video stream transmission process
336  * return error only when a transmission cannot be stopped
337  */
338 
uvc_video_tran_stop(struct uvc_handle * uvc)339 static int uvc_video_tran_stop(struct uvc_handle *uvc)
340 {
341   switch (uvc->state)
342     {
343     case UVC_STATE_TRAN_COPY:
344       uvc->copy_func = NULL;
345       break;
346 
347     case UVC_STATE_TRAN_NOCP:
348       uvc->next_func = NULL;
349       break;
350 
351     default:
352       return UVC_OK;
353     }
354 
355   uvc->_priv = NULL;
356 
357   /* update UVC handle state */
358 
359   if (uvc->fuvc != NULL)
360     {
361       uvc->state = fuvc_host_connected(uvc->fuvc) ? UVC_STATE_CONN : UVC_STATE_IDLE;
362     }
363   else
364     {
365       uvc->state = UVC_STATE_IDLE;
366     }
367   return UVC_OK;
368 }
369 
uvc_video_stop(uvc_t hdl)370 int uvc_video_stop(uvc_t hdl)
371 {
372   int ret;
373 
374   ret = uvc_check_handle(hdl);
375   if (ret != UVC_OK)
376     {
377       return ret;
378     }
379 
380   ret = uvc_video_tran_stop((struct uvc_handle *)hdl);
381   uvc_release_mutex();
382   return ret;
383 }
384 
uvc_close_device(uvc_t hdl)385 int uvc_close_device(uvc_t hdl)
386 {
387   int ret;
388   struct uvc_handle *uvc;
389   struct uvc_dev_s *fuvc;
390   uint32_t flags;
391 
392   ret = uvc_check_handle(hdl);
393   if (ret != UVC_OK)
394     {
395       return ret;
396     }
397   uvc = (struct uvc_handle *)hdl;
398 
399   /* stop Video transmission first */
400 
401   if (uvc->state == UVC_STATE_TRAN_COPY ||
402       uvc->state == UVC_STATE_TRAN_NOCP)
403     {
404       (void)uvc_video_tran_stop(uvc);
405     }
406 
407   fuvc = uvc->fuvc;
408   if (fuvc == NULL)
409     {
410       uvc_release_mutex();
411       return UVC_ERROR_PTR;
412     }
413   spin_lock_irqsave(&fuvc->lock, flags);
414   fuvc->uvc_handle = (void *)UVC_INVALID_HANDLE;
415 
416   /* set the global handle to NULL, and free the handle structure */
417 
418   g_uvc = (struct uvc_handle *)UVC_INVALID_HANDLE;
419   uvc->fuvc = NULL;
420   spin_unlock_irqrestore(&fuvc->lock, flags);
421   free(uvc);
422   uvc_release_mutex();
423   return UVC_OK;
424 }
425 
uvc_get_state(uvc_t hdl,uint32_t * state)426 int uvc_get_state(uvc_t hdl, uint32_t *state)
427 {
428   int ret;
429   struct uvc_handle *uvc;
430 
431   /* validate function parameters */
432 
433   if (state == NULL)
434     {
435       return UVC_ERROR_PTR;
436     }
437 
438   ret = uvc_check_handle(hdl);
439   if (ret != UVC_OK)
440     {
441       return ret;
442     }
443 
444   uvc = (struct uvc_handle *)hdl;
445   if (uvc->state == UVC_STATE_IDLE && uvc->fuvc &&
446       fuvc_host_connected(uvc->fuvc))
447     {
448       uvc->state = UVC_STATE_CONN;
449     }
450 
451   *state = uvc->state;
452   uvc_release_mutex();
453   return UVC_OK;
454 }
455 
uvc_video_tran_nocp(uvc_t hdl,uvc_continue_func next_func,void * priv)456 int uvc_video_tran_nocp(uvc_t hdl, uvc_continue_func next_func, void *priv)
457 {
458   int ret;
459   struct uvc_handle *uvc;
460   struct nocp_reserve *res;
461 
462   /* function reference & private pointer should not be NULL */
463 
464   if (next_func == NULL || priv == NULL)
465     {
466       return UVC_ERROR_PTR;
467     }
468 
469   ret = uvc_check_handle(hdl);
470   if (ret != UVC_OK)
471     {
472       return ret;
473     }
474   uvc = (struct uvc_handle *)hdl;
475 
476   if (uvc->fuvc == NULL)
477     {
478       uvc_release_mutex();
479       return UVC_ERROR_PTR;
480     }
481 
482   if (uvc->state != UVC_STATE_CONN)
483     {
484       uvc_release_mutex();
485       return UVC_ERROR_NOMATCH;
486     }
487 
488   /* initialize related UVC handle field members */
489 
490   uvc->frame_off    = 0;
491   uvc->tdata.data   = NULL;
492   uvc->tdata.length = 0;
493   uvc->tdata.last   = 0;
494 
495   /* store callback function and parameter */
496 
497   uvc->copy_func = NULL;
498   uvc->next_func = next_func;
499   uvc->_priv     = priv;
500 
501   /* initialize reserve structure */
502 
503   res       = &(uvc->reserve);
504   res->res  = NULL;
505   res->resl = 0;
506 
507   /* get the first frame of video data */
508 
509   ret = next_func(hdl, &(uvc->tdata), priv);
510   if (ret != UVC_OK)
511     {
512       uvc_release_mutex();
513       return ret;
514     }
515 
516   uvc->state = UVC_STATE_TRAN_NOCP;
517   ret        = fuvc_transfer_initiate(uvc->fuvc);
518   if (ret != UVC_OK)
519     {
520       uvc->state = UVC_STATE_ERR;
521       uvc_release_mutex();
522       return ret;
523     }
524   uvc_release_mutex();
525   return UVC_OK;
526 }
527 
uvc_video_tran_copy(uvc_t hdl,uvc_continue_func copy_func,void * priv)528 int uvc_video_tran_copy(uvc_t hdl, uvc_continue_func copy_func, void *priv)
529 {
530   int ret;
531   struct uvc_handle *uvc;
532   struct uvc_dev_s *fuvc;
533 
534   if (copy_func == NULL || priv == NULL)
535     {
536       return UVC_ERROR_PTR;
537     }
538 
539   ret = uvc_check_handle(hdl);
540   if (ret != UVC_OK)
541     {
542       return ret;
543     }
544 
545   uvc = (struct uvc_handle *)hdl;
546   if (uvc->fuvc == NULL)
547     {
548       uvc_release_mutex();
549       return UVC_ERROR_PTR;
550     }
551 
552   fuvc = uvc->fuvc;
553 
554   if (g_start_transfer == 0)
555    {
556       fuvc->connected = 0;
557       uvc_release_mutex();
558       usb_err("uvc can not start transfer!\n");
559       return UVC_ERROR_PTR;
560     }
561 
562   /* check whether UVC state matches */
563 
564   if (uvc->state != UVC_STATE_CONN)
565     {
566       uvc_release_mutex();
567       return UVC_ERROR_NOMATCH;
568     }
569 
570   /* initialize related UVC handle field members */
571 
572   uvc->frame_off    = 0;
573   uvc->tdata.data   = NULL;
574   uvc->tdata.length = 0;
575   uvc->tdata.last   = 0;
576 
577   /* set the callback function and parameter */
578 
579   uvc->next_func = NULL;
580   uvc->copy_func = copy_func;
581 
582   if (fuvc->transfer_status == STREAM_OFF)
583     {
584       uvc_release_mutex();
585       usb_err("uvc transfer status is stream off!\n");
586       return UVC_ERROR_PTR;
587     }
588 
589   uvc->_priv = priv;
590 
591   /* update UVC handle state */
592 
593   uvc->state = UVC_STATE_TRAN_COPY;
594   ret = fuvc_transfer_initiate(uvc->fuvc);
595   if (ret != UVC_OK)
596     {
597       uvc->state = UVC_STATE_ERR;
598       uvc_release_mutex();
599       return ret;
600     }
601   uvc_release_mutex();
602 
603   ret = LOS_EventRead(&g_uvc_event, 0x01, LOS_WAITMODE_OR |
604                       LOS_WAITMODE_CLR, 100);
605   if (ret == LOS_ERRNO_EVENT_READ_TIMEOUT)
606     {
607       usb_err("Transfer timeout!\n");
608       ret = uvc_check_handle(hdl);
609       if (ret)
610         {
611           return ret;
612         }
613       usbclass_uvc_stream_ep_reset(fuvc);
614       uvc_release_mutex();
615       return UVC_ERROR_VALUE;
616     }
617 
618   return UVC_OK;
619 }
620 
uvc_continue_transfer(struct uvc_dev_s * fuvc,struct uvc_isoc_transfer * tran)621 int uvc_continue_transfer(struct uvc_dev_s *fuvc, struct uvc_isoc_transfer *tran)
622 {
623   struct uvc_handle *uvc;
624   uint32_t flags;
625   int ret = UVC_ERROR_PTR;
626 
627   spin_lock_irqsave(&fuvc->lock, flags);
628   uvc = (struct uvc_handle *)fuvc->uvc_handle;
629   if (uvc == (struct uvc_handle *)UVC_INVALID_HANDLE)
630     {
631       goto done;
632     }
633 
634   if (uvc->copy_func)
635     {
636       ret = uvc_copy_continue(uvc, tran);
637       goto done;
638     }
639   if (uvc->next_func)
640     {
641       ret = uvc_nocp_continue(uvc, tran);
642     }
643 
644 done:
645   spin_unlock_irqrestore(&fuvc->lock, flags);
646   return ret;
647 }
648 
uvc_nocp_continue(struct uvc_handle * uvc,struct uvc_isoc_transfer * tran)649 static int uvc_nocp_continue(struct uvc_handle *uvc, struct uvc_isoc_transfer *tran)
650 {
651   uvc_continue_func next_func;
652   struct nocp_reserve *reserve;
653   struct uvc_transfer_data *transfer;
654   uint32_t length, offset, res;
655 
656   /* initialize local variables */
657 
658   length   = tran->length;
659   offset   = uvc->frame_off;
660   transfer = &(uvc->tdata);
661   reserve  = &(uvc->reserve);
662 
663   /* restore the reserved data */
664 
665   if (reserve->res != NULL)
666     {
667       uint32_t i, j;
668       j = (reserve->resl > NOCP_RESERVE_MAX) ? NOCP_RESERVE_MAX : reserve->resl;
669       for (i = 0; i < j; ++i)
670         {
671           reserve->res[i] = reserve->res_buf[i];
672         }
673     }
674 
675   /* determine how where the transfer should start */
676 
677   if (transfer->data == NULL)
678     {
679       return UVC_ERROR_PTR;
680     }
681 
682   tran->data = &(transfer->data[offset]);
683   res        = tran->reserved;
684   if (offset < res)
685     {
686       res = 0;
687       tran->reserved = 0;
688 
689       /* do not reserve */
690 
691       reserve->res  = NULL;
692       reserve->resl = res;
693     }
694   else
695     {
696       uint32_t i, j;
697       uint8_t *p;
698 
699       j = (res > NOCP_RESERVE_MAX) ? NOCP_RESERVE_MAX : res;
700       p = tran->data - j;
701 
702       for (i = 0; i < j; ++i)
703         {
704           reserve->res_buf[i] = p[i];
705         }
706       reserve->resl = j;
707       reserve->res  = p;
708     }
709 
710   /* determine whether reached the frame end */
711 
712   if ((offset + length) >= transfer->length)
713     {
714       tran->length   = transfer->length - offset;
715       transfer->data = NULL;
716 
717       /* get the next frame of video data */
718 
719       if ((next_func = uvc->next_func) != NULL)
720         {
721           int ret;
722           ret = next_func(uvc, transfer, uvc->_priv);
723           if (ret != UVC_OK)
724             {
725               dprintf("next_func %p returned: %d\n", next_func, ret);
726             }
727         }
728       offset     = 0;
729       tran->last = 1;
730     }
731   else
732     {
733       uintptr_t ptr;
734 
735       ptr  = (uintptr_t)tran->data;
736       ptr -= tran->res_next;
737 
738       /* make sure that next transimission buffer aligns at 4-byte boundary */
739 
740       if ((ptr + length) & 0x3)
741         {
742           while ((ptr + length) & 0x3)
743             {
744               if (length == 0)
745                 {
746                   break;
747                 }
748               length--;
749             }
750           tran->length = length;
751         }
752 
753       /* increment frame offset */
754 
755       offset += length;
756       tran->last = 0;
757     }
758 
759   /* write back computed values */
760 
761   uvc->frame_off = offset;
762   return UVC_OK;
763 }
764 
uvc_copy_continue(struct uvc_handle * uvc,struct uvc_isoc_transfer * tran)765 static int uvc_copy_continue(struct uvc_handle *uvc, struct uvc_isoc_transfer *tran)
766 {
767   int ret;
768   uint32_t cplen;
769   uvc_continue_func copy;
770   struct uvc_transfer_data *frame;
771 
772   copy = uvc->copy_func;
773   if (copy == NULL)
774     {
775       return UVC_ERROR_PTR;
776     }
777 
778   frame         = &(uvc->tdata);
779   frame->data   = tran->data;
780   frame->length = tran->length;
781   frame->last   = 0;
782   cplen         = tran->length;
783 
784   ret = copy(uvc, frame, uvc->_priv);
785   if (ret != UVC_OK)
786     {
787       usb_err("copy(...) has failed: %d\n", ret);
788       return ret;
789     }
790 
791   if (cplen != frame->length)
792     {
793       tran->length = frame->length;
794     }
795   tran->last = frame->last;
796 
797   return UVC_OK;
798 }
799 
uvc_stream_init(struct uvc_dev_s * fuvc)800 int uvc_stream_init(struct uvc_dev_s *fuvc)
801 {
802   uint32_t ret;
803 
804   g_f_uvc = fuvc;
805 
806   g_uvc_mutex = 0;
807   ret = LOS_MuxCreate(&g_uvc_mutex);
808   if (ret != LOS_OK)
809     {
810       usb_err("Failed to create Mutex for UVC: %#x\n", ret);
811       return -1;
812     }
813 
814   fuvc_fill_streaming_control(fuvc, &fuvc->probe, 0, 0);
815   fuvc_fill_streaming_control(fuvc, &fuvc->commit, 0, 0);
816 
817   return 0;
818 }
819 
820 #define GET_BYTE(data, bits)     (((data) >> (bits)) & 0xFF)
usb_format_yuv_semiplanar_420(char * buf_virt_y,char * buf_virt_c,uint8_t * frame_mem,uint32_t frame_len,uint32_t frame_height,uint32_t frame_width)821 void usb_format_yuv_semiplanar_420(char *buf_virt_y, char *buf_virt_c, uint8_t *frame_mem,
822                                    uint32_t frame_len, uint32_t frame_height, uint32_t frame_width)
823 {
824   uint32_t height = frame_height;
825   uint32_t width  = frame_width;
826   char *temp_buf_virt_y = buf_virt_y;
827   char *temp_buf_virt_c = buf_virt_c;
828   char *py, *end;
829   uint32_t *pyy, *pc;
830   uint32_t *p, *pp;
831   register uint32_t r1, r2, rr1, rr2;
832   register uint32_t c[2];
833   uint32_t i;
834   uint32_t reg;
835 
836   reg   = GET_UINT32(0x12020ee0);
837   reg >>= 24;
838   if (reg == 0x4 || reg == 0 || reg == 0x10)
839     {
840       for(i = 0; i < height / 2; i++)
841         {
842           py  = temp_buf_virt_y + (i * 2) * width;
843           pyy = (uint32_t *)(py + width);
844           end = (char *)pyy;
845           pc  = (uint32_t *)(temp_buf_virt_c + i * width);
846           p   = (uint32_t *)(frame_mem + frame_len + (i * 4) * width);
847           pp  = (uint32_t *)(frame_mem + frame_len + (i * 4 + 2) * width);
848           for(; py < end; py += 8)
849             {
850               c[0] = *(pc++);
851               c[1] = *(pc++);
852 
853               r1 = *((uint32_t *)py);
854               r2 = *((uint32_t *)py + 1);
855               *(p++) = ((GET_BYTE(r1, 0)) | (GET_BYTE(c[0], 8) << 8) |
856                         (GET_BYTE(r1, 8) << 16) | (GET_BYTE(c[0], 0) << 24));
857               *(p++) = ((GET_BYTE(r1, 16)) | (GET_BYTE(c[0], 24) << 8) |
858                         (GET_BYTE(r1, 24) << 16) | (GET_BYTE(c[0], 16) << 24));
859               *(p++) = ((GET_BYTE(r2, 0)) | (GET_BYTE(c[1], 8) << 8) |
860                         (GET_BYTE(r2, 8) << 16) | (GET_BYTE(c[1], 0) << 24));
861               *(p++) = ((GET_BYTE(r2, 16)) | (GET_BYTE(c[1], 24) << 8) |
862                         (GET_BYTE(r2, 24) << 16) | (GET_BYTE(c[1], 16) << 24));
863 
864               rr1 = *(pyy++);
865               rr2 = *(pyy++);
866               *(pp++) = ((GET_BYTE(rr1, 0)) | (GET_BYTE(c[0], 8) << 8) |
867                          (GET_BYTE(rr1, 8) << 16) | (GET_BYTE(c[0], 0) << 24));
868               *(pp++) = ((GET_BYTE(rr1, 16)) | (GET_BYTE(c[0], 24) << 8) |
869                          (GET_BYTE(rr1, 24) << 16) | (GET_BYTE(c[0], 16) << 24));
870               *(pp++) = ((GET_BYTE(rr2, 0)) | (GET_BYTE(c[1], 8) << 8) |
871                          (GET_BYTE(rr2, 8) << 16) | (GET_BYTE(c[1], 0) << 24));
872               *(pp++) = ((GET_BYTE(rr2, 16)) | (GET_BYTE(c[1], 24) << 8) |
873                          (GET_BYTE(rr2, 24) << 16) | (GET_BYTE(c[1], 16) << 24));
874             }
875         }
876     }
877 }
878 
879 #ifdef __cplusplus
880 #if __cplusplus
881 }
882 #endif /* __cplusplus */
883 #endif /* __cplusplus */