aboutsummaryrefslogtreecommitdiffstats
path: root/sound/arm
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-26 09:52:54 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-26 09:52:54 -0500
commit7f50548abb5454bd82c25aae15f0a3bf6a530f46 (patch)
tree175b5d695437151f0f9f778ad8eb7f274468842f /sound/arm
parentb3172f222ab5afdc91ea058bd11c42cf169728f3 (diff)
parent6b7b284958d47b77d06745b36bc7f36dab769d9b (diff)
Merge commit 'v2.6.33-rc2' into for-2.6.33
Diffstat (limited to 'sound/arm')
-rw-r--r--sound/arm/Makefile2
-rw-r--r--sound/arm/aaci.c204
-rw-r--r--sound/arm/aaci.h2
-rw-r--r--sound/arm/devdma.c80
-rw-r--r--sound/arm/devdma.h3
-rw-r--r--sound/arm/pxa2xx-ac97.c2
6 files changed, 70 insertions, 223 deletions
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
index 5a549ed6c8aa..8c0c851d4641 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o 5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
6snd-aaci-objs := aaci.o devdma.o 6snd-aaci-objs := aaci.o
7 7
8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o 8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o 9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 1f0f8213e2d5..c5699863643b 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -18,10 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/amba/bus.h> 20#include <linux/amba/bus.h>
21 21#include <linux/io.h>
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/sizes.h>
25 22
26#include <sound/core.h> 23#include <sound/core.h>
27#include <sound/initval.h> 24#include <sound/initval.h>
@@ -30,7 +27,6 @@
30#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
31 28
32#include "aaci.h" 29#include "aaci.h"
33#include "devdma.h"
34 30
35#define DRIVER_NAME "aaci-pl041" 31#define DRIVER_NAME "aaci-pl041"
36 32
@@ -176,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
176 return v; 172 return v;
177} 173}
178 174
179static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) 175static inline void
176aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
180{ 177{
181 u32 val; 178 u32 val;
182 int timeout = 5000; 179 int timeout = 5000;
183 180
184 do { 181 do {
185 val = readl(aacirun->base + AACI_SR); 182 val = readl(aacirun->base + AACI_SR);
186 } while (val & (SR_TXB|SR_RXB) && timeout--); 183 } while (val & mask && timeout--);
187} 184}
188 185
189 186
@@ -212,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
212 writel(0, aacirun->base + AACI_IE); 209 writel(0, aacirun->base + AACI_IE);
213 return; 210 return;
214 } 211 }
215 ptr = aacirun->ptr;
216 212
213 spin_lock(&aacirun->lock);
214
215 ptr = aacirun->ptr;
217 do { 216 do {
218 unsigned int len = aacirun->fifosz; 217 unsigned int len = aacirun->fifosz;
219 u32 val; 218 u32 val;
@@ -221,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
221 if (aacirun->bytes <= 0) { 220 if (aacirun->bytes <= 0) {
222 aacirun->bytes += aacirun->period; 221 aacirun->bytes += aacirun->period;
223 aacirun->ptr = ptr; 222 aacirun->ptr = ptr;
224 spin_unlock(&aaci->lock); 223 spin_unlock(&aacirun->lock);
225 snd_pcm_period_elapsed(aacirun->substream); 224 snd_pcm_period_elapsed(aacirun->substream);
226 spin_lock(&aaci->lock); 225 spin_lock(&aacirun->lock);
227 } 226 }
228 if (!(aacirun->cr & CR_EN)) 227 if (!(aacirun->cr & CR_EN))
229 break; 228 break;
@@ -249,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
249 ptr = aacirun->start; 248 ptr = aacirun->start;
250 } 249 }
251 } while(1); 250 } while(1);
251
252 aacirun->ptr = ptr; 252 aacirun->ptr = ptr;
253
254 spin_unlock(&aacirun->lock);
253 } 255 }
254 256
255 if (mask & ISR_URINTR) { 257 if (mask & ISR_URINTR) {
@@ -267,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
267 return; 269 return;
268 } 270 }
269 271
272 spin_lock(&aacirun->lock);
273
270 ptr = aacirun->ptr; 274 ptr = aacirun->ptr;
271 do { 275 do {
272 unsigned int len = aacirun->fifosz; 276 unsigned int len = aacirun->fifosz;
@@ -275,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
275 if (aacirun->bytes <= 0) { 279 if (aacirun->bytes <= 0) {
276 aacirun->bytes += aacirun->period; 280 aacirun->bytes += aacirun->period;
277 aacirun->ptr = ptr; 281 aacirun->ptr = ptr;
278 spin_unlock(&aaci->lock); 282 spin_unlock(&aacirun->lock);
279 snd_pcm_period_elapsed(aacirun->substream); 283 snd_pcm_period_elapsed(aacirun->substream);
280 spin_lock(&aaci->lock); 284 spin_lock(&aacirun->lock);
281 } 285 }
282 if (!(aacirun->cr & CR_EN)) 286 if (!(aacirun->cr & CR_EN))
283 break; 287 break;
@@ -305,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
305 } while (1); 309 } while (1);
306 310
307 aacirun->ptr = ptr; 311 aacirun->ptr = ptr;
312
313 spin_unlock(&aacirun->lock);
308 } 314 }
309} 315}
310 316
@@ -314,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
314 u32 mask; 320 u32 mask;
315 int i; 321 int i;
316 322
317 spin_lock(&aaci->lock);
318 mask = readl(aaci->base + AACI_ALLINTS); 323 mask = readl(aaci->base + AACI_ALLINTS);
319 if (mask) { 324 if (mask) {
320 u32 m = mask; 325 u32 m = mask;
@@ -324,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
324 } 329 }
325 } 330 }
326 } 331 }
327 spin_unlock(&aaci->lock);
328 332
329 return mask ? IRQ_HANDLED : IRQ_NONE; 333 return mask ? IRQ_HANDLED : IRQ_NONE;
330} 334}
@@ -334,63 +338,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
334/* 338/*
335 * ALSA support. 339 * ALSA support.
336 */ 340 */
337
338struct aaci_stream {
339 unsigned char codec_idx;
340 unsigned char rate_idx;
341};
342
343static struct aaci_stream aaci_streams[] = {
344 [ACSTREAM_FRONT] = {
345 .codec_idx = 0,
346 .rate_idx = AC97_RATES_FRONT_DAC,
347 },
348 [ACSTREAM_SURROUND] = {
349 .codec_idx = 0,
350 .rate_idx = AC97_RATES_SURR_DAC,
351 },
352 [ACSTREAM_LFE] = {
353 .codec_idx = 0,
354 .rate_idx = AC97_RATES_LFE_DAC,
355 },
356};
357
358static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid)
359{
360 struct aaci_stream *s = aaci_streams + streamid;
361 return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx];
362}
363
364static unsigned int rate_list[] = {
365 5512, 8000, 11025, 16000, 22050, 32000, 44100,
366 48000, 64000, 88200, 96000, 176400, 192000
367};
368
369/*
370 * Double-rate rule: we can support double rate iff channels == 2
371 * (unimplemented)
372 */
373static int
374aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
375{
376 struct aaci *aaci = rule->private;
377 unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
378 struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
379
380 switch (c->max) {
381 case 6:
382 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE);
383 case 4:
384 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND);
385 case 2:
386 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT);
387 }
388
389 return snd_interval_list(hw_param_interval(p, rule->var),
390 ARRAY_SIZE(rate_list), rate_list,
391 rate_mask);
392}
393
394static struct snd_pcm_hardware aaci_hw_info = { 341static struct snd_pcm_hardware aaci_hw_info = {
395 .info = SNDRV_PCM_INFO_MMAP | 342 .info = SNDRV_PCM_INFO_MMAP |
396 SNDRV_PCM_INFO_MMAP_VALID | 343 SNDRV_PCM_INFO_MMAP_VALID |
@@ -404,10 +351,7 @@ static struct snd_pcm_hardware aaci_hw_info = {
404 */ 351 */
405 .formats = SNDRV_PCM_FMTBIT_S16_LE, 352 .formats = SNDRV_PCM_FMTBIT_S16_LE,
406 353
407 /* should this be continuous or knot? */ 354 /* rates are setup from the AC'97 codec */
408 .rates = SNDRV_PCM_RATE_CONTINUOUS,
409 .rate_max = 48000,
410 .rate_min = 4000,
411 .channels_min = 2, 355 .channels_min = 2,
412 .channels_max = 6, 356 .channels_max = 6,
413 .buffer_bytes_max = 64 * 1024, 357 .buffer_bytes_max = 64 * 1024,
@@ -427,6 +371,12 @@ static int __aaci_pcm_open(struct aaci *aaci,
427 aacirun->substream = substream; 371 aacirun->substream = substream;
428 runtime->private_data = aacirun; 372 runtime->private_data = aacirun;
429 runtime->hw = aaci_hw_info; 373 runtime->hw = aaci_hw_info;
374 runtime->hw.rates = aacirun->pcm->rates;
375 snd_pcm_limit_hw_rates(runtime);
376
377 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
378 aacirun->pcm->r[1].slots)
379 snd_ac97_pcm_double_rate_rules(runtime);
430 380
431 /* 381 /*
432 * FIXME: ALSA specifies fifo_size in bytes. If we're in normal 382 * FIXME: ALSA specifies fifo_size in bytes. If we're in normal
@@ -437,17 +387,6 @@ static int __aaci_pcm_open(struct aaci *aaci,
437 */ 387 */
438 runtime->hw.fifo_size = aaci->fifosize * 2; 388 runtime->hw.fifo_size = aaci->fifosize * 2;
439 389
440 /*
441 * Add rule describing hardware rate dependency
442 * on the number of channels.
443 */
444 ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
445 aaci_rule_rate_by_channels, aaci,
446 SNDRV_PCM_HW_PARAM_CHANNELS,
447 SNDRV_PCM_HW_PARAM_RATE, -1);
448 if (ret)
449 goto out;
450
451 ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, 390 ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED,
452 DRIVER_NAME, aaci); 391 DRIVER_NAME, aaci);
453 if (ret) 392 if (ret)
@@ -492,7 +431,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
492 /* 431 /*
493 * Clear out the DMA and any allocated buffers. 432 * Clear out the DMA and any allocated buffers.
494 */ 433 */
495 devdma_hw_free(NULL, substream); 434 snd_pcm_lib_free_pages(substream);
496 435
497 return 0; 436 return 0;
498} 437}
@@ -504,27 +443,29 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
504 int err; 443 int err;
505 444
506 aaci_pcm_hw_free(substream); 445 aaci_pcm_hw_free(substream);
446 if (aacirun->pcm_open) {
447 snd_ac97_pcm_close(aacirun->pcm);
448 aacirun->pcm_open = 0;
449 }
507 450
508 err = devdma_hw_alloc(NULL, substream, 451 err = snd_pcm_lib_malloc_pages(substream,
509 params_buffer_bytes(params)); 452 params_buffer_bytes(params));
510 if (err < 0) 453 if (err >= 0) {
511 goto out; 454 unsigned int rate = params_rate(params);
455 int dbl = rate > 48000;
512 456
513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 457 err = snd_ac97_pcm_open(aacirun->pcm, rate,
514 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
515 params_channels(params),
516 aacirun->pcm->r[0].slots);
517 else
518 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
519 params_channels(params), 458 params_channels(params),
520 aacirun->pcm->r[1].slots); 459 aacirun->pcm->r[dbl].slots);
521 460
522 if (err) 461 aacirun->pcm_open = err == 0;
523 goto out; 462 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
463 aacirun->fifosz = aaci->fifosize * 4;
524 464
525 aacirun->pcm_open = 1; 465 if (aacirun->cr & CR_COMPACT)
466 aacirun->fifosz >>= 1;
467 }
526 468
527 out:
528 return err; 469 return err;
529} 470}
530 471
@@ -533,8 +474,8 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
533 struct snd_pcm_runtime *runtime = substream->runtime; 474 struct snd_pcm_runtime *runtime = substream->runtime;
534 struct aaci_runtime *aacirun = runtime->private_data; 475 struct aaci_runtime *aacirun = runtime->private_data;
535 476
536 aacirun->start = (void *)runtime->dma_area; 477 aacirun->start = runtime->dma_area;
537 aacirun->end = aacirun->start + runtime->dma_bytes; 478 aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
538 aacirun->ptr = aacirun->start; 479 aacirun->ptr = aacirun->start;
539 aacirun->period = 480 aacirun->period =
540 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size); 481 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -551,11 +492,6 @@ static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
551 return bytes_to_frames(runtime, bytes); 492 return bytes_to_frames(runtime, bytes);
552} 493}
553 494
554static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
555{
556 return devdma_mmap(NULL, substream, vma);
557}
558
559 495
560/* 496/*
561 * Playback specific ALSA stuff 497 * Playback specific ALSA stuff
@@ -638,14 +574,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
638 * Enable FIFO, compact mode, 16 bits per sample. 574 * Enable FIFO, compact mode, 16 bits per sample.
639 * FIXME: double rate slots? 575 * FIXME: double rate slots?
640 */ 576 */
641 if (ret >= 0) { 577 if (ret >= 0)
642 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
643 aacirun->cr |= channels_to_txmask[channels]; 578 aacirun->cr |= channels_to_txmask[channels];
644 579
645 aacirun->fifosz = aaci->fifosize * 4;
646 if (aacirun->cr & CR_COMPACT)
647 aacirun->fifosz >>= 1;
648 }
649 return ret; 580 return ret;
650} 581}
651 582
@@ -657,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
657 ie &= ~(IE_URIE|IE_TXIE); 588 ie &= ~(IE_URIE|IE_TXIE);
658 writel(ie, aacirun->base + AACI_IE); 589 writel(ie, aacirun->base + AACI_IE);
659 aacirun->cr &= ~CR_EN; 590 aacirun->cr &= ~CR_EN;
660 aaci_chan_wait_ready(aacirun); 591 aaci_chan_wait_ready(aacirun, SR_TXB);
661 writel(aacirun->cr, aacirun->base + AACI_TXCR); 592 writel(aacirun->cr, aacirun->base + AACI_TXCR);
662} 593}
663 594
@@ -665,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
665{ 596{
666 u32 ie; 597 u32 ie;
667 598
668 aaci_chan_wait_ready(aacirun); 599 aaci_chan_wait_ready(aacirun, SR_TXB);
669 aacirun->cr |= CR_EN; 600 aacirun->cr |= CR_EN;
670 601
671 ie = readl(aacirun->base + AACI_IE); 602 ie = readl(aacirun->base + AACI_IE);
@@ -676,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
676 607
677static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 608static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
678{ 609{
679 struct aaci *aaci = substream->private_data;
680 struct aaci_runtime *aacirun = substream->runtime->private_data; 610 struct aaci_runtime *aacirun = substream->runtime->private_data;
681 unsigned long flags; 611 unsigned long flags;
682 int ret = 0; 612 int ret = 0;
683 613
684 spin_lock_irqsave(&aaci->lock, flags); 614 spin_lock_irqsave(&aacirun->lock, flags);
615
685 switch (cmd) { 616 switch (cmd) {
686 case SNDRV_PCM_TRIGGER_START: 617 case SNDRV_PCM_TRIGGER_START:
687 aaci_pcm_playback_start(aacirun); 618 aaci_pcm_playback_start(aacirun);
@@ -708,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
708 default: 639 default:
709 ret = -EINVAL; 640 ret = -EINVAL;
710 } 641 }
711 spin_unlock_irqrestore(&aaci->lock, flags); 642
643 spin_unlock_irqrestore(&aacirun->lock, flags);
712 644
713 return ret; 645 return ret;
714} 646}
@@ -722,7 +654,6 @@ static struct snd_pcm_ops aaci_playback_ops = {
722 .prepare = aaci_pcm_prepare, 654 .prepare = aaci_pcm_prepare,
723 .trigger = aaci_pcm_playback_trigger, 655 .trigger = aaci_pcm_playback_trigger,
724 .pointer = aaci_pcm_pointer, 656 .pointer = aaci_pcm_pointer,
725 .mmap = aaci_pcm_mmap,
726}; 657};
727 658
728static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, 659static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
@@ -733,18 +664,10 @@ static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
733 int ret; 664 int ret;
734 665
735 ret = aaci_pcm_hw_params(substream, aacirun, params); 666 ret = aaci_pcm_hw_params(substream, aacirun, params);
736 667 if (ret >= 0)
737 if (ret >= 0) {
738 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
739
740 /* Line in record: slot 3 and 4 */ 668 /* Line in record: slot 3 and 4 */
741 aacirun->cr |= CR_SL3 | CR_SL4; 669 aacirun->cr |= CR_SL3 | CR_SL4;
742 670
743 aacirun->fifosz = aaci->fifosize * 4;
744
745 if (aacirun->cr & CR_COMPACT)
746 aacirun->fifosz >>= 1;
747 }
748 return ret; 671 return ret;
749} 672}
750 673
@@ -752,7 +675,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
752{ 675{
753 u32 ie; 676 u32 ie;
754 677
755 aaci_chan_wait_ready(aacirun); 678 aaci_chan_wait_ready(aacirun, SR_RXB);
756 679
757 ie = readl(aacirun->base + AACI_IE); 680 ie = readl(aacirun->base + AACI_IE);
758 ie &= ~(IE_ORIE | IE_RXIE); 681 ie &= ~(IE_ORIE | IE_RXIE);
@@ -767,7 +690,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
767{ 690{
768 u32 ie; 691 u32 ie;
769 692
770 aaci_chan_wait_ready(aacirun); 693 aaci_chan_wait_ready(aacirun, SR_RXB);
771 694
772#ifdef DEBUG 695#ifdef DEBUG
773 /* RX Timeout value: bits 28:17 in RXCR */ 696 /* RX Timeout value: bits 28:17 in RXCR */
@@ -784,12 +707,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
784 707
785static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 708static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
786{ 709{
787 struct aaci *aaci = substream->private_data;
788 struct aaci_runtime *aacirun = substream->runtime->private_data; 710 struct aaci_runtime *aacirun = substream->runtime->private_data;
789 unsigned long flags; 711 unsigned long flags;
790 int ret = 0; 712 int ret = 0;
791 713
792 spin_lock_irqsave(&aaci->lock, flags); 714 spin_lock_irqsave(&aacirun->lock, flags);
793 715
794 switch (cmd) { 716 switch (cmd) {
795 case SNDRV_PCM_TRIGGER_START: 717 case SNDRV_PCM_TRIGGER_START:
@@ -818,7 +740,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd
818 ret = -EINVAL; 740 ret = -EINVAL;
819 } 741 }
820 742
821 spin_unlock_irqrestore(&aaci->lock, flags); 743 spin_unlock_irqrestore(&aacirun->lock, flags);
822 744
823 return ret; 745 return ret;
824} 746}
@@ -850,7 +772,6 @@ static struct snd_pcm_ops aaci_capture_ops = {
850 .prepare = aaci_pcm_capture_prepare, 772 .prepare = aaci_pcm_capture_prepare,
851 .trigger = aaci_pcm_capture_trigger, 773 .trigger = aaci_pcm_capture_trigger,
852 .pointer = aaci_pcm_pointer, 774 .pointer = aaci_pcm_pointer,
853 .mmap = aaci_pcm_mmap,
854}; 775};
855 776
856/* 777/*
@@ -902,6 +823,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = {
902 (1 << AC97_SLOT_PCM_SRIGHT) | 823 (1 << AC97_SLOT_PCM_SRIGHT) |
903 (1 << AC97_SLOT_LFE), 824 (1 << AC97_SLOT_LFE),
904 }, 825 },
826 [1] = {
827 .slots = (1 << AC97_SLOT_PCM_LEFT) |
828 (1 << AC97_SLOT_PCM_RIGHT) |
829 (1 << AC97_SLOT_PCM_LEFT_0) |
830 (1 << AC97_SLOT_PCM_RIGHT_0),
831 },
905 }, 832 },
906 }, 833 },
907 [1] = { /* PCM in */ 834 [1] = { /* PCM in */
@@ -1014,7 +941,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
1014 941
1015 aaci = card->private_data; 942 aaci = card->private_data;
1016 mutex_init(&aaci->ac97_sem); 943 mutex_init(&aaci->ac97_sem);
1017 spin_lock_init(&aaci->lock);
1018 aaci->card = card; 944 aaci->card = card;
1019 aaci->dev = dev; 945 aaci->dev = dev;
1020 946
@@ -1040,6 +966,8 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
1040 966
1041 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); 967 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
1042 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); 968 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
969 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
970 NULL, 0, 64 * 1024);
1043 } 971 }
1044 972
1045 return ret; 973 return ret;
@@ -1099,12 +1027,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
1099 /* 1027 /*
1100 * Playback uses AACI channel 0 1028 * Playback uses AACI channel 0
1101 */ 1029 */
1030 spin_lock_init(&aaci->playback.lock);
1102 aaci->playback.base = aaci->base + AACI_CSCH1; 1031 aaci->playback.base = aaci->base + AACI_CSCH1;
1103 aaci->playback.fifo = aaci->base + AACI_DR1; 1032 aaci->playback.fifo = aaci->base + AACI_DR1;
1104 1033
1105 /* 1034 /*
1106 * Capture uses AACI channel 0 1035 * Capture uses AACI channel 0
1107 */ 1036 */
1037 spin_lock_init(&aaci->capture.lock);
1108 aaci->capture.base = aaci->base + AACI_CSCH1; 1038 aaci->capture.base = aaci->base + AACI_CSCH1;
1109 aaci->capture.fifo = aaci->base + AACI_DR1; 1039 aaci->capture.fifo = aaci->base + AACI_DR1;
1110 1040
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index 924f69c1c44c..6a4a2eebdda1 100644
--- a/sound/arm/aaci.h
+++ b/sound/arm/aaci.h
@@ -202,6 +202,7 @@
202struct aaci_runtime { 202struct aaci_runtime {
203 void __iomem *base; 203 void __iomem *base;
204 void __iomem *fifo; 204 void __iomem *fifo;
205 spinlock_t lock;
205 206
206 struct ac97_pcm *pcm; 207 struct ac97_pcm *pcm;
207 int pcm_open; 208 int pcm_open;
@@ -232,7 +233,6 @@ struct aaci {
232 struct snd_ac97 *ac97; 233 struct snd_ac97 *ac97;
233 234
234 u32 maincr; 235 u32 maincr;
235 spinlock_t lock;
236 236
237 struct aaci_runtime playback; 237 struct aaci_runtime playback;
238 struct aaci_runtime capture; 238 struct aaci_runtime capture;
diff --git a/sound/arm/devdma.c b/sound/arm/devdma.c
deleted file mode 100644
index 9d1e6665b546..000000000000
--- a/sound/arm/devdma.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/sound/arm/devdma.c
3 *
4 * Copyright (C) 2003-2004 Russell King, All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM DMA shim for ALSA.
11 */
12#include <linux/device.h>
13#include <linux/dma-mapping.h>
14
15#include <sound/core.h>
16#include <sound/pcm.h>
17
18#include "devdma.h"
19
20void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
21{
22 struct snd_pcm_runtime *runtime = substream->runtime;
23 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
24
25 if (runtime->dma_area == NULL)
26 return;
27
28 if (buf != &substream->dma_buffer) {
29 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
30 kfree(runtime->dma_buffer_p);
31 }
32
33 snd_pcm_set_runtime_buffer(substream, NULL);
34}
35
36int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
37{
38 struct snd_pcm_runtime *runtime = substream->runtime;
39 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
40 int ret = 0;
41
42 if (buf) {
43 if (buf->bytes >= size)
44 goto out;
45 devdma_hw_free(dev, substream);
46 }
47
48 if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
49 buf = &substream->dma_buffer;
50 } else {
51 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
52 if (!buf)
53 goto nomem;
54
55 buf->dev.type = SNDRV_DMA_TYPE_DEV;
56 buf->dev.dev = dev;
57 buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
58 buf->bytes = size;
59 buf->private_data = NULL;
60
61 if (!buf->area)
62 goto free;
63 }
64 snd_pcm_set_runtime_buffer(substream, buf);
65 ret = 1;
66 out:
67 runtime->dma_bytes = size;
68 return ret;
69
70 free:
71 kfree(buf);
72 nomem:
73 return -ENOMEM;
74}
75
76int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
77{
78 struct snd_pcm_runtime *runtime = substream->runtime;
79 return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
80}
diff --git a/sound/arm/devdma.h b/sound/arm/devdma.h
deleted file mode 100644
index d025329c8a0f..000000000000
--- a/sound/arm/devdma.h
+++ /dev/null
@@ -1,3 +0,0 @@
1void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream);
2int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size);
3int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index b4b48afb6de6..5d9411839cd7 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -159,7 +159,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
159 return ret; 159 return ret;
160} 160}
161 161
162static struct dev_pm_ops pxa2xx_ac97_pm_ops = { 162static const struct dev_pm_ops pxa2xx_ac97_pm_ops = {
163 .suspend = pxa2xx_ac97_suspend, 163 .suspend = pxa2xx_ac97_suspend,
164 .resume = pxa2xx_ac97_resume, 164 .resume = pxa2xx_ac97_resume,
165}; 165};