aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb/uvc/uvc_driver.c')
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c118
1 files changed, 112 insertions, 6 deletions
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 5cefca95734e..885f689ac870 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain)
1595 return buffer; 1595 return buffer;
1596} 1596}
1597 1597
1598static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev)
1599{
1600 struct uvc_video_chain *chain;
1601
1602 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1603 if (chain == NULL)
1604 return NULL;
1605
1606 INIT_LIST_HEAD(&chain->entities);
1607 mutex_init(&chain->ctrl_mutex);
1608 chain->dev = dev;
1609 v4l2_prio_init(&chain->prio);
1610
1611 return chain;
1612}
1613
1614/*
1615 * Fallback heuristic for devices that don't connect units and terminals in a
1616 * valid chain.
1617 *
1618 * Some devices have invalid baSourceID references, causing uvc_scan_chain()
1619 * to fail, but if we just take the entities we can find and put them together
1620 * in the most sensible chain we can think of, turns out they do work anyway.
1621 * Note: This heuristic assumes there is a single chain.
1622 *
1623 * At the time of writing, devices known to have such a broken chain are
1624 * - Acer Integrated Camera (5986:055a)
1625 * - Realtek rtl157a7 (0bda:57a7)
1626 */
1627static int uvc_scan_fallback(struct uvc_device *dev)
1628{
1629 struct uvc_video_chain *chain;
1630 struct uvc_entity *iterm = NULL;
1631 struct uvc_entity *oterm = NULL;
1632 struct uvc_entity *entity;
1633 struct uvc_entity *prev;
1634
1635 /*
1636 * Start by locating the input and output terminals. We only support
1637 * devices with exactly one of each for now.
1638 */
1639 list_for_each_entry(entity, &dev->entities, list) {
1640 if (UVC_ENTITY_IS_ITERM(entity)) {
1641 if (iterm)
1642 return -EINVAL;
1643 iterm = entity;
1644 }
1645
1646 if (UVC_ENTITY_IS_OTERM(entity)) {
1647 if (oterm)
1648 return -EINVAL;
1649 oterm = entity;
1650 }
1651 }
1652
1653 if (iterm == NULL || oterm == NULL)
1654 return -EINVAL;
1655
1656 /* Allocate the chain and fill it. */
1657 chain = uvc_alloc_chain(dev);
1658 if (chain == NULL)
1659 return -ENOMEM;
1660
1661 if (uvc_scan_chain_entity(chain, oterm) < 0)
1662 goto error;
1663
1664 prev = oterm;
1665
1666 /*
1667 * Add all Processing and Extension Units with two pads. The order
1668 * doesn't matter much, use reverse list traversal to connect units in
1669 * UVC descriptor order as we build the chain from output to input. This
1670 * leads to units appearing in the order meant by the manufacturer for
1671 * the cameras known to require this heuristic.
1672 */
1673 list_for_each_entry_reverse(entity, &dev->entities, list) {
1674 if (entity->type != UVC_VC_PROCESSING_UNIT &&
1675 entity->type != UVC_VC_EXTENSION_UNIT)
1676 continue;
1677
1678 if (entity->num_pads != 2)
1679 continue;
1680
1681 if (uvc_scan_chain_entity(chain, entity) < 0)
1682 goto error;
1683
1684 prev->baSourceID[0] = entity->id;
1685 prev = entity;
1686 }
1687
1688 if (uvc_scan_chain_entity(chain, iterm) < 0)
1689 goto error;
1690
1691 prev->baSourceID[0] = iterm->id;
1692
1693 list_add_tail(&chain->list, &dev->chains);
1694
1695 uvc_trace(UVC_TRACE_PROBE,
1696 "Found a video chain by fallback heuristic (%s).\n",
1697 uvc_print_chain(chain));
1698
1699 return 0;
1700
1701error:
1702 kfree(chain);
1703 return -EINVAL;
1704}
1705
1598/* 1706/*
1599 * Scan the device for video chains and register video devices. 1707 * Scan the device for video chains and register video devices.
1600 * 1708 *
@@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev)
1617 if (term->chain.next || term->chain.prev) 1725 if (term->chain.next || term->chain.prev)
1618 continue; 1726 continue;
1619 1727
1620 chain = kzalloc(sizeof(*chain), GFP_KERNEL); 1728 chain = uvc_alloc_chain(dev);
1621 if (chain == NULL) 1729 if (chain == NULL)
1622 return -ENOMEM; 1730 return -ENOMEM;
1623 1731
1624 INIT_LIST_HEAD(&chain->entities);
1625 mutex_init(&chain->ctrl_mutex);
1626 chain->dev = dev;
1627 v4l2_prio_init(&chain->prio);
1628
1629 term->flags |= UVC_ENTITY_FLAG_DEFAULT; 1732 term->flags |= UVC_ENTITY_FLAG_DEFAULT;
1630 1733
1631 if (uvc_scan_chain(chain, term) < 0) { 1734 if (uvc_scan_chain(chain, term) < 0) {
@@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev)
1639 list_add_tail(&chain->list, &dev->chains); 1742 list_add_tail(&chain->list, &dev->chains);
1640 } 1743 }
1641 1744
1745 if (list_empty(&dev->chains))
1746 uvc_scan_fallback(dev);
1747
1642 if (list_empty(&dev->chains)) { 1748 if (list_empty(&dev->chains)) {
1643 uvc_printk(KERN_INFO, "No valid video chain found.\n"); 1749 uvc_printk(KERN_INFO, "No valid video chain found.\n");
1644 return -1; 1750 return -1;