1 /*
2 ********************************************************************************
3 *                                USB UVC Driver
4 *
5 *                (c) Copyright 2006-2010, All winners Co,Ld.
6 *                        All Right Reserved
7 *
8 * FileName      :  UVC.c
9 *
10 * Author        :  Kingvan
11 *
12 * Date          :  2013/03/26
13 *
14 * Description   :  USB VIDEO CONTROL Driver中对USB接口设备的处理
15 *
16 * Others        :  NULL
17 *
18 * History:
19 *       <time>          <author>     <version >     <desc>
20 *      2013.03.26       Kingvan         1.0         build this file
21 *
22 ********************************************************************************
23 */
24 //#include  "usb_host_config.h"
25 //#include  "usb_host_base_types.h"
26 #include  "usb_os_platform.h"
27 #include  "error.h"
28 
29 #include  "usb_utils_find_zero_bit.h"
30 #include  "usb_list.h"
31 #include  "list_head_ext.h"
32 
33 #include  "usb_host_common.h"
34 #include  "usb_gen_dev_mod.h"
35 #include  "urb.h"
36 #include  "usb.h"
37 #include  "usb_core_interface.h"
38 #include  "usb_msg.h"
39 
40 //#include  "usbh_disk_info.h"
41 //#include  "usbh_buff_manager.h"
42 //#include  "usbh_disk_remove_time.h"
43 
44 #include "video.h"
45 #include "uvcvideo.h"
46 #include "uvc_driver.h"
47 
48 
49 #define  UVC_DRV_NAME       "UVC Class"
50 #define  UVC_DRV_AUTHOR     "Kingvan.Tong"
51 
52 //---------------------------------------------------------------
53 //  宏定义区
54 //---------------------------------------------------------------
55 
56 //---------------------------------------------------------------
57 //  全局变量区
58 //---------------------------------------------------------------
59 static struct usb_host_func_drv UVCDrv;
60 static __u32 UVCDev_id_array;               /* 记录了设备的编号 */
61 static void* UVCDev_attr;
62 
63 
64 static unsigned char g_enter_flag = 0;
65 
66 static struct usb_drv_dev_match_table UVC_match_table[] = {
67         /* Genius eFace 2025 */
68         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
69           0x0458, 0x706e,0,0,
70           0,0,0,
71           USB_CLASS_VIDEO,1,0,
72           UVC_QUIRK_PROBE_MINMAX },
73         /* Microsoft Lifecam NX-6000 */
74         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
75           0x045e, 0x00f8,0,0,
76           0,0,0,
77           USB_CLASS_VIDEO,1,0,
78           UVC_QUIRK_PROBE_MINMAX },
79         /* Microsoft Lifecam VX-7000 */
80         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
81           0x045e, 0x0723,0,0,
82           0,0,0,
83           USB_CLASS_VIDEO, 1, 0,
84           UVC_QUIRK_PROBE_MINMAX },
85         /* Logitech Quickcam Fusion */
86         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
87           0x046d, 0x08c1,0,0,
88           0,0,0,
89           USB_CLASS_VENDOR_SPEC, 1, 0,
90           0},
91         /* Logitech Quickcam Orbit MP */
92         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
93           0x046d, 0x08c2,0,0,
94           0,0,0,
95           USB_CLASS_VENDOR_SPEC, 1, 0,
96           0},
97         /* Logitech Quickcam Pro for Notebook */
98         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
99           0x046d,0x08c3,0,0,
100           0,0,0,
101           USB_CLASS_VENDOR_SPEC, 1, 0,
102           0},
103         /* Logitech Quickcam Pro 5000 */
104         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
105           0x046d,0x08c5,0,0,
106           0,0,0,
107           USB_CLASS_VENDOR_SPEC, 1, 0,
108          0},
109         /* Logitech Quickcam OEM Dell Notebook */
110         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
111           0x046d,0x08c6,0,0,
112           0,0,0,
113           USB_CLASS_VENDOR_SPEC,1,0,
114           0},
115         /* Logitech Quickcam OEM Cisco VT Camera II */
116         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
117           0x046d,0x08c7,0,0,
118           0,0,0,
119           USB_CLASS_VENDOR_SPEC, 1, 0,
120           0},
121         /* Chicony CNF7129 (Asus EEE 100HE) */
122         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
123           0x04f2, 0xb071,0,0,
124           0,0,0,
125           USB_CLASS_VIDEO, 1, 0,
126           UVC_QUIRK_RESTRICT_FRAME_RATE },
127         /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
128         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
129           0x058f, 0x3820,0,0,
130           0,0,0,
131           USB_CLASS_VIDEO, 1, 0,
132           UVC_QUIRK_PROBE_MINMAX },
133         /* Apple Built-In iSight */
134         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
135           0x05ac,0x8501,0,0,
136           0,0,0,
137           USB_CLASS_VIDEO,1,0,
138           UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_BUILTIN_ISIGHT },
139         /* Genesys Logic USB 2.0 PC Camera */
140         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
141           0x05e3,0x0505,0,0,
142           0,0,0,
143           USB_CLASS_VIDEO, 1, 0,
144           UVC_QUIRK_STREAM_NO_FID },
145         /* Hercules Classic Silver */
146         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
147           0x06f8, 0x300c,0,0,
148           0,0,0,
149           USB_CLASS_VIDEO, 1, 0,
150           UVC_QUIRK_FIX_BANDWIDTH },
151         /* ViMicro Vega */
152         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
153           0x0ac8, 0x332d,0,0,
154           0,0,0,
155           USB_CLASS_VIDEO, 1, 0,
156           UVC_QUIRK_FIX_BANDWIDTH },
157         /* ViMicro - Minoru3D */
158         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
159           0x0ac8,0x3410,0,0,
160           0,0,0,
161           USB_CLASS_VIDEO,1,0,
162           UVC_QUIRK_FIX_BANDWIDTH },
163         /* ViMicro Venus - Minoru3D */
164         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
165           0x0ac8, 0x3420,0,0,
166           0,0,0,
167           USB_CLASS_VIDEO, 1, 0,
168           UVC_QUIRK_FIX_BANDWIDTH },
169         /* MT6227 */
170         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
171           0x0e8d,0x0004,0,0,
172           0,0,0,
173           USB_CLASS_VIDEO,1,0,
174           UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_PROBE_DEF },
175         /* IMC Networks (Medion Akoya) */
176         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
177           0x13d3, 0x5103,0,0,
178           0,0,0,
179           USB_CLASS_VIDEO, 1, 0,
180           UVC_QUIRK_STREAM_NO_FID },
181         /* JMicron USB2.0 XGA WebCam */
182         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
183           0x152d,0x0310,0,0,
184           0,0,0,
185           USB_CLASS_VIDEO, 1, 0,
186           UVC_QUIRK_PROBE_MINMAX },
187         /* Syntek (HP Spartan) */
188         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
189           0x174f, 0x5212,0,0,
190           0,0,0,
191           USB_CLASS_VIDEO, 1, 0,
192           UVC_QUIRK_STREAM_NO_FID },
193         /* Syntek (Samsung Q310) */
194         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
195           0x174f, 0x5931,0,0,
196           0,0,0,
197           USB_CLASS_VIDEO, 1, 0,
198           UVC_QUIRK_STREAM_NO_FID },
199         /* Syntek (Packard Bell EasyNote MX52 */
200         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
201           0x174f, 0x8a12,0,0,
202           0,0,0,
203           USB_CLASS_VIDEO, 1, 0,
204           UVC_QUIRK_STREAM_NO_FID },
205         /* Syntek (Asus F9SG) */
206         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
207           0x174f, 0x8a31,0,0,
208           0,0,0,
209           USB_CLASS_VIDEO, 1, 0,
210           UVC_QUIRK_STREAM_NO_FID },
211         /* Syntek (Asus U3S) */
212         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
213           0x174f, 0x8a33,0,0,
214           0,0,0,
215           USB_CLASS_VIDEO, 1, 0,
216           UVC_QUIRK_STREAM_NO_FID },
217         /* Syntek (JAOtech Smart Terminal) */
218         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
219           0x174f, 0x8a34,0,0,
220           0,0,0,
221           USB_CLASS_VIDEO, 1, 0,
222           UVC_QUIRK_STREAM_NO_FID },
223         /* Miricle 307K */
224         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
225           0x17dc,0x0202,0,0,
226           0,0,0,
227           USB_CLASS_VIDEO,1,0,
228           UVC_QUIRK_STREAM_NO_FID },
229         /* Lenovo Thinkpad SL400/SL500 */
230         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
231           0x17ef,0x480b,0,0,
232           0,0,0,
233           USB_CLASS_VIDEO,1,0,
234           UVC_QUIRK_STREAM_NO_FID },
235         /* Aveo Technology USB 2.0 Camera */
236         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
237           0x1871,0x0306,0,0,
238           0,0,0,
239           USB_CLASS_VIDEO, 1, 0,
240           UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_PROBE_EXTRAFIELDS },
241         /* Ecamm Pico iMage */
242         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
243           0x18cd, 0xcafe,0,0,
244           0,0,0,
245           USB_CLASS_VIDEO, 1, 0,
246           UVC_QUIRK_PROBE_EXTRAFIELDS },
247         /* Manta MM-353 Plako */
248         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
249           0x18ec,0x3188,0,0,
250           0,0,0,
251           USB_CLASS_VIDEO,1, 0,
252           UVC_QUIRK_PROBE_MINMAX },
253         /* FSC WebCam V30S */
254         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
255           0x18ec, 0x3288,0,0,
256           0,0,0,
257           USB_CLASS_VIDEO, 1, 0,
258           UVC_QUIRK_PROBE_MINMAX },
259         /* Arkmicro unbranded */
260         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
261           0x18ec, 0x3290,0,0,
262           0,0,0,
263           USB_CLASS_VIDEO, 1, 0,
264           UVC_QUIRK_PROBE_DEF },
265         /* Bodelin ProScopeHR */
266         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_HI | USB_DEVICE_ID_MATCH_INT_INFO,
267           0x19ab,0x1000,0,0x0126,
268           0,0,0,
269           USB_CLASS_VIDEO,1,0,
270           UVC_QUIRK_STATUS_INTERVAL },
271         /* MSI StarCam 370i */
272         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
273           0x1b3b, 0x2951,0,0,
274           0,0,0,
275           USB_CLASS_VIDEO, 1, 0,
276           UVC_QUIRK_PROBE_MINMAX },
277         /* SiGma Micro USB Web Camera */
278         { USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
279           0x1c4f, 0x3000,0,0,
280           0,0,0,
281           USB_CLASS_VIDEO, 1, 0,
282            UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
283         /* Generic USB Video Class */
284         { USB_DEVICE_ID_MATCH_INT_INFO,
285           0,0,0,0,
286           0,0,0,
287           USB_CLASS_VIDEO, 1, 0,
288           0},
289         { 0,
290           0,0,0,0,
291           0,0,0,
292           0,0,0,
293           0}
294 };
295 
296 //---------------------------------------------------------------
297 //  函数区定义区
298 //---------------------------------------------------------------
299 
get_UVCDev_id(void)300 static unsigned int get_UVCDev_id(void)
301 {
302     unsigned int bit = 0;
303 
304     bit = find_next_zero_bit((const volatile u32 *)&UVCDev_id_array, (1 * 32), 0);
305     if(bit > 32){
306         hal_log_err("ERR: find_next_zero_bit failed\n");
307         return 31;
308     }
309 
310     usb_set_bit(bit, (volatile uint32_t *)&UVCDev_id_array);
311 
312     return bit;
313 }
314 
free_UVCDev_id(unsigned int bit)315 static int free_UVCDev_id(unsigned int bit)
316 {
317     if(usb_test_bit(bit, (volatile uint32_t *)&UVCDev_id_array) == 0){
318         hal_log_err("ERR: free_host_id: invalid bit(%d)\n", bit);
319         return -1;
320     }
321 
322     /* 回收该位 */
323     usb_clear_bit(bit, (volatile uint32_t *)&UVCDev_id_array);
324 
325     return 0;
326 }
327 
UVCDevInit(UVCDev_t * UVCDev,struct usb_interface * intf)328 static int UVCDevInit(UVCDev_t *UVCDev, struct usb_interface *intf)
329 {
330     int ret = 0;
331 
332     if(UVCDev == NULL || intf == NULL){
333         hal_log_err("ERR: UVCDevInit: input error\n");
334         return USB_ERR_BAD_ARGUMENTS;
335     }
336 
337     UVCDev->pusb_dev    = usb_mod_interface_to_usbdev(intf);
338     if(UVCDev->pusb_dev == NULL){
339         hal_log_err("ERR: UVCDevInit: UVCDev->pusb_dev == NULL\n");
340         return USB_ERR_BAD_ARGUMENTS;
341     }
342 
343     UVCDev->pusb_intf   = intf;
344     UVCDev->DevNo       = get_UVCDev_id();
345 
346     /* Store our private data in the interface */
347     usb_mod_usb_set_intf_priv_data(intf, (void *)UVCDev);
348 
349 
350     return USB_ERR_SUCCESS;
351 
352 }
353 
UVCDevFree(UVCDev_t * UVCDev)354 static int UVCDevFree(UVCDev_t *UVCDev)
355 {
356     unsigned char err = 0;
357 
358     if(UVCDev == NULL){
359         hal_log_err("ERR: UVC input error\n");
360         return USB_ERR_BAD_ARGUMENTS;
361     }
362 
363     /* Remove our private data from the interface */
364     usb_mod_usb_set_intf_priv_data(UVCDev->pusb_intf, NULL);
365 
366     free_UVCDev_id(UVCDev->DevNo);
367 
368     return 0;
369 }
370 
UVCGetDeviceInfo(UVCDev_t * UVCDev)371 static void UVCGetDeviceInfo(UVCDev_t *UVCDev)
372 {
373     struct usb_interface_descriptor *idesc = &(UVCDev->pusb_intf->cur_altsetting->desc);
374 
375     UVCDev->InterfaceNo = idesc->bInterfaceNumber;
376     UVCDev->SubClass    = idesc->bInterfaceSubClass;
377     UVCDev->Protocol    = idesc->bInterfaceProtocol;
378 
379     return;
380 }
381 
UVCSetDeviceState(UVCDev_t * UVCDev,UVCDev_State_t state)382 void UVCSetDeviceState(UVCDev_t *UVCDev, UVCDev_State_t state)
383 {
384     unsigned int cup_sr = 0;
385 
386     ENTER_CRITICAL(cup_sr);
387     UVCDev->State = state;
388     EXIT_CRITICAL(cup_sr);
389 }
390 
UVCDevScan(UVCDev_t * UVCDev,const struct usb_drv_dev_match_table * table_item)391 static int UVCDevScan(UVCDev_t *UVCDev, const struct usb_drv_dev_match_table * table_item)
392 {
393     struct usb_host_virt_interface *cur_alt = NULL;
394     int ret = 0;
395     unsigned int i = 0;
396 
397     if(UVCDev == NULL){
398         hal_log_err("ERR: UVCDevScan: input error\n");
399         return USB_ERR_BAD_ARGUMENTS;
400     }
401 
402     /* initalize parameter */
403     cur_alt = UVCDev->pusb_intf->cur_altsetting;
404 
405     /* get device type */
406     UVCDev->DevType = cur_alt->desc.bInterfaceProtocol;
407 
408     if (uvc_probe(UVCDev, table_item)) {
409         hal_log_err("ERR: uvc_probe failed\n");
410         return USB_ERR_DEVICE_PROBE_FAILED;
411     }
412 
413     if( usbWebcam_probe(UVCDev) != USB_ERR_SUCCESS){
414         hal_log_err("ERR: usbWebcamProbe failed\n");
415         return USB_ERR_DEVICE_PROBE_FAILED;
416     }
417 
418     return USB_ERR_SUCCESS;
419 }
420 
UVCDevAdd(UVCDev_t * UVCDev,const struct usb_drv_dev_match_table * table_item)421 static int UVCDevAdd(UVCDev_t * UVCDev, const struct usb_drv_dev_match_table * table_item)
422 {
423     return UVCDevScan(UVCDev, table_item);
424 }
425 
UVCDevDel(UVCDev_t * UVCDev)426 static int UVCDevDel(UVCDev_t * UVCDev)
427 {
428     if( usbWebcam_remove(UVCDev) != USB_ERR_SUCCESS){
429         hal_log_err("ERR: usbWebcamRemove failed\n");
430         return USB_ERR_DEVICE_PROBE_FAILED;
431     }
432     return USB_ERR_SUCCESS;
433 }
434 
435 
UVCDevProbe(struct usb_interface * intf,const struct usb_drv_dev_match_table * table_item)436 static int32_t UVCDevProbe(struct usb_interface *intf, const struct usb_drv_dev_match_table * table_item)
437 {
438     UVCDev_t *UVCDev = NULL;
439     int ret = 0;
440 //  unsigned char err  = 0;
441 
442     hal_log_info("UVCDevProbe begin\n");
443 
444     if( g_enter_flag == 1 )
445     {
446         hal_log_err("exception: UVCDevProbe\n");
447         return -1;
448     }
449 
450     if(intf == NULL || table_item == NULL){
451         hal_log_err("ERR: UVCDevProbe: input error\n");
452         return -1;
453     }
454 
455     //----------------------------------------------------------------
456     //   创建UVCDev设备
457     //----------------------------------------------------------------
458     /* 初始化一个mscDev */
459     UVCDev = hal_malloc(sizeof(UVCDev_t));
460     if(UVCDev == NULL){
461         hal_log_err("ERR: UVCDevProbe malloc failed\n");
462         goto error0;
463     }
464 
465     memset(UVCDev, 0, sizeof(UVCDev_t));
466 
467     ret = UVCDevInit(UVCDev, intf);
468     if(ret != USB_ERR_SUCCESS){
469         hal_log_err("ERR: UVCDevProbe failed\n");
470         ret = -1;
471         goto error1;
472     }
473 
474     /* 获得设备信息 */
475     UVCGetDeviceInfo(UVCDev);
476 
477     UVCSetDeviceState(UVCDev, UVC_DEV_ONLINE);
478 
479     //----------------------------------------------------------------
480     //   识别UVCDev设备
481     //----------------------------------------------------------------
482     ret = UVCDevAdd(UVCDev, table_item);
483     if(ret != USB_ERR_SUCCESS){
484         hal_log_err("ERR: UVCDevScan failed\n");
485         ret = -1;
486         goto error4;
487     }
488 
489     g_enter_flag = 1;
490 
491     return 0;
492 
493 error4:
494     UVCSetDeviceState(UVCDev, UVC_DEV_OFFLINE);
495 
496 error3:
497 error2:
498     UVCDevFree(UVCDev);
499 
500 error1:
501     hal_free(UVCDev);
502 
503 error0:
504 
505     return -1;
506 }
507 
UVCDevSuspend(struct usb_interface * intf)508 static int32_t UVCDevSuspend(struct usb_interface *intf)
509 {
510     hal_log_info("UVCDevSuspend not support\n");
511 
512     return 0;
513 }
514 
UVCDevRemove(struct usb_interface * intf)515 static void UVCDevRemove(struct usb_interface *intf)
516 {
517     UVCDev_t *UVCDev = NULL;
518 
519     if( g_enter_flag == 0 )
520     {
521         hal_log_err("exception: UVCDevRemove\n");
522         return;
523     }
524 
525     if(intf == NULL){
526         hal_log_err("ERR: UVCDevRemoves: input error\n");
527         return ;
528     }
529 
530     UVCDev = (UVCDev_t *)usb_mod_usb_get_intf_priv_data(intf);
531     if(UVCDev == NULL){
532         hal_log_err("ERR: UVCDev = NULL\n");
533         return ;
534     }
535 
536     UVCSetDeviceState(UVCDev, UVC_DEV_OFFLINE);
537 
538     UVCDevDel(UVCDev);
539 
540     uvc_disconnect(UVCDev);
541 
542     UVCDevFree(UVCDev);
543 
544     hal_free(UVCDev);
545 
546     hal_log_info("UVCDevRemove complete\n");
547 
548     g_enter_flag = 0;
549 
550     return ;
551 }
552 
UVCDriverInit(struct usb_host_func_drv * drv)553 static int UVCDriverInit(struct usb_host_func_drv *drv)
554 {
555     if(drv == NULL){
556         hal_log_err("ERR: mscDrv_init: input error\n");
557         return -1;
558     }
559 
560     USB_INIT_LIST_HEAD(&(drv->virt_dev_list));
561     drv->func_drv_name      = UVC_DRV_NAME;
562     drv->func_drv_auther    = UVC_DRV_AUTHOR;
563     drv->probe              = UVCDevProbe;
564     drv->disconnect         = UVCDevRemove;
565     drv->suspend            = UVCDevSuspend;
566     drv->resume             = NULL;
567     drv->match_table        = UVC_match_table;
568 
569     return 0;
570 }
UVCInit(void)571 int UVCInit(void)
572 {
573     int ret = 0;
574 
575     memset(&UVCDrv, 0, sizeof(struct usb_host_func_drv));
576 
577     UVCDev_attr = usbWebcam_init();
578     if( UVCDev_attr == NULL ){
579         hal_log_err("ERR: usbWebcam_init failed\n");
580         return -1;
581     }
582 
583     if(UVCDriverInit(&UVCDrv) != 0){
584         hal_log_err("ERR: UVCDriverInit failed\n");
585         return -1;
586     }
587 
588     ret = usb_host_func_drv_reg(&UVCDrv);
589     if(ret != 0){
590         hal_log_err("ERR: UVCInit: Reg driver %s failed\n", UVCDrv.func_drv_name);
591         return -1;
592     }
593 
594     g_enter_flag = 0;
595 
596     return 0;
597 }
598 
UVCExit(void)599 int UVCExit(void)
600 {
601     int ret = 0;
602 
603     ret = usb_host_func_drv_unreg(&UVCDrv);
604     if(ret != 0){
605         hal_log_err("ERR: UVCExit: UnReg driver %s failed\n", UVCDrv.func_drv_name);
606         return -1;
607     }
608 
609     ret = usbWebcam_exit(UVCDev_attr);
610     if(ret != 0){
611         hal_log_err("ERR: usbWebcam_exit() failed\n");
612         return -1;
613     }
614 
615     memset(&UVCDrv, 0, sizeof(struct usb_host_func_drv));
616 
617     return 0;
618 }
619 
620 
621 
622 
623 
624 
625 
626 
627 
628 
629