Update of /cvsroot/alsa/alsa-kernel/pci
In directory sc8-pr-cvs1:/tmp/cvs-serv22821

Modified Files:
        intel8x0.c 
Log Message:
- improved the probe/resume function.
  check only the valid codec bits in chip_init() during resume.



Index: intel8x0.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/intel8x0.c,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -r1.86 -r1.87
--- intel8x0.c  30 Jul 2003 10:54:03 -0000      1.86
+++ intel8x0.c  30 Jul 2003 14:39:38 -0000      1.87
@@ -523,6 +523,19 @@
 /*
  * access to AC97 codec via normal i/o (for ICH and SIS7012)
  */
+
+/* return the GLOB_STA bit for the corresponding codec */
+static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec)
+{
+       static unsigned int codec_bit[3] = {
+               ICH_PCR, ICH_SCR, ICH_TCR
+       };
+       snd_assert(codec < 3, return ICH_PCR);
+       if (chip->device_type == DEVICE_INTEL_ICH4)
+               codec = chip->ac97_sdin[codec];
+       return codec_bit[codec];
+}
+
 static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
 {
        int time;
@@ -534,19 +547,7 @@
                /* so we check any */
                codec = ICH_PCR | ICH_SCR | ICH_TCR;
        } else {
-               if (chip->device_type == DEVICE_INTEL_ICH4) {
-                       switch (chip->ac97_sdin[codec]) {
-                       case 0: codec = ICH_PCR; break;
-                       case 1: codec = ICH_SCR; break;
-                       case 2: codec = ICH_TCR; break;
-                       }
-               } else {
-                       switch (codec) {
-                       case 0: codec = ICH_PCR; break;
-                       case 1: codec = ICH_SCR; break;
-                       case 2: codec = ICH_TCR; break;
-                       }
-               }
+               codec = get_ich_codec_bit(chip, codec);
        }
 
        /* codec ready ? */
@@ -1731,9 +1732,14 @@
                }
        }
        ac97.pci = chip->pci;
-       if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0)
+       if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0) {
+               /* clear the cold-reset bit for the next chance */
+               if (chip->device_type != DEVICE_ALI)
+                       iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, 
ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
                return err;
+       }
        chip->ac97[0] = x97;
+       /* tune up the primary codec */
        snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks);
        /* the following three entries are common among all devices */
        chip->ichd[ICHD_PCMOUT].ac97 = x97;
@@ -1886,7 +1892,7 @@
        schedule_timeout(1);\
 } while (0)
 
