uvc.c 17 KB

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