コード例 #1
0
static void buffer_queue(struct vb2_buffer *vb)
{
	struct flite_buffer *buf
		= container_of(vb, struct flite_buffer, vb);
	struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
	unsigned long flags;

	spin_lock_irqsave(&fimc->slock, flags);
	buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);

	if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
	    !test_bit(ST_FLITE_STREAM, &fimc->state) &&
	    list_empty(&fimc->active_buf_q)) {
		flite_hw_set_output_addr(fimc, buf->paddr);
		fimc_lite_active_queue_add(fimc, buf);
	} else {
		fimc_lite_pending_queue_add(fimc, buf);
	}

	if (vb2_is_streaming(&fimc->vb_queue) &&
	    !list_empty(&fimc->pending_buf_q) &&
	    !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
		flite_hw_capture_start(fimc);
		spin_unlock_irqrestore(&fimc->slock, flags);

		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
			fimc_pipeline_call(fimc, set_stream,
					   &fimc->pipeline, 1);
		return;
	}
	spin_unlock_irqrestore(&fimc->slock, flags);
}
コード例 #2
0
ファイル: fimc-lite.c プロジェクト: 19Dan01/linux
static int start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct fimc_lite *fimc = q->drv_priv;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&fimc->slock, flags);

	fimc->buf_index = 0;
	fimc->frame_count = 0;

	spin_unlock_irqrestore(&fimc->slock, flags);

	ret = fimc_lite_hw_init(fimc, false);
	if (ret) {
		fimc_lite_reinit(fimc, false);
		return ret;
	}

	set_bit(ST_FLITE_PENDING, &fimc->state);

	if (!list_empty(&fimc->active_buf_q) &&
	    !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
		flite_hw_capture_start(fimc);

		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
			fimc_pipeline_call(&fimc->ve, set_stream, 1);
	}
	if (debug > 0)
		flite_hw_dump_regs(fimc, __func__);

	return 0;
}
コード例 #3
0
static int start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct fimc_lite *fimc = q->drv_priv;
	int ret;

	fimc->frame_count = 0;

	ret = fimc_lite_hw_init(fimc);
	if (ret) {
		fimc_lite_reinit(fimc, false);
		return ret;
	}

	set_bit(ST_FLITE_PENDING, &fimc->state);

	if (!list_empty(&fimc->active_buf_q) &&
	    !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
		flite_hw_capture_start(fimc);

		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
			fimc_pipeline_call(fimc, set_stream,
					   &fimc->pipeline, 1);
	}
	if (debug > 0)
		flite_hw_dump_regs(fimc, __func__);

	return 0;
}
コード例 #4
0
ファイル: fimc-lite.c プロジェクト: 19Dan01/linux
static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
{
	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
	unsigned long flags;
	int ret;

	/*
	 * Find sensor subdev linked to FIMC-LITE directly or through
	 * MIPI-CSIS. This is required for configuration where FIMC-LITE
	 * is used as a subdev only and feeds data internally to FIMC-IS.
	 * The pipeline links are protected through entity.stream_count
	 * so there is no need to take the media graph mutex here.
	 */
	fimc->sensor = fimc_find_remote_sensor(&sd->entity);

	if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
		return -ENOIOCTLCMD;

	mutex_lock(&fimc->lock);
	if (on) {
		flite_hw_reset(fimc);
		ret = fimc_lite_hw_init(fimc, true);
		if (!ret) {
			spin_lock_irqsave(&fimc->slock, flags);
			flite_hw_capture_start(fimc);
			spin_unlock_irqrestore(&fimc->slock, flags);
		}
	} else {
		set_bit(ST_FLITE_OFF, &fimc->state);

		spin_lock_irqsave(&fimc->slock, flags);
		flite_hw_capture_stop(fimc);
		spin_unlock_irqrestore(&fimc->slock, flags);

		ret = wait_event_timeout(fimc->irq_queue,
				!test_bit(ST_FLITE_OFF, &fimc->state),
				msecs_to_jiffies(200));
		if (ret == 0)
			v4l2_err(sd, "s_stream(0) timeout\n");
		clear_bit(ST_FLITE_RUN, &fimc->state);
	}

	mutex_unlock(&fimc->lock);
	return ret;
}