Ejemplo n.º 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;
}
Ejemplo n.º 2
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;
}