aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Chini <georg.chini@triaton-webhosting.com>2005-11-07 17:09:19 -0500
committerDavid S. Miller <davem@davemloft.net>2005-11-07 17:09:19 -0500
commitb128254fdb172eaa3273de24fa6ce405a1f534c9 (patch)
tree3b099bf16fafe78c5fca7b01933bb02353c60aa4
parentdedeb0029b9c83420fc1337d4ee53daa7b2a0ad4 (diff)
[SPARC]: More abstractions and cleanups of dma handling in cs4231.
From: Georg Chini <georg.chini@triaton-webhosting.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/asm-sparc64/ebus.h1
-rw-r--r--sound/sparc/cs4231.c683
2 files changed, 343 insertions, 341 deletions
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h
index 543e4e500a72..7a408a030f52 100644
--- a/include/asm-sparc64/ebus.h
+++ b/include/asm-sparc64/ebus.h
@@ -79,6 +79,7 @@ extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
79 size_t len); 79 size_t len);
80extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); 80extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
81extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); 81extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
82extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
82extern void ebus_dma_enable(struct ebus_dma_info *p, int on); 83extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
83 84
84extern struct linux_ebus *ebus_chain; 85extern struct linux_ebus *ebus_chain;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 110d64d4848d..1f8d27a6152e 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -62,25 +62,36 @@ MODULE_LICENSE("GPL");
62MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); 62MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
63 63
64#ifdef SBUS_SUPPORT 64#ifdef SBUS_SUPPORT
65struct sbus_dma_info { 65typedef struct sbus_dma_info {
66 spinlock_t lock; 66 spinlock_t lock;
67 int dir; 67 int dir;
68 void __iomem *regs; 68 void __iomem *regs;
69}; 69} sbus_dma_info_t;
70#endif 70#endif
71 71
72typedef struct snd_cs4231 { 72typedef struct snd_cs4231 cs4231_t;
73 spinlock_t lock; 73
74 void __iomem *port; 74typedef struct cs4231_dma_control {
75 void (*prepare)(struct cs4231_dma_control *dma_cont, int dir);
76 void (*enable)(struct cs4231_dma_control *dma_cont, int on);
77 int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
78 unsigned int (*address)(struct cs4231_dma_control *dma_cont);
79 void (*reset)(cs4231_t *chip);
80 void (*preallocate)(cs4231_t *chip, snd_pcm_t *pcm);
75#ifdef EBUS_SUPPORT 81#ifdef EBUS_SUPPORT
76 struct ebus_dma_info eb2c; 82 struct ebus_dma_info ebus_info;
77 struct ebus_dma_info eb2p;
78#endif 83#endif
79
80#ifdef SBUS_SUPPORT 84#ifdef SBUS_SUPPORT
81 struct sbus_dma_info sb2c; 85 struct sbus_dma_info sbus_info;
82 struct sbus_dma_info sb2p;
83#endif 86#endif
87} cs4231_dma_control_t;
88
89struct snd_cs4231 {
90 spinlock_t lock;
91 void __iomem *port;
92
93 cs4231_dma_control_t p_dma;
94 cs4231_dma_control_t c_dma;
84 95
85 u32 flags; 96 u32 flags;
86#define CS4231_FLAG_EBUS 0x00000001 97#define CS4231_FLAG_EBUS 0x00000001
@@ -119,7 +130,7 @@ typedef struct snd_cs4231 {
119 unsigned int irq[2]; 130 unsigned int irq[2];
120 unsigned int regs_size; 131 unsigned int regs_size;
121 struct snd_cs4231 *next; 132 struct snd_cs4231 *next;
122} cs4231_t; 133};
123 134
124static cs4231_t *cs4231_list; 135static cs4231_t *cs4231_list;
125 136
@@ -494,103 +505,6 @@ static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
494} 505}
495 506
496/* 507/*
497 * SBUS DMA routines
498 */
499#ifdef SBUS_SUPPORT
500
501int sbus_dma_request(struct sbus_dma_info *base, dma_addr_t bus_addr, size_t len)
502{
503 unsigned long flags;
504 u32 test, csr;
505 int err;
506
507 if (len >= (1 << 24))
508 return -EINVAL;
509 spin_lock_irqsave(&base->lock, flags);
510 csr = sbus_readl(base->regs + APCCSR);
511 err = -EINVAL;
512 test = APC_CDMA_READY;
513 if ( base->dir == APC_PLAY )
514 test = APC_PDMA_READY;
515 if (!(csr & test))
516 goto out;
517 err = -EBUSY;
518 csr = sbus_readl(base->regs + APCCSR);
519 test = APC_XINT_CNVA;
520 if ( base->dir == APC_PLAY )
521 test = APC_XINT_PNVA;
522 if (!(csr & test))
523 goto out;
524 err = 0;
525 sbus_writel(bus_addr, base->regs + base->dir + APCNVA);
526 sbus_writel(len, base->regs + base->dir + APCNC);
527out:
528 spin_unlock_irqrestore(&base->lock, flags);
529 return err;
530}
531
532void sbus_dma_prepare(struct sbus_dma_info *base)
533{
534 unsigned long flags;
535 u32 csr, test;
536
537 spin_lock_irqsave(&base->lock, flags);
538 csr = sbus_readl(base->regs + APCCSR);
539 test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
540 APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
541 APC_XINT_PENA;
542 if ( base->dir == APC_RECORD )
543 test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
544 APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
545 csr |= test;
546 sbus_writel(csr, base->regs + APCCSR);
547 spin_unlock_irqrestore(&base->lock, flags);
548}
549
550void sbus_dma_enable(struct sbus_dma_info *base, int on)
551{
552 unsigned long flags;
553 u32 csr, shift;
554
555 spin_lock_irqsave(&base->lock, flags);
556 if (!on) {
557 if (base->dir == APC_PLAY) {
558 sbus_writel(0, base->regs + base->dir + APCNVA);
559 sbus_writel(1, base->regs + base->dir + APCC);
560 }
561 else
562 {
563 sbus_writel(0, base->regs + base->dir + APCNC);
564 sbus_writel(0, base->regs + base->dir + APCVA);
565 }
566 }
567 udelay(500);
568 csr = sbus_readl(base->regs + APCCSR);
569 shift = 0;
570 if ( base->dir == APC_PLAY )
571 shift = 1;
572 if (on)
573 csr &= ~(APC_CPAUSE << shift);
574 else
575 csr |= (APC_CPAUSE << shift);
576 sbus_writel(csr, base->regs + APCCSR);
577 if (on)
578 csr |= (APC_CDMA_READY << shift);
579 else
580 csr &= ~(APC_CDMA_READY << shift);
581 sbus_writel(csr, base->regs + APCCSR);
582
583 spin_unlock_irqrestore(&base->lock, flags);
584}
585
586unsigned int sbus_dma_addr(struct sbus_dma_info *base)
587{
588 return sbus_readl(base->regs + base->dir + APCVA);
589}
590
591#endif
592
593/*
594 * CS4231 detection / MCE routines 508 * CS4231 detection / MCE routines
595 */ 509 */
596 510
@@ -688,8 +602,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
688 spin_unlock_irqrestore(&chip->lock, flags); 602 spin_unlock_irqrestore(&chip->lock, flags);
689} 603}
690 604
691#ifdef EBUS_SUPPORT 605static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent)
692static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
693{ 606{
694 snd_pcm_runtime_t *runtime = substream->runtime; 607 snd_pcm_runtime_t *runtime = substream->runtime;
695 608
@@ -700,89 +613,41 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre
700 if (period_size >= (1 << 24)) 613 if (period_size >= (1 << 24))
701 BUG(); 614 BUG();
702 615
703 if (ebus_dma_request(p, runtime->dma_addr + offset, period_size)) 616 if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size))
704 return; 617 return;
705 (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; 618 (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
706 } 619 }
707} 620}
708#endif
709
710#ifdef SBUS_SUPPORT
711static void snd_cs4231_sbus_advance_dma(struct sbus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
712{
713 snd_pcm_runtime_t *runtime = substream->runtime;
714
715 while (1) {
716 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
717 unsigned int offset = period_size * (*periods_sent);
718
719 if (period_size > 0xffff + 1)
720 BUG();
721
722 if (sbus_dma_request(p, runtime->dma_addr + offset, period_size))
723 return;
724 (*periods_sent) = (*periods_sent + 1) % runtime->periods;
725 }
726}
727#endif
728 621
729static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) 622static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
730{ 623{
731 cs4231_t *chip = snd_pcm_substream_chip(substream); 624 cs4231_t *chip = snd_pcm_substream_chip(substream);
625 cs4231_dma_control_t *dma_cont;
732 626
733#ifdef EBUS_SUPPORT
734 if (chip->flags & CS4231_FLAG_EBUS) {
735 if (what & CS4231_PLAYBACK_ENABLE) {
736 if (on) {
737 ebus_dma_prepare(&chip->eb2p, 0);
738 ebus_dma_enable(&chip->eb2p, 1);
739 snd_cs4231_ebus_advance_dma(&chip->eb2p,
740 chip->playback_substream,
741 &chip->p_periods_sent);
742 } else {
743 ebus_dma_enable(&chip->eb2p, 0);
744 }
745 }
746 if (what & CS4231_RECORD_ENABLE) {
747 if (on) {
748 ebus_dma_prepare(&chip->eb2c, 1);
749 ebus_dma_enable(&chip->eb2c, 1);
750 snd_cs4231_ebus_advance_dma(&chip->eb2c,
751 chip->capture_substream,
752 &chip->c_periods_sent);
753 } else {
754 ebus_dma_enable(&chip->eb2c, 0);
755 }
756 }
757 } else {
758#endif
759#ifdef SBUS_SUPPORT
760 if (what & CS4231_PLAYBACK_ENABLE) { 627 if (what & CS4231_PLAYBACK_ENABLE) {
628 dma_cont = &chip->p_dma;
761 if (on) { 629 if (on) {
762 sbus_dma_prepare(&chip->sb2p); 630 dma_cont->prepare(dma_cont, 0);
763 sbus_dma_enable(&chip->sb2p, 1); 631 dma_cont->enable(dma_cont, 1);
764 snd_cs4231_sbus_advance_dma(&chip->sb2p, 632 snd_cs4231_advance_dma(dma_cont,
765 chip->playback_substream, 633 chip->playback_substream,
766 &chip->p_periods_sent); 634 &chip->p_periods_sent);
767 } else { 635 } else {
768 sbus_dma_enable(&chip->sb2p, 0); 636 dma_cont->enable(dma_cont, 0);
769 } 637 }
770 } 638 }
771 if (what & CS4231_RECORD_ENABLE) { 639 if (what & CS4231_RECORD_ENABLE) {
640 dma_cont = &chip->c_dma;
772 if (on) { 641 if (on) {
773 sbus_dma_prepare(&chip->sb2c); 642 dma_cont->prepare(dma_cont, 1);
774 sbus_dma_enable(&chip->sb2c, 1); 643 dma_cont->enable(dma_cont, 1);
775 snd_cs4231_sbus_advance_dma(&chip->sb2c, 644 snd_cs4231_advance_dma(dma_cont,
776 chip->capture_substream, 645 chip->capture_substream,
777 &chip->c_periods_sent); 646 &chip->c_periods_sent);
778 } else { 647 } else {
779 sbus_dma_enable(&chip->sb2c, 0); 648 dma_cont->enable(dma_cont, 0);
780 } 649 }
781 } 650 }
782#endif
783#ifdef EBUS_SUPPORT
784 }
785#endif
786} 651}
787 652
788static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) 653static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
@@ -1273,140 +1138,55 @@ static void snd_cs4231_overrange(cs4231_t *chip)
1273 chip->capture_substream->runtime->overrange++; 1138 chip->capture_substream->runtime->overrange++;
1274} 1139}
1275 1140
1276#ifdef SBUS_SUPPORT 1141static void snd_cs4231_play_callback(cs4231_t *cookie)
1277static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1278{
1279 unsigned long flags;
1280 unsigned char status;
1281 u32 csr;
1282 cs4231_t *chip = dev_id;
1283
1284 /*This is IRQ is not raised by the cs4231*/
1285 if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
1286 return IRQ_NONE;
1287
1288 /* ACK the APC interrupt. */
1289 csr = sbus_readl(chip->port + APCCSR);
1290
1291 sbus_writel(csr, chip->port + APCCSR);
1292
1293 if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) &&
1294 (csr & APC_PLAY_INT) &&
1295 (csr & APC_XINT_PNVA) &&
1296 !(csr & APC_XINT_EMPT)) {
1297 snd_pcm_period_elapsed(chip->playback_substream);
1298 snd_cs4231_sbus_advance_dma(&chip->sb2p, chip->playback_substream,
1299 &chip->p_periods_sent);
1300 }
1301
1302 if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) &&
1303 (csr & APC_CAPT_INT) &&
1304 (csr & APC_XINT_CNVA) &&
1305 !(csr & APC_XINT_EMPT)) {
1306 snd_pcm_period_elapsed(chip->capture_substream);
1307 snd_cs4231_sbus_advance_dma(&chip->sb2c,chip->capture_substream,
1308 &chip->c_periods_sent);
1309 }
1310
1311 status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
1312
1313 if (status & CS4231_TIMER_IRQ) {
1314 if (chip->timer)
1315 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1316 }
1317
1318 if (status & CS4231_RECORD_IRQ)
1319 snd_cs4231_overrange(chip);
1320
1321 /* ACK the CS4231 interrupt. */
1322 spin_lock_irqsave(&chip->lock, flags);
1323 snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
1324 spin_unlock_irqrestore(&chip->lock, flags);
1325
1326 return 0;
1327}
1328#endif
1329
1330#ifdef EBUS_SUPPORT
1331static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
1332{ 1142{
1333 cs4231_t *chip = cookie; 1143 cs4231_t *chip = cookie;
1334 1144
1335 if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) { 1145 if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) {
1336 snd_pcm_period_elapsed(chip->playback_substream); 1146 snd_pcm_period_elapsed(chip->playback_substream);
1337 snd_cs4231_ebus_advance_dma(p, chip->playback_substream, 1147 snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream,
1338 &chip->p_periods_sent); 1148 &chip->p_periods_sent);
1339 } 1149 }
1340} 1150}
1341 1151
1342static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) 1152static void snd_cs4231_capture_callback(cs4231_t *cookie)
1343{ 1153{
1344 cs4231_t *chip = cookie; 1154 cs4231_t *chip = cookie;
1345 1155
1346 if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) { 1156 if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) {
1347 snd_pcm_period_elapsed(chip->capture_substream); 1157 snd_pcm_period_elapsed(chip->capture_substream);
1348 snd_cs4231_ebus_advance_dma(p, chip->capture_substream, 1158 snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream,
1349 &chip->c_periods_sent); 1159 &chip->c_periods_sent);
1350 } 1160 }
1351} 1161}
1352#endif
1353 1162
1354static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) 1163static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream)
1355{ 1164{
1356 cs4231_t *chip = snd_pcm_substream_chip(substream); 1165 cs4231_t *chip = snd_pcm_substream_chip(substream);
1166 cs4231_dma_control_t *dma_cont = &chip->p_dma;
1357 size_t ptr; 1167 size_t ptr;
1358#ifdef EBUS_SUPPORT
1359 size_t residue, period_bytes;
1360#endif
1361 1168
1362 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) 1169 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
1363 return 0; 1170 return 0;
1364#ifdef EBUS_SUPPORT 1171 ptr = dma_cont->address(dma_cont);
1365 period_bytes = snd_pcm_lib_period_bytes(substream); 1172 if (ptr != 0)
1366 ptr = period_bytes * chip->p_periods_sent; 1173 ptr -= substream->runtime->dma_addr;
1367 if (chip->flags & CS4231_FLAG_EBUS) { 1174
1368 residue = ebus_dma_residue(&chip->eb2p);
1369 ptr += period_bytes - residue;
1370 } else {
1371#endif
1372#ifdef SBUS_SUPPORT
1373 ptr = sbus_dma_addr(&chip->sb2p);
1374 if (ptr != 0)
1375 ptr -= substream->runtime->dma_addr;
1376#endif
1377#ifdef EBUS_SUPPORT
1378 }
1379#endif
1380
1381 return bytes_to_frames(substream->runtime, ptr); 1175 return bytes_to_frames(substream->runtime, ptr);
1382} 1176}
1383 1177
1384static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) 1178static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream)
1385{ 1179{
1386 cs4231_t *chip = snd_pcm_substream_chip(substream); 1180 cs4231_t *chip = snd_pcm_substream_chip(substream);
1181 cs4231_dma_control_t *dma_cont = &chip->c_dma;
1387 size_t ptr; 1182 size_t ptr;
1388#ifdef EBUS_SUPPORT
1389 size_t residue, period_bytes;
1390#endif
1391 1183
1392 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) 1184 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1393 return 0; 1185 return 0;
1394#ifdef EBUS_SUPPORT 1186 ptr = dma_cont->address(dma_cont);
1395 period_bytes = snd_pcm_lib_period_bytes(substream); 1187 if (ptr != 0)
1396 ptr = period_bytes * chip->c_periods_sent; 1188 ptr -= substream->runtime->dma_addr;
1397 if (chip->flags & CS4231_FLAG_EBUS) { 1189
1398 residue = ebus_dma_residue(&chip->eb2c);
1399 ptr += period_bytes - residue;
1400 } else {
1401#endif
1402#ifdef SBUS_SUPPORT
1403 ptr = sbus_dma_addr(&chip->sb2c);
1404 if (ptr != 0)
1405 ptr -= substream->runtime->dma_addr;
1406#endif
1407#ifdef EBUS_SUPPORT
1408 }
1409#endif
1410 return bytes_to_frames(substream->runtime, ptr); 1190 return bytes_to_frames(substream->runtime, ptr);
1411} 1191}
1412 1192
@@ -1442,30 +1222,8 @@ static int snd_cs4231_probe(cs4231_t *chip)
1442 spin_lock_irqsave(&chip->lock, flags); 1222 spin_lock_irqsave(&chip->lock, flags);
1443 1223
1444 1224
1445 /* Reset DMA engine. */ 1225 /* Reset DMA engine (sbus only). */
1446#ifdef EBUS_SUPPORT 1226 chip->p_dma.reset(chip);
1447 if (chip->flags & CS4231_FLAG_EBUS) {
1448 /* Done by ebus_dma_register */
1449 } else {
1450#endif
1451#ifdef SBUS_SUPPORT
1452 sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
1453 sbus_writel(0x00, chip->port + APCCSR);
1454 sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET,
1455 chip->port + APCCSR);
1456
1457 udelay(20);
1458
1459 sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET,
1460 chip->port + APCCSR);
1461 sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA |
1462 APC_XINT_PENA |
1463 APC_XINT_CENA),
1464 chip->port + APCCSR);
1465#endif
1466#ifdef EBUS_SUPPORT
1467 }
1468#endif
1469 1227
1470 __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ 1228 __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */
1471 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); 1229 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS));
@@ -1585,8 +1343,8 @@ static int snd_cs4231_playback_close(snd_pcm_substream_t *substream)
1585{ 1343{
1586 cs4231_t *chip = snd_pcm_substream_chip(substream); 1344 cs4231_t *chip = snd_pcm_substream_chip(substream);
1587 1345
1588 chip->playback_substream = NULL;
1589 snd_cs4231_close(chip, CS4231_MODE_PLAY); 1346 snd_cs4231_close(chip, CS4231_MODE_PLAY);
1347 chip->playback_substream = NULL;
1590 1348
1591 return 0; 1349 return 0;
1592} 1350}
@@ -1595,8 +1353,8 @@ static int snd_cs4231_capture_close(snd_pcm_substream_t *substream)
1595{ 1353{
1596 cs4231_t *chip = snd_pcm_substream_chip(substream); 1354 cs4231_t *chip = snd_pcm_substream_chip(substream);
1597 1355
1598 chip->capture_substream = NULL;
1599 snd_cs4231_close(chip, CS4231_MODE_RECORD); 1356 snd_cs4231_close(chip, CS4231_MODE_RECORD);
1357 chip->capture_substream = NULL;
1600 1358
1601 return 0; 1359 return 0;
1602} 1360}
@@ -1651,21 +1409,7 @@ int snd_cs4231_pcm(cs4231_t *chip)
1651 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; 1409 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1652 strcpy(pcm->name, "CS4231"); 1410 strcpy(pcm->name, "CS4231");
1653 1411
1654#ifdef EBUS_SUPPORT 1412 chip->p_dma.preallocate(chip, pcm);
1655 if (chip->flags & CS4231_FLAG_EBUS) {
1656 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1657 snd_dma_pci_data(chip->dev_u.pdev),
1658 64*1024, 128*1024);
1659 } else {
1660#endif
1661#ifdef SBUS_SUPPORT
1662 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
1663 snd_dma_sbus_data(chip->dev_u.sdev),
1664 64*1024, 128*1024);
1665#endif
1666#ifdef EBUS_SUPPORT
1667 }
1668#endif
1669 1413
1670 chip->pcm = pcm; 1414 chip->pcm = pcm;
1671 1415
@@ -2022,6 +1766,180 @@ out_err:
2022} 1766}
2023 1767
2024#ifdef SBUS_SUPPORT 1768#ifdef SBUS_SUPPORT
1769
1770static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1771{
1772 unsigned long flags;
1773 unsigned char status;
1774 u32 csr;
1775 cs4231_t *chip = dev_id;
1776
1777 /*This is IRQ is not raised by the cs4231*/
1778 if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
1779 return IRQ_NONE;
1780
1781 /* ACK the APC interrupt. */
1782 csr = sbus_readl(chip->port + APCCSR);
1783
1784 sbus_writel(csr, chip->port + APCCSR);
1785
1786 if ((csr & APC_PDMA_READY) &&
1787 (csr & APC_PLAY_INT) &&
1788 (csr & APC_XINT_PNVA) &&
1789 !(csr & APC_XINT_EMPT))
1790 snd_cs4231_play_callback(chip);
1791
1792 if ((csr & APC_CDMA_READY) &&
1793 (csr & APC_CAPT_INT) &&
1794 (csr & APC_XINT_CNVA) &&
1795 !(csr & APC_XINT_EMPT))
1796 snd_cs4231_capture_callback(chip);
1797
1798 status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
1799
1800 if (status & CS4231_TIMER_IRQ) {
1801 if (chip->timer)
1802 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1803 }
1804
1805 if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY))
1806 snd_cs4231_overrange(chip);
1807
1808 /* ACK the CS4231 interrupt. */
1809 spin_lock_irqsave(&chip->lock, flags);
1810 snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
1811 spin_unlock_irqrestore(&chip->lock, flags);
1812
1813 return 0;
1814}
1815
1816/*
1817 * SBUS DMA routines
1818 */
1819
1820int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
1821{
1822 unsigned long flags;
1823 u32 test, csr;
1824 int err;
1825 sbus_dma_info_t *base = &dma_cont->sbus_info;
1826
1827 if (len >= (1 << 24))
1828 return -EINVAL;
1829 spin_lock_irqsave(&base->lock, flags);
1830 csr = sbus_readl(base->regs + APCCSR);
1831 err = -EINVAL;
1832 test = APC_CDMA_READY;
1833 if ( base->dir == APC_PLAY )
1834 test = APC_PDMA_READY;
1835 if (!(csr & test))
1836 goto out;
1837 err = -EBUSY;
1838 csr = sbus_readl(base->regs + APCCSR);
1839 test = APC_XINT_CNVA;
1840 if ( base->dir == APC_PLAY )
1841 test = APC_XINT_PNVA;
1842 if (!(csr & test))
1843 goto out;
1844 err = 0;
1845 sbus_writel(bus_addr, base->regs + base->dir + APCNVA);
1846 sbus_writel(len, base->regs + base->dir + APCNC);
1847out:
1848 spin_unlock_irqrestore(&base->lock, flags);
1849 return err;
1850}
1851
1852void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
1853{
1854 unsigned long flags;
1855 u32 csr, test;
1856 sbus_dma_info_t *base = &dma_cont->sbus_info;
1857
1858 spin_lock_irqsave(&base->lock, flags);
1859 csr = sbus_readl(base->regs + APCCSR);
1860 test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
1861 APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
1862 APC_XINT_PENA;
1863 if ( base->dir == APC_RECORD )
1864 test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
1865 APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
1866 csr |= test;
1867 sbus_writel(csr, base->regs + APCCSR);
1868 spin_unlock_irqrestore(&base->lock, flags);
1869}
1870
1871void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
1872{
1873 unsigned long flags;
1874 u32 csr, shift;
1875 sbus_dma_info_t *base = &dma_cont->sbus_info;
1876
1877 spin_lock_irqsave(&base->lock, flags);
1878 if (!on) {
1879 if (base->dir == APC_PLAY) {
1880 sbus_writel(0, base->regs + base->dir + APCNVA);
1881 sbus_writel(1, base->regs + base->dir + APCC);
1882 }
1883 else
1884 {
1885 sbus_writel(0, base->regs + base->dir + APCNC);
1886 sbus_writel(0, base->regs + base->dir + APCVA);
1887 }
1888 }
1889 udelay(600);
1890 csr = sbus_readl(base->regs + APCCSR);
1891 shift = 0;
1892 if ( base->dir == APC_PLAY )
1893 shift = 1;
1894 if (on)
1895 csr &= ~(APC_CPAUSE << shift);
1896 else
1897 csr |= (APC_CPAUSE << shift);
1898 sbus_writel(csr, base->regs + APCCSR);
1899 if (on)
1900 csr |= (APC_CDMA_READY << shift);
1901 else
1902 csr &= ~(APC_CDMA_READY << shift);
1903 sbus_writel(csr, base->regs + APCCSR);
1904
1905 spin_unlock_irqrestore(&base->lock, flags);
1906}
1907
1908unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
1909{
1910 sbus_dma_info_t *base = &dma_cont->sbus_info;
1911
1912 return sbus_readl(base->regs + base->dir + APCVA);
1913}
1914
1915void sbus_dma_reset(cs4231_t *chip)
1916{
1917 sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
1918 sbus_writel(0x00, chip->port + APCCSR);
1919 sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET,
1920 chip->port + APCCSR);
1921
1922 udelay(20);
1923
1924 sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET,
1925 chip->port + APCCSR);
1926 sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA |
1927 APC_XINT_PENA |
1928 APC_XINT_CENA),
1929 chip->port + APCCSR);
1930}
1931
1932void sbus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
1933{
1934 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
1935 snd_dma_sbus_data(chip->dev_u.sdev),
1936 64*1024, 128*1024);
1937}
1938
1939/*
1940 * Init and exit routines
1941 */
1942
2025static int snd_cs4231_sbus_free(cs4231_t *chip) 1943static int snd_cs4231_sbus_free(cs4231_t *chip)
2026{ 1944{
2027 if (chip->irq[0]) 1945 if (chip->irq[0])
@@ -2063,8 +1981,8 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
2063 return -ENOMEM; 1981 return -ENOMEM;
2064 1982
2065 spin_lock_init(&chip->lock); 1983 spin_lock_init(&chip->lock);
2066 spin_lock_init(&chip->sb2c.lock); 1984 spin_lock_init(&chip->c_dma.sbus_info.lock);
2067 spin_lock_init(&chip->sb2p.lock); 1985 spin_lock_init(&chip->p_dma.sbus_info.lock);
2068 init_MUTEX(&chip->mce_mutex); 1986 init_MUTEX(&chip->mce_mutex);
2069 init_MUTEX(&chip->open_mutex); 1987 init_MUTEX(&chip->open_mutex);
2070 chip->card = card; 1988 chip->card = card;
@@ -2080,10 +1998,24 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
2080 return -EIO; 1998 return -EIO;
2081 } 1999 }
2082 2000
2083 chip->sb2c.regs = chip->port; 2001 chip->c_dma.sbus_info.regs = chip->port;
2084 chip->sb2p.regs = chip->port; 2002 chip->p_dma.sbus_info.regs = chip->port;
2085 chip->sb2c.dir = APC_RECORD; 2003 chip->c_dma.sbus_info.dir = APC_RECORD;
2086 chip->sb2p.dir = APC_PLAY; 2004 chip->p_dma.sbus_info.dir = APC_PLAY;
2005
2006 chip->p_dma.prepare = sbus_dma_prepare;
2007 chip->p_dma.enable = sbus_dma_enable;
2008 chip->p_dma.request = sbus_dma_request;
2009 chip->p_dma.address = sbus_dma_addr;
2010 chip->p_dma.reset = sbus_dma_reset;
2011 chip->p_dma.preallocate = sbus_dma_preallocate;
2012
2013 chip->c_dma.prepare = sbus_dma_prepare;
2014 chip->c_dma.enable = sbus_dma_enable;
2015 chip->c_dma.request = sbus_dma_request;
2016 chip->c_dma.address = sbus_dma_addr;
2017 chip->c_dma.reset = sbus_dma_reset;
2018 chip->c_dma.preallocate = sbus_dma_preallocate;
2087 2019
2088 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, 2020 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
2089 SA_SHIRQ, "cs4231", chip)) { 2021 SA_SHIRQ, "cs4231", chip)) {
@@ -2138,15 +2070,70 @@ static int cs4231_sbus_attach(struct sbus_dev *sdev)
2138#endif 2070#endif
2139 2071
2140#ifdef EBUS_SUPPORT 2072#ifdef EBUS_SUPPORT
2073
2074static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
2075{
2076 cs4231_t *chip = cookie;
2077
2078 snd_cs4231_play_callback(chip);
2079}
2080
2081static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie)
2082{
2083 cs4231_t *chip = cookie;
2084
2085 snd_cs4231_capture_callback(chip);
2086}
2087
2088/*
2089 * EBUS DMA wrappers
2090 */
2091
2092int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
2093{
2094 return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len);
2095}
2096
2097void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
2098{
2099 ebus_dma_enable(&dma_cont->ebus_info, on);
2100}
2101
2102void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir)
2103{
2104 ebus_dma_prepare(&dma_cont->ebus_info, dir);
2105}
2106
2107unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
2108{
2109 return ebus_dma_addr(&dma_cont->ebus_info);
2110}
2111
2112void _ebus_dma_reset(cs4231_t *chip)
2113{
2114 return;
2115}
2116
2117void _ebus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
2118{
2119 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2120 snd_dma_pci_data(chip->dev_u.pdev),
2121 64*1024, 128*1024);
2122}
2123
2124/*
2125 * Init and exit routines
2126 */
2127
2141static int snd_cs4231_ebus_free(cs4231_t *chip) 2128static int snd_cs4231_ebus_free(cs4231_t *chip)
2142{ 2129{
2143 if (chip->eb2c.regs) { 2130 if (chip->c_dma.ebus_info.regs) {
2144 ebus_dma_unregister(&chip->eb2c); 2131 ebus_dma_unregister(&chip->c_dma.ebus_info);
2145 iounmap(chip->eb2c.regs); 2132 iounmap(chip->c_dma.ebus_info.regs);
2146 } 2133 }
2147 if (chip->eb2p.regs) { 2134 if (chip->p_dma.ebus_info.regs) {
2148 ebus_dma_unregister(&chip->eb2p); 2135 ebus_dma_unregister(&chip->p_dma.ebus_info);
2149 iounmap(chip->eb2p.regs); 2136 iounmap(chip->p_dma.ebus_info.regs);
2150 } 2137 }
2151 2138
2152 if (chip->port) 2139 if (chip->port)
@@ -2184,8 +2171,8 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
2184 return -ENOMEM; 2171 return -ENOMEM;
2185 2172
2186 spin_lock_init(&chip->lock); 2173 spin_lock_init(&chip->lock);
2187 spin_lock_init(&chip->eb2c.lock); 2174 spin_lock_init(&chip->c_dma.ebus_info.lock);
2188 spin_lock_init(&chip->eb2p.lock); 2175 spin_lock_init(&chip->p_dma.ebus_info.lock);
2189 init_MUTEX(&chip->mce_mutex); 2176 init_MUTEX(&chip->mce_mutex);
2190 init_MUTEX(&chip->open_mutex); 2177 init_MUTEX(&chip->open_mutex);
2191 chip->flags |= CS4231_FLAG_EBUS; 2178 chip->flags |= CS4231_FLAG_EBUS;
@@ -2193,43 +2180,57 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
2193 chip->dev_u.pdev = edev->bus->self; 2180 chip->dev_u.pdev = edev->bus->self;
2194 memcpy(&chip->image, &snd_cs4231_original_image, 2181 memcpy(&chip->image, &snd_cs4231_original_image,
2195 sizeof(snd_cs4231_original_image)); 2182 sizeof(snd_cs4231_original_image));
2196 strcpy(chip->eb2c.name, "cs4231(capture)"); 2183 strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
2197 chip->eb2c.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 2184 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2198 chip->eb2c.callback = snd_cs4231_ebus_capture_callback; 2185 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
2199 chip->eb2c.client_cookie = chip; 2186 chip->c_dma.ebus_info.client_cookie = chip;
2200 chip->eb2c.irq = edev->irqs[0]; 2187 chip->c_dma.ebus_info.irq = edev->irqs[0];
2201 strcpy(chip->eb2p.name, "cs4231(play)"); 2188 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
2202 chip->eb2p.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 2189 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2203 chip->eb2p.callback = snd_cs4231_ebus_play_callback; 2190 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
2204 chip->eb2p.client_cookie = chip; 2191 chip->p_dma.ebus_info.client_cookie = chip;
2205 chip->eb2p.irq = edev->irqs[1]; 2192 chip->p_dma.ebus_info.irq = edev->irqs[1];
2193
2194 chip->p_dma.prepare = _ebus_dma_prepare;
2195 chip->p_dma.enable = _ebus_dma_enable;
2196 chip->p_dma.request = _ebus_dma_request;
2197 chip->p_dma.address = _ebus_dma_addr;
2198 chip->p_dma.reset = _ebus_dma_reset;
2199 chip->p_dma.preallocate = _ebus_dma_preallocate;
2200
2201 chip->c_dma.prepare = _ebus_dma_prepare;
2202 chip->c_dma.enable = _ebus_dma_enable;
2203 chip->c_dma.request = _ebus_dma_request;
2204 chip->c_dma.address = _ebus_dma_addr;
2205 chip->c_dma.reset = _ebus_dma_reset;
2206 chip->c_dma.preallocate = _ebus_dma_preallocate;
2206 2207
2207 chip->port = ioremap(edev->resource[0].start, 0x10); 2208 chip->port = ioremap(edev->resource[0].start, 0x10);
2208 chip->eb2p.regs = ioremap(edev->resource[1].start, 0x10); 2209 chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10);
2209 chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); 2210 chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10);
2210 if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { 2211 if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) {
2211 snd_cs4231_ebus_free(chip); 2212 snd_cs4231_ebus_free(chip);
2212 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); 2213 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
2213 return -EIO; 2214 return -EIO;
2214 } 2215 }
2215 2216
2216 if (ebus_dma_register(&chip->eb2c)) { 2217 if (ebus_dma_register(&chip->c_dma.ebus_info)) {
2217 snd_cs4231_ebus_free(chip); 2218 snd_cs4231_ebus_free(chip);
2218 snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); 2219 snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
2219 return -EBUSY; 2220 return -EBUSY;
2220 } 2221 }
2221 if (ebus_dma_irq_enable(&chip->eb2c, 1)) { 2222 if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) {
2222 snd_cs4231_ebus_free(chip); 2223 snd_cs4231_ebus_free(chip);
2223 snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); 2224 snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
2224 return -EBUSY; 2225 return -EBUSY;
2225 } 2226 }
2226 2227
2227 if (ebus_dma_register(&chip->eb2p)) { 2228 if (ebus_dma_register(&chip->p_dma.ebus_info)) {
2228 snd_cs4231_ebus_free(chip); 2229 snd_cs4231_ebus_free(chip);
2229 snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); 2230 snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
2230 return -EBUSY; 2231 return -EBUSY;
2231 } 2232 }
2232 if (ebus_dma_irq_enable(&chip->eb2p, 1)) { 2233 if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) {
2233 snd_cs4231_ebus_free(chip); 2234 snd_cs4231_ebus_free(chip);
2234 snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); 2235 snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
2235 return -EBUSY; 2236 return -EBUSY;