drivers/media/usb/cx231xx/cx231xx-vbi.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/cx231xx/cx231xx-vbi.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/cx231xx/cx231xx-vbi.c
Extension
.c
Size
16362 bytes
Lines
660
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (dma_q->is_partial_line) {
			/* Handle the case where we were working on a partial
			   line */
			sav_eav = dma_q->last_sav;
		} else {
			/* Check for a SAV/EAV overlapping the
			   buffer boundary */

			sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer,
							  dma_q->partial_buf,
							  &bytes_parsed);
		}

		sav_eav &= 0xF0;
		/* Get the first line if we have some portion of an SAV/EAV from
		   the last buffer or a partial line */
		if (sav_eav) {
			bytes_parsed += cx231xx_get_vbi_line(dev, dma_q,
				sav_eav,		       /* SAV/EAV */
				p_buffer + bytes_parsed,       /* p_buffer */
				buffer_size - bytes_parsed);   /* buffer size */
		}

		/* Now parse data that is completely in this buffer */
		dma_q->is_partial_line = 0;

		while (bytes_parsed < buffer_size) {
			u32 bytes_used = 0;

			sav_eav = cx231xx_find_next_SAV_EAV(
				p_buffer + bytes_parsed,	/* p_buffer */
				buffer_size - bytes_parsed, /* buffer size */
				&bytes_used);	/* bytes used to get SAV/EAV */

			bytes_parsed += bytes_used;

			sav_eav &= 0xF0;
			if (sav_eav && (bytes_parsed < buffer_size)) {
				bytes_parsed += cx231xx_get_vbi_line(dev,
					dma_q, sav_eav,	/* SAV/EAV */
					p_buffer+bytes_parsed, /* p_buffer */
					buffer_size-bytes_parsed);/*buf size*/
			}
		}

		/* Save the last four bytes of the buffer so we can
		check the buffer boundary condition next time */
		memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
		bytes_parsed = 0;
	}

	return rc;
}

/* ------------------------------------------------------------------
	Vbi buf operations
   ------------------------------------------------------------------*/

static int vbi_queue_setup(struct vb2_queue *vq,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], struct device *alloc_devs[])
{
	struct cx231xx *dev = vb2_get_drv_priv(vq);
	u32 height = 0;

	height = ((dev->norm & V4L2_STD_625_50) ?
		  PAL_VBI_LINES : NTSC_VBI_LINES);

	*nplanes = 1;
	sizes[0] = (dev->width * height * 2 * 2);
	return 0;
}

/* This is called *without* dev->slock held; please keep it that way */
static int vbi_buf_prepare(struct vb2_buffer *vb)
{
	struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
	u32 height = 0;
	u32 size;

	height = ((dev->norm & V4L2_STD_625_50) ?
		  PAL_VBI_LINES : NTSC_VBI_LINES);
	size = ((dev->width << 1) * height * 2);

	if (vb2_plane_size(vb, 0) < size)
		return -EINVAL;
	vb2_set_plane_payload(vb, 0, size);
	return 0;
}

Annotation

Implementation Notes