summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-04-17 08:57:14 +0200
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-13 18:26:20 +0200
commit15e64f0dde77660a6d84b87dc870055c06d6da85 (patch)
treeeb1330763a3cc47340308484a44965a1feb511b5
parent[media] saa7134: coding style cleanups (diff)
downloadlinux-15e64f0dde77660a6d84b87dc870055c06d6da85.tar.xz
linux-15e64f0dde77660a6d84b87dc870055c06d6da85.zip
[media] saa7134: drop abuse of low-level videobuf functions
saa7134-alsa used low-level videobuf functions to allocate and sync DMA buffers. Replace this with saa7134-specific code. These functions will not be available when we convert to vb2. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/pci/saa7134/saa7134-alsa.c95
-rw-r--r--drivers/media/pci/saa7134/saa7134.h5
2 files changed, 89 insertions, 11 deletions
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c
index ff6f3735f998..cf48987de5e8 100644
--- a/drivers/media/pci/saa7134/saa7134-alsa.c
+++ b/drivers/media/pci/saa7134/saa7134-alsa.c
@@ -274,6 +274,82 @@ static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream
return err;
}
+static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages)
+{
+ struct saa7134_dmasound *dma = &dev->dmasound;
+ struct page *pg;
+ int i;
+
+ dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+ if (NULL == dma->vaddr) {
+ dprintk("vmalloc_32(%d pages) failed\n", nr_pages);
+ return -ENOMEM;
+ }
+
+ dprintk("vmalloc is at addr 0x%08lx, size=%d\n",
+ (unsigned long)dma->vaddr,
+ nr_pages << PAGE_SHIFT);
+
+ memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
+ dma->nr_pages = nr_pages;
+
+ dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist));
+ if (NULL == dma->sglist)
+ goto vzalloc_err;
+
+ sg_init_table(dma->sglist, dma->nr_pages);
+ for (i = 0; i < dma->nr_pages; i++) {
+ pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE);
+ if (NULL == pg)
+ goto vmalloc_to_page_err;
+ sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0);
+ }
+ return 0;
+
+vmalloc_to_page_err:
+ vfree(dma->sglist);
+ dma->sglist = NULL;
+vzalloc_err:
+ vfree(dma->vaddr);
+ dma->vaddr = NULL;
+ return -ENOMEM;
+}
+
+static int saa7134_alsa_dma_map(struct saa7134_dev *dev)
+{
+ struct saa7134_dmasound *dma = &dev->dmasound;
+
+ dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist,
+ dma->nr_pages, PCI_DMA_FROMDEVICE);
+
+ if (0 == dma->sglen) {
+ pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev)
+{
+ struct saa7134_dmasound *dma = &dev->dmasound;
+
+ if (!dma->sglen)
+ return 0;
+
+ dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE);
+ dma->sglen = 0;
+ return 0;
+}
+
+static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma)
+{
+ vfree(dma->sglist);
+ dma->sglist = NULL;
+ vfree(dma->vaddr);
+ dma->vaddr = NULL;
+ return 0;
+}
+
/*
* DMA buffer initialization
*
@@ -291,9 +367,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
BUG_ON(!dev->dmasound.bufsize);
- videobuf_dma_init(&dev->dmasound.dma);
- err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
- (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
+ err = saa7134_alsa_dma_init(dev,
+ (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
if (0 != err)
return err;
return 0;
@@ -310,7 +385,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
{
BUG_ON(!dev->dmasound.blksize);
- videobuf_dma_free(&dev->dmasound.dma);
+ saa7134_alsa_dma_free(&dev->dmasound);
dev->dmasound.blocks = 0;
dev->dmasound.blksize = 0;
@@ -632,7 +707,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
/* release the old buffer */
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}
@@ -648,14 +723,14 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
return err;
}
- err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma);
+ err = saa7134_alsa_dma_map(dev);
if (err) {
dsp_buffer_free(dev);
return err;
}
err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt);
if (err) {
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
return err;
}
@@ -663,7 +738,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
dev->dmasound.sglist, dev->dmasound.sglen, 0);
if (err) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
return err;
}
@@ -672,7 +747,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
byte, but it doesn't work. So I allocate the DMA using the
V4L functions, and force ALSA to use that as the DMA area */
- substream->runtime->dma_area = dev->dmasound.dma.vaddr;
+ substream->runtime->dma_area = dev->dmasound.vaddr;
substream->runtime->dma_bytes = dev->dmasound.bufsize;
substream->runtime->dma_addr = 0;
@@ -699,7 +774,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ saa7134_alsa_dma_unmap(dev);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 2474e848f2c0..419f5f80c248 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -504,7 +504,10 @@ struct saa7134_dmasound {
unsigned int blksize;
unsigned int bufsize;
struct saa7134_pgtable pt;
- struct videobuf_dmabuf dma;
+ void *vaddr;
+ struct scatterlist *sglist;
+ int sglen;
+ int nr_pages;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;