aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc/uvc_driver.c')
-rw-r--r--drivers/media/video/uvc/uvc_driver.c66
1 files changed, 59 insertions, 7 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 823f4b389745..b6eae48d7fb8 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -248,7 +248,7 @@ uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator)
248 * Terminal and unit management 248 * Terminal and unit management
249 */ 249 */
250 250
251static struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id) 251struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
252{ 252{
253 struct uvc_entity *entity; 253 struct uvc_entity *entity;
254 254
@@ -795,9 +795,12 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
795 struct uvc_entity *entity; 795 struct uvc_entity *entity;
796 unsigned int num_inputs; 796 unsigned int num_inputs;
797 unsigned int size; 797 unsigned int size;
798 unsigned int i;
798 799
800 extra_size = ALIGN(extra_size, sizeof(*entity->pads));
799 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1; 801 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
800 size = sizeof(*entity) + extra_size + num_inputs; 802 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
803 + num_inputs;
801 entity = kzalloc(size, GFP_KERNEL); 804 entity = kzalloc(size, GFP_KERNEL);
802 if (entity == NULL) 805 if (entity == NULL)
803 return NULL; 806 return NULL;
@@ -805,8 +808,17 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
805 entity->id = id; 808 entity->id = id;
806 entity->type = type; 809 entity->type = type;
807 810
811 entity->num_links = 0;
812 entity->num_pads = num_pads;
813 entity->pads = ((void *)(entity + 1)) + extra_size;
814
815 for (i = 0; i < num_inputs; ++i)
816 entity->pads[i].flags = MEDIA_PAD_FL_SINK;
817 if (!UVC_ENTITY_IS_OTERM(entity))
818 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
819
808 entity->bNrInPins = num_inputs; 820 entity->bNrInPins = num_inputs;
809 entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size; 821 entity->baSourceID = (__u8 *)(&entity->pads[num_pads]);
810 822
811 return entity; 823 return entity;
812} 824}
@@ -1585,6 +1597,13 @@ static void uvc_delete(struct uvc_device *dev)
1585 uvc_status_cleanup(dev); 1597 uvc_status_cleanup(dev);
1586 uvc_ctrl_cleanup_device(dev); 1598 uvc_ctrl_cleanup_device(dev);
1587 1599
1600 if (dev->vdev.dev)
1601 v4l2_device_unregister(&dev->vdev);
1602#ifdef CONFIG_MEDIA_CONTROLLER
1603 if (media_devnode_is_registered(&dev->mdev.devnode))
1604 media_device_unregister(&dev->mdev);
1605#endif
1606
1588 list_for_each_safe(p, n, &dev->chains) { 1607 list_for_each_safe(p, n, &dev->chains) {
1589 struct uvc_video_chain *chain; 1608 struct uvc_video_chain *chain;
1590 chain = list_entry(p, struct uvc_video_chain, list); 1609 chain = list_entry(p, struct uvc_video_chain, list);
@@ -1594,6 +1613,13 @@ static void uvc_delete(struct uvc_device *dev)
1594 list_for_each_safe(p, n, &dev->entities) { 1613 list_for_each_safe(p, n, &dev->entities) {
1595 struct uvc_entity *entity; 1614 struct uvc_entity *entity;
1596 entity = list_entry(p, struct uvc_entity, list); 1615 entity = list_entry(p, struct uvc_entity, list);
1616#ifdef CONFIG_MEDIA_CONTROLLER
1617 uvc_mc_cleanup_entity(entity);
1618#endif
1619 if (entity->vdev) {
1620 video_device_release(entity->vdev);
1621 entity->vdev = NULL;
1622 }
1597 kfree(entity); 1623 kfree(entity);
1598 } 1624 }
1599 1625
@@ -1616,8 +1642,6 @@ static void uvc_release(struct video_device *vdev)
1616 struct uvc_streaming *stream = video_get_drvdata(vdev); 1642 struct uvc_streaming *stream = video_get_drvdata(vdev);
1617 struct uvc_device *dev = stream->dev; 1643 struct uvc_device *dev = stream->dev;
1618 1644
1619 video_device_release(vdev);
1620
1621 /* Decrement the registered streams count and delete the device when it 1645 /* Decrement the registered streams count and delete the device when it
1622 * reaches zero. 1646 * reaches zero.
1623 */ 1647 */
@@ -1682,7 +1706,7 @@ static int uvc_register_video(struct uvc_device *dev,
1682 * unregistered before the reference is released, so we don't need to 1706 * unregistered before the reference is released, so we don't need to
1683 * get another one. 1707 * get another one.
1684 */ 1708 */
1685 vdev->parent = &dev->intf->dev; 1709 vdev->v4l2_dev = &dev->vdev;
1686 vdev->fops = &uvc_fops; 1710 vdev->fops = &uvc_fops;
1687 vdev->release = uvc_release; 1711 vdev->release = uvc_release;
1688 strlcpy(vdev->name, dev->name, sizeof vdev->name); 1712 strlcpy(vdev->name, dev->name, sizeof vdev->name);
@@ -1731,6 +1755,8 @@ static int uvc_register_terms(struct uvc_device *dev,
1731 ret = uvc_register_video(dev, stream); 1755 ret = uvc_register_video(dev, stream);
1732 if (ret < 0) 1756 if (ret < 0)
1733 return ret; 1757 return ret;
1758
1759 term->vdev = stream->vdev;
1734 } 1760 }
1735 1761
1736 return 0; 1762 return 0;
@@ -1745,6 +1771,14 @@ static int uvc_register_chains(struct uvc_device *dev)
1745 ret = uvc_register_terms(dev, chain); 1771 ret = uvc_register_terms(dev, chain);
1746 if (ret < 0) 1772 if (ret < 0)
1747 return ret; 1773 return ret;
1774
1775#ifdef CONFIG_MEDIA_CONTROLLER
1776 ret = uvc_mc_register_entities(chain);
1777 if (ret < 0) {
1778 uvc_printk(KERN_INFO, "Failed to register entites "
1779 "(%d).\n", ret);
1780 }
1781#endif
1748 } 1782 }
1749 1783
1750 return 0; 1784 return 0;
@@ -1814,6 +1848,24 @@ static int uvc_probe(struct usb_interface *intf,
1814 "linux-uvc-devel mailing list.\n"); 1848 "linux-uvc-devel mailing list.\n");
1815 } 1849 }
1816 1850
1851 /* Register the media and V4L2 devices. */
1852#ifdef CONFIG_MEDIA_CONTROLLER
1853 dev->mdev.dev = &intf->dev;
1854 strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
1855 if (udev->serial)
1856 strlcpy(dev->mdev.serial, udev->serial,
1857 sizeof(dev->mdev.serial));
1858 strcpy(dev->mdev.bus_info, udev->devpath);
1859 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
1860 dev->mdev.driver_version = DRIVER_VERSION_NUMBER;
1861 if (media_device_register(&dev->mdev) < 0)
1862 goto error;
1863
1864 dev->vdev.mdev = &dev->mdev;
1865#endif
1866 if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
1867 goto error;
1868
1817 /* Initialize controls. */ 1869 /* Initialize controls. */
1818 if (uvc_ctrl_init_device(dev) < 0) 1870 if (uvc_ctrl_init_device(dev) < 0)
1819 goto error; 1871 goto error;
@@ -1822,7 +1874,7 @@ static int uvc_probe(struct usb_interface *intf,
1822 if (uvc_scan_device(dev) < 0) 1874 if (uvc_scan_device(dev) < 0)
1823 goto error; 1875 goto error;
1824 1876
1825 /* Register video devices. */ 1877 /* Register video device nodes. */
1826 if (uvc_register_chains(dev) < 0) 1878 if (uvc_register_chains(dev) < 0)
1827 goto error; 1879 goto error;
1828 1880