static int fimc_is_scp_stop_streaming(struct vb2_queue *q)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = q->drv_priv;
	struct fimc_is_queue *queue;
	struct fimc_is_device_ischain *device;
	struct fimc_is_subdev *subdev;

	BUG_ON(!vctx);

	mdbgv_scp("%s\n", vctx, __func__);

	queue = GET_DST_QUEUE(vctx);
	device = vctx->device;
	if (!device) {
		err("device is NULL");
		ret = -EINVAL;
		goto p_err;
	}
	subdev = &device->scp;

	ret = fimc_is_queue_stop_streaming(queue, device, subdev, vctx);
	if (ret)
		merr("fimc_is_queue_stop_streaming is fail(%d)", vctx, ret);

p_err:
	return ret;
}
static int fimc_is_scp_queue_setup(struct vb2_queue *vbq,
	const struct v4l2_format *fmt,
	unsigned int *num_buffers,
	unsigned int *num_planes,
	unsigned int sizes[],
	void *allocators[])
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = vbq->drv_priv;
	struct fimc_is_video *video;
	struct fimc_is_queue *queue;
	struct fimc_is_core *core;
	void *alloc_ctx;

	BUG_ON(!vctx);

	mdbgv_scp("%s\n", vctx, __func__);

	video = vctx->video;
	queue = GET_DST_QUEUE(vctx);
	core = video->core;
	alloc_ctx = core->mem.alloc_ctx;

	ret = fimc_is_queue_setup(queue,
		alloc_ctx,
		num_planes,
		sizes,
		allocators);
	if (ret)
		merr("fimc_is_queue_setup is fail(%d)", vctx, ret);

	return ret;
}
static int fimc_is_scp_video_g_ctrl(struct file *file, void *priv,
	struct v4l2_control *ctrl)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_framemgr *framemgr;

	BUG_ON(!vctx);
	BUG_ON(!ctrl);

	mdbgv_scp("%s\n", vctx, __func__);

	framemgr = GET_DST_FRAMEMGR(vctx);

	switch (ctrl->id) {
	case V4L2_CID_IS_G_COMPLETES:
		ctrl->value = framemgr->frame_com_cnt;
		break;
	default:
		err("unsupported ioctl(%d)\n", ctrl->id);
		ret = -EINVAL;
		break;
	}

	return ret;
}
static int fimc_is_scp_video_set_crop(struct file *file, void *fh,
	struct v4l2_crop *crop)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_queue *queue;
	struct fimc_is_device_ischain *ischain;

	BUG_ON(!vctx);

	mdbgv_scp("%s\n", vctx, __func__);

	queue = GET_DST_QUEUE(vctx);
	ischain = vctx->device;
	if (!ischain) {
		merr("ischain is NULL", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	ret = fimc_is_ischain_scp_s_format(ischain,
		queue->framecfg.format.pixelformat,
		crop->c.width,
		crop->c.height);
	if (ret)
		merr("fimc_is_ischain_scp_s_format is fail(%d)", vctx, ret);

p_err:
	return ret;
}
static int fimc_is_scp_video_set_format_mplane(struct file *file, void *fh,
	struct v4l2_format *format)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_queue *queue;
	struct fimc_is_device_ischain *ischain;

	BUG_ON(!vctx);
	BUG_ON(!vctx->device);
	BUG_ON(!format);

	mdbgv_scp("%s\n", vctx, __func__);

	queue = GET_DST_QUEUE(vctx);
	ischain = vctx->device;

	ret = fimc_is_video_set_format_mplane(file, vctx, format);
	if (ret) {
		merr("fimc_is_video_set_format_mplane is fail(%d)", vctx, ret);
		goto p_err;
	}

	ret = fimc_is_ischain_scp_s_format(ischain,
		queue->framecfg.format.pixelformat,
		queue->framecfg.width,
		queue->framecfg.height);
	if (ret)
		merr("fimc_is_ischain_scp_s_format is fail(%d)", vctx, ret);

p_err:
	return ret;
}
Example #6
0
static int fimc_is_scp_video_open(struct file *file)
{
	int ret = 0;
	u32 refcount;
	struct fimc_is_core *core;
	struct fimc_is_video *video;
	struct fimc_is_video_ctx *vctx;
	struct fimc_is_device_ischain *device;

	vctx = NULL;
	video = video_drvdata(file);
	core = container_of(video, struct fimc_is_core, video_scp);

	ret = open_vctx(file, video, &vctx, FRAMEMGR_ID_INVALID, FRAMEMGR_ID_SCP);
	if (ret) {
		err("open_vctx is fail(%d)", ret);
		goto p_err;
	}

	mdbgv_scp("[SCP:V:%d] %s\n",vctx, vctx->instance, __func__);

	refcount = atomic_read(&core->video_isp.refcount);
	if (refcount > FIMC_IS_MAX_NODES || refcount < 1) {
		err("invalid ischain refcount(%d)", refcount);
		close_vctx(file, video, vctx);
		ret = -EINVAL;
		goto p_err;
	}

	device = &core->ischain[refcount - 1];

	ret = fimc_is_video_open(vctx,
		device,
		VIDEO_SCP_READY_BUFFERS,
		video,
		FIMC_IS_VIDEO_TYPE_CAPTURE,
		&fimc_is_scp_qops,
		NULL,
		&fimc_is_ischain_sub_ops);
	if (ret) {
		err("fimc_is_video_open is fail");
		close_vctx(file, video, vctx);
		goto p_err;
	}

	ret = fimc_is_subdev_open(&device->scp, vctx, NULL);
	if (ret) {
		err("fimc_is_subdev_open is fail");
		close_vctx(file, video, vctx);
		goto p_err;
	}

p_err:
	return ret;
}
static int fimc_is_scp_video_s_ctrl(struct file *file, void *priv,
	struct v4l2_control *ctrl)
{
	int ret = 0;
	unsigned long flags;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_framemgr *framemgr;
	struct fimc_is_frame *frame;

