Lines Matching +full:rx +full:- +full:slots
1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
28 #define DRIVER_NAME "aaci-pl041"
39 u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num); in aaci_ac97_select_codec()
42 * Ensure that the slot 1/2 RX registers are empty. in aaci_ac97_select_codec()
44 v = readl(aaci->base + AACI_SLFR); in aaci_ac97_select_codec()
46 readl(aaci->base + AACI_SL2RX); in aaci_ac97_select_codec()
48 readl(aaci->base + AACI_SL1RX); in aaci_ac97_select_codec()
50 if (maincr != readl(aaci->base + AACI_MAINCR)) { in aaci_ac97_select_codec()
51 writel(maincr, aaci->base + AACI_MAINCR); in aaci_ac97_select_codec()
52 readl(aaci->base + AACI_MAINCR); in aaci_ac97_select_codec()
69 struct aaci *aaci = ac97->private_data; in aaci_ac97_write()
73 if (ac97->num >= 4) in aaci_ac97_write()
76 mutex_lock(&aaci->ac97_sem); in aaci_ac97_write()
84 writel(val << 4, aaci->base + AACI_SL2TX); in aaci_ac97_write()
85 writel(reg << 12, aaci->base + AACI_SL1TX); in aaci_ac97_write()
94 v = readl(aaci->base + AACI_SLFR); in aaci_ac97_write()
95 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); in aaci_ac97_write()
98 dev_err(&aaci->dev->dev, in aaci_ac97_write()
101 mutex_unlock(&aaci->ac97_sem); in aaci_ac97_write()
109 struct aaci *aaci = ac97->private_data; in aaci_ac97_read()
113 if (ac97->num >= 4) in aaci_ac97_read()
116 mutex_lock(&aaci->ac97_sem); in aaci_ac97_read()
123 writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); in aaci_ac97_read()
132 v = readl(aaci->base + AACI_SLFR); in aaci_ac97_read()
133 } while ((v & SLFR_1TXB) && --timeout); in aaci_ac97_read()
136 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n"); in aaci_ac97_read()
149 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); in aaci_ac97_read()
150 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); in aaci_ac97_read()
153 dev_err(&aaci->dev->dev, "timeout on RX valid\n"); in aaci_ac97_read()
159 v = readl(aaci->base + AACI_SL1RX) >> 12; in aaci_ac97_read()
161 v = readl(aaci->base + AACI_SL2RX) >> 4; in aaci_ac97_read()
163 } else if (--retries) { in aaci_ac97_read()
164 dev_warn(&aaci->dev->dev, in aaci_ac97_read()
168 dev_warn(&aaci->dev->dev, in aaci_ac97_read()
175 mutex_unlock(&aaci->ac97_sem); in aaci_ac97_read()
187 val = readl(aacirun->base + AACI_SR); in aaci_chan_wait_ready()
188 } while (val & mask && timeout--); in aaci_chan_wait_ready()
199 dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel); in aaci_fifo_irq()
200 writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR); in aaci_fifo_irq()
204 dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel); in aaci_fifo_irq()
205 writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR); in aaci_fifo_irq()
209 struct aaci_runtime *aacirun = &aaci->capture; in aaci_fifo_irq()
213 if (!aacirun->substream || !aacirun->start) { in aaci_fifo_irq()
214 dev_warn(&aaci->dev->dev, "RX interrupt???\n"); in aaci_fifo_irq()
215 writel(0, aacirun->base + AACI_IE); in aaci_fifo_irq()
219 spin_lock(&aacirun->lock); in aaci_fifo_irq()
221 ptr = aacirun->ptr; in aaci_fifo_irq()
223 unsigned int len = aacirun->fifo_bytes; in aaci_fifo_irq()
226 if (aacirun->bytes <= 0) { in aaci_fifo_irq()
227 aacirun->bytes += aacirun->period; in aaci_fifo_irq()
230 if (!(aacirun->cr & CR_EN)) in aaci_fifo_irq()
233 val = readl(aacirun->base + AACI_SR); in aaci_fifo_irq()
239 aacirun->bytes -= len; in aaci_fifo_irq()
242 for( ; len > 0; len -= 16) { in aaci_fifo_irq()
247 : "r" (aacirun->fifo) in aaci_fifo_irq()
250 if (ptr >= aacirun->end) in aaci_fifo_irq()
251 ptr = aacirun->start; in aaci_fifo_irq()
255 aacirun->ptr = ptr; in aaci_fifo_irq()
257 spin_unlock(&aacirun->lock); in aaci_fifo_irq()
260 snd_pcm_period_elapsed(aacirun->substream); in aaci_fifo_irq()
264 dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel); in aaci_fifo_irq()
265 writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR); in aaci_fifo_irq()
269 struct aaci_runtime *aacirun = &aaci->playback; in aaci_fifo_irq()
273 if (!aacirun->substream || !aacirun->start) { in aaci_fifo_irq()
274 dev_warn(&aaci->dev->dev, "TX interrupt???\n"); in aaci_fifo_irq()
275 writel(0, aacirun->base + AACI_IE); in aaci_fifo_irq()
279 spin_lock(&aacirun->lock); in aaci_fifo_irq()
281 ptr = aacirun->ptr; in aaci_fifo_irq()
283 unsigned int len = aacirun->fifo_bytes; in aaci_fifo_irq()
286 if (aacirun->bytes <= 0) { in aaci_fifo_irq()
287 aacirun->bytes += aacirun->period; in aaci_fifo_irq()
290 if (!(aacirun->cr & CR_EN)) in aaci_fifo_irq()
293 val = readl(aacirun->base + AACI_SR); in aaci_fifo_irq()
299 aacirun->bytes -= len; in aaci_fifo_irq()
302 for ( ; len > 0; len -= 16) { in aaci_fifo_irq()
307 : "r" (aacirun->fifo) in aaci_fifo_irq()
310 if (ptr >= aacirun->end) in aaci_fifo_irq()
311 ptr = aacirun->start; in aaci_fifo_irq()
315 aacirun->ptr = ptr; in aaci_fifo_irq()
317 spin_unlock(&aacirun->lock); in aaci_fifo_irq()
320 snd_pcm_period_elapsed(aacirun->substream); in aaci_fifo_irq()
330 mask = readl(aaci->base + AACI_ALLINTS); in aaci_irq()
356 * ALSA doesn't support 18-bit or 20-bit packed into 32-bit
357 * words. It also doesn't support 12-bit at all.
373 * six channel audio requires a non-standard channel ordering:
374 * 2 -> FL(3), FR(4)
375 * 4 -> FL(3), FR(4), SL(7), SR(8)
376 * 6 -> FL(3), FR(4), SL(7), SR(8), C(6), LFE(9) (required)
384 struct aaci *aaci = rule->private; in aaci_rule_channels()
385 unsigned int mask = 1 << 0, slots; in aaci_rule_channels() local
388 slots = aaci->ac97_bus->pcms[0].r[0].slots; in aaci_rule_channels()
389 if (slots & (1 << AC97_SLOT_PCM_SLEFT)) { in aaci_rule_channels()
391 if (slots & (1 << AC97_SLOT_LFE)) in aaci_rule_channels()
395 return snd_interval_list(hw_param_interval(p, rule->var), in aaci_rule_channels()
401 struct snd_pcm_runtime *runtime = substream->runtime; in aaci_pcm_open()
402 struct aaci *aaci = substream->private_data; in aaci_pcm_open()
406 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in aaci_pcm_open()
407 aacirun = &aaci->playback; in aaci_pcm_open()
409 aacirun = &aaci->capture; in aaci_pcm_open()
412 aacirun->substream = substream; in aaci_pcm_open()
413 runtime->private_data = aacirun; in aaci_pcm_open()
414 runtime->hw = aaci_hw_info; in aaci_pcm_open()
415 runtime->hw.rates = aacirun->pcm->rates; in aaci_pcm_open()
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in aaci_pcm_open()
419 runtime->hw.channels_max = 6; in aaci_pcm_open()
422 ret = snd_pcm_hw_rule_add(substream->runtime, 0, in aaci_pcm_open()
425 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in aaci_pcm_open()
429 if (aacirun->pcm->r[1].slots) in aaci_pcm_open()
434 * ALSA wants the byte-size of the FIFOs. As we only support in aaci_pcm_open()
435 * 16-bit samples, this is twice the FIFO depth irrespective in aaci_pcm_open()
438 runtime->hw.fifo_size = aaci->fifo_depth * 2; in aaci_pcm_open()
440 mutex_lock(&aaci->irq_lock); in aaci_pcm_open()
441 if (!aaci->users++) { in aaci_pcm_open()
442 ret = request_irq(aaci->dev->irq[0], aaci_irq, in aaci_pcm_open()
445 aaci->users--; in aaci_pcm_open()
447 mutex_unlock(&aaci->irq_lock); in aaci_pcm_open()
458 struct aaci *aaci = substream->private_data; in aaci_pcm_close()
459 struct aaci_runtime *aacirun = substream->runtime->private_data; in aaci_pcm_close()
461 WARN_ON(aacirun->cr & CR_EN); in aaci_pcm_close()
463 aacirun->substream = NULL; in aaci_pcm_close()
465 mutex_lock(&aaci->irq_lock); in aaci_pcm_close()
466 if (!--aaci->users) in aaci_pcm_close()
467 free_irq(aaci->dev->irq[0], aaci); in aaci_pcm_close()
468 mutex_unlock(&aaci->irq_lock); in aaci_pcm_close()
475 struct aaci_runtime *aacirun = substream->runtime->private_data; in aaci_pcm_hw_free()
480 WARN_ON(aacirun->cr & CR_EN); in aaci_pcm_hw_free()
482 if (aacirun->pcm_open) in aaci_pcm_hw_free()
483 snd_ac97_pcm_close(aacirun->pcm); in aaci_pcm_hw_free()
484 aacirun->pcm_open = 0; in aaci_pcm_hw_free()
499 struct aaci_runtime *aacirun = substream->runtime->private_data; in aaci_pcm_hw_params()
500 struct aaci *aaci = substream->private_data; in aaci_pcm_hw_params()
507 if (aacirun->pcm_open) { in aaci_pcm_hw_params()
508 snd_ac97_pcm_close(aacirun->pcm); in aaci_pcm_hw_params()
509 aacirun->pcm_open = 0; in aaci_pcm_hw_params()
514 return -EINVAL; in aaci_pcm_hw_params()
516 err = snd_ac97_pcm_open(aacirun->pcm, rate, channels, in aaci_pcm_hw_params()
517 aacirun->pcm->r[dbl].slots); in aaci_pcm_hw_params()
519 aacirun->pcm_open = err == 0; in aaci_pcm_hw_params()
520 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; in aaci_pcm_hw_params()
521 aacirun->cr |= channels_to_slotmask[channels + dbl * 2]; in aaci_pcm_hw_params()
528 aacirun->fifo_bytes = aaci->fifo_depth * 4 / 2; in aaci_pcm_hw_params()
535 struct snd_pcm_runtime *runtime = substream->runtime; in aaci_pcm_prepare()
536 struct aaci_runtime *aacirun = runtime->private_data; in aaci_pcm_prepare()
538 aacirun->period = snd_pcm_lib_period_bytes(substream); in aaci_pcm_prepare()
539 aacirun->start = runtime->dma_area; in aaci_pcm_prepare()
540 aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream); in aaci_pcm_prepare()
541 aacirun->ptr = aacirun->start; in aaci_pcm_prepare()
542 aacirun->bytes = aacirun->period; in aaci_pcm_prepare()
549 struct snd_pcm_runtime *runtime = substream->runtime; in aaci_pcm_pointer()
550 struct aaci_runtime *aacirun = runtime->private_data; in aaci_pcm_pointer()
551 ssize_t bytes = aacirun->ptr - aacirun->start; in aaci_pcm_pointer()
564 ie = readl(aacirun->base + AACI_IE); in aaci_pcm_playback_stop()
566 writel(ie, aacirun->base + AACI_IE); in aaci_pcm_playback_stop()
567 aacirun->cr &= ~CR_EN; in aaci_pcm_playback_stop()
569 writel(aacirun->cr, aacirun->base + AACI_TXCR); in aaci_pcm_playback_stop()
577 aacirun->cr |= CR_EN; in aaci_pcm_playback_start()
579 ie = readl(aacirun->base + AACI_IE); in aaci_pcm_playback_start()
581 writel(ie, aacirun->base + AACI_IE); in aaci_pcm_playback_start()
582 writel(aacirun->cr, aacirun->base + AACI_TXCR); in aaci_pcm_playback_start()
587 struct aaci_runtime *aacirun = substream->runtime->private_data; in aaci_pcm_playback_trigger()
591 spin_lock_irqsave(&aacirun->lock, flags); in aaci_pcm_playback_trigger()
617 ret = -EINVAL; in aaci_pcm_playback_trigger()
620 spin_unlock_irqrestore(&aacirun->lock, flags); in aaci_pcm_playback_trigger()
641 ie = readl(aacirun->base + AACI_IE); in aaci_pcm_capture_stop()
643 writel(ie, aacirun->base+AACI_IE); in aaci_pcm_capture_stop()
645 aacirun->cr &= ~CR_EN; in aaci_pcm_capture_stop()
647 writel(aacirun->cr, aacirun->base + AACI_RXCR); in aaci_pcm_capture_stop()
657 /* RX Timeout value: bits 28:17 in RXCR */ in aaci_pcm_capture_start()
658 aacirun->cr |= 0xf << 17; in aaci_pcm_capture_start()
661 aacirun->cr |= CR_EN; in aaci_pcm_capture_start()
662 writel(aacirun->cr, aacirun->base + AACI_RXCR); in aaci_pcm_capture_start()
664 ie = readl(aacirun->base + AACI_IE); in aaci_pcm_capture_start()
665 ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full in aaci_pcm_capture_start()
666 writel(ie, aacirun->base + AACI_IE); in aaci_pcm_capture_start()
671 struct aaci_runtime *aacirun = substream->runtime->private_data; in aaci_pcm_capture_trigger()
675 spin_lock_irqsave(&aacirun->lock, flags); in aaci_pcm_capture_trigger()
701 ret = -EINVAL; in aaci_pcm_capture_trigger()
704 spin_unlock_irqrestore(&aacirun->lock, flags); in aaci_pcm_capture_trigger()
711 struct snd_pcm_runtime *runtime = substream->runtime; in aaci_pcm_capture_prepare()
712 struct aaci *aaci = substream->private_data; in aaci_pcm_capture_prepare()
717 aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */ in aaci_pcm_capture_prepare()
718 aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); in aaci_pcm_capture_prepare()
719 aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate); in aaci_pcm_capture_prepare()
722 aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404); in aaci_pcm_capture_prepare()
771 .slots = (1 << AC97_SLOT_PCM_LEFT) |
779 .slots = (1 << AC97_SLOT_PCM_LEFT) |
791 .slots = (1 << AC97_SLOT_PCM_LEFT) |
801 .slots = (1 << AC97_SLOT_MIC),
822 writel(0, aaci->base + AACI_RESET); in aaci_probe_ac97()
824 writel(RESET_NRST, aaci->base + AACI_RESET); in aaci_probe_ac97()
832 ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); in aaci_probe_ac97()
836 ac97_bus->clock = 48000; in aaci_probe_ac97()
837 aaci->ac97_bus = ac97_bus; in aaci_probe_ac97()
847 aaci->ac97 = ac97; in aaci_probe_ac97()
859 aaci->playback.pcm = &ac97_bus->pcms[0]; in aaci_probe_ac97()
860 aaci->capture.pcm = &ac97_bus->pcms[1]; in aaci_probe_ac97()
868 struct aaci *aaci = card->private_data; in aaci_free_card()
870 iounmap(aaci->base); in aaci_free_card()
879 err = snd_card_new(&dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, in aaci_init_card()
884 card->private_free = aaci_free_card; in aaci_init_card()
886 strscpy(card->driver, DRIVER_NAME, sizeof(card->driver)); in aaci_init_card()
887 strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); in aaci_init_card()
888 snprintf(card->longname, sizeof(card->longname), in aaci_init_card()
890 card->shortname, amba_part(dev), amba_rev(dev), in aaci_init_card()
891 (unsigned long long)dev->res.start, dev->irq[0]); in aaci_init_card()
893 aaci = card->private_data; in aaci_init_card()
894 mutex_init(&aaci->ac97_sem); in aaci_init_card()
895 mutex_init(&aaci->irq_lock); in aaci_init_card()
896 aaci->card = card; in aaci_init_card()
897 aaci->dev = dev; in aaci_init_card()
900 aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN | in aaci_init_card()
911 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm); in aaci_init_pcm()
913 aaci->pcm = pcm; in aaci_init_pcm()
914 pcm->private_data = aaci; in aaci_init_pcm()
915 pcm->info_flags = 0; in aaci_init_pcm()
917 strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); in aaci_init_pcm()
922 aaci->card->dev, in aaci_init_pcm()
931 struct aaci_runtime *aacirun = &aaci->playback; in aaci_size_fifo()
935 * Enable the channel, but don't assign it to any slots, so in aaci_size_fifo()
938 writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR); in aaci_size_fifo()
940 for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++) in aaci_size_fifo()
941 writel(0, aacirun->fifo); in aaci_size_fifo()
943 writel(0, aacirun->base + AACI_TXCR); in aaci_size_fifo()
946 * Re-initialise the AACI after the FIFO depth test, to in aaci_size_fifo()
950 writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); in aaci_size_fifo()
951 readl(aaci->base + AACI_MAINCR); in aaci_size_fifo()
953 writel(aaci->maincr, aaci->base + AACI_MAINCR); in aaci_size_fifo()
977 ret = -ENOMEM; in aaci_probe()
981 aaci->base = ioremap(dev->res.start, resource_size(&dev->res)); in aaci_probe()
982 if (!aaci->base) { in aaci_probe()
983 ret = -ENOMEM; in aaci_probe()
990 spin_lock_init(&aaci->playback.lock); in aaci_probe()
991 aaci->playback.base = aaci->base + AACI_CSCH1; in aaci_probe()
992 aaci->playback.fifo = aaci->base + AACI_DR1; in aaci_probe()
997 spin_lock_init(&aaci->capture.lock); in aaci_probe()
998 aaci->capture.base = aaci->base + AACI_CSCH1; in aaci_probe()
999 aaci->capture.fifo = aaci->base + AACI_DR1; in aaci_probe()
1002 void __iomem *base = aaci->base + i * 0x14; in aaci_probe()
1009 writel(0x1fff, aaci->base + AACI_INTCLR); in aaci_probe()
1010 writel(aaci->maincr, aaci->base + AACI_MAINCR); in aaci_probe()
1015 readl(aaci->base + AACI_CSCH1); in aaci_probe()
1024 aaci->fifo_depth = aaci_size_fifo(aaci); in aaci_probe()
1025 if (aaci->fifo_depth & 15) { in aaci_probe()
1027 aaci->fifo_depth); in aaci_probe()
1028 ret = -ENODEV; in aaci_probe()
1036 ret = snd_card_register(aaci->card); in aaci_probe()
1038 dev_info(&dev->dev, "%s\n", aaci->card->longname); in aaci_probe()
1039 dev_info(&dev->dev, "FIFO %u entries\n", aaci->fifo_depth); in aaci_probe()
1040 amba_set_drvdata(dev, aaci->card); in aaci_probe()
1046 snd_card_free(aaci->card); in aaci_probe()
1056 struct aaci *aaci = card->private_data; in aaci_remove()
1057 writel(0, aaci->base + AACI_MAINCR); in aaci_remove()