コード例 #1
0
static int fimc_is_isp_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 *leader;

	BUG_ON(!vctx);

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

	queue = GET_SRC_QUEUE(vctx);
	device = vctx->device;
	if (!device) {
		err("device is NULL");
		ret = -EINVAL;
		goto p_err;
	}
	leader = &device->group_isp.leader;

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

p_err:
	return ret;
}
コード例 #2
0
static int fimc_is_vdo_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;

	BUG_ON(!vctx);
	BUG_ON(!vctx->video);

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

	queue = GET_SRC_QUEUE(vctx);
	video = vctx->video;

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

	return ret;
}
コード例 #3
0
static void fimc_is_isp_buffer_queue(struct vb2_buffer *vb)
{
	int ret = 0;
	u32 index;
	struct fimc_is_video_ctx *vctx = vb->vb2_queue->drv_priv;
	struct fimc_is_queue *queue;
	struct fimc_is_video *video;
	struct fimc_is_device_ischain *device;

	BUG_ON(!vctx);
	index = vb->v4l2_buf.index;

#ifdef DBG_STREAMING
	mdbgv_isp("%s(%d)\n", vctx, __func__, index);
#endif

	queue = GET_SRC_QUEUE(vctx);
	video = vctx->video;
	device = vctx->device;

	ret = fimc_is_queue_buffer_queue(queue, video->vb2, vb);
	if (ret) {
		merr("fimc_is_queue_buffer_queue is fail(%d)", vctx, ret);
		return;
	}

	ret = fimc_is_ischain_isp_buffer_queue(device, queue, index);
	if (ret) {
		merr("fimc_is_ischain_isp_buffer_queue is fail(%d)", vctx, ret);
		return;
	}
}
コード例 #4
0
static int fimc_is_isp_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;

	BUG_ON(!vctx);

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

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

	ret = fimc_is_ischain_isp_reqbufs(device, buf->count);
	if (ret) {
		merr("isp_reqbufs is fail(%d)", vctx, ret);
		goto p_err;
	}

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

p_err:
	return ret;
}
コード例 #5
0
static int fimc_is_isp_video_qbuf(struct file *file, void *priv,
	struct v4l2_buffer *buf)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_queue *queue;

	BUG_ON(!vctx);

#ifdef DBG_STREAMING
	mdbgv_isp("%s(index : %d)\n", vctx, __func__, buf->index);
#endif

	queue = GET_VCTX_QUEUE(vctx, buf);

	if (!test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		merr("stream off state, can NOT qbuf", vctx);
		ret = -EINVAL;
		goto p_err;
	}

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

p_err:
	return ret;
}
コード例 #6
0
static int fimc_is_isp_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 *device;

	BUG_ON(!vctx);

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

	queue = GET_VCTX_QUEUE(vctx, format);
	device = 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);

	fimc_is_ischain_isp_s_format(device,
		queue->framecfg.width,
		queue->framecfg.height);

	return ret;
}
コード例 #7
0
static int fimc_is_isp_video_s_input(struct file *file, void *priv,
	unsigned int input)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_device_ischain *device;

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

	mdbgv_isp("%s(input : %08X)\n", vctx, __func__, input);

	device = vctx->device;

	ret = fimc_is_ischain_isp_s_input(device, input);
	if (ret) {
		merr("fimc_is_ischain_isp_s_input is fail", vctx);
		goto p_err;
	}

	/* if there's only one group of isp, defines group id to 3a0 connected */
	if (GET_FIMC_IS_NUM_OF_SUBIP2(device, 3a0)
			|| GET_FIMC_IS_NUM_OF_SUBIP2(device, 3a1))
		goto p_err;

	ret = fimc_is_ischain_init_wrap(device, input);
	if (ret) {
		merr("fimc_is_device_init(%d) is fail", vctx, input);
		goto p_err;
	}

