diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-04-25 07:02:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-25 07:02:35 -0400 |
commit | 2fc565e4eaf8fc633bfc741b90e1f28dba732ee1 (patch) | |
tree | 98c994692f84aee07cf1c7b4cda245ae5235a94d /sound | |
parent | 7fc7d047216aa4923d401c637be2ebc6e3d5bd9b (diff) | |
parent | 5cc50fc858a5ab37dc2744d72d7ffed96f23afd8 (diff) |
Merge tag 'asoc-v3.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: More updates for v3.10
A few more fixes, nothing too major though the DMA changes fix modular
builds.
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_native.c | 12 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 15 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.h | 2 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-pcm.c | 11 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-pcm.h | 1 | ||||
-rw-r--r-- | sound/soc/mxs/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/mxs/mxs-pcm.c | 139 | ||||
-rw-r--r-- | sound/soc/mxs/mxs-saif.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 44 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.h | 1 |
10 files changed, 64 insertions, 166 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 5bce9152b64e..23e3c46cd0a4 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -3235,18 +3235,10 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | |||
3235 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3235 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
3236 | struct vm_area_struct *area) | 3236 | struct vm_area_struct *area) |
3237 | { | 3237 | { |
3238 | long size; | 3238 | struct snd_pcm_runtime *runtime = substream->runtime;; |
3239 | unsigned long offset; | ||
3240 | 3239 | ||
3241 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3240 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
3242 | area->vm_flags |= VM_IO; | 3241 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); |
3243 | size = area->vm_end - area->vm_start; | ||
3244 | offset = area->vm_pgoff << PAGE_SHIFT; | ||
3245 | if (io_remap_pfn_range(area, area->vm_start, | ||
3246 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, | ||
3247 | size, area->vm_page_prot)) | ||
3248 | return -EAGAIN; | ||
3249 | return 0; | ||
3250 | } | 3242 | } |
3251 | 3243 | ||
3252 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | 3244 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index aeb3a6627d6a..8b85049daab0 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -636,11 +636,12 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
636 | * callback, take it into account here. That allows us to for example | 636 | * callback, take it into account here. That allows us to for example |
637 | * send 32 bits per channel to the codec, while only 16 of them carry | 637 | * send 32 bits per channel to the codec, while only 16 of them carry |
638 | * audio payload. | 638 | * audio payload. |
639 | * The clock ratio is given for a full period of data (both left and | 639 | * The clock ratio is given for a full period of data (for I2S format |
640 | * right channels), so it has to be divided by 2. | 640 | * both left and right channels), so it has to be divided by number of |
641 | * tdm-slots (for I2S - divided by 2). | ||
641 | */ | 642 | */ |
642 | if (dev->bclk_lrclk_ratio) | 643 | if (dev->bclk_lrclk_ratio) |
643 | word_length = dev->bclk_lrclk_ratio / 2; | 644 | word_length = dev->bclk_lrclk_ratio / dev->tdm_slots; |
644 | 645 | ||
645 | /* mapping of the XSSZ bit-field as described in the datasheet */ | 646 | /* mapping of the XSSZ bit-field as described in the datasheet */ |
646 | fmt = (word_length >> 1) - 1; | 647 | fmt = (word_length >> 1) - 1; |
@@ -834,17 +835,20 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
834 | int word_length; | 835 | int word_length; |
835 | u8 fifo_level; | 836 | u8 fifo_level; |
836 | u8 slots = dev->tdm_slots; | 837 | u8 slots = dev->tdm_slots; |
838 | u8 active_serializers; | ||
837 | int channels; | 839 | int channels; |
838 | struct snd_interval *pcm_channels = hw_param_interval(params, | 840 | struct snd_interval *pcm_channels = hw_param_interval(params, |
839 | SNDRV_PCM_HW_PARAM_CHANNELS); | 841 | SNDRV_PCM_HW_PARAM_CHANNELS); |
840 | channels = pcm_channels->min; | 842 | channels = pcm_channels->min; |
841 | 843 | ||
844 | active_serializers = (channels + slots - 1) / slots; | ||
845 | |||
842 | if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL) | 846 | if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL) |
843 | return -EINVAL; | 847 | return -EINVAL; |
844 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 848 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
845 | fifo_level = dev->txnumevt; | 849 | fifo_level = dev->txnumevt * active_serializers; |
846 | else | 850 | else |
847 | fifo_level = dev->rxnumevt; | 851 | fifo_level = dev->rxnumevt * active_serializers; |
848 | 852 | ||
849 | if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) | 853 | if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) |
850 | davinci_hw_dit_param(dev); | 854 | davinci_hw_dit_param(dev); |
@@ -889,7 +893,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
889 | dma_params->acnt = dma_params->data_type; | 893 | dma_params->acnt = dma_params->data_type; |
890 | 894 | ||
891 | dma_params->fifo_level = fifo_level; | 895 | dma_params->fifo_level = fifo_level; |
892 | dma_params->active_serializers = (channels + slots - 1) / slots; | ||
893 | davinci_config_channel_size(dev, word_length); | 896 | davinci_config_channel_size(dev, word_length); |
894 | 897 | ||
895 | return 0; | 898 | return 0; |
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 0edd3b5a37fd..a9ac0c11da71 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -38,7 +38,7 @@ struct davinci_audio_dev { | |||
38 | u8 num_serializer; | 38 | u8 num_serializer; |
39 | u8 *serial_dir; | 39 | u8 *serial_dir; |
40 | u8 version; | 40 | u8 version; |
41 | u8 bclk_lrclk_ratio; | 41 | u16 bclk_lrclk_ratio; |
42 | 42 | ||
43 | /* McASP FIFO related */ | 43 | /* McASP FIFO related */ |
44 | u8 txnumevt; | 44 | u8 txnumevt; |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 078031d61167..b2f27c2e5fdc 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -181,7 +181,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
181 | unsigned short acnt; | 181 | unsigned short acnt; |
182 | unsigned int count; | 182 | unsigned int count; |
183 | unsigned int fifo_level; | 183 | unsigned int fifo_level; |
184 | unsigned char serializers = prtd->params->active_serializers; | ||
185 | 184 | ||
186 | period_size = snd_pcm_lib_period_bytes(substream); | 185 | period_size = snd_pcm_lib_period_bytes(substream); |
187 | dma_offset = prtd->period * period_size; | 186 | dma_offset = prtd->period * period_size; |
@@ -195,14 +194,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
195 | data_type = prtd->params->data_type; | 194 | data_type = prtd->params->data_type; |
196 | count = period_size / data_type; | 195 | count = period_size / data_type; |
197 | if (fifo_level) | 196 | if (fifo_level) |
198 | count /= fifo_level * serializers; | 197 | count /= fifo_level; |
199 | 198 | ||
200 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 199 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
201 | src = dma_pos; | 200 | src = dma_pos; |
202 | dst = prtd->params->dma_addr; | 201 | dst = prtd->params->dma_addr; |
203 | src_bidx = data_type; | 202 | src_bidx = data_type; |
204 | dst_bidx = 4; | 203 | dst_bidx = 4; |
205 | src_cidx = data_type * fifo_level * serializers; | 204 | src_cidx = data_type * fifo_level; |
206 | dst_cidx = 0; | 205 | dst_cidx = 0; |
207 | } else { | 206 | } else { |
208 | src = prtd->params->dma_addr; | 207 | src = prtd->params->dma_addr; |
@@ -210,7 +209,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
210 | src_bidx = 0; | 209 | src_bidx = 0; |
211 | dst_bidx = data_type; | 210 | dst_bidx = data_type; |
212 | src_cidx = 0; | 211 | src_cidx = 0; |
213 | dst_cidx = data_type * fifo_level * serializers; | 212 | dst_cidx = data_type * fifo_level; |
214 | } | 213 | } |
215 | 214 | ||
216 | acnt = prtd->params->acnt; | 215 | acnt = prtd->params->acnt; |
@@ -225,8 +224,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
225 | ASYNC); | 224 | ASYNC); |
226 | else | 225 | else |
227 | edma_set_transfer_params(prtd->asp_link[0], acnt, | 226 | edma_set_transfer_params(prtd->asp_link[0], acnt, |
228 | fifo_level * serializers, | 227 | fifo_level, |
229 | count, fifo_level * serializers, | 228 | count, fifo_level, |
230 | ABSYNC); | 229 | ABSYNC); |
231 | } | 230 | } |
232 | 231 | ||
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index 32d7634d7b26..b6ef7039dd09 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h | |||
@@ -27,7 +27,6 @@ struct davinci_pcm_dma_params { | |||
27 | unsigned char data_type; /* xfer data type */ | 27 | unsigned char data_type; /* xfer data type */ |
28 | unsigned char convert_mono_stereo; | 28 | unsigned char convert_mono_stereo; |
29 | unsigned int fifo_level; | 29 | unsigned int fifo_level; |
30 | unsigned char active_serializers; /* num. of active audio serializers */ | ||
31 | }; | 30 | }; |
32 | 31 | ||
33 | int davinci_soc_platform_register(struct device *dev); | 32 | int davinci_soc_platform_register(struct device *dev); |
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index b6fa77678d97..78d321cbe8b4 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | menuconfig SND_MXS_SOC | 1 | menuconfig SND_MXS_SOC |
2 | tristate "SoC Audio for Freescale MXS CPUs" | 2 | tristate "SoC Audio for Freescale MXS CPUs" |
3 | depends on ARCH_MXS | 3 | depends on ARCH_MXS |
4 | select SND_SOC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the MXS SAIF interface. | 7 | the MXS SAIF interface. |
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 7bceb16d0fd9..b41fffc056fb 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c | |||
@@ -18,32 +18,24 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/device.h> | 21 | #include <linux/device.h> |
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/init.h> | 22 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/module.h> | 23 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/dmaengine.h> | ||
31 | 24 | ||
32 | #include <sound/core.h> | 25 | #include <sound/core.h> |
33 | #include <sound/initval.h> | ||
34 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
35 | #include <sound/pcm_params.h> | ||
36 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
37 | #include <sound/dmaengine_pcm.h> | 28 | #include <sound/dmaengine_pcm.h> |
38 | 29 | ||
39 | #include "mxs-pcm.h" | 30 | #include "mxs-pcm.h" |
40 | 31 | ||
41 | static struct snd_pcm_hardware snd_mxs_hardware = { | 32 | static const struct snd_pcm_hardware snd_mxs_hardware = { |
42 | .info = SNDRV_PCM_INFO_MMAP | | 33 | .info = SNDRV_PCM_INFO_MMAP | |
43 | SNDRV_PCM_INFO_MMAP_VALID | | 34 | SNDRV_PCM_INFO_MMAP_VALID | |
44 | SNDRV_PCM_INFO_PAUSE | | 35 | SNDRV_PCM_INFO_PAUSE | |
45 | SNDRV_PCM_INFO_RESUME | | 36 | SNDRV_PCM_INFO_RESUME | |
46 | SNDRV_PCM_INFO_INTERLEAVED, | 37 | SNDRV_PCM_INFO_INTERLEAVED | |
38 | SNDRV_PCM_INFO_HALF_DUPLEX, | ||
47 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 39 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
48 | SNDRV_PCM_FMTBIT_S20_3LE | | 40 | SNDRV_PCM_FMTBIT_S20_3LE | |
49 | SNDRV_PCM_FMTBIT_S24_LE, | 41 | SNDRV_PCM_FMTBIT_S24_LE, |
@@ -55,7 +47,6 @@ static struct snd_pcm_hardware snd_mxs_hardware = { | |||
55 | .periods_max = 52, | 47 | .periods_max = 52, |
56 | .buffer_bytes_max = 64 * 1024, | 48 | .buffer_bytes_max = 64 * 1024, |
57 | .fifo_size = 32, | 49 | .fifo_size = 32, |
58 | |||
59 | }; | 50 | }; |
60 | 51 | ||
61 | static bool filter(struct dma_chan *chan, void *param) | 52 | static bool filter(struct dma_chan *chan, void *param) |
@@ -73,129 +64,25 @@ static bool filter(struct dma_chan *chan, void *param) | |||
73 | return true; | 64 | return true; |
74 | } | 65 | } |
75 | 66 | ||
76 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, | 67 | static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { |
77 | struct snd_pcm_hw_params *params) | 68 | .pcm_hardware = &snd_mxs_hardware, |
78 | { | 69 | .compat_filter_fn = filter, |
79 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 70 | .prealloc_buffer_size = 64 * 1024, |
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int snd_mxs_open(struct snd_pcm_substream *substream) | ||
85 | { | ||
86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
87 | |||
88 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); | ||
89 | |||
90 | return snd_dmaengine_pcm_open_request_chan(substream, filter, | ||
91 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); | ||
92 | } | ||
93 | |||
94 | static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, | ||
95 | struct vm_area_struct *vma) | ||
96 | { | ||
97 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
98 | |||
99 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
100 | runtime->dma_area, | ||
101 | runtime->dma_addr, | ||
102 | runtime->dma_bytes); | ||
103 | } | ||
104 | |||
105 | static struct snd_pcm_ops mxs_pcm_ops = { | ||
106 | .open = snd_mxs_open, | ||
107 | .close = snd_dmaengine_pcm_close_release_chan, | ||
108 | .ioctl = snd_pcm_lib_ioctl, | ||
109 | .hw_params = snd_mxs_pcm_hw_params, | ||
110 | .trigger = snd_dmaengine_pcm_trigger, | ||
111 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
112 | .mmap = snd_mxs_pcm_mmap, | ||
113 | }; | ||
114 | |||
115 | static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
116 | { | ||
117 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
118 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
119 | size_t size = snd_mxs_hardware.buffer_bytes_max; | ||
120 | |||
121 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
122 | buf->dev.dev = pcm->card->dev; | ||
123 | buf->private_data = NULL; | ||
124 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
125 | &buf->addr, GFP_KERNEL); | ||
126 | if (!buf->area) | ||
127 | return -ENOMEM; | ||
128 | buf->bytes = size; | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32); | ||
134 | static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
135 | { | ||
136 | struct snd_card *card = rtd->card->snd_card; | ||
137 | struct snd_pcm *pcm = rtd->pcm; | ||
138 | int ret = 0; | ||
139 | |||
140 | if (!card->dev->dma_mask) | ||
141 | card->dev->dma_mask = &mxs_pcm_dmamask; | ||
142 | if (!card->dev->coherent_dma_mask) | ||
143 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
144 | |||
145 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
146 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
147 | SNDRV_PCM_STREAM_PLAYBACK); | ||
148 | if (ret) | ||
149 | goto out; | ||
150 | } | ||
151 | |||
152 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
153 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
154 | SNDRV_PCM_STREAM_CAPTURE); | ||
155 | if (ret) | ||
156 | goto out; | ||
157 | } | ||
158 | |||
159 | out: | ||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | static void mxs_pcm_free(struct snd_pcm *pcm) | ||
164 | { | ||
165 | struct snd_pcm_substream *substream; | ||
166 | struct snd_dma_buffer *buf; | ||
167 | int stream; | ||
168 | |||
169 | for (stream = 0; stream < 2; stream++) { | ||
170 | substream = pcm->streams[stream].substream; | ||
171 | if (!substream) | ||
172 | continue; | ||
173 | |||
174 | buf = &substream->dma_buffer; | ||
175 | if (!buf->area) | ||
176 | continue; | ||
177 | |||
178 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
179 | buf->area, buf->addr); | ||
180 | buf->area = NULL; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static struct snd_soc_platform_driver mxs_soc_platform = { | ||
185 | .ops = &mxs_pcm_ops, | ||
186 | .pcm_new = mxs_pcm_new, | ||
187 | .pcm_free = mxs_pcm_free, | ||
188 | }; | 71 | }; |
189 | 72 | ||
190 | int mxs_pcm_platform_register(struct device *dev) | 73 | int mxs_pcm_platform_register(struct device *dev) |
191 | { | 74 | { |
192 | return snd_soc_register_platform(dev, &mxs_soc_platform); | 75 | return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, |
76 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
77 | SND_DMAENGINE_PCM_FLAG_NO_DT | | ||
78 | SND_DMAENGINE_PCM_FLAG_COMPAT | | ||
79 | SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); | ||
193 | } | 80 | } |
194 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); | 81 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); |
195 | 82 | ||
196 | void mxs_pcm_platform_unregister(struct device *dev) | 83 | void mxs_pcm_platform_unregister(struct device *dev) |
197 | { | 84 | { |
198 | snd_soc_unregister_platform(dev); | 85 | snd_dmaengine_pcm_unregister(dev); |
199 | } | 86 | } |
200 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); | 87 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); |
201 | 88 | ||
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index abf4ddf4ed89..b563141a6543 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -369,7 +369,6 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, | |||
369 | struct snd_soc_dai *cpu_dai) | 369 | struct snd_soc_dai *cpu_dai) |
370 | { | 370 | { |
371 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | 371 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); |
372 | snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param); | ||
373 | 372 | ||
374 | /* clear error status to 0 for each re-open */ | 373 | /* clear error status to 0 for each re-open */ |
375 | saif->fifo_underrun = 0; | 374 | saif->fifo_underrun = 0; |
@@ -605,6 +604,8 @@ static int mxs_saif_dai_probe(struct snd_soc_dai *dai) | |||
605 | struct mxs_saif *saif = dev_get_drvdata(dai->dev); | 604 | struct mxs_saif *saif = dev_get_drvdata(dai->dev); |
606 | 605 | ||
607 | snd_soc_dai_set_drvdata(dai, saif); | 606 | snd_soc_dai_set_drvdata(dai, saif); |
607 | dai->playback_dma_data = &saif->dma_param; | ||
608 | dai->capture_dma_data = &saif->dma_param; | ||
608 | 609 | ||
609 | return 0; | 610 | return 0; |
610 | } | 611 | } |
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index ae0c37e66ae0..e29ec3cd84b1 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_dma.h> | ||
25 | 24 | ||
26 | #include <sound/dmaengine_pcm.h> | 25 | #include <sound/dmaengine_pcm.h> |
27 | 26 | ||
@@ -29,7 +28,7 @@ struct dmaengine_pcm { | |||
29 | struct dma_chan *chan[SNDRV_PCM_STREAM_CAPTURE + 1]; | 28 | struct dma_chan *chan[SNDRV_PCM_STREAM_CAPTURE + 1]; |
30 | const struct snd_dmaengine_pcm_config *config; | 29 | const struct snd_dmaengine_pcm_config *config; |
31 | struct snd_soc_platform platform; | 30 | struct snd_soc_platform platform; |
32 | bool compat; | 31 | unsigned int flags; |
33 | }; | 32 | }; |
34 | 33 | ||
35 | static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) | 34 | static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) |
@@ -128,6 +127,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( | |||
128 | { | 127 | { |
129 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | 128 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); |
130 | 129 | ||
130 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) | ||
131 | return pcm->chan[0]; | ||
132 | |||
131 | if (pcm->config->compat_request_channel) | 133 | if (pcm->config->compat_request_channel) |
132 | return pcm->config->compat_request_channel(rtd, substream); | 134 | return pcm->config->compat_request_channel(rtd, substream); |
133 | 135 | ||
@@ -148,7 +150,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
148 | if (!substream) | 150 | if (!substream) |
149 | continue; | 151 | continue; |
150 | 152 | ||
151 | if (!pcm->chan[i] && pcm->compat) { | 153 | if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) { |
152 | pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, | 154 | pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, |
153 | substream); | 155 | substream); |
154 | } | 156 | } |
@@ -215,6 +217,25 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { | |||
215 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", | 217 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", |
216 | }; | 218 | }; |
217 | 219 | ||
220 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | ||
221 | struct device *dev) | ||
222 | { | ||
223 | unsigned int i; | ||
224 | |||
225 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || !dev->of_node) | ||
226 | return; | ||
227 | |||
228 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) { | ||
229 | pcm->chan[0] = dma_request_slave_channel(dev, "rx-tx"); | ||
230 | pcm->chan[1] = pcm->chan[0]; | ||
231 | } else { | ||
232 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
233 | pcm->chan[i] = dma_request_slave_channel(dev, | ||
234 | dmaengine_pcm_dma_channel_names[i]); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
218 | /** | 239 | /** |
219 | * snd_dmaengine_pcm_register - Register a dmaengine based PCM device | 240 | * snd_dmaengine_pcm_register - Register a dmaengine based PCM device |
220 | * @dev: The parent device for the PCM device | 241 | * @dev: The parent device for the PCM device |
@@ -225,23 +246,15 @@ int snd_dmaengine_pcm_register(struct device *dev, | |||
225 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) | 246 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) |
226 | { | 247 | { |
227 | struct dmaengine_pcm *pcm; | 248 | struct dmaengine_pcm *pcm; |
228 | unsigned int i; | ||
229 | 249 | ||
230 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | 250 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); |
231 | if (!pcm) | 251 | if (!pcm) |
232 | return -ENOMEM; | 252 | return -ENOMEM; |
233 | 253 | ||
234 | pcm->config = config; | 254 | pcm->config = config; |
255 | pcm->flags = flags; | ||
235 | 256 | ||
236 | if (flags & SND_DMAENGINE_PCM_FLAG_COMPAT) | 257 | dmaengine_pcm_request_chan_of(pcm, dev); |
237 | pcm->compat = true; | ||
238 | |||
239 | if (!(flags & SND_DMAENGINE_PCM_FLAG_NO_DT) && dev->of_node) { | ||
240 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
241 | pcm->chan[i] = of_dma_request_slave_channel(dev->of_node, | ||
242 | dmaengine_pcm_dma_channel_names[i]); | ||
243 | } | ||
244 | } | ||
245 | 258 | ||
246 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) | 259 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
247 | return snd_soc_add_platform(dev, &pcm->platform, | 260 | return snd_soc_add_platform(dev, &pcm->platform, |
@@ -272,8 +285,11 @@ void snd_dmaengine_pcm_unregister(struct device *dev) | |||
272 | pcm = soc_platform_to_pcm(platform); | 285 | pcm = soc_platform_to_pcm(platform); |
273 | 286 | ||
274 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | 287 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { |
275 | if (pcm->chan[i]) | 288 | if (pcm->chan[i]) { |
276 | dma_release_channel(pcm->chan[i]); | 289 | dma_release_channel(pcm->chan[i]); |
290 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | ||
291 | break; | ||
292 | } | ||
277 | } | 293 | } |
278 | 294 | ||
279 | snd_soc_remove_platform(platform); | 295 | snd_soc_remove_platform(platform); |
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 1311c0df7628..6f3e3dccbcb6 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -543,6 +543,7 @@ struct ux500_msp_dma_params { | |||
543 | struct stedma40_chan_cfg *dma_cfg; | 543 | struct stedma40_chan_cfg *dma_cfg; |
544 | }; | 544 | }; |
545 | 545 | ||
546 | struct msp_i2s_platform_data; | ||
546 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, | 547 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, |
547 | struct ux500_msp **msp_p, | 548 | struct ux500_msp **msp_p, |
548 | struct msp_i2s_platform_data *platform_data); | 549 | struct msp_i2s_platform_data *platform_data); |