/* Return a pointer to the ISP video instance at the far end of the pipeline. */ static struct isp_video * isp_video_far_end(struct isp_video *video) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; struct media_device *mdev = entity->parent; struct isp_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video.entity) continue; if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) continue; far_end = to_isp_video(media_entity_to_video_device(entity)); if (far_end->type != video->type) break; far_end = NULL; } mutex_unlock(&mdev->graph_mutex); return far_end; }
/* make a note of pipeline details */ static void vpfe_prepare_pipeline(struct vpfe_video_device *video) { struct media_entity *entity = &video->video_dev.entity; struct media_device *mdev = entity->parent; struct vpfe_pipeline *pipe = &video->pipe; struct vpfe_video_device *far_end = NULL; struct media_entity_graph graph; pipe->input_num = 0; pipe->output_num = 0; if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) pipe->inputs[pipe->input_num++] = video; else pipe->outputs[pipe->output_num++] = video; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) continue; if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) continue; far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) pipe->inputs[pipe->input_num++] = far_end; else pipe->outputs[pipe->output_num++] = far_end; } mutex_unlock(&mdev->graph_mutex); }
/* Return a pointer to the ISP video instance at the far end of the pipeline. */ static int isp_video_get_graph_data(struct isp_video *video, struct isp_pipeline *pipe) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; struct media_device *mdev = entity->graph_obj.mdev; struct isp_video *far_end = NULL; int ret; mutex_lock(&mdev->graph_mutex); ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); if (ret) { mutex_unlock(&mdev->graph_mutex); return ret; } media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video; media_entity_enum_set(&pipe->ent_enum, entity); if (far_end != NULL) continue; if (entity == &video->video.entity) continue; if (!is_media_entity_v4l2_video_device(entity)) continue; __video = to_isp_video(media_entity_to_video_device(entity)); if (__video->type != video->type) far_end = __video; } mutex_unlock(&mdev->graph_mutex); media_entity_graph_walk_cleanup(&graph); if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { pipe->input = far_end; pipe->output = video; } else { if (far_end == NULL) return -EPIPE; pipe->input = video; pipe->output = far_end; } return 0; }
/* Return a pointer to the ISP video instance at the far end of the pipeline. */ static int isp_video_get_graph_data(struct isp_video *video, struct isp_pipeline *pipe) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; struct media_device *mdev = entity->parent; struct isp_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video; pipe->entities |= 1 << entity->id; if (far_end != NULL) continue; if (entity == &video->video.entity) continue; if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) continue; __video = to_isp_video(media_entity_to_video_device(entity)); if (__video->type != video->type) far_end = __video; } mutex_unlock(&mdev->graph_mutex); if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { pipe->input = far_end; pipe->output = video; } else { if (far_end == NULL) return -EPIPE; pipe->input = video; pipe->output = far_end; } return 0; }
/* make a note of pipeline details */ static int vpfe_prepare_pipeline(struct vpfe_video_device *video) { struct media_graph graph; struct media_entity *entity = &video->video_dev.entity; struct media_device *mdev = entity->graph_obj.mdev; struct vpfe_pipeline *pipe = &video->pipe; struct vpfe_video_device *far_end = NULL; int ret; pipe->input_num = 0; pipe->output_num = 0; if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) pipe->inputs[pipe->input_num++] = video; else pipe->outputs[pipe->output_num++] = video; mutex_lock(&mdev->graph_mutex); ret = media_graph_walk_init(&graph, mdev); if (ret) { mutex_unlock(&mdev->graph_mutex); return -ENOMEM; } media_graph_walk_start(&graph, entity); while ((entity = media_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) continue; if (!is_media_entity_v4l2_video_device(entity)) continue; far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) pipe->inputs[pipe->input_num++] = far_end; else pipe->outputs[pipe->output_num++] = far_end; } media_graph_walk_cleanup(&graph); mutex_unlock(&mdev->graph_mutex); return 0; }
static int xvip_pipeline_validate(struct xvip_pipeline *pipe, struct xvip_dma *start) { struct media_entity_graph graph; struct media_entity *entity = &start->video.entity; struct media_device *mdev = entity->parent; unsigned int num_inputs = 0; unsigned int num_outputs = 0; mutex_lock(&mdev->graph_mutex); /* Walk the graph to locate the video nodes. */ media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma; if (entity->type != MEDIA_ENT_T_DEVNODE_V4L) continue; dma = to_xvip_dma(media_entity_to_video_device(entity)); if (dma->pad.flags & MEDIA_PAD_FL_SINK) { pipe->output = dma; num_outputs++; } else { num_inputs++; } } mutex_unlock(&mdev->graph_mutex); /* We need exactly one output and zero or one input. */ if (num_outputs != 1 || num_inputs > 1) return -EPIPE; pipe->num_dmas = num_inputs + num_outputs; return 0; }
/* * media_entity_operations */ static int nxp_link_setup(struct media_entity *entity, const struct media_pad *local, const struct media_pad *remote, u32 flags) { struct video_device *vdev = media_entity_to_video_device(entity); struct nxp_video *me = video_get_drvdata(vdev); pr_debug("%s: me type(%d)\n", __func__, me->type); switch (local->index | media_entity_type(remote->entity)) { case 0 | MEDIA_ENT_T_V4L2_SUBDEV: /* capture, m2m : sink * video : source */ pr_debug("local %d, link subdev\n", local->index); break; case 0 | MEDIA_ENT_T_DEVNODE: pr_debug("local %d, link videodev\n", local->index); break; case 1 | MEDIA_ENT_T_V4L2_SUBDEV: pr_debug("local %d, link subdev\n", local->index); break; case 1 | MEDIA_ENT_T_DEVNODE: pr_debug("local %d, link videodev\n", local->index); break; } if (flags & MEDIA_LNK_FL_ENABLED) pr_debug("====> linked\n"); else pr_debug("====> unlinked\n"); return 0; }