Hi Laurent,

On Thursday 28 May 2009 15:59:58 Laurent Pinchart wrote:
> Hi Jérôme,
>
> On Thursday 28 May 2009 15:21:52 Jérôme Pouiller wrote:
> > On Wednesday 27 May 2009 17:11:03 Laurent Pinchart wrote:
> > > On Tuesday 26 May 2009 17:49:14 Jérôme Pouiller wrote:
[...]
> > > Could you try to read the value (VIDIOC_G_CTRL) of the hue
> > > control ?
> >
> > It   return  EIO   and   uvcvideo  driver   print   same  message  
> > (see test-BisonCam.c and test-output).
>
> I expected the uvcvideo driver to print a slightly different message
> (129 instead of 135). I'm pretty sure it did, you might have missed
> that.
Yes, you're right.

[...]
> > VIDIOC_QUERYCTRL  success only  if  I remove  GET_DEF, GET_MIN, 
> > GET_MAX and  GET_RES flags.  In  all  other cases,  my  test 
> > program give  same output as  in test-output. (Except:  if I remove
> > UVC_CONTROL_GET* flags, VIDIOC_G_CTRL return EINVAL).
>
> It seems that the camera doesn't support the hue control at all, even
> though it reports it does.
>
> The proper way to fix this is to blacklist the hue control for your
> model. Setting the UVC_QUIRK_PRUNE_CONTROLS and modifying
> uvc_ctrl_prune_controls() should do the job. Could you please try the
> attached patch ?
Your patch apply right on 2.6.29. Nevertheless, with 2.6.28, I had to 
do some changes in order to use it. I also add UVC_QUIRK_PRUNE_CONTROLS 
flag to 5986:0241 in uvc_ids to automatically apply the quirk.

Else, this patch works very well. Thank you.

Best regards,

-- 
Jérôme Pouiller (jezz AT sysmic DOT org)

diff -rNU3 --label linux-2.6.28.9-orig/drivers/media/video/uvc --label linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc linux-2.6.28.9-orig/drivers/media/video/uvc linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
--- linux-2.6.28.9-orig/drivers/media/video/uvc
+++ linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
@@ -548,6 +548,11 @@
 	return (data[bit >> 3] >> (bit & 7)) & 1;
 }
 
+static inline void uvc_clear_bit(__u8 *data, int bit)
+{
+ data[bit >> 3] &= ~(1 << (bit & 7));
+}
+
 /* Extract the bit string specified by mapping->offset and mapping->size
  * from the little-endian data stored at 'data' and return the result as
  * a signed 32bit integer. Sign extension will be performed if the mapping
@@ -1306,6 +1311,47 @@
 }
 
 /*
+ * 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_device *dev, struct uvc_entity *entity)
+{
+ static const struct {
+   struct usb_device_id id;
+   u8 index;
+ } blacklist[] = {
+   { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
+   { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
+ };
+
+ u8 *controls;
+ unsigned int size;
+ unsigned int i;
+
+ if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT)
+   return;
+
+ controls = entity->processing.bmControls;
+ size = entity->processing.bControlSize;
+ 
+ for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
+   if (!usb_match_id(dev->intf, &blacklist[i].id))
+     continue;
+
+   if (blacklist[i].index >= 8 * size ||
+       !uvc_get_bit(controls, blacklist[i].index))
+     continue;
+
+   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].index);
+ }
+}
+
+/*
  * Initialize device controls.
  */
 int uvc_ctrl_init_device(struct uvc_device *dev)
@@ -1331,6 +1377,9 @@
 			bControlSize = entity->camera.bControlSize;
 		}
 
+        if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
+          uvc_ctrl_prune_entity(dev, entity);
+
 		for (i = 0; i < bControlSize; ++i)
 			ncontrols += hweight8(bmControls[i]);
 
diff -rNU3 --label linux-2.6.28.9-orig/drivers/media/video/uvc --label linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc linux-2.6.28.9-orig/drivers/media/video/uvc linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
--- linux-2.6.28.9-orig/drivers/media/video/uvc
+++ linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
@@ -1884,7 +1884,19 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_IGNORE_SELECTOR_UNIT},
+                | UVC_QUIRK_IGNORE_SELECTOR_UNIT
+                | UVC_QUIRK_PRUNE_CONTROLS },
+    /* Bison Electronics, Pro NB */
+    { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE
+                | USB_DEVICE_ID_MATCH_INT_INFO,
+      .idVendor     = 0x5986,
+      .idProduct        = 0x0241,
+      .bInterfaceClass  = USB_CLASS_VIDEO,
+      .bInterfaceSubClass   = 1,
+      .bInterfaceProtocol   = 0,
+      .driver_info      = UVC_QUIRK_PROBE_MINMAX 
+                | UVC_QUIRK_IGNORE_SELECTOR_UNIT
+                | UVC_QUIRK_PRUNE_CONTROLS },
 	/* Acer OEM Webcam - Unknown vendor */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff -rNU3 --label linux-2.6.28.9-orig/drivers/media/video/uvc --label linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc linux-2.6.28.9-orig/drivers/media/video/uvc linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
--- linux-2.6.28.9-orig/drivers/media/video/uvc
+++ linux-2.6.28.9-ctrl-blacklist/drivers/media/video/uvc
@@ -316,6 +316,7 @@
 #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
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to