drivers/media/platform/samsung/s3c-camif/camif-capture.c
Source file repositories/reference/linux-study-clean/drivers/media/platform/samsung/s3c-camif/camif-capture.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/platform/samsung/s3c-camif/camif-capture.c- Extension
.c- Size
- 43072 bytes
- Lines
- 1650
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bug.hlinux/clk.hlinux/device.hlinux/errno.hlinux/i2c.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/list.hlinux/module.hlinux/platform_device.hlinux/pm_runtime.hlinux/ratelimit.hlinux/slab.hlinux/types.hlinux/videodev2.hmedia/media-device.hmedia/v4l2-ctrls.hmedia/v4l2-event.hmedia/v4l2-ioctl.hmedia/videobuf2-v4l2.hmedia/videobuf2-dma-contig.hcamif-core.hcamif-regs.h
Detected Declarations
function camif_cfg_video_pathfunction camif_prepare_dma_offsetfunction s3c_camif_hw_initfunction s3c_camif_hw_vp_initfunction sensor_set_powerfunction sensor_set_streamingfunction pipelinefunction s3c_vp_activefunction camif_is_streamingfunction camif_stop_capturefunction camif_prepare_addrfunction s3c_camif_irq_handlerfunction start_streamingfunction stop_streamingfunction queue_setupfunction buffer_preparefunction buffer_queuefunction s3c_camif_openfunction s3c_camif_closefunction s3c_camif_pollfunction s3c_camif_mmapfunction s3c_camif_vidioc_querycapfunction s3c_camif_vidioc_enum_inputfunction s3c_camif_vidioc_s_inputfunction s3c_camif_vidioc_g_inputfunction s3c_camif_vidioc_enum_fmtfunction s3c_camif_vidioc_g_fmtfunction __camif_video_try_formatfunction s3c_camif_vidioc_try_fmtfunction s3c_camif_vidioc_s_fmtfunction camif_pipeline_validatefunction s3c_camif_streamonfunction s3c_camif_streamofffunction s3c_camif_reqbufsfunction s3c_camif_querybuffunction s3c_camif_qbuffunction s3c_camif_dqbuffunction s3c_camif_create_bufsfunction s3c_camif_prepare_buffunction s3c_camif_g_selectionfunction __camif_try_composefunction s3c_camif_s_selectionfunction s3c_camif_video_s_ctrlfunction s3c_camif_register_video_nodefunction s3c_camif_unregister_video_nodefunction s3c_camif_subdev_enum_mbus_codefunction s3c_camif_subdev_get_fmtfunction __camif_subdev_try_format
Annotated Snippet
if (vp->state & ST_VP_OFF) {
/* Last IRQ */
vp->state &= ~(ST_VP_OFF | ST_VP_ABORTING |
ST_VP_LASTIRQ);
wake_up(&vp->irq_queue);
goto unlock;
} else if (vp->state & ST_VP_LASTIRQ) {
camif_hw_disable_capture(vp);
camif_hw_enable_scaler(vp, false);
camif_hw_set_lastirq(vp, false);
vp->state |= ST_VP_OFF;
} else {
/* Disable capture, enable last IRQ */
camif_hw_set_lastirq(vp, true);
vp->state |= ST_VP_LASTIRQ;
}
}
if (!list_empty(&vp->pending_buf_q) && (vp->state & ST_VP_RUNNING) &&
!list_empty(&vp->active_buf_q)) {
unsigned int index;
struct camif_buffer *vbuf;
/*
* Get previous DMA write buffer index:
* 0 => DMA buffer 0, 2;
* 1 => DMA buffer 1, 3.
*/
index = (CISTATUS_FRAMECNT(status) + 2) & 1;
vbuf = camif_active_queue_peek(vp, index);
if (!WARN_ON(vbuf == NULL)) {
/* Dequeue a filled buffer */
vbuf->vb.vb2_buf.timestamp = ktime_get_ns();
vbuf->vb.sequence = vp->frame_sequence++;
vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
/* Set up an empty buffer at the DMA engine */
vbuf = camif_pending_queue_pop(vp);
vbuf->index = index;
camif_hw_set_output_addr(vp, &vbuf->paddr, index);
camif_hw_set_output_addr(vp, &vbuf->paddr, index + 2);
/* Scheduled in H/W, add to the queue */
camif_active_queue_add(vp, vbuf);
}
} else if (!(vp->state & ST_VP_ABORTING) &&
(vp->state & ST_VP_PENDING)) {
vp->state |= ST_VP_RUNNING;
}
if (vp->state & ST_VP_CONFIG) {
camif_prepare_dma_offset(vp);
camif_hw_set_camera_crop(camif);
camif_hw_set_scaler(vp);
camif_hw_set_flip(vp);
camif_hw_set_test_pattern(camif, camif->test_pattern);
if (camif->variant->has_img_effect)
camif_hw_set_effect(camif, camif->colorfx,
camif->colorfx_cr, camif->colorfx_cb);
vp->state &= ~ST_VP_CONFIG;
}
unlock:
spin_unlock(&camif->slock);
return IRQ_HANDLED;
}
static int start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct camif_vp *vp = vb2_get_drv_priv(vq);
struct camif_dev *camif = vp->camif;
unsigned long flags;
int ret;
/*
* We assume the codec capture path is always activated
* first, before the preview path starts streaming.
* This is required to avoid internal FIFO overflow and
* a need for CAMIF software reset.
*/
spin_lock_irqsave(&camif->slock, flags);
if (camif->stream_count == 0) {
camif_hw_reset(camif);
ret = s3c_camif_hw_init(camif, vp);
} else {
ret = s3c_camif_hw_vp_init(camif, vp);
}
spin_unlock_irqrestore(&camif->slock, flags);
if (ret < 0) {
Annotation
- Immediate include surface: `linux/bug.h`, `linux/clk.h`, `linux/device.h`, `linux/errno.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/io.h`, `linux/kernel.h`.
- Detected declarations: `function camif_cfg_video_path`, `function camif_prepare_dma_offset`, `function s3c_camif_hw_init`, `function s3c_camif_hw_vp_init`, `function sensor_set_power`, `function sensor_set_streaming`, `function pipeline`, `function s3c_vp_active`, `function camif_is_streaming`, `function camif_stop_capture`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.