Exemplo n.º 1
0
/* Kernel DVB framework calls this when the feed needs to start.
 * The CX18 framework should enable the transport DMA handling
 * and queue processing.
 */
static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
{
	struct dvb_demux *demux = feed->demux;
	struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
	struct cx18 *cx = stream->cx;
	int ret;
	u32 v;

	CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
			feed->pid, feed->index);

	mutex_lock(&cx->serialize_lock);
	ret = cx18_init_on_first_open(cx);
	mutex_unlock(&cx->serialize_lock);
	if (ret) {
		CX18_ERR("Failed to initialize firmware starting DVB feed\n");
		return ret;
	}
	ret = -EINVAL;

	switch (cx->card->type) {
	case CX18_CARD_HVR_1600_ESMT:
	case CX18_CARD_HVR_1600_SAMSUNG:
		v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
		v |= 0x00400000; /* Serial Mode */
		v |= 0x00002000; /* Data Length - Byte */
		v |= 0x00010000; /* Error - Polarity */
		v |= 0x00020000; /* Error - Passthru */
		v |= 0x000c0000; /* Error - Ignore */
		cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
		break;

	default:
		/* Assumption - Parallel transport - Signalling
		 * undefined or default.
		 */
		break;
	}

	if (!demux->dmx.frontend)
		return -EINVAL;

	if (stream) {
		mutex_lock(&stream->dvb.feedlock);
		if (stream->dvb.feeding++ == 0) {
			CX18_DEBUG_INFO("Starting Transport DMA\n");
			ret = cx18_start_v4l2_encode_stream(stream);
			if (ret < 0) {
				CX18_DEBUG_INFO(
					"Failed to start Transport DMA\n");
				stream->dvb.feeding--;
			}
		} else
			ret = 0;
		mutex_unlock(&stream->dvb.feedlock);
	}

	return ret;
}
Exemplo n.º 2
0
static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
{
	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
	struct cx18 *cx = to_cx18(v4l2_dev);
	struct cx18_stream *s;
	struct cx18_open_id item;
	int ret;

	/* Instruct the cx18 to start sending packets */
	snd_cx18_lock(cxsc);
	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];

	item.cx = cx;
	item.type = s->type;
	item.open_id = cx->open_id++;

	/* See if the stream is available */
	if (cx18_claim_stream(&item, item.type)) {
		/* No, it's already in use */
		snd_cx18_unlock(cxsc);
		return -EBUSY;
	}

	if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
	    test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		/* We're already streaming.  No additional action required */
		snd_cx18_unlock(cxsc);
		return 0;
	}


	runtime->hw = snd_cx18_hw_capture;
	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
	cxsc->capture_pcm_substream = substream;
	runtime->private_data = cx;

	cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;

	/* Not currently streaming, so start it up */
	set_bit(CX18_F_S_STREAMING, &s->s_flags);
	ret = cx18_start_v4l2_encode_stream(s);
	snd_cx18_unlock(cxsc);

	return ret;
}
Exemplo n.º 3
0
int cx18_start_capture(struct cx18_open_id *id)
{
    struct cx18 *cx = id->cx;
    struct cx18_stream *s = &cx->streams[id->type];
    struct cx18_stream *s_vbi;

    if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
        /* you cannot read from these stream types. */
        return -EPERM;
    }

    /* Try to claim this stream. */
    if (cx18_claim_stream(id, s->type))
        return -EBUSY;

    /* If capture is already in progress, then we also have to
       do nothing extra. */
    if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
            test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
        set_bit(CX18_F_S_APPL_IO, &s->s_flags);
        return 0;
    }

    /* Start VBI capture if required */
    s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
    if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
            test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
            !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
        /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed
           automatically when the MPG stream is claimed.
           We only need to start the VBI capturing. */
        if (cx18_start_v4l2_encode_stream(s_vbi)) {
            CX18_DEBUG_WARN("VBI capture start failed\n");

            /* Failure, clean up and return an error */
            clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
            clear_bit(CX18_F_S_STREAMING, &s->s_flags);
            /* also releases the associated VBI stream */
            cx18_release_stream(s);
            return -EIO;
        }
        CX18_DEBUG_INFO("VBI insertion started\n");
    }

    /* Tell the card to start capturing */
    if (!cx18_start_v4l2_encode_stream(s)) {
        /* We're done */
        set_bit(CX18_F_S_APPL_IO, &s->s_flags);
        /* Resume a possibly paused encoder */
        if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
            cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
        return 0;
    }

    /* failure, clean up */
    CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);

    /* Note: the CX18_ENC_STREAM_TYPE_VBI is released
       automatically when the MPG stream is released.
       We only need to stop the VBI capturing. */
    if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
            test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
        cx18_stop_v4l2_encode_stream(s_vbi, 0);
        clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
    }
    clear_bit(CX18_F_S_STREAMING, &s->s_flags);
    cx18_release_stream(s);
    return -EIO;
}