Beispiel #1
0
static int ivtv_open(struct file *filp)
{
	struct video_device *vdev = video_devdata(filp);
	struct ivtv_stream *s = video_get_drvdata(vdev);
	struct ivtv *itv = s->itv;
	struct ivtv_open_id *item;
	int res = 0;

	IVTV_DEBUG_FILE("open %s\n", s->name);

	if (ivtv_init_on_first_open(itv)) {
		IVTV_ERR("Failed to initialize on device %s\n",
			 video_device_node_name(vdev));
		return -ENXIO;
	}

#ifdef CONFIG_VIDEO_ADV_DEBUG
	/* Unless ivtv_fw_debug is set, error out if firmware dead. */
	if (ivtv_fw_debug) {
		IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
			  video_device_node_name(vdev));
		IVTV_WARN("Selected firmware errors will be ignored\n");
	} else {
#else
	if (1) {
#endif
		res = ivtv_firmware_check(itv, "ivtv_serialized_open");
		if (res == -EAGAIN)
			res = ivtv_firmware_check(itv, "ivtv_serialized_open");
		if (res < 0)
			return -EIO;
	}

	if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
		return -EBUSY;

	if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
		return -EBUSY;

	if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
		if (read_reg(0x82c) == 0) {
			IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
			/* return -ENODEV; */
		}
		ivtv_udma_alloc(itv);
	}

	/* Allocate memory */
	item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
	if (NULL == item) {
		IVTV_DEBUG_WARN("nomem on v4l2 open\n");
		return -ENOMEM;
	}
	v4l2_fh_init(&item->fh, &s->vdev);
	item->itv = itv;
	item->type = s->type;

	filp->private_data = &item->fh;
	v4l2_fh_add(&item->fh);

	if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
			v4l2_fh_is_singular_file(filp)) {
		if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
			if (atomic_read(&itv->capturing) > 0) {
				/* switching to radio while capture is
				   in progress is not polite */
				v4l2_fh_del(&item->fh);
				v4l2_fh_exit(&item->fh);
				kfree(item);
				return -EBUSY;
			}
		}
		/* Mark that the radio is being used. */
		set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
		/* We have the radio */
		ivtv_mute(itv);
		/* Switch tuner to radio */
		ivtv_call_all(itv, tuner, s_radio);
		/* Select the correct audio input (i.e. radio tuner) */
		ivtv_audio_set_io(itv);
		if (itv->hw_flags & IVTV_HW_SAA711X) {
			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
				SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
		}
		/* Done! Unmute and continue. */
		ivtv_unmute(itv);
	}

	/* YUV or MPG Decoding Mode? */
	if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {
		clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
	} else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
		set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
		/* For yuv, we need to know the dma size before we start */
		itv->dma_data_req_size =
				1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
		itv->yuv_info.stream_size = 0;
	}
	return 0;
}

int ivtv_v4l2_open(struct file *filp)
{
	struct video_device *vdev = video_devdata(filp);
	int res;

	if (mutex_lock_interruptible(vdev->lock))
		return -ERESTARTSYS;
	res = ivtv_open(filp);
	mutex_unlock(vdev->lock);
	return res;
}

void ivtv_mute(struct ivtv *itv)
{
	if (atomic_read(&itv->capturing))
		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
	IVTV_DEBUG_INFO("Mute\n");
}

void ivtv_unmute(struct ivtv *itv)
{
	if (atomic_read(&itv->capturing)) {
		ivtv_msleep_timeout(100, 0);
		ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
	}
	IVTV_DEBUG_INFO("Unmute\n");
}
Beispiel #2
0
static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv *itv = s->itv;
	int datatype;
	u16 width;
	u16 height;

	if (s->vdev == NULL)
		return -EINVAL;

	IVTV_DEBUG_INFO("Setting some initial decoder settings\n");

	width = itv->cxhdl.width;
	height = itv->cxhdl.height;

	/* set audio mode to left/stereo  for dual/stereo mode. */
	ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);

	/* set number of internal decoder buffers */
	ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0);

	/* prebuffering */
	ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1);

	/* extract from user packets */
	ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1);
	itv->vbi.dec_start = data[0];

	IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n",
		itv->vbi.dec_start, data[1]);

	/* set decoder source settings */
	/* Data type: 0 = mpeg from host,
	   1 = yuv from encoder,
	   2 = yuv_from_host */
	switch (s->type) {
	case IVTV_DEC_STREAM_TYPE_YUV:
		if (itv->output_mode == OUT_PASSTHROUGH) {
			datatype = 1;
		} else {
			/* Fake size to avoid switching video standard */
			datatype = 2;
			width = 720;
			height = itv->is_out_50hz ? 576 : 480;
		}
		IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
		break;
	case IVTV_DEC_STREAM_TYPE_MPG:
	default:
		datatype = 0;
		break;
	}
	if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
			width, height, itv->cxhdl.audio_properties)) {
		IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
	}

	/* Decoder sometimes dies here, so wait a moment */
	ivtv_msleep_timeout(10, 0);

	/* Known failure point for firmware, so check */
	return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream");
}
static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv *itv = s->itv;
	int datatype;
	u16 width;
	u16 height;

	if (s->vdev == NULL)
		return -EINVAL;

	IVTV_DEBUG_INFO("Setting some initial decoder settings\n");

	width = itv->cxhdl.width;
	height = itv->cxhdl.height;

	/*                                                      */
	ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);

	/*                                        */
	ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0);

	/*              */
	ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1);

	/*                           */
	ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1);
	itv->vbi.dec_start = data[0];

	IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n",
		itv->vbi.dec_start, data[1]);

	/*                             */
	/*                               
                         
                      */
	switch (s->type) {
	case IVTV_DEC_STREAM_TYPE_YUV:
		if (itv->output_mode == OUT_PASSTHROUGH) {
			datatype = 1;
		} else {
			/*                                             */
			datatype = 2;
			width = 720;
			height = itv->is_out_50hz ? 576 : 480;
		}
		IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
		break;
	case IVTV_DEC_STREAM_TYPE_MPG:
	default:
		datatype = 0;
		break;
	}
	if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
			width, height, itv->cxhdl.audio_properties)) {
		IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
	}

	/*                                               */
	ivtv_msleep_timeout(10, 0);

	/*                                            */
	return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream");
}