drivers/media/pci/ivtv/ivtv-irq.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/ivtv/ivtv-irq.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/ivtv/ivtv-irq.c
Extension
.c
Size
32852 bytes
Lines
1079
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 (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
			memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
		}
		else {
			memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
		}
		i++;
		if (i == s->sg_processing_size)
			break;
	}
	write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
}

void ivtv_irq_work_handler(struct kthread_work *work)
{
	struct ivtv *itv = container_of(work, struct ivtv, irq_work);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
		ivtv_pio_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
		ivtv_vbi_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
		ivtv_yuv_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags))
		ivtv_pcm_work_handler(itv);
}

/* Determine the required DMA size, setup enough buffers in the predma queue and
   actually copy the data from the card to the buffers in case a PIO transfer is
   required for this stream.
 */
static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
{
	struct ivtv *itv = s->itv;
	struct ivtv_buffer *buf;
	u32 bytes_needed = 0;
	u32 offset, size;
	u32 UVoffset = 0, UVsize = 0;
	int skip_bufs = s->q_predma.buffers;
	int idx = s->sg_pending_size;
	int rc;

	/* sanity checks */
	if (s->vdev.v4l2_dev == NULL) {
		IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
		return -1;
	}
	if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
		IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
		return -1;
	}

	/* determine offset, size and PTS for the various streams */
	switch (s->type) {
		case IVTV_ENC_STREAM_TYPE_MPG:
			offset = data[1];
			size = data[2];
			s->pending_pts = 0;
			break;

		case IVTV_ENC_STREAM_TYPE_YUV:
			offset = data[1];
			size = data[2];
			UVoffset = data[3];
			UVsize = data[4];
			s->pending_pts = ((u64) data[5] << 32) | data[6];
			break;

		case IVTV_ENC_STREAM_TYPE_PCM:
			offset = data[1] + 12;
			size = data[2] - 12;
			s->pending_pts = read_dec(offset - 8) |
				((u64)(read_dec(offset - 12)) << 32);
			if (itv->has_cx23415)
				offset += IVTV_DECODER_OFFSET;
			break;

		case IVTV_ENC_STREAM_TYPE_VBI:
			size = itv->vbi.enc_size * itv->vbi.fpi;
			offset = read_enc(itv->vbi.enc_start - 4) + 12;
			if (offset == 12) {
				IVTV_DEBUG_INFO("VBI offset == 0\n");
				return -1;
			}
			s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
			break;

Annotation

Implementation Notes