aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2009-05-31 16:05:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 18:07:29 -0400
commitd732c44c1a4b54e3c59ad92069bc2fd848aca5f3 (patch)
treed78fc6b272b69a0772de85720e68808a415eb611 /drivers/media/video/uvc
parent926b3b4122e4ebca52e67eecf9beb9a517e593f4 (diff)
V4L/DVB (11944): uvcvideo: Add generic control blacklist.
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>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c35
-rw-r--r--drivers/media/video/uvc/uvc_driver.c3
-rw-r--r--drivers/media/video/uvc/uvcvideo.h1
3 files changed, 16 insertions, 23 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 0d7e38d6ff6a..36a6ba92df27 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1372,21 +1372,19 @@ end:
1372} 1372}
1373 1373
1374/* 1374/*
1375 * Prune an entity of its bogus controls. This currently includes processing 1375 * Prune an entity of its bogus controls using a blacklist. Bogus controls
1376 * unit auto controls for which no corresponding manual control is available. 1376 * are currently the ones that crash the camera or unconditionally return an
1377 * Such auto controls make little sense if any, and are known to crash at 1377 * error when queried.
1378 * least the SiGma Micro webcam.
1379 */ 1378 */
1380static void 1379static void
1381uvc_ctrl_prune_entity(struct uvc_entity *entity) 1380uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1382{ 1381{
1383 static const struct { 1382 static const struct {
1384 u8 idx_manual; 1383 struct usb_device_id id;
1385 u8 idx_auto; 1384 u8 index;
1386 } blacklist[] = { 1385 } blacklist[] = {
1387 { 2, 11 }, /* Hue */ 1386 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
1388 { 6, 12 }, /* White Balance Temperature */ 1387 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
1389 { 7, 13 }, /* White Balance Component */
1390 }; 1388 };
1391 1389
1392 u8 *controls; 1390 u8 *controls;
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity)
1400 size = entity->processing.bControlSize; 1398 size = entity->processing.bControlSize;
1401 1399
1402 for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { 1400 for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
1403 if (blacklist[i].idx_auto >= 8 * size || 1401 if (!usb_match_id(dev->intf, &blacklist[i].id))
1404 blacklist[i].idx_manual >= 8 * size)
1405 continue; 1402 continue;
1406 1403
1407 if (!uvc_test_bit(controls, blacklist[i].idx_auto) || 1404 if (blacklist[i].index >= 8 * size ||
1408 uvc_test_bit(controls, blacklist[i].idx_manual)) 1405 !uvc_test_bit(controls, blacklist[i].index))
1409 continue; 1406 continue;
1410 1407
1411 uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " 1408 uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
1412 "matching manual control, removing it.\n", entity->id, 1409 "removing it.\n", entity->id, blacklist[i].index);
1413 blacklist[i].idx_auto);
1414 1410
1415 uvc_clear_bit(controls, blacklist[i].idx_auto); 1411 uvc_clear_bit(controls, blacklist[i].index);
1416 } 1412 }
1417} 1413}
1418 1414
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
1442 bControlSize = entity->camera.bControlSize; 1438 bControlSize = entity->camera.bControlSize;
1443 } 1439 }
1444 1440
1445 if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) 1441 uvc_ctrl_prune_entity(dev, entity);
1446 uvc_ctrl_prune_entity(entity);
1447 1442
1448 for (i = 0; i < bControlSize; ++i) 1443 for (i = 0; i < bControlSize; ++i)
1449 ncontrols += hweight8(bmControls[i]); 1444 ncontrols += hweight8(bmControls[i]);
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 46bfecb194e8..838585990ee8 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1946,8 +1946,7 @@ static struct usb_device_id uvc_ids[] = {
1946 .bInterfaceSubClass = 1, 1946 .bInterfaceSubClass = 1,
1947 .bInterfaceProtocol = 0, 1947 .bInterfaceProtocol = 0,
1948 .driver_info = UVC_QUIRK_PROBE_MINMAX 1948 .driver_info = UVC_QUIRK_PROBE_MINMAX
1949 | UVC_QUIRK_IGNORE_SELECTOR_UNIT 1949 | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
1950 | UVC_QUIRK_PRUNE_CONTROLS },
1951 /* Generic USB Video Class */ 1950 /* Generic USB Video Class */
1952 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1951 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
1953 {} 1952 {}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index daf074447304..f435e8eeccd2 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -313,7 +313,6 @@ struct uvc_xu_control {
313#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 313#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
314#define UVC_QUIRK_STREAM_NO_FID 0x00000010 314#define UVC_QUIRK_STREAM_NO_FID 0x00000010
315#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 315#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
316#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
317#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 316#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
318 317
319/* Format flags */ 318/* Format flags */