Commit 4313902e authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab
Browse files

[media] ivtv-alsa, ivtv: Connect ivtv PCM capture stream to ivtv-alsa interface driver



This change hooks up the ivtv PCM capture stream to the ivtv-alsa interface
driver.  This is all that should be needed for basic CX23415/CX23416 PCM
audio capture to be available via ALSA device nodes.

Signed-off-by: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 269c11fb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -259,6 +259,7 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DEC_PAUSED	   20 	/* the decoder is paused */
#define IVTV_F_I_INITED		   21 	/* set after first open */
#define IVTV_F_I_FAILED		   22 	/* set if first open failed */
#define IVTV_F_I_WORK_HANDLER_PCM  23	/* there is work to be done for PCM */

/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
+50 −0
Original line number Diff line number Diff line
@@ -38,6 +38,34 @@ static const int ivtv_stream_map[] = {
	IVTV_ENC_STREAM_TYPE_VBI,
};

static void ivtv_pcm_work_handler(struct ivtv *itv)
{
	struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
	struct ivtv_buffer *buf;

	/* Pass the PCM data to ivtv-alsa */

	while (1) {
		/*
		 * Users should not be using both the ALSA and V4L2 PCM audio
		 * capture interfaces at the same time.  If the user is doing
		 * this, there maybe a buffer in q_io to grab, use, and put
		 * back in rotation.
		 */
		buf = ivtv_dequeue(s, &s->q_io);
		if (buf == NULL)
			buf = ivtv_dequeue(s, &s->q_full);
		if (buf == NULL)
			break;

		if (buf->readpos < buf->bytesused)
			itv->pcm_announce_callback(itv->alsa,
				(u8 *)(buf->buf + buf->readpos),
				(size_t)(buf->bytesused - buf->readpos));

		ivtv_enqueue(s, buf, &s->q_free);
	}
}

static void ivtv_pio_work_handler(struct ivtv *itv)
{
@@ -83,6 +111,9 @@ void ivtv_irq_work_handler(struct kthread_work *work)

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
		ivtv_yuv_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags))
		ivtv_pcm_work_handler(itv);
}

/* Determine the required DMA size, setup enough buffers in the predma queue and
@@ -293,7 +324,26 @@ static void dma_post(struct ivtv_stream *s)
			return;
		}
	}

	ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);

	if (s->type == IVTV_ENC_STREAM_TYPE_PCM &&
	    itv->pcm_announce_callback != NULL) {
		/*
		 * Set up the work handler to pass the data to ivtv-alsa.
		 *
		 * We just use q_full and let the work handler race with users
		 * making ivtv-fileops.c calls on the PCM device node.
		 *
		 * Users should not be using both the ALSA and V4L2 PCM audio
		 * capture interfaces at the same time.  If the user does this,
		 * fragments of data will just go out each interface as they
		 * race for PCM data.
		 */
		set_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags);
		set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
	}

	if (s->fh)
		wake_up(&s->waitq);
}