Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27e543fa authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] media: add functions to allow creating interfaces



Interfaces are different than entities: they represent a
Kernel<->userspace interaction, while entities represent a
piece of hardware/firmware/software that executes a function.

Let's distinguish them by creating a separate structure to
store the interfaces.

Later patches should change the existing drivers and logic
to split the current interface embedded inside the entity
structure (device nodes) into a separate object of the graph.

Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarJavier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent a1d2510e
Loading
Loading
Loading
Loading
+83 −0
Original line number Original line Diff line number Diff line
@@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type)
		return "pad";
		return "pad";
	case MEDIA_GRAPH_LINK:
	case MEDIA_GRAPH_LINK:
		return "link";
		return "link";
	case MEDIA_GRAPH_INTF_DEVNODE:
		return "intf-devnode";
	default:
	default:
		return "unknown";
		return "unknown";
	}
	}
}
}


static inline const char *intf_type(struct media_interface *intf)
{
	switch (intf->type) {
	case MEDIA_INTF_T_DVB_FE:
		return "frontend";
	case MEDIA_INTF_T_DVB_DEMUX:
		return "demux";
	case MEDIA_INTF_T_DVB_DVR:
		return "DVR";
	case MEDIA_INTF_T_DVB_CA:
		return  "CA";
	case MEDIA_INTF_T_DVB_NET:
		return "dvbnet";
	case MEDIA_INTF_T_V4L_VIDEO:
		return "video";
	case MEDIA_INTF_T_V4L_VBI:
		return "vbi";
	case MEDIA_INTF_T_V4L_RADIO:
		return "radio";
	case MEDIA_INTF_T_V4L_SUBDEV:
		return "v4l2-subdev";
	case MEDIA_INTF_T_V4L_SWRADIO:
		return "swradio";
	default:
		return "unknown-intf";
	}
};

static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
{
{
#if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG)
#if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG)
@@ -84,6 +114,19 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj)
			"%s: id 0x%08x pad#%d: '%s':%d\n",
			"%s: id 0x%08x pad#%d: '%s':%d\n",
			event_name, gobj->id, media_localid(gobj),
			event_name, gobj->id, media_localid(gobj),
			pad->entity->name, pad->index);
			pad->entity->name, pad->index);
		break;
	}
	case MEDIA_GRAPH_INTF_DEVNODE:
	{
		struct media_interface *intf = gobj_to_intf(gobj);
		struct media_intf_devnode *devnode = intf_to_devnode(intf);

		dev_dbg(gobj->mdev->dev,
			"%s: id 0x%08x intf_devnode#%d: %s - major: %d, minor: %d\n",
			event_name, gobj->id, media_localid(gobj),
			intf_type(intf),
			devnode->major, devnode->minor);
		break;
	}
	}
	}
	}
#endif
#endif
@@ -119,6 +162,9 @@ void media_gobj_init(struct media_device *mdev,
	case MEDIA_GRAPH_LINK:
	case MEDIA_GRAPH_LINK:
		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
		break;
		break;
	case MEDIA_GRAPH_INTF_DEVNODE:
		gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id);
		break;
	}
	}
	dev_dbg_obj(__func__, gobj);
	dev_dbg_obj(__func__, gobj);
}
}
@@ -793,3 +839,40 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)


}
}
EXPORT_SYMBOL_GPL(media_entity_remote_pad);
EXPORT_SYMBOL_GPL(media_entity_remote_pad);


/* Functions related to the media interface via device nodes */

struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
						u32 type, u32 flags,
						u32 major, u32 minor,
						gfp_t gfp_flags)
{
	struct media_intf_devnode *devnode;
	struct media_interface *intf;

	devnode = kzalloc(sizeof(*devnode), gfp_flags);
	if (!devnode)
		return NULL;

	intf = &devnode->intf;

	intf->type = type;
	intf->flags = flags;

	devnode->major = major;
	devnode->minor = minor;

	media_gobj_init(mdev, MEDIA_GRAPH_INTF_DEVNODE,
		       &devnode->intf.graph_obj);

	return devnode;
}
EXPORT_SYMBOL_GPL(media_devnode_create);

void media_devnode_remove(struct media_intf_devnode *devnode)
{
	media_gobj_remove(&devnode->intf.graph_obj);
	kfree(devnode);
}
EXPORT_SYMBOL_GPL(media_devnode_remove);
+2 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ struct device;
 * @entity_id:	Unique ID used on the last entity registered
 * @entity_id:	Unique ID used on the last entity registered
 * @pad_id:	Unique ID used on the last pad registered
 * @pad_id:	Unique ID used on the last pad registered
 * @link_id:	Unique ID used on the last link registered
 * @link_id:	Unique ID used on the last link registered
 * @intf_devnode_id: Unique ID used on the last interface devnode registered
 * @entities:	List of registered entities
 * @entities:	List of registered entities
 * @lock:	Entities list lock
 * @lock:	Entities list lock
 * @graph_mutex: Entities graph operation lock
 * @graph_mutex: Entities graph operation lock
