diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-06 05:51:07 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-06 05:51:07 -0400 |
| commit | 012e060c95e547eceea4a12c6f58592473bf4011 (patch) | |
| tree | b57d3eafb50ce517577d2cf366c9ef0b4b286589 /sound/sparc | |
| parent | 923f122573851d18a3832ca808269fa2d5046fb1 (diff) | |
| parent | ed39f731ab2e77e58122232f6e27333331d7793d (diff) | |
Merge branch 'master'
Diffstat (limited to 'sound/sparc')
| -rw-r--r-- | sound/sparc/Kconfig | 3 | ||||
| -rw-r--r-- | sound/sparc/amd7930.c | 5 | ||||
| -rw-r--r-- | sound/sparc/cs4231.c | 330 | ||||
| -rw-r--r-- | sound/sparc/dbri.c | 234 |
4 files changed, 295 insertions, 277 deletions
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig index 25a8a558ef92..09ab138646a6 100644 --- a/sound/sparc/Kconfig +++ b/sound/sparc/Kconfig | |||
| @@ -7,6 +7,7 @@ config SND_SUN_AMD7930 | |||
| 7 | tristate "Sun AMD7930" | 7 | tristate "Sun AMD7930" |
| 8 | depends on SBUS && SND | 8 | depends on SBUS && SND |
| 9 | select SND_PCM | 9 | select SND_PCM |
| 10 | select SND_GENERIC_DRIVER | ||
| 10 | help | 11 | help |
| 11 | Say Y here to include support for AMD7930 sound device on Sun. | 12 | Say Y here to include support for AMD7930 sound device on Sun. |
| 12 | 13 | ||
| @@ -17,6 +18,7 @@ config SND_SUN_CS4231 | |||
| 17 | tristate "Sun CS4231" | 18 | tristate "Sun CS4231" |
| 18 | depends on SND | 19 | depends on SND |
| 19 | select SND_PCM | 20 | select SND_PCM |
| 21 | select SND_GENERIC_DRIVER | ||
| 20 | help | 22 | help |
| 21 | Say Y here to include support for CS4231 sound device on Sun. | 23 | Say Y here to include support for CS4231 sound device on Sun. |
| 22 | 24 | ||
| @@ -27,6 +29,7 @@ config SND_SUN_DBRI | |||
| 27 | tristate "Sun DBRI" | 29 | tristate "Sun DBRI" |
| 28 | depends on SND && SBUS | 30 | depends on SND && SBUS |
| 29 | select SND_PCM | 31 | select SND_PCM |
| 32 | select SND_GENERIC_DRIVER | ||
| 30 | help | 33 | help |
| 31 | Say Y here to include support for DBRI sound device on Sun. | 34 | Say Y here to include support for DBRI sound device on Sun. |
| 32 | 35 | ||
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index bd8a850e93ea..46d504ba7e03 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c | |||
| @@ -967,7 +967,7 @@ static int __init snd_amd7930_create(snd_card_t *card, | |||
| 967 | int err; | 967 | int err; |
| 968 | 968 | ||
| 969 | *ramd = NULL; | 969 | *ramd = NULL; |
| 970 | amd = kcalloc(1, sizeof(*amd), GFP_KERNEL); | 970 | amd = kzalloc(sizeof(*amd), GFP_KERNEL); |
| 971 | if (amd == NULL) | 971 | if (amd == NULL) |
| 972 | return -ENOMEM; | 972 | return -ENOMEM; |
| 973 | 973 | ||
| @@ -1088,6 +1088,9 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) | |||
| 1088 | if ((err = snd_amd7930_mixer(amd)) < 0) | 1088 | if ((err = snd_amd7930_mixer(amd)) < 0) |
| 1089 | goto out_err; | 1089 | goto out_err; |
| 1090 | 1090 | ||
| 1091 | if ((err = snd_card_set_generic_dev(card)) < 0) | ||
| 1092 | goto out_err; | ||
| 1093 | |||
| 1091 | if ((err = snd_card_register(card)) < 0) | 1094 | if ((err = snd_card_register(card)) < 0) |
| 1092 | goto out_err; | 1095 | goto out_err; |
| 1093 | 1096 | ||
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 36f9fe4d7bea..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 | ||
| 454 | static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg) | 455 | static 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 | |||
| 478 | static 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 | ||
| 538 | static void snd_cs4231_mce_up(cs4231_t *chip) | 493 | static 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,28 +567,7 @@ 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 | } | ||
| 627 | |||
| 628 | #if 0 /* Unused for now... */ | ||
| 629 | static 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 | } | 570 | } |
| 643 | #endif | ||
| 644 | 571 | ||
| 645 | #ifdef EBUS_SUPPORT | 572 | #ifdef EBUS_SUPPORT |
| 646 | static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent) | 573 | static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent) |
| @@ -648,25 +575,50 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre | |||
| 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 | ||
| 668 | static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on) | 591 | #ifdef SBUS_SUPPORT |
| 592 | static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent) | ||
| 669 | { | 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 | |||
| 618 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) | ||
| 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) | |||
| 1136 | static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream) | 1125 | static 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) | |||
| 1172 | static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) | 1171 | static 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 | ||
| 1199 | static void snd_cs4231_generic_interrupt(cs4231_t *chip) | 1202 | static 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 |
| 1226 | static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 1230 | static 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(); |
| @@ -1915,6 +1924,9 @@ static int cs4231_attach_finish(snd_card_t *card, cs4231_t *chip) | |||
| 1915 | if ((err = snd_cs4231_timer(chip)) < 0) | 1924 | if ((err = snd_cs4231_timer(chip)) < 0) |
| 1916 | goto out_err; | 1925 | goto out_err; |
| 1917 | 1926 | ||
| 1927 | if ((err = snd_card_set_generic_dev(card)) < 0) | ||
| 1928 | goto out_err; | ||
| 1929 | |||
| 1918 | if ((err = snd_card_register(card)) < 0) | 1930 | if ((err = snd_card_register(card)) < 0) |
| 1919 | goto out_err; | 1931 | goto out_err; |
| 1920 | 1932 | ||
| @@ -1966,7 +1978,7 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
| 1966 | int err; | 1978 | int err; |
| 1967 | 1979 | ||
| 1968 | *rchip = NULL; | 1980 | *rchip = NULL; |
| 1969 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | 1981 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 1970 | if (chip == NULL) | 1982 | if (chip == NULL) |
| 1971 | return -ENOMEM; | 1983 | return -ENOMEM; |
| 1972 | 1984 | ||
| @@ -1982,13 +1994,13 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
| 1982 | chip->port = sbus_ioremap(&sdev->resource[0], 0, | 1994 | chip->port = sbus_ioremap(&sdev->resource[0], 0, |
| 1983 | chip->regs_size, "cs4231"); | 1995 | chip->regs_size, "cs4231"); |
| 1984 | if (!chip->port) { | 1996 | if (!chip->port) { |
| 1985 | snd_printk("cs4231-%d: Unable to map chip registers.\n", dev); | 1997 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
| 1986 | return -EIO; | 1998 | return -EIO; |
| 1987 | } | 1999 | } |
| 1988 | 2000 | ||
| 1989 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, | 2001 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, |
| 1990 | SA_SHIRQ, "cs4231", chip)) { | 2002 | SA_SHIRQ, "cs4231", chip)) { |
| 1991 | snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n", | 2003 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n", |
| 1992 | dev, | 2004 | dev, |
| 1993 | __irq_itoa(sdev->irqs[0])); | 2005 | __irq_itoa(sdev->irqs[0])); |
| 1994 | snd_cs4231_sbus_free(chip); | 2006 | snd_cs4231_sbus_free(chip); |
| @@ -2080,7 +2092,7 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
| 2080 | int err; | 2092 | int err; |
| 2081 | 2093 | ||
| 2082 | *rchip = NULL; | 2094 | *rchip = NULL; |
| 2083 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | 2095 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 2084 | if (chip == NULL) | 2096 | if (chip == NULL) |
| 2085 | return -ENOMEM; | 2097 | return -ENOMEM; |
| 2086 | 2098 | ||
| @@ -2110,29 +2122,29 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
| 2110 | chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); | 2122 | chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); |
| 2111 | if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { | 2123 | if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { |
| 2112 | snd_cs4231_ebus_free(chip); | 2124 | snd_cs4231_ebus_free(chip); |
| 2113 | snd_printk("cs4231-%d: Unable to map chip registers.\n", dev); | 2125 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
| 2114 | return -EIO; | 2126 | return -EIO; |
| 2115 | } | 2127 | } |
| 2116 | 2128 | ||
| 2117 | if (ebus_dma_register(&chip->eb2c)) { | 2129 | if (ebus_dma_register(&chip->eb2c)) { |
| 2118 | snd_cs4231_ebus_free(chip); | 2130 | snd_cs4231_ebus_free(chip); |
| 2119 | 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); |
| 2120 | return -EBUSY; | 2132 | return -EBUSY; |
| 2121 | } | 2133 | } |
| 2122 | if (ebus_dma_irq_enable(&chip->eb2c, 1)) { | 2134 | if (ebus_dma_irq_enable(&chip->eb2c, 1)) { |
| 2123 | snd_cs4231_ebus_free(chip); | 2135 | snd_cs4231_ebus_free(chip); |
| 2124 | 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); |
| 2125 | return -EBUSY; | 2137 | return -EBUSY; |
| 2126 | } | 2138 | } |
| 2127 | 2139 | ||
| 2128 | if (ebus_dma_register(&chip->eb2p)) { | 2140 | if (ebus_dma_register(&chip->eb2p)) { |
| 2129 | snd_cs4231_ebus_free(chip); | 2141 | snd_cs4231_ebus_free(chip); |
| 2130 | 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); |
| 2131 | return -EBUSY; | 2143 | return -EBUSY; |
| 2132 | } | 2144 | } |
| 2133 | if (ebus_dma_irq_enable(&chip->eb2p, 1)) { | 2145 | if (ebus_dma_irq_enable(&chip->eb2p, 1)) { |
| 2134 | snd_cs4231_ebus_free(chip); | 2146 | snd_cs4231_ebus_free(chip); |
| 2135 | 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); |
| 2136 | return -EBUSY; | 2148 | return -EBUSY; |
| 2137 | } | 2149 | } |
| 2138 | 2150 | ||
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 941c7b1e7ebb..b5c4c15ae7f0 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Driver for DBRI sound chip found on Sparcs. | 2 | * Driver for DBRI sound chip found on Sparcs. |
| 3 | * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net) | 3 | * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net) |
| 4 | * | 4 | * |
| 5 | * Based entirely upon drivers/sbus/audio/dbri.c which is: | 5 | * Based entirely upon drivers/sbus/audio/dbri.c which is: |
| 6 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) | 6 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) |
| @@ -43,6 +43,12 @@ | |||
| 43 | * audio devices. But the SUN HW group decided against it, at least on my | 43 | * audio devices. But the SUN HW group decided against it, at least on my |
| 44 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly | 44 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly |
| 45 | * connected. | 45 | * connected. |
| 46 | * | ||
| 47 | * I've tried to stick to the following function naming conventions: | ||
| 48 | * snd_* ALSA stuff | ||
| 49 | * cs4215_* CS4215 codec specfic stuff | ||
| 50 | * dbri_* DBRI high-level stuff | ||
| 51 | * other DBRI low-level stuff | ||
| 46 | */ | 52 | */ |
| 47 | 53 | ||
| 48 | #include <sound/driver.h> | 54 | #include <sound/driver.h> |
| @@ -87,7 +93,7 @@ MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); | |||
| 87 | #define D_DESC (1<<5) | 93 | #define D_DESC (1<<5) |
| 88 | 94 | ||
| 89 | static int dbri_debug = 0; | 95 | static int dbri_debug = 0; |
| 90 | module_param(dbri_debug, int, 0444); | 96 | module_param(dbri_debug, int, 0644); |
| 91 | MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); | 97 | MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); |
| 92 | 98 | ||
| 93 | #ifdef DBRI_DEBUG | 99 | #ifdef DBRI_DEBUG |
| @@ -320,7 +326,8 @@ typedef struct snd_dbri { | |||
| 320 | void __iomem *regs; /* dbri HW regs */ | 326 | void __iomem *regs; /* dbri HW regs */ |
| 321 | int dbri_version; /* 'e' and up is OK */ | 327 | int dbri_version; /* 'e' and up is OK */ |
| 322 | int dbri_irqp; /* intr queue pointer */ | 328 | int dbri_irqp; /* intr queue pointer */ |
| 323 | int wait_seen; | 329 | int wait_send; /* sequence of command buffers send */ |
| 330 | int wait_ackd; /* sequence of command buffers acknowledged */ | ||
| 324 | 331 | ||
| 325 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ | 332 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ |
| 326 | struct dbri_desc descs[DBRI_NO_DESCS]; | 333 | struct dbri_desc descs[DBRI_NO_DESCS]; |
| @@ -625,16 +632,13 @@ static __u32 reverse_bytes(__u32 b, int len) | |||
| 625 | 632 | ||
| 626 | Commands are sent to the DBRI by building a list of them in memory, | 633 | Commands are sent to the DBRI by building a list of them in memory, |
| 627 | then writing the address of the first list item to DBRI register 8. | 634 | then writing the address of the first list item to DBRI register 8. |
| 628 | The list is terminated with a WAIT command, which can generate a | 635 | The list is terminated with a WAIT command, which generates a |
| 629 | CPU interrupt if required. | 636 | CPU interrupt to signal completion. |
| 630 | 637 | ||
| 631 | Since the DBRI can run in parallel with the CPU, several means of | 638 | Since the DBRI can run in parallel with the CPU, several means of |
| 632 | synchronization present themselves. The original scheme (Rudolf's) | 639 | synchronization present themselves. The method implemented here is close |
| 633 | was to set a flag when we "cmdlock"ed the DBRI, clear the flag when | 640 | to the original scheme (Rudolf's), and uses 2 counters (wait_send and |
| 634 | an interrupt signaled completion, and wait on a wait_queue if a routine | 641 | wait_ackd) to synchronize the command buffer between the CPU and the DBRI. |
| 635 | attempted to cmdlock while the flag was set. The problems arose when | ||
| 636 | we tried to cmdlock from inside an interrupt handler, which might | ||
| 637 | cause scheduling in an interrupt (if we waited), etc, etc | ||
| 638 | 642 | ||
| 639 | A more sophisticated scheme might involve a circular command buffer | 643 | A more sophisticated scheme might involve a circular command buffer |
| 640 | or an array of command buffers. A routine could fill one with | 644 | or an array of command buffers. A routine could fill one with |
| @@ -642,70 +646,75 @@ commands and link it onto a list. When a interrupt signaled | |||
| 642 | completion of the current command buffer, look on the list for | 646 | completion of the current command buffer, look on the list for |
| 643 | the next one. | 647 | the next one. |
| 644 | 648 | ||
| 645 | I've decided to implement something much simpler - after each command, | ||
| 646 | the CPU waits for the DBRI to finish the command by polling the P bit | ||
| 647 | in DBRI register 0. I've tried to implement this in such a way | ||
| 648 | that might make implementing a more sophisticated scheme easier. | ||
| 649 | |||
| 650 | Every time a routine wants to write commands to the DBRI, it must | 649 | Every time a routine wants to write commands to the DBRI, it must |
| 651 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd | 650 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd |
| 652 | in return. After the commands have been writen, dbri_cmdsend() is | 651 | in return. dbri_cmdlock() will block if the previous commands have not |
| 653 | called with the final pointer value. | 652 | been completed yet. After this the commands can be written to the buffer, |
| 653 | and dbri_cmdsend() is called with the final pointer value to send them | ||
| 654 | to the DBRI. | ||
| 654 | 655 | ||
| 655 | */ | 656 | */ |
| 656 | 657 | ||
| 658 | static void dbri_process_interrupt_buffer(snd_dbri_t * dbri); | ||
| 659 | |||
| 657 | enum dbri_lock_t { NoGetLock, GetLock }; | 660 | enum dbri_lock_t { NoGetLock, GetLock }; |
| 661 | #define MAXLOOPS 10 | ||
| 658 | 662 | ||
| 659 | static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) | 663 | static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) |
| 660 | { | 664 | { |
| 665 | int maxloops = MAXLOOPS; | ||
| 666 | |||
| 661 | #ifndef SMP | 667 | #ifndef SMP |
| 662 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { | 668 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { |
| 663 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); | 669 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); |
| 664 | } | 670 | } |
| 665 | #endif | 671 | #endif |
| 666 | 672 | ||
| 673 | /* Delay if previous commands are still being processed */ | ||
| 674 | while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) { | ||
| 675 | msleep_interruptible(1); | ||
| 676 | /* If dbri_cmdlock() got called from inside the | ||
| 677 | * interrupt handler, this will do the processing. | ||
| 678 | */ | ||
| 679 | dbri_process_interrupt_buffer(dbri); | ||
| 680 | } | ||
| 681 | if (maxloops == 0) { | ||
| 682 | printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n", | ||
| 683 | dbri->wait_send); | ||
| 684 | } else { | ||
| 685 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", | ||
| 686 | MAXLOOPS - maxloops - 1); | ||
| 687 | } | ||
| 688 | |||
| 667 | /*if (get == GetLock) spin_lock(&dbri->lock); */ | 689 | /*if (get == GetLock) spin_lock(&dbri->lock); */ |
| 668 | return &dbri->dma->cmd[0]; | 690 | return &dbri->dma->cmd[0]; |
| 669 | } | 691 | } |
| 670 | 692 | ||
| 671 | static void dbri_process_interrupt_buffer(snd_dbri_t *); | ||
| 672 | |||
| 673 | static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) | 693 | static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) |
| 674 | { | 694 | { |
| 675 | int MAXLOOPS = 1000000; | ||
| 676 | int maxloops = MAXLOOPS; | ||
| 677 | volatile s32 *ptr; | 695 | volatile s32 *ptr; |
| 696 | u32 reg; | ||
| 678 | 697 | ||
| 679 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { | 698 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { |
| 680 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 699 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); |
| 681 | } | 700 | } |
| 682 | 701 | ||
| 683 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { | 702 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { |
| 684 | printk("DBRI: Command buffer overflow! (bug in driver)\n"); | 703 | printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n"); |
| 685 | /* Ignore the last part. */ | 704 | /* Ignore the last part. */ |
| 686 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; | 705 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; |
| 687 | } | 706 | } |
| 688 | 707 | ||
| 708 | dbri->wait_send++; | ||
| 709 | dbri->wait_send &= 0xffff; /* restrict it to a 16 bit counter. */ | ||
| 689 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | 710 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); |
| 690 | *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); | 711 | *(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send); |
| 691 | dbri->wait_seen = 0; | 712 | |
| 713 | /* Set command pointer and signal it is valid. */ | ||
| 692 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); | 714 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); |
| 693 | while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) | 715 | reg = sbus_readl(dbri->regs + REG0); |
| 694 | barrier(); | 716 | reg |= D_P; |
| 695 | if (maxloops == 0) { | 717 | sbus_writel(reg, dbri->regs + REG0); |
| 696 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); | ||
| 697 | dprintk(D_CMD, "DBRI: Chip never completed command buffer\n"); | ||
| 698 | } else { | ||
| 699 | while ((--maxloops) > 0 && (!dbri->wait_seen)) | ||
| 700 | dbri_process_interrupt_buffer(dbri); | ||
| 701 | if (maxloops == 0) { | ||
| 702 | printk(KERN_ERR "DBRI: Chip never acked WAIT\n"); | ||
| 703 | dprintk(D_CMD, "DBRI: Chip never acked WAIT\n"); | ||
| 704 | } else { | ||
| 705 | dprintk(D_CMD, "Chip completed command " | ||
| 706 | "buffer (%d)\n", MAXLOOPS - maxloops); | ||
| 707 | } | ||
| 708 | } | ||
| 709 | 718 | ||
| 710 | /*spin_unlock(&dbri->lock); */ | 719 | /*spin_unlock(&dbri->lock); */ |
| 711 | } | 720 | } |
| @@ -757,10 +766,11 @@ static void dbri_initialize(snd_dbri_t * dbri) | |||
| 757 | for (n = 0; n < DBRI_NO_PIPES; n++) | 766 | for (n = 0; n < DBRI_NO_PIPES; n++) |
| 758 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; | 767 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; |
| 759 | 768 | ||
| 760 | /* We should query the openprom to see what burst sizes this | 769 | /* A brute approach - DBRI falls back to working burst size by itself |
| 761 | * SBus supports. For now, just disable all SBus bursts */ | 770 | * On SS20 D_S does not work, so do not try so high. */ |
| 762 | tmp = sbus_readl(dbri->regs + REG0); | 771 | tmp = sbus_readl(dbri->regs + REG0); |
| 763 | tmp &= ~(D_G | D_S | D_E); | 772 | tmp |= D_G | D_E; |
| 773 | tmp &= ~D_S; | ||
| 764 | sbus_writel(tmp, dbri->regs + REG0); | 774 | sbus_writel(tmp, dbri->regs + REG0); |
| 765 | 775 | ||
| 766 | /* | 776 | /* |
| @@ -805,13 +815,13 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe) | |||
| 805 | volatile int *cmd; | 815 | volatile int *cmd; |
| 806 | 816 | ||
| 807 | if (pipe < 0 || pipe > 31) { | 817 | if (pipe < 0 || pipe > 31) { |
| 808 | printk("DBRI: reset_pipe called with illegal pipe number\n"); | 818 | printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); |
| 809 | return; | 819 | return; |
| 810 | } | 820 | } |
| 811 | 821 | ||
| 812 | sdp = dbri->pipes[pipe].sdp; | 822 | sdp = dbri->pipes[pipe].sdp; |
| 813 | if (sdp == 0) { | 823 | if (sdp == 0) { |
| 814 | printk("DBRI: reset_pipe called on uninitialized pipe\n"); | 824 | printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n"); |
| 815 | return; | 825 | return; |
| 816 | } | 826 | } |
| 817 | 827 | ||
| @@ -834,12 +844,12 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe) | |||
| 834 | static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) | 844 | static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) |
| 835 | { | 845 | { |
| 836 | if (pipe < 0 || pipe > 31) { | 846 | if (pipe < 0 || pipe > 31) { |
| 837 | printk("DBRI: setup_pipe called with illegal pipe number\n"); | 847 | printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n"); |
| 838 | return; | 848 | return; |
| 839 | } | 849 | } |
| 840 | 850 | ||
| 841 | if ((sdp & 0xf800) != sdp) { | 851 | if ((sdp & 0xf800) != sdp) { |
| 842 | printk("DBRI: setup_pipe called with strange SDP value\n"); | 852 | printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n"); |
| 843 | /* sdp &= 0xf800; */ | 853 | /* sdp &= 0xf800; */ |
| 844 | } | 854 | } |
| 845 | 855 | ||
| @@ -872,13 +882,13 @@ static void link_time_slot(snd_dbri_t * dbri, int pipe, | |||
| 872 | int nextpipe; | 882 | int nextpipe; |
| 873 | 883 | ||
| 874 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { | 884 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { |
| 875 | printk | 885 | printk(KERN_ERR |
| 876 | ("DBRI: link_time_slot called with illegal pipe number\n"); | 886 | "DBRI: link_time_slot called with illegal pipe number\n"); |
| 877 | return; | 887 | return; |
| 878 | } | 888 | } |
| 879 | 889 | ||
| 880 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { | 890 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { |
| 881 | printk("DBRI: link_time_slot called on uninitialized pipe\n"); | 891 | printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n"); |
| 882 | return; | 892 | return; |
| 883 | } | 893 | } |
| 884 | 894 | ||
| @@ -960,8 +970,8 @@ static void unlink_time_slot(snd_dbri_t * dbri, int pipe, | |||
| 960 | int val; | 970 | int val; |
| 961 | 971 | ||
| 962 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { | 972 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { |
| 963 | printk | 973 | printk(KERN_ERR |
| 964 | ("DBRI: unlink_time_slot called with illegal pipe number\n"); | 974 | "DBRI: unlink_time_slot called with illegal pipe number\n"); |
| 965 | return; | 975 | return; |
| 966 | } | 976 | } |
| 967 | 977 | ||
| @@ -1001,22 +1011,22 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) | |||
| 1001 | volatile s32 *cmd; | 1011 | volatile s32 *cmd; |
| 1002 | 1012 | ||
| 1003 | if (pipe < 16 || pipe > 31) { | 1013 | if (pipe < 16 || pipe > 31) { |
| 1004 | printk("DBRI: xmit_fixed: Illegal pipe number\n"); | 1014 | printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n"); |
| 1005 | return; | 1015 | return; |
| 1006 | } | 1016 | } |
| 1007 | 1017 | ||
| 1008 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { | 1018 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { |
| 1009 | printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); | 1019 | printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); |
| 1010 | return; | 1020 | return; |
| 1011 | } | 1021 | } |
| 1012 | 1022 | ||
| 1013 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | 1023 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { |
| 1014 | printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); | 1024 | printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); |
| 1015 | return; | 1025 | return; |
| 1016 | } | 1026 | } |
| 1017 | 1027 | ||
| 1018 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { | 1028 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { |
| 1019 | printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); | 1029 | printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); |
| 1020 | return; | 1030 | return; |
| 1021 | } | 1031 | } |
| 1022 | 1032 | ||
| @@ -1036,17 +1046,17 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) | |||
| 1036 | static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) | 1046 | static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) |
| 1037 | { | 1047 | { |
| 1038 | if (pipe < 16 || pipe > 31) { | 1048 | if (pipe < 16 || pipe > 31) { |
| 1039 | printk("DBRI: recv_fixed called with illegal pipe number\n"); | 1049 | printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n"); |
| 1040 | return; | 1050 | return; |
| 1041 | } | 1051 | } |
| 1042 | 1052 | ||
| 1043 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | 1053 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { |
| 1044 | printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); | 1054 | printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); |
| 1045 | return; | 1055 | return; |
| 1046 | } | 1056 | } |
| 1047 | 1057 | ||
| 1048 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { | 1058 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { |
| 1049 | printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe); | 1059 | printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe); |
| 1050 | return; | 1060 | return; |
| 1051 | } | 1061 | } |
| 1052 | 1062 | ||
| @@ -1075,12 +1085,12 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
| 1075 | int last_desc = -1; | 1085 | int last_desc = -1; |
| 1076 | 1086 | ||
| 1077 | if (info->pipe < 0 || info->pipe > 15) { | 1087 | if (info->pipe < 0 || info->pipe > 15) { |
| 1078 | printk("DBRI: setup_descs: Illegal pipe number\n"); | 1088 | printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n"); |
| 1079 | return -2; | 1089 | return -2; |
| 1080 | } | 1090 | } |
| 1081 | 1091 | ||
| 1082 | if (dbri->pipes[info->pipe].sdp == 0) { | 1092 | if (dbri->pipes[info->pipe].sdp == 0) { |
| 1083 | printk("DBRI: setup_descs: Uninitialized pipe %d\n", | 1093 | printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n", |
| 1084 | info->pipe); | 1094 | info->pipe); |
| 1085 | return -2; | 1095 | return -2; |
| 1086 | } | 1096 | } |
| @@ -1090,20 +1100,20 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
| 1090 | 1100 | ||
| 1091 | if (streamno == DBRI_PLAY) { | 1101 | if (streamno == DBRI_PLAY) { |
| 1092 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { | 1102 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { |
| 1093 | printk("DBRI: setup_descs: Called on receive pipe %d\n", | 1103 | printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n", |
| 1094 | info->pipe); | 1104 | info->pipe); |
| 1095 | return -2; | 1105 | return -2; |
| 1096 | } | 1106 | } |
| 1097 | } else { | 1107 | } else { |
| 1098 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { | 1108 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { |
| 1099 | printk | 1109 | printk(KERN_ERR |
| 1100 | ("DBRI: setup_descs: Called on transmit pipe %d\n", | 1110 | "DBRI: setup_descs: Called on transmit pipe %d\n", |
| 1101 | info->pipe); | 1111 | info->pipe); |
| 1102 | return -2; | 1112 | return -2; |
| 1103 | } | 1113 | } |
| 1104 | /* Should be able to queue multiple buffers to receive on a pipe */ | 1114 | /* Should be able to queue multiple buffers to receive on a pipe */ |
| 1105 | if (pipe_active(dbri, info->pipe)) { | 1115 | if (pipe_active(dbri, info->pipe)) { |
| 1106 | printk("DBRI: recv_on_pipe: Called on active pipe %d\n", | 1116 | printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n", |
| 1107 | info->pipe); | 1117 | info->pipe); |
| 1108 | return -2; | 1118 | return -2; |
| 1109 | } | 1119 | } |
| @@ -1120,7 +1130,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
| 1120 | break; | 1130 | break; |
| 1121 | } | 1131 | } |
| 1122 | if (desc == DBRI_NO_DESCS) { | 1132 | if (desc == DBRI_NO_DESCS) { |
| 1123 | printk("DBRI: setup_descs: No descriptors\n"); | 1133 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); |
| 1124 | return -1; | 1134 | return -1; |
| 1125 | } | 1135 | } |
| 1126 | 1136 | ||
| @@ -1165,7 +1175,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
| 1165 | } | 1175 | } |
| 1166 | 1176 | ||
| 1167 | if (first_desc == -1 || last_desc == -1) { | 1177 | if (first_desc == -1 || last_desc == -1) { |
| 1168 | printk("DBRI: setup_descs: Not enough descriptors available\n"); | 1178 | printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n"); |
| 1169 | return -1; | 1179 | return -1; |
| 1170 | } | 1180 | } |
| 1171 | 1181 | ||
| @@ -1270,7 +1280,7 @@ static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave, | |||
| 1270 | int divisor = 12288 / clockrate; | 1280 | int divisor = 12288 / clockrate; |
| 1271 | 1281 | ||
| 1272 | if (divisor > 255 || divisor * clockrate != 12288) | 1282 | if (divisor > 255 || divisor * clockrate != 12288) |
| 1273 | printk("DBRI: illegal bits_per_frame in setup_chi\n"); | 1283 | printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n"); |
| 1274 | 1284 | ||
| 1275 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD | 1285 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD |
| 1276 | | D_CHI_BPF(bits_per_frame)); | 1286 | | D_CHI_BPF(bits_per_frame)); |
| @@ -1474,7 +1484,6 @@ static int cs4215_setctrl(snd_dbri_t * dbri) | |||
| 1474 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) | 1484 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) |
| 1475 | * to make sure this takes. This avoids clicking noises. | 1485 | * to make sure this takes. This avoids clicking noises. |
| 1476 | */ | 1486 | */ |
| 1477 | |||
| 1478 | cs4215_setdata(dbri, 1); | 1487 | cs4215_setdata(dbri, 1); |
| 1479 | udelay(125); | 1488 | udelay(125); |
| 1480 | 1489 | ||
| @@ -1530,8 +1539,8 @@ static int cs4215_setctrl(snd_dbri_t * dbri) | |||
| 1530 | tmp |= D_C; /* Enable CHI */ | 1539 | tmp |= D_C; /* Enable CHI */ |
| 1531 | sbus_writel(tmp, dbri->regs + REG0); | 1540 | sbus_writel(tmp, dbri->regs + REG0); |
| 1532 | 1541 | ||
| 1533 | for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) { | 1542 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) { |
| 1534 | udelay(125); | 1543 | msleep_interruptible(1); |
| 1535 | } | 1544 | } |
| 1536 | if (i == 0) { | 1545 | if (i == 0) { |
| 1537 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", | 1546 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", |
| @@ -1678,8 +1687,8 @@ buffer and calls dbri_process_one_interrupt() for each interrupt word. | |||
| 1678 | Complicated interrupts are handled by dedicated functions (which | 1687 | Complicated interrupts are handled by dedicated functions (which |
| 1679 | appear first in this file). Any pending interrupts can be serviced by | 1688 | appear first in this file). Any pending interrupts can be serviced by |
| 1680 | calling dbri_process_interrupt_buffer(), which works even if the CPU's | 1689 | calling dbri_process_interrupt_buffer(), which works even if the CPU's |
| 1681 | interrupts are disabled. This function is used by dbri_cmdsend() | 1690 | interrupts are disabled. This function is used by dbri_cmdlock() |
| 1682 | to make sure we're synced up with the chip after each command sequence, | 1691 | to make sure we're synced up with the chip before each command sequence, |
| 1683 | even if we're running cli'ed. | 1692 | even if we're running cli'ed. |
| 1684 | 1693 | ||
| 1685 | */ | 1694 | */ |
| @@ -1765,11 +1774,13 @@ DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); | |||
| 1765 | * Called by main interrupt handler when DBRI signals transmission complete | 1774 | * Called by main interrupt handler when DBRI signals transmission complete |
| 1766 | * on a pipe (interrupt triggered by the B bit in a transmit descriptor). | 1775 | * on a pipe (interrupt triggered by the B bit in a transmit descriptor). |
| 1767 | * | 1776 | * |
| 1768 | * Walks through the pipe's list of transmit buffer descriptors, releasing | 1777 | * Walks through the pipe's list of transmit buffer descriptors and marks |
| 1769 | * each one's DMA buffer (if present), flagging the descriptor available, | 1778 | * them as available. Stops when the first descriptor is found without |
| 1770 | * and signaling its callback routine (if present), before proceeding | ||
| 1771 | * to the next one. Stops when the first descriptor is found without | ||
| 1772 | * TBC (Transmit Buffer Complete) set, or we've run through them all. | 1779 | * TBC (Transmit Buffer Complete) set, or we've run through them all. |
| 1780 | * | ||
| 1781 | * The DMA buffers are not released, but re-used. Since the transmit buffer | ||
| 1782 | * descriptors are not clobbered, they can be re-submitted as is. This is | ||
| 1783 | * done by the xmit_descs() tasklet above since that could take longer. | ||
| 1773 | */ | 1784 | */ |
| 1774 | 1785 | ||
| 1775 | static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) | 1786 | static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) |
| @@ -1885,7 +1896,11 @@ static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x) | |||
| 1885 | } | 1896 | } |
| 1886 | 1897 | ||
| 1887 | if (channel == D_INTR_CMD && command == D_WAIT) { | 1898 | if (channel == D_INTR_CMD && command == D_WAIT) { |
| 1888 | dbri->wait_seen++; | 1899 | dbri->wait_ackd = val; |
| 1900 | if (dbri->wait_send != val) { | ||
| 1901 | printk(KERN_ERR "Processing wait command %d when %d was send.\n", | ||
| 1902 | val, dbri->wait_send); | ||
| 1903 | } | ||
| 1889 | return; | 1904 | return; |
| 1890 | } | 1905 | } |
| 1891 | 1906 | ||
| @@ -1994,8 +2009,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, | |||
| 1994 | * The only one I've seen is MRR, which will be triggered | 2009 | * The only one I've seen is MRR, which will be triggered |
| 1995 | * if you let a transmit pipe underrun, then try to CDP it. | 2010 | * if you let a transmit pipe underrun, then try to CDP it. |
| 1996 | * | 2011 | * |
| 1997 | * If these things persist, we should probably reset | 2012 | * If these things persist, we reset the chip. |
| 1998 | * and re-init the chip. | ||
| 1999 | */ | 2013 | */ |
| 2000 | if ((++errcnt) % 10 == 0) { | 2014 | if ((++errcnt) % 10 == 0) { |
| 2001 | dprintk(D_INT, "Interrupt errors exceeded.\n"); | 2015 | dprintk(D_INT, "Interrupt errors exceeded.\n"); |
| @@ -2094,7 +2108,7 @@ static int snd_dbri_hw_params(snd_pcm_substream_t * substream, | |||
| 2094 | 2108 | ||
| 2095 | if ((ret = snd_pcm_lib_malloc_pages(substream, | 2109 | if ((ret = snd_pcm_lib_malloc_pages(substream, |
| 2096 | params_buffer_bytes(hw_params))) < 0) { | 2110 | params_buffer_bytes(hw_params))) < 0) { |
| 2097 | snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret); | 2111 | printk(KERN_ERR "malloc_pages failed with %d\n", ret); |
| 2098 | return ret; | 2112 | return ret; |
| 2099 | } | 2113 | } |
| 2100 | 2114 | ||
| @@ -2455,8 +2469,7 @@ static int __init snd_dbri_mixer(snd_dbri_t * dbri) | |||
| 2455 | 2469 | ||
| 2456 | for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { | 2470 | for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { |
| 2457 | if ((err = snd_ctl_add(card, | 2471 | if ((err = snd_ctl_add(card, |
| 2458 | snd_ctl_new1(&dbri_controls[idx], | 2472 | snd_ctl_new1(&dbri_controls[idx], dbri))) < 0) |
| 2459 | dbri))) < 0) | ||
| 2460 | return err; | 2473 | return err; |
| 2461 | } | 2474 | } |
| 2462 | 2475 | ||
| @@ -2490,8 +2503,6 @@ static void dbri_debug_read(snd_info_entry_t * entry, | |||
| 2490 | int pipe; | 2503 | int pipe; |
| 2491 | snd_iprintf(buffer, "debug=%d\n", dbri_debug); | 2504 | snd_iprintf(buffer, "debug=%d\n", dbri_debug); |
| 2492 | 2505 | ||
| 2493 | snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n", | ||
| 2494 | dbri->chi_in_pipe, dbri->chi_out_pipe); | ||
| 2495 | for (pipe = 0; pipe < 32; pipe++) { | 2506 | for (pipe = 0; pipe < 32; pipe++) { |
| 2496 | if (pipe_active(dbri, pipe)) { | 2507 | if (pipe_active(dbri, pipe)) { |
| 2497 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; | 2508 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; |
| @@ -2506,18 +2517,6 @@ static void dbri_debug_read(snd_info_entry_t * entry, | |||
| 2506 | } | 2517 | } |
| 2507 | } | 2518 | } |
| 2508 | } | 2519 | } |
| 2509 | |||
| 2510 | static void dbri_debug_write(snd_info_entry_t * entry, | ||
| 2511 | snd_info_buffer_t * buffer) | ||
| 2512 | { | ||
| 2513 | char line[80]; | ||
| 2514 | int i; | ||
| 2515 | |||
| 2516 | if (snd_info_get_line(buffer, line, 80) == 0) { | ||
| 2517 | sscanf(line, "%d\n", &i); | ||
| 2518 | dbri_debug = i & 0x3f; | ||
| 2519 | } | ||
| 2520 | } | ||
| 2521 | #endif | 2520 | #endif |
| 2522 | 2521 | ||
| 2523 | void snd_dbri_proc(snd_dbri_t * dbri) | 2522 | void snd_dbri_proc(snd_dbri_t * dbri) |
| @@ -2531,9 +2530,7 @@ void snd_dbri_proc(snd_dbri_t * dbri) | |||
| 2531 | #ifdef DBRI_DEBUG | 2530 | #ifdef DBRI_DEBUG |
| 2532 | err = snd_card_proc_new(dbri->card, "debug", &entry); | 2531 | err = snd_card_proc_new(dbri->card, "debug", &entry); |
| 2533 | snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); | 2532 | snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); |
| 2534 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */ | 2533 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ |
| 2535 | entry->c.text.write_size = 256; | ||
| 2536 | entry->c.text.write = dbri_debug_write; | ||
| 2537 | #endif | 2534 | #endif |
| 2538 | } | 2535 | } |
| 2539 | 2536 | ||
| @@ -2637,7 +2634,11 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
| 2637 | return -ENOENT; | 2634 | return -ENOENT; |
| 2638 | } | 2635 | } |
| 2639 | 2636 | ||
| 2640 | prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); | 2637 | err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); |
| 2638 | if (err < 0) { | ||
| 2639 | printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev); | ||
| 2640 | return -ENODEV; | ||
| 2641 | } | ||
| 2641 | 2642 | ||
| 2642 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 2643 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, |
| 2643 | sizeof(snd_dbri_t)); | 2644 | sizeof(snd_dbri_t)); |
| @@ -2657,26 +2658,20 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
| 2657 | } | 2658 | } |
| 2658 | 2659 | ||
| 2659 | dbri = (snd_dbri_t *) card->private_data; | 2660 | dbri = (snd_dbri_t *) card->private_data; |
| 2660 | if ((err = snd_dbri_pcm(dbri)) < 0) { | 2661 | if ((err = snd_dbri_pcm(dbri)) < 0) |
| 2661 | snd_dbri_free(dbri); | 2662 | goto _err; |
| 2662 | snd_card_free(card); | ||
| 2663 | return err; | ||
| 2664 | } | ||
| 2665 | 2663 | ||
| 2666 | if ((err = snd_dbri_mixer(dbri)) < 0) { | 2664 | if ((err = snd_dbri_mixer(dbri)) < 0) |
| 2667 | snd_dbri_free(dbri); | 2665 | goto _err; |
| 2668 | snd_card_free(card); | ||
| 2669 | return err; | ||
| 2670 | } | ||
| 2671 | 2666 | ||
| 2672 | /* /proc file handling */ | 2667 | /* /proc file handling */ |
| 2673 | snd_dbri_proc(dbri); | 2668 | snd_dbri_proc(dbri); |
| 2674 | 2669 | ||
| 2675 | if ((err = snd_card_register(card)) < 0) { | 2670 | if ((err = snd_card_set_generic_dev(card)) < 0) |
| 2676 | snd_dbri_free(dbri); | 2671 | goto _err; |
| 2677 | snd_card_free(card); | 2672 | |
| 2678 | return err; | 2673 | if ((err = snd_card_register(card)) < 0) |
| 2679 | } | 2674 | goto _err; |
| 2680 | 2675 | ||
| 2681 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", | 2676 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", |
| 2682 | dev, dbri->regs, | 2677 | dev, dbri->regs, |
| @@ -2684,6 +2679,11 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
| 2684 | dev++; | 2679 | dev++; |
| 2685 | 2680 | ||
| 2686 | return 0; | 2681 | return 0; |
| 2682 | |||
| 2683 | _err: | ||
| 2684 | snd_dbri_free(dbri); | ||
| 2685 | snd_card_free(card); | ||
| 2686 | return err; | ||
| 2687 | } | 2687 | } |
| 2688 | 2688 | ||
| 2689 | /* Probe for the dbri chip and then attach the driver. */ | 2689 | /* Probe for the dbri chip and then attach the driver. */ |
