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