基于RV1126 Video分析-----链接 mipi csi 与 mipi csi phy 的media模块

现在继续分析 mipi csi 的 bound()函数

工作:

在这里插入图片描述

drivers\media\platform\rockchip\cif\mipi-csi2.c

static const struct v4l2_async_notifier_operations csi2_async_ops = {
	.bound = csi2_notifier_bound,
	.unbind = csi2_notifier_unbind,
};



/* The .bound() notifier callback when a match is found */
static int
csi2_notifier_bound(struct v4l2_async_notifier *notifier,
		    struct v4l2_subdev *sd,
		    struct v4l2_async_subdev *asd)
{
	struct csi2_dev *csi2 = container_of(notifier,
			struct csi2_dev,
			notifier);
	struct csi2_sensor *sensor;
	struct media_link *link;
	unsigned int pad, ret;

	if (csi2->num_sensors == ARRAY_SIZE(csi2->sensors)) {
		v4l2_err(&csi2->sd,
			 "%s: the num of sd is beyond:%d\n",
			 __func__, csi2->num_sensors);
		return -EBUSY;
	}
	sensor = &csi2->sensors[csi2->num_sensors++];
	
	
	   /*
         * 这里的sd是mipi csi phy的subdev
         */
	sensor->sd = sd;

	 /*
         * mipi csi phy 的entity有2个pad
         * 1个sink pad,1个source pad
         * 这里是要找到source pad
         * 为什么要找source呢?
         * 因为source才是下一级需要的
         * 可以看到这里只考虑了一个pad
         * 因为写驱动的人知道source media 及 sink media的pad的个数
         */
	for (pad = 0; pad < sd->entity.num_pads; pad++)
		if (sensor->sd->entity.pads[pad].flags
					& MEDIA_PAD_FL_SOURCE)
			break;

	if (pad == sensor->sd->entity.num_pads) {
		dev_err(csi2->dev,
			"failed to find src pad for %s\n",
			sd->name);

		return -ENXIO;
	}

	/* 

	参数1 mipi csi phy的 entity								子设备的entity	 
	参数2 mipi csi phy的 entity 中的 source pad	下标编号	子设备的entity中的 source pad	下标编号
	参数3 mipi csi的 entity									当前设备的entity 
	参数4 RK_CSI2_PAD_SINK									RK_CSI2_PAD_SINK
	0
	

	
	
工作

																											mipi csi		
																								   |----------------------------------|		
							mipi csi phy 					mipi csi phy link                      |    entity                     	  |		
													    |----------------------------------|       |                 #-------------#  | 	
			   |----------------------------------|	    |  #-------------# #-------------# |       |                 | source0 pad |--|-	
			   |       entity                     |  +--|->| source pad  | | sink  pad   |-|--+    |                 #-------------#  |		
			   |   #-------------# #-------------#|	 |  |  #-------------# #-------------# |  |    |                 #-------------#  |	  	
数据源  -------|-->| sink pad    | | source1 pad ||--+	|----------------------------------|  |    |   #----------#  | source1 pad |--|-	
			   |   #-------------# #-------------#|  |      mipi csi        link           +----|-->| sink pad |  #-------------#  | 	
			   |----------------------------------|	 |  |----------------------------------|  |    |   #----------#  #-------------#  | 	
			                                         |  |  #-------------# #-------------# |  |    |                 | source2 pad |--|-	
			                                         +--|->| source pad  | | sink  pad   |-|--+    |                 #-------------#  |		
			                                            |  #-------------# #-------------# |       |                 #-------------#  | 	
			                                            |----------------------------------|       | 				 | source2 pad |--|-	
			                                                                                       |                 #-------------#  |		
			                                                                                       |----------------------------------|		
绑定 子设备mipidphy_priv -----  link ----- 多媒体设备
绑定 设备 mipi csi link ----- 多媒体设备
							
	
	*/

	ret = media_create_pad_link(&sensor->sd->entity, pad,
				    &csi2->sd.entity, RK_CSI2_PAD_SINK,
				    0/* csi2->num_sensors != 1 ? 0 : MEDIA_LNK_FL_ENABLED */);
	if (ret) {
		dev_err(csi2->dev,
			"failed to create link for %s\n",
			sd->name);
		return ret;
	}

