diff options
-rw-r--r-- | Documentation/DocBook/v4l/media-controller.xml | 20 | ||||
-rw-r--r-- | Documentation/media-framework.txt | 151 | ||||
-rw-r--r-- | drivers/media/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/media-device.c | 56 | ||||
-rw-r--r-- | drivers/media/media-entity.c | 147 | ||||
-rw-r--r-- | include/media/media-device.h | 19 | ||||
-rw-r--r-- | include/media/media-entity.h | 122 |
7 files changed, 516 insertions, 1 deletions
diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml index 253ddb4426c9..f89228d3ec2a 100644 --- a/Documentation/DocBook/v4l/media-controller.xml +++ b/Documentation/DocBook/v4l/media-controller.xml | |||
@@ -53,4 +53,24 @@ | |||
53 | implementing policies that belong to userspace.</para> | 53 | implementing policies that belong to userspace.</para> |
54 | <para>The media controller API aims at solving those problems.</para> | 54 | <para>The media controller API aims at solving those problems.</para> |
55 | </section> | 55 | </section> |
56 | |||
57 | <section id="media-controller-model"> | ||
58 | <title>Media device model</title> | ||
59 | <para>Discovering a device internal topology, and configuring it at runtime, | ||
60 | is one of the goals of the media controller API. To achieve this, hardware | ||
61 | devices are modelled as an oriented graph of building blocks called entities | ||
62 | connected through pads.</para> | ||
63 | <para>An entity is a basic media hardware or software building block. It can | ||
64 | correspond to a large variety of logical blocks such as physical hardware | ||
65 | devices (CMOS sensor for instance), logical hardware devices (a building | ||
66 | block in a System-on-Chip image processing pipeline), DMA channels or | ||
67 | physical connectors.</para> | ||
68 | <para>A pad is a connection endpoint through which an entity can interact | ||
69 | with other entities. Data (not restricted to video) produced by an entity | ||
70 | flows from the entity's output to one or more entity inputs. Pads should not | ||
71 | be confused with physical pins at chip boundaries.</para> | ||
72 | <para>A link is a point-to-point oriented connection between two pads, | ||
73 | either on the same entity or on different entities. Data flows from a source | ||
74 | pad to a sink pad.</para> | ||
75 | </section> | ||
56 | </chapter> | 76 | </chapter> |
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index 1844c3f10728..0257bad2a104 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt | |||
@@ -13,6 +13,30 @@ Documentation/DocBook/v4l/media-controller.xml. This document will focus on | |||
13 | the kernel-side implementation of the media framework. | 13 | the kernel-side implementation of the media framework. |
14 | 14 | ||
15 | 15 | ||
16 | Abstract media device model | ||
17 | --------------------------- | ||
18 | |||
19 | Discovering a device internal topology, and configuring it at runtime, is one | ||
20 | of the goals of the media framework. To achieve this, hardware devices are | ||
21 | modeled as an oriented graph of building blocks called entities connected | ||
22 | through pads. | ||
23 | |||
24 | An entity is a basic media hardware building block. It can correspond to | ||
25 | a large variety of logical blocks such as physical hardware devices | ||
26 | (CMOS sensor for instance), logical hardware devices (a building block | ||
27 | in a System-on-Chip image processing pipeline), DMA channels or physical | ||
28 | connectors. | ||
29 | |||
30 | A pad is a connection endpoint through which an entity can interact with | ||
31 | other entities. Data (not restricted to video) produced by an entity | ||
32 | flows from the entity's output to one or more entity inputs. Pads should | ||
33 | not be confused with physical pins at chip boundaries. | ||
34 | |||
35 | A link is a point-to-point oriented connection between two pads, either | ||
36 | on the same entity or on different entities. Data flows from a source | ||
37 | pad to a sink pad. | ||
38 | |||
39 | |||
16 | Media device | 40 | Media device |
17 | ------------ | 41 | ------------ |
18 | 42 | ||
@@ -65,3 +89,130 @@ Drivers unregister media device instances by calling | |||
65 | media_device_unregister(struct media_device *mdev); | 89 | media_device_unregister(struct media_device *mdev); |
66 | 90 | ||
67 | Unregistering a media device that hasn't been registered is *NOT* safe. | 91 | Unregistering a media device that hasn't been registered is *NOT* safe. |
92 | |||
93 | |||
94 | Entities, pads and links | ||
95 | ------------------------ | ||
96 | |||
97 | - Entities | ||
98 | |||
99 | Entities are represented by a struct media_entity instance, defined in | ||
100 | include/media/media-entity.h. The structure is usually embedded into a | ||
101 | higher-level structure, such as a v4l2_subdev or video_device instance, | ||
102 | although drivers can allocate entities directly. | ||
103 | |||
104 | Drivers initialize entities by calling | ||
105 | |||
106 | media_entity_init(struct media_entity *entity, u16 num_pads, | ||
107 | struct media_pad *pads, u16 extra_links); | ||
108 | |||
109 | The media_entity name, type, flags, revision and group_id fields can be | ||
110 | initialized before or after calling media_entity_init. Entities embedded in | ||
111 | higher-level standard structures can have some of those fields set by the | ||
112 | higher-level framework. | ||
113 | |||
114 | As the number of pads is known in advance, the pads array is not allocated | ||
115 | dynamically but is managed by the entity driver. Most drivers will embed the | ||
116 | pads array in a driver-specific structure, avoiding dynamic allocation. | ||
117 | |||
118 | Drivers must set the direction of every pad in the pads array before calling | ||
119 | media_entity_init. The function will initialize the other pads fields. | ||
120 | |||
121 | Unlike the number of pads, the total number of links isn't always known in | ||
122 | advance by the entity driver. As an initial estimate, media_entity_init | ||
123 | pre-allocates a number of links equal to the number of pads plus an optional | ||
124 | number of extra links. The links array will be reallocated if it grows beyond | ||
125 | the initial estimate. | ||
126 | |||
127 | Drivers register entities with a media device by calling | ||
128 | |||
129 | media_device_register_entity(struct media_device *mdev, | ||
130 | struct media_entity *entity); | ||
131 | |||
132 | Entities are identified by a unique positive integer ID. Drivers can provide an | ||
133 | ID by filling the media_entity id field prior to registration, or request the | ||
134 | media controller framework to assign an ID automatically. Drivers that provide | ||
135 | IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be | ||
136 | contiguous even when they are all assigned automatically by the framework. | ||
137 | |||
138 | Drivers unregister entities by calling | ||
139 | |||
140 | media_device_unregister_entity(struct media_entity *entity); | ||
141 | |||
142 | Unregistering an entity will not change the IDs of the other entities, and the | ||
143 | ID will never be reused for a newly registered entity. | ||
144 | |||
145 | When a media device is unregistered, all its entities are unregistered | ||
146 | automatically. No manual entities unregistration is then required. | ||
147 | |||
148 | Drivers free resources associated with an entity by calling | ||
149 | |||
150 | media_entity_cleanup(struct media_entity *entity); | ||
151 | |||
152 | This function must be called during the cleanup phase after unregistering the | ||
153 | entity. Note that the media_entity instance itself must be freed explicitly by | ||
154 | the driver if required. | ||
155 | |||
156 | Entities have flags that describe the entity capabilities and state. | ||
157 | |||
158 | MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. | ||
159 | This can be used to report the default audio and video devices or the | ||
160 | default camera sensor. | ||
161 | |||
162 | Logical entity groups can be defined by setting the group ID of all member | ||
163 | entities to the same non-zero value. An entity group serves no purpose in the | ||
164 | kernel, but is reported to userspace during entities enumeration. The group_id | ||
165 | field belongs to the media device driver and must not by touched by entity | ||
166 | drivers. | ||
167 | |||
168 | Media device drivers should define groups if several entities are logically | ||
169 | bound together. Example usages include reporting | ||
170 | |||
171 | - ALSA, VBI and video nodes that carry the same media stream | ||
172 | - lens and flash controllers associated with a sensor | ||
173 | |||
174 | - Pads | ||
175 | |||
176 | Pads are represented by a struct media_pad instance, defined in | ||
177 | include/media/media-entity.h. Each entity stores its pads in a pads array | ||
178 | managed by the entity driver. Drivers usually embed the array in a | ||
179 | driver-specific structure. | ||
180 | |||
181 | Pads are identified by their entity and their 0-based index in the pads array. | ||
182 | Both information are stored in the media_pad structure, making the media_pad | ||
183 | pointer the canonical way to store and pass link references. | ||
184 | |||
185 | Pads have flags that describe the pad capabilities and state. | ||
186 | |||
187 | MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. | ||
188 | MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. | ||
189 | |||
190 | One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for | ||
191 | each pad. | ||
192 | |||
193 | - Links | ||
194 | |||
195 | Links are represented by a struct media_link instance, defined in | ||
196 | include/media/media-entity.h. Each entity stores all links originating at or | ||
197 | targetting any of its pads in a links array. A given link is thus stored | ||
198 | twice, once in the source entity and once in the target entity. The array is | ||
199 | pre-allocated and grows dynamically as needed. | ||
200 | |||
201 | Drivers create links by calling | ||
202 | |||
203 | media_entity_create_link(struct media_entity *source, u16 source_pad, | ||
204 | struct media_entity *sink, u16 sink_pad, | ||
205 | u32 flags); | ||
206 | |||
207 | An entry in the link array of each entity is allocated and stores pointers | ||
208 | to source and sink pads. | ||
209 | |||
210 | Links have flags that describe the link capabilities and state. | ||
211 | |||
212 | MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used | ||
213 | to transfer media data. When two or more links target a sink pad, only | ||
214 | one of them can be enabled at a time. | ||
215 | MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be | ||
216 | modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then | ||
217 | MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always | ||
218 | enabled. | ||
diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 36731aae57ea..64755c99ded2 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the kernel multimedia device drivers. | 2 | # Makefile for the kernel multimedia device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | media-objs := media-device.o media-devnode.o | 5 | media-objs := media-device.o media-devnode.o media-entity.o |
6 | 6 | ||
7 | ifeq ($(CONFIG_MEDIA_CONTROLLER),y) | 7 | ifeq ($(CONFIG_MEDIA_CONTROLLER),y) |
8 | obj-$(CONFIG_MEDIA_SUPPORT) += media.o | 8 | obj-$(CONFIG_MEDIA_SUPPORT) += media.o |
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index bcd3985d415a..a36509a1df09 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <media/media-device.h> | 26 | #include <media/media-device.h> |
27 | #include <media/media-devnode.h> | 27 | #include <media/media-devnode.h> |
28 | #include <media/media-entity.h> | ||
28 | 29 | ||
29 | static const struct media_file_operations media_device_fops = { | 30 | static const struct media_file_operations media_device_fops = { |
30 | .owner = THIS_MODULE, | 31 | .owner = THIS_MODULE, |
@@ -69,6 +70,10 @@ int __must_check media_device_register(struct media_device *mdev) | |||
69 | if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) | 70 | if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) |
70 | return -EINVAL; | 71 | return -EINVAL; |
71 | 72 | ||
73 | mdev->entity_id = 1; | ||
74 | INIT_LIST_HEAD(&mdev->entities); | ||
75 | spin_lock_init(&mdev->lock); | ||
76 | |||
72 | /* Register the device node. */ | 77 | /* Register the device node. */ |
73 | mdev->devnode.fops = &media_device_fops; | 78 | mdev->devnode.fops = &media_device_fops; |
74 | mdev->devnode.parent = mdev->dev; | 79 | mdev->devnode.parent = mdev->dev; |
@@ -94,7 +99,58 @@ EXPORT_SYMBOL_GPL(media_device_register); | |||
94 | */ | 99 | */ |
95 | void media_device_unregister(struct media_device *mdev) | 100 | void media_device_unregister(struct media_device *mdev) |
96 | { | 101 | { |
102 | struct media_entity *entity; | ||
103 | struct media_entity *next; | ||
104 | |||
105 | list_for_each_entry_safe(entity, next, &mdev->entities, list) | ||
106 | media_device_unregister_entity(entity); | ||
107 | |||
97 | device_remove_file(&mdev->devnode.dev, &dev_attr_model); | 108 | device_remove_file(&mdev->devnode.dev, &dev_attr_model); |
98 | media_devnode_unregister(&mdev->devnode); | 109 | media_devnode_unregister(&mdev->devnode); |
99 | } | 110 | } |
100 | EXPORT_SYMBOL_GPL(media_device_unregister); | 111 | EXPORT_SYMBOL_GPL(media_device_unregister); |
112 | |||
113 | /** | ||
114 | * media_device_register_entity - Register an entity with a media device | ||
115 | * @mdev: The media device | ||
116 | * @entity: The entity | ||
117 | */ | ||
118 | int __must_check media_device_register_entity(struct media_device *mdev, | ||
119 | struct media_entity *entity) | ||
120 | { | ||
121 | /* Warn if we apparently re-register an entity */ | ||
122 | WARN_ON(entity->parent != NULL); | ||
123 | entity->parent = mdev; | ||
124 | |||
125 | spin_lock(&mdev->lock); | ||
126 | if (entity->id == 0) | ||
127 | entity->id = mdev->entity_id++; | ||
128 | else | ||
129 | mdev->entity_id = max(entity->id + 1, mdev->entity_id); | ||
130 | list_add_tail(&entity->list, &mdev->entities); | ||
131 | spin_unlock(&mdev->lock); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(media_device_register_entity); | ||
136 | |||
137 | /** | ||
138 | * media_device_unregister_entity - Unregister an entity | ||
139 | * @entity: The entity | ||
140 | * | ||
141 | * If the entity has never been registered this function will return | ||
142 | * immediately. | ||
143 | */ | ||
144 | void media_device_unregister_entity(struct media_entity *entity) | ||
145 | { | ||
146 | struct media_device *mdev = entity->parent; | ||
147 | |||
148 | if (mdev == NULL) | ||
149 | return; | ||
150 | |||
151 | spin_lock(&mdev->lock); | ||
152 | list_del(&entity->list); | ||
153 | spin_unlock(&mdev->lock); | ||
154 | entity->parent = NULL; | ||
155 | } | ||
156 | EXPORT_SYMBOL_GPL(media_device_unregister_entity); | ||
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c new file mode 100644 index 000000000000..5c31df9ed765 --- /dev/null +++ b/drivers/media/media-entity.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* | ||
2 | * Media entity | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
7 | * Sakari Ailus <sakari.ailus@iki.fi> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <media/media-entity.h> | ||
26 | |||
27 | /** | ||
28 | * media_entity_init - Initialize a media entity | ||
29 | * | ||
30 | * @num_pads: Total number of sink and source pads. | ||
31 | * @extra_links: Initial estimate of the number of extra links. | ||
32 | * @pads: Array of 'num_pads' pads. | ||
33 | * | ||
34 | * The total number of pads is an intrinsic property of entities known by the | ||
35 | * entity driver, while the total number of links depends on hardware design | ||
36 | * and is an extrinsic property unknown to the entity driver. However, in most | ||
37 | * use cases the entity driver can guess the number of links which can safely | ||
38 | * be assumed to be equal to or larger than the number of pads. | ||
39 | * | ||
40 | * For those reasons the links array can be preallocated based on the entity | ||
41 | * driver guess and will be reallocated later if extra links need to be | ||
42 | * created. | ||
43 | * | ||
44 | * This function allocates a links array with enough space to hold at least | ||
45 | * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will | ||
46 | * be set to the number of allocated elements. | ||
47 | * | ||
48 | * The pads array is managed by the entity driver and passed to | ||
49 | * media_entity_init() where its pointer will be stored in the entity structure. | ||
50 | */ | ||
51 | int | ||
52 | media_entity_init(struct media_entity *entity, u16 num_pads, | ||
53 | struct media_pad *pads, u16 extra_links) | ||
54 | { | ||
55 | struct media_link *links; | ||
56 | unsigned int max_links = num_pads + extra_links; | ||
57 | unsigned int i; | ||
58 | |||
59 | links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL); | ||
60 | if (links == NULL) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | entity->group_id = 0; | ||
64 | entity->max_links = max_links; | ||
65 | entity->num_links = 0; | ||
66 | entity->num_backlinks = 0; | ||
67 | entity->num_pads = num_pads; | ||
68 | entity->pads = pads; | ||
69 | entity->links = links; | ||
70 | |||
71 | for (i = 0; i < num_pads; i++) { | ||
72 | pads[i].entity = entity; | ||
73 | pads[i].index = i; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(media_entity_init); | ||
79 | |||
80 | void | ||
81 | media_entity_cleanup(struct media_entity *entity) | ||
82 | { | ||
83 | kfree(entity->links); | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(media_entity_cleanup); | ||
86 | |||
87 | static struct media_link *media_entity_add_link(struct media_entity *entity) | ||
88 | { | ||
89 | if (entity->num_links >= entity->max_links) { | ||
90 | struct media_link *links = entity->links; | ||
91 | unsigned int max_links = entity->max_links + 2; | ||
92 | unsigned int i; | ||
93 | |||
94 | links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL); | ||
95 | if (links == NULL) | ||
96 | return NULL; | ||
97 | |||
98 | for (i = 0; i < entity->num_links; i++) | ||
99 | links[i].reverse->reverse = &links[i]; | ||
100 | |||
101 | entity->max_links = max_links; | ||
102 | entity->links = links; | ||
103 | } | ||
104 | |||
105 | return &entity->links[entity->num_links++]; | ||
106 | } | ||
107 | |||
108 | int | ||
109 | media_entity_create_link(struct media_entity *source, u16 source_pad, | ||
110 | struct media_entity *sink, u16 sink_pad, u32 flags) | ||
111 | { | ||
112 | struct media_link *link; | ||
113 | struct media_link *backlink; | ||
114 | |||
115 | BUG_ON(source == NULL || sink == NULL); | ||
116 | BUG_ON(source_pad >= source->num_pads); | ||
117 | BUG_ON(sink_pad >= sink->num_pads); | ||
118 | |||
119 | link = media_entity_add_link(source); | ||
120 | if (link == NULL) | ||
121 | return -ENOMEM; | ||
122 | |||
123 | link->source = &source->pads[source_pad]; | ||
124 | link->sink = &sink->pads[sink_pad]; | ||
125 | link->flags = flags; | ||
126 | |||
127 | /* Create the backlink. Backlinks are used to help graph traversal and | ||
128 | * are not reported to userspace. | ||
129 | */ | ||
130 | backlink = media_entity_add_link(sink); | ||
131 | if (backlink == NULL) { | ||
132 | source->num_links--; | ||
133 | return -ENOMEM; | ||
134 | } | ||
135 | |||
136 | backlink->source = &source->pads[source_pad]; | ||
137 | backlink->sink = &sink->pads[sink_pad]; | ||
138 | backlink->flags = flags; | ||
139 | |||
140 | link->reverse = backlink; | ||
141 | backlink->reverse = link; | ||
142 | |||
143 | sink->num_backlinks++; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | EXPORT_SYMBOL_GPL(media_entity_create_link); | ||
diff --git a/include/media/media-device.h b/include/media/media-device.h index 30857f7fc22b..a8390fe87e83 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h | |||
@@ -25,8 +25,10 @@ | |||
25 | 25 | ||
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
28 | #include <linux/spinlock.h> | ||
28 | 29 | ||
29 | #include <media/media-devnode.h> | 30 | #include <media/media-devnode.h> |
31 | #include <media/media-entity.h> | ||
30 | 32 | ||
31 | /** | 33 | /** |
32 | * struct media_device - Media device | 34 | * struct media_device - Media device |
@@ -37,6 +39,9 @@ | |||
37 | * @bus_info: Unique and stable device location identifier | 39 | * @bus_info: Unique and stable device location identifier |
38 | * @hw_revision: Hardware device revision | 40 | * @hw_revision: Hardware device revision |
39 | * @driver_version: Device driver version | 41 | * @driver_version: Device driver version |
42 | * @entity_id: ID of the next entity to be registered | ||
43 | * @entities: List of registered entities | ||
44 | * @lock: Entities list lock | ||
40 | * | 45 | * |
41 | * This structure represents an abstract high-level media device. It allows easy | 46 | * This structure represents an abstract high-level media device. It allows easy |
42 | * access to entities and provides basic media device-level support. The | 47 | * access to entities and provides basic media device-level support. The |
@@ -58,6 +63,12 @@ struct media_device { | |||
58 | char bus_info[32]; | 63 | char bus_info[32]; |
59 | u32 hw_revision; | 64 | u32 hw_revision; |
60 | u32 driver_version; | 65 | u32 driver_version; |
66 | |||
67 | u32 entity_id; | ||
68 | struct list_head entities; | ||
69 | |||
70 | /* Protects the entities list */ | ||
71 | spinlock_t lock; | ||
61 | }; | 72 | }; |
62 | 73 | ||
63 | /* media_devnode to media_device */ | 74 | /* media_devnode to media_device */ |
@@ -66,4 +77,12 @@ struct media_device { | |||
66 | int __must_check media_device_register(struct media_device *mdev); | 77 | int __must_check media_device_register(struct media_device *mdev); |
67 | void media_device_unregister(struct media_device *mdev); | 78 | void media_device_unregister(struct media_device *mdev); |
68 | 79 | ||
80 | int __must_check media_device_register_entity(struct media_device *mdev, | ||
81 | struct media_entity *entity); | ||
82 | void media_device_unregister_entity(struct media_entity *entity); | ||
83 | |||
84 | /* Iterate over all entities. */ | ||
85 | #define media_device_for_each_entity(entity, mdev) \ | ||
86 | list_for_each_entry(entity, &(mdev)->entities, list) | ||
87 | |||
69 | #endif | 88 | #endif |
diff --git a/include/media/media-entity.h b/include/media/media-entity.h new file mode 100644 index 000000000000..f6c856c9ac16 --- /dev/null +++ b/include/media/media-entity.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Media entity | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
7 | * Sakari Ailus <sakari.ailus@iki.fi> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef _MEDIA_ENTITY_H | ||
24 | #define _MEDIA_ENTITY_H | ||
25 | |||
26 | #include <linux/list.h> | ||
27 | |||
28 | #define MEDIA_ENT_TYPE_SHIFT 16 | ||
29 | #define MEDIA_ENT_TYPE_MASK 0x00ff0000 | ||
30 | #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff | ||
31 | |||
32 | #define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) | ||
33 | #define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) | ||
34 | #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) | ||
35 | #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) | ||
36 | #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) | ||
37 | |||
38 | #define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) | ||
39 | #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) | ||
40 | #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) | ||
41 | #define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) | ||
42 | |||
43 | #define MEDIA_ENT_FL_DEFAULT (1 << 0) | ||
44 | |||
45 | #define MEDIA_LNK_FL_ENABLED (1 << 0) | ||
46 | #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) | ||
47 | |||
48 | #define MEDIA_PAD_FL_SINK (1 << 0) | ||
49 | #define MEDIA_PAD_FL_SOURCE (1 << 1) | ||
50 | |||
51 | struct media_link { | ||
52 | struct media_pad *source; /* Source pad */ | ||
53 | struct media_pad *sink; /* Sink pad */ | ||
54 | struct media_link *reverse; /* Link in the reverse direction */ | ||
55 | unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ | ||
56 | }; | ||
57 | |||
58 | struct media_pad { | ||
59 | struct media_entity *entity; /* Entity this pad belongs to */ | ||
60 | u16 index; /* Pad index in the entity pads array */ | ||
61 | unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ | ||
62 | }; | ||
63 | |||
64 | struct media_entity { | ||
65 | struct list_head list; | ||
66 | struct media_device *parent; /* Media device this entity belongs to*/ | ||
67 | u32 id; /* Entity ID, unique in the parent media | ||
68 | * device context */ | ||
69 | const char *name; /* Entity name */ | ||
70 | u32 type; /* Entity type (MEDIA_ENT_T_*) */ | ||
71 | u32 revision; /* Entity revision, driver specific */ | ||
72 | unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */ | ||
73 | u32 group_id; /* Entity group ID */ | ||
74 | |||
75 | u16 num_pads; /* Number of sink and source pads */ | ||
76 | u16 num_links; /* Number of existing links, both | ||
77 | * enabled and disabled */ | ||
78 | u16 num_backlinks; /* Number of backlinks */ | ||
79 | u16 max_links; /* Maximum number of links */ | ||
80 | |||
81 | struct media_pad *pads; /* Pads array (num_pads elements) */ | ||
82 | struct media_link *links; /* Links array (max_links elements)*/ | ||
83 | |||
84 | union { | ||
85 | /* Node specifications */ | ||
86 | struct { | ||
87 | u32 major; | ||
88 | u32 minor; | ||
89 | } v4l; | ||
90 | struct { | ||
91 | u32 major; | ||
92 | u32 minor; | ||
93 | } fb; | ||
94 | struct { | ||
95 | u32 card; | ||
96 | u32 device; | ||
97 | u32 subdevice; | ||
98 | } alsa; | ||
99 | int dvb; | ||
100 | |||
101 | /* Sub-device specifications */ | ||
102 | /* Nothing needed yet */ | ||
103 | }; | ||
104 | }; | ||
105 | |||
106 | static inline u32 media_entity_type(struct media_entity *entity) | ||
107 | { | ||
108 | return entity->type & MEDIA_ENT_TYPE_MASK; | ||
109 | } | ||
110 | |||
111 | static inline u32 media_entity_subtype(struct media_entity *entity) | ||
112 | { | ||
113 | return entity->type & MEDIA_ENT_SUBTYPE_MASK; | ||
114 | } | ||
115 | |||
116 | int media_entity_init(struct media_entity *entity, u16 num_pads, | ||
117 | struct media_pad *pads, u16 extra_links); | ||
118 | void media_entity_cleanup(struct media_entity *entity); | ||
119 | int media_entity_create_link(struct media_entity *source, u16 source_pad, | ||
120 | struct media_entity *sink, u16 sink_pad, u32 flags); | ||
121 | |||
122 | #endif | ||