drivers/media/pci/cx25821/cx25821-video.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cx25821/cx25821-video.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cx25821/cx25821-video.c
Extension
.c
Size
21272 bytes
Lines
775
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 (!list_empty(&dmaq->active)) {
			buf = list_entry(dmaq->active.next,
					 struct cx25821_buffer, queue);

			buf->vb.vb2_buf.timestamp = ktime_get_ns();
			buf->vb.sequence = dmaq->count++;
			list_del(&buf->queue);
			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
		}
		spin_unlock(&dev->slock);
		handled++;
	}
	return handled;
}

static int cx25821_queue_setup(struct vb2_queue *q,
			   unsigned int *num_buffers, unsigned int *num_planes,
			   unsigned int sizes[], struct device *alloc_devs[])
{
	struct cx25821_channel *chan = q->drv_priv;
	unsigned size = (chan->fmt->depth * chan->width * chan->height) >> 3;

	if (*num_planes)
		return sizes[0] < size ? -EINVAL : 0;

	*num_planes = 1;
	sizes[0] = size;
	return 0;
}

static int cx25821_buffer_prepare(struct vb2_buffer *vb)
{
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct cx25821_channel *chan = vb->vb2_queue->drv_priv;
	struct cx25821_dev *dev = chan->dev;
	struct cx25821_buffer *buf =
		container_of(vbuf, struct cx25821_buffer, vb);
	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
	u32 line0_offset;
	int bpl_local = LINE_SIZE_D1;
	int ret;

	if (chan->pixel_formats == PIXEL_FRMT_411)
		buf->bpl = (chan->fmt->depth * chan->width) >> 3;
	else
		buf->bpl = (chan->fmt->depth >> 3) * chan->width;

	if (vb2_plane_size(vb, 0) < chan->height * buf->bpl)
		return -EINVAL;
	vb2_set_plane_payload(vb, 0, chan->height * buf->bpl);
	buf->vb.field = chan->field;

	if (chan->pixel_formats == PIXEL_FRMT_411) {
		bpl_local = buf->bpl;
	} else {
		bpl_local = buf->bpl;   /* Default */

		if (chan->use_cif_resolution) {
			if (dev->tvnorm & V4L2_STD_625_50)
				bpl_local = 352 << 1;
			else
				bpl_local = chan->cif_width << 1;
		}
	}

	switch (chan->field) {
	case V4L2_FIELD_TOP:
		ret = cx25821_risc_buffer(dev->pci, &buf->risc,
				sgt->sgl, 0, UNSET,
				buf->bpl, 0, chan->height);
		break;
	case V4L2_FIELD_BOTTOM:
		ret = cx25821_risc_buffer(dev->pci, &buf->risc,
				sgt->sgl, UNSET, 0,
				buf->bpl, 0, chan->height);
		break;
	case V4L2_FIELD_INTERLACED:
		/* All other formats are top field first */
		line0_offset = 0;
		dprintk(1, "top field first\n");

		ret = cx25821_risc_buffer(dev->pci, &buf->risc,
				sgt->sgl, line0_offset,
				bpl_local, bpl_local, bpl_local,
				chan->height >> 1);
		break;
	case V4L2_FIELD_SEQ_TB:
		ret = cx25821_risc_buffer(dev->pci, &buf->risc,
				sgt->sgl,
				0, buf->bpl * (chan->height >> 1),

Annotation

Implementation Notes