0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/delay.h>
0011 #include <linux/init.h>
0012 #include <linux/ioport.h>
0013 #include <linux/device.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/err.h>
0017 #include <linux/amba/bus.h>
0018 #include <linux/io.h>
0019
0020 #include <sound/core.h>
0021 #include <sound/initval.h>
0022 #include <sound/ac97_codec.h>
0023 #include <sound/pcm.h>
0024 #include <sound/pcm_params.h>
0025
0026 #include "aaci.h"
0027
0028 #define DRIVER_NAME "aaci-pl041"
0029
0030 #define FRAME_PERIOD_US 21
0031
0032
0033
0034
0035 #undef CONFIG_PM
0036
0037 static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
0038 {
0039 u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num);
0040
0041
0042
0043
0044 v = readl(aaci->base + AACI_SLFR);
0045 if (v & SLFR_2RXV)
0046 readl(aaci->base + AACI_SL2RX);
0047 if (v & SLFR_1RXV)
0048 readl(aaci->base + AACI_SL1RX);
0049
0050 if (maincr != readl(aaci->base + AACI_MAINCR)) {
0051 writel(maincr, aaci->base + AACI_MAINCR);
0052 readl(aaci->base + AACI_MAINCR);
0053 udelay(1);
0054 }
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
0067 unsigned short val)
0068 {
0069 struct aaci *aaci = ac97->private_data;
0070 int timeout;
0071 u32 v;
0072
0073 if (ac97->num >= 4)
0074 return;
0075
0076 mutex_lock(&aaci->ac97_sem);
0077
0078 aaci_ac97_select_codec(aaci, ac97);
0079
0080
0081
0082
0083
0084 writel(val << 4, aaci->base + AACI_SL2TX);
0085 writel(reg << 12, aaci->base + AACI_SL1TX);
0086
0087
0088 udelay(FRAME_PERIOD_US);
0089
0090
0091 timeout = FRAME_PERIOD_US * 8;
0092 do {
0093 udelay(1);
0094 v = readl(aaci->base + AACI_SLFR);
0095 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
0096
0097 if (v & (SLFR_1TXB|SLFR_2TXB))
0098 dev_err(&aaci->dev->dev,
0099 "timeout waiting for write to complete\n");
0100
0101 mutex_unlock(&aaci->ac97_sem);
0102 }
0103
0104
0105
0106
0107 static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
0108 {
0109 struct aaci *aaci = ac97->private_data;
0110 int timeout, retries = 10;
0111 u32 v;
0112
0113 if (ac97->num >= 4)
0114 return ~0;
0115
0116 mutex_lock(&aaci->ac97_sem);
0117
0118 aaci_ac97_select_codec(aaci, ac97);
0119
0120
0121
0122
0123 writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
0124
0125
0126 udelay(FRAME_PERIOD_US);
0127
0128
0129 timeout = FRAME_PERIOD_US * 8;
0130 do {
0131 udelay(1);
0132 v = readl(aaci->base + AACI_SLFR);
0133 } while ((v & SLFR_1TXB) && --timeout);
0134
0135 if (v & SLFR_1TXB) {
0136 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
0137 v = ~0;
0138 goto out;
0139 }
0140
0141
0142 udelay(FRAME_PERIOD_US);
0143
0144
0145 timeout = FRAME_PERIOD_US * 8;
0146 do {
0147 udelay(1);
0148 cond_resched();
0149 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
0150 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
0151
0152 if (v != (SLFR_1RXV|SLFR_2RXV)) {
0153 dev_err(&aaci->dev->dev, "timeout on RX valid\n");
0154 v = ~0;
0155 goto out;
0156 }
0157
0158 do {
0159 v = readl(aaci->base + AACI_SL1RX) >> 12;
0160 if (v == reg) {
0161 v = readl(aaci->base + AACI_SL2RX) >> 4;
0162 break;
0163 } else if (--retries) {
0164 dev_warn(&aaci->dev->dev,
0165 "ac97 read back fail. retry\n");
0166 continue;
0167 } else {
0168 dev_warn(&aaci->dev->dev,
0169 "wrong ac97 register read back (%x != %x)\n",
0170 v, reg);
0171 v = ~0;
0172 }
0173 } while (retries);
0174 out:
0175 mutex_unlock(&aaci->ac97_sem);
0176 return v;
0177 }
0178
0179 static inline void
0180 aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
0181 {
0182 u32 val;
0183 int timeout = 5000;
0184
0185 do {
0186 udelay(1);
0187 val = readl(aacirun->base + AACI_SR);
0188 } while (val & mask && timeout--);
0189 }
0190
0191
0192
0193
0194
0195
0196 static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
0197 {
0198 if (mask & ISR_ORINTR) {
0199 dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel);
0200 writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR);
0201 }
0202
0203 if (mask & ISR_RXTOINTR) {
0204 dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel);
0205 writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR);
0206 }
0207
0208 if (mask & ISR_RXINTR) {
0209 struct aaci_runtime *aacirun = &aaci->capture;
0210 bool period_elapsed = false;
0211 void *ptr;
0212
0213 if (!aacirun->substream || !aacirun->start) {
0214 dev_warn(&aaci->dev->dev, "RX interrupt???\n");
0215 writel(0, aacirun->base + AACI_IE);
0216 return;
0217 }
0218
0219 spin_lock(&aacirun->lock);
0220
0221 ptr = aacirun->ptr;
0222 do {
0223 unsigned int len = aacirun->fifo_bytes;
0224 u32 val;
0225
0226 if (aacirun->bytes <= 0) {
0227 aacirun->bytes += aacirun->period;
0228 period_elapsed = true;
0229 }
0230 if (!(aacirun->cr & CR_EN))
0231 break;
0232
0233 val = readl(aacirun->base + AACI_SR);
0234 if (!(val & SR_RXHF))
0235 break;
0236 if (!(val & SR_RXFF))
0237 len >>= 1;
0238
0239 aacirun->bytes -= len;
0240
0241
0242 for( ; len > 0; len -= 16) {
0243 asm(
0244 "ldmia %1, {r0, r1, r2, r3}\n\t"
0245 "stmia %0!, {r0, r1, r2, r3}"
0246 : "+r" (ptr)
0247 : "r" (aacirun->fifo)
0248 : "r0", "r1", "r2", "r3", "cc");
0249
0250 if (ptr >= aacirun->end)
0251 ptr = aacirun->start;
0252 }
0253 } while(1);
0254
0255 aacirun->ptr = ptr;
0256
0257 spin_unlock(&aacirun->lock);
0258
0259 if (period_elapsed)
0260 snd_pcm_period_elapsed(aacirun->substream);
0261 }
0262
0263 if (mask & ISR_URINTR) {
0264 dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel);
0265 writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR);
0266 }
0267
0268 if (mask & ISR_TXINTR) {
0269 struct aaci_runtime *aacirun = &aaci->playback;
0270 bool period_elapsed = false;
0271 void *ptr;
0272
0273 if (!aacirun->substream || !aacirun->start) {
0274 dev_warn(&aaci->dev->dev, "TX interrupt???\n");
0275 writel(0, aacirun->base + AACI_IE);
0276 return;
0277 }
0278
0279 spin_lock(&aacirun->lock);
0280
0281 ptr = aacirun->ptr;
0282 do {
0283 unsigned int len = aacirun->fifo_bytes;
0284 u32 val;
0285
0286 if (aacirun->bytes <= 0) {
0287 aacirun->bytes += aacirun->period;
0288 period_elapsed = true;
0289 }
0290 if (!(aacirun->cr & CR_EN))
0291 break;
0292
0293 val = readl(aacirun->base + AACI_SR);
0294 if (!(val & SR_TXHE))
0295 break;
0296 if (!(val & SR_TXFE))
0297 len >>= 1;
0298
0299 aacirun->bytes -= len;
0300
0301
0302 for ( ; len > 0; len -= 16) {
0303 asm(
0304 "ldmia %0!, {r0, r1, r2, r3}\n\t"
0305 "stmia %1, {r0, r1, r2, r3}"
0306 : "+r" (ptr)
0307 : "r" (aacirun->fifo)
0308 : "r0", "r1", "r2", "r3", "cc");
0309
0310 if (ptr >= aacirun->end)
0311 ptr = aacirun->start;
0312 }
0313 } while (1);
0314
0315 aacirun->ptr = ptr;
0316
0317 spin_unlock(&aacirun->lock);
0318
0319 if (period_elapsed)
0320 snd_pcm_period_elapsed(aacirun->substream);
0321 }
0322 }
0323
0324 static irqreturn_t aaci_irq(int irq, void *devid)
0325 {
0326 struct aaci *aaci = devid;
0327 u32 mask;
0328 int i;
0329
0330 mask = readl(aaci->base + AACI_ALLINTS);
0331 if (mask) {
0332 u32 m = mask;
0333 for (i = 0; i < 4; i++, m >>= 7) {
0334 if (m & 0x7f) {
0335 aaci_fifo_irq(aaci, i, m);
0336 }
0337 }
0338 }
0339
0340 return mask ? IRQ_HANDLED : IRQ_NONE;
0341 }
0342
0343
0344
0345
0346
0347
0348 static const struct snd_pcm_hardware aaci_hw_info = {
0349 .info = SNDRV_PCM_INFO_MMAP |
0350 SNDRV_PCM_INFO_MMAP_VALID |
0351 SNDRV_PCM_INFO_INTERLEAVED |
0352 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0353 SNDRV_PCM_INFO_RESUME,
0354
0355
0356
0357
0358
0359 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0360
0361
0362 .channels_min = 2,
0363 .channels_max = 2,
0364 .buffer_bytes_max = 64 * 1024,
0365 .period_bytes_min = 256,
0366 .period_bytes_max = PAGE_SIZE,
0367 .periods_min = 4,
0368 .periods_max = PAGE_SIZE / 16,
0369 };
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static int aaci_rule_channels(struct snd_pcm_hw_params *p,
0381 struct snd_pcm_hw_rule *rule)
0382 {
0383 static const unsigned int channel_list[] = { 2, 4, 6 };
0384 struct aaci *aaci = rule->private;
0385 unsigned int mask = 1 << 0, slots;
0386
0387
0388 slots = aaci->ac97_bus->pcms[0].r[0].slots;
0389 if (slots & (1 << AC97_SLOT_PCM_SLEFT)) {
0390 mask |= 1 << 1;
0391 if (slots & (1 << AC97_SLOT_LFE))
0392 mask |= 1 << 2;
0393 }
0394
0395 return snd_interval_list(hw_param_interval(p, rule->var),
0396 ARRAY_SIZE(channel_list), channel_list, mask);
0397 }
0398
0399 static int aaci_pcm_open(struct snd_pcm_substream *substream)
0400 {
0401 struct snd_pcm_runtime *runtime = substream->runtime;
0402 struct aaci *aaci = substream->private_data;
0403 struct aaci_runtime *aacirun;
0404 int ret = 0;
0405
0406 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0407 aacirun = &aaci->playback;
0408 } else {
0409 aacirun = &aaci->capture;
0410 }
0411
0412 aacirun->substream = substream;
0413 runtime->private_data = aacirun;
0414 runtime->hw = aaci_hw_info;
0415 runtime->hw.rates = aacirun->pcm->rates;
0416 snd_pcm_limit_hw_rates(runtime);
0417
0418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0419 runtime->hw.channels_max = 6;
0420
0421
0422 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
0423 SNDRV_PCM_HW_PARAM_CHANNELS,
0424 aaci_rule_channels, aaci,
0425 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
0426 if (ret)
0427 return ret;
0428
0429 if (aacirun->pcm->r[1].slots)
0430 snd_ac97_pcm_double_rate_rules(runtime);
0431 }
0432
0433
0434
0435
0436
0437
0438 runtime->hw.fifo_size = aaci->fifo_depth * 2;
0439
0440 mutex_lock(&aaci->irq_lock);
0441 if (!aaci->users++) {
0442 ret = request_irq(aaci->dev->irq[0], aaci_irq,
0443 IRQF_SHARED, DRIVER_NAME, aaci);
0444 if (ret != 0)
0445 aaci->users--;
0446 }
0447 mutex_unlock(&aaci->irq_lock);
0448
0449 return ret;
0450 }
0451
0452
0453
0454
0455
0456 static int aaci_pcm_close(struct snd_pcm_substream *substream)
0457 {
0458 struct aaci *aaci = substream->private_data;
0459 struct aaci_runtime *aacirun = substream->runtime->private_data;
0460
0461 WARN_ON(aacirun->cr & CR_EN);
0462
0463 aacirun->substream = NULL;
0464
0465 mutex_lock(&aaci->irq_lock);
0466 if (!--aaci->users)
0467 free_irq(aaci->dev->irq[0], aaci);
0468 mutex_unlock(&aaci->irq_lock);
0469
0470 return 0;
0471 }
0472
0473 static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
0474 {
0475 struct aaci_runtime *aacirun = substream->runtime->private_data;
0476
0477
0478
0479
0480 WARN_ON(aacirun->cr & CR_EN);
0481
0482 if (aacirun->pcm_open)
0483 snd_ac97_pcm_close(aacirun->pcm);
0484 aacirun->pcm_open = 0;
0485
0486 return 0;
0487 }
0488
0489
0490 static const u32 channels_to_slotmask[] = {
0491 [2] = CR_SL3 | CR_SL4,
0492 [4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8,
0493 [6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9,
0494 };
0495
0496 static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
0497 struct snd_pcm_hw_params *params)
0498 {
0499 struct aaci_runtime *aacirun = substream->runtime->private_data;
0500 struct aaci *aaci = substream->private_data;
0501 unsigned int channels = params_channels(params);
0502 unsigned int rate = params_rate(params);
0503 int dbl = rate > 48000;
0504 int err;
0505
0506 aaci_pcm_hw_free(substream);
0507 if (aacirun->pcm_open) {
0508 snd_ac97_pcm_close(aacirun->pcm);
0509 aacirun->pcm_open = 0;
0510 }
0511
0512
0513 if (dbl && channels != 2)
0514 return -EINVAL;
0515
0516 err = snd_ac97_pcm_open(aacirun->pcm, rate, channels,
0517 aacirun->pcm->r[dbl].slots);
0518
0519 aacirun->pcm_open = err == 0;
0520 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
0521 aacirun->cr |= channels_to_slotmask[channels + dbl * 2];
0522
0523
0524
0525
0526
0527
0528 aacirun->fifo_bytes = aaci->fifo_depth * 4 / 2;
0529
0530 return err;
0531 }
0532
0533 static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
0534 {
0535 struct snd_pcm_runtime *runtime = substream->runtime;
0536 struct aaci_runtime *aacirun = runtime->private_data;
0537
0538 aacirun->period = snd_pcm_lib_period_bytes(substream);
0539 aacirun->start = runtime->dma_area;
0540 aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
0541 aacirun->ptr = aacirun->start;
0542 aacirun->bytes = aacirun->period;
0543
0544 return 0;
0545 }
0546
0547 static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
0548 {
0549 struct snd_pcm_runtime *runtime = substream->runtime;
0550 struct aaci_runtime *aacirun = runtime->private_data;
0551 ssize_t bytes = aacirun->ptr - aacirun->start;
0552
0553 return bytes_to_frames(runtime, bytes);
0554 }
0555
0556
0557
0558
0559
0560 static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
0561 {
0562 u32 ie;
0563
0564 ie = readl(aacirun->base + AACI_IE);
0565 ie &= ~(IE_URIE|IE_TXIE);
0566 writel(ie, aacirun->base + AACI_IE);
0567 aacirun->cr &= ~CR_EN;
0568 aaci_chan_wait_ready(aacirun, SR_TXB);
0569 writel(aacirun->cr, aacirun->base + AACI_TXCR);
0570 }
0571
0572 static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
0573 {
0574 u32 ie;
0575
0576 aaci_chan_wait_ready(aacirun, SR_TXB);
0577 aacirun->cr |= CR_EN;
0578
0579 ie = readl(aacirun->base + AACI_IE);
0580 ie |= IE_URIE | IE_TXIE;
0581 writel(ie, aacirun->base + AACI_IE);
0582 writel(aacirun->cr, aacirun->base + AACI_TXCR);
0583 }
0584
0585 static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
0586 {
0587 struct aaci_runtime *aacirun = substream->runtime->private_data;
0588 unsigned long flags;
0589 int ret = 0;
0590
0591 spin_lock_irqsave(&aacirun->lock, flags);
0592
0593 switch (cmd) {
0594 case SNDRV_PCM_TRIGGER_START:
0595 aaci_pcm_playback_start(aacirun);
0596 break;
0597
0598 case SNDRV_PCM_TRIGGER_RESUME:
0599 aaci_pcm_playback_start(aacirun);
0600 break;
0601
0602 case SNDRV_PCM_TRIGGER_STOP:
0603 aaci_pcm_playback_stop(aacirun);
0604 break;
0605
0606 case SNDRV_PCM_TRIGGER_SUSPEND:
0607 aaci_pcm_playback_stop(aacirun);
0608 break;
0609
0610 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0611 break;
0612
0613 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0614 break;
0615
0616 default:
0617 ret = -EINVAL;
0618 }
0619
0620 spin_unlock_irqrestore(&aacirun->lock, flags);
0621
0622 return ret;
0623 }
0624
0625 static const struct snd_pcm_ops aaci_playback_ops = {
0626 .open = aaci_pcm_open,
0627 .close = aaci_pcm_close,
0628 .hw_params = aaci_pcm_hw_params,
0629 .hw_free = aaci_pcm_hw_free,
0630 .prepare = aaci_pcm_prepare,
0631 .trigger = aaci_pcm_playback_trigger,
0632 .pointer = aaci_pcm_pointer,
0633 };
0634
0635 static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
0636 {
0637 u32 ie;
0638
0639 aaci_chan_wait_ready(aacirun, SR_RXB);
0640
0641 ie = readl(aacirun->base + AACI_IE);
0642 ie &= ~(IE_ORIE | IE_RXIE);
0643 writel(ie, aacirun->base+AACI_IE);
0644
0645 aacirun->cr &= ~CR_EN;
0646
0647 writel(aacirun->cr, aacirun->base + AACI_RXCR);
0648 }
0649
0650 static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
0651 {
0652 u32 ie;
0653
0654 aaci_chan_wait_ready(aacirun, SR_RXB);
0655
0656 #ifdef DEBUG
0657
0658 aacirun->cr |= 0xf << 17;
0659 #endif
0660
0661 aacirun->cr |= CR_EN;
0662 writel(aacirun->cr, aacirun->base + AACI_RXCR);
0663
0664 ie = readl(aacirun->base + AACI_IE);
0665 ie |= IE_ORIE |IE_RXIE;
0666 writel(ie, aacirun->base + AACI_IE);
0667 }
0668
0669 static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
0670 {
0671 struct aaci_runtime *aacirun = substream->runtime->private_data;
0672 unsigned long flags;
0673 int ret = 0;
0674
0675 spin_lock_irqsave(&aacirun->lock, flags);
0676
0677 switch (cmd) {
0678 case SNDRV_PCM_TRIGGER_START:
0679 aaci_pcm_capture_start(aacirun);
0680 break;
0681
0682 case SNDRV_PCM_TRIGGER_RESUME:
0683 aaci_pcm_capture_start(aacirun);
0684 break;
0685
0686 case SNDRV_PCM_TRIGGER_STOP:
0687 aaci_pcm_capture_stop(aacirun);
0688 break;
0689
0690 case SNDRV_PCM_TRIGGER_SUSPEND:
0691 aaci_pcm_capture_stop(aacirun);
0692 break;
0693
0694 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0695 break;
0696
0697 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0698 break;
0699
0700 default:
0701 ret = -EINVAL;
0702 }
0703
0704 spin_unlock_irqrestore(&aacirun->lock, flags);
0705
0706 return ret;
0707 }
0708
0709 static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream)
0710 {
0711 struct snd_pcm_runtime *runtime = substream->runtime;
0712 struct aaci *aaci = substream->private_data;
0713
0714 aaci_pcm_prepare(substream);
0715
0716
0717 aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001);
0718 aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
0719 aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
0720
0721
0722 aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
0723
0724 return 0;
0725 }
0726
0727 static const struct snd_pcm_ops aaci_capture_ops = {
0728 .open = aaci_pcm_open,
0729 .close = aaci_pcm_close,
0730 .hw_params = aaci_pcm_hw_params,
0731 .hw_free = aaci_pcm_hw_free,
0732 .prepare = aaci_pcm_capture_prepare,
0733 .trigger = aaci_pcm_capture_trigger,
0734 .pointer = aaci_pcm_pointer,
0735 };
0736
0737
0738
0739
0740 #ifdef CONFIG_PM
0741 static int aaci_do_suspend(struct snd_card *card)
0742 {
0743 struct aaci *aaci = card->private_data;
0744 snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
0745 return 0;
0746 }
0747
0748 static int aaci_do_resume(struct snd_card *card)
0749 {
0750 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
0751 return 0;
0752 }
0753
0754 static int aaci_suspend(struct device *dev)
0755 {
0756 struct snd_card *card = dev_get_drvdata(dev);
0757 return card ? aaci_do_suspend(card) : 0;
0758 }
0759
0760 static int aaci_resume(struct device *dev)
0761 {
0762 struct snd_card *card = dev_get_drvdata(dev);
0763 return card ? aaci_do_resume(card) : 0;
0764 }
0765
0766 static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume);
0767 #define AACI_DEV_PM_OPS (&aaci_dev_pm_ops)
0768 #else
0769 #define AACI_DEV_PM_OPS NULL
0770 #endif
0771
0772
0773 static const struct ac97_pcm ac97_defs[] = {
0774 [0] = {
0775 .exclusive = 1,
0776 .r = {
0777 [0] = {
0778 .slots = (1 << AC97_SLOT_PCM_LEFT) |
0779 (1 << AC97_SLOT_PCM_RIGHT) |
0780 (1 << AC97_SLOT_PCM_CENTER) |
0781 (1 << AC97_SLOT_PCM_SLEFT) |
0782 (1 << AC97_SLOT_PCM_SRIGHT) |
0783 (1 << AC97_SLOT_LFE),
0784 },
0785 [1] = {
0786 .slots = (1 << AC97_SLOT_PCM_LEFT) |
0787 (1 << AC97_SLOT_PCM_RIGHT) |
0788 (1 << AC97_SLOT_PCM_LEFT_0) |
0789 (1 << AC97_SLOT_PCM_RIGHT_0),
0790 },
0791 },
0792 },
0793 [1] = {
0794 .stream = 1,
0795 .exclusive = 1,
0796 .r = {
0797 [0] = {
0798 .slots = (1 << AC97_SLOT_PCM_LEFT) |
0799 (1 << AC97_SLOT_PCM_RIGHT),
0800 },
0801 },
0802 },
0803 [2] = {
0804 .stream = 1,
0805 .exclusive = 1,
0806 .r = {
0807 [0] = {
0808 .slots = (1 << AC97_SLOT_MIC),
0809 },
0810 },
0811 }
0812 };
0813
0814 static const struct snd_ac97_bus_ops aaci_bus_ops = {
0815 .write = aaci_ac97_write,
0816 .read = aaci_ac97_read,
0817 };
0818
0819 static int aaci_probe_ac97(struct aaci *aaci)
0820 {
0821 struct snd_ac97_template ac97_template;
0822 struct snd_ac97_bus *ac97_bus;
0823 struct snd_ac97 *ac97;
0824 int ret;
0825
0826
0827
0828
0829 writel(0, aaci->base + AACI_RESET);
0830 udelay(2);
0831 writel(RESET_NRST, aaci->base + AACI_RESET);
0832
0833
0834
0835
0836
0837 udelay(FRAME_PERIOD_US * 2);
0838
0839 ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
0840 if (ret)
0841 goto out;
0842
0843 ac97_bus->clock = 48000;
0844 aaci->ac97_bus = ac97_bus;
0845
0846 memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
0847 ac97_template.private_data = aaci;
0848 ac97_template.num = 0;
0849 ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
0850
0851 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
0852 if (ret)
0853 goto out;
0854 aaci->ac97 = ac97;
0855
0856
0857
0858
0859 if (ac97_is_audio(ac97))
0860 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x801e);
0861
0862 ret = snd_ac97_pcm_assign(ac97_bus, ARRAY_SIZE(ac97_defs), ac97_defs);
0863 if (ret)
0864 goto out;
0865
0866 aaci->playback.pcm = &ac97_bus->pcms[0];
0867 aaci->capture.pcm = &ac97_bus->pcms[1];
0868
0869 out:
0870 return ret;
0871 }
0872
0873 static void aaci_free_card(struct snd_card *card)
0874 {
0875 struct aaci *aaci = card->private_data;
0876
0877 iounmap(aaci->base);
0878 }
0879
0880 static struct aaci *aaci_init_card(struct amba_device *dev)
0881 {
0882 struct aaci *aaci;
0883 struct snd_card *card;
0884 int err;
0885
0886 err = snd_card_new(&dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
0887 THIS_MODULE, sizeof(struct aaci), &card);
0888 if (err < 0)
0889 return NULL;
0890
0891 card->private_free = aaci_free_card;
0892
0893 strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
0894 strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
0895 snprintf(card->longname, sizeof(card->longname),
0896 "%s PL%03x rev%u at 0x%08llx, irq %d",
0897 card->shortname, amba_part(dev), amba_rev(dev),
0898 (unsigned long long)dev->res.start, dev->irq[0]);
0899
0900 aaci = card->private_data;
0901 mutex_init(&aaci->ac97_sem);
0902 mutex_init(&aaci->irq_lock);
0903 aaci->card = card;
0904 aaci->dev = dev;
0905
0906
0907 aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN |
0908 MAINCR_SL2RXEN | MAINCR_SL2TXEN;
0909
0910 return aaci;
0911 }
0912
0913 static int aaci_init_pcm(struct aaci *aaci)
0914 {
0915 struct snd_pcm *pcm;
0916 int ret;
0917
0918 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm);
0919 if (ret == 0) {
0920 aaci->pcm = pcm;
0921 pcm->private_data = aaci;
0922 pcm->info_flags = 0;
0923
0924 strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
0925
0926 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
0927 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
0928 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0929 aaci->card->dev,
0930 0, 64 * 1024);
0931 }
0932
0933 return ret;
0934 }
0935
0936 static unsigned int aaci_size_fifo(struct aaci *aaci)
0937 {
0938 struct aaci_runtime *aacirun = &aaci->playback;
0939 int i;
0940
0941
0942
0943
0944
0945 writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR);
0946
0947 for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++)
0948 writel(0, aacirun->fifo);
0949
0950 writel(0, aacirun->base + AACI_TXCR);
0951
0952
0953
0954
0955
0956
0957 writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR);
0958 readl(aaci->base + AACI_MAINCR);
0959 udelay(1);
0960 writel(aaci->maincr, aaci->base + AACI_MAINCR);
0961
0962
0963
0964
0965
0966 if (i == 4096)
0967 i = 8;
0968
0969 return i;
0970 }
0971
0972 static int aaci_probe(struct amba_device *dev,
0973 const struct amba_id *id)
0974 {
0975 struct aaci *aaci;
0976 int ret, i;
0977
0978 ret = amba_request_regions(dev, NULL);
0979 if (ret)
0980 return ret;
0981
0982 aaci = aaci_init_card(dev);
0983 if (!aaci) {
0984 ret = -ENOMEM;
0985 goto out;
0986 }
0987
0988 aaci->base = ioremap(dev->res.start, resource_size(&dev->res));
0989 if (!aaci->base) {
0990 ret = -ENOMEM;
0991 goto out;
0992 }
0993
0994
0995
0996
0997 spin_lock_init(&aaci->playback.lock);
0998 aaci->playback.base = aaci->base + AACI_CSCH1;
0999 aaci->playback.fifo = aaci->base + AACI_DR1;
1000
1001
1002
1003
1004 spin_lock_init(&aaci->capture.lock);
1005 aaci->capture.base = aaci->base + AACI_CSCH1;
1006 aaci->capture.fifo = aaci->base + AACI_DR1;
1007
1008 for (i = 0; i < 4; i++) {
1009 void __iomem *base = aaci->base + i * 0x14;
1010
1011 writel(0, base + AACI_IE);
1012 writel(0, base + AACI_TXCR);
1013 writel(0, base + AACI_RXCR);
1014 }
1015
1016 writel(0x1fff, aaci->base + AACI_INTCLR);
1017 writel(aaci->maincr, aaci->base + AACI_MAINCR);
1018
1019
1020
1021
1022 readl(aaci->base + AACI_CSCH1);
1023 ret = aaci_probe_ac97(aaci);
1024 if (ret)
1025 goto out;
1026
1027
1028
1029
1030
1031 aaci->fifo_depth = aaci_size_fifo(aaci);
1032 if (aaci->fifo_depth & 15) {
1033 printk(KERN_WARNING "AACI: FIFO depth %d not supported\n",
1034 aaci->fifo_depth);
1035 ret = -ENODEV;
1036 goto out;
1037 }
1038
1039 ret = aaci_init_pcm(aaci);
1040 if (ret)
1041 goto out;
1042
1043 ret = snd_card_register(aaci->card);
1044 if (ret == 0) {
1045 dev_info(&dev->dev, "%s\n", aaci->card->longname);
1046 dev_info(&dev->dev, "FIFO %u entries\n", aaci->fifo_depth);
1047 amba_set_drvdata(dev, aaci->card);
1048 return ret;
1049 }
1050
1051 out:
1052 if (aaci)
1053 snd_card_free(aaci->card);
1054 amba_release_regions(dev);
1055 return ret;
1056 }
1057
1058 static void aaci_remove(struct amba_device *dev)
1059 {
1060 struct snd_card *card = amba_get_drvdata(dev);
1061
1062 if (card) {
1063 struct aaci *aaci = card->private_data;
1064 writel(0, aaci->base + AACI_MAINCR);
1065
1066 snd_card_free(card);
1067 amba_release_regions(dev);
1068 }
1069 }
1070
1071 static struct amba_id aaci_ids[] = {
1072 {
1073 .id = 0x00041041,
1074 .mask = 0x000fffff,
1075 },
1076 { 0, 0 },
1077 };
1078
1079 MODULE_DEVICE_TABLE(amba, aaci_ids);
1080
1081 static struct amba_driver aaci_driver = {
1082 .drv = {
1083 .name = DRIVER_NAME,
1084 .pm = AACI_DEV_PM_OPS,
1085 },
1086 .probe = aaci_probe,
1087 .remove = aaci_remove,
1088 .id_table = aaci_ids,
1089 };
1090
1091 module_amba_driver(aaci_driver);
1092
1093 MODULE_LICENSE("GPL");
1094 MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver");