Esempio n. 1
0
static int start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct fimc_ctx *ctx = q->drv_priv;
	struct fimc_dev *fimc = ctx->fimc_dev;
	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
	int min_bufs;
	int ret;

	fimc_hw_reset(fimc);
	vid_cap->frame_count = 0;

	ret = fimc_init_capture(fimc);
	if (ret)
		goto error;

	set_bit(ST_CAPT_PEND, &fimc->state);

	min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;

	if (vid_cap->active_buf_cnt >= min_bufs &&
	    !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
		fimc_activate_capture(ctx);

		if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
			fimc_pipeline_s_stream(fimc, 1);
	}

	return 0;
error:
	fimc_capture_state_cleanup(fimc, false);
	return ret;
}
Esempio n. 2
0
static int start_streaming(struct vb2_queue *q)
{
    struct fimc_ctx *ctx = q->drv_priv;
    struct fimc_dev *fimc = ctx->fimc_dev;
    struct s5p_fimc_isp_info *isp_info;
    int ret;

    fimc_hw_reset(fimc);

    ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
    if (ret && ret != -ENOIOCTLCMD)
        return ret;

    ret = fimc_prepare_config(ctx, ctx->state);
    if (ret)
        return ret;

    isp_info = &fimc->pdata->isp_info[fimc->vid_cap.input_index];
    fimc_hw_set_camera_type(fimc, isp_info);
    fimc_hw_set_camera_source(fimc, isp_info);
    fimc_hw_set_camera_offset(fimc, &ctx->s_frame);

    if (ctx->state & FIMC_PARAMS) {
        ret = fimc_set_scaler_info(ctx);
        if (ret) {
            err("Scaler setup error");
            return ret;
        }
        fimc_hw_set_input_path(ctx);
        fimc_hw_set_prescaler(ctx);
        fimc_hw_set_mainscaler(ctx);
        fimc_hw_set_target_format(ctx);
        fimc_hw_set_rotation(ctx);
        fimc_hw_set_effect(ctx);
    }

    fimc_hw_set_output_path(ctx);
    fimc_hw_set_out_dma(ctx);

    INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
    INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
    fimc->vid_cap.active_buf_cnt = 0;
    fimc->vid_cap.frame_count = 0;
    fimc->vid_cap.buf_index = 0;

    set_bit(ST_CAPT_PEND, &fimc->state);

    return 0;
}
Esempio n. 3
0
/*
 * Reinitialize the driver so it is ready to start the streaming again.
 * Set fimc->state to indicate stream off and the hardware shut down state.
 * If not suspending (@suspend is false), return any buffers to videobuf2.
 * Otherwise put any owned buffers onto the pending buffers queue, so they
 * can be re-spun when the device is being resumed. Also perform FIMC
 * software reset and disable streaming on the whole pipeline if required.
 */
static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
{
	struct fimc_vid_cap *cap = &fimc->vid_cap;
	struct fimc_vid_buffer *buf;
	unsigned long flags;
	bool streaming;

	spin_lock_irqsave(&fimc->slock, flags);
	streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);

	fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
			 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
	if (suspend)
		fimc->state |= (1 << ST_CAPT_SUSPENDED);
	else
		fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);

	/* Release unused buffers */
	while (!suspend && !list_empty(&cap->pending_buf_q)) {
		buf = fimc_pending_queue_pop(cap);
		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
	}
	/* If suspending put unused buffers onto pending queue */
	while (!list_empty(&cap->active_buf_q)) {
		buf = fimc_active_queue_pop(cap);
		if (suspend)
			fimc_pending_queue_add(cap, buf);
		else
			vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
	}

	fimc_hw_reset(fimc);
	cap->buf_index = 0;

	spin_unlock_irqrestore(&fimc->slock, flags);

	if (streaming)
		return fimc_pipeline_call(fimc, set_stream,
					  &fimc->pipeline, 0);
	else
		return 0;
}