dmaengine_pcm.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* SPDX-License-Identifier: GPL-2.0+
  2. *
  3. * Copyright (C) 2012, Analog Devices Inc.
  4. * Author: Lars-Peter Clausen <lars@metafoo.de>
  5. */
  6. #ifndef __SOUND_DMAENGINE_PCM_H__
  7. #define __SOUND_DMAENGINE_PCM_H__
  8. #include <sound/pcm.h>
  9. #include <sound/soc.h>
  10. #include <linux/dmaengine.h>
  11. /**
  12. * snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM
  13. * substream
  14. * @substream: PCM substream
  15. */
  16. static inline enum dma_transfer_direction
  17. snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
  18. {
  19. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  20. return DMA_MEM_TO_DEV;
  21. else
  22. return DMA_DEV_TO_MEM;
  23. }
  24. int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
  25. const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
  26. int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
  27. snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
  28. snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
  29. int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
  30. struct dma_chan *chan);
  31. int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
  32. int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
  33. dma_filter_fn filter_fn, void *filter_data);
  34. int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
  35. struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
  36. void *filter_data);
  37. struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
  38. /*
  39. * The DAI supports packed transfers, eg 2 16-bit samples in a 32-bit word.
  40. * If this flag is set the dmaengine driver won't put any restriction on
  41. * the supported sample formats and set the DMA transfer size to undefined.
  42. * The DAI driver is responsible to disable any unsupported formats in it's
  43. * configuration and catch corner cases that are not already handled in
  44. * the ALSA core.
  45. */
  46. #define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
  47. /**
  48. * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
  49. * @addr: Address of the DAI data source or destination register.
  50. * @addr_width: Width of the DAI data source or destination register.
  51. * @maxburst: Maximum number of words(note: words, as in units of the
  52. * src_addr_width member, not bytes) that can be send to or received from the
  53. * DAI in one burst.
  54. * @slave_id: Slave requester id for the DMA channel.
  55. * @filter_data: Custom DMA channel filter data, this will usually be used when
  56. * requesting the DMA channel.
  57. * @chan_name: Custom channel name to use when requesting DMA channel.
  58. * @fifo_size: FIFO size of the DAI controller in bytes
  59. * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
  60. */
  61. struct snd_dmaengine_dai_dma_data {
  62. dma_addr_t addr;
  63. enum dma_slave_buswidth addr_width;
  64. u32 maxburst;
  65. unsigned int slave_id;
  66. void *filter_data;
  67. const char *chan_name;
  68. unsigned int fifo_size;
  69. unsigned int flags;
  70. };
  71. void snd_dmaengine_pcm_set_config_from_dai_data(
  72. const struct snd_pcm_substream *substream,
  73. const struct snd_dmaengine_dai_dma_data *dma_data,
  74. struct dma_slave_config *config);
  75. /*
  76. * Try to request the DMA channel using compat_request_channel or
  77. * compat_filter_fn if it couldn't be requested through devicetree.
  78. */
  79. #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
  80. /*
  81. * Don't try to request the DMA channels through devicetree. This flag only
  82. * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
  83. */
  84. #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
  85. /*
  86. * The PCM is half duplex and the DMA channel is shared between capture and
  87. * playback.
  88. */
  89. #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
  90. /*
  91. * The PCM streams have custom channel names specified.
  92. */
  93. #define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
  94. /**
  95. * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
  96. * @prepare_slave_config: Callback used to fill in the DMA slave_config for a
  97. * PCM substream. Will be called from the PCM drivers hwparams callback.
  98. * @compat_request_channel: Callback to request a DMA channel for platforms
  99. * which do not use devicetree.
  100. * @process: Callback used to apply processing on samples transferred from/to
  101. * user space.
  102. * @compat_filter_fn: Will be used as the filter function when requesting a
  103. * channel for platforms which do not use devicetree. The filter parameter
  104. * will be the DAI's DMA data.
  105. * @dma_dev: If set, request DMA channel on this device rather than the DAI
  106. * device.
  107. * @chan_names: If set, these custom DMA channel names will be requested at
  108. * registration time.
  109. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
  110. * @prealloc_buffer_size: Size of the preallocated audio buffer.
  111. *
  112. * Note: If both compat_request_channel and compat_filter_fn are set
  113. * compat_request_channel will be used to request the channel and
  114. * compat_filter_fn will be ignored. Otherwise the channel will be requested
  115. * using dma_request_channel with compat_filter_fn as the filter function.
  116. */
  117. struct snd_dmaengine_pcm_config {
  118. int (*prepare_slave_config)(struct snd_pcm_substream *substream,
  119. struct snd_pcm_hw_params *params,
  120. struct dma_slave_config *slave_config);
  121. struct dma_chan *(*compat_request_channel)(
  122. struct snd_soc_pcm_runtime *rtd,
  123. struct snd_pcm_substream *substream);
  124. int (*process)(struct snd_pcm_substream *substream,
  125. int channel, unsigned long hwoff,
  126. void *buf, unsigned long bytes);
  127. dma_filter_fn compat_filter_fn;
  128. struct device *dma_dev;
  129. const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
  130. const struct snd_pcm_hardware *pcm_hardware;
  131. unsigned int prealloc_buffer_size;
  132. };
  133. int snd_dmaengine_pcm_register(struct device *dev,
  134. const struct snd_dmaengine_pcm_config *config,
  135. unsigned int flags);
  136. void snd_dmaengine_pcm_unregister(struct device *dev);
  137. int devm_snd_dmaengine_pcm_register(struct device *dev,
  138. const struct snd_dmaengine_pcm_config *config,
  139. unsigned int flags);
  140. int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
  141. struct snd_pcm_hw_params *params,
  142. struct dma_slave_config *slave_config);
  143. #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
  144. #endif