diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_proc.c | 2 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 79 | ||||
-rw-r--r-- | sound/pci/intel8x0m.c | 14 |
4 files changed, 72 insertions, 25 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 44f2381b0aed..97ee127ac33d 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -384,7 +384,7 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho | |||
384 | 384 | ||
385 | EXPORT_SYMBOL(snd_ac97_update_bits); | 385 | EXPORT_SYMBOL(snd_ac97_update_bits); |
386 | 386 | ||
387 | /* no lock version - see snd_ac97_updat_bits() */ | 387 | /* no lock version - see snd_ac97_update_bits() */ |
388 | int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, | 388 | int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, |
389 | unsigned short mask, unsigned short value) | 389 | unsigned short mask, unsigned short value) |
390 | { | 390 | { |
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 060ea59d5f02..73b17d526c8b 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c | |||
@@ -125,6 +125,8 @@ static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffe | |||
125 | snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n", | 125 | snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n", |
126 | ac97->subsystem_device); | 126 | ac97->subsystem_device); |
127 | 127 | ||
128 | snd_iprintf(buffer, "Flags: %x\n", ac97->flags); | ||
129 | |||
128 | if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) { | 130 | if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) { |
129 | val = snd_ac97_read(ac97, AC97_INT_PAGING); | 131 | val = snd_ac97_read(ac97, AC97_INT_PAGING); |
130 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, | 132 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 608655e9275e..57648810eaf1 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -689,7 +689,7 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich | |||
689 | bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ | 689 | bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ |
690 | ichdev->fragsize >> ichdev->pos_shift); | 690 | ichdev->fragsize >> ichdev->pos_shift); |
691 | #if 0 | 691 | #if 0 |
692 | printk("bdbar[%i] = 0x%x [0x%x]\n", | 692 | printk(KERN_DEBUG "bdbar[%i] = 0x%x [0x%x]\n", |
693 | idx + 0, bdbar[idx + 0], bdbar[idx + 1]); | 693 | idx + 0, bdbar[idx + 0], bdbar[idx + 1]); |
694 | #endif | 694 | #endif |
695 | } | 695 | } |
@@ -701,8 +701,10 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich | |||
701 | ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; | 701 | ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; |
702 | ichdev->position = 0; | 702 | ichdev->position = 0; |
703 | #if 0 | 703 | #if 0 |
704 | printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n", | 704 | printk(KERN_DEBUG "lvi_frag = %i, frags = %i, period_size = 0x%x, " |
705 | ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1); | 705 | "period_size1 = 0x%x\n", |
706 | ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, | ||
707 | ichdev->fragsize1); | ||
706 | #endif | 708 | #endif |
707 | /* clear interrupts */ | 709 | /* clear interrupts */ |
708 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); | 710 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); |
@@ -768,7 +770,8 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich | |||
768 | ichdev->lvi_frag %= ichdev->frags; | 770 | ichdev->lvi_frag %= ichdev->frags; |
769 | ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1); | 771 | ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1); |
770 | #if 0 | 772 | #if 0 |
771 | printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", | 773 | printk(KERN_DEBUG "new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, " |
774 | "all = 0x%x, 0x%x\n", | ||
772 | ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], | 775 | ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], |
773 | ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), | 776 | ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), |
774 | inl(port + 4), inb(port + ICH_REG_OFF_CR)); | 777 | inl(port + 4), inb(port + ICH_REG_OFF_CR)); |
@@ -2287,23 +2290,23 @@ static void do_ali_reset(struct intel8x0 *chip) | |||
2287 | iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000); | 2290 | iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000); |
2288 | } | 2291 | } |
2289 | 2292 | ||
2290 | static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | 2293 | #ifdef CONFIG_SND_AC97_POWER_SAVE |
2291 | { | 2294 | static struct snd_pci_quirk ich_chip_reset_mode[] = { |
2292 | unsigned long end_time; | 2295 | SND_PCI_QUIRK(0x1014, 0x051f, "Thinkpad R32", 1), |
2293 | unsigned int cnt, status, nstatus; | 2296 | { } /* end */ |
2294 | 2297 | }; | |
2295 | /* put logic to right state */ | ||
2296 | /* first clear status bits */ | ||
2297 | status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT; | ||
2298 | if (chip->device_type == DEVICE_NFORCE) | ||
2299 | status |= ICH_NVSPINT; | ||
2300 | cnt = igetdword(chip, ICHREG(GLOB_STA)); | ||
2301 | iputdword(chip, ICHREG(GLOB_STA), cnt & status); | ||
2302 | 2298 | ||
2299 | static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip) | ||
2300 | { | ||
2301 | unsigned int cnt; | ||
2303 | /* ACLink on, 2 channels */ | 2302 | /* ACLink on, 2 channels */ |
2303 | |||
2304 | if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode)) | ||
2305 | return -EIO; | ||
2306 | |||
2304 | cnt = igetdword(chip, ICHREG(GLOB_CNT)); | 2307 | cnt = igetdword(chip, ICHREG(GLOB_CNT)); |
2305 | cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK); | 2308 | cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK); |
2306 | #ifdef CONFIG_SND_AC97_POWER_SAVE | 2309 | |
2307 | /* do cold reset - the full ac97 powerdown may leave the controller | 2310 | /* do cold reset - the full ac97 powerdown may leave the controller |
2308 | * in a warm state but actually it cannot communicate with the codec. | 2311 | * in a warm state but actually it cannot communicate with the codec. |
2309 | */ | 2312 | */ |
@@ -2312,22 +2315,58 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | |||
2312 | udelay(10); | 2315 | udelay(10); |
2313 | iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD); | 2316 | iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD); |
2314 | msleep(1); | 2317 | msleep(1); |
2318 | return 0; | ||
2319 | } | ||
2320 | #define snd_intel8x0_ich_chip_can_cold_reset(chip) \ | ||
2321 | (!snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode)) | ||
2315 | #else | 2322 | #else |
2323 | #define snd_intel8x0_ich_chip_cold_reset(chip) 0 | ||
2324 | #define snd_intel8x0_ich_chip_can_cold_reset(chip) (0) | ||
2325 | #endif | ||
2326 | |||
2327 | static int snd_intel8x0_ich_chip_reset(struct intel8x0 *chip) | ||
2328 | { | ||
2329 | unsigned long end_time; | ||
2330 | unsigned int cnt; | ||
2331 | /* ACLink on, 2 channels */ | ||
2332 | cnt = igetdword(chip, ICHREG(GLOB_CNT)); | ||
2333 | cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK); | ||
2316 | /* finish cold or do warm reset */ | 2334 | /* finish cold or do warm reset */ |
2317 | cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM; | 2335 | cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM; |
2318 | iputdword(chip, ICHREG(GLOB_CNT), cnt); | 2336 | iputdword(chip, ICHREG(GLOB_CNT), cnt); |
2319 | end_time = (jiffies + (HZ / 4)) + 1; | 2337 | end_time = (jiffies + (HZ / 4)) + 1; |
2320 | do { | 2338 | do { |
2321 | if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0) | 2339 | if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0) |
2322 | goto __ok; | 2340 | return 0; |
2323 | schedule_timeout_uninterruptible(1); | 2341 | schedule_timeout_uninterruptible(1); |
2324 | } while (time_after_eq(end_time, jiffies)); | 2342 | } while (time_after_eq(end_time, jiffies)); |
2325 | snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", | 2343 | snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", |
2326 | igetdword(chip, ICHREG(GLOB_CNT))); | 2344 | igetdword(chip, ICHREG(GLOB_CNT))); |
2327 | return -EIO; | 2345 | return -EIO; |
2346 | } | ||
2347 | |||
2348 | static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | ||
2349 | { | ||
2350 | unsigned long end_time; | ||
2351 | unsigned int status, nstatus; | ||
2352 | unsigned int cnt; | ||
2353 | int err; | ||
2354 | |||
2355 | /* put logic to right state */ | ||
2356 | /* first clear status bits */ | ||
2357 | status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT; | ||
2358 | if (chip->device_type == DEVICE_NFORCE) | ||
2359 | status |= ICH_NVSPINT; | ||
2360 | cnt = igetdword(chip, ICHREG(GLOB_STA)); | ||
2361 | iputdword(chip, ICHREG(GLOB_STA), cnt & status); | ||
2362 | |||
2363 | if (snd_intel8x0_ich_chip_can_cold_reset(chip)) | ||
2364 | err = snd_intel8x0_ich_chip_cold_reset(chip); | ||
2365 | else | ||
2366 | err = snd_intel8x0_ich_chip_reset(chip); | ||
2367 | if (err < 0) | ||
2368 | return err; | ||
2328 | 2369 | ||
2329 | __ok: | ||
2330 | #endif | ||
2331 | if (probing) { | 2370 | if (probing) { |
2332 | /* wait for any codec ready status. | 2371 | /* wait for any codec ready status. |
2333 | * Once it becomes ready it should remain ready | 2372 | * Once it becomes ready it should remain ready |
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 33a843c19316..6ec0fc50d6be 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -411,7 +411,10 @@ static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ic | |||
411 | bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size)); | 411 | bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size)); |
412 | bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ | 412 | bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ |
413 | ichdev->fragsize >> chip->pcm_pos_shift); | 413 | ichdev->fragsize >> chip->pcm_pos_shift); |
414 | // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]); | 414 | /* |
415 | printk(KERN_DEBUG "bdbar[%i] = 0x%x [0x%x]\n", | ||
416 | idx + 0, bdbar[idx + 0], bdbar[idx + 1]); | ||
417 | */ | ||
415 | } | 418 | } |
416 | ichdev->frags = ichdev->size / ichdev->fragsize; | 419 | ichdev->frags = ichdev->size / ichdev->fragsize; |
417 | } | 420 | } |
@@ -421,8 +424,10 @@ static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ic | |||
421 | ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; | 424 | ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; |
422 | ichdev->position = 0; | 425 | ichdev->position = 0; |
423 | #if 0 | 426 | #if 0 |
424 | printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n", | 427 | printk(KERN_DEBUG "lvi_frag = %i, frags = %i, period_size = 0x%x, " |
425 | ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1); | 428 | "period_size1 = 0x%x\n", |
429 | ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, | ||
430 | ichdev->fragsize1); | ||
426 | #endif | 431 | #endif |
427 | /* clear interrupts */ | 432 | /* clear interrupts */ |
428 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); | 433 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); |
@@ -465,7 +470,8 @@ static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ic | |||
465 | ichdev->lvi_frag * | 470 | ichdev->lvi_frag * |
466 | ichdev->fragsize1); | 471 | ichdev->fragsize1); |
467 | #if 0 | 472 | #if 0 |
468 | printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", | 473 | printk(KERN_DEBUG "new: bdbar[%i] = 0x%x [0x%x], " |
474 | "prefetch = %i, all = 0x%x, 0x%x\n", | ||
469 | ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], | 475 | ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], |
470 | ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), | 476 | ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), |
471 | inl(port + 4), inb(port + ICH_REG_OFF_CR)); | 477 | inl(port + 4), inb(port + ICH_REG_OFF_CR)); |