]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/media/video/cx18/cx18-alsa-pcm.c
V4L/DVB: drivers/media/video/cx18/cx18-alsa-pcm.c: fix printk warning
[net-next-2.6.git] / drivers / media / video / cx18 / cx18-alsa-pcm.c
index e14f8e42a2ab4e06f040da4f04daa7ba3698f905..2bd312daeb1e5d6a25521a45e6b289ba256f117e 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
 #include <media/v4l2-device.h>
 
 #include "cx18-fileops.h"
 #include "cx18-alsa.h"
 
-extern int cx18_alsa_debug;
+static unsigned int pcm_debug;
+module_param(pcm_debug, int, 0644);
+MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
 
 #define dprintk(fmt, arg...) do {                                      \
-           if (cx18_alsa_debug)                                        \
-               printk(KERN_INFO "cx18-alsa %s: " fmt,                  \
+           if (pcm_debug)                                              \
+               printk(KERN_INFO "cx18-alsa-pcm %s: " fmt,              \
                                  __func__, ##arg);                     \
        } while (0)
 
-/* Forward Declaration */
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
-                                size_t num_bytes);
-
 static struct snd_pcm_hardware snd_cx18_hw_capture = {
        .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
                SNDRV_PCM_INFO_MMAP           |
@@ -57,7 +56,7 @@ static struct snd_pcm_hardware snd_cx18_hw_capture = {
 
        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 
-       .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
+       .rates = SNDRV_PCM_RATE_48000,
 
        .rate_min = 48000,
        .rate_max = 48000,
@@ -70,6 +69,82 @@ static struct snd_pcm_hardware snd_cx18_hw_capture = {
        .periods_max = 98,              /* 12544, */
 };
 
+void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
+                                size_t num_bytes)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_pcm_runtime *runtime;
+       unsigned int oldptr;
+       unsigned int stride;
+       int period_elapsed = 0;
+       int length;
+
+       dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
+               pcm_data, num_bytes);
+
+       substream = cxsc->capture_pcm_substream;
+       if (substream == NULL) {
+               dprintk("substream was NULL\n");
+               return;
+       }
+
+       runtime = substream->runtime;
+       if (runtime == NULL) {
+               dprintk("runtime was NULL\n");
+               return;
+       }
+
+       stride = runtime->frame_bits >> 3;
+       if (stride == 0) {
+               dprintk("stride is zero\n");
+               return;
+       }
+
+       length = num_bytes / stride;
+       if (length == 0) {
+               dprintk("%s: length was zero\n", __func__);
+               return;
+       }
+
+       if (runtime->dma_area == NULL) {
+               dprintk("dma area was NULL - ignoring\n");
+               return;
+       }
+
+       oldptr = cxsc->hwptr_done_capture;
+       if (oldptr + length >= runtime->buffer_size) {
+               unsigned int cnt =
+                       runtime->buffer_size - oldptr;
+               memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+                      cnt * stride);
+               memcpy(runtime->dma_area, pcm_data + cnt * stride,
+                      length * stride - cnt * stride);
+       } else {
+               memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+                      length * stride);
+       }
+       snd_pcm_stream_lock(substream);
+
+       cxsc->hwptr_done_capture += length;
+       if (cxsc->hwptr_done_capture >=
+           runtime->buffer_size)
+               cxsc->hwptr_done_capture -=
+                       runtime->buffer_size;
+
+       cxsc->capture_transfer_done += length;
+       if (cxsc->capture_transfer_done >=
+           runtime->period_size) {
+               cxsc->capture_transfer_done -=
+                       runtime->period_size;
+               period_elapsed = 1;
+       }
+
+       snd_pcm_stream_unlock(substream);
+
+       if (period_elapsed)
+               snd_pcm_period_elapsed(substream);
+}
+
 static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
 {
        struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
@@ -77,31 +152,28 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
        struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
        struct cx18 *cx = to_cx18(v4l2_dev);
        struct cx18_stream *s;
-       struct cx18_open_id *item;
+       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];
 
