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 /* ------------------------------------------------------------------------
23 * Video subdevices registration and unregistration
26 static int uvc_mc_register_entity(struct uvc_video_chain
*chain
,
27 struct uvc_entity
*entity
)
29 const u32 flags
= MEDIA_LNK_FL_ENABLED
| MEDIA_LNK_FL_IMMUTABLE
;
30 struct media_entity
*sink
;
34 sink
= (UVC_ENTITY_TYPE(entity
) == UVC_TT_STREAMING
)
35 ? (entity
->vdev
? &entity
->vdev
->entity
: NULL
)
36 : &entity
->subdev
.entity
;
40 for (i
= 0; i
< entity
->num_pads
; ++i
) {
41 struct media_entity
*source
;
42 struct uvc_entity
*remote
;
45 if (!(entity
->pads
[i
].flags
& MEDIA_PAD_FL_SINK
))
48 remote
= uvc_entity_by_id(chain
->dev
, entity
->baSourceID
[i
]);
52 source
= (UVC_ENTITY_TYPE(remote
) == UVC_TT_STREAMING
)
53 ? (remote
->vdev
? &remote
->vdev
->entity
: NULL
)
54 : &remote
->subdev
.entity
;
58 remote_pad
= remote
->num_pads
- 1;
59 ret
= media_entity_create_link(source
, remote_pad
,
65 if (UVC_ENTITY_TYPE(entity
) == UVC_TT_STREAMING
)
68 return v4l2_device_register_subdev(&chain
->dev
->vdev
, &entity
->subdev
);
71 static struct v4l2_subdev_ops uvc_subdev_ops
= {
74 void uvc_mc_cleanup_entity(struct uvc_entity
*entity
)
76 if (UVC_ENTITY_TYPE(entity
) != UVC_TT_STREAMING
)
77 media_entity_cleanup(&entity
->subdev
.entity
);
78 else if (entity
->vdev
!= NULL
)
79 media_entity_cleanup(&entity
->vdev
->entity
);
82 static int uvc_mc_init_entity(struct uvc_entity
*entity
)
86 if (UVC_ENTITY_TYPE(entity
) != UVC_TT_STREAMING
) {
87 v4l2_subdev_init(&entity
->subdev
, &uvc_subdev_ops
);
88 strlcpy(entity
->subdev
.name
, entity
->name
,
89 sizeof(entity
->subdev
.name
));
91 ret
= media_entity_init(&entity
->subdev
.entity
,
92 entity
->num_pads
, entity
->pads
, 0);
93 } else if (entity
->vdev
!= NULL
) {
94 ret
= media_entity_init(&entity
->vdev
->entity
,
95 entity
->num_pads
, entity
->pads
, 0);
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(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_register_entity(chain
, entity
);
121 uvc_printk(KERN_INFO
, "Failed to register entity for "
122 "entity %u\n", entity
->id
);