struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse) { struct vsp1_hsit *hsit; int ret; hsit = devm_kzalloc(vsp1->dev, sizeof(*hsit), GFP_KERNEL); if (hsit == NULL) return ERR_PTR(-ENOMEM); hsit->inverse = inverse; hsit->entity.ops = &hsit_entity_ops; if (inverse) hsit->entity.type = VSP1_ENTITY_HSI; else hsit->entity.type = VSP1_ENTITY_HST; ret = vsp1_entity_init(vsp1, &hsit->entity, inverse ? "hsi" : "hst", 2, &hsit_ops, MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV); if (ret < 0) return ERR_PTR(ret); return hsit; }
struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_uds *uds; int ret; uds = devm_kzalloc(vsp1->dev, sizeof(*uds), GFP_KERNEL); if (uds == NULL) return ERR_PTR(-ENOMEM); uds->entity.type = VSP1_ENTITY_UDS; uds->entity.index = index; ret = vsp1_entity_init(vsp1, &uds->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &uds->entity.subdev; v4l2_subdev_init(subdev, &uds_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s uds.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, uds); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); return uds; }
struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1) { struct v4l2_subdev *subdev; struct vsp1_lut *lut; int ret; lut = devm_kzalloc(vsp1->dev, sizeof(*lut), GFP_KERNEL); if (lut == NULL) return ERR_PTR(-ENOMEM); lut->entity.type = VSP1_ENTITY_LUT; ret = vsp1_entity_init(vsp1, &lut->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &lut->entity.subdev; v4l2_subdev_init(subdev, &lut_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s lut", dev_name(vsp1->dev)); v4l2_set_subdevdata(subdev, lut); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); return lut; }
struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index) { struct vsp1_lif *lif; int ret; lif = devm_kzalloc(vsp1->dev, sizeof(*lif), GFP_KERNEL); if (lif == NULL) return ERR_PTR(-ENOMEM); lif->entity.ops = &lif_entity_ops; lif->entity.type = VSP1_ENTITY_LIF; lif->entity.index = index; /* * The LIF is never exposed to userspace, but media entity registration * requires a function to be set. Use PROC_VIDEO_PIXEL_FORMATTER just to * avoid triggering a WARN_ON(), the value won't be seen anywhere. */ ret = vsp1_entity_init(vsp1, &lif->entity, "lif", 2, &lif_ops, MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); if (ret < 0) return ERR_PTR(ret); return lif; }
struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_rwpf *rpf; int ret; rpf = devm_kzalloc(vsp1->dev, sizeof(*rpf), GFP_KERNEL); if (rpf == NULL) return ERR_PTR(-ENOMEM); rpf->ops = &rpf_vdev_ops; rpf->max_width = RPF_MAX_WIDTH; rpf->max_height = RPF_MAX_HEIGHT; rpf->entity.type = VSP1_ENTITY_RPF; rpf->entity.index = index; ret = vsp1_entity_init(vsp1, &rpf->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &rpf->entity.subdev; v4l2_subdev_init(subdev, &rpf_ops); subdev->entity.ops = &vsp1->media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s rpf.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, rpf); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&rpf->ctrls, 1); rpf->alpha = v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); rpf->entity.subdev.ctrl_handler = &rpf->ctrls; if (rpf->ctrls.error) { dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n", index); ret = rpf->ctrls.error; goto error; } return rpf; error: vsp1_entity_destroy(&rpf->entity); return ERR_PTR(ret); }
struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) { struct vsp1_rwpf *wpf; char name[6]; int ret; wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); if (wpf == NULL) return ERR_PTR(-ENOMEM); if (vsp1->info->gen == 2) { wpf->max_width = WPF_GEN2_MAX_WIDTH; wpf->max_height = WPF_GEN2_MAX_HEIGHT; } else { wpf->max_width = WPF_GEN3_MAX_WIDTH; wpf->max_height = WPF_GEN3_MAX_HEIGHT; } wpf->entity.ops = &wpf_entity_ops; wpf->entity.type = VSP1_ENTITY_WPF; wpf->entity.index = index; sprintf(name, "wpf.%u", index); ret = vsp1_entity_init(vsp1, &wpf->entity, name, 2, &wpf_ops, MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); if (ret < 0) return ERR_PTR(ret); /* Initialize the display list manager. */ wpf->dlm = vsp1_dlm_create(vsp1, index, 4); if (!wpf->dlm) { ret = -ENOMEM; goto error; } /* Initialize the control handler. */ ret = wpf_init_controls(wpf); if (ret < 0) { dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", index); goto error; } v4l2_ctrl_handler_setup(&wpf->ctrls); return wpf; error: vsp1_entity_destroy(&wpf->entity); return ERR_PTR(ret); }
struct vsp1_brx *vsp1_brx_create(struct vsp1_device *vsp1, enum vsp1_entity_type type) { struct vsp1_brx *brx; unsigned int num_pads; const char *name; int ret; brx = devm_kzalloc(vsp1->dev, sizeof(*brx), GFP_KERNEL); if (brx == NULL) return ERR_PTR(-ENOMEM); brx->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE : VI6_BRS_BASE; brx->entity.ops = &brx_entity_ops; brx->entity.type = type; if (type == VSP1_ENTITY_BRU) { num_pads = vsp1->info->num_bru_inputs + 1; name = "bru"; } else { num_pads = 3; name = "brs"; } ret = vsp1_entity_init(vsp1, &brx->entity, name, num_pads, &brx_ops, MEDIA_ENT_F_PROC_VIDEO_COMPOSER); if (ret < 0) return ERR_PTR(ret); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&brx->ctrls, 1); v4l2_ctrl_new_std(&brx->ctrls, &brx_ctrl_ops, V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0); brx->bgcolor = 0; brx->entity.subdev.ctrl_handler = &brx->ctrls; if (brx->ctrls.error) { dev_err(vsp1->dev, "%s: failed to initialize controls\n", name); ret = brx->ctrls.error; vsp1_entity_destroy(&brx->entity); return ERR_PTR(ret); } return brx; }
struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1) { struct v4l2_subdev *subdev; struct vsp1_bru *bru; int ret; bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL); if (bru == NULL) return ERR_PTR(-ENOMEM); bru->entity.type = VSP1_ENTITY_BRU; ret = vsp1_entity_init(vsp1, &bru->entity, vsp1->info->num_bru_inputs + 1); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &bru->entity.subdev; v4l2_subdev_init(subdev, &bru_ops); subdev->entity.ops = &vsp1->media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s bru", dev_name(vsp1->dev)); v4l2_set_subdevdata(subdev, bru); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&bru->ctrls, 1); v4l2_ctrl_new_std(&bru->ctrls, &bru_ctrl_ops, V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0); bru->entity.subdev.ctrl_handler = &bru->ctrls; if (bru->ctrls.error) { dev_err(vsp1->dev, "bru: failed to initialize controls\n"); ret = bru->ctrls.error; vsp1_entity_destroy(&bru->entity); return ERR_PTR(ret); } return bru; }
struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1) { struct vsp1_lut *lut; int ret; lut = devm_kzalloc(vsp1->dev, sizeof(*lut), GFP_KERNEL); if (lut == NULL) return ERR_PTR(-ENOMEM); lut->entity.ops = &lut_entity_ops; lut->entity.type = VSP1_ENTITY_LUT; ret = vsp1_entity_init(vsp1, &lut->entity, "lut", 2, &lut_ops); if (ret < 0) return ERR_PTR(ret); return lut; }
struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1) { struct vsp1_lif *lif; int ret; lif = devm_kzalloc(vsp1->dev, sizeof(*lif), GFP_KERNEL); if (lif == NULL) return ERR_PTR(-ENOMEM); lif->entity.ops = &lif_entity_ops; lif->entity.type = VSP1_ENTITY_LIF; ret = vsp1_entity_init(vsp1, &lif->entity, "lif", 2, &lif_ops); if (ret < 0) return ERR_PTR(ret); return lif; }
struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) { struct vsp1_rwpf *rpf; char name[6]; int ret; rpf = devm_kzalloc(vsp1->dev, sizeof(*rpf), GFP_KERNEL); if (rpf == NULL) return ERR_PTR(-ENOMEM); rpf->max_width = RPF_MAX_WIDTH; rpf->max_height = RPF_MAX_HEIGHT; rpf->entity.ops = &rpf_entity_ops; rpf->entity.type = VSP1_ENTITY_RPF; rpf->entity.index = index; sprintf(name, "rpf.%u", index); ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &rpf_ops, MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); if (ret < 0) return ERR_PTR(ret); /* Initialize the control handler. */ ret = vsp1_rwpf_init_ctrls(rpf, 0); if (ret < 0) { dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n", index); goto error; } v4l2_ctrl_handler_setup(&rpf->ctrls); return rpf; error: vsp1_entity_destroy(&rpf->entity); return ERR_PTR(ret); }
struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1) { struct vsp1_clu *clu; int ret; clu = devm_kzalloc(vsp1->dev, sizeof(*clu), GFP_KERNEL); if (clu == NULL) return ERR_PTR(-ENOMEM); spin_lock_init(&clu->lock); clu->entity.ops = &clu_entity_ops; clu->entity.type = VSP1_ENTITY_CLU; ret = vsp1_entity_init(vsp1, &clu->entity, "clu", 2, &clu_ops, MEDIA_ENT_F_PROC_VIDEO_LUT); if (ret < 0) return ERR_PTR(ret); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&clu->ctrls, 2); v4l2_ctrl_new_custom(&clu->ctrls, &clu_table_control, NULL); v4l2_ctrl_new_custom(&clu->ctrls, &clu_mode_control, NULL); clu->entity.subdev.ctrl_handler = &clu->ctrls; if (clu->ctrls.error) { dev_err(vsp1->dev, "clu: failed to initialize controls\n"); ret = clu->ctrls.error; vsp1_entity_destroy(&clu->entity); return ERR_PTR(ret); } v4l2_ctrl_handler_setup(&clu->ctrls); return clu; }
struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1) { struct vsp1_bru *bru; int ret; bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL); if (bru == NULL) return ERR_PTR(-ENOMEM); bru->entity.ops = &bru_entity_ops; bru->entity.type = VSP1_ENTITY_BRU; ret = vsp1_entity_init(vsp1, &bru->entity, "bru", vsp1->info->num_bru_inputs + 1, &bru_ops, MEDIA_ENT_F_PROC_VIDEO_COMPOSER); if (ret < 0) return ERR_PTR(ret); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&bru->ctrls, 1); v4l2_ctrl_new_std(&bru->ctrls, &bru_ctrl_ops, V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0); bru->bgcolor = 0; bru->entity.subdev.ctrl_handler = &bru->ctrls; if (bru->ctrls.error) { dev_err(vsp1->dev, "bru: failed to initialize controls\n"); ret = bru->ctrls.error; vsp1_entity_destroy(&bru->entity); return ERR_PTR(ret); } return bru; }
struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1) { struct vsp1_lut *lut; int ret; lut = devm_kzalloc(vsp1->dev, sizeof(*lut), GFP_KERNEL); if (lut == NULL) return ERR_PTR(-ENOMEM); spin_lock_init(&lut->lock); lut->entity.ops = &lut_entity_ops; lut->entity.type = VSP1_ENTITY_LUT; ret = vsp1_entity_init(vsp1, &lut->entity, "lut", 2, &lut_ops, MEDIA_ENT_F_PROC_VIDEO_LUT); if (ret < 0) return ERR_PTR(ret); /* Initialize the control handler. */ v4l2_ctrl_handler_init(&lut->ctrls, 1); v4l2_ctrl_new_custom(&lut->ctrls, &lut_table_control, NULL); lut->entity.subdev.ctrl_handler = &lut->ctrls; if (lut->ctrls.error) { dev_err(vsp1->dev, "lut: failed to initialize controls\n"); ret = lut->ctrls.error; vsp1_entity_destroy(&lut->entity); return ERR_PTR(ret); } v4l2_ctrl_handler_setup(&lut->ctrls); return lut; }
struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse) { struct v4l2_subdev *subdev; struct vsp1_hsit *hsit; int ret; hsit = devm_kzalloc(vsp1->dev, sizeof(*hsit), GFP_KERNEL); if (hsit == NULL) return ERR_PTR(-ENOMEM); hsit->inverse = inverse; if (inverse) hsit->entity.type = VSP1_ENTITY_HSI; else hsit->entity.type = VSP1_ENTITY_HST; ret = vsp1_entity_init(vsp1, &hsit->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &hsit->entity.subdev; v4l2_subdev_init(subdev, &hsit_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s %s", dev_name(vsp1->dev), inverse ? "hsi" : "hst"); v4l2_set_subdevdata(subdev, hsit); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); return hsit; }
int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo, enum vsp1_entity_type type, const char *name, const struct vsp1_entity_operations *ops, const unsigned int *formats, unsigned int num_formats, size_t data_size, u32 meta_format) { int ret; histo->formats = formats; histo->num_formats = num_formats; histo->data_size = data_size; histo->meta_format = meta_format; histo->pad.flags = MEDIA_PAD_FL_SINK; histo->video.vfl_dir = VFL_DIR_RX; mutex_init(&histo->lock); spin_lock_init(&histo->irqlock); INIT_LIST_HEAD(&histo->irqqueue); init_waitqueue_head(&histo->wait_queue); /* Initialize the VSP entity... */ histo->entity.ops = ops; histo->entity.type = type; ret = vsp1_entity_init(vsp1, &histo->entity, name, 2, &histo_ops, MEDIA_ENT_F_PROC_VIDEO_STATISTICS); if (ret < 0) return ret; /* ... and the media entity... */ ret = media_entity_pads_init(&histo->video.entity, 1, &histo->pad); if (ret < 0) return ret; /* ... and the video node... */ histo->video.v4l2_dev = &vsp1->v4l2_dev; histo->video.fops = &histo_v4l2_fops; snprintf(histo->video.name, sizeof(histo->video.name), "%s histo", histo->entity.subdev.name); histo->video.vfl_type = VFL_TYPE_GRABBER; histo->video.release = video_device_release_empty; histo->video.ioctl_ops = &histo_v4l2_ioctl_ops; video_set_drvdata(&histo->video, histo); /* ... and the buffers queue... */ histo->queue.type = V4L2_BUF_TYPE_META_CAPTURE; histo->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; histo->queue.lock = &histo->lock; histo->queue.drv_priv = histo; histo->queue.buf_struct_size = sizeof(struct vsp1_histogram_buffer); histo->queue.ops = &histo_video_queue_qops; histo->queue.mem_ops = &vb2_vmalloc_memops; histo->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; histo->queue.dev = vsp1->dev; ret = vb2_queue_init(&histo->queue); if (ret < 0) { dev_err(vsp1->dev, "failed to initialize vb2 queue\n"); goto error; } /* ... and register the video device. */ histo->video.queue = &histo->queue; ret = video_register_device(&histo->video, VFL_TYPE_GRABBER, -1); if (ret < 0) { dev_err(vsp1->dev, "failed to register video device\n"); goto error; } return 0; error: vsp1_histogram_cleanup(histo); return ret; }
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); }
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; 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 control handler. */ v4l2_ctrl_handler_init(&wpf->ctrls, 1); v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); wpf->entity.subdev.ctrl_handler = &wpf->ctrls; if (wpf->ctrls.error) { dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", index); ret = wpf->ctrls.error; goto error; } /* 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; wpf->entity.video = 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; wpf->entity.sink = &wpf->video.video.entity; return wpf; error: vsp1_entity_destroy(&wpf->entity); return ERR_PTR(ret); }
struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *rpf; int ret; rpf = devm_kzalloc(vsp1->dev, sizeof(*rpf), GFP_KERNEL); if (rpf == NULL) return ERR_PTR(-ENOMEM); rpf->max_width = RPF_MAX_WIDTH; rpf->max_height = RPF_MAX_HEIGHT; rpf->entity.type = VSP1_ENTITY_RPF; rpf->entity.index = index; ret = vsp1_entity_init(vsp1, &rpf->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &rpf->entity.subdev; v4l2_subdev_init(subdev, &rpf_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s rpf.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, rpf); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the video device. */ video = &rpf->video; video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; video->vsp1 = vsp1; video->ops = &rpf_vdev_ops; ret = vsp1_video_init(video, &rpf->entity); if (ret < 0) goto error_video; /* Connect the video device to the RPF. */ ret = media_entity_create_link(&rpf->video.video.entity, 0, &rpf->entity.subdev.entity, RWPF_PAD_SINK, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) goto error_link; return rpf; error_link: vsp1_video_cleanup(video); error_video: media_entity_cleanup(&rpf->entity.subdev.entity); return ERR_PTR(ret); }