153e269c1SLaurent Pinchart /* 253e269c1SLaurent Pinchart * Media entity 353e269c1SLaurent Pinchart * 453e269c1SLaurent Pinchart * Copyright (C) 2010 Nokia Corporation 553e269c1SLaurent Pinchart * 653e269c1SLaurent Pinchart * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 753e269c1SLaurent Pinchart * Sakari Ailus <sakari.ailus@iki.fi> 853e269c1SLaurent Pinchart * 953e269c1SLaurent Pinchart * This program is free software; you can redistribute it and/or modify 1053e269c1SLaurent Pinchart * it under the terms of the GNU General Public License version 2 as 1153e269c1SLaurent Pinchart * published by the Free Software Foundation. 1253e269c1SLaurent Pinchart * 1353e269c1SLaurent Pinchart * This program is distributed in the hope that it will be useful, 1453e269c1SLaurent Pinchart * but WITHOUT ANY WARRANTY; without even the implied warranty of 1553e269c1SLaurent Pinchart * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1653e269c1SLaurent Pinchart * GNU General Public License for more details. 1753e269c1SLaurent Pinchart * 1853e269c1SLaurent Pinchart * You should have received a copy of the GNU General Public License 1953e269c1SLaurent Pinchart * along with this program; if not, write to the Free Software 2053e269c1SLaurent Pinchart * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2153e269c1SLaurent Pinchart */ 2253e269c1SLaurent Pinchart 2353e269c1SLaurent Pinchart #ifndef _MEDIA_ENTITY_H 2453e269c1SLaurent Pinchart #define _MEDIA_ENTITY_H 2553e269c1SLaurent Pinchart 265c7b25b9SLaurent Pinchart #include <linux/bitops.h> 27*0149a2e1SSakari Ailus #include <linux/kernel.h> 2853e269c1SLaurent Pinchart #include <linux/list.h> 291651333bSLaurent Pinchart #include <linux/media.h> 3053e269c1SLaurent Pinchart 31e02188c9SLaurent Pinchart struct media_pipeline { 32e02188c9SLaurent Pinchart }; 33e02188c9SLaurent Pinchart 3453e269c1SLaurent Pinchart struct media_link { 3553e269c1SLaurent Pinchart struct media_pad *source; /* Source pad */ 3653e269c1SLaurent Pinchart struct media_pad *sink; /* Sink pad */ 3753e269c1SLaurent Pinchart struct media_link *reverse; /* Link in the reverse direction */ 3853e269c1SLaurent Pinchart unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ 3953e269c1SLaurent Pinchart }; 4053e269c1SLaurent Pinchart 4153e269c1SLaurent Pinchart struct media_pad { 4253e269c1SLaurent Pinchart struct media_entity *entity; /* Entity this pad belongs to */ 4353e269c1SLaurent Pinchart u16 index; /* Pad index in the entity pads array */ 4453e269c1SLaurent Pinchart unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ 4553e269c1SLaurent Pinchart }; 4653e269c1SLaurent Pinchart 4797548ed4SLaurent Pinchart struct media_entity_operations { 4897548ed4SLaurent Pinchart int (*link_setup)(struct media_entity *entity, 4997548ed4SLaurent Pinchart const struct media_pad *local, 5097548ed4SLaurent Pinchart const struct media_pad *remote, u32 flags); 51af88be38SSakari Ailus int (*link_validate)(struct media_link *link); 5297548ed4SLaurent Pinchart }; 5397548ed4SLaurent Pinchart 5453e269c1SLaurent Pinchart struct media_entity { 5553e269c1SLaurent Pinchart struct list_head list; 5653e269c1SLaurent Pinchart struct media_device *parent; /* Media device this entity belongs to*/ 5753e269c1SLaurent Pinchart u32 id; /* Entity ID, unique in the parent media 5853e269c1SLaurent Pinchart * device context */ 5953e269c1SLaurent Pinchart const char *name; /* Entity name */ 6053e269c1SLaurent Pinchart u32 type; /* Entity type (MEDIA_ENT_T_*) */ 6153e269c1SLaurent Pinchart u32 revision; /* Entity revision, driver specific */ 6253e269c1SLaurent Pinchart unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */ 6353e269c1SLaurent Pinchart u32 group_id; /* Entity group ID */ 6453e269c1SLaurent Pinchart 6553e269c1SLaurent Pinchart u16 num_pads; /* Number of sink and source pads */ 6653e269c1SLaurent Pinchart u16 num_links; /* Number of existing links, both 6753e269c1SLaurent Pinchart * enabled and disabled */ 6853e269c1SLaurent Pinchart u16 num_backlinks; /* Number of backlinks */ 6953e269c1SLaurent Pinchart u16 max_links; /* Maximum number of links */ 7053e269c1SLaurent Pinchart 7153e269c1SLaurent Pinchart struct media_pad *pads; /* Pads array (num_pads elements) */ 7253e269c1SLaurent Pinchart struct media_link *links; /* Links array (max_links elements)*/ 7353e269c1SLaurent Pinchart 7497548ed4SLaurent Pinchart const struct media_entity_operations *ops; /* Entity operations */ 7597548ed4SLaurent Pinchart 76503c3d82SLaurent Pinchart /* Reference counts must never be negative, but are signed integers on 77503c3d82SLaurent Pinchart * purpose: a simple WARN_ON(<0) check can be used to detect reference 78503c3d82SLaurent Pinchart * count bugs that would make them negative. 79503c3d82SLaurent Pinchart */ 80e02188c9SLaurent Pinchart int stream_count; /* Stream count for the entity. */ 81503c3d82SLaurent Pinchart int use_count; /* Use count for the entity. */ 82503c3d82SLaurent Pinchart 83e02188c9SLaurent Pinchart struct media_pipeline *pipe; /* Pipeline this entity belongs to. */ 84e02188c9SLaurent Pinchart 8553e269c1SLaurent Pinchart union { 8653e269c1SLaurent Pinchart /* Node specifications */ 8753e269c1SLaurent Pinchart struct { 8853e269c1SLaurent Pinchart u32 major; 8953e269c1SLaurent Pinchart u32 minor; 9053e269c1SLaurent Pinchart } v4l; 9153e269c1SLaurent Pinchart struct { 9253e269c1SLaurent Pinchart u32 major; 9353e269c1SLaurent Pinchart u32 minor; 9453e269c1SLaurent Pinchart } fb; 9553e269c1SLaurent Pinchart struct { 9653e269c1SLaurent Pinchart u32 card; 9753e269c1SLaurent Pinchart u32 device; 9853e269c1SLaurent Pinchart u32 subdevice; 9953e269c1SLaurent Pinchart } alsa; 10053e269c1SLaurent Pinchart int dvb; 10153e269c1SLaurent Pinchart 10253e269c1SLaurent Pinchart /* Sub-device specifications */ 10353e269c1SLaurent Pinchart /* Nothing needed yet */ 104fa5034c6SClemens Ladisch } info; 10553e269c1SLaurent Pinchart }; 10653e269c1SLaurent Pinchart 10753e269c1SLaurent Pinchart static inline u32 media_entity_type(struct media_entity *entity) 10853e269c1SLaurent Pinchart { 10953e269c1SLaurent Pinchart return entity->type & MEDIA_ENT_TYPE_MASK; 11053e269c1SLaurent Pinchart } 11153e269c1SLaurent Pinchart 11253e269c1SLaurent Pinchart static inline u32 media_entity_subtype(struct media_entity *entity) 11353e269c1SLaurent Pinchart { 11453e269c1SLaurent Pinchart return entity->type & MEDIA_ENT_SUBTYPE_MASK; 11553e269c1SLaurent Pinchart } 11653e269c1SLaurent Pinchart 117a5ccc48aSSakari Ailus #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 1185c7b25b9SLaurent Pinchart #define MEDIA_ENTITY_ENUM_MAX_ID 64 119a5ccc48aSSakari Ailus 120a5ccc48aSSakari Ailus struct media_entity_graph { 121a5ccc48aSSakari Ailus struct { 122a5ccc48aSSakari Ailus struct media_entity *entity; 123a5ccc48aSSakari Ailus int link; 124a5ccc48aSSakari Ailus } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; 1255c7b25b9SLaurent Pinchart 1265c7b25b9SLaurent Pinchart DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); 127a5ccc48aSSakari Ailus int top; 128a5ccc48aSSakari Ailus }; 129a5ccc48aSSakari Ailus 13053e269c1SLaurent Pinchart int media_entity_init(struct media_entity *entity, u16 num_pads, 13153e269c1SLaurent Pinchart struct media_pad *pads, u16 extra_links); 13253e269c1SLaurent Pinchart void media_entity_cleanup(struct media_entity *entity); 133e02188c9SLaurent Pinchart 13453e269c1SLaurent Pinchart int media_entity_create_link(struct media_entity *source, u16 source_pad, 13553e269c1SLaurent Pinchart struct media_entity *sink, u16 sink_pad, u32 flags); 1367349cec1SSylwester Nawrocki void __media_entity_remove_links(struct media_entity *entity); 1377349cec1SSylwester Nawrocki void media_entity_remove_links(struct media_entity *entity); 1387349cec1SSylwester Nawrocki 13997548ed4SLaurent Pinchart int __media_entity_setup_link(struct media_link *link, u32 flags); 14097548ed4SLaurent Pinchart int media_entity_setup_link(struct media_link *link, u32 flags); 14197548ed4SLaurent Pinchart struct media_link *media_entity_find_link(struct media_pad *source, 14297548ed4SLaurent Pinchart struct media_pad *sink); 1431bddf1b3SAndrzej Hajda struct media_pad *media_entity_remote_pad(struct media_pad *pad); 14453e269c1SLaurent Pinchart 145503c3d82SLaurent Pinchart struct media_entity *media_entity_get(struct media_entity *entity); 146503c3d82SLaurent Pinchart void media_entity_put(struct media_entity *entity); 147503c3d82SLaurent Pinchart 148a5ccc48aSSakari Ailus void media_entity_graph_walk_start(struct media_entity_graph *graph, 149a5ccc48aSSakari Ailus struct media_entity *entity); 150a5ccc48aSSakari Ailus struct media_entity * 151a5ccc48aSSakari Ailus media_entity_graph_walk_next(struct media_entity_graph *graph); 152af88be38SSakari Ailus __must_check int media_entity_pipeline_start(struct media_entity *entity, 153e02188c9SLaurent Pinchart struct media_pipeline *pipe); 154e02188c9SLaurent Pinchart void media_entity_pipeline_stop(struct media_entity *entity); 155a5ccc48aSSakari Ailus 15697548ed4SLaurent Pinchart #define media_entity_call(entity, operation, args...) \ 15797548ed4SLaurent Pinchart (((entity)->ops && (entity)->ops->operation) ? \ 15897548ed4SLaurent Pinchart (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) 15997548ed4SLaurent Pinchart 16053e269c1SLaurent Pinchart #endif 161