diff options
author | Kevin Hilman <khilman@mvista.com> | 2007-02-06 23:45:32 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-02-18 05:59:49 -0500 |
commit | 41762b8ca9e16c7443d8348ec53daddbe940cdcc (patch) | |
tree | bec07a1eac2a998d332c2f3870f85467d6550993 | |
parent | 62578cbfaa50df06b3bb6e4231adc3b911a3d4b4 (diff) |
[ARM] 4139/1: AACI record support
Add PCM audio capture support for AACI audio on Versatile platform.
Signed-off-by: Kevin Hilman <khilman@mvista.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | sound/arm/aaci.c | 258 | ||||
-rw-r--r-- | sound/arm/aaci.h | 41 |
2 files changed, 253 insertions, 46 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b85df793cdce..a032aee82adf 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -166,6 +166,65 @@ static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) | |||
166 | */ | 166 | */ |
167 | static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | 167 | static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) |
168 | { | 168 | { |
169 | if (mask & ISR_ORINTR) { | ||
170 | dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel); | ||
171 | writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR); | ||
172 | } | ||
173 | |||
174 | if (mask & ISR_RXTOINTR) { | ||
175 | dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel); | ||
176 | writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR); | ||
177 | } | ||
178 | |||
179 | if (mask & ISR_RXINTR) { | ||
180 | struct aaci_runtime *aacirun = &aaci->capture; | ||
181 | void *ptr; | ||
182 | |||
183 | if (!aacirun->substream || !aacirun->start) { | ||
184 | dev_warn(&aaci->dev->dev, "RX interrupt???"); | ||
185 | writel(0, aacirun->base + AACI_IE); | ||
186 | return; | ||
187 | } | ||
188 | ptr = aacirun->ptr; | ||
189 | |||
190 | do { | ||
191 | unsigned int len = aacirun->fifosz; | ||
192 | u32 val; | ||
193 | |||
194 | if (aacirun->bytes <= 0) { | ||
195 | aacirun->bytes += aacirun->period; | ||
196 | aacirun->ptr = ptr; | ||
197 | spin_unlock(&aaci->lock); | ||
198 | snd_pcm_period_elapsed(aacirun->substream); | ||
199 | spin_lock(&aaci->lock); | ||
200 | } | ||
201 | if (!(aacirun->cr & CR_EN)) | ||
202 | break; | ||
203 | |||
204 | val = readl(aacirun->base + AACI_SR); | ||
205 | if (!(val & SR_RXHF)) | ||
206 | break; | ||
207 | if (!(val & SR_RXFF)) | ||
208 | len >>= 1; | ||
209 | |||
210 | aacirun->bytes -= len; | ||
211 | |||
212 | /* reading 16 bytes at a time */ | ||
213 | for( ; len > 0; len -= 16) { | ||
214 | asm( | ||
215 | "ldmia %1, {r0, r1, r2, r3}\n\t" | ||
216 | "stmia %0!, {r0, r1, r2, r3}" | ||
217 | : "+r" (ptr) | ||
218 | : "r" (aacirun->fifo) | ||
219 | : "r0", "r1", "r2", "r3", "cc"); | ||
220 | |||
221 | if (ptr >= aacirun->end) | ||
222 | ptr = aacirun->start; | ||
223 | } | ||
224 | } while(1); | ||
225 | aacirun->ptr = ptr; | ||
226 | } | ||
227 | |||
169 | if (mask & ISR_URINTR) { | 228 | if (mask & ISR_URINTR) { |
170 | dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel); | 229 | dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel); |
171 | writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR); | 230 | writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR); |
@@ -193,7 +252,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
193 | snd_pcm_period_elapsed(aacirun->substream); | 252 | snd_pcm_period_elapsed(aacirun->substream); |
194 | spin_lock(&aaci->lock); | 253 | spin_lock(&aaci->lock); |
195 | } | 254 | } |
196 | if (!(aacirun->cr & TXCR_TXEN)) | 255 | if (!(aacirun->cr & CR_EN)) |
197 | break; | 256 | break; |
198 | 257 | ||
199 | val = readl(aacirun->base + AACI_SR); | 258 | val = readl(aacirun->base + AACI_SR); |
@@ -331,8 +390,9 @@ static struct snd_pcm_hardware aaci_hw_info = { | |||
331 | .periods_max = PAGE_SIZE / 16, | 390 | .periods_max = PAGE_SIZE / 16, |
332 | }; | 391 | }; |
333 | 392 | ||
334 | static int aaci_pcm_open(struct aaci *aaci, struct snd_pcm_substream *substream, | 393 | static int __aaci_pcm_open(struct aaci *aaci, |
335 | struct aaci_runtime *aacirun) | 394 | struct snd_pcm_substream *substream, |
395 | struct aaci_runtime *aacirun) | ||
336 | { | 396 | { |
337 | struct snd_pcm_runtime *runtime = substream->runtime; | 397 | struct snd_pcm_runtime *runtime = substream->runtime; |
338 | int ret; | 398 | int ret; |
@@ -381,7 +441,7 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream) | |||
381 | struct aaci *aaci = substream->private_data; | 441 | struct aaci *aaci = substream->private_data; |
382 | struct aaci_runtime *aacirun = substream->runtime->private_data; | 442 | struct aaci_runtime *aacirun = substream->runtime->private_data; |
383 | 443 | ||
384 | WARN_ON(aacirun->cr & TXCR_TXEN); | 444 | WARN_ON(aacirun->cr & CR_EN); |
385 | 445 | ||
386 | aacirun->substream = NULL; | 446 | aacirun->substream = NULL; |
387 | free_irq(aaci->dev->irq[0], aaci); | 447 | free_irq(aaci->dev->irq[0], aaci); |
@@ -396,7 +456,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream) | |||
396 | /* | 456 | /* |
397 | * This must not be called with the device enabled. | 457 | * This must not be called with the device enabled. |
398 | */ | 458 | */ |
399 | WARN_ON(aacirun->cr & TXCR_TXEN); | 459 | WARN_ON(aacirun->cr & CR_EN); |
400 | 460 | ||
401 | if (aacirun->pcm_open) | 461 | if (aacirun->pcm_open) |
402 | snd_ac97_pcm_close(aacirun->pcm); | 462 | snd_ac97_pcm_close(aacirun->pcm); |
@@ -423,9 +483,15 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
423 | if (err < 0) | 483 | if (err < 0) |
424 | goto out; | 484 | goto out; |
425 | 485 | ||
426 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), | 486 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
427 | params_channels(params), | 487 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), |
428 | aacirun->pcm->r[0].slots); | 488 | params_channels(params), |
489 | aacirun->pcm->r[0].slots); | ||
490 | else | ||
491 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), | ||
492 | params_channels(params), | ||
493 | aacirun->pcm->r[1].slots); | ||
494 | |||
429 | if (err) | 495 | if (err) |
430 | goto out; | 496 | goto out; |
431 | 497 | ||
@@ -468,9 +534,9 @@ static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_str | |||
468 | * Playback specific ALSA stuff | 534 | * Playback specific ALSA stuff |
469 | */ | 535 | */ |
470 | static const u32 channels_to_txmask[] = { | 536 | static const u32 channels_to_txmask[] = { |
471 | [2] = TXCR_TX3 | TXCR_TX4, | 537 | [2] = CR_SL3 | CR_SL4, |
472 | [4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8, | 538 | [4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8, |
473 | [6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9, | 539 | [6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9, |
474 | }; | 540 | }; |
475 | 541 | ||
476 | /* | 542 | /* |
@@ -505,7 +571,7 @@ aaci_rule_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule) | |||
505 | chan_mask); | 571 | chan_mask); |
506 | } | 572 | } |
507 | 573 | ||
508 | static int aaci_pcm_playback_open(struct snd_pcm_substream *substream) | 574 | static int aaci_pcm_open(struct snd_pcm_substream *substream) |
509 | { | 575 | { |
510 | struct aaci *aaci = substream->private_data; | 576 | struct aaci *aaci = substream->private_data; |
511 | int ret; | 577 | int ret; |
@@ -520,7 +586,12 @@ static int aaci_pcm_playback_open(struct snd_pcm_substream *substream) | |||
520 | if (ret) | 586 | if (ret) |
521 | return ret; | 587 | return ret; |
522 | 588 | ||
523 | return aaci_pcm_open(aaci, substream, &aaci->playback); | 589 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
590 | ret = __aaci_pcm_open(aaci, substream, &aaci->playback); | ||
591 | } else { | ||
592 | ret = __aaci_pcm_open(aaci, substream, &aaci->capture); | ||
593 | } | ||
594 | return ret; | ||
524 | } | 595 | } |
525 | 596 | ||
526 | static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, | 597 | static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, |
@@ -541,11 +612,11 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
541 | * FIXME: double rate slots? | 612 | * FIXME: double rate slots? |
542 | */ | 613 | */ |
543 | if (ret >= 0) { | 614 | if (ret >= 0) { |
544 | aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16; | 615 | aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; |
545 | aacirun->cr |= channels_to_txmask[channels]; | 616 | aacirun->cr |= channels_to_txmask[channels]; |
546 | 617 | ||
547 | aacirun->fifosz = aaci->fifosize * 4; | 618 | aacirun->fifosz = aaci->fifosize * 4; |
548 | if (aacirun->cr & TXCR_COMPACT) | 619 | if (aacirun->cr & CR_COMPACT) |
549 | aacirun->fifosz >>= 1; | 620 | aacirun->fifosz >>= 1; |
550 | } | 621 | } |
551 | return ret; | 622 | return ret; |
@@ -558,7 +629,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun) | |||
558 | ie = readl(aacirun->base + AACI_IE); | 629 | ie = readl(aacirun->base + AACI_IE); |
559 | ie &= ~(IE_URIE|IE_TXIE); | 630 | ie &= ~(IE_URIE|IE_TXIE); |
560 | writel(ie, aacirun->base + AACI_IE); | 631 | writel(ie, aacirun->base + AACI_IE); |
561 | aacirun->cr &= ~TXCR_TXEN; | 632 | aacirun->cr &= ~CR_EN; |
562 | aaci_chan_wait_ready(aacirun); | 633 | aaci_chan_wait_ready(aacirun); |
563 | writel(aacirun->cr, aacirun->base + AACI_TXCR); | 634 | writel(aacirun->cr, aacirun->base + AACI_TXCR); |
564 | } | 635 | } |
@@ -568,7 +639,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) | |||
568 | u32 ie; | 639 | u32 ie; |
569 | 640 | ||
570 | aaci_chan_wait_ready(aacirun); | 641 | aaci_chan_wait_ready(aacirun); |
571 | aacirun->cr |= TXCR_TXEN; | 642 | aacirun->cr |= CR_EN; |
572 | 643 | ||
573 | ie = readl(aacirun->base + AACI_IE); | 644 | ie = readl(aacirun->base + AACI_IE); |
574 | ie |= IE_URIE | IE_TXIE; | 645 | ie |= IE_URIE | IE_TXIE; |
@@ -616,7 +687,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm | |||
616 | } | 687 | } |
617 | 688 | ||
618 | static struct snd_pcm_ops aaci_playback_ops = { | 689 | static struct snd_pcm_ops aaci_playback_ops = { |
619 | .open = aaci_pcm_playback_open, | 690 | .open = aaci_pcm_open, |
620 | .close = aaci_pcm_close, | 691 | .close = aaci_pcm_close, |
621 | .ioctl = snd_pcm_lib_ioctl, | 692 | .ioctl = snd_pcm_lib_ioctl, |
622 | .hw_params = aaci_pcm_playback_hw_params, | 693 | .hw_params = aaci_pcm_playback_hw_params, |
@@ -627,7 +698,133 @@ static struct snd_pcm_ops aaci_playback_ops = { | |||
627 | .mmap = aaci_pcm_mmap, | 698 | .mmap = aaci_pcm_mmap, |
628 | }; | 699 | }; |
629 | 700 | ||
701 | static int aaci_pcm_capture_hw_params(snd_pcm_substream_t *substream, | ||
702 | snd_pcm_hw_params_t *params) | ||
703 | { | ||
704 | struct aaci *aaci = substream->private_data; | ||
705 | struct aaci_runtime *aacirun = substream->runtime->private_data; | ||
706 | int ret; | ||
707 | |||
708 | ret = aaci_pcm_hw_params(substream, aacirun, params); | ||
709 | |||
710 | if (ret >= 0) { | ||
711 | aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; | ||
712 | |||
713 | /* Line in record: slot 3 and 4 */ | ||
714 | aacirun->cr |= CR_SL3 | CR_SL4; | ||
715 | |||
716 | aacirun->fifosz = aaci->fifosize * 4; | ||
717 | |||
718 | if (aacirun->cr & CR_COMPACT) | ||
719 | aacirun->fifosz >>= 1; | ||
720 | } | ||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun) | ||
725 | { | ||
726 | u32 ie; | ||
727 | |||
728 | aaci_chan_wait_ready(aacirun); | ||
729 | |||
730 | ie = readl(aacirun->base + AACI_IE); | ||
731 | ie &= ~(IE_ORIE | IE_RXIE); | ||
732 | writel(ie, aacirun->base+AACI_IE); | ||
733 | |||
734 | aacirun->cr &= ~CR_EN; | ||
630 | 735 | ||
736 | writel(aacirun->cr, aacirun->base + AACI_RXCR); | ||
737 | } | ||
738 | |||
739 | static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) | ||
740 | { | ||
741 | u32 ie; | ||
742 | |||
743 | aaci_chan_wait_ready(aacirun); | ||
744 | |||
745 | #ifdef DEBUG | ||
746 | /* RX Timeout value: bits 28:17 in RXCR */ | ||
747 | aacirun->cr |= 0xf << 17; | ||
748 | #endif | ||
749 | |||
750 | aacirun->cr |= CR_EN; | ||
751 | writel(aacirun->cr, aacirun->base + AACI_RXCR); | ||
752 | |||
753 | ie = readl(aacirun->base + AACI_IE); | ||
754 | ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full | ||
755 | writel(ie, aacirun->base + AACI_IE); | ||
756 | } | ||
757 | |||
758 | static int aaci_pcm_capture_trigger(snd_pcm_substream_t *substream, int cmd){ | ||
759 | |||
760 | struct aaci *aaci = substream->private_data; | ||
761 | struct aaci_runtime *aacirun = substream->runtime->private_data; | ||
762 | unsigned long flags; | ||
763 | int ret = 0; | ||
764 | |||
765 | spin_lock_irqsave(&aaci->lock, flags); | ||
766 | |||
767 | switch (cmd) { | ||
768 | case SNDRV_PCM_TRIGGER_START: | ||
769 | aaci_pcm_capture_start(aacirun); | ||
770 | break; | ||
771 | |||
772 | case SNDRV_PCM_TRIGGER_RESUME: | ||
773 | aaci_pcm_capture_start(aacirun); | ||
774 | break; | ||
775 | |||
776 | case SNDRV_PCM_TRIGGER_STOP: | ||
777 | aaci_pcm_capture_stop(aacirun); | ||
778 | break; | ||
779 | |||
780 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
781 | aaci_pcm_capture_stop(aacirun); | ||
782 | break; | ||
783 | |||
784 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
785 | break; | ||
786 | |||
787 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
788 | break; | ||
789 | |||
790 | default: | ||
791 | ret = -EINVAL; | ||
792 | } | ||
793 | |||
794 | spin_unlock_irqrestore(&aaci->lock, flags); | ||
795 | |||
796 | return ret; | ||
797 | } | ||
798 | |||
799 | static int aaci_pcm_capture_prepare(snd_pcm_substream_t *substream) | ||
800 | { | ||
801 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
802 | struct aaci *aaci = substream->private_data; | ||
803 | |||
804 | aaci_pcm_prepare(substream); | ||
805 | |||
806 | /* allow changing of sample rate */ | ||
807 | aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */ | ||
808 | aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); | ||
809 | aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate); | ||
810 | |||
811 | /* Record select: Mic: 0, Aux: 3, Line: 4 */ | ||
812 | aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404); | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | static snd_pcm_ops_t aaci_capture_ops = { | ||
818 | .open = aaci_pcm_open, | ||
819 | .close = aaci_pcm_close, | ||
820 | .ioctl = snd_pcm_lib_ioctl, | ||
821 | .hw_params = aaci_pcm_capture_hw_params, | ||
822 | .hw_free = aaci_pcm_hw_free, | ||
823 | .prepare = aaci_pcm_capture_prepare, | ||
824 | .trigger = aaci_pcm_capture_trigger, | ||
825 | .pointer = aaci_pcm_pointer, | ||
826 | .mmap = aaci_pcm_mmap, | ||
827 | }; | ||
631 | 828 | ||
632 | /* | 829 | /* |
633 | * Power Management. | 830 | * Power Management. |
@@ -667,7 +864,7 @@ static int aaci_resume(struct amba_device *dev) | |||
667 | 864 | ||
668 | 865 | ||
669 | static struct ac97_pcm ac97_defs[] __devinitdata = { | 866 | static struct ac97_pcm ac97_defs[] __devinitdata = { |
670 | [0] = { /* Front PCM */ | 867 | [0] = { /* Front PCM */ |
671 | .exclusive = 1, | 868 | .exclusive = 1, |
672 | .r = { | 869 | .r = { |
673 | [0] = { | 870 | [0] = { |
@@ -741,6 +938,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) | |||
741 | ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); | 938 | ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); |
742 | if (ret) | 939 | if (ret) |
743 | goto out; | 940 | goto out; |
941 | aaci->ac97 = ac97; | ||
744 | 942 | ||
745 | /* | 943 | /* |
746 | * Disable AC97 PC Beep input on audio codecs. | 944 | * Disable AC97 PC Beep input on audio codecs. |
@@ -753,6 +951,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) | |||
753 | goto out; | 951 | goto out; |
754 | 952 | ||
755 | aaci->playback.pcm = &ac97_bus->pcms[0]; | 953 | aaci->playback.pcm = &ac97_bus->pcms[0]; |
954 | aaci->capture.pcm = &ac97_bus->pcms[1]; | ||
756 | 955 | ||
757 | out: | 956 | out: |
758 | return ret; | 957 | return ret; |
@@ -802,7 +1001,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) | |||
802 | struct snd_pcm *pcm; | 1001 | struct snd_pcm *pcm; |
803 | int ret; | 1002 | int ret; |
804 | 1003 | ||
805 | ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm); | 1004 | ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm); |
806 | if (ret == 0) { | 1005 | if (ret == 0) { |
807 | aaci->pcm = pcm; | 1006 | aaci->pcm = pcm; |
808 | pcm->private_data = aaci; | 1007 | pcm->private_data = aaci; |
@@ -811,6 +1010,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) | |||
811 | strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); | 1010 | strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); |
812 | 1011 | ||
813 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); | 1012 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); |
1013 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); | ||
814 | } | 1014 | } |
815 | 1015 | ||
816 | return ret; | 1016 | return ret; |
@@ -818,15 +1018,15 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) | |||
818 | 1018 | ||
819 | static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) | 1019 | static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) |
820 | { | 1020 | { |
821 | void __iomem *base = aaci->base + AACI_CSCH1; | 1021 | struct aaci_runtime *aacirun = &aaci->playback; |
822 | int i; | 1022 | int i; |
823 | 1023 | ||
824 | writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR); | 1024 | writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR); |
825 | 1025 | ||
826 | for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++) | 1026 | for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++) |
827 | writel(0, aaci->base + AACI_DR1); | 1027 | writel(0, aacirun->fifo); |
828 | 1028 | ||
829 | writel(0, base + AACI_TXCR); | 1029 | writel(0, aacirun->base + AACI_TXCR); |
830 | 1030 | ||
831 | /* | 1031 | /* |
832 | * Re-initialise the AACI after the FIFO depth test, to | 1032 | * Re-initialise the AACI after the FIFO depth test, to |
@@ -873,6 +1073,12 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id) | |||
873 | aaci->playback.base = aaci->base + AACI_CSCH1; | 1073 | aaci->playback.base = aaci->base + AACI_CSCH1; |
874 | aaci->playback.fifo = aaci->base + AACI_DR1; | 1074 | aaci->playback.fifo = aaci->base + AACI_DR1; |
875 | 1075 | ||
1076 | /* | ||
1077 | * Capture uses AACI channel 0 | ||
1078 | */ | ||
1079 | aaci->capture.base = aaci->base + AACI_CSCH1; | ||
1080 | aaci->capture.fifo = aaci->base + AACI_DR1; | ||
1081 | |||
876 | for (i = 0; i < 4; i++) { | 1082 | for (i = 0; i < 4; i++) { |
877 | void __iomem *base = aaci->base + i * 0x14; | 1083 | void __iomem *base = aaci->base + i * 0x14; |
878 | 1084 | ||
@@ -908,7 +1114,7 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id) | |||
908 | ret = snd_card_register(aaci->card); | 1114 | ret = snd_card_register(aaci->card); |
909 | if (ret == 0) { | 1115 | if (ret == 0) { |
910 | dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname, | 1116 | dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname, |
911 | aaci->fifosize); | 1117 | aaci->fifosize); |
912 | amba_set_drvdata(dev, aaci->card); | 1118 | amba_set_drvdata(dev, aaci->card); |
913 | return ret; | 1119 | return ret; |
914 | } | 1120 | } |
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 06295190606c..788c24afaf9f 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h | |||
@@ -49,27 +49,27 @@ | |||
49 | #define AACI_DR4 0x0f0 /* data read/written fifo 4 */ | 49 | #define AACI_DR4 0x0f0 /* data read/written fifo 4 */ |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * transmit fifo control register. P48 | 52 | * TX/RX fifo control register (CR). P48 |
53 | */ | 53 | */ |
54 | #define TXCR_FEN (1 << 16) /* fifo enable */ | 54 | #define CR_FEN (1 << 16) /* fifo enable */ |
55 | #define TXCR_COMPACT (1 << 15) /* compact mode */ | 55 | #define CR_COMPACT (1 << 15) /* compact mode */ |
56 | #define TXCR_TSZ16 (0 << 13) /* 16 bits */ | 56 | #define CR_SZ16 (0 << 13) /* 16 bits */ |
57 | #define TXCR_TSZ18 (1 << 13) /* 18 bits */ | 57 | #define CR_SZ18 (1 << 13) /* 18 bits */ |
58 | #define TXCR_TSZ20 (2 << 13) /* 20 bits */ | 58 | #define CR_SZ20 (2 << 13) /* 20 bits */ |
59 | #define TXCR_TSZ12 (3 << 13) /* 12 bits */ | 59 | #define CR_SZ12 (3 << 13) /* 12 bits */ |
60 | #define TXCR_TX12 (1 << 12) /* transmits slot 12 */ | 60 | #define CR_SL12 (1 << 12) |
61 | #define TXCR_TX11 (1 << 11) /* transmits slot 12 */ | 61 | #define CR_SL11 (1 << 11) |
62 | #define TXCR_TX10 (1 << 10) /* transmits slot 12 */ | 62 | #define CR_SL10 (1 << 10) |
63 | #define TXCR_TX9 (1 << 9) /* transmits slot 12 */ | 63 | #define CR_SL9 (1 << 9) |
64 | #define TXCR_TX8 (1 << 8) /* transmits slot 12 */ | 64 | #define CR_SL8 (1 << 8) |
65 | #define TXCR_TX7 (1 << 7) /* transmits slot 12 */ | 65 | #define CR_SL7 (1 << 7) |
66 | #define TXCR_TX6 (1 << 6) /* transmits slot 12 */ | 66 | #define CR_SL6 (1 << 6) |
67 | #define TXCR_TX5 (1 << 5) /* transmits slot 12 */ | 67 | #define CR_SL5 (1 << 5) |
68 | #define TXCR_TX4 (1 << 4) /* transmits slot 12 */ | 68 | #define CR_SL4 (1 << 4) |
69 | #define TXCR_TX3 (1 << 3) /* transmits slot 12 */ | 69 | #define CR_SL3 (1 << 3) |
70 | #define TXCR_TX2 (1 << 2) /* transmits slot 12 */ | 70 | #define CR_SL2 (1 << 2) |
71 | #define TXCR_TX1 (1 << 1) /* transmits slot 12 */ | 71 | #define CR_SL1 (1 << 1) |
72 | #define TXCR_TXEN (1 << 0) /* transmit enable */ | 72 | #define CR_EN (1 << 0) /* transmit enable */ |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * status register bits. P49 | 75 | * status register bits. P49 |
@@ -229,6 +229,7 @@ struct aaci { | |||
229 | /* AC'97 */ | 229 | /* AC'97 */ |
230 | struct mutex ac97_sem; | 230 | struct mutex ac97_sem; |
231 | ac97_bus_t *ac97_bus; | 231 | ac97_bus_t *ac97_bus; |
232 | ac97_t *ac97; | ||
232 | 233 | ||
233 | u32 maincr; | 234 | u32 maincr; |
234 | spinlock_t lock; | 235 | spinlock_t lock; |