drivers/media/pci/tw5864/tw5864-video.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/tw5864/tw5864-video.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/tw5864/tw5864-video.c- Extension
.c- Size
- 47605 bytes
- Lines
- 1514
- 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/module.hlinux/workqueue.hmedia/v4l2-common.hmedia/v4l2-event.hmedia/videobuf2-dma-contig.htw5864.htw5864-reg.h
Detected Declarations
function tw5864_queue_setupfunction tw5864_buf_queuefunction tw5864_input_std_getfunction tw5864_enable_inputfunction tw5864_request_encoded_framefunction tw5864_disable_inputfunction tw5864_start_streamingfunction tw5864_stop_streamingfunction tw5864_s_ctrlfunction tw5864_fmt_vid_capfunction tw5864_enum_inputfunction tw5864_g_inputfunction tw5864_s_inputfunction tw5864_querycapfunction tw5864_querystdfunction tw5864_g_stdfunction tw5864_s_stdfunction tw5864_enum_fmt_vid_capfunction tw5864_subscribe_eventfunction tw5864_frame_interval_setfunction tw5864_frameinterval_getfunction tw5864_enum_framesizesfunction tw5864_enum_frameintervalsfunction tw5864_g_parmfunction tw5864_s_parmfunction tw5864_g_regfunction tw5864_s_regfunction tw5864_video_initfunction tw5864_video_input_initfunction tw5864_video_input_finifunction tw5864_video_finifunction tw5864_prepare_frame_headersfunction tw5864_md_metric_from_mvdfunction tw5864_is_motion_triggeredfunction tw5864_handle_frame_workfunction tw5864_vlc_checksumfunction tw5864_handle_framefunction tw5864_is_motion_triggeredfunction tw5864_get_v4l2_stdfunction tw5864_from_v4l2_stdfunction tw5864_encoder_tables_upload
Annotated Snippet
if (!frame->vlc.addr) {
dev_err(&dev->pci->dev, "dma alloc fail\n");
ret = -ENOMEM;
goto free_dma;
}
frame->mv.addr = dma_alloc_coherent(&dev->pci->dev,
H264_MV_BUF_SIZE,
&frame->mv.dma_addr,
GFP_KERNEL | GFP_DMA32);
if (!frame->mv.addr) {
dev_err(&dev->pci->dev, "dma alloc fail\n");
ret = -ENOMEM;
dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE,
frame->vlc.addr, frame->vlc.dma_addr);
goto free_dma;
}
last_dma_allocated = i;
}
tw5864_encoder_tables_upload(dev);
/* Picture is distorted without this block */
/* use falling edge to sample 54M to 108M */
tw_indir_writeb(TW5864_INDIR_VD_108_POL, TW5864_INDIR_VD_108_POL_BOTH);
tw_indir_writeb(TW5864_INDIR_CLK0_SEL, 0x00);
tw_indir_writeb(TW5864_INDIR_DDRA_DLL_DQS_SEL0, 0x02);
tw_indir_writeb(TW5864_INDIR_DDRA_DLL_DQS_SEL1, 0x02);
tw_indir_writeb(TW5864_INDIR_DDRA_DLL_CLK90_SEL, 0x02);
tw_indir_writeb(TW5864_INDIR_DDRB_DLL_DQS_SEL0, 0x02);
tw_indir_writeb(TW5864_INDIR_DDRB_DLL_DQS_SEL1, 0x02);
tw_indir_writeb(TW5864_INDIR_DDRB_DLL_CLK90_SEL, 0x02);
/* video input reset */
tw_indir_writeb(TW5864_INDIR_RESET, 0);
tw_indir_writeb(TW5864_INDIR_RESET, TW5864_INDIR_RESET_VD |
TW5864_INDIR_RESET_DLL | TW5864_INDIR_RESET_MUX_CORE);
msleep(20);
/*
* Select Part A mode for all channels.
* tw_setl instead of tw_clearl for Part B mode.
*
* I guess "Part B" is primarily for downscaled version of same channel
* which goes in Part A of same bus
*/
tw_writel(TW5864_FULL_HALF_MODE_SEL, 0);
tw_indir_writeb(TW5864_INDIR_PV_VD_CK_POL,
TW5864_INDIR_PV_VD_CK_POL_VD(0) |
TW5864_INDIR_PV_VD_CK_POL_VD(1) |
TW5864_INDIR_PV_VD_CK_POL_VD(2) |
TW5864_INDIR_PV_VD_CK_POL_VD(3));
spin_lock_irqsave(&dev->slock, flags);
dev->encoder_busy = 0;
dev->h264_buf_r_index = 0;
dev->h264_buf_w_index = 0;
tw_writel(TW5864_VLC_STREAM_BASE_ADDR,
dev->h264_buf[dev->h264_buf_w_index].vlc.dma_addr);
tw_writel(TW5864_MV_STREAM_BASE_ADDR,
dev->h264_buf[dev->h264_buf_w_index].mv.dma_addr);
spin_unlock_irqrestore(&dev->slock, flags);
tw_writel(TW5864_SEN_EN_CH, 0x000f);
tw_writel(TW5864_H264EN_CH_EN, 0x000f);
tw_writel(TW5864_H264EN_BUS0_MAP, 0x00000000);
tw_writel(TW5864_H264EN_BUS1_MAP, 0x00001111);
tw_writel(TW5864_H264EN_BUS2_MAP, 0x00002222);
tw_writel(TW5864_H264EN_BUS3_MAP, 0x00003333);
/*
* Quote from Intersil (manufacturer):
* 0x0038 is managed by HW, and by default it won't pass the pointer set
* at 0x0010. So if you don't do encoding, 0x0038 should stay at '3'
* (with 4 frames in buffer). If you encode one frame and then move
* 0x0010 to '1' for example, HW will take one more frame and set it to
* buffer #0, and then you should see 0x0038 is set to '0'. There is
* only one HW encoder engine, so 4 channels cannot get encoded
* simultaneously. But each channel does have its own buffer (for
* original frames and reconstructed frames). So there is no problem to
* manage encoding for 4 channels at same time and no need to force
* I-frames in switching channels.
* End of quote.
*
* If we set 0x0010 (TW5864_ENC_BUF_PTR_REC1) to 0 (for any channel), we
* have no "rolling" (until we change this value).
* If we set 0x0010 (TW5864_ENC_BUF_PTR_REC1) to 0x3, it starts to roll
* continuously together with 0x0038.
Annotation
- Immediate include surface: `linux/module.h`, `linux/workqueue.h`, `media/v4l2-common.h`, `media/v4l2-event.h`, `media/videobuf2-dma-contig.h`, `tw5864.h`, `tw5864-reg.h`.
- Detected declarations: `function tw5864_queue_setup`, `function tw5864_buf_queue`, `function tw5864_input_std_get`, `function tw5864_enable_input`, `function tw5864_request_encoded_frame`, `function tw5864_disable_input`, `function tw5864_start_streaming`, `function tw5864_stop_streaming`, `function tw5864_s_ctrl`, `function tw5864_fmt_vid_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.
- 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.