2 * uvc_entity.c -- USB Video Class driver
4 * Copyright (C) 2005-2011
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
14 #include <linux/kernel.h>
15 #include <linux/list.h>
16 #include <linux/videodev2.h>
18 #include <media/v4l2-common.h>
22 static int uvc_mc_create_links(struct uvc_video_chain
*chain
,
23 struct uvc_entity
*entity
)
25 const u32 flags
= MEDIA_LNK_FL_ENABLED
| MEDIA_LNK_FL_IMMUTABLE
;
26 struct media_entity
*sink
;
30 sink
= (UVC_ENTITY_TYPE(entity
) == UVC_TT_STREAMING
)
31 ? (entity
->vdev
? &entity
->vdev
->entity
: NULL
)
32 : &entity
->subdev
.entity
;
36 for (i
= 0; i
< entity
->num_pads
; ++i
) {
37 struct media_entity
*source
;
38 struct uvc_entity
*remote
;
41 if (!(entity
->pads
[i
].flags
& MEDIA_PAD_FL_SINK
))
44 remote
= uvc_entity_by_id(chain
->dev
, entity
->baSourceID
[i
]);
48 source
= (UVC_ENTITY_TYPE(remote
) == UVC_TT_STREAMING
)
49 ? (remote
->vdev
? &remote
->vdev
->entity
: NULL
)
50 : &remote
->subdev
.entity
;
54 remote_pad
= remote
->num_pads
- 1;
55 ret
= media_create_pad_link(source
, remote_pad
,
64 static const struct v4l2_subdev_ops uvc_subdev_ops
= {
67 void uvc_mc_cleanup_entity(struct uvc_entity
*entity
)
69 if (UVC_ENTITY_TYPE(entity
) != UVC_TT_STREAMING
)
70 media_entity_cleanup(&entity
->subdev
.entity
);
71 else if (entity
->vdev
!= NULL
)
72 media_entity_cleanup(&entity
->vdev
->entity
);
75 static int uvc_mc_init_entity(struct uvc_video_chain
*chain
,
76 struct uvc_entity
*entity
)
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
));
85 ret
= media_entity_pads_init(&entity
->subdev
.entity
,
86 entity
->num_pads
, entity
->pads
);
91 ret
= v4l2_device_register_subdev(&chain
->dev
->vdev
,
93 } else if (entity
->vdev
!= NULL
) {
94 ret
= media_entity_pads_init(&entity
->vdev
->entity
,
95 entity
->num_pads
, entity
->pads
);
96 if (entity
->flags
& UVC_ENTITY_FLAG_DEFAULT
)
97 entity
->vdev
->entity
.flags
|= MEDIA_ENT_FL_DEFAULT
;
104 int uvc_mc_register_entities(struct uvc_video_chain
*chain
)
106 struct uvc_entity
*entity
;
109 list_for_each_entry(entity
, &chain
->entities
, chain
) {
110 ret
= uvc_mc_init_entity(chain
, entity
);
112 uvc_printk(KERN_INFO
, "Failed to initialize entity for "
113 "entity %u\n", entity
->id
);
118 list_for_each_entry(entity
, &chain
->entities
, chain
) {
119 ret
= uvc_mc_create_links(chain
, entity
);
121 uvc_printk(KERN_INFO
, "Failed to create links for "
122 "entity %u\n", entity
->id
);