dmaengine_pcm.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. * Return: DMA transfer direction
  17. */
  18. static inline enum dma_transfer_direction
  19. snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
  20. {
  21. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  22. return DMA_MEM_TO_DEV;
  23. else
  24. return DMA_DEV_TO_MEM;
  25. }
  26. int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
  27. const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
  28. int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
  29. snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
  30. snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
  31. int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
  32. struct dma_chan *chan);
  33. int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
  34. int snd_dmaengine_pcm_sync_stop(struct snd_pcm_substream *substream);
  35. int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
  36. struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
  37. void *filter_data);
  38. struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
  39. /*
  40. * The DAI supports packed transfers, eg 2 16-bit samples in a 32-bit word.
  41. * If this flag is set the dmaengine driver won't put any restriction on
  42. * the supported sample formats and set the DMA transfer size to undefined.
  43. * The DAI driver is responsible to disable any unsupported formats in it's
  44. * configuration and catch corner cases that are not already handled in
  45. * the ALSA core.
  46. */
  47. #define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
  48. /**
  49. * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
  50. * @addr: Address of the DAI data source or destination register.
  51. * @addr_width: Width of the DAI data source or destination register.
  52. * @maxburst: Maximum number of words(note: words, as in units of the
  53. * src_addr_width member, not bytes) that can be send to or received from the
  54. * DAI in one burst.
  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. * @peripheral_config: peripheral configuration for programming peripheral
  61. * for dmaengine transfer
  62. * @peripheral_size: peripheral configuration buffer size
  63. * @port_window_size: The length of the register area in words the data need
  64. * to be accessed on the device side. It is only used for devices which is using
  65. * an area instead of a single register to send/receive the data. Typically the
  66. * DMA loops in this area in order to transfer the data.
  67. */
  68. struct snd_dmaengine_dai_dma_data {
  69. dma_addr_t addr;
  70. enum dma_slave_buswidth addr_width;
  71. u32 maxburst;
  72. void *filter_data;
  73. const char *chan_name;
  74. unsigned int fifo_size;
  75. unsigned int flags;
  76. void *peripheral_config;
  77. size_t peripheral_size;
  78. u32 port_window_size;
  79. };
  80. void snd_dmaengine_pcm_set_config_from_dai_data(
  81. const struct snd_pcm_substream *substream,
  82. const struct snd_dmaengine_dai_dma_data *dma_data,
  83. struct dma_slave_config *config);
  84. int snd_dmaengine_pcm_refine_runtime_hwparams(
  85. struct snd_pcm_substream *substream,
  86. struct snd_dmaengine_dai_dma_data *dma_data,
  87. struct snd_pcm_hardware *hw,
  88. struct dma_chan *chan);
  89. /*
  90. * Try to request the DMA channel using compat_request_channel or
  91. * compat_filter_fn if it couldn't be requested through devicetree.
  92. */
  93. #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
  94. /*
  95. * Don't try to request the DMA channels through devicetree. This flag only
  96. * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
  97. */
  98. #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
  99. /*
  100. * The PCM is half duplex and the DMA channel is shared between capture and
  101. * playback.
  102. */
  103. #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
  104. /**
  105. * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
  106. * @prepare_slave_config: Callback used to fill in the DMA slave_config for a
  107. * PCM substream. Will be called from the PCM drivers hwparams callback.
  108. * @compat_request_channel: Callback to request a DMA channel for platforms
  109. * which do not use devicetree.
  110. * @process: Callback used to apply processing on samples transferred from/to
  111. * user space.
  112. * @name: Component name. If null, dev_name will be used.
  113. * @compat_filter_fn: Will be used as the filter function when requesting a
  114. * channel for platforms which do not use devicetree. The filter parameter
  115. * will be the DAI's DMA data.
  116. * @dma_dev: If set, request DMA channel on this device rather than the DAI
  117. * device.
  118. * @chan_names: If set, these custom DMA channel names will be requested at
  119. * registration time.
  120. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
  121. * @prealloc_buffer_size: Size of the preallocated audio buffer.
  122. *
  123. * Note: If both compat_request_channel and compat_filter_fn are set
  124. * compat_request_channel will be used to request the channel and
  125. * compat_filter_fn will be ignored. Otherwise the channel will be requested
  126. * using dma_request_channel with compat_filter_fn as the filter function.
  127. */
  128. struct snd_dmaengine_pcm_config {
  129. int (*prepare_slave_config)(struct snd_pcm_substream *substream,
  130. struct snd_pcm_hw_params *params,
  131. struct dma_slave_config *slave_config);
  132. struct dma_chan *(*compat_request_channel)(
  133. struct snd_soc_pcm_runtime *rtd,
  134. struct snd_pcm_substream *substream);
  135. int (*process)(struct snd_pcm_substream *substream,
  136. int channel, unsigned long hwoff,
  137. unsigned long bytes);
  138. const char *name;
  139. dma_filter_fn compat_filter_fn;
  140. struct device *dma_dev;
  141. const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
  142. const struct snd_pcm_hardware *pcm_hardware;
  143. unsigned int prealloc_buffer_size;
  144. };
  145. int snd_dmaengine_pcm_register(struct device *dev,
  146. const struct snd_dmaengine_pcm_config *config,
  147. unsigned int flags);
  148. void snd_dmaengine_pcm_unregister(struct device *dev);
  149. int devm_snd_dmaengine_pcm_register(struct device *dev,
  150. const struct snd_dmaengine_pcm_config *config,
  151. unsigned int flags);
  152. int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
  153. struct snd_pcm_hw_params *params,
  154. struct dma_slave_config *slave_config);
  155. #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
  156. struct dmaengine_pcm {
  157. struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
  158. const struct snd_dmaengine_pcm_config *config;
  159. struct snd_soc_component component;
  160. unsigned int flags;
  161. };
  162. static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
  163. {
  164. return container_of(p, struct dmaengine_pcm, component);
  165. }
  166. #endif