162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Media entity 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2010 Nokia Corporation 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 862306a36Sopenharmony_ci * Sakari Ailus <sakari.ailus@iki.fi> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifndef _MEDIA_ENTITY_H 1262306a36Sopenharmony_ci#define _MEDIA_ENTITY_H 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/bitmap.h> 1562306a36Sopenharmony_ci#include <linux/bug.h> 1662306a36Sopenharmony_ci#include <linux/container_of.h> 1762306a36Sopenharmony_ci#include <linux/fwnode.h> 1862306a36Sopenharmony_ci#include <linux/list.h> 1962306a36Sopenharmony_ci#include <linux/media.h> 2062306a36Sopenharmony_ci#include <linux/minmax.h> 2162306a36Sopenharmony_ci#include <linux/types.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* Enums used internally at the media controller to represent graphs */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/** 2662306a36Sopenharmony_ci * enum media_gobj_type - type of a graph object 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * @MEDIA_GRAPH_ENTITY: Identify a media entity 2962306a36Sopenharmony_ci * @MEDIA_GRAPH_PAD: Identify a media pad 3062306a36Sopenharmony_ci * @MEDIA_GRAPH_LINK: Identify a media link 3162306a36Sopenharmony_ci * @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via 3262306a36Sopenharmony_ci * a device node 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cienum media_gobj_type { 3562306a36Sopenharmony_ci MEDIA_GRAPH_ENTITY, 3662306a36Sopenharmony_ci MEDIA_GRAPH_PAD, 3762306a36Sopenharmony_ci MEDIA_GRAPH_LINK, 3862306a36Sopenharmony_ci MEDIA_GRAPH_INTF_DEVNODE, 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define MEDIA_BITS_PER_TYPE 8 4262306a36Sopenharmony_ci#define MEDIA_BITS_PER_ID (32 - MEDIA_BITS_PER_TYPE) 4362306a36Sopenharmony_ci#define MEDIA_ID_MASK GENMASK_ULL(MEDIA_BITS_PER_ID - 1, 0) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* Structs to represent the objects that belong to a media graph */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/** 4862306a36Sopenharmony_ci * struct media_gobj - Define a graph object. 4962306a36Sopenharmony_ci * 5062306a36Sopenharmony_ci * @mdev: Pointer to the struct &media_device that owns the object 5162306a36Sopenharmony_ci * @id: Non-zero object ID identifier. The ID should be unique 5262306a36Sopenharmony_ci * inside a media_device, as it is composed by 5362306a36Sopenharmony_ci * %MEDIA_BITS_PER_TYPE to store the type plus 5462306a36Sopenharmony_ci * %MEDIA_BITS_PER_ID to store the ID 5562306a36Sopenharmony_ci * @list: List entry stored in one of the per-type mdev object lists 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci * All objects on the media graph should have this struct embedded 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistruct media_gobj { 6062306a36Sopenharmony_ci struct media_device *mdev; 6162306a36Sopenharmony_ci u32 id; 6262306a36Sopenharmony_ci struct list_head list; 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/** 6862306a36Sopenharmony_ci * struct media_entity_enum - An enumeration of media entities. 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * @bmap: Bit map in which each bit represents one entity at struct 7162306a36Sopenharmony_ci * media_entity->internal_idx. 7262306a36Sopenharmony_ci * @idx_max: Number of bits in bmap 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cistruct media_entity_enum { 7562306a36Sopenharmony_ci unsigned long *bmap; 7662306a36Sopenharmony_ci int idx_max; 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/** 8062306a36Sopenharmony_ci * struct media_graph - Media graph traversal state 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * @stack: Graph traversal stack; the stack contains information 8362306a36Sopenharmony_ci * on the path the media entities to be walked and the 8462306a36Sopenharmony_ci * links through which they were reached. 8562306a36Sopenharmony_ci * @stack.entity: pointer to &struct media_entity at the graph. 8662306a36Sopenharmony_ci * @stack.link: pointer to &struct list_head. 8762306a36Sopenharmony_ci * @ent_enum: Visited entities 8862306a36Sopenharmony_ci * @top: The top of the stack 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_cistruct media_graph { 9162306a36Sopenharmony_ci struct { 9262306a36Sopenharmony_ci struct media_entity *entity; 9362306a36Sopenharmony_ci struct list_head *link; 9462306a36Sopenharmony_ci } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci struct media_entity_enum ent_enum; 9762306a36Sopenharmony_ci int top; 9862306a36Sopenharmony_ci}; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/** 10162306a36Sopenharmony_ci * struct media_pipeline - Media pipeline related information 10262306a36Sopenharmony_ci * 10362306a36Sopenharmony_ci * @allocated: Media pipeline allocated and freed by the framework 10462306a36Sopenharmony_ci * @mdev: The media device the pipeline is part of 10562306a36Sopenharmony_ci * @pads: List of media_pipeline_pad 10662306a36Sopenharmony_ci * @start_count: Media pipeline start - stop count 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_cistruct media_pipeline { 10962306a36Sopenharmony_ci bool allocated; 11062306a36Sopenharmony_ci struct media_device *mdev; 11162306a36Sopenharmony_ci struct list_head pads; 11262306a36Sopenharmony_ci int start_count; 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/** 11662306a36Sopenharmony_ci * struct media_pipeline_pad - A pad part of a media pipeline 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * @list: Entry in the media_pad pads list 11962306a36Sopenharmony_ci * @pipe: The media_pipeline that the pad is part of 12062306a36Sopenharmony_ci * @pad: The media pad 12162306a36Sopenharmony_ci * 12262306a36Sopenharmony_ci * This structure associate a pad with a media pipeline. Instances of 12362306a36Sopenharmony_ci * media_pipeline_pad are created by media_pipeline_start() when it builds the 12462306a36Sopenharmony_ci * pipeline, and stored in the &media_pad.pads list. media_pipeline_stop() 12562306a36Sopenharmony_ci * removes the entries from the list and deletes them. 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_cistruct media_pipeline_pad { 12862306a36Sopenharmony_ci struct list_head list; 12962306a36Sopenharmony_ci struct media_pipeline *pipe; 13062306a36Sopenharmony_ci struct media_pad *pad; 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/** 13462306a36Sopenharmony_ci * struct media_pipeline_pad_iter - Iterator for media_pipeline_for_each_pad 13562306a36Sopenharmony_ci * 13662306a36Sopenharmony_ci * @cursor: The current element 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_cistruct media_pipeline_pad_iter { 13962306a36Sopenharmony_ci struct list_head *cursor; 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/** 14362306a36Sopenharmony_ci * struct media_pipeline_entity_iter - Iterator for media_pipeline_for_each_entity 14462306a36Sopenharmony_ci * 14562306a36Sopenharmony_ci * @ent_enum: The entity enumeration tracker 14662306a36Sopenharmony_ci * @cursor: The current element 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_cistruct media_pipeline_entity_iter { 14962306a36Sopenharmony_ci struct media_entity_enum ent_enum; 15062306a36Sopenharmony_ci struct list_head *cursor; 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/** 15462306a36Sopenharmony_ci * struct media_link - A link object part of a media graph. 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * @graph_obj: Embedded structure containing the media object common data 15762306a36Sopenharmony_ci * @list: Linked list associated with an entity or an interface that 15862306a36Sopenharmony_ci * owns the link. 15962306a36Sopenharmony_ci * @gobj0: Part of a union. Used to get the pointer for the first 16062306a36Sopenharmony_ci * graph_object of the link. 16162306a36Sopenharmony_ci * @source: Part of a union. Used only if the first object (gobj0) is 16262306a36Sopenharmony_ci * a pad. In that case, it represents the source pad. 16362306a36Sopenharmony_ci * @intf: Part of a union. Used only if the first object (gobj0) is 16462306a36Sopenharmony_ci * an interface. 16562306a36Sopenharmony_ci * @gobj1: Part of a union. Used to get the pointer for the second 16662306a36Sopenharmony_ci * graph_object of the link. 16762306a36Sopenharmony_ci * @sink: Part of a union. Used only if the second object (gobj1) is 16862306a36Sopenharmony_ci * a pad. In that case, it represents the sink pad. 16962306a36Sopenharmony_ci * @entity: Part of a union. Used only if the second object (gobj1) is 17062306a36Sopenharmony_ci * an entity. 17162306a36Sopenharmony_ci * @reverse: Pointer to the link for the reverse direction of a pad to pad 17262306a36Sopenharmony_ci * link. 17362306a36Sopenharmony_ci * @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*) 17462306a36Sopenharmony_ci * @is_backlink: Indicate if the link is a backlink. 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_cistruct media_link { 17762306a36Sopenharmony_ci struct media_gobj graph_obj; 17862306a36Sopenharmony_ci struct list_head list; 17962306a36Sopenharmony_ci union { 18062306a36Sopenharmony_ci struct media_gobj *gobj0; 18162306a36Sopenharmony_ci struct media_pad *source; 18262306a36Sopenharmony_ci struct media_interface *intf; 18362306a36Sopenharmony_ci }; 18462306a36Sopenharmony_ci union { 18562306a36Sopenharmony_ci struct media_gobj *gobj1; 18662306a36Sopenharmony_ci struct media_pad *sink; 18762306a36Sopenharmony_ci struct media_entity *entity; 18862306a36Sopenharmony_ci }; 18962306a36Sopenharmony_ci struct media_link *reverse; 19062306a36Sopenharmony_ci unsigned long flags; 19162306a36Sopenharmony_ci bool is_backlink; 19262306a36Sopenharmony_ci}; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci/** 19562306a36Sopenharmony_ci * enum media_pad_signal_type - type of the signal inside a media pad 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * @PAD_SIGNAL_DEFAULT: 19862306a36Sopenharmony_ci * Default signal. Use this when all inputs or all outputs are 19962306a36Sopenharmony_ci * uniquely identified by the pad number. 20062306a36Sopenharmony_ci * @PAD_SIGNAL_ANALOG: 20162306a36Sopenharmony_ci * The pad contains an analog signal. It can be Radio Frequency, 20262306a36Sopenharmony_ci * Intermediate Frequency, a baseband signal or sub-carriers. 20362306a36Sopenharmony_ci * Tuner inputs, IF-PLL demodulators, composite and s-video signals 20462306a36Sopenharmony_ci * should use it. 20562306a36Sopenharmony_ci * @PAD_SIGNAL_DV: 20662306a36Sopenharmony_ci * Contains a digital video signal, with can be a bitstream of samples 20762306a36Sopenharmony_ci * taken from an analog TV video source. On such case, it usually 20862306a36Sopenharmony_ci * contains the VBI data on it. 20962306a36Sopenharmony_ci * @PAD_SIGNAL_AUDIO: 21062306a36Sopenharmony_ci * Contains an Intermediate Frequency analog signal from an audio 21162306a36Sopenharmony_ci * sub-carrier or an audio bitstream. IF signals are provided by tuners 21262306a36Sopenharmony_ci * and consumed by audio AM/FM decoders. Bitstream audio is provided by 21362306a36Sopenharmony_ci * an audio decoder. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_cienum media_pad_signal_type { 21662306a36Sopenharmony_ci PAD_SIGNAL_DEFAULT = 0, 21762306a36Sopenharmony_ci PAD_SIGNAL_ANALOG, 21862306a36Sopenharmony_ci PAD_SIGNAL_DV, 21962306a36Sopenharmony_ci PAD_SIGNAL_AUDIO, 22062306a36Sopenharmony_ci}; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci/** 22362306a36Sopenharmony_ci * struct media_pad - A media pad graph object. 22462306a36Sopenharmony_ci * 22562306a36Sopenharmony_ci * @graph_obj: Embedded structure containing the media object common data 22662306a36Sopenharmony_ci * @entity: Entity this pad belongs to 22762306a36Sopenharmony_ci * @index: Pad index in the entity pads array, numbered from 0 to n 22862306a36Sopenharmony_ci * @num_links: Number of links connected to this pad 22962306a36Sopenharmony_ci * @sig_type: Type of the signal inside a media pad 23062306a36Sopenharmony_ci * @flags: Pad flags, as defined in 23162306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 23262306a36Sopenharmony_ci * (seek for ``MEDIA_PAD_FL_*``) 23362306a36Sopenharmony_ci * @pipe: Pipeline this pad belongs to. Use media_entity_pipeline() to 23462306a36Sopenharmony_ci * access this field. 23562306a36Sopenharmony_ci */ 23662306a36Sopenharmony_cistruct media_pad { 23762306a36Sopenharmony_ci struct media_gobj graph_obj; /* must be first field in struct */ 23862306a36Sopenharmony_ci struct media_entity *entity; 23962306a36Sopenharmony_ci u16 index; 24062306a36Sopenharmony_ci u16 num_links; 24162306a36Sopenharmony_ci enum media_pad_signal_type sig_type; 24262306a36Sopenharmony_ci unsigned long flags; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci /* 24562306a36Sopenharmony_ci * The fields below are private, and should only be accessed via 24662306a36Sopenharmony_ci * appropriate functions. 24762306a36Sopenharmony_ci */ 24862306a36Sopenharmony_ci struct media_pipeline *pipe; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/** 25262306a36Sopenharmony_ci * struct media_entity_operations - Media entity operations 25362306a36Sopenharmony_ci * @get_fwnode_pad: Return the pad number based on a fwnode endpoint or 25462306a36Sopenharmony_ci * a negative value on error. This operation can be used 25562306a36Sopenharmony_ci * to map a fwnode to a media pad number. Optional. 25662306a36Sopenharmony_ci * @link_setup: Notify the entity of link changes. The operation can 25762306a36Sopenharmony_ci * return an error, in which case link setup will be 25862306a36Sopenharmony_ci * cancelled. Optional. 25962306a36Sopenharmony_ci * @link_validate: Return whether a link is valid from the entity point of 26062306a36Sopenharmony_ci * view. The media_pipeline_start() function 26162306a36Sopenharmony_ci * validates all links by calling this operation. Optional. 26262306a36Sopenharmony_ci * @has_pad_interdep: Return whether two pads of the entity are 26362306a36Sopenharmony_ci * interdependent. If two pads are interdependent they are 26462306a36Sopenharmony_ci * part of the same pipeline and enabling one of the pads 26562306a36Sopenharmony_ci * means that the other pad will become "locked" and 26662306a36Sopenharmony_ci * doesn't allow configuration changes. pad0 and pad1 are 26762306a36Sopenharmony_ci * guaranteed to not both be sinks or sources. Never call 26862306a36Sopenharmony_ci * the .has_pad_interdep() operation directly, always use 26962306a36Sopenharmony_ci * media_entity_has_pad_interdep(). 27062306a36Sopenharmony_ci * Optional: If the operation isn't implemented all pads 27162306a36Sopenharmony_ci * will be considered as interdependent. 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * .. note:: 27462306a36Sopenharmony_ci * 27562306a36Sopenharmony_ci * Those these callbacks are called with struct &media_device.graph_mutex 27662306a36Sopenharmony_ci * mutex held. 27762306a36Sopenharmony_ci */ 27862306a36Sopenharmony_cistruct media_entity_operations { 27962306a36Sopenharmony_ci int (*get_fwnode_pad)(struct media_entity *entity, 28062306a36Sopenharmony_ci struct fwnode_endpoint *endpoint); 28162306a36Sopenharmony_ci int (*link_setup)(struct media_entity *entity, 28262306a36Sopenharmony_ci const struct media_pad *local, 28362306a36Sopenharmony_ci const struct media_pad *remote, u32 flags); 28462306a36Sopenharmony_ci int (*link_validate)(struct media_link *link); 28562306a36Sopenharmony_ci bool (*has_pad_interdep)(struct media_entity *entity, unsigned int pad0, 28662306a36Sopenharmony_ci unsigned int pad1); 28762306a36Sopenharmony_ci}; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/** 29062306a36Sopenharmony_ci * enum media_entity_type - Media entity type 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci * @MEDIA_ENTITY_TYPE_BASE: 29362306a36Sopenharmony_ci * The entity isn't embedded in another subsystem structure. 29462306a36Sopenharmony_ci * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE: 29562306a36Sopenharmony_ci * The entity is embedded in a struct video_device instance. 29662306a36Sopenharmony_ci * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV: 29762306a36Sopenharmony_ci * The entity is embedded in a struct v4l2_subdev instance. 29862306a36Sopenharmony_ci * 29962306a36Sopenharmony_ci * Media entity objects are often not instantiated directly, but the media 30062306a36Sopenharmony_ci * entity structure is inherited by (through embedding) other subsystem-specific 30162306a36Sopenharmony_ci * structures. The media entity type identifies the type of the subclass 30262306a36Sopenharmony_ci * structure that implements a media entity instance. 30362306a36Sopenharmony_ci * 30462306a36Sopenharmony_ci * This allows runtime type identification of media entities and safe casting to 30562306a36Sopenharmony_ci * the correct object type. For instance, a media entity structure instance 30662306a36Sopenharmony_ci * embedded in a v4l2_subdev structure instance will have the type 30762306a36Sopenharmony_ci * %MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a &v4l2_subdev 30862306a36Sopenharmony_ci * structure using the container_of() macro. 30962306a36Sopenharmony_ci */ 31062306a36Sopenharmony_cienum media_entity_type { 31162306a36Sopenharmony_ci MEDIA_ENTITY_TYPE_BASE, 31262306a36Sopenharmony_ci MEDIA_ENTITY_TYPE_VIDEO_DEVICE, 31362306a36Sopenharmony_ci MEDIA_ENTITY_TYPE_V4L2_SUBDEV, 31462306a36Sopenharmony_ci}; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci/** 31762306a36Sopenharmony_ci * struct media_entity - A media entity graph object. 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci * @graph_obj: Embedded structure containing the media object common data. 32062306a36Sopenharmony_ci * @name: Entity name. 32162306a36Sopenharmony_ci * @obj_type: Type of the object that implements the media_entity. 32262306a36Sopenharmony_ci * @function: Entity main function, as defined in 32362306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 32462306a36Sopenharmony_ci * (seek for ``MEDIA_ENT_F_*``) 32562306a36Sopenharmony_ci * @flags: Entity flags, as defined in 32662306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 32762306a36Sopenharmony_ci * (seek for ``MEDIA_ENT_FL_*``) 32862306a36Sopenharmony_ci * @num_pads: Number of sink and source pads. 32962306a36Sopenharmony_ci * @num_links: Total number of links, forward and back, enabled and disabled. 33062306a36Sopenharmony_ci * @num_backlinks: Number of backlinks 33162306a36Sopenharmony_ci * @internal_idx: An unique internal entity specific number. The numbers are 33262306a36Sopenharmony_ci * re-used if entities are unregistered or registered again. 33362306a36Sopenharmony_ci * @pads: Pads array with the size defined by @num_pads. 33462306a36Sopenharmony_ci * @links: List of data links. 33562306a36Sopenharmony_ci * @ops: Entity operations. 33662306a36Sopenharmony_ci * @use_count: Use count for the entity. 33762306a36Sopenharmony_ci * @info: Union with devnode information. Kept just for backward 33862306a36Sopenharmony_ci * compatibility. 33962306a36Sopenharmony_ci * @info.dev: Contains device major and minor info. 34062306a36Sopenharmony_ci * @info.dev.major: device node major, if the device is a devnode. 34162306a36Sopenharmony_ci * @info.dev.minor: device node minor, if the device is a devnode. 34262306a36Sopenharmony_ci * @major: Devnode major number (zero if not applicable). Kept just 34362306a36Sopenharmony_ci * for backward compatibility. 34462306a36Sopenharmony_ci * @minor: Devnode minor number (zero if not applicable). Kept just 34562306a36Sopenharmony_ci * for backward compatibility. 34662306a36Sopenharmony_ci * 34762306a36Sopenharmony_ci * .. note:: 34862306a36Sopenharmony_ci * 34962306a36Sopenharmony_ci * The @use_count reference count must never be negative, but is a signed 35062306a36Sopenharmony_ci * integer on purpose: a simple ``WARN_ON(<0)`` check can be used to detect 35162306a36Sopenharmony_ci * reference count bugs that would make it negative. 35262306a36Sopenharmony_ci */ 35362306a36Sopenharmony_cistruct media_entity { 35462306a36Sopenharmony_ci struct media_gobj graph_obj; /* must be first field in struct */ 35562306a36Sopenharmony_ci const char *name; 35662306a36Sopenharmony_ci enum media_entity_type obj_type; 35762306a36Sopenharmony_ci u32 function; 35862306a36Sopenharmony_ci unsigned long flags; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci u16 num_pads; 36162306a36Sopenharmony_ci u16 num_links; 36262306a36Sopenharmony_ci u16 num_backlinks; 36362306a36Sopenharmony_ci int internal_idx; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci struct media_pad *pads; 36662306a36Sopenharmony_ci struct list_head links; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci const struct media_entity_operations *ops; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci int use_count; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci union { 37362306a36Sopenharmony_ci struct { 37462306a36Sopenharmony_ci u32 major; 37562306a36Sopenharmony_ci u32 minor; 37662306a36Sopenharmony_ci } dev; 37762306a36Sopenharmony_ci } info; 37862306a36Sopenharmony_ci}; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci/** 38162306a36Sopenharmony_ci * media_entity_for_each_pad - Iterate on all pads in an entity 38262306a36Sopenharmony_ci * @entity: The entity the pads belong to 38362306a36Sopenharmony_ci * @iter: The iterator pad 38462306a36Sopenharmony_ci * 38562306a36Sopenharmony_ci * Iterate on all pads in a media entity. 38662306a36Sopenharmony_ci */ 38762306a36Sopenharmony_ci#define media_entity_for_each_pad(entity, iter) \ 38862306a36Sopenharmony_ci for (iter = (entity)->pads; \ 38962306a36Sopenharmony_ci iter < &(entity)->pads[(entity)->num_pads]; \ 39062306a36Sopenharmony_ci ++iter) 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci/** 39362306a36Sopenharmony_ci * struct media_interface - A media interface graph object. 39462306a36Sopenharmony_ci * 39562306a36Sopenharmony_ci * @graph_obj: embedded graph object 39662306a36Sopenharmony_ci * @links: List of links pointing to graph entities 39762306a36Sopenharmony_ci * @type: Type of the interface as defined in 39862306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 39962306a36Sopenharmony_ci * (seek for ``MEDIA_INTF_T_*``) 40062306a36Sopenharmony_ci * @flags: Interface flags as defined in 40162306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 40262306a36Sopenharmony_ci * (seek for ``MEDIA_INTF_FL_*``) 40362306a36Sopenharmony_ci * 40462306a36Sopenharmony_ci * .. note:: 40562306a36Sopenharmony_ci * 40662306a36Sopenharmony_ci * Currently, no flags for &media_interface is defined. 40762306a36Sopenharmony_ci */ 40862306a36Sopenharmony_cistruct media_interface { 40962306a36Sopenharmony_ci struct media_gobj graph_obj; 41062306a36Sopenharmony_ci struct list_head links; 41162306a36Sopenharmony_ci u32 type; 41262306a36Sopenharmony_ci u32 flags; 41362306a36Sopenharmony_ci}; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci/** 41662306a36Sopenharmony_ci * struct media_intf_devnode - A media interface via a device node. 41762306a36Sopenharmony_ci * 41862306a36Sopenharmony_ci * @intf: embedded interface object 41962306a36Sopenharmony_ci * @major: Major number of a device node 42062306a36Sopenharmony_ci * @minor: Minor number of a device node 42162306a36Sopenharmony_ci */ 42262306a36Sopenharmony_cistruct media_intf_devnode { 42362306a36Sopenharmony_ci struct media_interface intf; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci /* Should match the fields at media_v2_intf_devnode */ 42662306a36Sopenharmony_ci u32 major; 42762306a36Sopenharmony_ci u32 minor; 42862306a36Sopenharmony_ci}; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/** 43162306a36Sopenharmony_ci * media_entity_id() - return the media entity graph object id 43262306a36Sopenharmony_ci * 43362306a36Sopenharmony_ci * @entity: pointer to &media_entity 43462306a36Sopenharmony_ci */ 43562306a36Sopenharmony_cistatic inline u32 media_entity_id(struct media_entity *entity) 43662306a36Sopenharmony_ci{ 43762306a36Sopenharmony_ci return entity->graph_obj.id; 43862306a36Sopenharmony_ci} 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci/** 44162306a36Sopenharmony_ci * media_type() - return the media object type 44262306a36Sopenharmony_ci * 44362306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 44462306a36Sopenharmony_ci */ 44562306a36Sopenharmony_cistatic inline enum media_gobj_type media_type(struct media_gobj *gobj) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci return gobj->id >> MEDIA_BITS_PER_ID; 44862306a36Sopenharmony_ci} 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci/** 45162306a36Sopenharmony_ci * media_id() - return the media object ID 45262306a36Sopenharmony_ci * 45362306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 45462306a36Sopenharmony_ci */ 45562306a36Sopenharmony_cistatic inline u32 media_id(struct media_gobj *gobj) 45662306a36Sopenharmony_ci{ 45762306a36Sopenharmony_ci return gobj->id & MEDIA_ID_MASK; 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/** 46162306a36Sopenharmony_ci * media_gobj_gen_id() - encapsulates type and ID on at the object ID 46262306a36Sopenharmony_ci * 46362306a36Sopenharmony_ci * @type: object type as define at enum &media_gobj_type. 46462306a36Sopenharmony_ci * @local_id: next ID, from struct &media_device.id. 46562306a36Sopenharmony_ci */ 46662306a36Sopenharmony_cistatic inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci u32 id; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci id = type << MEDIA_BITS_PER_ID; 47162306a36Sopenharmony_ci id |= local_id & MEDIA_ID_MASK; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci return id; 47462306a36Sopenharmony_ci} 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci/** 47762306a36Sopenharmony_ci * is_media_entity_v4l2_video_device() - Check if the entity is a video_device 47862306a36Sopenharmony_ci * @entity: pointer to entity 47962306a36Sopenharmony_ci * 48062306a36Sopenharmony_ci * Return: %true if the entity is an instance of a video_device object and can 48162306a36Sopenharmony_ci * safely be cast to a struct video_device using the container_of() macro, or 48262306a36Sopenharmony_ci * %false otherwise. 48362306a36Sopenharmony_ci */ 48462306a36Sopenharmony_cistatic inline bool is_media_entity_v4l2_video_device(struct media_entity *entity) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci/** 49062306a36Sopenharmony_ci * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev 49162306a36Sopenharmony_ci * @entity: pointer to entity 49262306a36Sopenharmony_ci * 49362306a36Sopenharmony_ci * Return: %true if the entity is an instance of a &v4l2_subdev object and can 49462306a36Sopenharmony_ci * safely be cast to a struct &v4l2_subdev using the container_of() macro, or 49562306a36Sopenharmony_ci * %false otherwise. 49662306a36Sopenharmony_ci */ 49762306a36Sopenharmony_cistatic inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) 49862306a36Sopenharmony_ci{ 49962306a36Sopenharmony_ci return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV; 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci/** 50362306a36Sopenharmony_ci * media_entity_enum_init - Initialise an entity enumeration 50462306a36Sopenharmony_ci * 50562306a36Sopenharmony_ci * @ent_enum: Entity enumeration to be initialised 50662306a36Sopenharmony_ci * @mdev: The related media device 50762306a36Sopenharmony_ci * 50862306a36Sopenharmony_ci * Return: zero on success or a negative error code. 50962306a36Sopenharmony_ci */ 51062306a36Sopenharmony_ci__must_check int media_entity_enum_init(struct media_entity_enum *ent_enum, 51162306a36Sopenharmony_ci struct media_device *mdev); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci/** 51462306a36Sopenharmony_ci * media_entity_enum_cleanup - Release resources of an entity enumeration 51562306a36Sopenharmony_ci * 51662306a36Sopenharmony_ci * @ent_enum: Entity enumeration to be released 51762306a36Sopenharmony_ci */ 51862306a36Sopenharmony_civoid media_entity_enum_cleanup(struct media_entity_enum *ent_enum); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci/** 52162306a36Sopenharmony_ci * media_entity_enum_zero - Clear the entire enum 52262306a36Sopenharmony_ci * 52362306a36Sopenharmony_ci * @ent_enum: Entity enumeration to be cleared 52462306a36Sopenharmony_ci */ 52562306a36Sopenharmony_cistatic inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) 52662306a36Sopenharmony_ci{ 52762306a36Sopenharmony_ci bitmap_zero(ent_enum->bmap, ent_enum->idx_max); 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci/** 53162306a36Sopenharmony_ci * media_entity_enum_set - Mark a single entity in the enum 53262306a36Sopenharmony_ci * 53362306a36Sopenharmony_ci * @ent_enum: Entity enumeration 53462306a36Sopenharmony_ci * @entity: Entity to be marked 53562306a36Sopenharmony_ci */ 53662306a36Sopenharmony_cistatic inline void media_entity_enum_set(struct media_entity_enum *ent_enum, 53762306a36Sopenharmony_ci struct media_entity *entity) 53862306a36Sopenharmony_ci{ 53962306a36Sopenharmony_ci if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) 54062306a36Sopenharmony_ci return; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci __set_bit(entity->internal_idx, ent_enum->bmap); 54362306a36Sopenharmony_ci} 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci/** 54662306a36Sopenharmony_ci * media_entity_enum_clear - Unmark a single entity in the enum 54762306a36Sopenharmony_ci * 54862306a36Sopenharmony_ci * @ent_enum: Entity enumeration 54962306a36Sopenharmony_ci * @entity: Entity to be unmarked 55062306a36Sopenharmony_ci */ 55162306a36Sopenharmony_cistatic inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, 55262306a36Sopenharmony_ci struct media_entity *entity) 55362306a36Sopenharmony_ci{ 55462306a36Sopenharmony_ci if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) 55562306a36Sopenharmony_ci return; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci __clear_bit(entity->internal_idx, ent_enum->bmap); 55862306a36Sopenharmony_ci} 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci/** 56162306a36Sopenharmony_ci * media_entity_enum_test - Test whether the entity is marked 56262306a36Sopenharmony_ci * 56362306a36Sopenharmony_ci * @ent_enum: Entity enumeration 56462306a36Sopenharmony_ci * @entity: Entity to be tested 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci * Returns %true if the entity was marked. 56762306a36Sopenharmony_ci */ 56862306a36Sopenharmony_cistatic inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, 56962306a36Sopenharmony_ci struct media_entity *entity) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) 57262306a36Sopenharmony_ci return true; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci return test_bit(entity->internal_idx, ent_enum->bmap); 57562306a36Sopenharmony_ci} 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci/** 57862306a36Sopenharmony_ci * media_entity_enum_test_and_set - Test whether the entity is marked, 57962306a36Sopenharmony_ci * and mark it 58062306a36Sopenharmony_ci * 58162306a36Sopenharmony_ci * @ent_enum: Entity enumeration 58262306a36Sopenharmony_ci * @entity: Entity to be tested 58362306a36Sopenharmony_ci * 58462306a36Sopenharmony_ci * Returns %true if the entity was marked, and mark it before doing so. 58562306a36Sopenharmony_ci */ 58662306a36Sopenharmony_cistatic inline bool 58762306a36Sopenharmony_cimedia_entity_enum_test_and_set(struct media_entity_enum *ent_enum, 58862306a36Sopenharmony_ci struct media_entity *entity) 58962306a36Sopenharmony_ci{ 59062306a36Sopenharmony_ci if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) 59162306a36Sopenharmony_ci return true; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci return __test_and_set_bit(entity->internal_idx, ent_enum->bmap); 59462306a36Sopenharmony_ci} 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci/** 59762306a36Sopenharmony_ci * media_entity_enum_empty - Test whether the entire enum is empty 59862306a36Sopenharmony_ci * 59962306a36Sopenharmony_ci * @ent_enum: Entity enumeration 60062306a36Sopenharmony_ci * 60162306a36Sopenharmony_ci * Return: %true if the entity was empty. 60262306a36Sopenharmony_ci */ 60362306a36Sopenharmony_cistatic inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) 60462306a36Sopenharmony_ci{ 60562306a36Sopenharmony_ci return bitmap_empty(ent_enum->bmap, ent_enum->idx_max); 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci/** 60962306a36Sopenharmony_ci * media_entity_enum_intersects - Test whether two enums intersect 61062306a36Sopenharmony_ci * 61162306a36Sopenharmony_ci * @ent_enum1: First entity enumeration 61262306a36Sopenharmony_ci * @ent_enum2: Second entity enumeration 61362306a36Sopenharmony_ci * 61462306a36Sopenharmony_ci * Return: %true if entity enumerations @ent_enum1 and @ent_enum2 intersect, 61562306a36Sopenharmony_ci * otherwise %false. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_cistatic inline bool media_entity_enum_intersects( 61862306a36Sopenharmony_ci struct media_entity_enum *ent_enum1, 61962306a36Sopenharmony_ci struct media_entity_enum *ent_enum2) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci WARN_ON(ent_enum1->idx_max != ent_enum2->idx_max); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci return bitmap_intersects(ent_enum1->bmap, ent_enum2->bmap, 62462306a36Sopenharmony_ci min(ent_enum1->idx_max, ent_enum2->idx_max)); 62562306a36Sopenharmony_ci} 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci/** 62862306a36Sopenharmony_ci * gobj_to_entity - returns the struct &media_entity pointer from the 62962306a36Sopenharmony_ci * @gobj contained on it. 63062306a36Sopenharmony_ci * 63162306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 63262306a36Sopenharmony_ci */ 63362306a36Sopenharmony_ci#define gobj_to_entity(gobj) \ 63462306a36Sopenharmony_ci container_of(gobj, struct media_entity, graph_obj) 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci/** 63762306a36Sopenharmony_ci * gobj_to_pad - returns the struct &media_pad pointer from the 63862306a36Sopenharmony_ci * @gobj contained on it. 63962306a36Sopenharmony_ci * 64062306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 64162306a36Sopenharmony_ci */ 64262306a36Sopenharmony_ci#define gobj_to_pad(gobj) \ 64362306a36Sopenharmony_ci container_of(gobj, struct media_pad, graph_obj) 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci/** 64662306a36Sopenharmony_ci * gobj_to_link - returns the struct &media_link pointer from the 64762306a36Sopenharmony_ci * @gobj contained on it. 64862306a36Sopenharmony_ci * 64962306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 65062306a36Sopenharmony_ci */ 65162306a36Sopenharmony_ci#define gobj_to_link(gobj) \ 65262306a36Sopenharmony_ci container_of(gobj, struct media_link, graph_obj) 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci/** 65562306a36Sopenharmony_ci * gobj_to_intf - returns the struct &media_interface pointer from the 65662306a36Sopenharmony_ci * @gobj contained on it. 65762306a36Sopenharmony_ci * 65862306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 65962306a36Sopenharmony_ci */ 66062306a36Sopenharmony_ci#define gobj_to_intf(gobj) \ 66162306a36Sopenharmony_ci container_of(gobj, struct media_interface, graph_obj) 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci/** 66462306a36Sopenharmony_ci * intf_to_devnode - returns the struct media_intf_devnode pointer from the 66562306a36Sopenharmony_ci * @intf contained on it. 66662306a36Sopenharmony_ci * 66762306a36Sopenharmony_ci * @intf: Pointer to struct &media_intf_devnode 66862306a36Sopenharmony_ci */ 66962306a36Sopenharmony_ci#define intf_to_devnode(intf) \ 67062306a36Sopenharmony_ci container_of(intf, struct media_intf_devnode, intf) 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci/** 67362306a36Sopenharmony_ci * media_gobj_create - Initialize a graph object 67462306a36Sopenharmony_ci * 67562306a36Sopenharmony_ci * @mdev: Pointer to the &media_device that contains the object 67662306a36Sopenharmony_ci * @type: Type of the object 67762306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 67862306a36Sopenharmony_ci * 67962306a36Sopenharmony_ci * This routine initializes the embedded struct &media_gobj inside a 68062306a36Sopenharmony_ci * media graph object. It is called automatically if ``media_*_create`` 68162306a36Sopenharmony_ci * function calls are used. However, if the object (entity, link, pad, 68262306a36Sopenharmony_ci * interface) is embedded on some other object, this function should be 68362306a36Sopenharmony_ci * called before registering the object at the media controller. 68462306a36Sopenharmony_ci */ 68562306a36Sopenharmony_civoid media_gobj_create(struct media_device *mdev, 68662306a36Sopenharmony_ci enum media_gobj_type type, 68762306a36Sopenharmony_ci struct media_gobj *gobj); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci/** 69062306a36Sopenharmony_ci * media_gobj_destroy - Stop using a graph object on a media device 69162306a36Sopenharmony_ci * 69262306a36Sopenharmony_ci * @gobj: Pointer to the struct &media_gobj graph object 69362306a36Sopenharmony_ci * 69462306a36Sopenharmony_ci * This should be called by all routines like media_device_unregister() 69562306a36Sopenharmony_ci * that remove/destroy media graph objects. 69662306a36Sopenharmony_ci */ 69762306a36Sopenharmony_civoid media_gobj_destroy(struct media_gobj *gobj); 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci/** 70062306a36Sopenharmony_ci * media_entity_pads_init() - Initialize the entity pads 70162306a36Sopenharmony_ci * 70262306a36Sopenharmony_ci * @entity: entity where the pads belong 70362306a36Sopenharmony_ci * @num_pads: total number of sink and source pads 70462306a36Sopenharmony_ci * @pads: Array of @num_pads pads. 70562306a36Sopenharmony_ci * 70662306a36Sopenharmony_ci * The pads array is managed by the entity driver and passed to 70762306a36Sopenharmony_ci * media_entity_pads_init() where its pointer will be stored in the 70862306a36Sopenharmony_ci * &media_entity structure. 70962306a36Sopenharmony_ci * 71062306a36Sopenharmony_ci * If no pads are needed, drivers could either directly fill 71162306a36Sopenharmony_ci * &media_entity->num_pads with 0 and &media_entity->pads with %NULL or call 71262306a36Sopenharmony_ci * this function that will do the same. 71362306a36Sopenharmony_ci * 71462306a36Sopenharmony_ci * As the number of pads is known in advance, the pads array is not allocated 71562306a36Sopenharmony_ci * dynamically but is managed by the entity driver. Most drivers will embed the 71662306a36Sopenharmony_ci * pads array in a driver-specific structure, avoiding dynamic allocation. 71762306a36Sopenharmony_ci * 71862306a36Sopenharmony_ci * Drivers must set the direction of every pad in the pads array before calling 71962306a36Sopenharmony_ci * media_entity_pads_init(). The function will initialize the other pads fields. 72062306a36Sopenharmony_ci */ 72162306a36Sopenharmony_ciint media_entity_pads_init(struct media_entity *entity, u16 num_pads, 72262306a36Sopenharmony_ci struct media_pad *pads); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci/** 72562306a36Sopenharmony_ci * media_entity_cleanup() - free resources associated with an entity 72662306a36Sopenharmony_ci * 72762306a36Sopenharmony_ci * @entity: entity where the pads belong 72862306a36Sopenharmony_ci * 72962306a36Sopenharmony_ci * This function must be called during the cleanup phase after unregistering 73062306a36Sopenharmony_ci * the entity (currently, it does nothing). 73162306a36Sopenharmony_ci * 73262306a36Sopenharmony_ci * Calling media_entity_cleanup() on a media_entity whose memory has been 73362306a36Sopenharmony_ci * zeroed but that has not been initialized with media_entity_pad_init() is 73462306a36Sopenharmony_ci * valid and is a no-op. 73562306a36Sopenharmony_ci */ 73662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) 73762306a36Sopenharmony_cistatic inline void media_entity_cleanup(struct media_entity *entity) {} 73862306a36Sopenharmony_ci#else 73962306a36Sopenharmony_ci#define media_entity_cleanup(entity) do { } while (false) 74062306a36Sopenharmony_ci#endif 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci/** 74362306a36Sopenharmony_ci * media_get_pad_index() - retrieves a pad index from an entity 74462306a36Sopenharmony_ci * 74562306a36Sopenharmony_ci * @entity: entity where the pads belong 74662306a36Sopenharmony_ci * @pad_type: the type of the pad, one of MEDIA_PAD_FL_* pad types 74762306a36Sopenharmony_ci * @sig_type: type of signal of the pad to be search 74862306a36Sopenharmony_ci * 74962306a36Sopenharmony_ci * This helper function finds the first pad index inside an entity that 75062306a36Sopenharmony_ci * satisfies both @is_sink and @sig_type conditions. 75162306a36Sopenharmony_ci * 75262306a36Sopenharmony_ci * Return: 75362306a36Sopenharmony_ci * 75462306a36Sopenharmony_ci * On success, return the pad number. If the pad was not found or the media 75562306a36Sopenharmony_ci * entity is a NULL pointer, return -EINVAL. 75662306a36Sopenharmony_ci */ 75762306a36Sopenharmony_ciint media_get_pad_index(struct media_entity *entity, u32 pad_type, 75862306a36Sopenharmony_ci enum media_pad_signal_type sig_type); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci/** 76162306a36Sopenharmony_ci * media_create_pad_link() - creates a link between two entities. 76262306a36Sopenharmony_ci * 76362306a36Sopenharmony_ci * @source: pointer to &media_entity of the source pad. 76462306a36Sopenharmony_ci * @source_pad: number of the source pad in the pads array 76562306a36Sopenharmony_ci * @sink: pointer to &media_entity of the sink pad. 76662306a36Sopenharmony_ci * @sink_pad: number of the sink pad in the pads array. 76762306a36Sopenharmony_ci * @flags: Link flags, as defined in 76862306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 76962306a36Sopenharmony_ci * ( seek for ``MEDIA_LNK_FL_*``) 77062306a36Sopenharmony_ci * 77162306a36Sopenharmony_ci * Valid values for flags: 77262306a36Sopenharmony_ci * 77362306a36Sopenharmony_ci * %MEDIA_LNK_FL_ENABLED 77462306a36Sopenharmony_ci * Indicates that the link is enabled and can be used to transfer media data. 77562306a36Sopenharmony_ci * When two or more links target a sink pad, only one of them can be 77662306a36Sopenharmony_ci * enabled at a time. 77762306a36Sopenharmony_ci * 77862306a36Sopenharmony_ci * %MEDIA_LNK_FL_IMMUTABLE 77962306a36Sopenharmony_ci * Indicates that the link enabled state can't be modified at runtime. If 78062306a36Sopenharmony_ci * %MEDIA_LNK_FL_IMMUTABLE is set, then %MEDIA_LNK_FL_ENABLED must also be 78162306a36Sopenharmony_ci * set, since an immutable link is always enabled. 78262306a36Sopenharmony_ci * 78362306a36Sopenharmony_ci * .. note:: 78462306a36Sopenharmony_ci * 78562306a36Sopenharmony_ci * Before calling this function, media_entity_pads_init() and 78662306a36Sopenharmony_ci * media_device_register_entity() should be called previously for both ends. 78762306a36Sopenharmony_ci */ 78862306a36Sopenharmony_ci__must_check int media_create_pad_link(struct media_entity *source, 78962306a36Sopenharmony_ci u16 source_pad, struct media_entity *sink, 79062306a36Sopenharmony_ci u16 sink_pad, u32 flags); 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci/** 79362306a36Sopenharmony_ci * media_create_pad_links() - creates a link between two entities. 79462306a36Sopenharmony_ci * 79562306a36Sopenharmony_ci * @mdev: Pointer to the media_device that contains the object 79662306a36Sopenharmony_ci * @source_function: Function of the source entities. Used only if @source is 79762306a36Sopenharmony_ci * NULL. 79862306a36Sopenharmony_ci * @source: pointer to &media_entity of the source pad. If NULL, it will use 79962306a36Sopenharmony_ci * all entities that matches the @sink_function. 80062306a36Sopenharmony_ci * @source_pad: number of the source pad in the pads array 80162306a36Sopenharmony_ci * @sink_function: Function of the sink entities. Used only if @sink is NULL. 80262306a36Sopenharmony_ci * @sink: pointer to &media_entity of the sink pad. If NULL, it will use 80362306a36Sopenharmony_ci * all entities that matches the @sink_function. 80462306a36Sopenharmony_ci * @sink_pad: number of the sink pad in the pads array. 80562306a36Sopenharmony_ci * @flags: Link flags, as defined in include/uapi/linux/media.h. 80662306a36Sopenharmony_ci * @allow_both_undefined: if %true, then both @source and @sink can be NULL. 80762306a36Sopenharmony_ci * In such case, it will create a crossbar between all entities that 80862306a36Sopenharmony_ci * matches @source_function to all entities that matches @sink_function. 80962306a36Sopenharmony_ci * If %false, it will return 0 and won't create any link if both @source 81062306a36Sopenharmony_ci * and @sink are NULL. 81162306a36Sopenharmony_ci * 81262306a36Sopenharmony_ci * Valid values for flags: 81362306a36Sopenharmony_ci * 81462306a36Sopenharmony_ci * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be 81562306a36Sopenharmony_ci * used to transfer media data. If multiple links are created and this 81662306a36Sopenharmony_ci * flag is passed as an argument, only the first created link will have 81762306a36Sopenharmony_ci * this flag. 81862306a36Sopenharmony_ci * 81962306a36Sopenharmony_ci * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't 82062306a36Sopenharmony_ci * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then 82162306a36Sopenharmony_ci * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is 82262306a36Sopenharmony_ci * always enabled. 82362306a36Sopenharmony_ci * 82462306a36Sopenharmony_ci * It is common for some devices to have multiple source and/or sink entities 82562306a36Sopenharmony_ci * of the same type that should be linked. While media_create_pad_link() 82662306a36Sopenharmony_ci * creates link by link, this function is meant to allow 1:n, n:1 and even 82762306a36Sopenharmony_ci * cross-bar (n:n) links. 82862306a36Sopenharmony_ci * 82962306a36Sopenharmony_ci * .. note:: 83062306a36Sopenharmony_ci * 83162306a36Sopenharmony_ci * Before calling this function, media_entity_pads_init() and 83262306a36Sopenharmony_ci * media_device_register_entity() should be called previously for the 83362306a36Sopenharmony_ci * entities to be linked. 83462306a36Sopenharmony_ci */ 83562306a36Sopenharmony_ciint media_create_pad_links(const struct media_device *mdev, 83662306a36Sopenharmony_ci const u32 source_function, 83762306a36Sopenharmony_ci struct media_entity *source, 83862306a36Sopenharmony_ci const u16 source_pad, 83962306a36Sopenharmony_ci const u32 sink_function, 84062306a36Sopenharmony_ci struct media_entity *sink, 84162306a36Sopenharmony_ci const u16 sink_pad, 84262306a36Sopenharmony_ci u32 flags, 84362306a36Sopenharmony_ci const bool allow_both_undefined); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_civoid __media_entity_remove_links(struct media_entity *entity); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci/** 84862306a36Sopenharmony_ci * media_entity_remove_links() - remove all links associated with an entity 84962306a36Sopenharmony_ci * 85062306a36Sopenharmony_ci * @entity: pointer to &media_entity 85162306a36Sopenharmony_ci * 85262306a36Sopenharmony_ci * .. note:: 85362306a36Sopenharmony_ci * 85462306a36Sopenharmony_ci * This is called automatically when an entity is unregistered via 85562306a36Sopenharmony_ci * media_device_register_entity(). 85662306a36Sopenharmony_ci */ 85762306a36Sopenharmony_civoid media_entity_remove_links(struct media_entity *entity); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci/** 86062306a36Sopenharmony_ci * __media_entity_setup_link - Configure a media link without locking 86162306a36Sopenharmony_ci * @link: The link being configured 86262306a36Sopenharmony_ci * @flags: Link configuration flags 86362306a36Sopenharmony_ci * 86462306a36Sopenharmony_ci * The bulk of link setup is handled by the two entities connected through the 86562306a36Sopenharmony_ci * link. This function notifies both entities of the link configuration change. 86662306a36Sopenharmony_ci * 86762306a36Sopenharmony_ci * If the link is immutable or if the current and new configuration are 86862306a36Sopenharmony_ci * identical, return immediately. 86962306a36Sopenharmony_ci * 87062306a36Sopenharmony_ci * The user is expected to hold link->source->parent->mutex. If not, 87162306a36Sopenharmony_ci * media_entity_setup_link() should be used instead. 87262306a36Sopenharmony_ci */ 87362306a36Sopenharmony_ciint __media_entity_setup_link(struct media_link *link, u32 flags); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci/** 87662306a36Sopenharmony_ci * media_entity_setup_link() - changes the link flags properties in runtime 87762306a36Sopenharmony_ci * 87862306a36Sopenharmony_ci * @link: pointer to &media_link 87962306a36Sopenharmony_ci * @flags: the requested new link flags 88062306a36Sopenharmony_ci * 88162306a36Sopenharmony_ci * The only configurable property is the %MEDIA_LNK_FL_ENABLED link flag 88262306a36Sopenharmony_ci * to enable/disable a link. Links marked with the 88362306a36Sopenharmony_ci * %MEDIA_LNK_FL_IMMUTABLE link flag can not be enabled or disabled. 88462306a36Sopenharmony_ci * 88562306a36Sopenharmony_ci * When a link is enabled or disabled, the media framework calls the 88662306a36Sopenharmony_ci * link_setup operation for the two entities at the source and sink of the 88762306a36Sopenharmony_ci * link, in that order. If the second link_setup call fails, another 88862306a36Sopenharmony_ci * link_setup call is made on the first entity to restore the original link 88962306a36Sopenharmony_ci * flags. 89062306a36Sopenharmony_ci * 89162306a36Sopenharmony_ci * Media device drivers can be notified of link setup operations by setting the 89262306a36Sopenharmony_ci * &media_device.link_notify pointer to a callback function. If provided, the 89362306a36Sopenharmony_ci * notification callback will be called before enabling and after disabling 89462306a36Sopenharmony_ci * links. 89562306a36Sopenharmony_ci * 89662306a36Sopenharmony_ci * Entity drivers must implement the link_setup operation if any of their links 89762306a36Sopenharmony_ci * is non-immutable. The operation must either configure the hardware or store 89862306a36Sopenharmony_ci * the configuration information to be applied later. 89962306a36Sopenharmony_ci * 90062306a36Sopenharmony_ci * Link configuration must not have any side effect on other links. If an 90162306a36Sopenharmony_ci * enabled link at a sink pad prevents another link at the same pad from 90262306a36Sopenharmony_ci * being enabled, the link_setup operation must return %-EBUSY and can't 90362306a36Sopenharmony_ci * implicitly disable the first enabled link. 90462306a36Sopenharmony_ci * 90562306a36Sopenharmony_ci * .. note:: 90662306a36Sopenharmony_ci * 90762306a36Sopenharmony_ci * The valid values of the flags for the link is the same as described 90862306a36Sopenharmony_ci * on media_create_pad_link(), for pad to pad links or the same as described 90962306a36Sopenharmony_ci * on media_create_intf_link(), for interface to entity links. 91062306a36Sopenharmony_ci */ 91162306a36Sopenharmony_ciint media_entity_setup_link(struct media_link *link, u32 flags); 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci/** 91462306a36Sopenharmony_ci * media_entity_find_link - Find a link between two pads 91562306a36Sopenharmony_ci * @source: Source pad 91662306a36Sopenharmony_ci * @sink: Sink pad 91762306a36Sopenharmony_ci * 91862306a36Sopenharmony_ci * Return: returns a pointer to the link between the two entities. If no 91962306a36Sopenharmony_ci * such link exists, return %NULL. 92062306a36Sopenharmony_ci */ 92162306a36Sopenharmony_cistruct media_link *media_entity_find_link(struct media_pad *source, 92262306a36Sopenharmony_ci struct media_pad *sink); 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci/** 92562306a36Sopenharmony_ci * media_pad_remote_pad_first - Find the first pad at the remote end of a link 92662306a36Sopenharmony_ci * @pad: Pad at the local end of the link 92762306a36Sopenharmony_ci * 92862306a36Sopenharmony_ci * Search for a remote pad connected to the given pad by iterating over all 92962306a36Sopenharmony_ci * links originating or terminating at that pad until an enabled link is found. 93062306a36Sopenharmony_ci * 93162306a36Sopenharmony_ci * Return: returns a pointer to the pad at the remote end of the first found 93262306a36Sopenharmony_ci * enabled link, or %NULL if no enabled link has been found. 93362306a36Sopenharmony_ci */ 93462306a36Sopenharmony_cistruct media_pad *media_pad_remote_pad_first(const struct media_pad *pad); 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci/** 93762306a36Sopenharmony_ci * media_pad_remote_pad_unique - Find a remote pad connected to a pad 93862306a36Sopenharmony_ci * @pad: The pad 93962306a36Sopenharmony_ci * 94062306a36Sopenharmony_ci * Search for and return a remote pad connected to @pad through an enabled 94162306a36Sopenharmony_ci * link. If multiple (or no) remote pads are found, an error is returned. 94262306a36Sopenharmony_ci * 94362306a36Sopenharmony_ci * The uniqueness constraint makes this helper function suitable for entities 94462306a36Sopenharmony_ci * that support a single active source at a time on a given pad. 94562306a36Sopenharmony_ci * 94662306a36Sopenharmony_ci * Return: A pointer to the remote pad, or one of the following error pointers 94762306a36Sopenharmony_ci * if an error occurs: 94862306a36Sopenharmony_ci * 94962306a36Sopenharmony_ci * * -ENOTUNIQ - Multiple links are enabled 95062306a36Sopenharmony_ci * * -ENOLINK - No connected pad found 95162306a36Sopenharmony_ci */ 95262306a36Sopenharmony_cistruct media_pad *media_pad_remote_pad_unique(const struct media_pad *pad); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci/** 95562306a36Sopenharmony_ci * media_entity_remote_pad_unique - Find a remote pad connected to an entity 95662306a36Sopenharmony_ci * @entity: The entity 95762306a36Sopenharmony_ci * @type: The type of pad to find (MEDIA_PAD_FL_SINK or MEDIA_PAD_FL_SOURCE) 95862306a36Sopenharmony_ci * 95962306a36Sopenharmony_ci * Search for and return a remote pad of @type connected to @entity through an 96062306a36Sopenharmony_ci * enabled link. If multiple (or no) remote pads match these criteria, an error 96162306a36Sopenharmony_ci * is returned. 96262306a36Sopenharmony_ci * 96362306a36Sopenharmony_ci * The uniqueness constraint makes this helper function suitable for entities 96462306a36Sopenharmony_ci * that support a single active source or sink at a time. 96562306a36Sopenharmony_ci * 96662306a36Sopenharmony_ci * Return: A pointer to the remote pad, or one of the following error pointers 96762306a36Sopenharmony_ci * if an error occurs: 96862306a36Sopenharmony_ci * 96962306a36Sopenharmony_ci * * -ENOTUNIQ - Multiple links are enabled 97062306a36Sopenharmony_ci * * -ENOLINK - No connected pad found 97162306a36Sopenharmony_ci */ 97262306a36Sopenharmony_cistruct media_pad * 97362306a36Sopenharmony_cimedia_entity_remote_pad_unique(const struct media_entity *entity, 97462306a36Sopenharmony_ci unsigned int type); 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci/** 97762306a36Sopenharmony_ci * media_entity_remote_source_pad_unique - Find a remote source pad connected to 97862306a36Sopenharmony_ci * an entity 97962306a36Sopenharmony_ci * @entity: The entity 98062306a36Sopenharmony_ci * 98162306a36Sopenharmony_ci * Search for and return a remote source pad connected to @entity through an 98262306a36Sopenharmony_ci * enabled link. If multiple (or no) remote pads match these criteria, an error 98362306a36Sopenharmony_ci * is returned. 98462306a36Sopenharmony_ci * 98562306a36Sopenharmony_ci * The uniqueness constraint makes this helper function suitable for entities 98662306a36Sopenharmony_ci * that support a single active source at a time. 98762306a36Sopenharmony_ci * 98862306a36Sopenharmony_ci * Return: A pointer to the remote pad, or one of the following error pointers 98962306a36Sopenharmony_ci * if an error occurs: 99062306a36Sopenharmony_ci * 99162306a36Sopenharmony_ci * * -ENOTUNIQ - Multiple links are enabled 99262306a36Sopenharmony_ci * * -ENOLINK - No connected pad found 99362306a36Sopenharmony_ci */ 99462306a36Sopenharmony_cistatic inline struct media_pad * 99562306a36Sopenharmony_cimedia_entity_remote_source_pad_unique(const struct media_entity *entity) 99662306a36Sopenharmony_ci{ 99762306a36Sopenharmony_ci return media_entity_remote_pad_unique(entity, MEDIA_PAD_FL_SOURCE); 99862306a36Sopenharmony_ci} 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci/** 100162306a36Sopenharmony_ci * media_pad_is_streaming - Test if a pad is part of a streaming pipeline 100262306a36Sopenharmony_ci * @pad: The pad 100362306a36Sopenharmony_ci * 100462306a36Sopenharmony_ci * Return: True if the pad is part of a pipeline started with the 100562306a36Sopenharmony_ci * media_pipeline_start() function, false otherwise. 100662306a36Sopenharmony_ci */ 100762306a36Sopenharmony_cistatic inline bool media_pad_is_streaming(const struct media_pad *pad) 100862306a36Sopenharmony_ci{ 100962306a36Sopenharmony_ci return pad->pipe; 101062306a36Sopenharmony_ci} 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci/** 101362306a36Sopenharmony_ci * media_entity_is_streaming - Test if an entity is part of a streaming pipeline 101462306a36Sopenharmony_ci * @entity: The entity 101562306a36Sopenharmony_ci * 101662306a36Sopenharmony_ci * Return: True if the entity is part of a pipeline started with the 101762306a36Sopenharmony_ci * media_pipeline_start() function, false otherwise. 101862306a36Sopenharmony_ci */ 101962306a36Sopenharmony_cistatic inline bool media_entity_is_streaming(const struct media_entity *entity) 102062306a36Sopenharmony_ci{ 102162306a36Sopenharmony_ci struct media_pad *pad; 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci media_entity_for_each_pad(entity, pad) { 102462306a36Sopenharmony_ci if (media_pad_is_streaming(pad)) 102562306a36Sopenharmony_ci return true; 102662306a36Sopenharmony_ci } 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci return false; 102962306a36Sopenharmony_ci} 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci/** 103262306a36Sopenharmony_ci * media_entity_pipeline - Get the media pipeline an entity is part of 103362306a36Sopenharmony_ci * @entity: The entity 103462306a36Sopenharmony_ci * 103562306a36Sopenharmony_ci * DEPRECATED: use media_pad_pipeline() instead. 103662306a36Sopenharmony_ci * 103762306a36Sopenharmony_ci * This function returns the media pipeline that an entity has been associated 103862306a36Sopenharmony_ci * with when constructing the pipeline with media_pipeline_start(). The pointer 103962306a36Sopenharmony_ci * remains valid until media_pipeline_stop() is called. 104062306a36Sopenharmony_ci * 104162306a36Sopenharmony_ci * In general, entities can be part of multiple pipelines, when carrying 104262306a36Sopenharmony_ci * multiple streams (either on different pads, or on the same pad using 104362306a36Sopenharmony_ci * multiplexed streams). This function is to be used only for entities that 104462306a36Sopenharmony_ci * do not support multiple pipelines. 104562306a36Sopenharmony_ci * 104662306a36Sopenharmony_ci * Return: The media_pipeline the entity is part of, or NULL if the entity is 104762306a36Sopenharmony_ci * not part of any pipeline. 104862306a36Sopenharmony_ci */ 104962306a36Sopenharmony_cistruct media_pipeline *media_entity_pipeline(struct media_entity *entity); 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci/** 105262306a36Sopenharmony_ci * media_pad_pipeline - Get the media pipeline a pad is part of 105362306a36Sopenharmony_ci * @pad: The pad 105462306a36Sopenharmony_ci * 105562306a36Sopenharmony_ci * This function returns the media pipeline that a pad has been associated 105662306a36Sopenharmony_ci * with when constructing the pipeline with media_pipeline_start(). The pointer 105762306a36Sopenharmony_ci * remains valid until media_pipeline_stop() is called. 105862306a36Sopenharmony_ci * 105962306a36Sopenharmony_ci * Return: The media_pipeline the pad is part of, or NULL if the pad is 106062306a36Sopenharmony_ci * not part of any pipeline. 106162306a36Sopenharmony_ci */ 106262306a36Sopenharmony_cistruct media_pipeline *media_pad_pipeline(struct media_pad *pad); 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci/** 106562306a36Sopenharmony_ci * media_entity_get_fwnode_pad - Get pad number from fwnode 106662306a36Sopenharmony_ci * 106762306a36Sopenharmony_ci * @entity: The entity 106862306a36Sopenharmony_ci * @fwnode: Pointer to the fwnode_handle which should be used to find the pad 106962306a36Sopenharmony_ci * @direction_flags: Expected direction of the pad, as defined in 107062306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 107162306a36Sopenharmony_ci * (seek for ``MEDIA_PAD_FL_*``) 107262306a36Sopenharmony_ci * 107362306a36Sopenharmony_ci * This function can be used to resolve the media pad number from 107462306a36Sopenharmony_ci * a fwnode. This is useful for devices which use more complex 107562306a36Sopenharmony_ci * mappings of media pads. 107662306a36Sopenharmony_ci * 107762306a36Sopenharmony_ci * If the entity does not implement the get_fwnode_pad() operation 107862306a36Sopenharmony_ci * then this function searches the entity for the first pad that 107962306a36Sopenharmony_ci * matches the @direction_flags. 108062306a36Sopenharmony_ci * 108162306a36Sopenharmony_ci * Return: returns the pad number on success or a negative error code. 108262306a36Sopenharmony_ci */ 108362306a36Sopenharmony_ciint media_entity_get_fwnode_pad(struct media_entity *entity, 108462306a36Sopenharmony_ci const struct fwnode_handle *fwnode, 108562306a36Sopenharmony_ci unsigned long direction_flags); 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci/** 108862306a36Sopenharmony_ci * media_graph_walk_init - Allocate resources used by graph walk. 108962306a36Sopenharmony_ci * 109062306a36Sopenharmony_ci * @graph: Media graph structure that will be used to walk the graph 109162306a36Sopenharmony_ci * @mdev: Pointer to the &media_device that contains the object 109262306a36Sopenharmony_ci * 109362306a36Sopenharmony_ci * This function is deprecated, use media_pipeline_for_each_pad() instead. 109462306a36Sopenharmony_ci * 109562306a36Sopenharmony_ci * The caller is required to hold the media_device graph_mutex during the graph 109662306a36Sopenharmony_ci * walk until the graph state is released. 109762306a36Sopenharmony_ci * 109862306a36Sopenharmony_ci * Returns zero on success or a negative error code otherwise. 109962306a36Sopenharmony_ci */ 110062306a36Sopenharmony_ci__must_check int media_graph_walk_init( 110162306a36Sopenharmony_ci struct media_graph *graph, struct media_device *mdev); 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci/** 110462306a36Sopenharmony_ci * media_graph_walk_cleanup - Release resources used by graph walk. 110562306a36Sopenharmony_ci * 110662306a36Sopenharmony_ci * @graph: Media graph structure that will be used to walk the graph 110762306a36Sopenharmony_ci * 110862306a36Sopenharmony_ci * This function is deprecated, use media_pipeline_for_each_pad() instead. 110962306a36Sopenharmony_ci */ 111062306a36Sopenharmony_civoid media_graph_walk_cleanup(struct media_graph *graph); 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci/** 111362306a36Sopenharmony_ci * media_graph_walk_start - Start walking the media graph at a 111462306a36Sopenharmony_ci * given entity 111562306a36Sopenharmony_ci * 111662306a36Sopenharmony_ci * @graph: Media graph structure that will be used to walk the graph 111762306a36Sopenharmony_ci * @entity: Starting entity 111862306a36Sopenharmony_ci * 111962306a36Sopenharmony_ci * This function is deprecated, use media_pipeline_for_each_pad() instead. 112062306a36Sopenharmony_ci * 112162306a36Sopenharmony_ci * Before using this function, media_graph_walk_init() must be 112262306a36Sopenharmony_ci * used to allocate resources used for walking the graph. This 112362306a36Sopenharmony_ci * function initializes the graph traversal structure to walk the 112462306a36Sopenharmony_ci * entities graph starting at the given entity. The traversal 112562306a36Sopenharmony_ci * structure must not be modified by the caller during graph 112662306a36Sopenharmony_ci * traversal. After the graph walk, the resources must be released 112762306a36Sopenharmony_ci * using media_graph_walk_cleanup(). 112862306a36Sopenharmony_ci */ 112962306a36Sopenharmony_civoid media_graph_walk_start(struct media_graph *graph, 113062306a36Sopenharmony_ci struct media_entity *entity); 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci/** 113362306a36Sopenharmony_ci * media_graph_walk_next - Get the next entity in the graph 113462306a36Sopenharmony_ci * @graph: Media graph structure 113562306a36Sopenharmony_ci * 113662306a36Sopenharmony_ci * This function is deprecated, use media_pipeline_for_each_pad() instead. 113762306a36Sopenharmony_ci * 113862306a36Sopenharmony_ci * Perform a depth-first traversal of the given media entities graph. 113962306a36Sopenharmony_ci * 114062306a36Sopenharmony_ci * The graph structure must have been previously initialized with a call to 114162306a36Sopenharmony_ci * media_graph_walk_start(). 114262306a36Sopenharmony_ci * 114362306a36Sopenharmony_ci * Return: returns the next entity in the graph or %NULL if the whole graph 114462306a36Sopenharmony_ci * have been traversed. 114562306a36Sopenharmony_ci */ 114662306a36Sopenharmony_cistruct media_entity *media_graph_walk_next(struct media_graph *graph); 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci/** 114962306a36Sopenharmony_ci * media_pipeline_start - Mark a pipeline as streaming 115062306a36Sopenharmony_ci * @pad: Starting pad 115162306a36Sopenharmony_ci * @pipe: Media pipeline to be assigned to all pads in the pipeline. 115262306a36Sopenharmony_ci * 115362306a36Sopenharmony_ci * Mark all pads connected to a given pad through enabled links, either 115462306a36Sopenharmony_ci * directly or indirectly, as streaming. The given pipeline object is assigned 115562306a36Sopenharmony_ci * to every pad in the pipeline and stored in the media_pad pipe field. 115662306a36Sopenharmony_ci * 115762306a36Sopenharmony_ci * Calls to this function can be nested, in which case the same number of 115862306a36Sopenharmony_ci * media_pipeline_stop() calls will be required to stop streaming. The 115962306a36Sopenharmony_ci * pipeline pointer must be identical for all nested calls to 116062306a36Sopenharmony_ci * media_pipeline_start(). 116162306a36Sopenharmony_ci */ 116262306a36Sopenharmony_ci__must_check int media_pipeline_start(struct media_pad *pad, 116362306a36Sopenharmony_ci struct media_pipeline *pipe); 116462306a36Sopenharmony_ci/** 116562306a36Sopenharmony_ci * __media_pipeline_start - Mark a pipeline as streaming 116662306a36Sopenharmony_ci * 116762306a36Sopenharmony_ci * @pad: Starting pad 116862306a36Sopenharmony_ci * @pipe: Media pipeline to be assigned to all pads in the pipeline. 116962306a36Sopenharmony_ci * 117062306a36Sopenharmony_ci * ..note:: This is the non-locking version of media_pipeline_start() 117162306a36Sopenharmony_ci */ 117262306a36Sopenharmony_ci__must_check int __media_pipeline_start(struct media_pad *pad, 117362306a36Sopenharmony_ci struct media_pipeline *pipe); 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_ci/** 117662306a36Sopenharmony_ci * media_pipeline_stop - Mark a pipeline as not streaming 117762306a36Sopenharmony_ci * @pad: Starting pad 117862306a36Sopenharmony_ci * 117962306a36Sopenharmony_ci * Mark all pads connected to a given pad through enabled links, either 118062306a36Sopenharmony_ci * directly or indirectly, as not streaming. The media_pad pipe field is 118162306a36Sopenharmony_ci * reset to %NULL. 118262306a36Sopenharmony_ci * 118362306a36Sopenharmony_ci * If multiple calls to media_pipeline_start() have been made, the same 118462306a36Sopenharmony_ci * number of calls to this function are required to mark the pipeline as not 118562306a36Sopenharmony_ci * streaming. 118662306a36Sopenharmony_ci */ 118762306a36Sopenharmony_civoid media_pipeline_stop(struct media_pad *pad); 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_ci/** 119062306a36Sopenharmony_ci * __media_pipeline_stop - Mark a pipeline as not streaming 119162306a36Sopenharmony_ci * 119262306a36Sopenharmony_ci * @pad: Starting pad 119362306a36Sopenharmony_ci * 119462306a36Sopenharmony_ci * .. note:: This is the non-locking version of media_pipeline_stop() 119562306a36Sopenharmony_ci */ 119662306a36Sopenharmony_civoid __media_pipeline_stop(struct media_pad *pad); 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_cistruct media_pad * 119962306a36Sopenharmony_ci__media_pipeline_pad_iter_next(struct media_pipeline *pipe, 120062306a36Sopenharmony_ci struct media_pipeline_pad_iter *iter, 120162306a36Sopenharmony_ci struct media_pad *pad); 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci/** 120462306a36Sopenharmony_ci * media_pipeline_for_each_pad - Iterate on all pads in a media pipeline 120562306a36Sopenharmony_ci * @pipe: The pipeline 120662306a36Sopenharmony_ci * @iter: The iterator (struct media_pipeline_pad_iter) 120762306a36Sopenharmony_ci * @pad: The iterator pad 120862306a36Sopenharmony_ci * 120962306a36Sopenharmony_ci * Iterate on all pads in a media pipeline. This is only valid after the 121062306a36Sopenharmony_ci * pipeline has been built with media_pipeline_start() and before it gets 121162306a36Sopenharmony_ci * destroyed with media_pipeline_stop(). 121262306a36Sopenharmony_ci */ 121362306a36Sopenharmony_ci#define media_pipeline_for_each_pad(pipe, iter, pad) \ 121462306a36Sopenharmony_ci for (pad = __media_pipeline_pad_iter_next((pipe), iter, NULL); \ 121562306a36Sopenharmony_ci pad != NULL; \ 121662306a36Sopenharmony_ci pad = __media_pipeline_pad_iter_next((pipe), iter, pad)) 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci/** 121962306a36Sopenharmony_ci * media_pipeline_entity_iter_init - Initialize a pipeline entity iterator 122062306a36Sopenharmony_ci * @pipe: The pipeline 122162306a36Sopenharmony_ci * @iter: The iterator 122262306a36Sopenharmony_ci * 122362306a36Sopenharmony_ci * This function must be called to initialize the iterator before using it in a 122462306a36Sopenharmony_ci * media_pipeline_for_each_entity() loop. The iterator must be destroyed by a 122562306a36Sopenharmony_ci * call to media_pipeline_entity_iter_cleanup after the loop (including in code 122662306a36Sopenharmony_ci * paths that break from the loop). 122762306a36Sopenharmony_ci * 122862306a36Sopenharmony_ci * The same iterator can be used in multiple consecutive loops without being 122962306a36Sopenharmony_ci * destroyed and reinitialized. 123062306a36Sopenharmony_ci * 123162306a36Sopenharmony_ci * Return: 0 on success or a negative error code otherwise. 123262306a36Sopenharmony_ci */ 123362306a36Sopenharmony_ciint media_pipeline_entity_iter_init(struct media_pipeline *pipe, 123462306a36Sopenharmony_ci struct media_pipeline_entity_iter *iter); 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci/** 123762306a36Sopenharmony_ci * media_pipeline_entity_iter_cleanup - Destroy a pipeline entity iterator 123862306a36Sopenharmony_ci * @iter: The iterator 123962306a36Sopenharmony_ci * 124062306a36Sopenharmony_ci * This function must be called to destroy iterators initialized with 124162306a36Sopenharmony_ci * media_pipeline_entity_iter_init(). 124262306a36Sopenharmony_ci */ 124362306a36Sopenharmony_civoid media_pipeline_entity_iter_cleanup(struct media_pipeline_entity_iter *iter); 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_cistruct media_entity * 124662306a36Sopenharmony_ci__media_pipeline_entity_iter_next(struct media_pipeline *pipe, 124762306a36Sopenharmony_ci struct media_pipeline_entity_iter *iter, 124862306a36Sopenharmony_ci struct media_entity *entity); 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci/** 125162306a36Sopenharmony_ci * media_pipeline_for_each_entity - Iterate on all entities in a media pipeline 125262306a36Sopenharmony_ci * @pipe: The pipeline 125362306a36Sopenharmony_ci * @iter: The iterator (struct media_pipeline_entity_iter) 125462306a36Sopenharmony_ci * @entity: The iterator entity 125562306a36Sopenharmony_ci * 125662306a36Sopenharmony_ci * Iterate on all entities in a media pipeline. This is only valid after the 125762306a36Sopenharmony_ci * pipeline has been built with media_pipeline_start() and before it gets 125862306a36Sopenharmony_ci * destroyed with media_pipeline_stop(). The iterator must be initialized with 125962306a36Sopenharmony_ci * media_pipeline_entity_iter_init() before iteration, and destroyed with 126062306a36Sopenharmony_ci * media_pipeline_entity_iter_cleanup() after (including in code paths that 126162306a36Sopenharmony_ci * break from the loop). 126262306a36Sopenharmony_ci */ 126362306a36Sopenharmony_ci#define media_pipeline_for_each_entity(pipe, iter, entity) \ 126462306a36Sopenharmony_ci for (entity = __media_pipeline_entity_iter_next((pipe), iter, NULL); \ 126562306a36Sopenharmony_ci entity != NULL; \ 126662306a36Sopenharmony_ci entity = __media_pipeline_entity_iter_next((pipe), iter, entity)) 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci/** 126962306a36Sopenharmony_ci * media_pipeline_alloc_start - Mark a pipeline as streaming 127062306a36Sopenharmony_ci * @pad: Starting pad 127162306a36Sopenharmony_ci * 127262306a36Sopenharmony_ci * media_pipeline_alloc_start() is similar to media_pipeline_start() but instead 127362306a36Sopenharmony_ci * of working on a given pipeline the function will use an existing pipeline if 127462306a36Sopenharmony_ci * the pad is already part of a pipeline, or allocate a new pipeline. 127562306a36Sopenharmony_ci * 127662306a36Sopenharmony_ci * Calls to media_pipeline_alloc_start() must be matched with 127762306a36Sopenharmony_ci * media_pipeline_stop(). 127862306a36Sopenharmony_ci */ 127962306a36Sopenharmony_ci__must_check int media_pipeline_alloc_start(struct media_pad *pad); 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_ci/** 128262306a36Sopenharmony_ci * media_devnode_create() - creates and initializes a device node interface 128362306a36Sopenharmony_ci * 128462306a36Sopenharmony_ci * @mdev: pointer to struct &media_device 128562306a36Sopenharmony_ci * @type: type of the interface, as given by 128662306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 128762306a36Sopenharmony_ci * ( seek for ``MEDIA_INTF_T_*``) macros. 128862306a36Sopenharmony_ci * @flags: Interface flags, as defined in 128962306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 129062306a36Sopenharmony_ci * ( seek for ``MEDIA_INTF_FL_*``) 129162306a36Sopenharmony_ci * @major: Device node major number. 129262306a36Sopenharmony_ci * @minor: Device node minor number. 129362306a36Sopenharmony_ci * 129462306a36Sopenharmony_ci * Return: if succeeded, returns a pointer to the newly allocated 129562306a36Sopenharmony_ci * &media_intf_devnode pointer. 129662306a36Sopenharmony_ci * 129762306a36Sopenharmony_ci * .. note:: 129862306a36Sopenharmony_ci * 129962306a36Sopenharmony_ci * Currently, no flags for &media_interface is defined. 130062306a36Sopenharmony_ci */ 130162306a36Sopenharmony_cistruct media_intf_devnode * 130262306a36Sopenharmony_ci__must_check media_devnode_create(struct media_device *mdev, 130362306a36Sopenharmony_ci u32 type, u32 flags, 130462306a36Sopenharmony_ci u32 major, u32 minor); 130562306a36Sopenharmony_ci/** 130662306a36Sopenharmony_ci * media_devnode_remove() - removes a device node interface 130762306a36Sopenharmony_ci * 130862306a36Sopenharmony_ci * @devnode: pointer to &media_intf_devnode to be freed. 130962306a36Sopenharmony_ci * 131062306a36Sopenharmony_ci * When a device node interface is removed, all links to it are automatically 131162306a36Sopenharmony_ci * removed. 131262306a36Sopenharmony_ci */ 131362306a36Sopenharmony_civoid media_devnode_remove(struct media_intf_devnode *devnode); 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci/** 131662306a36Sopenharmony_ci * media_create_intf_link() - creates a link between an entity and an interface 131762306a36Sopenharmony_ci * 131862306a36Sopenharmony_ci * @entity: pointer to %media_entity 131962306a36Sopenharmony_ci * @intf: pointer to %media_interface 132062306a36Sopenharmony_ci * @flags: Link flags, as defined in 132162306a36Sopenharmony_ci * :ref:`include/uapi/linux/media.h <media_header>` 132262306a36Sopenharmony_ci * ( seek for ``MEDIA_LNK_FL_*``) 132362306a36Sopenharmony_ci * 132462306a36Sopenharmony_ci * 132562306a36Sopenharmony_ci * Valid values for flags: 132662306a36Sopenharmony_ci * 132762306a36Sopenharmony_ci * %MEDIA_LNK_FL_ENABLED 132862306a36Sopenharmony_ci * Indicates that the interface is connected to the entity hardware. 132962306a36Sopenharmony_ci * That's the default value for interfaces. An interface may be disabled if 133062306a36Sopenharmony_ci * the hardware is busy due to the usage of some other interface that it is 133162306a36Sopenharmony_ci * currently controlling the hardware. 133262306a36Sopenharmony_ci * 133362306a36Sopenharmony_ci * A typical example is an hybrid TV device that handle only one type of 133462306a36Sopenharmony_ci * stream on a given time. So, when the digital TV is streaming, 133562306a36Sopenharmony_ci * the V4L2 interfaces won't be enabled, as such device is not able to 133662306a36Sopenharmony_ci * also stream analog TV or radio. 133762306a36Sopenharmony_ci * 133862306a36Sopenharmony_ci * .. note:: 133962306a36Sopenharmony_ci * 134062306a36Sopenharmony_ci * Before calling this function, media_devnode_create() should be called for 134162306a36Sopenharmony_ci * the interface and media_device_register_entity() should be called for the 134262306a36Sopenharmony_ci * interface that will be part of the link. 134362306a36Sopenharmony_ci */ 134462306a36Sopenharmony_cistruct media_link * 134562306a36Sopenharmony_ci__must_check media_create_intf_link(struct media_entity *entity, 134662306a36Sopenharmony_ci struct media_interface *intf, 134762306a36Sopenharmony_ci u32 flags); 134862306a36Sopenharmony_ci/** 134962306a36Sopenharmony_ci * __media_remove_intf_link() - remove a single interface link 135062306a36Sopenharmony_ci * 135162306a36Sopenharmony_ci * @link: pointer to &media_link. 135262306a36Sopenharmony_ci * 135362306a36Sopenharmony_ci * .. note:: This is an unlocked version of media_remove_intf_link() 135462306a36Sopenharmony_ci */ 135562306a36Sopenharmony_civoid __media_remove_intf_link(struct media_link *link); 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci/** 135862306a36Sopenharmony_ci * media_remove_intf_link() - remove a single interface link 135962306a36Sopenharmony_ci * 136062306a36Sopenharmony_ci * @link: pointer to &media_link. 136162306a36Sopenharmony_ci * 136262306a36Sopenharmony_ci * .. note:: Prefer to use this one, instead of __media_remove_intf_link() 136362306a36Sopenharmony_ci */ 136462306a36Sopenharmony_civoid media_remove_intf_link(struct media_link *link); 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci/** 136762306a36Sopenharmony_ci * __media_remove_intf_links() - remove all links associated with an interface 136862306a36Sopenharmony_ci * 136962306a36Sopenharmony_ci * @intf: pointer to &media_interface 137062306a36Sopenharmony_ci * 137162306a36Sopenharmony_ci * .. note:: This is an unlocked version of media_remove_intf_links(). 137262306a36Sopenharmony_ci */ 137362306a36Sopenharmony_civoid __media_remove_intf_links(struct media_interface *intf); 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci/** 137662306a36Sopenharmony_ci * media_remove_intf_links() - remove all links associated with an interface 137762306a36Sopenharmony_ci * 137862306a36Sopenharmony_ci * @intf: pointer to &media_interface 137962306a36Sopenharmony_ci * 138062306a36Sopenharmony_ci * .. note:: 138162306a36Sopenharmony_ci * 138262306a36Sopenharmony_ci * #) This is called automatically when an entity is unregistered via 138362306a36Sopenharmony_ci * media_device_register_entity() and by media_devnode_remove(). 138462306a36Sopenharmony_ci * 138562306a36Sopenharmony_ci * #) Prefer to use this one, instead of __media_remove_intf_links(). 138662306a36Sopenharmony_ci */ 138762306a36Sopenharmony_civoid media_remove_intf_links(struct media_interface *intf); 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci/** 139062306a36Sopenharmony_ci * media_entity_call - Calls a struct media_entity_operations operation on 139162306a36Sopenharmony_ci * an entity 139262306a36Sopenharmony_ci * 139362306a36Sopenharmony_ci * @entity: entity where the @operation will be called 139462306a36Sopenharmony_ci * @operation: type of the operation. Should be the name of a member of 139562306a36Sopenharmony_ci * struct &media_entity_operations. 139662306a36Sopenharmony_ci * 139762306a36Sopenharmony_ci * This helper function will check if @operation is not %NULL. On such case, 139862306a36Sopenharmony_ci * it will issue a call to @operation\(@entity, @args\). 139962306a36Sopenharmony_ci */ 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci#define media_entity_call(entity, operation, args...) \ 140262306a36Sopenharmony_ci (((entity)->ops && (entity)->ops->operation) ? \ 140362306a36Sopenharmony_ci (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci/** 140662306a36Sopenharmony_ci * media_create_ancillary_link() - create an ancillary link between two 140762306a36Sopenharmony_ci * instances of &media_entity 140862306a36Sopenharmony_ci * 140962306a36Sopenharmony_ci * @primary: pointer to the primary &media_entity 141062306a36Sopenharmony_ci * @ancillary: pointer to the ancillary &media_entity 141162306a36Sopenharmony_ci * 141262306a36Sopenharmony_ci * Create an ancillary link between two entities, indicating that they 141362306a36Sopenharmony_ci * represent two connected pieces of hardware that form a single logical unit. 141462306a36Sopenharmony_ci * A typical example is a camera lens controller being linked to the sensor that 141562306a36Sopenharmony_ci * it is supporting. 141662306a36Sopenharmony_ci * 141762306a36Sopenharmony_ci * The function sets both MEDIA_LNK_FL_ENABLED and MEDIA_LNK_FL_IMMUTABLE for 141862306a36Sopenharmony_ci * the new link. 141962306a36Sopenharmony_ci */ 142062306a36Sopenharmony_cistruct media_link * 142162306a36Sopenharmony_cimedia_create_ancillary_link(struct media_entity *primary, 142262306a36Sopenharmony_ci struct media_entity *ancillary); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci/** 142562306a36Sopenharmony_ci * __media_entity_next_link() - Iterate through a &media_entity's links 142662306a36Sopenharmony_ci * 142762306a36Sopenharmony_ci * @entity: pointer to the &media_entity 142862306a36Sopenharmony_ci * @link: pointer to a &media_link to hold the iterated values 142962306a36Sopenharmony_ci * @link_type: one of the MEDIA_LNK_FL_LINK_TYPE flags 143062306a36Sopenharmony_ci * 143162306a36Sopenharmony_ci * Return the next link against an entity matching a specific link type. This 143262306a36Sopenharmony_ci * allows iteration through an entity's links whilst guaranteeing all of the 143362306a36Sopenharmony_ci * returned links are of the given type. 143462306a36Sopenharmony_ci */ 143562306a36Sopenharmony_cistruct media_link *__media_entity_next_link(struct media_entity *entity, 143662306a36Sopenharmony_ci struct media_link *link, 143762306a36Sopenharmony_ci unsigned long link_type); 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci/** 144062306a36Sopenharmony_ci * for_each_media_entity_data_link() - Iterate through an entity's data links 144162306a36Sopenharmony_ci * 144262306a36Sopenharmony_ci * @entity: pointer to the &media_entity 144362306a36Sopenharmony_ci * @link: pointer to a &media_link to hold the iterated values 144462306a36Sopenharmony_ci * 144562306a36Sopenharmony_ci * Iterate over a &media_entity's data links 144662306a36Sopenharmony_ci */ 144762306a36Sopenharmony_ci#define for_each_media_entity_data_link(entity, link) \ 144862306a36Sopenharmony_ci for (link = __media_entity_next_link(entity, NULL, \ 144962306a36Sopenharmony_ci MEDIA_LNK_FL_DATA_LINK); \ 145062306a36Sopenharmony_ci link; \ 145162306a36Sopenharmony_ci link = __media_entity_next_link(entity, link, \ 145262306a36Sopenharmony_ci MEDIA_LNK_FL_DATA_LINK)) 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci#endif 1455