Commit ab3225bc authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA CVS update

D:2003/07/30 15:39:38
A:Takashi Iwai <tiwai@suse.de>
F:pci/intel8x0.c:1.86->1.87 
L:- improved the probe/resume function.
L:  check only the valid codec bits in chip_init() during resume.
parent c7d96eae
......@@ -523,6 +523,19 @@ static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
/*
* 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 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
/* 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 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
}
}
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 @@ static void do_ali_reset(intel8x0_t *chip)
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,6 +1921,7 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip)
return -EIO;
__ok:
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.
......@@ -1923,41 +1930,46 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip)
do {
status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
if (status)
goto __ok1;
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;
}
__ok1:
if (status == (ICH_PCR | ICH_SCR | ICH_TCR))
goto __ok3;
/* wait for other codecs ready status. No secondary codecs? , ok */
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;
do {
nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
if (nstatus != status) {
status = nstatus;
goto __ok2;
}
while (status != nstatus && time_after_eq(end_time, jiffies)) {
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
}
__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 */
} 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 (nstatus != status) {
status = nstatus;
goto __ok2;
}
if (status == nstatus)
break;
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
}
__ok3:
if (chip->device_type == DEVICE_SIS) {
/* unmute the output on SIS7012 */
iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
......@@ -1972,7 +1984,7 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip)
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,6 +2003,7 @@ static int snd_intel8x0_ali_chip_init(intel8x0_t *chip)
do_delay(chip);
}
snd_printk(KERN_ERR "AC'97 reset failed.\n");
if (probing)
return -EIO;
__ok:
......@@ -2006,17 +2019,17 @@ static int snd_intel8x0_ali_chip_init(intel8x0_t *chip)
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 @@ static void intel8x0_resume(intel8x0_t *chip)
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 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment