Exemple #1
0
static int cx18_encoder_cmd(struct file *file, void *fh,
				struct v4l2_encoder_cmd *enc)
{
	struct cx18_open_id *id = fh;
	struct cx18 *cx = id->cx;
	u32 h;

	switch (enc->cmd) {
	case V4L2_ENC_CMD_START:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
		enc->flags = 0;
		return cx18_start_capture(id);

	case V4L2_ENC_CMD_STOP:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
		cx18_stop_capture(id,
				  enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
		break;

	case V4L2_ENC_CMD_PAUSE:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
		enc->flags = 0;
		if (!atomic_read(&cx->ana_capturing))
			return -EPERM;
		if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
			return 0;
		h = cx18_find_handle(cx);
		if (h == CX18_INVALID_TASK_HANDLE) {
			CX18_ERR("Can't find valid task handle for "
				 "V4L2_ENC_CMD_PAUSE\n");
			return -EBADFD;
		}
		cx18_mute(cx);
		cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
		break;

	case V4L2_ENC_CMD_RESUME:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
		enc->flags = 0;
		if (!atomic_read(&cx->ana_capturing))
			return -EPERM;
		if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
			return 0;
		h = cx18_find_handle(cx);
		if (h == CX18_INVALID_TASK_HANDLE) {
			CX18_ERR("Can't find valid task handle for "
				 "V4L2_ENC_CMD_RESUME\n");
			return -EBADFD;
		}
		cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
		cx18_unmute(cx);
		break;

	default:
		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
		return -EINVAL;
	}
	return 0;
}
Exemple #2
0
int cx18_s_input(struct file *file, void *fh, unsigned int inp)
{
	struct cx18_open_id *id = fh;
	struct cx18 *cx = id->cx;
	int ret;

	ret = v4l2_prio_check(&cx->prio, &id->prio);
	if (ret)
		return ret;

	if (inp < 0 || inp >= cx->nof_inputs)
		return -EINVAL;

	if (inp == cx->active_input) {
		CX18_DEBUG_INFO("Input unchanged\n");
		return 0;
	}

	CX18_DEBUG_INFO("Changing input from %d to %d\n",
			cx->active_input, inp);

	cx->active_input = inp;
	/* Set the audio input to whatever is appropriate for the input type. */
	cx->audio_input = cx->card->video_inputs[inp].audio_index;

	/* prevent others from messing with the streams until
	   we're finished changing inputs. */
	cx18_mute(cx);
	cx18_video_set_io(cx);
	cx18_audio_set_io(cx);
	cx18_unmute(cx);
	return 0;
}
Exemple #3
0
static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
{
    struct cx18 *cx = s->cx;
    struct cx18_open_id *item;

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

    /* Allocate memory */
    item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
    if (NULL == item) {
        CX18_DEBUG_WARN("nomem on v4l2 open\n");
        return -ENOMEM;
    }
    item->cx = cx;
    item->type = s->type;
    v4l2_prio_open(&cx->prio, &item->prio);

    item->open_id = cx->open_id++;
    filp->private_data = item;

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

        if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
            if (atomic_read(&cx->ana_capturing) > 0) {
                /* switching to radio while capture is
                   in progress is not polite */
                cx18_release_stream(s);
                kfree(item);
                return -EBUSY;
            }
        }

        /* Mark that the radio is being used. */
        set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
        /* We have the radio */
        cx18_mute(cx);
        /* Switch tuner to radio */
        cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
        /* Select the correct audio input (i.e. radio tuner) */
        cx18_audio_set_io(cx);
        /* Done! Unmute and continue. */
        cx18_unmute(cx);
    }
    return 0;
}
Exemple #4
0
int cx18_v4l2_close(struct inode *inode, struct file *filp)
{
    struct cx18_open_id *id = filp->private_data;
    struct cx18 *cx = id->cx;
    struct cx18_stream *s = &cx->streams[id->type];

    CX18_DEBUG_IOCTL("close() of %s\n", s->name);

    v4l2_prio_close(&cx->prio, &id->prio);

    /* Easy case first: this stream was never claimed by us */
    if (s->id != id->open_id) {
        kfree(id);
        return 0;
    }

    /* 'Unclaim' this stream */

    /* Stop radio */
    mutex_lock(&cx->serialize_lock);
    if (id->type == CX18_ENC_STREAM_TYPE_RAD) {
        /* Closing radio device, return to TV mode */
        cx18_mute(cx);
        /* Mark that the radio is no longer in use */
        clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
        /* Switch tuner to TV */
        cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
        /* Select correct audio input (i.e. TV tuner or Line in) */
        cx18_audio_set_io(cx);
        if (atomic_read(&cx->ana_capturing) > 0) {
            /* Undo video mute */
            cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
                      cx->params.video_mute |
                      (cx->params.video_mute_yuv << 8));
        }
        /* Done! Unmute and continue. */
        cx18_unmute(cx);
        cx18_release_stream(s);
    } else {
        cx18_stop_capture(id, 0);
    }
    kfree(id);
    mutex_unlock(&cx->serialize_lock);
    return 0;
}
Exemple #5
0
int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
{
	struct cx18_open_id *id = fh;
	struct cx18 *cx = id->cx;
	int ret;

	ret = v4l2_prio_check(&cx->prio, &id->prio);
	if (ret)
		return ret;

	if (vf->tuner != 0)
		return -EINVAL;

	cx18_mute(cx);
	CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
	cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
	cx18_unmute(cx);
	return 0;
}