修改点如下,通过节点名称判断usb判断video


 

 
  1. --- a/kernel/drivers/media/usb/uvc/uvc_driver.c

  2. +++ b/kernel/drivers/media/usb/uvc/uvc_driver.c

  3. @@ -1736,7 +1736,10 @@ static int uvc_register_video(struct uvc_device *dev,

  4.          */

  5.         stream->vdev = vdev;

  6.         video_set_drvdata(vdev, stream);

  7. -

  8. +

  9. +       vdev->hw_portnum = dev->udev->hw_portnum;

  10. +       printk(KERN_ERR"CCCC vdev->hw_portnum=%d\n",vdev->hw_portnum);

  11. +

  12.         ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);

  13.         if (ret < 0) {

  14.                 uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",

  15. diff --git a/kernel/drivers/media/v4l2-core/v4l2-dev.c b/kernel/drivers/media/v4l2-core/v4l2-dev.c

  16. index ed5040eb2e..3f37eaedd8 100644

  17. --- a/kernel/drivers/media/v4l2-core/v4l2-dev.c

  18. +++ b/kernel/drivers/media/v4l2-core/v4l2-dev.c

  19. @@ -847,7 +847,23 @@ int __video_register_device(struct video_device *vdev, int type, int nr,

  20.  
  21.         /* Pick a device node number */

  22.         mutex_lock(&videodev_lock);

  23. -       nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);

  24. +

  25. +       printk(KERN_ERR "AAAA portnum=%d\n",vdev->hw_portnum);

  26. +       if(vdev->vfl_type == VFL_TYPE_GRABBER) {

  27. +               printk(KERN_ERR "BBB portnum=%d\n",vdev->hw_portnum);

  28. +               if(7 == vdev->hw_portnum) {

  29. +                       nr = 7;

  30. +               }else  if(8 == vdev->hw_portnum) {

  31. +                       nr = 8;

  32. +               }

  33. +       }

  34. +       //else

  35. +       {

  36. +

  37. +               nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);

  38. +       }

  39. +

  40. +//     nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);

  41.         if (nr == minor_cnt)

  42.                 nr = devnode_find(vdev, 0, minor_cnt);

  43.         if (nr == minor_cnt) {

  44.  
  45.  

 

 
  1. --- a/kernel/drivers/usb/core/hub.c

  2. +++ b/kernel/drivers/usb/core/hub.c

  3. @@ -2147,15 +2147,24 @@ static void show_string(struct usb_device *udev, char *id, char *string)

  4.  
  5. static void announce_device(struct usb_device *udev)

  6. {

  7. - dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",

  8. + udev->hw_portnum=0;

  9. + printk(KERN_ERR"kobject_name(&udev->dev->kobj)=%s\n",kobject_name(&(udev->dev.kobj)));

  10. + if(!strcmp("1-1.1.4",kobject_name(&(udev->dev.kobj)))){

  11. + udev->hw_portnum=7;

  12. + }else if(!strcmp("1-1.2.4",kobject_name(&(udev->dev.kobj)))){

  13. + udev->hw_portnum=8;

  14. + }

  15. + printk(KERN_ERR"udev->hw_portnum=%d\n",udev->hw_portnum);

  16. +

  17. + dev_info(&udev->dev, "AAA New USB device found, idVendor=%04x, idProduct=%04x\n",

  18. le16_to_cpu(udev->descriptor.idVendor),

  19. le16_to_cpu(udev->descriptor.idProduct));

  20. dev_info(&udev->dev,

  21. - "New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",

  22. + "AAA New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",

  23. udev->descriptor.iManufacturer,

  24. udev->descriptor.iProduct,

  25. udev->descriptor.iSerialNumber);

  26. - show_string(udev, "Product", udev->product);

  27. + show_string(udev, "AAAProduct", udev->product);

  28. show_string(udev, "Manufacturer", udev->manufacturer);

  29. show_string(udev, "SerialNumber", udev->serial);

  30. }

  31. @@ -2406,7 +2415,7 @@ int usb_new_device(struct usb_device *udev)

  32. err = usb_enumerate_device(udev); /* Read descriptors */

  33. if (err < 0)

  34. goto fail;

  35. - dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",

  36. + printk(KERN_ERR "udev %d, busnum %d, minor = %d\n",

  37. udev->devnum, udev->bus->busnum,

  38. (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));

  39. /* export the usbdev device-node for libusb */

 

 
  1. --- a/kernel/include/linux/usb.h

  2. +++ b/kernel/include/linux/usb.h

  3. @@ -546,6 +546,7 @@ struct usb_device {

  4.  
  5. unsigned short bus_mA;

  6. u8 portnum;

  7. + u8 hw_portnum;

  8. u8 level;

  9.  
  10. unsigned can_submit:1;

  11. diff --git a/kernel/include/media/v4l2-dev.h b/kernel/include/media/v4l2-dev.h

  12. index 95d1c91770..5421ee172a 100644

  13. --- a/kernel/include/media/v4l2-dev.h

  14. +++ b/kernel/include/media/v4l2-dev.h

  15. @@ -126,7 +126,7 @@ struct video_device

  16. struct list_head fh_list; /* List of struct v4l2_fh */

  17.  
  18. int debug; /* Activates debug level*/

  19. -

  20. + int hw_portnum; /*usb hw port*/

  21. /* Video standard vars */

  22. v4l2_std_id tvnorms; /* Supported tv norms */

  23. v4l2_std_id current_norm; /* Current tvnorm */

 

下面那个毛用都没有,portnum usb插拔情况下会变化

 

转载自:https://www.cnblogs.com/zou107/p/7895111.html

在Android的系统会有前置摄像头和后置摄像头的定义,摄像头分为SOC类型的摄像头和USB这一类的摄像头,接下要分析就是USB摄像头这一类 。

一般在android或者linux系统中分析一个模块,先从总体的框架上有一个认识,然后在局部细细的研究。

 一、Android 摄像头总体架构

固定USB摄像头硬件端口——LINUX

上面的框架,分析的比较粗糙,主要是一些自己看代码后总结下来的东西。以USB摄像为例,在插入的USB摄像头后,会生成/dev/video0这样的设备节点,而在硬件抽象层中,会去判断是否存在该设备节点,以提供给android系统层使用。再往上分析就是android部分的了,先暂时不分析。

二、Linux层中UVC摄像头注册流程

固定USB摄像头硬件端口——LINUX

在USB子系统判断有UVC设备接入后,会去调用uvc_probe(代码位置:/driver/media/uvc/uvc_driver.c)来完成USB摄像头的创建,通过一步一步的分析,最终会走到v4L2框架中,创建摄像头的设备节点。

三、固定USB摄像头硬件端口

前面分析了这么多,都是为了接下来的做准备。

 现在客户那么使用我们的主板机器,其中会使用两个USB摄像头,一个作为前置摄像头用于人脸识别,一个用于后置摄像头,由于在安装时并不知道那个端口的摄像头先插入,那个后插入(设备节点中先接入的就会分配video0,而在android中一般定义video0为后置摄像头,video1为前置摄像头),就导致android系统层前后置摄像头混乱。

为了解决该问题,就需要在驱动中,将前后置摄像头和USB的硬件端口做一个绑定。

具体改法如下:

(1) 在/include/media/v4l2-dev.h的video_device结构体中添加变量portnum

 
  1. struct video_device

  2. struct list_head fh_list; /* List of struct v4l2_fh */

  3.  
  4. int debug; /* Activates debug level*/

  5. + int portnum; /*usb hw port*/

(2)在/drivers/media/usb/uvc/uvc_driver.c的uvc_register_video函数中添加vdev->portnum = dev->udev->portnum;

固定USB摄像头硬件端口——LINUX

 
  1. static int uvc_register_video(struct uvc_device *dev,

  2. ...

  3. stream->vdev = vdev;

  4. video_set_drvdata(vdev, stream);

  5.  
  6. + vdev->portnum = dev->udev->portnum;

  7. ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);

固定USB摄像头硬件端口——LINUX

这里先将USB的portnum存下来,在创建设备节点的是否,就会根据该变量来区分硬件的上哪个USB是前置,哪个USB是后置了

 (3)在/drivers/media/v4l2-core/v4l2-dev.c的__video_register_device函数中,修改

固定USB摄像头硬件端口——LINUX

 
  1. int __video_register_device(struct video_device *vdev, int type, int nr,

  2. ...

  3. /* Pick a device node number */

  4. mutex_lock(&videodev_lock);+ if(vdev->vfl_type == VFL_TYPE_GRABBER) {

  5. + if(4 == vdev->portnum) {

  6. + nr = 1;

  7. + }else {

  8. + nr = 0;

  9. + }

  10. + }else {

  11. + nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);

  12. + }

  13. +

  14. if (nr == minor_cnt)

  15. nr = devnode_find(vdev, 0, minor_cnt);

  16. if (nr == minor_cnt) {

固定USB摄像头硬件端口——LINUX

注意:这里的“4 == vdev->portnum”是根据时机板子的端口上的,在调试的时候,可以先将portnum变量的值打印出来,就知道如何区分了。

 

相关文章: