0001
0002
0003
0004
0005
0006
0007 #ifndef __SOUND_DMAENGINE_PCM_H__
0008 #define __SOUND_DMAENGINE_PCM_H__
0009
0010 #include <sound/pcm.h>
0011 #include <sound/soc.h>
0012 #include <linux/dmaengine.h>
0013
0014
0015
0016
0017
0018
0019
0020
0021 static inline enum dma_transfer_direction
0022 snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
0023 {
0024 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0025 return DMA_MEM_TO_DEV;
0026 else
0027 return DMA_DEV_TO_MEM;
0028 }
0029
0030 int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
0031 const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
0032 int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
0033 snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
0034 snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
0035
0036 int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
0037 struct dma_chan *chan);
0038 int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
0039
0040 int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
0041 dma_filter_fn filter_fn, void *filter_data);
0042 int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
0043
0044 struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
0045 void *filter_data);
0046 struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 #define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 struct snd_dmaengine_dai_dma_data {
0075 dma_addr_t addr;
0076 enum dma_slave_buswidth addr_width;
0077 u32 maxburst;
0078 void *filter_data;
0079 const char *chan_name;
0080 unsigned int fifo_size;
0081 unsigned int flags;
0082 void *peripheral_config;
0083 size_t peripheral_size;
0084 };
0085
0086 void snd_dmaengine_pcm_set_config_from_dai_data(
0087 const struct snd_pcm_substream *substream,
0088 const struct snd_dmaengine_dai_dma_data *dma_data,
0089 struct dma_slave_config *config);
0090
0091 int snd_dmaengine_pcm_refine_runtime_hwparams(
0092 struct snd_pcm_substream *substream,
0093 struct snd_dmaengine_dai_dma_data *dma_data,
0094 struct snd_pcm_hardware *hw,
0095 struct dma_chan *chan);
0096
0097
0098
0099
0100
0101 #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
0102
0103
0104
0105
0106 #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
0107
0108
0109
0110
0111 #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 struct snd_dmaengine_pcm_config {
0137 int (*prepare_slave_config)(struct snd_pcm_substream *substream,
0138 struct snd_pcm_hw_params *params,
0139 struct dma_slave_config *slave_config);
0140 struct dma_chan *(*compat_request_channel)(
0141 struct snd_soc_pcm_runtime *rtd,
0142 struct snd_pcm_substream *substream);
0143 int (*process)(struct snd_pcm_substream *substream,
0144 int channel, unsigned long hwoff,
0145 void *buf, unsigned long bytes);
0146 dma_filter_fn compat_filter_fn;
0147 struct device *dma_dev;
0148 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
0149
0150 const struct snd_pcm_hardware *pcm_hardware;
0151 unsigned int prealloc_buffer_size;
0152 };
0153
0154 int snd_dmaengine_pcm_register(struct device *dev,
0155 const struct snd_dmaengine_pcm_config *config,
0156 unsigned int flags);
0157 void snd_dmaengine_pcm_unregister(struct device *dev);
0158
0159 int devm_snd_dmaengine_pcm_register(struct device *dev,
0160 const struct snd_dmaengine_pcm_config *config,
0161 unsigned int flags);
0162
0163 int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
0164 struct snd_pcm_hw_params *params,
0165 struct dma_slave_config *slave_config);
0166
0167 #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
0168
0169 struct dmaengine_pcm {
0170 struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
0171 const struct snd_dmaengine_pcm_config *config;
0172 struct snd_soc_component component;
0173 unsigned int flags;
0174 };
0175
0176 static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
0177 {
0178 return container_of(p, struct dmaengine_pcm, component);
0179 }
0180 #endif