	/*

	media_create_pad_link中已经设置:
		
		struct csi2_dev
			struct v4l2_subdev	sd;                        			(backlink)
				struct media_entity entity;         	       struct media_link {
							struct list_head links;	---创建绑定--->	struct list_head list;
																	struct media_gobj graph_obj------+
																		struct list_head	list; ---|------+
																									 |      |
					struct media_gobj graph_obj	                               指定同一个 多媒体设备 |      |
						struct media_device	*mdev; --------------------------------------------------+      | 关联
							struct list_head links ---------------------------------------------------------+
	
	
	所以这里就是 获取 csi2_dev模块抽象的 反向链接 backlink !!!
	*/
	link = list_first_entry(&csi2->sd.entity.links, struct media_link, list);
	
	/*
	参数1 csi2_dev模块抽象的 反向链接backlink !!!
			
	参数2 MEDIA_LNK_FL_ENABLED		
	*/
	
	/*
	工作 : 
		
	主要就是调用 mipi csi 的 link_setup == csi2_link_setup。
	在V4L2设备层面,即 v4l2_subdev层面 建立数据源之间的关系, 指定 mipi csi 的V4L2子设备 数据源  是  mipi-csi-phy的V4L2子设备
		
	*/
	ret = media_entity_setup_link(link, MEDIA_LNK_FL_ENABLED);
	if (ret) {
		dev_err(csi2->dev,
			"failed to create link for %s\n",
			sensor->sd->name);
		return ret;
	}

	return 0;
}





	/* 
	参数1 mipi csi phy 的 entity								子设备的entity	 
	参数2 mipi csi phy 的 entity 中的 source pad	下标编号	子设备的entity中的 source pad	下标编号
	参数3 mipi csi的 entity									当前设备的entity 
	参数4 RK_CSI2_PAD_SINK									RK_CSI2_PAD_SINK
	0
	*/
	
	/*
	工作

																												mipi csi		
																									   |----------------------------------|		
								mipi csi phy 					mipi csi phy link                      |    entity                     	  |		
														    |----------------------------------|       |                 #-------------#  | 	
				   |----------------------------------|	    |  #-------------# #-------------# |       |                 | source0 pad |--|-	
				   |       entity                     |  +--|->| source pad  | | sink  pad   |-|--+    |                 #-------------#  |		
				   |   #-------------# #-------------#|	 |  |  #-------------# #-------------# |  |    |                 #-------------#  |	  	
	数据源  -------|-->| sink pad    | | source1 pad ||--+	|----------------------------------|  |    |   #----------#  | source1 pad |--|-	
				   |   #-------------# #-------------#|  |     mipi csi link                   +----|-->| sink pad |  #-------------#  | 	
				   |----------------------------------|	 |  |----------------------------------|  |    |   #----------#  #-------------#  | 	
				                                         |  |  #-------------# #-------------# |  |    |                 | source2 pad |--|-	
				                                         +--|->| source pad  | | sink  pad   |-|--+    |                 #-------------#  |		
				                                            |  #-------------# #-------------# |       |                 #-------------#  | 	
				                                            |----------------------------------|       | 				 | source2 pad |--|-	
				                                                                                       |                 #-------------#  |		
				                                                                                       |----------------------------------|		
	绑定 子设备mipidphy_priv -----  link ----- 多媒体设备
	绑定 设备 mipi csi link ----- 多媒体设备
								
	
  此时 

		mipi csi phy设备抽象   ----    mipi csi phy 的 抽象链接  ----   mipi csi设备抽象
							   ----	   mipi csi的 抽象链接  ----
								   
		关联 这两个link : link和backlink
				
	
	*/
int media_create_pad_link(struct media_entity *source, u16 source_pad,
			 struct media_entity *sink, u16 sink_pad, u32 flags)
{
	struct media_link *link;
	struct media_link *backlink;

	BUG_ON(source == NULL || sink == NULL);
	BUG_ON(source_pad >= source->num_pads);
	BUG_ON(sink_pad >= sink->num_pads);

	/*
	参数 子设备 mipi csi phy 的entity中的 links

	创建子设备的 entity	的连接抽象(media_link) 
	
		struct media_entity {                             struct media_link {
			struct list_head links;	-----------创建绑定---------->struct list_head list;

		并返回 media_link
	*/
	link = media_add_link(&source->links);
	if (link == NULL)
		return -ENOMEM;

	
	//初始化 子设备的entity中的 连接抽象(media_link) 	

