drivers/media/pci/tw68/tw68-risc.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/tw68/tw68-risc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/tw68/tw68-risc.c
Extension
.c
Size
6606 bytes
Lines
224
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

while (offset && offset >= sg_dma_len(sg)) {
			offset -= sg_dma_len(sg);
			sg = sg_next(sg);
		}
		if (bpl <= sg_dma_len(sg) - offset) {
			/* fits into current chunk */
			*(rp++) = cpu_to_le32(RISC_LINESTART |
					      /* (offset<<12) |*/  bpl);
			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
			offset += bpl;
		} else {
			/*
			 * scanline needs to be split.  Put the start in
			 * whatever memory remains using RISC_LINESTART,
			 * then the remainder into following addresses
			 * given by the scatter-gather list.
			 */
			todo = bpl;	/* one full line to be done */
			/* first fragment */
			done = (sg_dma_len(sg) - offset);
			*(rp++) = cpu_to_le32(RISC_LINESTART |
						(7 << 24) |
						done);
			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
			todo -= done;
			sg = sg_next(sg);
			/* succeeding fragments have no offset */
			while (todo > sg_dma_len(sg)) {
				*(rp++) = cpu_to_le32(RISC_INLINE |
						(done << 12) |
						sg_dma_len(sg));
				*(rp++) = cpu_to_le32(sg_dma_address(sg));
				todo -= sg_dma_len(sg);
				sg = sg_next(sg);
				done += sg_dma_len(sg);
			}
			if (todo) {
				/* final chunk - offset 0, count 'todo' */
				*(rp++) = cpu_to_le32(RISC_INLINE |
							(done << 12) |
							todo);
				*(rp++) = cpu_to_le32(sg_dma_address(sg));
			}
			offset = todo;
		}
		offset += padding;
	}

	return rp;
}

/**
 * tw68_risc_buffer
 *
 *	This routine is called by tw68-video.  It allocates
 *	memory for the dma controller "program" and then fills in that
 *	memory with the appropriate "instructions".
 *
 *	@pci:		structure with info about the pci
 *			slot which our device is in.
 *	@buf:		structure with info about the memory
 *			used for our controller program.
 *	@sglist:	scatter-gather list entry
 *	@top_offset:	offset within the risc program area for the
 *			first odd frame line
 *	@bottom_offset:	offset within the risc program area for the
 *			first even frame line
 *	@bpl:		number of data bytes per scan line
 *	@padding:	number of extra bytes to add at end of line
 *	@lines:		number of scan lines
 */
int tw68_risc_buffer(struct pci_dev *pci,
			struct tw68_buf *buf,
			struct scatterlist *sglist,
			unsigned int top_offset,
			unsigned int bottom_offset,
			unsigned int bpl,
			unsigned int padding,
			unsigned int lines)
{
	u32 instructions, fields;
	__le32 *rp;

	fields = 0;
	if (UNSET != top_offset)
		fields++;
	if (UNSET != bottom_offset)
		fields++;
	/*
	 * estimate risc mem: worst case is one write per page border +

Annotation

Implementation Notes