Esempio n. 1
0
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;
}