drivers/media/platform/rockchip/rkcif/rkcif-stream.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/rockchip/rkcif/rkcif-stream.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/rockchip/rkcif/rkcif-stream.c
Extension
.c
Size
17092 bytes
Lines
637
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (vb2_plane_size(vb, i) < size) {
			dev_err(stream->rkcif->dev,
				"user buffer too small (%ld < %ld)\n",
				vb2_plane_size(vb, i), size);
			return -EINVAL;
		}

		vb2_set_plane_payload(vb, i, size);
	}

	vbuf->field = V4L2_FIELD_NONE;

	return 0;
}

static void rkcif_stream_queue_buffer(struct vb2_buffer *vb)
{
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct rkcif_buffer *buffer = to_rkcif_buffer(vbuf);
	struct rkcif_stream *stream = vb->vb2_queue->drv_priv;

	rkcif_stream_push_buffer(stream, buffer);
}

static int rkcif_stream_start_streaming(struct vb2_queue *queue,
					unsigned int count)
{
	struct rkcif_stream *stream = queue->drv_priv;
	struct rkcif_device *rkcif = stream->rkcif;
	u64 mask;
	int ret;

	stream->frame_idx = 0;
	stream->frame_phase = 0;

	ret = video_device_pipeline_start(&stream->vdev, &stream->pipeline);
	if (ret) {
		dev_err(rkcif->dev, "failed to start pipeline %d\n", ret);
		goto err_out;
	}

	ret = pm_runtime_resume_and_get(rkcif->dev);
	if (ret < 0) {
		dev_err(rkcif->dev, "failed to get runtime pm, %d\n", ret);
		goto err_pipeline_stop;
	}

	ret = rkcif_stream_init_buffers(stream);
	if (ret)
		goto err_runtime_put;

	if (stream->start_streaming) {
		ret = stream->start_streaming(stream);
		if (ret < 0)
			goto err_runtime_put;
	}

	mask = BIT_ULL(stream->id);
	ret = v4l2_subdev_enable_streams(&stream->interface->sd,
					 RKCIF_IF_PAD_SRC, mask);
	if (ret < 0)
		goto err_stop_stream;

	return 0;

err_stop_stream:
	if (stream->stop_streaming)
		stream->stop_streaming(stream);
err_runtime_put:
	pm_runtime_put(rkcif->dev);
err_pipeline_stop:
	video_device_pipeline_stop(&stream->vdev);
err_out:
	rkcif_stream_return_all_buffers(stream, VB2_BUF_STATE_QUEUED);
	return ret;
}

static void rkcif_stream_stop_streaming(struct vb2_queue *queue)
{
	struct rkcif_stream *stream = queue->drv_priv;
	struct rkcif_device *rkcif = stream->rkcif;
	u64 mask;
	int ret;

	mask = BIT_ULL(stream->id);
	v4l2_subdev_disable_streams(&stream->interface->sd, RKCIF_IF_PAD_SRC,
				    mask);

	stream->stopping = true;
	ret = wait_event_timeout(stream->wq_stopped, !stream->stopping,

Annotation

Implementation Notes