diff options
author | Laurent Pinchart <laurent.pinchart@skynet.be> | 2009-05-31 16:05:55 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 18:07:29 -0400 |
commit | d732c44c1a4b54e3c59ad92069bc2fd848aca5f3 (patch) | |
tree | d78fc6b272b69a0772de85720e68808a415eb611 /drivers/media/video/uvc | |
parent | 926b3b4122e4ebca52e67eecf9beb9a517e593f4 (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.c | 35 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 3 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 1 |
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 | */ |
1380 | static void | 1379 | static void |
1381 | uvc_ctrl_prune_entity(struct uvc_entity *entity) | 1380 | uvc_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 */ |