diff options
Diffstat (limited to 'sound/arm')
-rw-r--r-- | sound/arm/aaci.c | 180 | ||||
-rw-r--r-- | sound/arm/aaci.h | 2 | ||||
-rw-r--r-- | sound/arm/pxa2xx-ac97.c | 2 |
3 files changed, 62 insertions, 122 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1497dce1b04a..656e474dca47 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -172,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
172 | return v; | 172 | return v; |
173 | } | 173 | } |
174 | 174 | ||
175 | static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) | 175 | static inline void |
176 | aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask) | ||
176 | { | 177 | { |
177 | u32 val; | 178 | u32 val; |
178 | int timeout = 5000; | 179 | int timeout = 5000; |
179 | 180 | ||
180 | do { | 181 | do { |
181 | val = readl(aacirun->base + AACI_SR); | 182 | val = readl(aacirun->base + AACI_SR); |
182 | } while (val & (SR_TXB|SR_RXB) && timeout--); | 183 | } while (val & mask && timeout--); |
183 | } | 184 | } |
184 | 185 | ||
185 | 186 | ||
@@ -208,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
208 | writel(0, aacirun->base + AACI_IE); | 209 | writel(0, aacirun->base + AACI_IE); |
209 | return; | 210 | return; |
210 | } | 211 | } |
211 | ptr = aacirun->ptr; | ||
212 | 212 | ||
213 | spin_lock(&aacirun->lock); | ||
214 | |||
215 | ptr = aacirun->ptr; | ||
213 | do { | 216 | do { |
214 | unsigned int len = aacirun->fifosz; | 217 | unsigned int len = aacirun->fifosz; |
215 | u32 val; | 218 | u32 val; |
@@ -217,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
217 | if (aacirun->bytes <= 0) { | 220 | if (aacirun->bytes <= 0) { |
218 | aacirun->bytes += aacirun->period; | 221 | aacirun->bytes += aacirun->period; |
219 | aacirun->ptr = ptr; | 222 | aacirun->ptr = ptr; |
220 | spin_unlock(&aaci->lock); | 223 | spin_unlock(&aacirun->lock); |
221 | snd_pcm_period_elapsed(aacirun->substream); | 224 | snd_pcm_period_elapsed(aacirun->substream); |
222 | spin_lock(&aaci->lock); | 225 | spin_lock(&aacirun->lock); |
223 | } | 226 | } |
224 | if (!(aacirun->cr & CR_EN)) | 227 | if (!(aacirun->cr & CR_EN)) |
225 | break; | 228 | break; |
@@ -245,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
245 | ptr = aacirun->start; | 248 | ptr = aacirun->start; |
246 | } | 249 | } |
247 | } while(1); | 250 | } while(1); |
251 | |||
248 | aacirun->ptr = ptr; | 252 | aacirun->ptr = ptr; |
253 | |||
254 | spin_unlock(&aacirun->lock); | ||
249 | } | 255 | } |
250 | 256 | ||
251 | if (mask & ISR_URINTR) { | 257 | if (mask & ISR_URINTR) { |
@@ -263,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
263 | return; | 269 | return; |
264 | } | 270 | } |
265 | 271 | ||
272 | spin_lock(&aacirun->lock); | ||
273 | |||
266 | ptr = aacirun->ptr; | 274 | ptr = aacirun->ptr; |
267 | do { | 275 | do { |
268 | unsigned int len = aacirun->fifosz; | 276 | unsigned int len = aacirun->fifosz; |
@@ -271,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
271 | if (aacirun->bytes <= 0) { | 279 | if (aacirun->bytes <= 0) { |
272 | aacirun->bytes += aacirun->period; | 280 | aacirun->bytes += aacirun->period; |
273 | aacirun->ptr = ptr; | 281 | aacirun->ptr = ptr; |
274 | spin_unlock(&aaci->lock); | 282 | spin_unlock(&aacirun->lock); |
275 | snd_pcm_period_elapsed(aacirun->substream); | 283 | snd_pcm_period_elapsed(aacirun->substream); |
276 | spin_lock(&aaci->lock); | 284 | spin_lock(&aacirun->lock); |
277 | } | 285 | } |
278 | if (!(aacirun->cr & CR_EN)) | 286 | if (!(aacirun->cr & CR_EN)) |
279 | break; | 287 | break; |
@@ -301,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
301 | } while (1); | 309 | } while (1); |
302 | 310 | ||
303 | aacirun->ptr = ptr; | 311 | aacirun->ptr = ptr; |
312 | |||
313 | spin_unlock(&aacirun->lock); | ||
304 | } | 314 | } |
305 | } | 315 | } |
306 | 316 | ||
@@ -310,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) | |||
310 | u32 mask; | 320 | u32 mask; |
311 | int i; | 321 | int i; |
312 | 322 | ||
313 | spin_lock(&aaci->lock); | ||
314 | mask = readl(aaci->base + AACI_ALLINTS); | 323 | mask = readl(aaci->base + AACI_ALLINTS); |
315 | if (mask) { | 324 | if (mask) { |
316 | u32 m = mask; | 325 | u32 m = mask; |
@@ -320,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) | |||
320 | } | 329 | } |
321 | } | 330 | } |
322 | } | 331 | } |
323 | spin_unlock(&aaci->lock); | ||
324 | 332 | ||
325 | return mask ? IRQ_HANDLED : IRQ_NONE; | 333 | return mask ? IRQ_HANDLED : IRQ_NONE; |
326 | } | 334 | } |
@@ -330,63 +338,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) | |||
330 | /* | 338 | /* |
331 | * ALSA support. | 339 | * ALSA support. |
332 | */ | 340 | */ |
333 | |||
334 | struct aaci_stream { | ||
335 | unsigned char codec_idx; | ||
336 | unsigned char rate_idx; | ||
337 | }; | ||
338 | |||
339 | static struct aaci_stream aaci_streams[] = { | ||
340 | [ACSTREAM_FRONT] = { | ||
341 | .codec_idx = 0, | ||
342 | .rate_idx = AC97_RATES_FRONT_DAC, | ||
343 | }, | ||
344 | [ACSTREAM_SURROUND] = { | ||
345 | .codec_idx = 0, | ||
346 | .rate_idx = AC97_RATES_SURR_DAC, | ||
347 | }, | ||
348 | [ACSTREAM_LFE] = { | ||
349 | .codec_idx = 0, | ||
350 | .rate_idx = AC97_RATES_LFE_DAC, | ||
351 | }, | ||
352 | }; | ||
353 | |||
354 | static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid) | ||
355 | { | ||
356 | struct aaci_stream *s = aaci_streams + streamid; | ||
357 | return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx]; | ||
358 | } | ||
359 | |||
360 | static unsigned int rate_list[] = { | ||
361 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, | ||
362 | 48000, 64000, 88200, 96000, 176400, 192000 | ||
363 | }; | ||
364 | |||
365 | /* | ||
366 | * Double-rate rule: we can support double rate iff channels == 2 | ||
367 | * (unimplemented) | ||
368 | */ | ||
369 | static int | ||
370 | aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule) | ||
371 | { | ||
372 | struct aaci *aaci = rule->private; | ||
373 | unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512; | ||
374 | struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
375 | |||
376 | switch (c->max) { | ||
377 | case 6: | ||
378 | rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE); | ||
379 | case 4: | ||
380 | rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND); | ||
381 | case 2: | ||
382 | rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT); | ||
383 | } | ||
384 | |||
385 | return snd_interval_list(hw_param_interval(p, rule->var), | ||
386 | ARRAY_SIZE(rate_list), rate_list, | ||
387 | rate_mask); | ||
388 | } | ||
389 | |||
390 | static struct snd_pcm_hardware aaci_hw_info = { | 341 | static struct snd_pcm_hardware aaci_hw_info = { |
391 | .info = SNDRV_PCM_INFO_MMAP | | 342 | .info = SNDRV_PCM_INFO_MMAP | |
392 | SNDRV_PCM_INFO_MMAP_VALID | | 343 | SNDRV_PCM_INFO_MMAP_VALID | |
@@ -400,10 +351,7 @@ static struct snd_pcm_hardware aaci_hw_info = { | |||
400 | */ | 351 | */ |
401 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 352 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
402 | 353 | ||
403 | /* should this be continuous or knot? */ | 354 | /* rates are setup from the AC'97 codec */ |
404 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
405 | .rate_max = 48000, | ||
406 | .rate_min = 4000, | ||
407 | .channels_min = 2, | 355 | .channels_min = 2, |
408 | .channels_max = 6, | 356 | .channels_max = 6, |
409 | .buffer_bytes_max = 64 * 1024, | 357 | .buffer_bytes_max = 64 * 1024, |
@@ -423,6 +371,12 @@ static int __aaci_pcm_open(struct aaci *aaci, | |||
423 | aacirun->substream = substream; | 371 | aacirun->substream = substream; |
424 | runtime->private_data = aacirun; | 372 | runtime->private_data = aacirun; |
425 | 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); | ||
426 | 380 | ||
427 | /* | 381 | /* |
428 | * 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 |
@@ -433,17 +387,6 @@ static int __aaci_pcm_open(struct aaci *aaci, | |||
433 | */ | 387 | */ |
434 | runtime->hw.fifo_size = aaci->fifosize * 2; | 388 | runtime->hw.fifo_size = aaci->fifosize * 2; |
435 | 389 | ||
436 | /* | ||
437 | * Add rule describing hardware rate dependency | ||
438 | * on the number of channels. | ||
439 | */ | ||
440 | ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
441 | aaci_rule_rate_by_channels, aaci, | ||
442 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
443 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
444 | if (ret) | ||
445 | goto out; | ||
446 | |||
447 | 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, |
448 | DRIVER_NAME, aaci); | 391 | DRIVER_NAME, aaci); |
449 | if (ret) | 392 | if (ret) |
@@ -498,6 +441,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
498 | struct snd_pcm_hw_params *params) | 441 | struct snd_pcm_hw_params *params) |
499 | { | 442 | { |
500 | int err; | 443 | int err; |
444 | struct aaci *aaci = substream->private_data; | ||
501 | 445 | ||
502 | aaci_pcm_hw_free(substream); | 446 | aaci_pcm_hw_free(substream); |
503 | if (aacirun->pcm_open) { | 447 | if (aacirun->pcm_open) { |
@@ -507,18 +451,22 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
507 | 451 | ||
508 | err = snd_pcm_lib_malloc_pages(substream, | 452 | err = snd_pcm_lib_malloc_pages(substream, |
509 | params_buffer_bytes(params)); | 453 | params_buffer_bytes(params)); |
510 | if (err < 0) | 454 | if (err >= 0) { |
511 | goto out; | 455 | unsigned int rate = params_rate(params); |
456 | int dbl = rate > 48000; | ||
512 | 457 | ||
513 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), | 458 | err = snd_ac97_pcm_open(aacirun->pcm, rate, |
514 | params_channels(params), | 459 | params_channels(params), |
515 | aacirun->pcm->r[0].slots); | 460 | aacirun->pcm->r[dbl].slots); |
516 | if (err) | ||
517 | goto out; | ||
518 | 461 | ||
519 | aacirun->pcm_open = 1; | 462 | aacirun->pcm_open = err == 0; |
463 | aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; | ||
464 | aacirun->fifosz = aaci->fifosize * 4; | ||
465 | |||
466 | if (aacirun->cr & CR_COMPACT) | ||
467 | aacirun->fifosz >>= 1; | ||
468 | } | ||
520 | 469 | ||
521 | out: | ||
522 | return err; | 470 | return err; |
523 | } | 471 | } |
524 | 472 | ||
@@ -527,7 +475,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream) | |||
527 | struct snd_pcm_runtime *runtime = substream->runtime; | 475 | struct snd_pcm_runtime *runtime = substream->runtime; |
528 | struct aaci_runtime *aacirun = runtime->private_data; | 476 | struct aaci_runtime *aacirun = runtime->private_data; |
529 | 477 | ||
530 | aacirun->start = (void *)runtime->dma_area; | 478 | aacirun->start = runtime->dma_area; |
531 | aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream); | 479 | aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream); |
532 | aacirun->ptr = aacirun->start; | 480 | aacirun->ptr = aacirun->start; |
533 | aacirun->period = | 481 | aacirun->period = |
@@ -613,7 +561,6 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream) | |||
613 | static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, | 561 | static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, |
614 | struct snd_pcm_hw_params *params) | 562 | struct snd_pcm_hw_params *params) |
615 | { | 563 | { |
616 | struct aaci *aaci = substream->private_data; | ||
617 | struct aaci_runtime *aacirun = substream->runtime->private_data; | 564 | struct aaci_runtime *aacirun = substream->runtime->private_data; |
618 | unsigned int channels = params_channels(params); | 565 | unsigned int channels = params_channels(params); |
619 | int ret; | 566 | int ret; |
@@ -627,14 +574,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
627 | * Enable FIFO, compact mode, 16 bits per sample. | 574 | * Enable FIFO, compact mode, 16 bits per sample. |
628 | * FIXME: double rate slots? | 575 | * FIXME: double rate slots? |
629 | */ | 576 | */ |
630 | if (ret >= 0) { | 577 | if (ret >= 0) |
631 | aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; | ||
632 | aacirun->cr |= channels_to_txmask[channels]; | 578 | aacirun->cr |= channels_to_txmask[channels]; |
633 | 579 | ||
634 | aacirun->fifosz = aaci->fifosize * 4; | ||
635 | if (aacirun->cr & CR_COMPACT) | ||
636 | aacirun->fifosz >>= 1; | ||
637 | } | ||
638 | return ret; | 580 | return ret; |
639 | } | 581 | } |
640 | 582 | ||
@@ -646,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun) | |||
646 | ie &= ~(IE_URIE|IE_TXIE); | 588 | ie &= ~(IE_URIE|IE_TXIE); |
647 | writel(ie, aacirun->base + AACI_IE); | 589 | writel(ie, aacirun->base + AACI_IE); |
648 | aacirun->cr &= ~CR_EN; | 590 | aacirun->cr &= ~CR_EN; |
649 | aaci_chan_wait_ready(aacirun); | 591 | aaci_chan_wait_ready(aacirun, SR_TXB); |
650 | writel(aacirun->cr, aacirun->base + AACI_TXCR); | 592 | writel(aacirun->cr, aacirun->base + AACI_TXCR); |
651 | } | 593 | } |
652 | 594 | ||
@@ -654,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) | |||
654 | { | 596 | { |
655 | u32 ie; | 597 | u32 ie; |
656 | 598 | ||
657 | aaci_chan_wait_ready(aacirun); | 599 | aaci_chan_wait_ready(aacirun, SR_TXB); |
658 | aacirun->cr |= CR_EN; | 600 | aacirun->cr |= CR_EN; |
659 | 601 | ||
660 | ie = readl(aacirun->base + AACI_IE); | 602 | ie = readl(aacirun->base + AACI_IE); |
@@ -665,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) | |||
665 | 607 | ||
666 | static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) | 608 | static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) |
667 | { | 609 | { |
668 | struct aaci *aaci = substream->private_data; | ||
669 | struct aaci_runtime *aacirun = substream->runtime->private_data; | 610 | struct aaci_runtime *aacirun = substream->runtime->private_data; |
670 | unsigned long flags; | 611 | unsigned long flags; |
671 | int ret = 0; | 612 | int ret = 0; |
672 | 613 | ||
673 | spin_lock_irqsave(&aaci->lock, flags); | 614 | spin_lock_irqsave(&aacirun->lock, flags); |
615 | |||
674 | switch (cmd) { | 616 | switch (cmd) { |
675 | case SNDRV_PCM_TRIGGER_START: | 617 | case SNDRV_PCM_TRIGGER_START: |
676 | aaci_pcm_playback_start(aacirun); | 618 | aaci_pcm_playback_start(aacirun); |
@@ -697,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm | |||
697 | default: | 639 | default: |
698 | ret = -EINVAL; | 640 | ret = -EINVAL; |
699 | } | 641 | } |
700 | spin_unlock_irqrestore(&aaci->lock, flags); | 642 | |
643 | spin_unlock_irqrestore(&aacirun->lock, flags); | ||
701 | 644 | ||
702 | return ret; | 645 | return ret; |
703 | } | 646 | } |
@@ -716,23 +659,14 @@ static struct snd_pcm_ops aaci_playback_ops = { | |||
716 | static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, | 659 | static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, |
717 | struct snd_pcm_hw_params *params) | 660 | struct snd_pcm_hw_params *params) |
718 | { | 661 | { |
719 | struct aaci *aaci = substream->private_data; | ||
720 | struct aaci_runtime *aacirun = substream->runtime->private_data; | 662 | struct aaci_runtime *aacirun = substream->runtime->private_data; |
721 | int ret; | 663 | int ret; |
722 | 664 | ||
723 | ret = aaci_pcm_hw_params(substream, aacirun, params); | 665 | ret = aaci_pcm_hw_params(substream, aacirun, params); |
724 | 666 | if (ret >= 0) | |
725 | if (ret >= 0) { | ||
726 | aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; | ||
727 | |||
728 | /* Line in record: slot 3 and 4 */ | 667 | /* Line in record: slot 3 and 4 */ |
729 | aacirun->cr |= CR_SL3 | CR_SL4; | 668 | aacirun->cr |= CR_SL3 | CR_SL4; |
730 | 669 | ||
731 | aacirun->fifosz = aaci->fifosize * 4; | ||
732 | |||
733 | if (aacirun->cr & CR_COMPACT) | ||
734 | aacirun->fifosz >>= 1; | ||
735 | } | ||
736 | return ret; | 670 | return ret; |
737 | } | 671 | } |
738 | 672 | ||
@@ -740,7 +674,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun) | |||
740 | { | 674 | { |
741 | u32 ie; | 675 | u32 ie; |
742 | 676 | ||
743 | aaci_chan_wait_ready(aacirun); | 677 | aaci_chan_wait_ready(aacirun, SR_RXB); |
744 | 678 | ||
745 | ie = readl(aacirun->base + AACI_IE); | 679 | ie = readl(aacirun->base + AACI_IE); |
746 | ie &= ~(IE_ORIE | IE_RXIE); | 680 | ie &= ~(IE_ORIE | IE_RXIE); |
@@ -755,7 +689,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) | |||
755 | { | 689 | { |
756 | u32 ie; | 690 | u32 ie; |
757 | 691 | ||
758 | aaci_chan_wait_ready(aacirun); | 692 | aaci_chan_wait_ready(aacirun, SR_RXB); |
759 | 693 | ||
760 | #ifdef DEBUG | 694 | #ifdef DEBUG |
761 | /* RX Timeout value: bits 28:17 in RXCR */ | 695 | /* RX Timeout value: bits 28:17 in RXCR */ |
@@ -772,12 +706,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) | |||
772 | 706 | ||
773 | static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) | 707 | static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) |
774 | { | 708 | { |
775 | struct aaci *aaci = substream->private_data; | ||
776 | struct aaci_runtime *aacirun = substream->runtime->private_data; | 709 | struct aaci_runtime *aacirun = substream->runtime->private_data; |
777 | unsigned long flags; | 710 | unsigned long flags; |
778 | int ret = 0; | 711 | int ret = 0; |
779 | 712 | ||
780 | spin_lock_irqsave(&aaci->lock, flags); | 713 | spin_lock_irqsave(&aacirun->lock, flags); |
781 | 714 | ||
782 | switch (cmd) { | 715 | switch (cmd) { |
783 | case SNDRV_PCM_TRIGGER_START: | 716 | case SNDRV_PCM_TRIGGER_START: |
@@ -806,7 +739,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd | |||
806 | ret = -EINVAL; | 739 | ret = -EINVAL; |
807 | } | 740 | } |
808 | 741 | ||
809 | spin_unlock_irqrestore(&aaci->lock, flags); | 742 | spin_unlock_irqrestore(&aacirun->lock, flags); |
810 | 743 | ||
811 | return ret; | 744 | return ret; |
812 | } | 745 | } |
@@ -889,6 +822,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = { | |||
889 | (1 << AC97_SLOT_PCM_SRIGHT) | | 822 | (1 << AC97_SLOT_PCM_SRIGHT) | |
890 | (1 << AC97_SLOT_LFE), | 823 | (1 << AC97_SLOT_LFE), |
891 | }, | 824 | }, |
825 | [1] = { | ||
826 | .slots = (1 << AC97_SLOT_PCM_LEFT) | | ||
827 | (1 << AC97_SLOT_PCM_RIGHT) | | ||
828 | (1 << AC97_SLOT_PCM_LEFT_0) | | ||
829 | (1 << AC97_SLOT_PCM_RIGHT_0), | ||
830 | }, | ||
892 | }, | 831 | }, |
893 | }, | 832 | }, |
894 | [1] = { /* PCM in */ | 833 | [1] = { /* PCM in */ |
@@ -1001,7 +940,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) | |||
1001 | 940 | ||
1002 | aaci = card->private_data; | 941 | aaci = card->private_data; |
1003 | mutex_init(&aaci->ac97_sem); | 942 | mutex_init(&aaci->ac97_sem); |
1004 | spin_lock_init(&aaci->lock); | ||
1005 | aaci->card = card; | 943 | aaci->card = card; |
1006 | aaci->dev = dev; | 944 | aaci->dev = dev; |
1007 | 945 | ||
@@ -1028,7 +966,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) | |||
1028 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); | 966 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); |
1029 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); | 967 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); |
1030 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 968 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1031 | NULL, 0, 64 * 104); | 969 | NULL, 0, 64 * 1024); |
1032 | } | 970 | } |
1033 | 971 | ||
1034 | return ret; | 972 | return ret; |
@@ -1088,12 +1026,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) | |||
1088 | /* | 1026 | /* |
1089 | * Playback uses AACI channel 0 | 1027 | * Playback uses AACI channel 0 |
1090 | */ | 1028 | */ |
1029 | spin_lock_init(&aaci->playback.lock); | ||
1091 | aaci->playback.base = aaci->base + AACI_CSCH1; | 1030 | aaci->playback.base = aaci->base + AACI_CSCH1; |
1092 | aaci->playback.fifo = aaci->base + AACI_DR1; | 1031 | aaci->playback.fifo = aaci->base + AACI_DR1; |
1093 | 1032 | ||
1094 | /* | 1033 | /* |
1095 | * Capture uses AACI channel 0 | 1034 | * Capture uses AACI channel 0 |
1096 | */ | 1035 | */ |
1036 | spin_lock_init(&aaci->capture.lock); | ||
1097 | aaci->capture.base = aaci->base + AACI_CSCH1; | 1037 | aaci->capture.base = aaci->base + AACI_CSCH1; |
1098 | aaci->capture.fifo = aaci->base + AACI_DR1; | 1038 | aaci->capture.fifo = aaci->base + AACI_DR1; |
1099 | 1039 | ||
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 @@ | |||
202 | struct aaci_runtime { | 202 | struct 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/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 | ||
162 | static struct dev_pm_ops pxa2xx_ac97_pm_ops = { | 162 | static 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 | }; |