diff options
author | Andy Walls <awalls@md.metrocast.net> | 2012-09-03 13:50:49 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-18 12:29:07 -0400 |
commit | 4313902ebe33155209472215c62d2f29d117be29 (patch) | |
tree | 74bdcb1474e9275359c50e3c58e6636fbc0e0fdd | |
parent | 269c11fbac4f7b4ed58e77f3049b64b55a342234 (diff) |
[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: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/pci/ivtv/ivtv-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/pci/ivtv/ivtv-irq.c | 50 |
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index 1918e7326795..bc309f42c8ed 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h | |||
@@ -259,6 +259,7 @@ struct ivtv_mailbox_data { | |||
259 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ | 259 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ |
260 | #define IVTV_F_I_INITED 21 /* set after first open */ | 260 | #define IVTV_F_I_INITED 21 /* set after first open */ |
261 | #define IVTV_F_I_FAILED 22 /* set if first open failed */ | 261 | #define IVTV_F_I_FAILED 22 /* set if first open failed */ |
262 | #define IVTV_F_I_WORK_HANDLER_PCM 23 /* there is work to be done for PCM */ | ||
262 | 263 | ||
263 | /* Event notifications */ | 264 | /* Event notifications */ |
264 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ | 265 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ |
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c index 1b3b9578bf47..19a7c9b990a3 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.c +++ b/drivers/media/pci/ivtv/ivtv-irq.c | |||
@@ -38,6 +38,34 @@ static const int ivtv_stream_map[] = { | |||
38 | IVTV_ENC_STREAM_TYPE_VBI, | 38 | IVTV_ENC_STREAM_TYPE_VBI, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static void ivtv_pcm_work_handler(struct ivtv *itv) | ||
42 | { | ||
43 | struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; | ||
44 | struct ivtv_buffer *buf; | ||
45 | |||
46 | /* Pass the PCM data to ivtv-alsa */ | ||
47 | |||
48 | while (1) { | ||
49 | /* | ||
50 | * Users should not be using both the ALSA and V4L2 PCM audio | ||
51 | * capture interfaces at the same time. If the user is doing | ||
52 | * this, there maybe a buffer in q_io to grab, use, and put | ||
53 | * back in rotation. | ||
54 | */ | ||
55 | buf = ivtv_dequeue(s, &s->q_io); | ||
56 | if (buf == NULL) | ||
57 | buf = ivtv_dequeue(s, &s->q_full); | ||
58 | if (buf == NULL) | ||
59 | break; | ||
60 | |||
61 | if (buf->readpos < buf->bytesused) | ||
62 | itv->pcm_announce_callback(itv->alsa, | ||
63 | (u8 *)(buf->buf + buf->readpos), | ||
64 | (size_t)(buf->bytesused - buf->readpos)); | ||
65 | |||
66 | ivtv_enqueue(s, buf, &s->q_free); | ||
67 | } | ||
68 | } | ||
41 | 69 | ||
42 | static void ivtv_pio_work_handler(struct ivtv *itv) | 70 | static void ivtv_pio_work_handler(struct ivtv *itv) |
43 | { | 71 | { |
@@ -83,6 +111,9 @@ void ivtv_irq_work_handler(struct kthread_work *work) | |||
83 | 111 | ||
84 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) | 112 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) |
85 | ivtv_yuv_work_handler(itv); | 113 | ivtv_yuv_work_handler(itv); |
114 | |||
115 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags)) | ||
116 | ivtv_pcm_work_handler(itv); | ||
86 | } | 117 | } |
87 | 118 | ||
88 | /* Determine the required DMA size, setup enough buffers in the predma queue and | 119 | /* 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) | |||
293 | return; | 324 | return; |
294 | } | 325 | } |
295 | } | 326 | } |
327 | |||
296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); | 328 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); |
329 | |||
330 | if (s->type == IVTV_ENC_STREAM_TYPE_PCM && | ||
331 | itv->pcm_announce_callback != NULL) { | ||
332 | /* | ||
333 | * Set up the work handler to pass the data to ivtv-alsa. | ||
334 | * | ||
335 | * We just use q_full and let the work handler race with users | ||
336 | * making ivtv-fileops.c calls on the PCM device node. | ||
337 | * | ||
338 | * Users should not be using both the ALSA and V4L2 PCM audio | ||
339 | * capture interfaces at the same time. If the user does this, | ||
340 | * fragments of data will just go out each interface as they | ||
341 | * race for PCM data. | ||
342 | */ | ||
343 | set_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags); | ||
344 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); | ||
345 | } | ||
346 | |||
297 | if (s->fh) | 347 | if (s->fh) |
298 | wake_up(&s->waitq); | 348 | wake_up(&s->waitq); |
299 | } | 349 | } |