	/* 	 										
		
链接管道 子设备mipidphy_priv -----  正向link ----- mipi csi phy 
	
																																					
																								
																												mipi csi		
                                                                                                       |----------------------------------|		
														                                               |    entity                     	  |		
								mipi csi phy 														   |                 #-------------#  | 			
														                                               |                 | source0 pad |--|-	
				   |----------------------------------|			mipi csi phy  link                     |                 #-------------#  |		
				   |       entity                     |     |----------------------------------|       |                 #-------------#  |	  	
				   |   #-------------# #-------------#|	    |  #-------------# #-------------# |       |   #----------#  | source1 pad |--|-	
	数据源  -------|-->| sink pad    | | source1 pad ||	----|->| source pad  | | | sink  pad | | ------|-->| sink pad |  #-------------#  | 	
				   |   #-------------# #-------------#|     |  #-------------# #-------------# |       |   #----------#  #-------------#  | 	
				   |----------------------------------|	    |----------------------------------|       |                 | source2 pad |--|-	
				                                                                                       |                 #-------------#  |		
                                                                                                       |                 #-------------#  | 	
                                                                                                       | 				 | source2 pad |--|-	
                                                                                                       |                 #-------------#  |		
                                                                                                       |----------------------------------|		
		  																						
	*/                                                                          
	link->source = &source->pads[source_pad];                                      										
	link->sink = &sink->pads[sink_pad];
	link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;

	/* Initialize graph object embedded at the new link 
	
	绑定 子设备mipidphy_priv -----  link ----- 多媒体设备

		struct mipidphy_priv
			struct v4l2_subdev sd;          绑定 entity---link
				struct media_entity entity;		|	struct media_link
					struct list_head links; ---------> 	struct list_head list; 
														struct media_gobj graph_obj;
															struct media_device	*mdev------+    
															struct list_head	list; -----|--->-+
																						   |     |
					struct media_gobj graph_obj;                   绑定 多媒体设备--link   |     |
							struct media_device	*mdev;	-----------------------------------+     | 挂载到多媒体设备中的 links 链表
								struct list_head links; ------------------<----------------------+

	*/
	media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
			&link->graph_obj);


	//关于反向链接 
	/* 
	
	struct csi2_dev
		struct v4l2_subdev	sd;                        	反向link
			struct media_entity entity;				 struct media_link {
				struct list_head links;-----创建绑定-----> struct list_head list;
				
				
	 */
	backlink = media_add_link(&sink->links);
	if (backlink == NULL) {
		__media_entity_remove_link(source, link);
		return -ENOMEM;
	}

/*

链接管道 子设备 mipi csi phy -----  link(mipi csi link) ----- mipi csi 
																																					

																												mipi csi		
                                                                                                       |----------------------------------|		
														                                               |    entity                     	  |		
								mipi csi phy 														   |                 #-------------#  | 			
														                                               |                 | source0 pad |--|-	
				   |----------------------------------|			mipi csi  back_link                    |                 #-------------#  |		
				   |       entity                     |     |----------------------------------|       |                 #-------------#  |	  	
				   |   #-------------# #-------------#|	    |  #-------------# #-------------# |       |   #----------#  | source1 pad |--|-	
	数据源  -------|-->| sink pad    | | source1 pad ||	----|->| source pad  | | | sink  pad | | ------|-->| sink pad |  #-------------#  | 	
				   |   #-------------# #-------------#|     |  #-------------# #-------------# |       |   #----------#  #-------------#  | 	
				   |----------------------------------|	    |----------------------------------|       |                 | source2 pad |--|-	
				                                                      mipi csi link                    |                 #-------------#  |		
                                                                                                       |                 #-------------#  | 	
                                                                                                       | 				 | source2 pad |--|-	
                                                                                                       |                 #-------------#  |		
                                                                                                       |----------------------------------|		
	
*/
	backlink->source = &source->pads[source_pad];
	backlink->sink = &sink->pads[sink_pad];
	backlink->flags = flags;
	backlink->is_backlink = true;

	/* 
	
	绑定 设备 mipi csi link ----- 多媒体设备
	
	struct csi2_dev
		struct v4l2_subdev	sd;              绑定 entity---backlink
			struct media_entity entity;         	|       struct media_link {
						struct list_head links;	---创建绑定--->	struct list_head list;
																struct media_gobj graph_obj------+
																	struct list_head	list; ---|------+
																	                             |      |
				struct media_gobj graph_obj	                           绑定 多媒体设备--backlink |      |
					struct media_device	*mdev; --------------------------------------------------+      | 挂载到多媒体设备中的 links 链表
						struct list_head links ---------------------------------------------------------+
	*/
	media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
			&backlink->graph_obj);

	/*    
	 * link和backlink关联起来
	 */
	link->reverse = backlink;
	backlink->reverse = link;

	sink->num_backlinks++;
	sink->num_links++;
	source->num_links++;

	return 0;
}
EXPORT_SYMBOL_GPL(media_create_pad_link);	





	/*
	参数1 csi2_dev模块抽象的 反向链接backlink !!!

	参数2 MEDIA_LNK_FL_ENABLED		
	*/
