drivers/media/pci/cx23885/cx23885-video.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/cx23885/cx23885-video.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/cx23885/cx23885-video.c- Extension
.c- Size
- 38902 bytes
- Lines
- 1425
- 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
cx23885.hcx23885-video.hlinux/init.hlinux/list.hlinux/module.hlinux/moduleparam.hlinux/kmod.hlinux/kernel.hlinux/slab.hlinux/interrupt.hlinux/delay.hlinux/kthread.hasm/div64.hmedia/v4l2-common.hmedia/v4l2-ioctl.hmedia/v4l2-event.hcx23885-ioctl.hxc2028.hmedia/drv-intf/cx25840.h
Detected Declarations
function cx23885_video_wakeupfunction cx23885_set_tvnormfunction cx23885_flatiron_writefunction cx23885_flatiron_readfunction cx23885_flatiron_dumpfunction cx23885_flatiron_muxfunction cx23885_video_muxfunction cx23885_audio_muxfunction cx23885_start_video_dmafunction queue_setupfunction buffer_preparefunction buffer_finishfunction buffer_queuefunction cx23885_start_streamingfunction cx23885_stop_streamingfunction vidioc_g_fmt_vid_capfunction vidioc_try_fmt_vid_capfunction vidioc_s_fmt_vid_capfunction vidioc_querycapfunction vidioc_enum_fmt_vid_capfunction vidioc_g_pixelaspectfunction vidioc_g_selectionfunction vidioc_g_stdfunction vidioc_s_stdfunction cx23885_enum_inputfunction vidioc_enum_inputfunction cx23885_get_inputfunction vidioc_g_inputfunction cx23885_set_inputfunction vidioc_s_inputfunction vidioc_log_statusfunction cx23885_query_audinputfunction vidioc_enum_audinputfunction vidioc_g_audinputfunction vidioc_s_audinputfunction vidioc_g_tunerfunction vidioc_s_tunerfunction vidioc_g_frequencyfunction cx23885_set_freqfunction cx23885_set_freq_via_opsfunction cx23885_set_frequencyfunction vidioc_s_frequencyfunction cx23885_video_irqfunction cx23885_video_unregisterfunction cx23885_video_register
Annotated Snippet
if (field_tff) {
/* cx25840 transmits NTSC bottom field first */
dprintk(1, "%s() Creating TFF/NTSC risc\n",
__func__);
line0_offset = buf->bpl;
line1_offset = 0;
} else {
/* All other formats are top field first */
dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
__func__);
line0_offset = 0;
line1_offset = buf->bpl;
}
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
sgt->sgl, line0_offset,
line1_offset,
buf->bpl, buf->bpl,
dev->height >> 1);
break;
case V4L2_FIELD_SEQ_TB:
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
sgt->sgl,
0, buf->bpl * (dev->height >> 1),
buf->bpl, 0,
dev->height >> 1);
break;
case V4L2_FIELD_SEQ_BT:
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
sgt->sgl,
buf->bpl * (dev->height >> 1), 0,
buf->bpl, 0,
dev->height >> 1);
break;
default:
return -EINVAL; /* should not happen */
}
dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
buf, buf->vb.vb2_buf.index,
dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc,
(unsigned long)buf->risc.dma);
return ret;
}
static void buffer_finish(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
}
/*
* The risc program for each buffer works as follows: it starts with a simple
* 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
* buffer follows and at the end we have a JUMP back to the start + 12 (skipping
* the initial JUMP).
*
* This is the risc program of the first buffer to be queued if the active list
* is empty and it just keeps DMAing this buffer without generating any
* interrupts.
*
* If a new buffer is added then the initial JUMP in the code for that buffer
* will generate an interrupt which signals that the previous buffer has been
* DMAed successfully and that it can be returned to userspace.
*
* It also sets the final jump of the previous buffer to the start of the new
* buffer, thus chaining the new buffer into the DMA chain. This is a single
* atomic u32 write, so there is no race condition.
*
* The end-result of all this that you only get an interrupt when a buffer
* is ready, so the control flow is very easy.
*/
static void buffer_queue(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
struct cx23885_buffer *prev;
struct cx23885_dmaqueue *q = &dev->vidq;
unsigned long flags;
/* add jump to start */
buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
spin_lock_irqsave(&dev->slock, flags);
Annotation
- Immediate include surface: `cx23885.h`, `cx23885-video.h`, `linux/init.h`, `linux/list.h`, `linux/module.h`, `linux/moduleparam.h`, `linux/kmod.h`, `linux/kernel.h`.
- Detected declarations: `function cx23885_video_wakeup`, `function cx23885_set_tvnorm`, `function cx23885_flatiron_write`, `function cx23885_flatiron_read`, `function cx23885_flatiron_dump`, `function cx23885_flatiron_mux`, `function cx23885_video_mux`, `function cx23885_audio_mux`, `function cx23885_start_video_dma`, `function queue_setup`.
- 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.