int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, unsigned int num_pads) { static const struct { unsigned int id; unsigned int reg; } routes[] = { { VI6_DPR_NODE_HSI, VI6_DPR_HSI_ROUTE }, { VI6_DPR_NODE_HST, VI6_DPR_HST_ROUTE }, { VI6_DPR_NODE_LIF, 0 }, { VI6_DPR_NODE_LUT, VI6_DPR_LUT_ROUTE }, { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) }, { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) }, { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) }, { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) }, { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) }, { VI6_DPR_NODE_SRU, VI6_DPR_SRU_ROUTE }, { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) }, { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) }, { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) }, { VI6_DPR_NODE_WPF(0), 0 }, { VI6_DPR_NODE_WPF(1), 0 }, { VI6_DPR_NODE_WPF(2), 0 }, { VI6_DPR_NODE_WPF(3), 0 }, }; unsigned int i; for (i = 0; i < ARRAY_SIZE(routes); ++i) { if (routes[i].id == entity->id) { entity->route = routes[i].reg; break; } } if (i == ARRAY_SIZE(routes)) return -EINVAL; entity->vsp1 = vsp1; entity->source_pad = num_pads - 1; /* Allocate formats and pads. */ entity->formats = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->formats), GFP_KERNEL); if (entity->formats == NULL) return -ENOMEM; entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads), GFP_KERNEL); if (entity->pads == NULL) return -ENOMEM; /* Initialize pads. */ for (i = 0; i < num_pads - 1; ++i) entity->pads[i].flags = MEDIA_PAD_FL_SINK; entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE; /* Initialize the media entity. */ return media_entity_init(&entity->subdev.entity, num_pads, entity->pads, 0); }
{ VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1), VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), } }, { VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } }, { VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } }, { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } }, { VSP1_ENTITY_LUT, 0, VI6_DPR_LUT_ROUTE, { VI6_DPR_NODE_LUT, } }, { VSP1_ENTITY_RPF, 0, VI6_DPR_RPF_ROUTE(0), { VI6_DPR_NODE_RPF(0), } }, { VSP1_ENTITY_RPF, 1, VI6_DPR_RPF_ROUTE(1), { VI6_DPR_NODE_RPF(1), } }, { VSP1_ENTITY_RPF, 2, VI6_DPR_RPF_ROUTE(2), { VI6_DPR_NODE_RPF(2), } }, { VSP1_ENTITY_RPF, 3, VI6_DPR_RPF_ROUTE(3), { VI6_DPR_NODE_RPF(3), } }, { VSP1_ENTITY_RPF, 4, VI6_DPR_RPF_ROUTE(4), { VI6_DPR_NODE_RPF(4), } }, { VSP1_ENTITY_SRU, 0, VI6_DPR_SRU_ROUTE, { VI6_DPR_NODE_SRU, } }, { VSP1_ENTITY_UDS, 0, VI6_DPR_UDS_ROUTE(0), { VI6_DPR_NODE_UDS(0), } }, { VSP1_ENTITY_UDS, 1, VI6_DPR_UDS_ROUTE(1), { VI6_DPR_NODE_UDS(1), } }, { VSP1_ENTITY_UDS, 2, VI6_DPR_UDS_ROUTE(2), { VI6_DPR_NODE_UDS(2), } }, { VSP1_ENTITY_WPF, 0, 0, { VI6_DPR_NODE_WPF(0), } }, { VSP1_ENTITY_WPF, 1, 0, { VI6_DPR_NODE_WPF(1), } }, { VSP1_ENTITY_WPF, 2, 0, { VI6_DPR_NODE_WPF(2), } }, { VSP1_ENTITY_WPF, 3, 0, { VI6_DPR_NODE_WPF(3), } }, }; int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, unsigned int num_pads) { unsigned int i; for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) { if (vsp1_routes[i].type == entity->type && vsp1_routes[i].index == entity->index) { entity->route = &vsp1_routes[i]; break;
struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *wpf; unsigned int flags; int ret; wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); if (wpf == NULL) return ERR_PTR(-ENOMEM); wpf->max_width = WPF_MAX_WIDTH; wpf->max_height = WPF_MAX_HEIGHT; wpf->entity.type = VSP1_ENTITY_WPF; wpf->entity.index = index; wpf->entity.id = VI6_DPR_NODE_WPF(index); ret = vsp1_entity_init(vsp1, &wpf->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &wpf->entity.subdev; v4l2_subdev_init(subdev, &wpf_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s wpf.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, wpf); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the video device. */ video = &wpf->video; video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; video->vsp1 = vsp1; video->ops = &wpf_vdev_ops; ret = vsp1_video_init(video, &wpf->entity); if (ret < 0) goto error_video; /* Connect the video device to the WPF. All connections are immutable * except for the WPF0 source link if a LIF is present. */ flags = MEDIA_LNK_FL_ENABLED; if (!(vsp1->pdata->features & VSP1_HAS_LIF) || index != 0) flags |= MEDIA_LNK_FL_IMMUTABLE; ret = media_entity_create_link(&wpf->entity.subdev.entity, RWPF_PAD_SOURCE, &wpf->video.video.entity, 0, flags); if (ret < 0) goto error_link; wpf->entity.sink = &wpf->video.video.entity; return wpf; error_link: vsp1_video_cleanup(video); error_video: media_entity_cleanup(&wpf->entity.subdev.entity); return ERR_PTR(ret); }