	BUG_ON(!vctx);
	BUG_ON(!ctrl);

	mdbgv_scp("%s\n", vctx, __func__);

	framemgr = GET_DST_FRAMEMGR(vctx);
	frame = NULL;

	switch (ctrl->id) {
	case V4L2_CID_IS_FORCE_DONE:
		if (framemgr->frame_pro_cnt) {
			err("force done can be performed(process count %d)",
				framemgr->frame_pro_cnt);
			ret = -EINVAL;
		} else if (!framemgr->frame_req_cnt) {
			err("force done can be performed(request count %d)",
				framemgr->frame_req_cnt);
			ret = -EINVAL;
		} else {
			framemgr_e_barrier_irqs(framemgr, 0, flags);

			fimc_is_frame_request_head(framemgr, &frame);
			if (frame) {
				fimc_is_frame_trans_req_to_com(framemgr, frame);
				buffer_done(vctx, frame->index);
			} else {
				err("frame is NULL");
				ret = -EINVAL;
			}

			framemgr_x_barrier_irqr(framemgr, 0, flags);
		}
		break;
	default:
		err("unsupported ioctl(%d)\n", ctrl->id);
		ret = -EINVAL;
		break;
	}

	return ret;
}
static int fimc_is_scp_video_streamoff(struct file *file, void *priv,
	enum v4l2_buf_type type)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;

	mdbgv_scp("%s\n", vctx, __func__);

	ret = fimc_is_video_streamoff(file, vctx, type);
	if (ret)
		merr("fimc_is_video_streamoff is fail(%d)", vctx, ret);

	return ret;
}
static int fimc_is_scp_video_querybuf(struct file *file, void *priv,
	struct v4l2_buffer *buf)
{
	int ret;
	struct fimc_is_video_ctx *vctx = file->private_data;

	mdbgv_scp("%s\n", vctx, __func__);

	ret = fimc_is_video_querybuf(file, vctx, buf);
	if (ret)
		merr("fimc_is_video_querybuf is fail(%d)", vctx, ret);

	return ret;
}
static int fimc_is_scp_video_dqbuf(struct file *file, void *priv,
	struct v4l2_buffer *buf)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;

#ifdef DBG_STREAMING
	mdbgv_scp("%s\n", vctx, __func__);
