drivers/media/common/saa7146/saa7146_video.c
Source file repositories/reference/linux-study-clean/drivers/media/common/saa7146/saa7146_video.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/common/saa7146/saa7146_video.c- Extension
.c- Size
- 19559 bytes
- Lines
- 724
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
media/drv-intf/saa7146_vv.hmedia/v4l2-event.hmedia/v4l2-ctrls.hlinux/module.hlinux/kernel.h
Detected Declarations
function saa7146_format_by_fourccfunction saa7146_pgtable_buildfunction video_beginfunction video_endfunction vidioc_querycapfunction vidioc_enum_fmt_vid_capfunction saa7146_s_ctrlfunction vidioc_g_parmfunction vidioc_g_fmt_vid_capfunction vidioc_g_fmt_vbi_capfunction vidioc_try_fmt_vid_capfunction vidioc_s_fmt_vid_capfunction vidioc_g_stdfunction vidioc_s_stdfunction buffer_activatefunction release_all_pagetablesfunction queue_setupfunction buf_queuefunction buf_initfunction buf_preparefunction buf_cleanupfunction return_buffersfunction start_streamingfunction stop_streamingfunction video_initfunction video_irq_done
Annotated Snippet
if (formats[i].pixelformat == fourcc) {
return formats+i;
}
}
DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
return NULL;
}
/********************************************************************************/
/* common pagetable functions */
static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
{
struct saa7146_vv *vv = dev->vv_data;
struct pci_dev *pci = dev->pci;
struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
struct scatterlist *list = sgt->sgl;
int length = sgt->nents;
struct v4l2_pix_format *pix = &vv->video_fmt;
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat);
DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length);
if( 0 != IS_PLANAR(sfmt->trans)) {
struct saa7146_pgtable *pt1 = &buf->pt[0];
struct saa7146_pgtable *pt2 = &buf->pt[1];
struct saa7146_pgtable *pt3 = &buf->pt[2];
struct sg_dma_page_iter dma_iter;
__le32 *ptr1, *ptr2, *ptr3;
__le32 fill;
int size = pix->width * pix->height;
int i, m1, m2, m3, o1, o2;
switch( sfmt->depth ) {
case 12: {
/* create some offsets inside the page table */
m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1;
m2 = ((size + (size / 4) + PAGE_SIZE) / PAGE_SIZE) - 1;
m3 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1;
o1 = size % PAGE_SIZE;
o2 = (size + (size / 4)) % PAGE_SIZE;
DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
size, m1, m2, m3, o1, o2);
break;
}
case 16: {
/* create some offsets inside the page table */
m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1;
m2 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1;
m3 = ((2 * size + PAGE_SIZE) / PAGE_SIZE) - 1;
o1 = size % PAGE_SIZE;
o2 = (size + (size / 2)) % PAGE_SIZE;
DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
size, m1, m2, m3, o1, o2);
break;
}
default: {
return -1;
}
}
ptr1 = pt1->cpu;
ptr2 = pt2->cpu;
ptr3 = pt3->cpu;
for_each_sg_dma_page(list, &dma_iter, length, 0)
*ptr1++ = cpu_to_le32(sg_page_iter_dma_address(&dma_iter) - list->offset);
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
pt1->offset = sgt->sgl->offset;
pt2->offset = pt1->offset + o1;
pt3->offset = pt1->offset + o2;
/* create video-dma2 page table */
ptr1 = pt1->cpu;
for (i = m1; i <= m2; i++, ptr2++)
*ptr2 = ptr1[i];
fill = *(ptr2 - 1);
for (; i < 1024; i++, ptr2++)
*ptr2 = fill;
/* create video-dma3 page table */
ptr1 = pt1->cpu;
for (i = m2; i <= m3; i++, ptr3++)
*ptr3 = ptr1[i];
fill = *(ptr3 - 1);
for (; i < 1024; i++, ptr3++)
*ptr3 = fill;
Annotation
- Immediate include surface: `media/drv-intf/saa7146_vv.h`, `media/v4l2-event.h`, `media/v4l2-ctrls.h`, `linux/module.h`, `linux/kernel.h`.
- Detected declarations: `function saa7146_format_by_fourcc`, `function saa7146_pgtable_build`, `function video_begin`, `function video_end`, `function vidioc_querycap`, `function vidioc_enum_fmt_vid_cap`, `function saa7146_s_ctrl`, `function vidioc_g_parm`, `function vidioc_g_fmt_vid_cap`, `function vidioc_g_fmt_vbi_cap`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.