devdma.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * linux/sound/arm/devdma.c
  3. *
  4. * Copyright (C) 2003-2004 Russell King, All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * ARM DMA shim for ALSA.
  11. */
  12. #include <linux/device.h>
  13. #include <linux/dma-mapping.h>
  14. #include <sound/core.h>
  15. #include <sound/pcm.h>
  16. #include "devdma.h"
  17. void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
  18. {
  19. struct snd_pcm_runtime *runtime = substream->runtime;
  20. struct snd_dma_buffer *buf = runtime->dma_buffer_p;
  21. if (runtime->dma_area == NULL)
  22. return;
  23. if (buf != &substream->dma_buffer) {
  24. dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
  25. kfree(runtime->dma_buffer_p);
  26. }
  27. snd_pcm_set_runtime_buffer(substream, NULL);
  28. }
  29. int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
  30. {
  31. struct snd_pcm_runtime *runtime = substream->runtime;
  32. struct snd_dma_buffer *buf = runtime->dma_buffer_p;
  33. int ret = 0;
  34. if (buf) {
  35. if (buf->bytes >= size)
  36. goto out;
  37. devdma_hw_free(dev, substream);
  38. }
  39. if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
  40. buf = &substream->dma_buffer;
  41. } else {
  42. buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
  43. if (!buf)
  44. goto nomem;
  45. buf->dev.type = SNDRV_DMA_TYPE_DEV;
  46. buf->dev.dev = dev;
  47. buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
  48. buf->bytes = size;
  49. buf->private_data = NULL;
  50. if (!buf->area)
  51. goto free;
  52. }
  53. snd_pcm_set_runtime_buffer(substream, buf);
  54. ret = 1;
  55. out:
  56. runtime->dma_bytes = size;
  57. return ret;
  58. free:
  59. kfree(buf);
  60. nomem:
  61. return -ENOMEM;
  62. }
  63. int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
  64. {
  65. struct snd_pcm_runtime *runtime = substream->runtime;
  66. return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
  67. }