@@ -73,6 +74,7 @@ struct media_device {
	u32 entity_id;
	u32 entity_id;
	u32 pad_id;
	u32 pad_id;
	u32 link_id;
	u32 link_id;
	u32 intf_devnode_id;


	struct list_head entities;
	struct list_head entities;


+48 −0
Original line number Original line Diff line number Diff line
@@ -36,11 +36,14 @@
 * @MEDIA_GRAPH_ENTITY:		Identify a media entity
 * @MEDIA_GRAPH_ENTITY:		Identify a media entity
 * @MEDIA_GRAPH_PAD:		Identify a media pad
 * @MEDIA_GRAPH_PAD:		Identify a media pad
 * @MEDIA_GRAPH_LINK:		Identify a media link
 * @MEDIA_GRAPH_LINK:		Identify a media link
 * @MEDIA_GRAPH_INTF_DEVNODE:	Identify a media Kernel API interface via
 *				a device node
 */
 */
enum media_gobj_type {
enum media_gobj_type {
	MEDIA_GRAPH_ENTITY,
	MEDIA_GRAPH_ENTITY,
	MEDIA_GRAPH_PAD,
	MEDIA_GRAPH_PAD,
	MEDIA_GRAPH_LINK,
	MEDIA_GRAPH_LINK,
	MEDIA_GRAPH_INTF_DEVNODE,
};
};


#define MEDIA_BITS_PER_TYPE		8
#define MEDIA_BITS_PER_TYPE		8
@@ -141,6 +144,34 @@ struct media_entity {
	} info;
	} info;
};
};


/**
 * struct media_intf_devnode - Define a Kernel API interface
 *
 * @graph_obj:		embedded graph object
 * @type:		Type of the interface as defined at the
 *			uapi/media/media.h header, e. g.
 *			MEDIA_INTF_T_*
 * @flags:		Interface flags as defined at uapi/media/media.h
 */
struct media_interface {
	struct media_gobj		graph_obj;
	u32				type;
	u32				flags;
};

/**
 * struct media_intf_devnode - Define a Kernel API interface via a device node
 *
 * @intf:	embedded interface object
 * @major:	Major number of a device node
 * @minor:	Minor number of a device node
 */
struct media_intf_devnode {
	struct media_interface		intf;
	u32				major;
	u32				minor;
};

static inline u32 media_entity_type(struct media_entity *entity)
static inline u32 media_entity_type(struct media_entity *entity)
{
{
	return entity->type & MEDIA_ENT_TYPE_MASK;
	return entity->type & MEDIA_ENT_TYPE_MASK;
@@ -205,6 +236,18 @@ struct media_entity_graph {
#define gobj_to_link(gobj) \
#define gobj_to_link(gobj) \
		container_of(gobj, struct media_link, graph_obj)
		container_of(gobj, struct media_link, graph_obj)


#define gobj_to_link(gobj) \
		container_of(gobj, struct media_link, graph_obj)

#define gobj_to_pad(gobj) \
		container_of(gobj, struct media_pad, graph_obj)

#define gobj_to_intf(gobj) \
		container_of(gobj, struct media_interface, graph_obj)

#define intf_to_devnode(intf) \
		container_of(intf, struct media_intf_devnode, intf)

void media_gobj_init(struct media_device *mdev,
void media_gobj_init(struct media_device *mdev,
		    enum media_gobj_type type,
		    enum media_gobj_type type,
		    struct media_gobj *gobj);
		    struct media_gobj *gobj);
@@ -236,6 +279,11 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
					     struct media_pipeline *pipe);
					     struct media_pipeline *pipe);
void media_entity_pipeline_stop(struct media_entity *entity);
void media_entity_pipeline_stop(struct media_entity *entity);


struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
						u32 type, u32 flags,
						u32 major, u32 minor,
						gfp_t gfp_flags);
void media_devnode_remove(struct media_intf_devnode *devnode);
#define media_entity_call(entity, operation, args...)			\
#define media_entity_call(entity, operation, args...)			\
	(((entity)->ops && (entity)->ops->operation) ?			\
	(((entity)->ops && (entity)->ops->operation) ?			\
	 (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
	 (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)