#endif

	ret = fimc_is_video_dqbuf(file, vctx, buf);
	if (ret)
		merr("fimc_is_video_dqbuf is fail(%d)", vctx, ret);

	return ret;
}
Example #11
0
static int fimc_is_scp_video_close(struct file *file)
{
	int ret = 0;
	struct fimc_is_video *video = NULL;
	struct fimc_is_video_ctx *vctx = NULL;
	struct fimc_is_device_ischain *device = NULL;

	BUG_ON(!file);

	vctx = file->private_data;
	if (!vctx) {
		err("vctx is NULL");
		ret = -EINVAL;
		goto p_err;
	}

	video = vctx->video;
	if (!video) {
		merr("video is NULL", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	mdbgv_scp("[SCP:V:%d] %s\n", vctx, vctx->instance, __func__);

	device = vctx->device;
	if (!device) {
		err("device is NULL");
		ret = -EINVAL;
		goto p_err;
	}

	fimc_is_subdev_close(&device->scp);
	fimc_is_video_close(vctx);

	ret = close_vctx(file, video, vctx);
	if (ret < 0)
		err("close_vctx is fail(%d)", ret);

p_err:
	return ret;
}
static int fimc_is_scp_start_streaming(struct vb2_queue *q,
	unsigned int count)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = q->drv_priv;
	struct fimc_is_queue *queue;
	struct fimc_is_device_ischain *device;
	struct fimc_is_subdev *subdev;

	BUG_ON(!vctx);

	mdbgv_scp("%s\n", vctx, __func__);

	queue = GET_DST_QUEUE(vctx);
	device = vctx->device;
	subdev = &device->scp;

	ret = fimc_is_queue_start_streaming(queue, device, subdev, vctx);
	if (ret)
		merr("fimc_is_queue_start_streaming is fail(%d)", vctx, ret);

	return ret;
}
static int fimc_is_scp_video_reqbufs(struct file *file, void *priv,
					struct v4l2_requestbuffers *buf)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_device_ischain *device;
	struct fimc_is_subdev *subdev;
	struct fimc_is_subdev *leader;

	BUG_ON(!vctx);

	mdbgv_scp("%s(buffers : %d)\n", vctx, __func__, buf->count);

	device = vctx->device;
	subdev = &device->scp;
	leader = subdev->leader;

	if (!leader) {
		merr("leader is NULL ptr", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	if (test_bit(FIMC_IS_ISDEV_DSTART, &leader->state)) {
		merr("leader still running, not applied", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	ret = fimc_is_video_reqbufs(file, vctx, buf);
	if (ret)
		merr("fimc_is_video_reqbufs is fail(%d)", vctx, ret);

p_err:
	return ret;
}
static int fimc_is_scp_video_s_ctrl(struct file *file, void *priv,
	struct v4l2_control *ctrl)
{
	int ret = 0;
	unsigned long flags;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_device_ischain *device;
	struct fimc_is_framemgr *framemgr;
	struct fimc_is_frame *frame;

	BUG_ON(!vctx);
	BUG_ON(!ctrl);

	mdbgv_scp("%s\n", vctx, __func__);

	device = vctx->device;
	if (!device) {
		merr("device is NULL", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	framemgr = GET_DST_FRAMEMGR(vctx);
	frame = NULL;

	switch (ctrl->id) {
	case V4L2_CID_IS_FORCE_DONE:
		if (framemgr->frame_pro_cnt) {
			err("force done can be performed(process count %d)",
				framemgr->frame_pro_cnt);
			ret = -EINVAL;
		} else if (!framemgr->frame_req_cnt) {
			err("force done can be performed(request count %d)",
				framemgr->frame_req_cnt);
			ret = -EINVAL;
		} else {
			framemgr_e_barrier_irqs(framemgr, 0, flags);

			fimc_is_frame_request_head(framemgr, &frame);
			if (frame) {
				fimc_is_frame_trans_req_to_com(framemgr, frame);
				buffer_done(vctx, frame->index);
			} else {
				err("frame is NULL");
				ret = -EINVAL;
			}

			framemgr_x_barrier_irqr(framemgr, 0, flags);
		}
		break;
	case V4L2_CID_IS_COLOR_RANGE:
		if (test_bit(FIMC_IS_SUBDEV_START, &device->group_isp.leader.state)) {
			err("failed to change color range: device started already (0x%08x)",
					ctrl->value);
			ret = -EINVAL;
		} else {
			device->setfile &= ~FIMC_IS_SCP_CRANGE_MASK;

			if (ctrl->value)
				device->setfile	|=
					(FIMC_IS_CRANGE_LIMITED << FIMC_IS_SCP_CRANGE_SHIFT);
		}
		break;
	default:
		err("unsupported ioctl(%d)\n", ctrl->id);
		ret = -EINVAL;
		break;
	}

p_err:
	return ret;
}