Beispiel #1
0
static int cx18_try_encoder_cmd(struct file *file, void *fh,
				struct v4l2_encoder_cmd *enc)
{
	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;

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

	case V4L2_ENC_CMD_STOP:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
		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;
		break;

	case V4L2_ENC_CMD_RESUME:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
		enc->flags = 0;
		break;

	default:
		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
		return -EINVAL;
	}
	return 0;
}
Beispiel #2
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;
}
Beispiel #3
0
static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
{
	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;

	switch (cmd) {
	case VIDIOC_INT_S_AUDIO_ROUTING: {
		struct v4l2_routing *route = arg;

		CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
			route->input, route->output);
		cx18_audio_set_route(cx, route);
		break;
	}

	case VIDIOC_INT_RESET: {
		u32 val = *(u32 *)arg;

		if ((val == 0) || (val & 0x01))
			cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
		break;
	}

	default:
		return -EINVAL;
	}
	return 0;
}
Beispiel #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;
}
static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
{
	switch (vctrl->id) {
		/* Standard V4L2 controls */
	case V4L2_CID_BRIGHTNESS:
	case V4L2_CID_HUE:
	case V4L2_CID_SATURATION:
	case V4L2_CID_CONTRAST:
		return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);

	case V4L2_CID_AUDIO_VOLUME:
	case V4L2_CID_AUDIO_MUTE:
	case V4L2_CID_AUDIO_BALANCE:
	case V4L2_CID_AUDIO_BASS:
	case V4L2_CID_AUDIO_TREBLE:
	case V4L2_CID_AUDIO_LOUDNESS:
		return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);

	default:
		CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
		return -EINVAL;
	}
	return 0;
}
Beispiel #6
0
void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
{
    struct cx18 *cx = id->cx;
    struct cx18_stream *s = &cx->streams[id->type];

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

    /* 'Unclaim' this stream */

    /* Stop capturing */
    if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
        struct cx18_stream *s_vbi =
                &cx->streams[CX18_ENC_STREAM_TYPE_VBI];

        CX18_DEBUG_INFO("close stopping capture\n");
        /* Special case: a running VBI capture for VBI insertion
           in the mpeg stream. Need to stop that too. */
        if (id->type == CX18_ENC_STREAM_TYPE_MPG &&
                test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
                !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
            CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
            cx18_stop_v4l2_encode_stream(s_vbi, 0);
        }
        if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
                test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
            /* Also used internally, don't stop capturing */
            s->id = -1;
        else
            cx18_stop_v4l2_encode_stream(s, gop_end);
    }
    if (!gop_end) {
        clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
        clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
        cx18_release_stream(s);
    }
}