aboutsummaryrefslogtreecommitdiffstats
path: root/sound/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 16:18:39 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 16:18:39 -0500
commit59b8175c771040afcd4ad67022b0cc80c216b866 (patch)
tree4ef5935bee1e342716d49b9d4b99e3fa835526e6 /sound/arm
parent920841d8d1d61bc12b43f95a579a5374f6d98f81 (diff)
parent3b0eb4a195a124567cd0dd6f700f8388def542c6 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (117 commits) [ARM] 4058/2: iop32x: set ->broken_parity_status on n2100 onboard r8169 ports [ARM] 4140/1: AACI stability add ac97 timeout and retries [ARM] 4139/1: AACI record support [ARM] 4138/1: AACI: multiple channel support for IRQ handling [ARM] 4211/1: Provide a defconfig for ns9xxx [ARM] 4210/1: base for new machine type "NetSilicon NS9360" [ARM] 4222/1: S3C2443: Remove reference to missing S3C2443_PM [ARM] 4221/1: S3C2443: DMA support [ARM] 4220/1: S3C24XX: DMA system initialised from sysdev [ARM] 4219/1: S3C2443: DMA source definitions [ARM] 4218/1: S3C2412: fix CONFIG_CPU_S3C2412_ONLY wrt to S3C2443 [ARM] 4217/1: S3C24XX: remove the dma channel show at startup [ARM] 4090/2: avoid clash between PXA and SA1111 defines [ARM] 4216/1: add .gitignore entries for ARM specific files [ARM] 4214/2: S3C2410: Add Armzone QT2410 [ARM] 4215/1: s3c2410 usb device: per-platform vbus_draw [ARM] 4213/1: S3C2410 - Update definition of ADCTSC_XY_PST [ARM] 4098/1: ARM: rtc_lock only used with rtc_cmos [ARM] 4137/1: Add kexec support [ARM] 4201/1: SMP barriers pair needed for the secondary boot process ... Fix up conflict due to typedef removal in sound/arm/aaci.h
Diffstat (limited to 'sound/arm')
-rw-r--r--sound/arm/aaci.c315
-rw-r--r--sound/arm/aaci.h41
2 files changed, 296 insertions, 60 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 53675cf4de44..5190d7acdb9f 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -65,10 +65,12 @@ static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
65 * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR 65 * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
66 * register. 66 * register.
67 */ 67 */
68static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 68static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
69 unsigned short val)
69{ 70{
70 struct aaci *aaci = ac97->private_data; 71 struct aaci *aaci = ac97->private_data;
71 u32 v; 72 u32 v;
73 int timeout = 5000;
72 74
73 if (ac97->num >= 4) 75 if (ac97->num >= 4)
74 return; 76 return;
@@ -89,7 +91,11 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
89 */ 91 */
90 do { 92 do {
91 v = readl(aaci->base + AACI_SLFR); 93 v = readl(aaci->base + AACI_SLFR);
92 } while (v & (SLFR_1TXB|SLFR_2TXB)); 94 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--);
95
96 if (!timeout)
97 dev_err(&aaci->dev->dev,
98 "timeout waiting for write to complete\n");
93 99
94 mutex_unlock(&aaci->ac97_sem); 100 mutex_unlock(&aaci->ac97_sem);
95} 101}
@@ -101,6 +107,8 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
101{ 107{
102 struct aaci *aaci = ac97->private_data; 108 struct aaci *aaci = ac97->private_data;
103 u32 v; 109 u32 v;
110 int timeout = 5000;
111 int retries = 10;
104 112
105 if (ac97->num >= 4) 113 if (ac97->num >= 4)
106 return ~0; 114 return ~0;
@@ -119,7 +127,13 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
119 */ 127 */
120 do { 128 do {
121 v = readl(aaci->base + AACI_SLFR); 129 v = readl(aaci->base + AACI_SLFR);
122 } while (v & SLFR_1TXB); 130 } while ((v & SLFR_1TXB) && timeout--);
131
132 if (!timeout) {
133 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
134 v = ~0;
135 goto out;
136 }
123 137
124 /* 138 /*
125 * Give the AC'97 codec more than enough time 139 * Give the AC'97 codec more than enough time
@@ -130,21 +144,35 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
130 /* 144 /*
131 * Wait for slot 2 to indicate data. 145 * Wait for slot 2 to indicate data.
132 */ 146 */
147 timeout = 5000;
133 do { 148 do {
134 cond_resched(); 149 cond_resched();
135 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); 150 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
136 } while (v != (SLFR_1RXV|SLFR_2RXV)); 151 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--);
137 152
138 v = readl(aaci->base + AACI_SL1RX) >> 12; 153 if (!timeout) {
139 if (v == reg) { 154 dev_err(&aaci->dev->dev, "timeout on RX valid\n");
140 v = readl(aaci->base + AACI_SL2RX) >> 4;
141 } else {
142 dev_err(&aaci->dev->dev,
143 "wrong ac97 register read back (%x != %x)\n",
144 v, reg);
145 v = ~0; 155 v = ~0;
156 goto out;
146 } 157 }
147 158
159 do {
160 v = readl(aaci->base + AACI_SL1RX) >> 12;
161 if (v == reg) {
162 v = readl(aaci->base + AACI_SL2RX) >> 4;
163 break;
164 } else if (--retries) {
165 dev_warn(&aaci->dev->dev,
166 "ac97 read back fail. retry\n");
167 continue;
168 } else {
169 dev_warn(&aaci->dev->dev,
170 "wrong ac97 register read back (%x != %x)\n",
171 v, reg);
172 v = ~0;
173 }
174 } while (retries);
175 out:
148 mutex_unlock(&aaci->ac97_sem); 176 mutex_unlock(&aaci->ac97_sem);
149 return v; 177 return v;
150} 178}
@@ -164,10 +192,70 @@ static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
164/* 192/*
165 * Interrupt support. 193 * Interrupt support.
166 */ 194 */
167static void aaci_fifo_irq(struct aaci *aaci, u32 mask) 195static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
168{ 196{
197 if (mask & ISR_ORINTR) {
198 dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel);
199 writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR);
200 }
201
202 if (mask & ISR_RXTOINTR) {
203 dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel);
204 writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR);
205 }
206
207 if (mask & ISR_RXINTR) {
208 struct aaci_runtime *aacirun = &aaci->capture;
209 void *ptr;
210
211 if (!aacirun->substream || !aacirun->start) {
212 dev_warn(&aaci->dev->dev, "RX interrupt???");
213 writel(0, aacirun->base + AACI_IE);
214 return;
215 }
216 ptr = aacirun->ptr;
217
218 do {
219 unsigned int len = aacirun->fifosz;
220 u32 val;
221
222 if (aacirun->bytes <= 0) {
223 aacirun->bytes += aacirun->period;
224 aacirun->ptr = ptr;
225 spin_unlock(&aaci->lock);
226 snd_pcm_period_elapsed(aacirun->substream);
227 spin_lock(&aaci->lock);
228 }
229 if (!(aacirun->cr & CR_EN))
230 break;
231
232 val = readl(aacirun->base + AACI_SR);
233 if (!(val & SR_RXHF))
234 break;
235 if (!(val & SR_RXFF))
236 len >>= 1;
237
238 aacirun->bytes -= len;
239
240 /* reading 16 bytes at a time */
241 for( ; len > 0; len -= 16) {
242 asm(
243 "ldmia %1, {r0, r1, r2, r3}\n\t"
244 "stmia %0!, {r0, r1, r2, r3}"
245 : "+r" (ptr)
246 : "r" (aacirun->fifo)
247 : "r0", "r1", "r2", "r3", "cc");
248
249 if (ptr >= aacirun->end)
250 ptr = aacirun->start;
251 }
252 } while(1);
253 aacirun->ptr = ptr;
254 }
255
169 if (mask & ISR_URINTR) { 256 if (mask & ISR_URINTR) {
170 writel(ICLR_TXUEC1, aaci->base + AACI_INTCLR); 257 dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel);
258 writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR);
171 } 259 }
172 260
173 if (mask & ISR_TXINTR) { 261 if (mask & ISR_TXINTR) {
@@ -192,7 +280,7 @@ static void aaci_fifo_irq(struct aaci *aaci, u32 mask)
192 snd_pcm_period_elapsed(aacirun->substream); 280 snd_pcm_period_elapsed(aacirun->substream);
193 spin_lock(&aaci->lock); 281 spin_lock(&aaci->lock);
194 } 282 }
195 if (!(aacirun->cr & TXCR_TXEN)) 283 if (!(aacirun->cr & CR_EN))
196 break; 284 break;
197 285
198 val = readl(aacirun->base + AACI_SR); 286 val = readl(aacirun->base + AACI_SR);
@@ -233,7 +321,7 @@ static irqreturn_t aaci_irq(int irq, void *devid)
233 u32 m = mask; 321 u32 m = mask;
234 for (i = 0; i < 4; i++, m >>= 7) { 322 for (i = 0; i < 4; i++, m >>= 7) {
235 if (m & 0x7f) { 323 if (m & 0x7f) {
236 aaci_fifo_irq(aaci, m); 324 aaci_fifo_irq(aaci, i, m);
237 } 325 }
238 } 326 }
239 } 327 }
@@ -330,8 +418,9 @@ static struct snd_pcm_hardware aaci_hw_info = {
330 .periods_max = PAGE_SIZE / 16, 418 .periods_max = PAGE_SIZE / 16,
331}; 419};
332 420
333static int aaci_pcm_open(struct aaci *aaci, struct snd_pcm_substream *substream, 421static int __aaci_pcm_open(struct aaci *aaci,
334 struct aaci_runtime *aacirun) 422 struct snd_pcm_substream *substream,
423 struct aaci_runtime *aacirun)
335{ 424{
336 struct snd_pcm_runtime *runtime = substream->runtime; 425 struct snd_pcm_runtime *runtime = substream->runtime;
337 int ret; 426 int ret;
@@ -380,7 +469,7 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream)
380 struct aaci *aaci = substream->private_data; 469 struct aaci *aaci = substream->private_data;
381 struct aaci_runtime *aacirun = substream->runtime->private_data; 470 struct aaci_runtime *aacirun = substream->runtime->private_data;
382 471
383 WARN_ON(aacirun->cr & TXCR_TXEN); 472 WARN_ON(aacirun->cr & CR_EN);
384 473
385 aacirun->substream = NULL; 474 aacirun->substream = NULL;
386 free_irq(aaci->dev->irq[0], aaci); 475 free_irq(aaci->dev->irq[0], aaci);
@@ -395,7 +484,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
395 /* 484 /*
396 * This must not be called with the device enabled. 485 * This must not be called with the device enabled.
397 */ 486 */
398 WARN_ON(aacirun->cr & TXCR_TXEN); 487 WARN_ON(aacirun->cr & CR_EN);
399 488
400 if (aacirun->pcm_open) 489 if (aacirun->pcm_open)
401 snd_ac97_pcm_close(aacirun->pcm); 490 snd_ac97_pcm_close(aacirun->pcm);
@@ -422,9 +511,15 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
422 if (err < 0) 511 if (err < 0)
423 goto out; 512 goto out;
424 513
425 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), 514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
426 params_channels(params), 515 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
427 aacirun->pcm->r[0].slots); 516 params_channels(params),
517 aacirun->pcm->r[0].slots);
518 else
519 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
520 params_channels(params),
521 aacirun->pcm->r[1].slots);
522
428 if (err) 523 if (err)
429 goto out; 524 goto out;
430 525
@@ -467,9 +562,9 @@ static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_str
467 * Playback specific ALSA stuff 562 * Playback specific ALSA stuff
468 */ 563 */
469static const u32 channels_to_txmask[] = { 564static const u32 channels_to_txmask[] = {
470 [2] = TXCR_TX3 | TXCR_TX4, 565 [2] = CR_SL3 | CR_SL4,
471 [4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8, 566 [4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8,
472 [6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9, 567 [6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9,
473}; 568};
474 569
475/* 570/*
@@ -504,7 +599,7 @@ aaci_rule_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
504 chan_mask); 599 chan_mask);
505} 600}
506 601
507static int aaci_pcm_playback_open(struct snd_pcm_substream *substream) 602static int aaci_pcm_open(struct snd_pcm_substream *substream)
508{ 603{
509 struct aaci *aaci = substream->private_data; 604 struct aaci *aaci = substream->private_data;
510 int ret; 605 int ret;
@@ -519,7 +614,12 @@ static int aaci_pcm_playback_open(struct snd_pcm_substream *substream)
519 if (ret) 614 if (ret)
520 return ret; 615 return ret;
521 616
522 return aaci_pcm_open(aaci, substream, &aaci->playback); 617 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
618 ret = __aaci_pcm_open(aaci, substream, &aaci->playback);
619 } else {
620 ret = __aaci_pcm_open(aaci, substream, &aaci->capture);
621 }
622 return ret;
523} 623}
524 624
525static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, 625static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
@@ -540,11 +640,11 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
540 * FIXME: double rate slots? 640 * FIXME: double rate slots?
541 */ 641 */
542 if (ret >= 0) { 642 if (ret >= 0) {
543 aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16; 643 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
544 aacirun->cr |= channels_to_txmask[channels]; 644 aacirun->cr |= channels_to_txmask[channels];
545 645
546 aacirun->fifosz = aaci->fifosize * 4; 646 aacirun->fifosz = aaci->fifosize * 4;
547 if (aacirun->cr & TXCR_COMPACT) 647 if (aacirun->cr & CR_COMPACT)
548 aacirun->fifosz >>= 1; 648 aacirun->fifosz >>= 1;
549 } 649 }
550 return ret; 650 return ret;
@@ -557,7 +657,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
557 ie = readl(aacirun->base + AACI_IE); 657 ie = readl(aacirun->base + AACI_IE);
558 ie &= ~(IE_URIE|IE_TXIE); 658 ie &= ~(IE_URIE|IE_TXIE);
559 writel(ie, aacirun->base + AACI_IE); 659 writel(ie, aacirun->base + AACI_IE);
560 aacirun->cr &= ~TXCR_TXEN; 660 aacirun->cr &= ~CR_EN;
561 aaci_chan_wait_ready(aacirun); 661 aaci_chan_wait_ready(aacirun);
562 writel(aacirun->cr, aacirun->base + AACI_TXCR); 662 writel(aacirun->cr, aacirun->base + AACI_TXCR);
563} 663}
@@ -567,7 +667,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
567 u32 ie; 667 u32 ie;
568 668
569 aaci_chan_wait_ready(aacirun); 669 aaci_chan_wait_ready(aacirun);
570 aacirun->cr |= TXCR_TXEN; 670 aacirun->cr |= CR_EN;
571 671
572 ie = readl(aacirun->base + AACI_IE); 672 ie = readl(aacirun->base + AACI_IE);
573 ie |= IE_URIE | IE_TXIE; 673 ie |= IE_URIE | IE_TXIE;
@@ -615,7 +715,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
615} 715}
616 716
617static struct snd_pcm_ops aaci_playback_ops = { 717static struct snd_pcm_ops aaci_playback_ops = {
618 .open = aaci_pcm_playback_open, 718 .open = aaci_pcm_open,
619 .close = aaci_pcm_close, 719 .close = aaci_pcm_close,
620 .ioctl = snd_pcm_lib_ioctl, 720 .ioctl = snd_pcm_lib_ioctl,
621 .hw_params = aaci_pcm_playback_hw_params, 721 .hw_params = aaci_pcm_playback_hw_params,
@@ -626,7 +726,133 @@ static struct snd_pcm_ops aaci_playback_ops = {
626 .mmap = aaci_pcm_mmap, 726 .mmap = aaci_pcm_mmap,
627}; 727};
628 728
729static int aaci_pcm_capture_hw_params(snd_pcm_substream_t *substream,
730 snd_pcm_hw_params_t *params)
731{
732 struct aaci *aaci = substream->private_data;
733 struct aaci_runtime *aacirun = substream->runtime->private_data;
734 int ret;
735
736 ret = aaci_pcm_hw_params(substream, aacirun, params);
737
738 if (ret >= 0) {
739 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
740
741 /* Line in record: slot 3 and 4 */
742 aacirun->cr |= CR_SL3 | CR_SL4;
743
744 aacirun->fifosz = aaci->fifosize * 4;
745
746 if (aacirun->cr & CR_COMPACT)
747 aacirun->fifosz >>= 1;
748 }
749 return ret;
750}
751
752static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
753{
754 u32 ie;
755
756 aaci_chan_wait_ready(aacirun);
757
758 ie = readl(aacirun->base + AACI_IE);
759 ie &= ~(IE_ORIE | IE_RXIE);
760 writel(ie, aacirun->base+AACI_IE);
761
762 aacirun->cr &= ~CR_EN;
763
764 writel(aacirun->cr, aacirun->base + AACI_RXCR);
765}
766
767static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
768{
769 u32 ie;
770
771 aaci_chan_wait_ready(aacirun);
772
773#ifdef DEBUG
774 /* RX Timeout value: bits 28:17 in RXCR */
775 aacirun->cr |= 0xf << 17;
776#endif
777
778 aacirun->cr |= CR_EN;
779 writel(aacirun->cr, aacirun->base + AACI_RXCR);
780
781 ie = readl(aacirun->base + AACI_IE);
782 ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full
783 writel(ie, aacirun->base + AACI_IE);
784}
785
786static int aaci_pcm_capture_trigger(snd_pcm_substream_t *substream, int cmd){
787
788 struct aaci *aaci = substream->private_data;
789 struct aaci_runtime *aacirun = substream->runtime->private_data;
790 unsigned long flags;
791 int ret = 0;
792
793 spin_lock_irqsave(&aaci->lock, flags);
794
795 switch (cmd) {
796 case SNDRV_PCM_TRIGGER_START:
797 aaci_pcm_capture_start(aacirun);
798 break;
799
800 case SNDRV_PCM_TRIGGER_RESUME:
801 aaci_pcm_capture_start(aacirun);
802 break;
803
804 case SNDRV_PCM_TRIGGER_STOP:
805 aaci_pcm_capture_stop(aacirun);
806 break;
807
808 case SNDRV_PCM_TRIGGER_SUSPEND:
809 aaci_pcm_capture_stop(aacirun);
810 break;
811
812 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
813 break;
814
815 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
816 break;
817
818 default:
819 ret = -EINVAL;
820 }
821
822 spin_unlock_irqrestore(&aaci->lock, flags);
823
824 return ret;
825}
629 826
827static int aaci_pcm_capture_prepare(snd_pcm_substream_t *substream)
828{
829 struct snd_pcm_runtime *runtime = substream->runtime;
830 struct aaci *aaci = substream->private_data;
831
832 aaci_pcm_prepare(substream);
833
834 /* allow changing of sample rate */
835 aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */
836 aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
837 aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
838
839 /* Record select: Mic: 0, Aux: 3, Line: 4 */
840 aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
841
842 return 0;
843}
844
845static snd_pcm_ops_t aaci_capture_ops = {
846 .open = aaci_pcm_open,
847 .close = aaci_pcm_close,
848 .ioctl = snd_pcm_lib_ioctl,
849 .hw_params = aaci_pcm_capture_hw_params,
850 .hw_free = aaci_pcm_hw_free,
851 .prepare = aaci_pcm_capture_prepare,
852 .trigger = aaci_pcm_capture_trigger,
853 .pointer = aaci_pcm_pointer,
854 .mmap = aaci_pcm_mmap,
855};
630 856
631/* 857/*
632 * Power Management. 858 * Power Management.
@@ -666,7 +892,7 @@ static int aaci_resume(struct amba_device *dev)
666 892
667 893
668static struct ac97_pcm ac97_defs[] __devinitdata = { 894static struct ac97_pcm ac97_defs[] __devinitdata = {
669 [0] = { /* Front PCM */ 895 [0] = { /* Front PCM */
670 .exclusive = 1, 896 .exclusive = 1,
671 .r = { 897 .r = {
672 [0] = { 898 [0] = {
@@ -740,6 +966,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
740 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); 966 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
741 if (ret) 967 if (ret)
742 goto out; 968 goto out;
969 aaci->ac97 = ac97;
743 970
744 /* 971 /*
745 * Disable AC97 PC Beep input on audio codecs. 972 * Disable AC97 PC Beep input on audio codecs.
@@ -752,6 +979,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
752 goto out; 979 goto out;
753 980
754 aaci->playback.pcm = &ac97_bus->pcms[0]; 981 aaci->playback.pcm = &ac97_bus->pcms[0];
982 aaci->capture.pcm = &ac97_bus->pcms[1];
755 983
756 out: 984 out:
757 return ret; 985 return ret;
@@ -801,7 +1029,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
801 struct snd_pcm *pcm; 1029 struct snd_pcm *pcm;
802 int ret; 1030 int ret;
803 1031
804 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm); 1032 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm);
805 if (ret == 0) { 1033 if (ret == 0) {
806 aaci->pcm = pcm; 1034 aaci->pcm = pcm;
807 pcm->private_data = aaci; 1035 pcm->private_data = aaci;
@@ -810,6 +1038,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
810 strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); 1038 strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
811 1039
812 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); 1040 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
1041 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
813 } 1042 }
814 1043
815 return ret; 1044 return ret;
@@ -817,15 +1046,15 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
817 1046
818static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) 1047static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
819{ 1048{
820 void __iomem *base = aaci->base + AACI_CSCH1; 1049 struct aaci_runtime *aacirun = &aaci->playback;
821 int i; 1050 int i;
822 1051
823 writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR); 1052 writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR);
824 1053
825 for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++) 1054 for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++)
826 writel(0, aaci->base + AACI_DR1); 1055 writel(0, aacirun->fifo);
827 1056
828 writel(0, base + AACI_TXCR); 1057 writel(0, aacirun->base + AACI_TXCR);
829 1058
830 /* 1059 /*
831 * Re-initialise the AACI after the FIFO depth test, to 1060 * Re-initialise the AACI after the FIFO depth test, to
@@ -872,6 +1101,12 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
872 aaci->playback.base = aaci->base + AACI_CSCH1; 1101 aaci->playback.base = aaci->base + AACI_CSCH1;
873 aaci->playback.fifo = aaci->base + AACI_DR1; 1102 aaci->playback.fifo = aaci->base + AACI_DR1;
874 1103
1104 /*
1105 * Capture uses AACI channel 0
1106 */
1107 aaci->capture.base = aaci->base + AACI_CSCH1;
1108 aaci->capture.fifo = aaci->base + AACI_DR1;
1109
875 for (i = 0; i < 4; i++) { 1110 for (i = 0; i < 4; i++) {
876 void __iomem *base = aaci->base + i * 0x14; 1111 void __iomem *base = aaci->base + i * 0x14;
877 1112
@@ -907,7 +1142,7 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
907 ret = snd_card_register(aaci->card); 1142 ret = snd_card_register(aaci->card);
908 if (ret == 0) { 1143 if (ret == 0) {
909 dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname, 1144 dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
910 aaci->fifosize); 1145 aaci->fifosize);
911 amba_set_drvdata(dev, aaci->card); 1146 amba_set_drvdata(dev, aaci->card);
912 return ret; 1147 return ret;
913 } 1148 }
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index 9175ff9ded01..924f69c1c44c 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 struct snd_ac97_bus *ac97_bus; 231 struct snd_ac97_bus *ac97_bus;
232 struct snd_ac97 *ac97;
232 233
233 u32 maincr; 234 u32 maincr;
234 spinlock_t lock; 235 spinlock_t lock;