int gsc_register_capture_device(struct gsc_dev *gsc) { struct video_device *vfd; struct gsc_capture_device *gsc_cap; struct gsc_ctx *ctx; struct vb2_queue *q; struct exynos_platform_gscaler *pdata = gsc->pdata; struct exynos_isp_info *isp_info; int ret = -ENOMEM; int i; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->gsc_dev = gsc; ctx->in_path = GSC_CAMERA; ctx->out_path = GSC_DMA; ctx->state = GSC_CTX_CAP; vfd = video_device_alloc(); if (!vfd) { printk("Failed to allocate video device\n"); goto err_ctx_alloc; } snprintf(vfd->name, sizeof(vfd->name), "%s.capture", dev_name(&gsc->pdev->dev)); vfd->fops = &gsc_capture_fops; vfd->ioctl_ops = &gsc_capture_ioctl_ops; vfd->v4l2_dev = &gsc->mdev[MDEV_CAPTURE]->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &gsc->lock; video_set_drvdata(vfd, gsc); gsc_cap = &gsc->cap; gsc_cap->vfd = vfd; gsc_cap->refcnt = 0; gsc_cap->active_buf_cnt = 0; gsc_cap->reqbufs_cnt = 0; spin_lock_init(&ctx->slock); gsc_cap->ctx = ctx; q = &gsc->cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = gsc->cap.ctx; q->ops = &gsc_capture_qops; q->mem_ops = gsc->vb2->ops; vb2_queue_init(q); /* Get mipi-csis and fimc-lite subdev ptr using mdev */ for (i = 0; i < FLITE_MAX_ENTITIES; i++) gsc->cap.sd_flite[i] = gsc->mdev[MDEV_CAPTURE]->flite_sd[i]; for (i = 0; i < CSIS_MAX_ENTITIES; i++) gsc->cap.sd_csis[i] = gsc->mdev[MDEV_CAPTURE]->csis_sd[i]; if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) { isp_info = pdata->isp_info[i]; ret = gsc_cap_config_camclk(gsc, isp_info, i); if (ret) { gsc_err("failed setup cam clk"); goto err_ctx_alloc; } } } ret = gsc_cap_register_sensor_entities(gsc); if (ret) { gsc_err("failed register sensor entities"); goto err_clk; } ret = video_register_device(vfd, VFL_TYPE_GRABBER, EXYNOS_VIDEONODE_GSC_CAP(gsc->id)); if (ret) { gsc_err("failed to register video device"); goto err_clk; } gsc->cap.vd_pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&vfd->entity, 1, &gsc->cap.vd_pad, 0); if (ret) { gsc_err("failed to initialize entity"); goto err_ent; } ret = gsc_capture_create_subdev(gsc); if (ret) { gsc_err("failed create subdev"); goto err_sd_reg; } ret = gsc_capture_create_link(gsc); if (ret) { gsc_err("failed create link"); goto err_sd_reg; } vfd->ctrl_handler = &ctx->ctrl_handler; gsc_dbg("gsc capture driver registered as /dev/video%d", vfd->num); return 0; err_sd_reg: media_entity_cleanup(&vfd->entity); err_ent: video_device_release(vfd); err_clk: if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) clk_put(gsc_cap->sensor[i].camclk); } err_ctx_alloc: kfree(ctx); return ret; }
int gsc_register_capture_device(struct gsc_dev *gsc) { struct video_device *vfd; struct gsc_capture_device *gsc_cap; struct gsc_ctx *ctx; struct vb2_queue *q; int ret = -ENOMEM; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->gsc_dev = gsc; ctx->in_path = GSC_WRITEBACK; ctx->out_path = GSC_DMA; ctx->state = GSC_CTX_CAP; vfd = video_device_alloc(); if (!vfd) { printk("Failed to allocate video device\n"); goto err_ctx_alloc; } snprintf(vfd->name, sizeof(vfd->name), "%s.capture", dev_name(&gsc->pdev->dev)); vfd->fops = &gsc_capture_fops; vfd->ioctl_ops = &gsc_capture_ioctl_ops; vfd->v4l2_dev = &gsc->mdev[MDEV_CAPTURE]->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &gsc->lock; vfd->vfl_dir = VFL_DIR_RX; video_set_drvdata(vfd, gsc); gsc_cap = &gsc->cap; gsc_cap->vfd = vfd; gsc_cap->refcnt = 0; gsc_cap->active_buf_cnt = 0; gsc_cap->reqbufs_cnt = 0; INIT_LIST_HEAD(&gsc->cap.active_buf_q); spin_lock_init(&ctx->slock); gsc_cap->ctx = ctx; q = &gsc->cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = gsc->cap.ctx; q->ops = &gsc_capture_qops; q->mem_ops = gsc->vb2->ops; q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(q); if (ret) { gsc_err("failed to init vb2_queue"); goto err_ctx_alloc; } ret = video_register_device(vfd, VFL_TYPE_GRABBER, EXYNOS_VIDEONODE_GSC_CAP(gsc->id)); if (ret) { gsc_err("failed to register video device"); goto err_ctx_alloc; } gsc->cap.vd_pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&vfd->entity, 1, &gsc->cap.vd_pad, 0); if (ret) { gsc_err("failed to initialize entity"); goto err_ent; } ret = gsc_capture_create_subdev(gsc); if (ret) { gsc_err("failed create subdev"); goto err_sd_reg; } ret = gsc_capture_create_link(gsc); if (ret) { gsc_err("failed create link"); goto err_sd_reg; } vfd->ctrl_handler = &ctx->ctrl_handler; gsc_info("gsc capture driver registered as /dev/video%d", vfd->num); return 0; err_sd_reg: media_entity_cleanup(&vfd->entity); err_ent: video_device_release(vfd); err_ctx_alloc: kfree(ctx); return ret; }