-       /* Allocate memory */
-       item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
-       if (NULL == item) {
-               return -ENOMEM;
-       }
-       item->cx = cx;
-       item->type = s->type;
-       item->open_id = cx->open_id++;
+       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)) {
+       if (cx18_claim_stream(&item, item.type)) {
                /* No, it's already in use */
-               kfree(item);
+               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;
        }
 
@@ -116,13 +188,13 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
        /* 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 0;
 }
 
 static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
 {
-       unsigned long flags;
        struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
        struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
        struct cx18 *cx = to_cx18(v4l2_dev);
@@ -130,6 +202,7 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
        int ret;
 
        /* Instruct the cx18 to stop sending packets */
+       snd_cx18_lock(cxsc);
        s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
        ret = cx18_stop_v4l2_encode_stream(s, 0);
        clear_bit(CX18_F_S_STREAMING, &s->s_flags);
@@ -137,14 +210,7 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
        cx18_release_stream(s);
 
        cx->pcm_announce_callback = NULL;
-
-       spin_lock_irqsave(&cxsc->slock, flags);
-       if (substream->runtime->dma_area) {
-               dprintk("freeing pcm capture region\n");
-               vfree(substream->runtime->dma_area);
-               substream->runtime->dma_area = NULL;
-       }
-       spin_unlock_irqrestore(&cxsc->slock, flags);
+       snd_cx18_unlock(cxsc);
 
        return 0;
 }
@@ -191,6 +257,17 @@ static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
 {
+       struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+       unsigned long flags;
+
+       spin_lock_irqsave(&cxsc->slock, flags);
+       if (substream->runtime->dma_area) {
+               dprintk("freeing pcm capture region\n");
+               vfree(substream->runtime->dma_area);
+               substream->runtime->dma_area = NULL;
+       }
+       spin_unlock_irqrestore(&cxsc->slock, flags);
+
        return 0;
 }
 
@@ -223,7 +300,6 @@ snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
        return hwptr_done;
 }
 
-
 static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
                                             unsigned long offset)
 {
@@ -244,82 +320,6 @@ static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
        .page           = snd_pcm_get_vmalloc_page,
 };
 
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
-                                size_t num_bytes)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_pcm_runtime *runtime;
-       unsigned int oldptr;
-       unsigned int stride;
-       int period_elapsed = 0;
-       int length;
-
-       dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%d\n", cxsc,
-               pcm_data, num_bytes);
-
-       substream = cxsc->capture_pcm_substream;
-       if (substream == NULL) {
-               dprintk("substream was NULL\n");
-               return;
-       }
-
-       runtime = substream->runtime;
-       if (runtime == NULL) {
-               dprintk("runtime was NULL\n");
-               return;
-       }
-
-       stride = runtime->frame_bits >> 3;
-       if (stride == 0) {
-               dprintk("stride is zero\n");
-               return;
-       }
-
-       length = num_bytes / stride;
-       if (length == 0) {
-               dprintk("%s: length was zero\n", __func__);
-               return;
-       }
-
-       if (runtime->dma_area == NULL) {
-               dprintk("dma area was NULL - ignoring\n");
-               return;
-       }
-
-       oldptr = cxsc->hwptr_done_capture;
-       if (oldptr + length >= runtime->buffer_size) {
-               unsigned int cnt =
-                       runtime->buffer_size - oldptr;
-               memcpy(runtime->dma_area + oldptr * stride, pcm_data,
-                      cnt * stride);
-               memcpy(runtime->dma_area, pcm_data + cnt * stride,
-                      length * stride - cnt * stride);
-       } else {
-               memcpy(runtime->dma_area + oldptr * stride, pcm_data,
-                      length * stride);
-       }
-       snd_pcm_stream_lock(substream);
-
-       cxsc->hwptr_done_capture += length;
-       if (cxsc->hwptr_done_capture >=
-           runtime->buffer_size)
-               cxsc->hwptr_done_capture -=
-                       runtime->buffer_size;
-
-       cxsc->capture_transfer_done += length;
-       if (cxsc->capture_transfer_done >=
-           runtime->period_size) {
-               cxsc->capture_transfer_done -=
-                       runtime->period_size;
-               period_elapsed = 1;
-       }
-
-       snd_pcm_stream_unlock(substream);
-
-       if (period_elapsed)
-               snd_pcm_period_elapsed(substream);
-}
-
 int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
 {
        struct snd_pcm *sp;
@@ -341,7 +341,8 @@ int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
 
        spin_lock_init(&cxsc->slock);
 
-       snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE, &snd_cx18_pcm_capture_ops);
+       snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
+                       &snd_cx18_pcm_capture_ops);
        sp->info_flags = 0;
        sp->private_data = cxsc;
        strlcpy(sp->name, cx->card_name, sizeof(sp->name));