aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_ctrl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-17 00:15:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-17 00:15:42 -0400
commit0dd5198672dd2bbeb933862e1fc82162e0b636be (patch)
treec9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media/video/uvc/uvc_ctrl.c
parentc868d550115b9ccc0027c67265b9520790f05601 (diff)
parent11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits) V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added. V4L/DVB (12004): poll method lose race condition V4L/DVB (11894): flexcop-pci: dmesg visible names broken V4L/DVB (11892): Siano: smsendian - declare function as extern V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol V4L/DVB (11890): Siano: smscore - remove redundant code V4L/DVB (11889): Siano: smsdvb - add DVB v3 events V4L/DVB (11888): Siano: smsusb - remove redundant ifdef V4L/DVB (11887): Siano: smscards - add board (target) events V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names V4L/DVB (11885): Siano: Add new GPIO management interface V4L/DVB (11884): Siano: smssdio - revert to stand alone module V4L/DVB (11883): Siano: cards - add two additional (USB) devices V4L/DVB (11824): Siano: smsusb - change exit func debug msg V4L/DVB (11823): Siano: smsusb - fix typo in module description V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name V4L/DVB (11820): Siano: smscore - fix byte ordering bug V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets ...
Diffstat (limited to 'drivers/media/video/uvc/uvc_ctrl.c')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c35
1 files changed, 15 insertions, 20 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]);