dmaengine_pcm.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /* SPDX-License-Identifier: GPL-2.0+
  2. *
  3. * Copyright (C) 2012, Analog Devices Inc.
  4. * Author: Lars-Peter Clausen <[email protected]>
  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_open_request_chan(struct snd_pcm_substream *substream,
  35. dma_filter_fn filter_fn, void *filter_data);
  36. int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
  37. struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
  38. void *filter_data);
  39. struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
  40. /*
  41. * The DAI supports packed transfers, eg 2 16-bit samples in a 32-bit word.
  42. * If this flag is set the dmaengine driver won't put any restriction on
  43. * the supported sample formats and set the DMA transfer size to undefined.
  44. * The DAI driver is responsible to disable any unsupported formats in it's
  45. * configuration and catch corner cases that are not already handled in
  46. * the ALSA core.
  47. */
  48. #define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
  49. /**
  50. * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
  51. * @addr: Address of the DAI data source or destination register.
  52. * @addr_width: Width of the DAI data source or destination register.
  53. * @maxburst: Maximum number of words(note: words, as in units of the
  54. * src_addr_width member, not bytes) that can be send to or received from the
  55. * DAI in one burst.
  56. * @filter_data: Custom DMA channel filter data, this will usually be used when
  57. * requesting the DMA channel.
  58. * @chan_name: Custom channel name to use when requesting DMA channel.
  59. * @fifo_size: FIFO size of the DAI controller in bytes
  60. * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
  61. * @peripheral_config: peripheral configuration for programming peripheral
  62. * for dmaengine transfer
  63. * @peripheral_size: peripheral configuration buffer size
  64. */
  65. struct snd_dmaengine_dai_dma_data {
  66. dma_addr_t addr;
  67. enum dma_slave_buswidth addr_width;
  68. u32 maxburst;
  69. void *filter_data;
  70. const char *chan_name;
  71. unsigned int fifo_size;
  72. unsigned int flags;
  73. void *peripheral_config;
  74. size_t peripheral_size;
  75. };
  76. void snd_dmaengine_pcm_set_config_from_dai_data(
  77. const struct snd_pcm_substream *substream,
  78. const struct snd_dmaengine_dai_dma_data *dma_data,
  79. struct dma_slave_config *config);
  80. int snd_dmaengine_pcm_refine_runtime_hwparams(
  81. struct snd_pcm_substream *substream,
  82. struct snd_dmaengine_dai_dma_data *dma_data,
  83. struct snd_pcm_hardware *hw,
  84. struct dma_chan *chan);
  85. /*
  86. * Try to request the DMA channel using compat_request_channel or
  87. * compat_filter_fn if it couldn't be requested through devicetree.
  88. */
  89. #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
  90. /*
  91. * Don't try to request the DMA channels through devicetree. This flag only
  92. * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
  93. */
  94. #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
  95. /*
  96. * The PCM is half duplex and the DMA channel is shared between capture and
  97. * playback.
  98. */
  99. #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
  100. /**
  101. * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
  102. * @prepare_slave_config: Callback used to fill in the DMA slave_config for a
  103. * PCM substream. Will be called from the PCM drivers hwparams callback.
  104. * @compat_request_channel: Callback to request a DMA channel for platforms
  105. * which do not use devicetree.
  106. * @process: Callback used to apply processing on samples transferred from/to
  107. * user space.
  108. * @compat_filter_fn: Will be used as the filter function when requesting a
  109. * channel for platforms which do not use devicetree. The filter parameter
  110. * will be the DAI's DMA data.
  111. * @dma_dev: If set, request DMA channel on this device rather than the DAI
  112. * device.
  113. * @chan_names: If set, these custom DMA channel names will be requested at
  114. * registration time.
  115. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
  116. * @prealloc_buffer_size: Size of the preallocated audio buffer.
  117. *
  118. * Note: If both compat_request_channel and compat_filter_fn are set
  119. * compat_request_channel will be used to request the channel and
  120. * compat_filter_fn will be ignored. Otherwise the channel will be requested
  121. * using dma_request_channel with compat_filter_fn as the filter function.
  122. */
  123. struct snd_dmaengine_pcm_config {
  124. int (*prepare_slave_config)(struct snd_pcm_substream *substream,
  125. struct snd_pcm_hw_params *params,
  126. struct dma_slave_config *slave_config);
  127. struct dma_chan *(*compat_request_channel)(
  128. struct snd_soc_pcm_runtime *rtd,
  129. struct snd_pcm_substream *substream);
  130. int (*process)(struct snd_pcm_substream *substream,
  131. int channel, unsigned long hwoff,
  132. void *buf, unsigned long bytes);
  133. dma_filter_fn compat_filter_fn;
  134. struct device *dma_dev;
  135. const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
  136. const struct snd_pcm_hardware *pcm_hardware;
  137. unsigned int prealloc_buffer_size;
  138. };
  139. int snd_dmaengine_pcm_register(struct device *dev,
  140. const struct snd_dmaengine_pcm_config *config,
  141. unsigned int flags);
  142. void snd_dmaengine_pcm_unregister(struct device *dev);
  143. int devm_snd_dmaengine_pcm_register(struct device *dev,
  144. const struct snd_dmaengine_pcm_config *config,
  145. unsigned int flags);
  146. int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
  147. struct snd_pcm_hw_params *params,
  148. struct dma_slave_config *slave_config);
  149. #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
  150. struct dmaengine_pcm {
  151. struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
  152. const struct snd_dmaengine_pcm_config *config;
  153. struct snd_soc_component component;
  154. unsigned int flags;
  155. };
  156. static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
  157. {
  158. return container_of(p, struct dmaengine_pcm, component);
  159. }
  160. #endif