Lines Matching full:aaci
3 * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
26 #include "aaci.h"
28 #define DRIVER_NAME "aaci-pl041"
37 static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97) in aaci_ac97_select_codec() argument
39 u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num); 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() local
76 mutex_lock(&aaci->ac97_sem); in aaci_ac97_write()
78 aaci_ac97_select_codec(aaci, ac97); 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()
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() local
116 mutex_lock(&aaci->ac97_sem); in aaci_ac97_read()
118 aaci_ac97_select_codec(aaci, ac97); 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()
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()
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()
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()
196 static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) in aaci_fifo_irq() argument
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()
214 dev_warn(&aaci->dev->dev, "RX interrupt???\n"); 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()
274 dev_warn(&aaci->dev->dev, "TX interrupt???\n"); in aaci_fifo_irq()
326 struct aaci *aaci = devid; in aaci_irq() local
330 mask = readl(aaci->base + AACI_ALLINTS); in aaci_irq()
335 aaci_fifo_irq(aaci, i, m); in aaci_irq()
384 struct aaci *aaci = rule->private; in aaci_rule_channels() local
388 slots = aaci->ac97_bus->pcms[0].r[0].slots; in aaci_rule_channels()
402 struct aaci *aaci = substream->private_data; in aaci_pcm_open() local
407 aacirun = &aaci->playback; in aaci_pcm_open()
409 aacirun = &aaci->capture; in aaci_pcm_open()
424 aaci_rule_channels, aaci, 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()
443 IRQF_SHARED, DRIVER_NAME, aaci); 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() local
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()
500 struct aaci *aaci = substream->private_data; in aaci_pcm_hw_params() local
528 aacirun->fifo_bytes = aaci->fifo_depth * 4 / 2; in aaci_pcm_hw_params()
712 struct aaci *aaci = substream->private_data; in aaci_pcm_capture_prepare() local
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()
743 struct aaci *aaci = card->private_data; in aaci_do_suspend() local
819 static int aaci_probe_ac97(struct aaci *aaci) in aaci_probe_ac97() argument
829 writel(0, aaci->base + AACI_RESET); in aaci_probe_ac97()
831 writel(RESET_NRST, aaci->base + AACI_RESET); in aaci_probe_ac97()
839 ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); in aaci_probe_ac97()
844 aaci->ac97_bus = ac97_bus; in aaci_probe_ac97()
847 ac97_template.private_data = aaci; in aaci_probe_ac97()
854 aaci->ac97 = ac97; in aaci_probe_ac97()
866 aaci->playback.pcm = &ac97_bus->pcms[0]; in aaci_probe_ac97()
867 aaci->capture.pcm = &ac97_bus->pcms[1]; in aaci_probe_ac97()
875 struct aaci *aaci = card->private_data; in aaci_free_card() local
877 iounmap(aaci->base); in aaci_free_card()
880 static struct aaci *aaci_init_card(struct amba_device *dev) in aaci_init_card()
882 struct aaci *aaci; in aaci_init_card() local
887 THIS_MODULE, sizeof(struct aaci), &card); in aaci_init_card()
900 aaci = card->private_data; in aaci_init_card()
901 mutex_init(&aaci->ac97_sem); in aaci_init_card()
902 mutex_init(&aaci->irq_lock); in aaci_init_card()
903 aaci->card = card; in aaci_init_card()
904 aaci->dev = dev; in aaci_init_card()
907 aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN | in aaci_init_card()
910 return aaci; in aaci_init_card()
913 static int aaci_init_pcm(struct aaci *aaci) in aaci_init_pcm() argument
918 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm); in aaci_init_pcm()
920 aaci->pcm = pcm; in aaci_init_pcm()
921 pcm->private_data = aaci; in aaci_init_pcm()
929 aaci->card->dev, in aaci_init_pcm()
936 static unsigned int aaci_size_fifo(struct aaci *aaci) in aaci_size_fifo() argument
938 struct aaci_runtime *aacirun = &aaci->playback; in aaci_size_fifo()
953 * Re-initialise the AACI after the FIFO depth test, to in aaci_size_fifo()
957 writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); in aaci_size_fifo()
958 readl(aaci->base + AACI_MAINCR); in aaci_size_fifo()
960 writel(aaci->maincr, aaci->base + AACI_MAINCR); in aaci_size_fifo()
975 struct aaci *aaci; in aaci_probe() local
982 aaci = aaci_init_card(dev); in aaci_probe()
983 if (!aaci) { in aaci_probe()
988 aaci->base = ioremap(dev->res.start, resource_size(&dev->res)); in aaci_probe()
989 if (!aaci->base) { in aaci_probe()
995 * Playback uses AACI channel 0 in aaci_probe()
997 spin_lock_init(&aaci->playback.lock); in aaci_probe()
998 aaci->playback.base = aaci->base + AACI_CSCH1; in aaci_probe()
999 aaci->playback.fifo = aaci->base + AACI_DR1; in aaci_probe()
1002 * Capture uses AACI channel 0 in aaci_probe()
1004 spin_lock_init(&aaci->capture.lock); in aaci_probe()
1005 aaci->capture.base = aaci->base + AACI_CSCH1; in aaci_probe()
1006 aaci->capture.fifo = aaci->base + AACI_DR1; in aaci_probe()
1009 void __iomem *base = aaci->base + i * 0x14; in aaci_probe()
1016 writel(0x1fff, aaci->base + AACI_INTCLR); in aaci_probe()
1017 writel(aaci->maincr, aaci->base + AACI_MAINCR); in aaci_probe()
1020 * from any arbitrary aaci register. in aaci_probe()
1022 readl(aaci->base + AACI_CSCH1); in aaci_probe()
1023 ret = aaci_probe_ac97(aaci); in aaci_probe()
1031 aaci->fifo_depth = aaci_size_fifo(aaci); in aaci_probe()
1032 if (aaci->fifo_depth & 15) { in aaci_probe()
1033 printk(KERN_WARNING "AACI: FIFO depth %d not supported\n", in aaci_probe()
1034 aaci->fifo_depth); in aaci_probe()
1039 ret = aaci_init_pcm(aaci); in aaci_probe()
1043 ret = snd_card_register(aaci->card); in aaci_probe()
1045 dev_info(&dev->dev, "%s\n", aaci->card->longname); in aaci_probe()
1046 dev_info(&dev->dev, "FIFO %u entries\n", aaci->fifo_depth); in aaci_probe()
1047 amba_set_drvdata(dev, aaci->card); in aaci_probe()
1052 if (aaci) in aaci_probe()
1053 snd_card_free(aaci->card); in aaci_probe()
1063 struct aaci *aaci = card->private_data; in aaci_remove() local
1064 writel(0, aaci->base + AACI_MAINCR); in aaci_remove()