예제 #1
0
int ivtv_v4l2_open(struct file *filp)
{
	int res;
	struct ivtv *itv = NULL;
	struct ivtv_stream *s = NULL;
	struct video_device *vdev = video_devdata(filp);

	s = video_get_drvdata(vdev);
	itv = s->itv;

	mutex_lock(&itv->serialize_lock);
	if (ivtv_init_on_first_open(itv)) {
		IVTV_ERR("Failed to initialize on minor %d\n",
				vdev->minor);
		mutex_unlock(&itv->serialize_lock);
		return -ENXIO;
	}
	res = ivtv_serialized_open(s, filp);
	mutex_unlock(&itv->serialize_lock);
	return res;
}
예제 #2
0
int ivtv_v4l2_open(struct inode *inode, struct file *filp)
{
    int res, x, y = 0;
    struct ivtv *itv = NULL;
    struct ivtv_stream *s = NULL;
    int minor = iminor(inode);

    /* Find which card this open was on */
    spin_lock(&ivtv_cards_lock);
    for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
        if (ivtv_cards[x] == NULL)
            continue;
        /* find out which stream this open was on */
        for (y = 0; y < IVTV_MAX_STREAMS; y++) {
            s = &ivtv_cards[x]->streams[y];
            if (s->v4l2dev && s->v4l2dev->minor == minor) {
                itv = ivtv_cards[x];
                break;
            }
        }
    }
    spin_unlock(&ivtv_cards_lock);

    if (itv == NULL) {
        /* Couldn't find a device registered
           on that minor, shouldn't happen! */
        printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
        return -ENXIO;
    }

    mutex_lock(&itv->serialize_lock);
    if (ivtv_init_on_first_open(itv)) {
        IVTV_ERR("Failed to initialize on minor %d\n", minor);
        mutex_unlock(&itv->serialize_lock);
        return -ENXIO;
    }
    res = ivtv_serialized_open(s, filp);
    mutex_unlock(&itv->serialize_lock);
    return res;
}
예제 #3
0
static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
	struct video_device *vdev = video_devdata(filp);
#endif
	struct ivtv *itv = s->itv;
	struct ivtv_open_id *item;
	int res = 0;

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

#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);
	if (res < 0) {
		v4l2_fh_exit(&item->fh);
		kfree(item);
		return res;
	}
	item->itv = itv;
	item->type = s->type;

	item->open_id = itv->open_id++;
	filp->private_data = &item->fh;

	if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
		/* Try to claim this stream */
		if (ivtv_claim_stream(item, item->type)) {
			/* No, it's already in use */
			v4l2_fh_exit(&item->fh);
			kfree(item);
			return -EBUSY;
		}

		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 */
				ivtv_release_stream(s);
				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;
	}
	v4l2_fh_add(&item->fh);
	return 0;
}

int ivtv_v4l2_open(struct file *filp)
{
	int res;
	struct ivtv *itv = NULL;
	struct ivtv_stream *s = NULL;
	struct video_device *vdev = video_devdata(filp);

	s = video_get_drvdata(vdev);
	itv = s->itv;

	mutex_lock(&itv->serialize_lock);
	if (ivtv_init_on_first_open(itv)) {
		IVTV_ERR("Failed to initialize on device %s\n",
			 video_device_node_name(vdev));
		mutex_unlock(&itv->serialize_lock);
		return -ENXIO;
	}
	res = ivtv_serialized_open(s, filp);
	mutex_unlock(&itv->serialize_lock);
	return res;
}