diff options
| -rw-r--r-- | include/asm-sparc64/ebus.h | 1 | ||||
| -rw-r--r-- | sound/sparc/cs4231.c | 683 |
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); |
| 80 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); | 80 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); |
| 81 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); | 81 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); |
| 82 | extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); | ||
| 82 | extern void ebus_dma_enable(struct ebus_dma_info *p, int on); | 83 | extern void ebus_dma_enable(struct ebus_dma_info *p, int on); |
| 83 | 84 | ||
| 84 | extern struct linux_ebus *ebus_chain; | 85 | extern 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"); | |||
| 62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); | 62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); |
| 63 | 63 | ||
| 64 | #ifdef SBUS_SUPPORT | 64 | #ifdef SBUS_SUPPORT |
| 65 | struct sbus_dma_info { | 65 | typedef 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 | ||
| 72 | typedef struct snd_cs4231 { | 72 | typedef struct snd_cs4231 cs4231_t; |
| 73 | spinlock_t lock; | 73 | |
| 74 | void __iomem *port; | 74 | typedef 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 | |||
| 89 | struct 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 | ||
| 124 | static cs4231_t *cs4231_list; | 135 | static 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 | |||
| 501 | int 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); | ||
| 527 | out: | ||
| 528 | spin_unlock_irqrestore(&base->lock, flags); | ||
| 529 | return err; | ||
| 530 | } | ||
| 531 | |||
| 532 | void 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 | |||
| 550 | void 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 | |||
| 586 | unsigned 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 | 605 | static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent) |
| 692 | static 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 | ||
| 711 | static 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 | ||
| 729 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) | 622 | static 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 | ||
| 788 | static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) | 653 | static 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 | 1141 | static void snd_cs4231_play_callback(cs4231_t *cookie) |
| 1277 | static 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 | ||
| 1331 | static 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 | ||
| 1342 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | 1152 | static 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 | ||
| 1354 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) | 1163 | static 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 | ||
| 1384 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) | 1178 | static 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 | |||
| 1770 | static 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 | |||
| 1820 | int 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); | ||
| 1847 | out: | ||
| 1848 | spin_unlock_irqrestore(&base->lock, flags); | ||
| 1849 | return err; | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | void 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 | |||
| 1871 | void 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 | |||
| 1908 | unsigned 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 | |||
| 1915 | void 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 | |||
| 1932 | void 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 | |||
| 2025 | static int snd_cs4231_sbus_free(cs4231_t *chip) | 1943 | static 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 | |||
| 2074 | static 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 | |||
| 2081 | static 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 | |||
| 2092 | int _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 | |||
| 2097 | void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | ||
| 2098 | { | ||
| 2099 | ebus_dma_enable(&dma_cont->ebus_info, on); | ||
| 2100 | } | ||
| 2101 | |||
| 2102 | void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir) | ||
| 2103 | { | ||
| 2104 | ebus_dma_prepare(&dma_cont->ebus_info, dir); | ||
| 2105 | } | ||
| 2106 | |||
| 2107 | unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont) | ||
| 2108 | { | ||
| 2109 | return ebus_dma_addr(&dma_cont->ebus_info); | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | void _ebus_dma_reset(cs4231_t *chip) | ||
| 2113 | { | ||
| 2114 | return; | ||
| 2115 | } | ||
| 2116 | |||
| 2117 | void _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 | |||
| 2141 | static int snd_cs4231_ebus_free(cs4231_t *chip) | 2128 | static 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; |
