drivers/media/pci/cx18/cx18-streams.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cx18/cx18-streams.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cx18/cx18-streams.c
Extension
.c
Size
29396 bytes
Lines
1052
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (cx->card->hw_all & CX18_HW_DVB) {
			s->dvb = kzalloc_obj(struct cx18_dvb);
			if (s->dvb == NULL) {
				CX18_ERR("Couldn't allocate cx18_dvb structure for %s\n",
					 s->name);
				return -ENOMEM;
			}
		} else {
			/* Don't need buffers for the TS, if there is no DVB */
			s->buffers = 0;
		}
	}

	if (num_offset == -1)
		return 0;

	/* initialize the v4l2 video device structure */
	snprintf(s->video_dev.name, sizeof(s->video_dev.name), "%s %s",
		 cx->v4l2_dev.name, s->name);

	s->video_dev.num = num;
	s->video_dev.v4l2_dev = &cx->v4l2_dev;
	if (type == CX18_ENC_STREAM_TYPE_YUV)
		s->video_dev.fops = &cx18_v4l2_enc_yuv_fops;
	else
		s->video_dev.fops = &cx18_v4l2_enc_fops;
	s->video_dev.release = video_device_release_empty;
	if (cx->card->video_inputs->video_type == CX18_CARD_INPUT_VID_TUNER)
		s->video_dev.tvnorms = cx->tuner_std;
	else
		s->video_dev.tvnorms = V4L2_STD_ALL;
	s->video_dev.lock = &cx->serialize_lock;
	cx18_set_funcs(&s->video_dev);
	return 0;
}

/* Initialize v4l2 variables and register v4l2 devices */
int cx18_streams_setup(struct cx18 *cx)
{
	int type, ret;

	/* Setup V4L2 Devices */
	for (type = 0; type < CX18_MAX_STREAMS; type++) {
		/* Prepare device */
		ret = cx18_prep_dev(cx, type);
		if (ret < 0)
			break;

		/* Allocate Stream */
		ret = cx18_stream_alloc(&cx->streams[type]);
		if (ret < 0)
			break;
	}
	if (type == CX18_MAX_STREAMS)
		return 0;

	/* One or more streams could not be initialized. Clean 'em all up. */
	cx18_streams_cleanup(cx, 0);
	return ret;
}

static int cx18_reg_dev(struct cx18 *cx, int type)
{
	struct cx18_stream *s = &cx->streams[type];
	int vfl_type = cx18_stream_info[type].vfl_type;
	const char *name;
	int num, ret;

	if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
		ret = cx18_dvb_register(s);
		if (ret < 0) {
			CX18_ERR("DVB failed to register\n");
			return ret;
		}
	}

	if (s->video_dev.v4l2_dev == NULL)
		return 0;

	num = s->video_dev.num;
	s->video_dev.device_caps = s->v4l2_dev_caps;	/* device capabilities */
	/* card number + user defined offset + device offset */
	if (type != CX18_ENC_STREAM_TYPE_MPG) {
		struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];

		if (s_mpg->video_dev.v4l2_dev)
			num = s_mpg->video_dev.num
			    + cx18_stream_info[type].num_offset;
	}
	video_set_drvdata(&s->video_dev, s);

Annotation

Implementation Notes