usbtuner: fix dvb functionality after v4l2 operation
Jean Huang [Fri, 24 Feb 2017 18:31:39 +0000 (10:31 -0800)]
Cameraserver calls v4l2_open to check the device type as
soon as a v4l2 device is registered, and then v4l2_close
if the device isn't a camera.

For cx231xx tuners, the device needs to stay in DIGITAL_MODE
for dvb_init, however, in v4l2_open the mode is switched to
ANALOG_MODE, which fails dvb_init. This patch fails v4l2_open
if it's called before dvb_init is done for cx231xx tuners.

For em28xx tuners, v4l2_close resets the usb interface alternate
to 0, which is supposed to be 1 for dvb function to work after
dvb_init. This patch skipped the usb interface reset after dvb_init
for em28xx tuners.

Bug 1861283

Change-Id: I91eb7ae0e171529ed7c0cf0f07404afb33b32d53
Signed-off-by: Jean Huang <jeanh@nvidia.com>
Signed-off-by: Patrick Horng <phorng@nvidia.com>
Reviewed-on: http://git-master/r/1313562
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/1456516
Reviewed-by: Manish Tuteja <mtuteja@nvidia.com>

drivers/media/usb/cx231xx/cx231xx-video.c
drivers/media/usb/em28xx/em28xx-video.c

index eee7e3f..546a45d 100644 (file)
@@ -1848,7 +1848,7 @@ static int cx231xx_v4l2_open(struct file *filp)
                         video_device_node_name(vdev), v4l2_type_names[fh_type],
                         dev->users);
 
-#if 0
+#if 1
        errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
        if (errCode < 0) {
                cx231xx_errdev
index a2737b4..fe1ee75 100644 (file)
@@ -1741,13 +1741,15 @@ static int em28xx_v4l2_close(struct file *filp)
                em28xx_set_mode(dev, EM28XX_SUSPEND);
 
                /* set alternate 0 */
-               dev->alt = 0;
-               em28xx_videodbg("setting alternate 0\n");
-               errCode = usb_set_interface(dev->udev, 0, 0);
-               if (errCode < 0) {
-                       em28xx_errdev("cannot change alternate number to "
-                                       "0 (error=%i)\n", errCode);
-               }
+                if (!dev->board.has_dvb) {
+                       dev->alt = 0;
+                       em28xx_videodbg("setting alternate 0\n");
+                       errCode = usb_set_interface(dev->udev, 0, 0);
+                       if (errCode < 0) {
+                               em28xx_errdev("cannot change alternate number to "
+                                               "0 (error=%i)\n", errCode);
+                       }
+                }
        }
 
        dev->users--;