V4L/DVB (11944): uvcvideo: Add generic control blacklist.
authorLaurent Pinchart <laurent.pinchart@skynet.be>
Sun, 31 May 2009 20:05:55 +0000 (17:05 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 16 Jun 2009 22:07:29 +0000 (19:07 -0300)
Another device (5986:0241) has been reported to advertise a UVC control it
does not support. Rework the control blacklist to match devices by their
VID:PID instead of trying to be clever about which controls might not be
supported properly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvcvideo.h

index 0d7e38d6ff6a416ed6905b9bb66d6b3f6f2dd2f6..36a6ba92df2700710746db302c152dc61ea14842 100644 (file)
@@ -1372,21 +1372,19 @@ end:
 }
 
 /*
- * Prune an entity of its bogus controls. This currently includes processing
- * unit auto controls for which no corresponding manual control is available.
- * Such auto controls make little sense if any, and are known to crash at
- * least the SiGma Micro webcam.
+ * Prune an entity of its bogus controls using a blacklist. Bogus controls
+ * are currently the ones that crash the camera or unconditionally return an
+ * error when queried.
  */
 static void
-uvc_ctrl_prune_entity(struct uvc_entity *entity)
+uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
 {
        static const struct {
-               u8 idx_manual;
-               u8 idx_auto;
+               struct usb_device_id id;
+               u8 index;
        } blacklist[] = {
-               { 2, 11 }, /* Hue */
-               { 6, 12 }, /* White Balance Temperature */
-               { 7, 13 }, /* White Balance Component */
+               { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
+               { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
        };
 
        u8 *controls;
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity)
        size = entity->processing.bControlSize;
 
        for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
-               if (blacklist[i].idx_auto >= 8 * size ||
-                   blacklist[i].idx_manual >= 8 * size)
+               if (!usb_match_id(dev->intf, &blacklist[i].id))
                        continue;
 
-               if (!uvc_test_bit(controls, blacklist[i].idx_auto) ||
-                    uvc_test_bit(controls, blacklist[i].idx_manual))
+               if (blacklist[i].index >= 8 * size ||
+                   !uvc_test_bit(controls, blacklist[i].index))
                        continue;
 
-               uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no "
-                       "matching manual control, removing it.\n", entity->id,
-                       blacklist[i].idx_auto);
+               uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
+                       "removing it.\n", entity->id, blacklist[i].index);
 
-               uvc_clear_bit(controls, blacklist[i].idx_auto);
+               uvc_clear_bit(controls, blacklist[i].index);
        }
 }
 
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
                        bControlSize = entity->camera.bControlSize;
                }
 
-               if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
-                       uvc_ctrl_prune_entity(entity);
+               uvc_ctrl_prune_entity(dev, entity);
 
                for (i = 0; i < bControlSize; ++i)
                        ncontrols += hweight8(bmControls[i]);
index 46bfecb194e81a0d95a9e5fbc33ea27db7e3c238..838585990ee87a538c1ae144ef84d6dc0af5b8ee 100644 (file)
@@ -1946,8 +1946,7 @@ static struct usb_device_id uvc_ids[] = {
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
          .driver_info          = UVC_QUIRK_PROBE_MINMAX
-                               | UVC_QUIRK_IGNORE_SELECTOR_UNIT
-                               | UVC_QUIRK_PRUNE_CONTROLS },
+                               | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
        /* Generic USB Video Class */
        { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
        {}
index daf0744473046c0a8d87127eb4bd1ca2b432d162..f435e8eeccd261bd5823ced9838c12a7f39aca98 100644 (file)
@@ -313,7 +313,6 @@ struct uvc_xu_control {
 #define UVC_QUIRK_BUILTIN_ISIGHT       0x00000008
 #define UVC_QUIRK_STREAM_NO_FID                0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
-#define UVC_QUIRK_PRUNE_CONTROLS       0x00000040
 #define UVC_QUIRK_FIX_BANDWIDTH                0x00000080
 
 /* Format flags */