-static int snd_intel8x0_ich_chip_init(intel8x0_t *chip)
+static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
 {
        unsigned long end_time;
        unsigned int cnt, status, nstatus;
@@ -1915,49 +1921,55 @@
        return -EIO;
 
       __ok:
-       /* wait for any codec ready status.
-        * Once it becomes ready it should remain ready
-        * as long as we do not disable the ac97 link.
-        */
-       end_time = jiffies + HZ;
-       do {
-               status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | 
ICH_TCR);
-               if (status)
-                       goto __ok1;
-               do_delay(chip);
-       } while (time_after_eq(end_time, jiffies));
-       snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", 
igetdword(chip, ICHREG(GLOB_STA)));
-       return -EIO;
-
-      __ok1:
-       if (status == (ICH_PCR | ICH_SCR | ICH_TCR))
-               goto __ok3;
-       /* wait for other codecs ready status. No secondary codecs? , ok */
-       end_time = jiffies + HZ / 4;
-       do {
-               nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | 
ICH_TCR);
-               if (nstatus != status) {
-                       status = nstatus;
-                       goto __ok2;
+       if (probing) {
+               /* wait for any codec ready status.
+                * Once it becomes ready it should remain ready
+                * as long as we do not disable the ac97 link.
+                */
+               end_time = jiffies + HZ;
+               do {
+                       status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | 
ICH_SCR | ICH_TCR);
+                       if (status)
+                               break;
+                       do_delay(chip);
+               } while (time_after_eq(end_time, jiffies));
+               if (! status) {
+                       /* no codec is found */
+                       snd_printk(KERN_ERR "codec_ready: codec is not ready 
[0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
+                       return -EIO;
                }
-               do_delay(chip);
-       } while (time_after_eq(end_time, jiffies));
 
-      __ok2:
-       if (status == (ICH_PCR | ICH_SCR | ICH_TCR))
-               goto __ok3;
-       /* wait for other codecs ready status. No other secondary codecs? , ok */
-       /* end_time is not initialized here */
-       do {
-               nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | 
ICH_TCR);
-               if (nstatus != status) {
-                       status = nstatus;
-                       goto __ok2;
+               if (chip->device_type == DEVICE_INTEL_ICH4)
+                       /* ICH4 can have three codecs */
+                       nstatus = ICH_PCR | ICH_SCR | ICH_TCR;
+               else
+                       /* others up to two codecs */
+                       nstatus = ICH_PCR | ICH_SCR;
+
+               /* wait for other codecs ready status. */
+               end_time = jiffies + HZ / 4;
+               while (status != nstatus && time_after_eq(end_time, jiffies)) {
+                       do_delay(chip);
+                       status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
                }
-               do_delay(chip);
-       } while (time_after_eq(end_time, jiffies));
 
-      __ok3:      
+       } else {
+               /* resume phase */
+               int i;
+               status = 0;
+               for (i = 0; i < 3; i++)
+                       if (chip->ac97[i])
+                               status |= get_ich_codec_bit(chip, i);
+               /* wait until all the probed codecs are ready */
+               end_time = jiffies + HZ;
+               do {
+                       nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | 
ICH_SCR | ICH_TCR);
+                       if (status == nstatus)
+                               break;
+                       do_delay(chip);
+               } while (time_after_eq(end_time, jiffies));
+       }
+
        if (chip->device_type == DEVICE_SIS) {
                /* unmute the output on SIS7012 */
                iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
@@ -1972,7 +1984,7 @@
        return 0;
 }
 
-static int snd_intel8x0_ali_chip_init(intel8x0_t *chip)
+static int snd_intel8x0_ali_chip_init(intel8x0_t *chip, int probing)
 {
        u32 reg;
        int i = 0;
@@ -1991,7 +2003,8 @@
                do_delay(chip);
        }
        snd_printk(KERN_ERR "AC'97 reset failed.\n");
-       return -EIO;
+       if (probing)
+               return -EIO;
 
  __ok:
        for (i = 0; i < HZ / 2; i++) {
@@ -2006,17 +2019,17 @@
        return 0;
 }
 
-static int snd_intel8x0_chip_init(intel8x0_t *chip)
+static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing)
 {
        unsigned int i;
        int err;
        
        if (chip->device_type != DEVICE_ALI) {
-               if ((err = snd_intel8x0_ich_chip_init(chip)) < 0)
+               if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0)
                        return err;
                iagetword(chip, 0);     /* clear semaphore flag */
        } else {
-               if ((err = snd_intel8x0_ali_chip_init(chip)) < 0)
+               if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0)
                        return err;
        }
 
@@ -2104,7 +2117,7 @@
 
        pci_enable_device(chip->pci);
        pci_set_master(chip->pci);
-       snd_intel8x0_chip_init(chip);
+       snd_intel8x0_chip_init(chip, 0);
        for (i = 0; i < 3; i++)
                if (chip->ac97[i])
                        snd_ac97_resume(chip->ac97[i]);
@@ -2462,7 +2475,7 @@
        chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : 
ICH_REG_GLOB_STA;
        chip->int_sta_mask = int_sta_masks;
 
-       if ((err = snd_intel8x0_chip_init(chip)) < 0) {
+       if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
                snd_intel8x0_free(chip);
                return err;
        }



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to