xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/media/mc-core.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunMedia Controller devices
4*4882a593Smuzhiyun------------------------
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunMedia Controller
7*4882a593Smuzhiyun~~~~~~~~~~~~~~~~
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunThe media controller userspace API is documented in
10*4882a593Smuzhiyun:ref:`the Media Controller uAPI book <media_controller>`. This document focus
11*4882a593Smuzhiyunon the kernel-side implementation of the media framework.
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunAbstract media device model
14*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^
15*4882a593Smuzhiyun
16*4882a593SmuzhiyunDiscovering a device internal topology, and configuring it at runtime, is one
17*4882a593Smuzhiyunof the goals of the media framework. To achieve this, hardware devices are
18*4882a593Smuzhiyunmodelled as an oriented graph of building blocks called entities connected
19*4882a593Smuzhiyunthrough pads.
20*4882a593Smuzhiyun
21*4882a593SmuzhiyunAn entity is a basic media hardware building block. It can correspond to
22*4882a593Smuzhiyuna large variety of logical blocks such as physical hardware devices
23*4882a593Smuzhiyun(CMOS sensor for instance), logical hardware devices (a building block
24*4882a593Smuzhiyunin a System-on-Chip image processing pipeline), DMA channels or physical
25*4882a593Smuzhiyunconnectors.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunA pad is a connection endpoint through which an entity can interact with
28*4882a593Smuzhiyunother entities. Data (not restricted to video) produced by an entity
29*4882a593Smuzhiyunflows from the entity's output to one or more entity inputs. Pads should
30*4882a593Smuzhiyunnot be confused with physical pins at chip boundaries.
31*4882a593Smuzhiyun
32*4882a593SmuzhiyunA link is a point-to-point oriented connection between two pads, either
33*4882a593Smuzhiyunon the same entity or on different entities. Data flows from a source
34*4882a593Smuzhiyunpad to a sink pad.
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunMedia device
37*4882a593Smuzhiyun^^^^^^^^^^^^
38*4882a593Smuzhiyun
39*4882a593SmuzhiyunA media device is represented by a struct media_device
40*4882a593Smuzhiyuninstance, defined in ``include/media/media-device.h``.
41*4882a593SmuzhiyunAllocation of the structure is handled by the media device driver, usually by
42*4882a593Smuzhiyunembedding the :c:type:`media_device` instance in a larger driver-specific
43*4882a593Smuzhiyunstructure.
44*4882a593Smuzhiyun
45*4882a593SmuzhiyunDrivers register media device instances by calling
46*4882a593Smuzhiyun:c:func:`__media_device_register()` via the macro ``media_device_register()``
47*4882a593Smuzhiyunand unregistered by calling :c:func:`media_device_unregister()`.
48*4882a593Smuzhiyun
49*4882a593SmuzhiyunEntities
50*4882a593Smuzhiyun^^^^^^^^
51*4882a593Smuzhiyun
52*4882a593SmuzhiyunEntities are represented by a struct media_entity
53*4882a593Smuzhiyuninstance, defined in ``include/media/media-entity.h``. The structure is usually
54*4882a593Smuzhiyunembedded into a higher-level structure, such as
55*4882a593Smuzhiyun:c:type:`v4l2_subdev` or :c:type:`video_device`
56*4882a593Smuzhiyuninstances, although drivers can allocate entities directly.
57*4882a593Smuzhiyun
58*4882a593SmuzhiyunDrivers initialize entity pads by calling
59*4882a593Smuzhiyun:c:func:`media_entity_pads_init()`.
60*4882a593Smuzhiyun
61*4882a593SmuzhiyunDrivers register entities with a media device by calling
62*4882a593Smuzhiyun:c:func:`media_device_register_entity()`
63*4882a593Smuzhiyunand unregistered by calling
64*4882a593Smuzhiyun:c:func:`media_device_unregister_entity()`.
65*4882a593Smuzhiyun
66*4882a593SmuzhiyunInterfaces
67*4882a593Smuzhiyun^^^^^^^^^^
68*4882a593Smuzhiyun
69*4882a593SmuzhiyunInterfaces are represented by a
70*4882a593Smuzhiyunstruct media_interface instance, defined in
71*4882a593Smuzhiyun``include/media/media-entity.h``. Currently, only one type of interface is
72*4882a593Smuzhiyundefined: a device node. Such interfaces are represented by a
73*4882a593Smuzhiyunstruct media_intf_devnode.
74*4882a593Smuzhiyun
75*4882a593SmuzhiyunDrivers initialize and create device node interfaces by calling
76*4882a593Smuzhiyun:c:func:`media_devnode_create()`
77*4882a593Smuzhiyunand remove them by calling:
78*4882a593Smuzhiyun:c:func:`media_devnode_remove()`.
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunPads
81*4882a593Smuzhiyun^^^^
82*4882a593SmuzhiyunPads are represented by a struct media_pad instance,
83*4882a593Smuzhiyundefined in ``include/media/media-entity.h``. Each entity stores its pads in
84*4882a593Smuzhiyuna pads array managed by the entity driver. Drivers usually embed the array in
85*4882a593Smuzhiyuna driver-specific structure.
86*4882a593Smuzhiyun
87*4882a593SmuzhiyunPads are identified by their entity and their 0-based index in the pads
88*4882a593Smuzhiyunarray.
89*4882a593Smuzhiyun
90*4882a593SmuzhiyunBoth information are stored in the struct media_pad,
91*4882a593Smuzhiyunmaking the struct media_pad pointer the canonical way
92*4882a593Smuzhiyunto store and pass link references.
93*4882a593Smuzhiyun
94*4882a593SmuzhiyunPads have flags that describe the pad capabilities and state.
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
97*4882a593Smuzhiyun``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun.. note::
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun  One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
102*4882a593Smuzhiyun  be set for each pad.
103*4882a593Smuzhiyun
104*4882a593SmuzhiyunLinks
105*4882a593Smuzhiyun^^^^^
106*4882a593Smuzhiyun
107*4882a593SmuzhiyunLinks are represented by a struct media_link instance,
108*4882a593Smuzhiyundefined in ``include/media/media-entity.h``. There are two types of links:
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun**1. pad to pad links**:
111*4882a593Smuzhiyun
112*4882a593SmuzhiyunAssociate two entities via their PADs. Each entity has a list that points
113*4882a593Smuzhiyunto all links originating at or targeting any of its pads.
114*4882a593SmuzhiyunA given link is thus stored twice, once in the source entity and once in
115*4882a593Smuzhiyunthe target entity.
116*4882a593Smuzhiyun
117*4882a593SmuzhiyunDrivers create pad to pad links by calling:
118*4882a593Smuzhiyun:c:func:`media_create_pad_link()` and remove with
119*4882a593Smuzhiyun:c:func:`media_entity_remove_links()`.
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun**2. interface to entity links**:
122*4882a593Smuzhiyun
123*4882a593SmuzhiyunAssociate one interface to a Link.
124*4882a593Smuzhiyun
125*4882a593SmuzhiyunDrivers create interface to entity links by calling:
126*4882a593Smuzhiyun:c:func:`media_create_intf_link()` and remove with
127*4882a593Smuzhiyun:c:func:`media_remove_intf_links()`.
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun.. note::
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun   Links can only be created after having both ends already created.
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunLinks have flags that describe the link capabilities and state. The
134*4882a593Smuzhiyunvalid values are described at :c:func:`media_create_pad_link()` and
135*4882a593Smuzhiyun:c:func:`media_create_intf_link()`.
136*4882a593Smuzhiyun
137*4882a593SmuzhiyunGraph traversal
138*4882a593Smuzhiyun^^^^^^^^^^^^^^^
139*4882a593Smuzhiyun
140*4882a593SmuzhiyunThe media framework provides APIs to iterate over entities in a graph.
141*4882a593Smuzhiyun
142*4882a593SmuzhiyunTo iterate over all entities belonging to a media device, drivers can use
143*4882a593Smuzhiyunthe media_device_for_each_entity macro, defined in
144*4882a593Smuzhiyun``include/media/media-device.h``.
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun..  code-block:: c
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun    struct media_entity *entity;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun    media_device_for_each_entity(entity, mdev) {
151*4882a593Smuzhiyun    // entity will point to each entity in turn
152*4882a593Smuzhiyun    ...
153*4882a593Smuzhiyun    }
154*4882a593Smuzhiyun
155*4882a593SmuzhiyunDrivers might also need to iterate over all entities in a graph that can be
156*4882a593Smuzhiyunreached only through enabled links starting at a given entity. The media
157*4882a593Smuzhiyunframework provides a depth-first graph traversal API for that purpose.
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun.. note::
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun   Graphs with cycles (whether directed or undirected) are **NOT**
162*4882a593Smuzhiyun   supported by the graph traversal API. To prevent infinite loops, the graph
163*4882a593Smuzhiyun   traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
164*4882a593Smuzhiyun   currently defined as 16.
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunDrivers initiate a graph traversal by calling
167*4882a593Smuzhiyun:c:func:`media_graph_walk_start()`
168*4882a593Smuzhiyun
169*4882a593SmuzhiyunThe graph structure, provided by the caller, is initialized to start graph
170*4882a593Smuzhiyuntraversal at the given entity.
171*4882a593Smuzhiyun
172*4882a593SmuzhiyunDrivers can then retrieve the next entity by calling
173*4882a593Smuzhiyun:c:func:`media_graph_walk_next()`
174*4882a593Smuzhiyun
175*4882a593SmuzhiyunWhen the graph traversal is complete the function will return ``NULL``.
176*4882a593Smuzhiyun
177*4882a593SmuzhiyunGraph traversal can be interrupted at any moment. No cleanup function call
178*4882a593Smuzhiyunis required and the graph structure can be freed normally.
179*4882a593Smuzhiyun
180*4882a593SmuzhiyunHelper functions can be used to find a link between two given pads, or a pad
181*4882a593Smuzhiyunconnected to another pad through an enabled link
182*4882a593Smuzhiyun:c:func:`media_entity_find_link()` and
183*4882a593Smuzhiyun:c:func:`media_entity_remote_pad()`.
184*4882a593Smuzhiyun
185*4882a593SmuzhiyunUse count and power handling
186*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187*4882a593Smuzhiyun
188*4882a593SmuzhiyunDue to the wide differences between drivers regarding power management
189*4882a593Smuzhiyunneeds, the media controller does not implement power management. However,
190*4882a593Smuzhiyunthe struct media_entity includes a ``use_count``
191*4882a593Smuzhiyunfield that media drivers
192*4882a593Smuzhiyuncan use to track the number of users of every entity for power management
193*4882a593Smuzhiyunneeds.
194*4882a593Smuzhiyun
195*4882a593SmuzhiyunThe :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
196*4882a593Smuzhiyunmedia drivers and must not be
197*4882a593Smuzhiyuntouched by entity drivers. Access to the field must be protected by the
198*4882a593Smuzhiyun:c:type:`media_device`.\ ``graph_mutex`` lock.
199*4882a593Smuzhiyun
200*4882a593SmuzhiyunLinks setup
201*4882a593Smuzhiyun^^^^^^^^^^^
202*4882a593Smuzhiyun
203*4882a593SmuzhiyunLink properties can be modified at runtime by calling
204*4882a593Smuzhiyun:c:func:`media_entity_setup_link()`.
205*4882a593Smuzhiyun
206*4882a593SmuzhiyunPipelines and media streams
207*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^
208*4882a593Smuzhiyun
209*4882a593SmuzhiyunWhen starting streaming, drivers must notify all entities in the pipeline to
210*4882a593Smuzhiyunprevent link states from being modified during streaming by calling
211*4882a593Smuzhiyun:c:func:`media_pipeline_start()`.
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunThe function will mark all entities connected to the given entity through
214*4882a593Smuzhiyunenabled links, either directly or indirectly, as streaming.
215*4882a593Smuzhiyun
216*4882a593SmuzhiyunThe struct media_pipeline instance pointed to by
217*4882a593Smuzhiyunthe pipe argument will be stored in every entity in the pipeline.
218*4882a593SmuzhiyunDrivers should embed the struct media_pipeline
219*4882a593Smuzhiyunin higher-level pipeline structures and can then access the
220*4882a593Smuzhiyunpipeline through the struct media_entity
221*4882a593Smuzhiyunpipe field.
222*4882a593Smuzhiyun
223*4882a593SmuzhiyunCalls to :c:func:`media_pipeline_start()` can be nested.
224*4882a593SmuzhiyunThe pipeline pointer must be identical for all nested calls to the function.
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun:c:func:`media_pipeline_start()` may return an error. In that case,
227*4882a593Smuzhiyunit will clean up any of the changes it did by itself.
228*4882a593Smuzhiyun
229*4882a593SmuzhiyunWhen stopping the stream, drivers must notify the entities with
230*4882a593Smuzhiyun:c:func:`media_pipeline_stop()`.
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunIf multiple calls to :c:func:`media_pipeline_start()` have been
233*4882a593Smuzhiyunmade the same number of :c:func:`media_pipeline_stop()` calls
234*4882a593Smuzhiyunare required to stop streaming.
235*4882a593SmuzhiyunThe :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
236*4882a593Smuzhiyunnested stop call.
237*4882a593Smuzhiyun
238*4882a593SmuzhiyunLink configuration will fail with ``-EBUSY`` by default if either end of the
239*4882a593Smuzhiyunlink is a streaming entity. Links that can be modified while streaming must
240*4882a593Smuzhiyunbe marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
241*4882a593Smuzhiyun
242*4882a593SmuzhiyunIf other operations need to be disallowed on streaming entities (such as
243*4882a593Smuzhiyunchanging entities configuration parameters) drivers can explicitly check the
244*4882a593Smuzhiyunmedia_entity stream_count field to find out if an entity is streaming. This
245*4882a593Smuzhiyunoperation must be done with the media_device graph_mutex held.
246*4882a593Smuzhiyun
247*4882a593SmuzhiyunLink validation
248*4882a593Smuzhiyun^^^^^^^^^^^^^^^
249*4882a593Smuzhiyun
250*4882a593SmuzhiyunLink validation is performed by :c:func:`media_pipeline_start()`
251*4882a593Smuzhiyunfor any entity which has sink pads in the pipeline. The
252*4882a593Smuzhiyun:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
253*4882a593Smuzhiyunpurpose. In ``link_validate()`` callback, entity driver should check
254*4882a593Smuzhiyunthat the properties of the source pad of the connected entity and its own
255*4882a593Smuzhiyunsink pad match. It is up to the type of the entity (and in the end, the
256*4882a593Smuzhiyunproperties of the hardware) what matching actually means.
257*4882a593Smuzhiyun
258*4882a593SmuzhiyunSubsystems should facilitate link validation by providing subsystem specific
259*4882a593Smuzhiyunhelper functions to provide easy access for commonly needed information, and
260*4882a593Smuzhiyunin the end provide a way to use driver-specific callbacks.
261*4882a593Smuzhiyun
262*4882a593SmuzhiyunMedia Controller Device Allocator API
263*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
264*4882a593Smuzhiyun
265*4882a593SmuzhiyunWhen the media device belongs to more than one driver, the shared media
266*4882a593Smuzhiyundevice is allocated with the shared struct device as the key for look ups.
267*4882a593Smuzhiyun
268*4882a593SmuzhiyunThe shared media device should stay in registered state until the last
269*4882a593Smuzhiyundriver unregisters it. In addition, the media device should be released when
270*4882a593Smuzhiyunall the references are released. Each driver gets a reference to the media
271*4882a593Smuzhiyundevice during probe, when it allocates the media device. If media device is
272*4882a593Smuzhiyunalready allocated, the allocate API bumps up the refcount and returns the
273*4882a593Smuzhiyunexisting media device. The driver puts the reference back in its disconnect
274*4882a593Smuzhiyunroutine when it calls :c:func:`media_device_delete()`.
275*4882a593Smuzhiyun
276*4882a593SmuzhiyunThe media device is unregistered and cleaned up from the kref put handler to
277*4882a593Smuzhiyunensure that the media device stays in registered state until the last driver
278*4882a593Smuzhiyununregisters the media device.
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun**Driver Usage**
281*4882a593Smuzhiyun
282*4882a593SmuzhiyunDrivers should use the appropriate media-core routines to manage the shared
283*4882a593Smuzhiyunmedia device life-time handling the two states:
284*4882a593Smuzhiyun1. allocate -> register -> delete
285*4882a593Smuzhiyun2. get reference to already registered device -> delete
286*4882a593Smuzhiyun
287*4882a593Smuzhiyuncall :c:func:`media_device_delete()` routine to make sure the shared media
288*4882a593Smuzhiyundevice delete is handled correctly.
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun**driver probe:**
291*4882a593SmuzhiyunCall :c:func:`media_device_usb_allocate()` to allocate or get a reference
292*4882a593SmuzhiyunCall :c:func:`media_device_register()`, if media devnode isn't registered
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun**driver disconnect:**
295*4882a593SmuzhiyunCall :c:func:`media_device_delete()` to free the media_device. Freeing is
296*4882a593Smuzhiyunhandled by the kref put handler.
297*4882a593Smuzhiyun
298*4882a593SmuzhiyunAPI Definitions
299*4882a593Smuzhiyun^^^^^^^^^^^^^^^
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun.. kernel-doc:: include/media/media-device.h
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun.. kernel-doc:: include/media/media-devnode.h
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun.. kernel-doc:: include/media/media-entity.h
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun.. kernel-doc:: include/media/media-request.h
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun.. kernel-doc:: include/media/media-dev-allocator.h
310