diff options
| -rw-r--r-- | sound/pci/ens1370.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 537cfba829a5..863eafea691f 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
| @@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); | |||
| 229 | #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ | 229 | #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ |
| 230 | #define ES_1371_CODEC_RDY (1<<31) /* codec ready */ | 230 | #define ES_1371_CODEC_RDY (1<<31) /* codec ready */ |
| 231 | #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ | 231 | #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ |
| 232 | #define EV_1938_CODEC_MAGIC (1<<26) | ||
| 232 | #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ | 233 | #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ |
| 233 | #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) | 234 | #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) |
| 234 | #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) | 235 | #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) |
| @@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, | |||
| 603 | 604 | ||
| 604 | #ifdef CHIP1371 | 605 | #ifdef CHIP1371 |
| 605 | 606 | ||
| 607 | static inline bool is_ev1938(struct ensoniq *ensoniq) | ||
| 608 | { | ||
| 609 | return ensoniq->pci->device == 0x8938; | ||
| 610 | } | ||
| 611 | |||
| 606 | static void snd_es1371_codec_write(struct snd_ac97 *ac97, | 612 | static void snd_es1371_codec_write(struct snd_ac97 *ac97, |
| 607 | unsigned short reg, unsigned short val) | 613 | unsigned short reg, unsigned short val) |
| 608 | { | 614 | { |
| 609 | struct ensoniq *ensoniq = ac97->private_data; | 615 | struct ensoniq *ensoniq = ac97->private_data; |
| 610 | unsigned int t, x; | 616 | unsigned int t, x, flag; |
| 611 | 617 | ||
| 618 | flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; | ||
| 612 | mutex_lock(&ensoniq->src_mutex); | 619 | mutex_lock(&ensoniq->src_mutex); |
| 613 | for (t = 0; t < POLL_COUNT; t++) { | 620 | for (t = 0; t < POLL_COUNT; t++) { |
| 614 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { | 621 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { |
| @@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, | |||
| 630 | 0x00010000) | 637 | 0x00010000) |
| 631 | break; | 638 | break; |
| 632 | } | 639 | } |
| 633 | outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); | 640 | outl(ES_1371_CODEC_WRITE(reg, val) | flag, |
| 641 | ES_REG(ensoniq, 1371_CODEC)); | ||
| 634 | /* restore SRC reg */ | 642 | /* restore SRC reg */ |
| 635 | snd_es1371_wait_src_ready(ensoniq); | 643 | snd_es1371_wait_src_ready(ensoniq); |
| 636 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); | 644 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); |
| @@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
| 647 | unsigned short reg) | 655 | unsigned short reg) |
| 648 | { | 656 | { |
| 649 | struct ensoniq *ensoniq = ac97->private_data; | 657 | struct ensoniq *ensoniq = ac97->private_data; |
| 650 | unsigned int t, x, fail = 0; | 658 | unsigned int t, x, flag, fail = 0; |
| 651 | 659 | ||
| 660 | flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; | ||
| 652 | __again: | 661 | __again: |
| 653 | mutex_lock(&ensoniq->src_mutex); | 662 | mutex_lock(&ensoniq->src_mutex); |
| 654 | for (t = 0; t < POLL_COUNT; t++) { | 663 | for (t = 0; t < POLL_COUNT; t++) { |
| @@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
| 671 | 0x00010000) | 680 | 0x00010000) |
| 672 | break; | 681 | break; |
| 673 | } | 682 | } |
| 674 | outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); | 683 | outl(ES_1371_CODEC_READS(reg) | flag, |
| 684 | ES_REG(ensoniq, 1371_CODEC)); | ||
| 675 | /* restore SRC reg */ | 685 | /* restore SRC reg */ |
| 676 | snd_es1371_wait_src_ready(ensoniq); | 686 | snd_es1371_wait_src_ready(ensoniq); |
| 677 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); | 687 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); |
| @@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
| 683 | /* now wait for the stinkin' data (RDY) */ | 693 | /* now wait for the stinkin' data (RDY) */ |
| 684 | for (t = 0; t < POLL_COUNT; t++) { | 694 | for (t = 0; t < POLL_COUNT; t++) { |
| 685 | if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { | 695 | if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { |
| 696 | if (is_ev1938(ensoniq)) { | ||
| 697 | for (t = 0; t < 100; t++) | ||
| 698 | inl(ES_REG(ensoniq, CONTROL)); | ||
| 699 | x = inl(ES_REG(ensoniq, 1371_CODEC)); | ||
| 700 | } | ||
| 686 | mutex_unlock(&ensoniq->src_mutex); | 701 | mutex_unlock(&ensoniq->src_mutex); |
| 687 | return ES_1371_CODEC_READ(x); | 702 | return ES_1371_CODEC_READ(x); |
| 688 | } | 703 | } |