int media_entity_setup_link(struct media_link *link, u32 flags)
{
	int ret;

	mutex_lock(&link->graph_obj.mdev->graph_mutex);
	ret = __media_entity_setup_link(link, flags);
	mutex_unlock(&link->graph_obj.mdev->graph_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(media_entity_setup_link);




	/*
	参数1 mipi csi 模块抽象的 反向链接backlink !!!
		在前面的 media_create_pad_link 中已经设置了 mipi csi 模块抽象的 反向连接(backlink) 的连接方式 : 上一级是 mipi csi phy  下一级是mipi csi

	参数2 MEDIA_LNK_FL_ENABLED		
	*/
int __media_entity_setup_link(struct media_link *link, u32 flags)
{
	const u32 mask = MEDIA_LNK_FL_ENABLED;
	struct media_device *mdev;
	struct media_entity *source, *sink;
	int ret = -EBUSY;

...

	/*
	
	在前面的 media_create_pad_link 中已经设置了 mipi csi 模块抽象的 反向连接(backlink) 的连接方式 : 上一级是 mipi csi phy  下一级是mipi csi
	
	  source entity : mipi csi phy的 模块抽象 entity
	  sink entity : mipi csi的 模块抽象 entity
	 */
	source = link->source->entity;
	sink = link->sink->entity;



	// 找到  mipi csi phy的 模块抽象 entity 所属的 多媒体设备
	mdev = source->graph_obj.mdev;

	
	 /*
	 medv没有ops,跳过
	 */
	if (mdev->ops && mdev->ops->link_notify) {
		ret = mdev->ops->link_notify(link, flags,
					     MEDIA_DEV_NOTIFY_PRE_LINK_CH);
		if (ret < 0)
			return ret;
	}

	/*
	参数1 mipi csi 模块抽象的 反向链接backlink !!!
						
	参数2 MEDIA_LNK_FL_ENABLED		
	*/
	ret = __media_entity_setup_link_notify(link, flags);

	if (mdev->ops && mdev->ops->link_notify)
		mdev->ops->link_notify(link, flags,
				       MEDIA_DEV_NOTIFY_POST_LINK_CH);

	return ret;
}
EXPORT_SYMBOL_GPL(__media_entity_setup_link);




	/*
	参数1 mipi csi 模块抽象的 反向链接backlink !!!
							
	参数2 MEDIA_LNK_FL_ENABLED		
	*/
static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
{
	int ret;

	/* Notify both entities. */
	/*
		对于csi2_dev模块抽象的 反向链接backlink !!!
	
	  source entity : mipi csi phy的 模块抽象 entity
	  sink entity : mipi csi的 模块抽象 entity
	*/
	
	//mipi csi phy的 模块抽象 entity 没有 ops
	ret = media_entity_call(link->source->entity, link_setup,
				link->source, link->sink, flags);
	if (ret < 0 && ret != -ENOIOCTLCMD)
		return ret;

	//mipi csi的 模块抽象 entity 有 ops
	/*
	调用 ops: 
		csi2_entity_ops = {
			.link_setup = csi2_link_setup,
			
	参数1 	mipi csi的 模块抽象 entity	
	参数2   mipi csi 模块抽象的 反向链接backlink 所连接的 下一级pad 即 pad(mipi csi)
	参数3   mipi csi phy 模块抽象的 反向链接backlink 所连接的 上一级pad 即 pad(mipi csi phy)
	参数4   MEDIA_LNK_FL_ENABLED
	
	工作:csi2_link_setup
		在V4L2设备层面,即 v4l2_subdev层面 建立数据源之间的关系, 指定 mipi csi 的V4L2子设备 数据源  是  mipi-csi-phy的V4L2子设备
				struct csi2_dev                           struct mipidphy_priv
					struct v4l2_subdev	*src_sd;------绑定-----struct v4l2_subdev sd
	*/
	ret = media_entity_call(link->sink->entity, link_setup,
				link->sink, link->source, flags);
				
	if (ret < 0 && ret != -ENOIOCTLCMD) {
		media_entity_call(link->source->entity, link_setup,
				  link->source, link->sink, link->flags);
		return ret;
	}

	link->flags = flags;
	link->reverse->flags = link->flags;

	return 0;
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值