aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:13 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:13 -0400
commit843ad02fa4fb9230cd19923cc8ea1d6096cadf4e (patch)
treeb9dccce37420e6fd0d2b8e65cf6526b3c9be3944
parent60c4e7c120d8cfe83fa4b0978b682b6d140483ac (diff)
parent14ab08610971eb1db572ad8ca63acd13bc4d4caf (diff)
Merge branch 'topic/intel8x0' into for-linus
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_proc.c2
-rw-r--r--sound/pci/intel8x0.c79
-rw-r--r--sound/pci/intel8x0m.c14
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
385EXPORT_SYMBOL(snd_ac97_update_bits); 385EXPORT_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() */
388int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, 388int 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
2290static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) 2293#ifdef CONFIG_SND_AC97_POWER_SAVE
2291{ 2294static 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
2299static 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
2327static 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
2348static 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));