diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2010-01-21 06:56:19 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-25 18:51:09 -0400 |
commit | 8a65a9485832f90e18e2f7069b75a4181e2840c0 (patch) | |
tree | 151551e14937c7b1a2d28e738eed3ee154486497 /drivers | |
parent | 4ffc2d89f38a7fbb3b24adb7fb066a159c351c11 (diff) |
[media] uvcvideo: Connect video devices to media entities
The video devices associated to USB streaming terminals must be
connected to their associated terminal's media entity instead of being
standalone entities.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 8 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_entity.c | 40 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 1 |
3 files changed, 39 insertions, 10 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 0bf3413e8d37..b6eae48d7fb8 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1616,6 +1616,10 @@ static void uvc_delete(struct uvc_device *dev) | |||
1616 | #ifdef CONFIG_MEDIA_CONTROLLER | 1616 | #ifdef CONFIG_MEDIA_CONTROLLER |
1617 | uvc_mc_cleanup_entity(entity); | 1617 | uvc_mc_cleanup_entity(entity); |
1618 | #endif | 1618 | #endif |
1619 | if (entity->vdev) { | ||
1620 | video_device_release(entity->vdev); | ||
1621 | entity->vdev = NULL; | ||
1622 | } | ||
1619 | kfree(entity); | 1623 | kfree(entity); |
1620 | } | 1624 | } |
1621 | 1625 | ||
@@ -1638,8 +1642,6 @@ static void uvc_release(struct video_device *vdev) | |||
1638 | struct uvc_streaming *stream = video_get_drvdata(vdev); | 1642 | struct uvc_streaming *stream = video_get_drvdata(vdev); |
1639 | struct uvc_device *dev = stream->dev; | 1643 | struct uvc_device *dev = stream->dev; |
1640 | 1644 | ||
1641 | video_device_release(vdev); | ||
1642 | |||
1643 | /* Decrement the registered streams count and delete the device when it | 1645 | /* Decrement the registered streams count and delete the device when it |
1644 | * reaches zero. | 1646 | * reaches zero. |
1645 | */ | 1647 | */ |
@@ -1753,6 +1755,8 @@ static int uvc_register_terms(struct uvc_device *dev, | |||
1753 | ret = uvc_register_video(dev, stream); | 1755 | ret = uvc_register_video(dev, stream); |
1754 | if (ret < 0) | 1756 | if (ret < 0) |
1755 | return ret; | 1757 | return ret; |
1758 | |||
1759 | term->vdev = stream->vdev; | ||
1756 | } | 1760 | } |
1757 | 1761 | ||
1758 | return 0; | 1762 | return 0; |
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c index 8e8e7efb4608..ede7852bb1df 100644 --- a/drivers/media/video/uvc/uvc_entity.c +++ b/drivers/media/video/uvc/uvc_entity.c | |||
@@ -33,6 +33,9 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
33 | int ret; | 33 | int ret; |
34 | 34 | ||
35 | for (i = 0; i < entity->num_pads; ++i) { | 35 | for (i = 0; i < entity->num_pads; ++i) { |
36 | struct media_entity *source; | ||
37 | struct media_entity *sink; | ||
38 | |||
36 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) | 39 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) |
37 | continue; | 40 | continue; |
38 | 41 | ||
@@ -40,14 +43,23 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
40 | if (remote == NULL) | 43 | if (remote == NULL) |
41 | return -EINVAL; | 44 | return -EINVAL; |
42 | 45 | ||
46 | source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) | ||
47 | ? &remote->vdev->entity : &remote->subdev.entity; | ||
48 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) | ||
49 | ? &entity->vdev->entity : &entity->subdev.entity; | ||
50 | |||
43 | remote_pad = remote->num_pads - 1; | 51 | remote_pad = remote->num_pads - 1; |
44 | ret = media_entity_create_link(&remote->subdev.entity, | 52 | ret = media_entity_create_link(source, remote_pad, |
45 | remote_pad, &entity->subdev.entity, i, flags); | 53 | sink, i, flags); |
46 | if (ret < 0) | 54 | if (ret < 0) |
47 | return ret; | 55 | return ret; |
48 | } | 56 | } |
49 | 57 | ||
50 | return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); | 58 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) |
59 | ret = v4l2_device_register_subdev(&chain->dev->vdev, | ||
60 | &entity->subdev); | ||
61 | |||
62 | return ret; | ||
51 | } | 63 | } |
52 | 64 | ||
53 | static struct v4l2_subdev_ops uvc_subdev_ops = { | 65 | static struct v4l2_subdev_ops uvc_subdev_ops = { |
@@ -55,16 +67,28 @@ static struct v4l2_subdev_ops uvc_subdev_ops = { | |||
55 | 67 | ||
56 | void uvc_mc_cleanup_entity(struct uvc_entity *entity) | 68 | void uvc_mc_cleanup_entity(struct uvc_entity *entity) |
57 | { | 69 | { |
58 | media_entity_cleanup(&entity->subdev.entity); | 70 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) |
71 | media_entity_cleanup(&entity->subdev.entity); | ||
72 | else if (entity->vdev != NULL) | ||
73 | media_entity_cleanup(&entity->vdev->entity); | ||
59 | } | 74 | } |
60 | 75 | ||
61 | static int uvc_mc_init_entity(struct uvc_entity *entity) | 76 | static int uvc_mc_init_entity(struct uvc_entity *entity) |
62 | { | 77 | { |
63 | v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops); | 78 | int ret; |
64 | strlcpy(entity->subdev.name, entity->name, sizeof(entity->subdev.name)); | 79 | |
80 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) { | ||
81 | v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops); | ||
82 | strlcpy(entity->subdev.name, entity->name, | ||
83 | sizeof(entity->subdev.name)); | ||
84 | |||
85 | ret = media_entity_init(&entity->subdev.entity, | ||
86 | entity->num_pads, entity->pads, 0); | ||
87 | } else | ||
88 | ret = media_entity_init(&entity->vdev->entity, | ||
89 | entity->num_pads, entity->pads, 0); | ||
65 | 90 | ||
66 | return media_entity_init(&entity->subdev.entity, entity->num_pads, | 91 | return ret; |
67 | entity->pads, 0); | ||
68 | } | 92 | } |
69 | 93 | ||
70 | int uvc_mc_register_entities(struct uvc_video_chain *chain) | 94 | int uvc_mc_register_entities(struct uvc_video_chain *chain) |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 3906f6ed4061..20107fd3574d 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -305,6 +305,7 @@ struct uvc_entity { | |||
305 | char name[64]; | 305 | char name[64]; |
306 | 306 | ||
307 | /* Media controller-related fields. */ | 307 | /* Media controller-related fields. */ |
308 | struct video_device *vdev; | ||
308 | struct v4l2_subdev subdev; | 309 | struct v4l2_subdev subdev; |
309 | unsigned int num_pads; | 310 | unsigned int num_pads; |
310 | unsigned int num_links; | 311 | unsigned int num_links; |