aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorChristopher Zimmermann <madroach@zakweb.de>2005-09-21 03:41:22 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-21 03:41:22 -0400
commita131430c200f6bda313bf5d0a8e238c41afdfe0a (patch)
treec156cf5e4b65af0ad7bd2f5828e7697884a3c358 /sound
parent1a3e64aa480101d11d8cac94ca57fd8bbe2536b7 (diff)
[SPARC] cs4231: Fix SBUS support in this driver.
From: Christopher Zimmermann <madroach@zakweb.de> This patch enables SBus support for the cs4231 sound driver. It is tested on an Ultra2. Capture and playback both work. I experienced lags and crashes using certain threaded players like ogg123 and mp3blaster, while the former is lagging far more. This behavior may be specific to SMP systems. It is reproducable using the dummy sound card driver. Sox works flawlessly. Setting up the calculation of ptr in snd_cs4231_playback_pointer was a bit strange. I got it to work by not incrementing the [pc]_periods_sent counter when starting DMA the first time in cs4231_dma_trigger. Therefore this dummy thing. [ I did some minor cleanups -DaveM ] Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'sound')
-rw-r--r--sound/sparc/cs4231.c323
1 files changed, 166 insertions, 157 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 2fb27c4e951f..f4361c518e46 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -173,7 +173,7 @@ static cs4231_t *cs4231_list;
173 173
174#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */ 174#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
175 175
176/* definitions for codec irq status */ 176/* definitions for codec irq status - CS4231_IRQ_STATUS */
177 177
178#define CS4231_PLAYBACK_IRQ 0x10 178#define CS4231_PLAYBACK_IRQ 0x10
179#define CS4231_RECORD_IRQ 0x20 179#define CS4231_RECORD_IRQ 0x20
@@ -402,7 +402,7 @@ static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
402 udelay(100); 402 udelay(100);
403#ifdef CONFIG_SND_DEBUG 403#ifdef CONFIG_SND_DEBUG
404 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 404 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
405 snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); 405 snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
406#endif 406#endif
407 if (chip->calibrate_mute) { 407 if (chip->calibrate_mute) {
408 chip->image[reg] &= mask; 408 chip->image[reg] &= mask;
@@ -425,6 +425,10 @@ static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char val
425 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); 425 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
426 timeout--) 426 timeout--)
427 udelay(100); 427 udelay(100);
428#ifdef CONFIG_SND_DEBUG
429 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
430 snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
431#endif
428 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); 432 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
429 __cs4231_writeb(chip, value, CS4231P(chip, REG)); 433 __cs4231_writeb(chip, value, CS4231P(chip, REG));
430 mb(); 434 mb();
@@ -440,15 +444,12 @@ static void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char valu
440 udelay(100); 444 udelay(100);
441#ifdef CONFIG_SND_DEBUG 445#ifdef CONFIG_SND_DEBUG
442 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 446 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
443 snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); 447 snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
444#endif 448#endif
445 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); 449 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
446 __cs4231_writeb(chip, value, CS4231P(chip, REG)); 450 __cs4231_writeb(chip, value, CS4231P(chip, REG));
447 chip->image[reg] = value; 451 chip->image[reg] = value;
448 mb(); 452 mb();
449#if 0
450 printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
451#endif
452} 453}
453 454
454static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg) 455static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
@@ -462,61 +463,14 @@ static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
462 udelay(100); 463 udelay(100);
463#ifdef CONFIG_SND_DEBUG 464#ifdef CONFIG_SND_DEBUG
464 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 465 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
465 snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); 466 snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg);
466#endif 467#endif
467 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); 468 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
468 mb(); 469 mb();
469 ret = __cs4231_readb(chip, CS4231P(chip, REG)); 470 ret = __cs4231_readb(chip, CS4231P(chip, REG));
470#if 0
471 printk("codec in - reg 0x%x = 0x%x\n", chip->mce_bit | reg, ret);
472#endif
473 return ret; 471 return ret;
474} 472}
475 473
476#if 0
477
478static void snd_cs4231_debug(cs4231_t *chip)
479{
480 printk("CS4231 REGS: INDEX = 0x%02x ",
481 __cs4231_readb(chip, CS4231P(chip, REGSEL)));
482 printk(" STATUS = 0x%02x\n",
483 __cs4231_readb(chip, CS4231P(chip, STATUS)));
484 printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00));
485 printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10));
486 printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01));
487 printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11));
488 printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02));
489 printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12));
490 printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03));
491 printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13));
492 printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04));
493 printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14));
494 printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05));
495 printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15));
496 printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06));
497 printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16));
498 printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07));
499 printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17));
500 printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08));
501 printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18));
502 printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09));
503 printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19));
504 printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a));
505 printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a));
506 printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b));
507 printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b));
508 printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c));
509 printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c));
510 printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d));
511 printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d));
512 printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e));
513 printk(" 0x1e: rec upr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e));
514 printk(" 0x0f: ply lwr count = 0x%02x ", snd_cs4231_in(chip, 0x0f));
515 printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f));
516}
517
518#endif
519
520/* 474/*
521 * CS4231 detection / MCE routines 475 * CS4231 detection / MCE routines
522 */ 476 */
@@ -528,11 +482,12 @@ static void snd_cs4231_busy_wait(cs4231_t *chip)
528 /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ 482 /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
529 for (timeout = 5; timeout > 0; timeout--) 483 for (timeout = 5; timeout > 0; timeout--)
530 __cs4231_readb(chip, CS4231P(chip, REGSEL)); 484 __cs4231_readb(chip, CS4231P(chip, REGSEL));
485
531 /* end of cleanup sequence */ 486 /* end of cleanup sequence */
532 for (timeout = 250; 487 for (timeout = 500;
533 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); 488 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
534 timeout--) 489 timeout--)
535 udelay(100); 490 udelay(1000);
536} 491}
537 492
538static void snd_cs4231_mce_up(cs4231_t *chip) 493static void snd_cs4231_mce_up(cs4231_t *chip)
@@ -545,12 +500,12 @@ static void snd_cs4231_mce_up(cs4231_t *chip)
545 udelay(100); 500 udelay(100);
546#ifdef CONFIG_SND_DEBUG 501#ifdef CONFIG_SND_DEBUG
547 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 502 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
548 snd_printk("mce_up - auto calibration time out (0)\n"); 503 snd_printdd("mce_up - auto calibration time out (0)\n");
549#endif 504#endif
550 chip->mce_bit |= CS4231_MCE; 505 chip->mce_bit |= CS4231_MCE;
551 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); 506 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
552 if (timeout == 0x80) 507 if (timeout == 0x80)
553 snd_printk("mce_up [%p]: serious init problem - codec still busy\n", chip->port); 508 snd_printdd("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
554 if (!(timeout & CS4231_MCE)) 509 if (!(timeout & CS4231_MCE))
555 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); 510 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
556 spin_unlock_irqrestore(&chip->lock, flags); 511 spin_unlock_irqrestore(&chip->lock, flags);
@@ -563,18 +518,15 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
563 518
564 spin_lock_irqsave(&chip->lock, flags); 519 spin_lock_irqsave(&chip->lock, flags);
565 snd_cs4231_busy_wait(chip); 520 snd_cs4231_busy_wait(chip);
566#if 0
567 printk("(1) timeout = %i\n", timeout);
568#endif
569#ifdef CONFIG_SND_DEBUG 521#ifdef CONFIG_SND_DEBUG
570 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 522 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
571 snd_printk("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL)); 523 snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
572#endif 524#endif
573 chip->mce_bit &= ~CS4231_MCE; 525 chip->mce_bit &= ~CS4231_MCE;
574 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); 526 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
575 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); 527 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
576 if (timeout == 0x80) 528 if (timeout == 0x80)
577 snd_printk("mce_down [%p]: serious init problem - codec still busy\n", chip->port); 529 snd_printdd("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
578 if ((timeout & CS4231_MCE) == 0) { 530 if ((timeout & CS4231_MCE) == 0) {
579 spin_unlock_irqrestore(&chip->lock, flags); 531 spin_unlock_irqrestore(&chip->lock, flags);
580 return; 532 return;
@@ -590,9 +542,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
590 spin_unlock_irqrestore(&chip->lock, flags); 542 spin_unlock_irqrestore(&chip->lock, flags);
591 return; 543 return;
592 } 544 }
593#if 0 545
594 printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
595#endif
596 /* in 10ms increments, check condition, up to 250ms */ 546 /* in 10ms increments, check condition, up to 250ms */
597 timeout = 25; 547 timeout = 25;
598 while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { 548 while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
@@ -604,9 +554,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
604 msleep(10); 554 msleep(10);
605 spin_lock_irqsave(&chip->lock, flags); 555 spin_lock_irqsave(&chip->lock, flags);
606 } 556 }
607#if 0 557
608 printk("(3) jiffies = %li\n", jiffies);
609#endif
610 /* in 10ms increments, check condition, up to 100ms */ 558 /* in 10ms increments, check condition, up to 100ms */
611 timeout = 10; 559 timeout = 10;
612 while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) { 560 while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
@@ -619,54 +567,58 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
619 spin_lock_irqsave(&chip->lock, flags); 567 spin_lock_irqsave(&chip->lock, flags);
620 } 568 }
621 spin_unlock_irqrestore(&chip->lock, flags); 569 spin_unlock_irqrestore(&chip->lock, flags);
622#if 0
623 printk("(4) jiffies = %li\n", jiffies);
624 snd_printk("mce_down - exit = 0x%x\n", __cs4231_readb(chip, CS4231P(chip, REGSEL)));
625#endif
626} 570}
627 571
628#if 0 /* Unused for now... */
629static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
630{
631 switch (format & 0xe0) {
632 case CS4231_LINEAR_16:
633 case CS4231_LINEAR_16_BIG:
634 size >>= 1;
635 break;
636 case CS4231_ADPCM_16:
637 return size >> 2;
638 }
639 if (format & CS4231_STEREO)
640 size >>= 1;
641 return size;
642}
643#endif
644
645#ifdef EBUS_SUPPORT 572#ifdef EBUS_SUPPORT
646static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent) 573static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
647{ 574{
648 snd_pcm_runtime_t *runtime = substream->runtime; 575 snd_pcm_runtime_t *runtime = substream->runtime;
649 576
650 while (1) { 577 while (1) {
651 unsigned int dma_size = snd_pcm_lib_period_bytes(substream); 578 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
652 unsigned int offset = dma_size * (*periods_sent); 579 unsigned int offset = period_size * (*periods_sent);
653 580
654 if (dma_size >= (1 << 24)) 581 if (period_size >= (1 << 24))
655 BUG(); 582 BUG();
656 583
657 if (ebus_dma_request(p, runtime->dma_addr + offset, dma_size)) 584 if (ebus_dma_request(p, runtime->dma_addr + offset, period_size))
658 return; 585 return;
659#if 0
660 printk("ebus_advance: Sent period %u (size[%x] offset[%x])\n",
661 (*periods_sent), dma_size, offset);
662#endif
663 (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; 586 (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
664 } 587 }
665} 588}
666#endif 589#endif
667 590
668static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on) 591#ifdef SBUS_SUPPORT
592static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent)
593{
594 cs4231_t *chip = snd_pcm_substream_chip(substream);
595 snd_pcm_runtime_t *runtime = substream->runtime;
596
597 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
598 unsigned int offset = period_size * (*periods_sent % runtime->periods);
599
600 if (runtime->period_size > 0xffff + 1)
601 BUG();
602
603 switch (substream->stream) {
604 case SNDRV_PCM_STREAM_PLAYBACK:
605 sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA);
606 sbus_writel(period_size, chip->port + APCPNC);
607 break;
608 case SNDRV_PCM_STREAM_CAPTURE:
609 sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA);
610 sbus_writel(period_size, chip->port + APCCNC);
611 break;
612 }
613
614 (*periods_sent) = (*periods_sent + 1) % runtime->periods;
615}
616#endif
617
618static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
669{ 619{
620 cs4231_t *chip = snd_pcm_substream_chip(substream);
621
670#ifdef EBUS_SUPPORT 622#ifdef EBUS_SUPPORT
671 if (chip->flags & CS4231_FLAG_EBUS) { 623 if (chip->flags & CS4231_FLAG_EBUS) {
672 if (what & CS4231_PLAYBACK_ENABLE) { 624 if (what & CS4231_PLAYBACK_ENABLE) {
@@ -694,6 +646,60 @@ static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on)
694 } else { 646 } else {
695#endif 647#endif
696#ifdef SBUS_SUPPORT 648#ifdef SBUS_SUPPORT
649 u32 csr = sbus_readl(chip->port + APCCSR);
650 /* I don't know why, but on sbus the period counter must
651 * only start counting after the first period is sent.
652 * Therefore this dummy thing.
653 */
654 unsigned int dummy = 0;
655
656 switch (what) {
657 case CS4231_PLAYBACK_ENABLE:
658 if (on) {
659 csr &= ~APC_XINT_PLAY;
660 sbus_writel(csr, chip->port + APCCSR);
661
662 csr &= ~APC_PPAUSE;
663 sbus_writel(csr, chip->port + APCCSR);
664
665 snd_cs4231_sbus_advance_dma(substream, &dummy);
666
667 csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
668 APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL |
669 APC_XINT_PENA | APC_PDMA_READY;
670 sbus_writel(csr, chip->port + APCCSR);
671 } else {
672 csr |= APC_PPAUSE;
673 sbus_writel(csr, chip->port + APCCSR);
674
675 csr &= ~APC_PDMA_READY;
676 sbus_writel(csr, chip->port + APCCSR);
677 }
678 break;
679 case CS4231_RECORD_ENABLE:
680 if (on) {
681 csr &= ~APC_XINT_CAPT;
682 sbus_writel(csr, chip->port + APCCSR);
683
684 csr &= ~APC_CPAUSE;
685 sbus_writel(csr, chip->port + APCCSR);
686
687 snd_cs4231_sbus_advance_dma(substream, &dummy);
688
689 csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
690 APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL |
691 APC_CDMA_READY;
692
693 sbus_writel(csr, chip->port + APCCSR);
694 } else {
695 csr |= APC_CPAUSE;
696 sbus_writel(csr, chip->port + APCCSR);
697
698 csr &= ~APC_CDMA_READY;
699 sbus_writel(csr, chip->port + APCCSR);
700 }
701 break;
702 }
697#endif 703#endif
698#ifdef EBUS_SUPPORT 704#ifdef EBUS_SUPPORT
699 } 705 }
@@ -725,25 +731,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
725 } 731 }
726 } 732 }
727 733
728#if 0
729 printk("TRIGGER: what[%x] on(%d)\n",
730 what, (cmd == SNDRV_PCM_TRIGGER_START));
731#endif
732
733 spin_lock_irqsave(&chip->lock, flags); 734 spin_lock_irqsave(&chip->lock, flags);
734 if (cmd == SNDRV_PCM_TRIGGER_START) { 735 if (cmd == SNDRV_PCM_TRIGGER_START) {
735 cs4231_dma_trigger(chip, what, 1); 736 cs4231_dma_trigger(substream, what, 1);
736 chip->image[CS4231_IFACE_CTRL] |= what; 737 chip->image[CS4231_IFACE_CTRL] |= what;
737 if (what & CS4231_PLAYBACK_ENABLE) {
738 snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, 0xff);
739 snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, 0xff);
740 }
741 if (what & CS4231_RECORD_ENABLE) {
742 snd_cs4231_out(chip, CS4231_REC_LWR_CNT, 0xff);
743 snd_cs4231_out(chip, CS4231_REC_UPR_CNT, 0xff);
744 }
745 } else { 738 } else {
746 cs4231_dma_trigger(chip, what, 0); 739 cs4231_dma_trigger(substream, what, 0);
747 chip->image[CS4231_IFACE_CTRL] &= ~what; 740 chip->image[CS4231_IFACE_CTRL] &= ~what;
748 } 741 }
749 snd_cs4231_out(chip, CS4231_IFACE_CTRL, 742 snd_cs4231_out(chip, CS4231_IFACE_CTRL,
@@ -755,9 +748,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
755 result = -EINVAL; 748 result = -EINVAL;
756 break; 749 break;
757 } 750 }
758#if 0 751
759 snd_cs4231_debug(chip);
760#endif
761 return result; 752 return result;
762} 753}
763 754
@@ -790,9 +781,6 @@ static unsigned char snd_cs4231_get_format(cs4231_t *chip, int format, int chann
790 } 781 }
791 if (channels > 1) 782 if (channels > 1)
792 rformat |= CS4231_STEREO; 783 rformat |= CS4231_STEREO;
793#if 0
794 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
795#endif
796 return rformat; 784 return rformat;
797} 785}
798 786
@@ -944,7 +932,7 @@ static void snd_cs4231_init(cs4231_t *chip)
944 snd_cs4231_mce_down(chip); 932 snd_cs4231_mce_down(chip);
945 933
946#ifdef SNDRV_DEBUG_MCE 934#ifdef SNDRV_DEBUG_MCE
947 snd_printk("init: (1)\n"); 935 snd_printdd("init: (1)\n");
948#endif 936#endif
949 snd_cs4231_mce_up(chip); 937 snd_cs4231_mce_up(chip);
950 spin_lock_irqsave(&chip->lock, flags); 938 spin_lock_irqsave(&chip->lock, flags);
@@ -957,7 +945,7 @@ static void snd_cs4231_init(cs4231_t *chip)
957 snd_cs4231_mce_down(chip); 945 snd_cs4231_mce_down(chip);
958 946
959#ifdef SNDRV_DEBUG_MCE 947#ifdef SNDRV_DEBUG_MCE
960 snd_printk("init: (2)\n"); 948 snd_printdd("init: (2)\n");
961#endif 949#endif
962 950
963 snd_cs4231_mce_up(chip); 951 snd_cs4231_mce_up(chip);
@@ -967,7 +955,7 @@ static void snd_cs4231_init(cs4231_t *chip)
967 snd_cs4231_mce_down(chip); 955 snd_cs4231_mce_down(chip);
968 956
969#ifdef SNDRV_DEBUG_MCE 957#ifdef SNDRV_DEBUG_MCE
970 snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); 958 snd_printdd("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
971#endif 959#endif
972 960
973 spin_lock_irqsave(&chip->lock, flags); 961 spin_lock_irqsave(&chip->lock, flags);
@@ -981,7 +969,7 @@ static void snd_cs4231_init(cs4231_t *chip)
981 snd_cs4231_mce_down(chip); 969 snd_cs4231_mce_down(chip);
982 970
983#ifdef SNDRV_DEBUG_MCE 971#ifdef SNDRV_DEBUG_MCE
984 snd_printk("init: (4)\n"); 972 snd_printdd("init: (4)\n");
985#endif 973#endif
986 974
987 snd_cs4231_mce_up(chip); 975 snd_cs4231_mce_up(chip);
@@ -991,7 +979,7 @@ static void snd_cs4231_init(cs4231_t *chip)
991 snd_cs4231_mce_down(chip); 979 snd_cs4231_mce_down(chip);
992 980
993#ifdef SNDRV_DEBUG_MCE 981#ifdef SNDRV_DEBUG_MCE
994 snd_printk("init: (5)\n"); 982 snd_printdd("init: (5)\n");
995#endif 983#endif
996} 984}
997 985
@@ -1022,6 +1010,7 @@ static int snd_cs4231_open(cs4231_t *chip, unsigned int mode)
1022 CS4231_RECORD_IRQ | 1010 CS4231_RECORD_IRQ |
1023 CS4231_TIMER_IRQ); 1011 CS4231_TIMER_IRQ);
1024 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); 1012 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
1013
1025 spin_unlock_irqrestore(&chip->lock, flags); 1014 spin_unlock_irqrestore(&chip->lock, flags);
1026 1015
1027 chip->mode = mode; 1016 chip->mode = mode;
@@ -1136,11 +1125,21 @@ static int snd_cs4231_playback_hw_free(snd_pcm_substream_t *substream)
1136static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream) 1125static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
1137{ 1126{
1138 cs4231_t *chip = snd_pcm_substream_chip(substream); 1127 cs4231_t *chip = snd_pcm_substream_chip(substream);
1128 snd_pcm_runtime_t *runtime = substream->runtime;
1139 unsigned long flags; 1129 unsigned long flags;
1140 1130
1141 spin_lock_irqsave(&chip->lock, flags); 1131 spin_lock_irqsave(&chip->lock, flags);
1132
1142 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | 1133 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
1143 CS4231_PLAYBACK_PIO); 1134 CS4231_PLAYBACK_PIO);
1135
1136 if (runtime->period_size > 0xffff + 1)
1137 BUG();
1138
1139 snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
1140 snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
1141 chip->p_periods_sent = 0;
1142
1144 spin_unlock_irqrestore(&chip->lock, flags); 1143 spin_unlock_irqrestore(&chip->lock, flags);
1145 1144
1146 return 0; 1145 return 0;
@@ -1172,12 +1171,16 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream)
1172static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) 1171static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
1173{ 1172{
1174 cs4231_t *chip = snd_pcm_substream_chip(substream); 1173 cs4231_t *chip = snd_pcm_substream_chip(substream);
1174 snd_pcm_runtime_t *runtime = substream->runtime;
1175 unsigned long flags; 1175 unsigned long flags;
1176 1176
1177 spin_lock_irqsave(&chip->lock, flags); 1177 spin_lock_irqsave(&chip->lock, flags);
1178 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | 1178 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
1179 CS4231_RECORD_PIO); 1179 CS4231_RECORD_PIO);
1180 1180
1181 snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
1182 snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
1183
1181 spin_unlock_irqrestore(&chip->lock, flags); 1184 spin_unlock_irqrestore(&chip->lock, flags);
1182 1185
1183 return 0; 1186 return 0;
@@ -1196,53 +1199,61 @@ static void snd_cs4231_overrange(cs4231_t *chip)
1196 chip->capture_substream->runtime->overrange++; 1199 chip->capture_substream->runtime->overrange++;
1197} 1200}
1198 1201
1199static void snd_cs4231_generic_interrupt(cs4231_t *chip) 1202static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip)
1200{ 1203{
1201 unsigned long flags; 1204 unsigned long flags;
1202 unsigned char status; 1205 unsigned char status;
1203 1206
1207 /*This is IRQ is not raised by the cs4231*/
1208 if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
1209 return IRQ_NONE;
1210
1204 status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); 1211 status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
1205 if (!status)
1206 return;
1207 1212
1208 if (status & CS4231_TIMER_IRQ) { 1213 if (status & CS4231_TIMER_IRQ) {
1209 if (chip->timer) 1214 if (chip->timer)
1210 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1215 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1211 } 1216 }
1212 if (status & CS4231_PLAYBACK_IRQ) 1217
1213 snd_pcm_period_elapsed(chip->playback_substream); 1218 if (status & CS4231_RECORD_IRQ)
1214 if (status & CS4231_RECORD_IRQ) {
1215 snd_cs4231_overrange(chip); 1219 snd_cs4231_overrange(chip);
1216 snd_pcm_period_elapsed(chip->capture_substream);
1217 }
1218 1220
1219 /* ACK the CS4231 interrupt. */ 1221 /* ACK the CS4231 interrupt. */
1220 spin_lock_irqsave(&chip->lock, flags); 1222 spin_lock_irqsave(&chip->lock, flags);
1221 snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); 1223 snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
1222 spin_unlock_irqrestore(&chip->lock, flags); 1224 spin_unlock_irqrestore(&chip->lock, flags);
1225
1226 return 0;
1223} 1227}
1224 1228
1225#ifdef SBUS_SUPPORT 1229#ifdef SBUS_SUPPORT
1226static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) 1230static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1227{ 1231{
1228 cs4231_t *chip = dev_id; 1232 cs4231_t *chip = dev_id;
1229 u32 csr;
1230
1231 csr = sbus_readl(chip->port + APCCSR);
1232 if (!(csr & (APC_INT_PENDING |
1233 APC_PLAY_INT |
1234 APC_CAPT_INT |
1235 APC_GENL_INT |
1236 APC_XINT_PEMP |
1237 APC_XINT_CEMP)))
1238 return IRQ_NONE;
1239 1233
1240 /* ACK the APC interrupt. */ 1234 /* ACK the APC interrupt. */
1235 u32 csr = sbus_readl(chip->port + APCCSR);
1236
1241 sbus_writel(csr, chip->port + APCCSR); 1237 sbus_writel(csr, chip->port + APCCSR);
1242 1238
1243 snd_cs4231_generic_interrupt(chip); 1239 if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) &&
1240 (csr & APC_PLAY_INT) &&
1241 (csr & APC_XINT_PNVA) &&
1242 !(csr & APC_XINT_EMPT)) {
1243 snd_cs4231_sbus_advance_dma(chip->playback_substream,
1244 &chip->p_periods_sent);
1245 snd_pcm_period_elapsed(chip->playback_substream);
1246 }
1244 1247
1245 return IRQ_HANDLED; 1248 if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) &&
1249 (csr & APC_CAPT_INT) &&
1250 (csr & APC_XINT_CNVA)) {
1251 snd_cs4231_sbus_advance_dma(chip->capture_substream,
1252 &chip->c_periods_sent);
1253 snd_pcm_period_elapsed(chip->capture_substream);
1254 }
1255
1256 return snd_cs4231_generic_interrupt(chip);
1246} 1257}
1247#endif 1258#endif
1248 1259
@@ -1290,7 +1301,8 @@ static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substr
1290#ifdef EBUS_SUPPORT 1301#ifdef EBUS_SUPPORT
1291 } 1302 }
1292#endif 1303#endif
1293 ptr += (period_bytes - residue); 1304 ptr += period_bytes - residue;
1305
1294 return bytes_to_frames(substream->runtime, ptr); 1306 return bytes_to_frames(substream->runtime, ptr);
1295} 1307}
1296 1308
@@ -1314,7 +1326,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substr
1314#ifdef EBUS_SUPPORT 1326#ifdef EBUS_SUPPORT
1315 } 1327 }
1316#endif 1328#endif
1317 ptr += (period_bytes - residue); 1329 ptr += period_bytes - residue;
1318 return bytes_to_frames(substream->runtime, ptr); 1330 return bytes_to_frames(substream->runtime, ptr);
1319} 1331}
1320 1332
@@ -1328,9 +1340,6 @@ static int snd_cs4231_probe(cs4231_t *chip)
1328 int i, id, vers; 1340 int i, id, vers;
1329 unsigned char *ptr; 1341 unsigned char *ptr;
1330 1342
1331#if 0
1332 snd_cs4231_debug(chip);
1333#endif
1334 id = vers = 0; 1343 id = vers = 0;
1335 for (i = 0; i < 50; i++) { 1344 for (i = 0; i < 50; i++) {
1336 mb(); 1345 mb();
@@ -1985,13 +1994,13 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
1985 chip->port = sbus_ioremap(&sdev->resource[0], 0, 1994 chip->port = sbus_ioremap(&sdev->resource[0], 0,
1986 chip->regs_size, "cs4231"); 1995 chip->regs_size, "cs4231");
1987 if (!chip->port) { 1996 if (!chip->port) {
1988 snd_printk("cs4231-%d: Unable to map chip registers.\n", dev); 1997 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
1989 return -EIO; 1998 return -EIO;
1990 } 1999 }
1991 2000
1992 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, 2001 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
1993 SA_SHIRQ, "cs4231", chip)) { 2002 SA_SHIRQ, "cs4231", chip)) {
1994 snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n", 2003 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n",
1995 dev, 2004 dev,
1996 __irq_itoa(sdev->irqs[0])); 2005 __irq_itoa(sdev->irqs[0]));
1997 snd_cs4231_sbus_free(chip); 2006 snd_cs4231_sbus_free(chip);
@@ -2113,29 +2122,29 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
2113 chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); 2122 chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10);
2114 if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { 2123 if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) {
2115 snd_cs4231_ebus_free(chip); 2124 snd_cs4231_ebus_free(chip);
2116 snd_printk("cs4231-%d: Unable to map chip registers.\n", dev); 2125 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
2117 return -EIO; 2126 return -EIO;
2118 } 2127 }
2119 2128
2120 if (ebus_dma_register(&chip->eb2c)) { 2129 if (ebus_dma_register(&chip->eb2c)) {
2121 snd_cs4231_ebus_free(chip); 2130 snd_cs4231_ebus_free(chip);
2122 snd_printk("cs4231-%d: Unable to register EBUS capture DMA\n", dev); 2131 snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
2123 return -EBUSY; 2132 return -EBUSY;
2124 } 2133 }
2125 if (ebus_dma_irq_enable(&chip->eb2c, 1)) { 2134 if (ebus_dma_irq_enable(&chip->eb2c, 1)) {
2126 snd_cs4231_ebus_free(chip); 2135 snd_cs4231_ebus_free(chip);
2127 snd_printk("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); 2136 snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
2128 return -EBUSY; 2137 return -EBUSY;
2129 } 2138 }
2130 2139
2131 if (ebus_dma_register(&chip->eb2p)) { 2140 if (ebus_dma_register(&chip->eb2p)) {
2132 snd_cs4231_ebus_free(chip); 2141 snd_cs4231_ebus_free(chip);
2133 snd_printk("cs4231-%d: Unable to register EBUS play DMA\n", dev); 2142 snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
2134 return -EBUSY; 2143 return -EBUSY;
2135 } 2144 }
2136 if (ebus_dma_irq_enable(&chip->eb2p, 1)) { 2145 if (ebus_dma_irq_enable(&chip->eb2p, 1)) {
2137 snd_cs4231_ebus_free(chip); 2146 snd_cs4231_ebus_free(chip);
2138 snd_printk("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); 2147 snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
2139 return -EBUSY; 2148 return -EBUSY;
2140 } 2149 }
2141 2150