drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
Extension
.c
Size
37491 bytes
Lines
1393
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

struct solo_enc_buf {
	enum solo_enc_types	type;
	const vop_header	*vh;
	int			motion;
};

static int solo_is_motion_on(struct solo_enc_dev *solo_enc)
{
	struct solo_dev *solo_dev = solo_enc->solo_dev;

	return (solo_dev->motion_mask >> solo_enc->ch) & 1;
}

static int solo_motion_detected(struct solo_enc_dev *solo_enc)
{
	struct solo_dev *solo_dev = solo_enc->solo_dev;
	unsigned long flags;
	u32 ch_mask = 1 << solo_enc->ch;
	int ret = 0;

	spin_lock_irqsave(&solo_enc->motion_lock, flags);
	if (solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS) & ch_mask) {
		solo_reg_write(solo_dev, SOLO_VI_MOT_CLEAR, ch_mask);
		ret = 1;
	}
	spin_unlock_irqrestore(&solo_enc->motion_lock, flags);

	return ret;
}

static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on)
{
	struct solo_dev *solo_dev = solo_enc->solo_dev;
	u32 mask = 1 << solo_enc->ch;
	unsigned long flags;

	spin_lock_irqsave(&solo_enc->motion_lock, flags);

	if (on)
		solo_dev->motion_mask |= mask;
	else
		solo_dev->motion_mask &= ~mask;

	solo_reg_write(solo_dev, SOLO_VI_MOT_CLEAR, mask);

	solo_reg_write(solo_dev, SOLO_VI_MOT_ADR,
		       SOLO_VI_MOTION_EN(solo_dev->motion_mask) |
		       (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));

	spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
}

void solo_update_mode(struct solo_enc_dev *solo_enc)
{
	struct solo_dev *solo_dev = solo_enc->solo_dev;
	int vop_len;
	u8 *vop;

	solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0;
	solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1);

	if (solo_enc->mode == SOLO_ENC_MODE_CIF) {
		solo_enc->width = solo_dev->video_hsize >> 1;
		solo_enc->height = solo_dev->video_vsize;
		if (solo_dev->type == SOLO_DEV_6110) {
			if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
				vop = vop_6110_ntsc_cif;
				vop_len = sizeof(vop_6110_ntsc_cif);
			} else {
				vop = vop_6110_pal_cif;
				vop_len = sizeof(vop_6110_pal_cif);
			}
		} else {
			if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
				vop = vop_6010_ntsc_cif;
				vop_len = sizeof(vop_6010_ntsc_cif);
			} else {
				vop = vop_6010_pal_cif;
				vop_len = sizeof(vop_6010_pal_cif);
			}
		}
	} else {
		solo_enc->width = solo_dev->video_hsize;
		solo_enc->height = solo_dev->video_vsize << 1;
		solo_enc->bw_weight <<= 2;
		if (solo_dev->type == SOLO_DEV_6110) {
			if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
				vop = vop_6110_ntsc_d1;
				vop_len = sizeof(vop_6110_ntsc_d1);
			} else {

Annotation

Implementation Notes