xref: /linux/Documentation/driver-api/media/mc-core.rst (revision 03b282861ca737b7e2dfb9a1e4a2a4a7e3594688)
1f2ac8ce8SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2f2ac8ce8SMauro Carvalho Chehab
3684ffa2dSMauro Carvalho ChehabMedia Controller devices
4684ffa2dSMauro Carvalho Chehab------------------------
5684ffa2dSMauro Carvalho Chehab
6684ffa2dSMauro Carvalho ChehabMedia Controller
7684ffa2dSMauro Carvalho Chehab~~~~~~~~~~~~~~~~
8684ffa2dSMauro Carvalho Chehab
974604b73SMauro Carvalho ChehabThe media controller userspace API is documented in
10da83c888SMauro Carvalho Chehab:ref:`the Media Controller uAPI book <media_controller>`. This document focus
11684ffa2dSMauro Carvalho Chehabon the kernel-side implementation of the media framework.
12684ffa2dSMauro Carvalho Chehab
13684ffa2dSMauro Carvalho ChehabAbstract media device model
14684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^
15684ffa2dSMauro Carvalho Chehab
16684ffa2dSMauro Carvalho ChehabDiscovering a device internal topology, and configuring it at runtime, is one
17684ffa2dSMauro Carvalho Chehabof the goals of the media framework. To achieve this, hardware devices are
18684ffa2dSMauro Carvalho Chehabmodelled as an oriented graph of building blocks called entities connected
19684ffa2dSMauro Carvalho Chehabthrough pads.
20684ffa2dSMauro Carvalho Chehab
21684ffa2dSMauro Carvalho ChehabAn entity is a basic media hardware building block. It can correspond to
22684ffa2dSMauro Carvalho Chehaba large variety of logical blocks such as physical hardware devices
23684ffa2dSMauro Carvalho Chehab(CMOS sensor for instance), logical hardware devices (a building block
24684ffa2dSMauro Carvalho Chehabin a System-on-Chip image processing pipeline), DMA channels or physical
25684ffa2dSMauro Carvalho Chehabconnectors.
26684ffa2dSMauro Carvalho Chehab
27684ffa2dSMauro Carvalho ChehabA pad is a connection endpoint through which an entity can interact with
28684ffa2dSMauro Carvalho Chehabother entities. Data (not restricted to video) produced by an entity
29684ffa2dSMauro Carvalho Chehabflows from the entity's output to one or more entity inputs. Pads should
30684ffa2dSMauro Carvalho Chehabnot be confused with physical pins at chip boundaries.
31684ffa2dSMauro Carvalho Chehab
32684ffa2dSMauro Carvalho ChehabA link is a point-to-point oriented connection between two pads, either
33684ffa2dSMauro Carvalho Chehabon the same entity or on different entities. Data flows from a source
34684ffa2dSMauro Carvalho Chehabpad to a sink pad.
35684ffa2dSMauro Carvalho Chehab
36684ffa2dSMauro Carvalho ChehabMedia device
37684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^
38684ffa2dSMauro Carvalho Chehab
399303c9d5SMauro Carvalho ChehabA media device is represented by a struct media_device
4074604b73SMauro Carvalho Chehabinstance, defined in ``include/media/media-device.h``.
4174604b73SMauro Carvalho ChehabAllocation of the structure is handled by the media device driver, usually by
4274604b73SMauro Carvalho Chehabembedding the :c:type:`media_device` instance in a larger driver-specific
4374604b73SMauro Carvalho Chehabstructure.
44684ffa2dSMauro Carvalho Chehab
451d1d8669SSakari AilusDrivers initialise media device instances by calling
461d1d8669SSakari Ailus:c:func:`media_device_init()`. After initialising a media device instance, it is
471d1d8669SSakari Ailusregistered by calling :c:func:`__media_device_register()` via the macro
481d1d8669SSakari Ailus``media_device_register()`` and unregistered by calling
491d1d8669SSakari Ailus:c:func:`media_device_unregister()`. An initialised media device must be
501d1d8669SSakari Ailuseventually cleaned up by calling :c:func:`media_device_cleanup()`.
511d1d8669SSakari Ailus
521d1d8669SSakari AilusNote that it is not allowed to unregister a media device instance that was not
531d1d8669SSakari Ailuspreviously registered, or clean up a media device instance that was not
541d1d8669SSakari Ailuspreviously initialised.
55684ffa2dSMauro Carvalho Chehab
56684ffa2dSMauro Carvalho ChehabEntities
57684ffa2dSMauro Carvalho Chehab^^^^^^^^
58684ffa2dSMauro Carvalho Chehab
599303c9d5SMauro Carvalho ChehabEntities are represented by a struct media_entity
6074604b73SMauro Carvalho Chehabinstance, defined in ``include/media/media-entity.h``. The structure is usually
6174604b73SMauro Carvalho Chehabembedded into a higher-level structure, such as
62041d8211SMauro Carvalho Chehab:c:type:`v4l2_subdev` or :c:type:`video_device`
6374604b73SMauro Carvalho Chehabinstances, although drivers can allocate entities directly.
64684ffa2dSMauro Carvalho Chehab
65684ffa2dSMauro Carvalho ChehabDrivers initialize entity pads by calling
667b998baeSMauro Carvalho Chehab:c:func:`media_entity_pads_init()`.
67684ffa2dSMauro Carvalho Chehab
68684ffa2dSMauro Carvalho ChehabDrivers register entities with a media device by calling
697b998baeSMauro Carvalho Chehab:c:func:`media_device_register_entity()`
70adf48e3fSMauro Carvalho Chehaband unregistered by calling
717b998baeSMauro Carvalho Chehab:c:func:`media_device_unregister_entity()`.
72684ffa2dSMauro Carvalho Chehab
73684ffa2dSMauro Carvalho ChehabInterfaces
74684ffa2dSMauro Carvalho Chehab^^^^^^^^^^
75684ffa2dSMauro Carvalho Chehab
7674604b73SMauro Carvalho ChehabInterfaces are represented by a
779303c9d5SMauro Carvalho Chehabstruct media_interface instance, defined in
7874604b73SMauro Carvalho Chehab``include/media/media-entity.h``. Currently, only one type of interface is
7974604b73SMauro Carvalho Chehabdefined: a device node. Such interfaces are represented by a
809303c9d5SMauro Carvalho Chehabstruct media_intf_devnode.
81684ffa2dSMauro Carvalho Chehab
82684ffa2dSMauro Carvalho ChehabDrivers initialize and create device node interfaces by calling
837b998baeSMauro Carvalho Chehab:c:func:`media_devnode_create()`
84684ffa2dSMauro Carvalho Chehaband remove them by calling:
857b998baeSMauro Carvalho Chehab:c:func:`media_devnode_remove()`.
86684ffa2dSMauro Carvalho Chehab
87684ffa2dSMauro Carvalho ChehabPads
88684ffa2dSMauro Carvalho Chehab^^^^
899303c9d5SMauro Carvalho ChehabPads are represented by a struct media_pad instance,
9074604b73SMauro Carvalho Chehabdefined in ``include/media/media-entity.h``. Each entity stores its pads in
9174604b73SMauro Carvalho Chehaba pads array managed by the entity driver. Drivers usually embed the array in
9274604b73SMauro Carvalho Chehaba driver-specific structure.
93684ffa2dSMauro Carvalho Chehab
94684ffa2dSMauro Carvalho ChehabPads are identified by their entity and their 0-based index in the pads
95684ffa2dSMauro Carvalho Chehabarray.
9674604b73SMauro Carvalho Chehab
979303c9d5SMauro Carvalho ChehabBoth information are stored in the struct media_pad,
989303c9d5SMauro Carvalho Chehabmaking the struct media_pad pointer the canonical way
993c7d91efSMauro Carvalho Chehabto store and pass link references.
100684ffa2dSMauro Carvalho Chehab
101684ffa2dSMauro Carvalho ChehabPads have flags that describe the pad capabilities and state.
102684ffa2dSMauro Carvalho Chehab
10374604b73SMauro Carvalho Chehab``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
10474604b73SMauro Carvalho Chehab``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
105684ffa2dSMauro Carvalho Chehab
10674604b73SMauro Carvalho Chehab.. note::
10774604b73SMauro Carvalho Chehab
10874604b73SMauro Carvalho Chehab  One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
109684ffa2dSMauro Carvalho Chehab  be set for each pad.
110684ffa2dSMauro Carvalho Chehab
111684ffa2dSMauro Carvalho ChehabLinks
112684ffa2dSMauro Carvalho Chehab^^^^^
113684ffa2dSMauro Carvalho Chehab
1149303c9d5SMauro Carvalho ChehabLinks are represented by a struct media_link instance,
11574604b73SMauro Carvalho Chehabdefined in ``include/media/media-entity.h``. There are two types of links:
116684ffa2dSMauro Carvalho Chehab
11774604b73SMauro Carvalho Chehab**1. pad to pad links**:
118684ffa2dSMauro Carvalho Chehab
119684ffa2dSMauro Carvalho ChehabAssociate two entities via their PADs. Each entity has a list that points
120684ffa2dSMauro Carvalho Chehabto all links originating at or targeting any of its pads.
121684ffa2dSMauro Carvalho ChehabA given link is thus stored twice, once in the source entity and once in
122684ffa2dSMauro Carvalho Chehabthe target entity.
123684ffa2dSMauro Carvalho Chehab
124684ffa2dSMauro Carvalho ChehabDrivers create pad to pad links by calling:
1257b998baeSMauro Carvalho Chehab:c:func:`media_create_pad_link()` and remove with
1267b998baeSMauro Carvalho Chehab:c:func:`media_entity_remove_links()`.
127684ffa2dSMauro Carvalho Chehab
12874604b73SMauro Carvalho Chehab**2. interface to entity links**:
129684ffa2dSMauro Carvalho Chehab
130684ffa2dSMauro Carvalho ChehabAssociate one interface to a Link.
131684ffa2dSMauro Carvalho Chehab
132684ffa2dSMauro Carvalho ChehabDrivers create interface to entity links by calling:
1337b998baeSMauro Carvalho Chehab:c:func:`media_create_intf_link()` and remove with
1347b998baeSMauro Carvalho Chehab:c:func:`media_remove_intf_links()`.
135684ffa2dSMauro Carvalho Chehab
136684ffa2dSMauro Carvalho Chehab.. note::
137684ffa2dSMauro Carvalho Chehab
138684ffa2dSMauro Carvalho Chehab   Links can only be created after having both ends already created.
139684ffa2dSMauro Carvalho Chehab
140684ffa2dSMauro Carvalho ChehabLinks have flags that describe the link capabilities and state. The
1417b998baeSMauro Carvalho Chehabvalid values are described at :c:func:`media_create_pad_link()` and
1427b998baeSMauro Carvalho Chehab:c:func:`media_create_intf_link()`.
143684ffa2dSMauro Carvalho Chehab
144684ffa2dSMauro Carvalho ChehabGraph traversal
145684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^^^^
146684ffa2dSMauro Carvalho Chehab
147684ffa2dSMauro Carvalho ChehabThe media framework provides APIs to iterate over entities in a graph.
148684ffa2dSMauro Carvalho Chehab
149684ffa2dSMauro Carvalho ChehabTo iterate over all entities belonging to a media device, drivers can use
150684ffa2dSMauro Carvalho Chehabthe media_device_for_each_entity macro, defined in
15174604b73SMauro Carvalho Chehab``include/media/media-device.h``.
15274604b73SMauro Carvalho Chehab
15374604b73SMauro Carvalho Chehab..  code-block:: c
154684ffa2dSMauro Carvalho Chehab
155684ffa2dSMauro Carvalho Chehab    struct media_entity *entity;
156684ffa2dSMauro Carvalho Chehab
157684ffa2dSMauro Carvalho Chehab    media_device_for_each_entity(entity, mdev) {
158684ffa2dSMauro Carvalho Chehab    // entity will point to each entity in turn
159684ffa2dSMauro Carvalho Chehab    ...
160684ffa2dSMauro Carvalho Chehab    }
161684ffa2dSMauro Carvalho Chehab
162684ffa2dSMauro Carvalho ChehabDrivers might also need to iterate over all entities in a graph that can be
163684ffa2dSMauro Carvalho Chehabreached only through enabled links starting at a given entity. The media
164684ffa2dSMauro Carvalho Chehabframework provides a depth-first graph traversal API for that purpose.
165684ffa2dSMauro Carvalho Chehab
16674604b73SMauro Carvalho Chehab.. note::
16774604b73SMauro Carvalho Chehab
16874604b73SMauro Carvalho Chehab   Graphs with cycles (whether directed or undirected) are **NOT**
169684ffa2dSMauro Carvalho Chehab   supported by the graph traversal API. To prevent infinite loops, the graph
17074604b73SMauro Carvalho Chehab   traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
171684ffa2dSMauro Carvalho Chehab   currently defined as 16.
172684ffa2dSMauro Carvalho Chehab
173684ffa2dSMauro Carvalho ChehabDrivers initiate a graph traversal by calling
17420b85227SSakari Ailus:c:func:`media_graph_walk_start()`
175684ffa2dSMauro Carvalho Chehab
176684ffa2dSMauro Carvalho ChehabThe graph structure, provided by the caller, is initialized to start graph
177684ffa2dSMauro Carvalho Chehabtraversal at the given entity.
178684ffa2dSMauro Carvalho Chehab
179684ffa2dSMauro Carvalho ChehabDrivers can then retrieve the next entity by calling
18020b85227SSakari Ailus:c:func:`media_graph_walk_next()`
181684ffa2dSMauro Carvalho Chehab
18274604b73SMauro Carvalho ChehabWhen the graph traversal is complete the function will return ``NULL``.
183684ffa2dSMauro Carvalho Chehab
184684ffa2dSMauro Carvalho ChehabGraph traversal can be interrupted at any moment. No cleanup function call
185684ffa2dSMauro Carvalho Chehabis required and the graph structure can be freed normally.
186684ffa2dSMauro Carvalho Chehab
187684ffa2dSMauro Carvalho ChehabHelper functions can be used to find a link between two given pads, or a pad
188684ffa2dSMauro Carvalho Chehabconnected to another pad through an enabled link
189*03b28286SLaurent Pinchart(:c:func:`media_entity_find_link()`, :c:func:`media_pad_remote_pad_first()`n
190*03b28286SLaurent Pinchart:c:func:`media_entity_remote_source_pad_unique()` and
191*03b28286SLaurent Pinchart:c:func:`media_pad_remote_pad_unique()`).
192684ffa2dSMauro Carvalho Chehab
193684ffa2dSMauro Carvalho ChehabUse count and power handling
194684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^
195684ffa2dSMauro Carvalho Chehab
196684ffa2dSMauro Carvalho ChehabDue to the wide differences between drivers regarding power management
197684ffa2dSMauro Carvalho Chehabneeds, the media controller does not implement power management. However,
1989303c9d5SMauro Carvalho Chehabthe struct media_entity includes a ``use_count``
19974604b73SMauro Carvalho Chehabfield that media drivers
200684ffa2dSMauro Carvalho Chehabcan use to track the number of users of every entity for power management
201684ffa2dSMauro Carvalho Chehabneeds.
202684ffa2dSMauro Carvalho Chehab
20374604b73SMauro Carvalho ChehabThe :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
20474604b73SMauro Carvalho Chehabmedia drivers and must not be
205684ffa2dSMauro Carvalho Chehabtouched by entity drivers. Access to the field must be protected by the
20674604b73SMauro Carvalho Chehab:c:type:`media_device`.\ ``graph_mutex`` lock.
207684ffa2dSMauro Carvalho Chehab
208684ffa2dSMauro Carvalho ChehabLinks setup
209684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^
210684ffa2dSMauro Carvalho Chehab
211684ffa2dSMauro Carvalho ChehabLink properties can be modified at runtime by calling
2127b998baeSMauro Carvalho Chehab:c:func:`media_entity_setup_link()`.
213684ffa2dSMauro Carvalho Chehab
214684ffa2dSMauro Carvalho ChehabPipelines and media streams
215684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^
216684ffa2dSMauro Carvalho Chehab
217684ffa2dSMauro Carvalho ChehabWhen starting streaming, drivers must notify all entities in the pipeline to
218684ffa2dSMauro Carvalho Chehabprevent link states from being modified during streaming by calling
21920b85227SSakari Ailus:c:func:`media_pipeline_start()`.
220684ffa2dSMauro Carvalho Chehab
221684ffa2dSMauro Carvalho ChehabThe function will mark all entities connected to the given entity through
222684ffa2dSMauro Carvalho Chehabenabled links, either directly or indirectly, as streaming.
223684ffa2dSMauro Carvalho Chehab
2249303c9d5SMauro Carvalho ChehabThe struct media_pipeline instance pointed to by
22574604b73SMauro Carvalho Chehabthe pipe argument will be stored in every entity in the pipeline.
2269303c9d5SMauro Carvalho ChehabDrivers should embed the struct media_pipeline
22774604b73SMauro Carvalho Chehabin higher-level pipeline structures and can then access the
2289303c9d5SMauro Carvalho Chehabpipeline through the struct media_entity
22974604b73SMauro Carvalho Chehabpipe field.
230684ffa2dSMauro Carvalho Chehab
23120b85227SSakari AilusCalls to :c:func:`media_pipeline_start()` can be nested.
23274604b73SMauro Carvalho ChehabThe pipeline pointer must be identical for all nested calls to the function.
233684ffa2dSMauro Carvalho Chehab
23420b85227SSakari Ailus:c:func:`media_pipeline_start()` may return an error. In that case,
23574604b73SMauro Carvalho Chehabit will clean up any of the changes it did by itself.
236684ffa2dSMauro Carvalho Chehab
237684ffa2dSMauro Carvalho ChehabWhen stopping the stream, drivers must notify the entities with
23820b85227SSakari Ailus:c:func:`media_pipeline_stop()`.
239684ffa2dSMauro Carvalho Chehab
24020b85227SSakari AilusIf multiple calls to :c:func:`media_pipeline_start()` have been
24120b85227SSakari Ailusmade the same number of :c:func:`media_pipeline_stop()` calls
24274604b73SMauro Carvalho Chehabare required to stop streaming.
24374604b73SMauro Carvalho ChehabThe :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
24474604b73SMauro Carvalho Chehabnested stop call.
245684ffa2dSMauro Carvalho Chehab
24674604b73SMauro Carvalho ChehabLink configuration will fail with ``-EBUSY`` by default if either end of the
247684ffa2dSMauro Carvalho Chehablink is a streaming entity. Links that can be modified while streaming must
24874604b73SMauro Carvalho Chehabbe marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
249684ffa2dSMauro Carvalho Chehab
250684ffa2dSMauro Carvalho ChehabIf other operations need to be disallowed on streaming entities (such as
251684ffa2dSMauro Carvalho Chehabchanging entities configuration parameters) drivers can explicitly check the
252684ffa2dSMauro Carvalho Chehabmedia_entity stream_count field to find out if an entity is streaming. This
253684ffa2dSMauro Carvalho Chehaboperation must be done with the media_device graph_mutex held.
254684ffa2dSMauro Carvalho Chehab
255684ffa2dSMauro Carvalho ChehabLink validation
256684ffa2dSMauro Carvalho Chehab^^^^^^^^^^^^^^^
257684ffa2dSMauro Carvalho Chehab
25820b85227SSakari AilusLink validation is performed by :c:func:`media_pipeline_start()`
25974604b73SMauro Carvalho Chehabfor any entity which has sink pads in the pipeline. The
26074604b73SMauro Carvalho Chehab:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
26174604b73SMauro Carvalho Chehabpurpose. In ``link_validate()`` callback, entity driver should check
26274604b73SMauro Carvalho Chehabthat the properties of the source pad of the connected entity and its own
26374604b73SMauro Carvalho Chehabsink pad match. It is up to the type of the entity (and in the end, the
26474604b73SMauro Carvalho Chehabproperties of the hardware) what matching actually means.
265684ffa2dSMauro Carvalho Chehab
266684ffa2dSMauro Carvalho ChehabSubsystems should facilitate link validation by providing subsystem specific
267684ffa2dSMauro Carvalho Chehabhelper functions to provide easy access for commonly needed information, and
268684ffa2dSMauro Carvalho Chehabin the end provide a way to use driver-specific callbacks.
269684ffa2dSMauro Carvalho Chehab
2706e1d824eSShuah KhanMedia Controller Device Allocator API
2716e1d824eSShuah Khan^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2726e1d824eSShuah Khan
2736e1d824eSShuah KhanWhen the media device belongs to more than one driver, the shared media
2746e1d824eSShuah Khandevice is allocated with the shared struct device as the key for look ups.
2756e1d824eSShuah Khan
2766e1d824eSShuah KhanThe shared media device should stay in registered state until the last
2776e1d824eSShuah Khandriver unregisters it. In addition, the media device should be released when
2786e1d824eSShuah Khanall the references are released. Each driver gets a reference to the media
2796e1d824eSShuah Khandevice during probe, when it allocates the media device. If media device is
2806e1d824eSShuah Khanalready allocated, the allocate API bumps up the refcount and returns the
2816e1d824eSShuah Khanexisting media device. The driver puts the reference back in its disconnect
2826e1d824eSShuah Khanroutine when it calls :c:func:`media_device_delete()`.
2836e1d824eSShuah Khan
2846e1d824eSShuah KhanThe media device is unregistered and cleaned up from the kref put handler to
2856e1d824eSShuah Khanensure that the media device stays in registered state until the last driver
2866e1d824eSShuah Khanunregisters the media device.
2876e1d824eSShuah Khan
2886e1d824eSShuah Khan**Driver Usage**
2896e1d824eSShuah Khan
2906e1d824eSShuah KhanDrivers should use the appropriate media-core routines to manage the shared
2916e1d824eSShuah Khanmedia device life-time handling the two states:
2926e1d824eSShuah Khan1. allocate -> register -> delete
2936e1d824eSShuah Khan2. get reference to already registered device -> delete
2946e1d824eSShuah Khan
2956e1d824eSShuah Khancall :c:func:`media_device_delete()` routine to make sure the shared media
2966e1d824eSShuah Khandevice delete is handled correctly.
2976e1d824eSShuah Khan
2986e1d824eSShuah Khan**driver probe:**
2996e1d824eSShuah KhanCall :c:func:`media_device_usb_allocate()` to allocate or get a reference
3006e1d824eSShuah KhanCall :c:func:`media_device_register()`, if media devnode isn't registered
3016e1d824eSShuah Khan
3026e1d824eSShuah Khan**driver disconnect:**
3036e1d824eSShuah KhanCall :c:func:`media_device_delete()` to free the media_device. Freeing is
3046e1d824eSShuah Khanhandled by the kref put handler.
3056e1d824eSShuah Khan
3066e1d824eSShuah KhanAPI Definitions
3076e1d824eSShuah Khan^^^^^^^^^^^^^^^
3086e1d824eSShuah Khan
309684ffa2dSMauro Carvalho Chehab.. kernel-doc:: include/media/media-device.h
310684ffa2dSMauro Carvalho Chehab
311684ffa2dSMauro Carvalho Chehab.. kernel-doc:: include/media/media-devnode.h
312684ffa2dSMauro Carvalho Chehab
313684ffa2dSMauro Carvalho Chehab.. kernel-doc:: include/media/media-entity.h
314496f6f4dSSakari Ailus
315496f6f4dSSakari Ailus.. kernel-doc:: include/media/media-request.h
3166e1d824eSShuah Khan
3176e1d824eSShuah Khan.. kernel-doc:: include/media/media-dev-allocator.h
318