diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:19 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:19 -0400 |
commit | 59338599d8e234bee671573972f13d0912d0f27c (patch) | |
tree | 576ca43f66073e94ab1f6288ffad3380bdb63cb3 | |
parent | e95e939d15d0b14d210d43553f58fb7cefe8d93c (diff) | |
parent | be87f75efed8248d74c8ec56e997de989ecc963e (diff) |
Merge remote-tracking branch 'asoc/topic/ep93xx' into asoc-next
-rw-r--r-- | sound/soc/cirrus/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/cirrus/ep93xx-ac97.c | 16 | ||||
-rw-r--r-- | sound/soc/cirrus/ep93xx-i2s.c | 16 | ||||
-rw-r--r-- | sound/soc/cirrus/ep93xx-pcm.c | 138 |
4 files changed, 21 insertions, 151 deletions
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 88143db7e753..2c20f01e1f7e 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config SND_EP93XX_SOC | 1 | config SND_EP93XX_SOC |
2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" | 2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" |
3 | depends on ARCH_EP93XX && SND_SOC | 3 | depends on ARCH_EP93XX && SND_SOC |
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 EP93xx I2S or AC97 interfaces. | 7 | the EP93xx I2S or AC97 interfaces. |
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 7798fbd5e81d..3f4f88877c84 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c | |||
@@ -314,22 +314,15 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, | |||
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | 316 | ||
317 | static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, | 317 | static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai) |
318 | struct snd_soc_dai *dai) | ||
319 | { | 318 | { |
320 | struct ep93xx_dma_data *dma_data; | 319 | dai->playback_dma_data = &ep93xx_ac97_pcm_out; |
320 | dai->capture_dma_data = &ep93xx_ac97_pcm_in; | ||
321 | 321 | ||
322 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
323 | dma_data = &ep93xx_ac97_pcm_out; | ||
324 | else | ||
325 | dma_data = &ep93xx_ac97_pcm_in; | ||
326 | |||
327 | snd_soc_dai_set_dma_data(dai, substream, dma_data); | ||
328 | return 0; | 322 | return 0; |
329 | } | 323 | } |
330 | 324 | ||
331 | static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { | 325 | static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { |
332 | .startup = ep93xx_ac97_startup, | ||
333 | .trigger = ep93xx_ac97_trigger, | 326 | .trigger = ep93xx_ac97_trigger, |
334 | }; | 327 | }; |
335 | 328 | ||
@@ -337,6 +330,7 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { | |||
337 | .name = "ep93xx-ac97", | 330 | .name = "ep93xx-ac97", |
338 | .id = 0, | 331 | .id = 0, |
339 | .ac97_control = 1, | 332 | .ac97_control = 1, |
333 | .probe = ep93xx_ac97_dai_probe, | ||
340 | .playback = { | 334 | .playback = { |
341 | .stream_name = "AC97 Playback", | 335 | .stream_name = "AC97 Playback", |
342 | .channels_min = 2, | 336 | .channels_min = 2, |
@@ -403,7 +397,6 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) | |||
403 | return 0; | 397 | return 0; |
404 | 398 | ||
405 | fail: | 399 | fail: |
406 | platform_set_drvdata(pdev, NULL); | ||
407 | ep93xx_ac97_info = NULL; | 400 | ep93xx_ac97_info = NULL; |
408 | dev_set_drvdata(&pdev->dev, NULL); | 401 | dev_set_drvdata(&pdev->dev, NULL); |
409 | return ret; | 402 | return ret; |
@@ -418,7 +411,6 @@ static int ep93xx_ac97_remove(struct platform_device *pdev) | |||
418 | /* disable the AC97 controller */ | 411 | /* disable the AC97 controller */ |
419 | ep93xx_ac97_write_reg(info, AC97GCR, 0); | 412 | ep93xx_ac97_write_reg(info, AC97GCR, 0); |
420 | 413 | ||
421 | platform_set_drvdata(pdev, NULL); | ||
422 | ep93xx_ac97_info = NULL; | 414 | ep93xx_ac97_info = NULL; |
423 | dev_set_drvdata(&pdev->dev, NULL); | 415 | dev_set_drvdata(&pdev->dev, NULL); |
424 | 416 | ||
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 5c1102e9e159..17ad70bca9fe 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c | |||
@@ -60,11 +60,10 @@ struct ep93xx_i2s_info { | |||
60 | struct clk *mclk; | 60 | struct clk *mclk; |
61 | struct clk *sclk; | 61 | struct clk *sclk; |
62 | struct clk *lrclk; | 62 | struct clk *lrclk; |
63 | struct ep93xx_dma_data *dma_data; | ||
64 | void __iomem *regs; | 63 | void __iomem *regs; |
65 | }; | 64 | }; |
66 | 65 | ||
67 | struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { | 66 | static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { |
68 | [SNDRV_PCM_STREAM_PLAYBACK] = { | 67 | [SNDRV_PCM_STREAM_PLAYBACK] = { |
69 | .name = "i2s-pcm-out", | 68 | .name = "i2s-pcm-out", |
70 | .port = EP93XX_DMA_I2S1, | 69 | .port = EP93XX_DMA_I2S1, |
@@ -139,15 +138,11 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) | |||
139 | } | 138 | } |
140 | } | 139 | } |
141 | 140 | ||
142 | static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, | 141 | static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) |
143 | struct snd_soc_dai *dai) | ||
144 | { | 142 | { |
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 143 | dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK]; |
146 | struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); | 144 | dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; |
147 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
148 | 145 | ||
149 | snd_soc_dai_set_dma_data(cpu_dai, substream, | ||
150 | &info->dma_data[substream->stream]); | ||
151 | return 0; | 146 | return 0; |
152 | } | 147 | } |
153 | 148 | ||
@@ -338,7 +333,6 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai) | |||
338 | #endif | 333 | #endif |
339 | 334 | ||
340 | static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { | 335 | static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { |
341 | .startup = ep93xx_i2s_startup, | ||
342 | .shutdown = ep93xx_i2s_shutdown, | 336 | .shutdown = ep93xx_i2s_shutdown, |
343 | .hw_params = ep93xx_i2s_hw_params, | 337 | .hw_params = ep93xx_i2s_hw_params, |
344 | .set_sysclk = ep93xx_i2s_set_sysclk, | 338 | .set_sysclk = ep93xx_i2s_set_sysclk, |
@@ -349,6 +343,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { | |||
349 | 343 | ||
350 | static struct snd_soc_dai_driver ep93xx_i2s_dai = { | 344 | static struct snd_soc_dai_driver ep93xx_i2s_dai = { |
351 | .symmetric_rates= 1, | 345 | .symmetric_rates= 1, |
346 | .probe = ep93xx_i2s_dai_probe, | ||
352 | .suspend = ep93xx_i2s_suspend, | 347 | .suspend = ep93xx_i2s_suspend, |
353 | .resume = ep93xx_i2s_resume, | 348 | .resume = ep93xx_i2s_resume, |
354 | .playback = { | 349 | .playback = { |
@@ -407,7 +402,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) | |||
407 | } | 402 | } |
408 | 403 | ||
409 | dev_set_drvdata(&pdev->dev, info); | 404 | dev_set_drvdata(&pdev->dev, info); |
410 | info->dma_data = ep93xx_i2s_dma_data; | ||
411 | 405 | ||
412 | err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, | 406 | err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, |
413 | &ep93xx_i2s_dai, 1); | 407 | &ep93xx_i2s_dai, 1); |
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 488032690378..0e9f56e0d4b2 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c | |||
@@ -14,20 +14,14 @@ | |||
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/dmaengine.h> | 18 | #include <linux/dmaengine.h> |
20 | #include <linux/dma-mapping.h> | ||
21 | 19 | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
26 | #include <sound/dmaengine_pcm.h> | 22 | #include <sound/dmaengine_pcm.h> |
27 | 23 | ||
28 | #include <linux/platform_data/dma-ep93xx.h> | 24 | #include <linux/platform_data/dma-ep93xx.h> |
29 | #include <mach/hardware.h> | ||
30 | #include <mach/ep93xx-regs.h> | ||
31 | 25 | ||
32 | static const struct snd_pcm_hardware ep93xx_pcm_hardware = { | 26 | static const struct snd_pcm_hardware ep93xx_pcm_hardware = { |
33 | .info = (SNDRV_PCM_INFO_MMAP | | 27 | .info = (SNDRV_PCM_INFO_MMAP | |
@@ -63,134 +57,24 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) | |||
63 | return false; | 57 | return false; |
64 | } | 58 | } |
65 | 59 | ||
66 | static int ep93xx_pcm_open(struct snd_pcm_substream *substream) | 60 | static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = { |
67 | { | 61 | .pcm_hardware = &ep93xx_pcm_hardware, |
68 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 62 | .compat_filter_fn = ep93xx_pcm_dma_filter, |
69 | 63 | .prealloc_buffer_size = 131072, | |
70 | snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); | ||
71 | |||
72 | return snd_dmaengine_pcm_open_request_chan(substream, | ||
73 | ep93xx_pcm_dma_filter, | ||
74 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); | ||
75 | } | ||
76 | |||
77 | static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, | ||
78 | struct snd_pcm_hw_params *params) | ||
79 | { | ||
80 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream) | ||
86 | { | ||
87 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, | ||
92 | struct vm_area_struct *vma) | ||
93 | { | ||
94 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
95 | |||
96 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
97 | runtime->dma_area, | ||
98 | runtime->dma_addr, | ||
99 | runtime->dma_bytes); | ||
100 | } | ||
101 | |||
102 | static struct snd_pcm_ops ep93xx_pcm_ops = { | ||
103 | .open = ep93xx_pcm_open, | ||
104 | .close = snd_dmaengine_pcm_close_release_chan, | ||
105 | .ioctl = snd_pcm_lib_ioctl, | ||
106 | .hw_params = ep93xx_pcm_hw_params, | ||
107 | .hw_free = ep93xx_pcm_hw_free, | ||
108 | .trigger = snd_dmaengine_pcm_trigger, | ||
109 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
110 | .mmap = ep93xx_pcm_mmap, | ||
111 | }; | ||
112 | |||
113 | static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
114 | { | ||
115 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
116 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
117 | size_t size = ep93xx_pcm_hardware.buffer_bytes_max; | ||
118 | |||
119 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
120 | buf->dev.dev = pcm->card->dev; | ||
121 | buf->private_data = NULL; | ||
122 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
123 | &buf->addr, GFP_KERNEL); | ||
124 | buf->bytes = size; | ||
125 | |||
126 | return (buf->area == NULL) ? -ENOMEM : 0; | ||
127 | } | ||
128 | |||
129 | static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
130 | { | ||
131 | struct snd_pcm_substream *substream; | ||
132 | struct snd_dma_buffer *buf; | ||
133 | int stream; | ||
134 | |||
135 | for (stream = 0; stream < 2; stream++) { | ||
136 | substream = pcm->streams[stream].substream; | ||
137 | if (!substream) | ||
138 | continue; | ||
139 | |||
140 | buf = &substream->dma_buffer; | ||
141 | if (!buf->area) | ||
142 | continue; | ||
143 | |||
144 | dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, | ||
145 | buf->addr); | ||
146 | buf->area = NULL; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32); | ||
151 | |||
152 | static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
153 | { | ||
154 | struct snd_card *card = rtd->card->snd_card; | ||
155 | struct snd_pcm *pcm = rtd->pcm; | ||
156 | int ret = 0; | ||
157 | |||
158 | if (!card->dev->dma_mask) | ||
159 | card->dev->dma_mask = &ep93xx_pcm_dmamask; | ||
160 | if (!card->dev->coherent_dma_mask) | ||
161 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
162 | |||
163 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
164 | ret = ep93xx_pcm_preallocate_dma_buffer(pcm, | ||
165 | SNDRV_PCM_STREAM_PLAYBACK); | ||
166 | if (ret) | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
171 | ret = ep93xx_pcm_preallocate_dma_buffer(pcm, | ||
172 | SNDRV_PCM_STREAM_CAPTURE); | ||
173 | if (ret) | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static struct snd_soc_platform_driver ep93xx_soc_platform = { | ||
181 | .ops = &ep93xx_pcm_ops, | ||
182 | .pcm_new = &ep93xx_pcm_new, | ||
183 | .pcm_free = &ep93xx_pcm_free_dma_buffers, | ||
184 | }; | 64 | }; |
185 | 65 | ||
186 | static int ep93xx_soc_platform_probe(struct platform_device *pdev) | 66 | static int ep93xx_soc_platform_probe(struct platform_device *pdev) |
187 | { | 67 | { |
188 | return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform); | 68 | return snd_dmaengine_pcm_register(&pdev->dev, |
69 | &ep93xx_dmaengine_pcm_config, | ||
70 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
71 | SND_DMAENGINE_PCM_FLAG_NO_DT | | ||
72 | SND_DMAENGINE_PCM_FLAG_COMPAT); | ||
189 | } | 73 | } |
190 | 74 | ||
191 | static int ep93xx_soc_platform_remove(struct platform_device *pdev) | 75 | static int ep93xx_soc_platform_remove(struct platform_device *pdev) |
192 | { | 76 | { |
193 | snd_soc_unregister_platform(&pdev->dev); | 77 | snd_dmaengine_pcm_unregister(&pdev->dev); |
194 | return 0; | 78 | return 0; |
195 | } | 79 | } |
196 | 80 | ||