p_err:
	return ret;
}
コード例 #8
0
static int fimc_is_isp_video_s_input(struct file *file, void *priv,
	unsigned int input)
{
	int ret = 0;
	u32 vindex, module;
	bool reprocessing;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_core *core;
	struct fimc_is_device_ischain *device;
	struct fimc_is_device_sensor *sensor;

	BUG_ON(!vctx);

	mdbgv_isp("%s(input : %08X)\n", vctx, __func__, input);

	core = vctx->video->core;
	device = vctx->device;
	module = input & MODULE_MASK;
	vindex = (input & SSX_VINDEX_MASK) >> SSX_VINDEX_SHIFT;
	reprocessing = input & REPROCESSING_MASK;
	input = input & ~SSX_VINDEX_MASK;
	sensor = NULL;

	if (vindex == FIMC_IS_VIDEO_SS0_NUM) {
		sensor = &core->sensor[0];
		pr_info("[ISP:V:%d] <-> [SEN:V:0]\n", vctx->instance);
	} else if (vindex == FIMC_IS_VIDEO_SS1_NUM) {
		sensor = &core->sensor[1];
		pr_info("[ISP:V:%d] <-> [SEN:V:1]\n", vctx->instance);
	} else {
		sensor = NULL;
		merr("sensor is not matched", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	if (!test_bit(FIMC_IS_SENSOR_OPEN, &sensor->state)) {
		merr("sensor%d is not opened", vctx, vindex);
		ret = -EINVAL;
		goto p_err;
	}

	device->instance_sensor = sensor->instance;
	device->sensor = sensor;
	if (!reprocessing)
		sensor->ischain = device;

	ret = fimc_is_ischain_init(device, input,
		sensor->enum_sensor[module].i2c_ch,
		&sensor->enum_sensor[module].ext,
		sensor->enum_sensor[module].setfile_name);
	if (ret)
		merr("fimc_is_device_init is fail", vctx);

p_err:
	return ret;
}
コード例 #9
0
static int fimc_is_isp_buffer_finish(struct vb2_buffer *vb)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = vb->vb2_queue->drv_priv;
	struct fimc_is_device_ischain *device = vctx->device;

#ifdef DBG_STREAMING
	mdbgv_isp("%s(%d)\n", vctx, __func__, vb->v4l2_buf.index);
#endif

	ret = fimc_is_ischain_isp_buffer_finish(device, vb->v4l2_buf.index);

	return ret;
}
コード例 #10
0
static int fimc_is_isp_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_isp("%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;
}
コード例 #11
0
static int fimc_is_isp_video_querybuf(struct file *file, void *priv,
	struct v4l2_buffer *buf)
{
	int ret;
	struct fimc_is_video_ctx *vctx = file->private_data;

	mdbgv_isp("%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;
}
コード例 #12
0
static int fimc_is_isp_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_isp("%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;
}
コード例 #13
0
static int fimc_is_isp_video_set_crop(struct file *file, void *fh,
	struct v4l2_crop *crop)
{
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_device_ischain *ischain;

	BUG_ON(!vctx);

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

	ischain = vctx->device;
	BUG_ON(!ischain);

	fimc_is_ischain_isp_s_format(ischain,
		crop->c.width, crop->c.height);

	return 0;
}
コード例 #14
0
static int fimc_is_isp_start_streaming(struct vb2_queue *vbq,
	unsigned int count)
{
	int ret = 0;
	struct fimc_is_video_ctx *vctx = vbq->drv_priv;
	struct fimc_is_queue *queue;
	struct fimc_is_device_ischain *device;
	struct fimc_is_subdev *leader;

	BUG_ON(!vctx);

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

	queue = GET_SRC_QUEUE(vctx);
	device = vctx->device;
	leader = &device->group_isp.leader;

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

	return ret;
}
コード例 #15
0
static int fimc_is_isp_video_s_input(struct file *file, void *priv,
	unsigned int input)
{
	int ret = 0;
	u32 dindex;
	u32 flag;
	u32 group_id;
	u32 module, ssx_vindex, tax_vindex, rep_stream;
	struct fimc_is_video *video;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_core *core;
	struct fimc_is_device_ischain *device, *temp;
	struct fimc_is_device_sensor *sensor;

	BUG_ON(!vctx);
	BUG_ON(!vctx->video);

	mdbgv_isp("%s(input : %08X)\n", vctx, __func__, input);

	flag = 0;
	temp = NULL;
	device = NULL;
	sensor = NULL;
	video = vctx->video;
	core = container_of(video, struct fimc_is_core, video_isp);
	module = input & MODULE_MASK;
	ssx_vindex = (input & SSX_VINDEX_MASK) >> SSX_VINDEX_SHIFT;
	tax_vindex = (input & TAX_VINDEX_MASK) >> TAX_VINDEX_SHIFT;
	rep_stream = (input & REPROCESSING_MASK) >> REPROCESSING_SHIFT;

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

	/* 1. checking sensor video node to connect */
	if (ssx_vindex == FIMC_IS_VIDEO_SS0_NUM) {
		sensor = &core->sensor[0];
		info("[ISP:V:%d] <-> [SS0:V:0]\n", vctx->instance);
	} else if (ssx_vindex == FIMC_IS_VIDEO_SS1_NUM) {
		sensor = &core->sensor[1];
		info("[ISP:V:%d] <-> [SS1:V:0]\n", vctx->instance);
	} else {
		sensor = NULL;
		merr("sensor is not matched", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	if (!test_bit(FIMC_IS_SENSOR_OPEN, &sensor->state)) {
		merr("sensor%d is not opened", vctx, ssx_vindex);
		ret = -EINVAL;
		goto p_err;
	}

	/* if there's only one group of isp, defines group id to 3a0 connected */
	if (GET_FIMC_IS_NUM_OF_SUBIP(core, 3a0)
			|| GET_FIMC_IS_NUM_OF_SUBIP(core, 3a1)) {

		/* 2. checking 3ax group to connect */
		if ((tax_vindex == FIMC_IS_VIDEO_3A0C_NUM) ||
			(tax_vindex == FIMC_IS_VIDEO_3A0P_NUM)) {
			group_id = GROUP_ID_3A0;
			info("[ISP:V:%d] <-> [3A0:V:0]\n", device->instance);
		} else if ((tax_vindex == FIMC_IS_VIDEO_3A1C_NUM) ||
			(tax_vindex == FIMC_IS_VIDEO_3A1P_NUM)) {
			group_id = GROUP_ID_3A1;
			info("[ISP:V:%d] <-> [3A1:V:0]\n", device->instance);
		} else {
			group_id = GROUP_ID_INVALID;
			merr("group%d is invalid", device, group_id);
			ret = -EINVAL;
			goto p_err;
		}
	} else {
		group_id = GROUP_ID_3A0;
	}

	/* 3. checking reprocessing stream */
	if (rep_stream) {
		for (dindex = 0; dindex < FIMC_IS_MAX_NODES; ++dindex) {
			temp = &core->ischain[dindex];

			if (temp == device)
				continue;

			if (!test_bit(FIMC_IS_ISCHAIN_OPEN, &temp->state))
				continue;

			if (temp->module == module) {
				flag = REPROCESSING_FLAG | dindex;
				break;
			}

#ifdef DEBUG
			info("device.module(%08X) != ischain[%d].module(%08X)\n", module,
				dindex, temp->module);
#endif
		}

		if (dindex >= FIMC_IS_MAX_NODES) {
			merr("preview stream can NOT be found", vctx);
			ret = -EINVAL;
			goto p_err;
		}

		set_bit(FIMC_IS_ISCHAIN_REPROCESSING, &device->state);
	} else {
		/* connect to sensor if it's not a reprocessing stream */
		sensor->ischain = device;
		flag = 0;
	}

	/* 4. init variable */
	device->instance_sensor = sensor->instance;
	device->sensor = sensor;

	/* 5. init ischain */
	ret = fimc_is_ischain_init(device, module, group_id, tax_vindex, flag);
	if (ret)
		merr("fimc_is_device_init(%d, %d, %d) is fail", vctx, module, group_id, rep_stream);

p_err:
	return ret;
}