aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/nm256
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2005-10-19 10:03:10 -0400
committerJaroslav Kysela <perex@suse.cz>2005-11-04 07:19:10 -0500
commit47530cf44cb5f3945ed04a5ae65d06bf423cd97b (patch)
tree82c7423027bc01ff89d293f4714778e5ed948a1a /sound/pci/nm256
parentd44c39acafff98590b9bcdecb44dbbc3f7714b4a (diff)
[ALSA] nm256: reset workaround for Latitude CSx
Modules: NM256 driver The current snd-nm256 driver can cause Dell Latitude CSx laptops to lock-up during module (un)load. I have isolated this to the writes to the control port register at offset 0x6cc which were not already protected by the existing reset_workaround. I tried grouping these writes with the existing reset_workaround clause, but that caused the driver to have (un)load problems on the Dell Latitude LS laptops. So, I have implemented a reset_workaround_2 clause (please feel free to suggest a better name!) to cover this situation and added a quirk entry for the CSx laptops. Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/nm256')
-rw-r--r--sound/pci/nm256/nm256.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index ebfa38b51128..d0da9a53de03 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -62,6 +62,7 @@ static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not spe
62static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ 62static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
63static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ 63static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
64static int reset_workaround[SNDRV_CARDS]; 64static int reset_workaround[SNDRV_CARDS];
65static int reset_workaround_2[SNDRV_CARDS];
65 66
66module_param_array(index, int, NULL, 0444); 67module_param_array(index, int, NULL, 0444);
67MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 68MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -83,6 +84,8 @@ module_param_array(vaio_hack, bool, NULL, 0444);
83MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks."); 84MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
84module_param_array(reset_workaround, bool, NULL, 0444); 85module_param_array(reset_workaround, bool, NULL, 0444);
85MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops."); 86MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
87module_param_array(reset_workaround_2, bool, NULL, 0444);
88MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
86 89
87/* 90/*
88 * hw definitions 91 * hw definitions
@@ -226,6 +229,7 @@ struct snd_nm256 {
226 unsigned int coeffs_current: 1; /* coeff. table is loaded? */ 229 unsigned int coeffs_current: 1; /* coeff. table is loaded? */
227 unsigned int use_cache: 1; /* use one big coef. table */ 230 unsigned int use_cache: 1; /* use one big coef. table */
228 unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ 231 unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
232 unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
229 233
230 int mixer_base; /* register offset of ac97 mixer */ 234 int mixer_base; /* register offset of ac97 mixer */
231 int mixer_status_offset; /* offset of mixer status reg. */ 235 int mixer_status_offset; /* offset of mixer status reg. */
@@ -1199,8 +1203,11 @@ snd_nm256_ac97_reset(ac97_t *ac97)
1199 /* Dell latitude LS will lock up by this */ 1203 /* Dell latitude LS will lock up by this */
1200 snd_nm256_writeb(chip, 0x6cc, 0x87); 1204 snd_nm256_writeb(chip, 0x6cc, 0x87);
1201 } 1205 }
1202 snd_nm256_writeb(chip, 0x6cc, 0x80); 1206 if (! chip->reset_workaround_2) {
1203 snd_nm256_writeb(chip, 0x6cc, 0x0); 1207 /* Dell latitude CSx will lock up by this */
1208 snd_nm256_writeb(chip, 0x6cc, 0x80);
1209 snd_nm256_writeb(chip, 0x6cc, 0x0);
1210 }
1204} 1211}
1205 1212
1206/* create an ac97 mixer interface */ 1213/* create an ac97 mixer interface */
@@ -1536,7 +1543,7 @@ struct nm256_quirk {
1536 int type; 1543 int type;
1537}; 1544};
1538 1545
1539enum { NM_BLACKLISTED, NM_RESET_WORKAROUND }; 1546enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
1540 1547
1541static struct nm256_quirk nm256_quirks[] __devinitdata = { 1548static struct nm256_quirk nm256_quirks[] __devinitdata = {
1542 /* HP omnibook 4150 has cs4232 codec internally */ 1549 /* HP omnibook 4150 has cs4232 codec internally */
@@ -1545,6 +1552,8 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = {
1545 { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND }, 1552 { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
1546 /* Dell Latitude LS */ 1553 /* Dell Latitude LS */
1547 { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND }, 1554 { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
1555 /* Dell Latitude CSx */
1556 { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
1548 { } /* terminator */ 1557 { } /* terminator */
1549}; 1558};
1550 1559
@@ -1576,6 +1585,9 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
1576 case NM_BLACKLISTED: 1585 case NM_BLACKLISTED:
1577 printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n"); 1586 printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n");
1578 return -ENODEV; 1587 return -ENODEV;
1588 case NM_RESET_WORKAROUND_2:
1589 reset_workaround_2[dev] = 1;
1590 /* Fall-through */
1579 case NM_RESET_WORKAROUND: 1591 case NM_RESET_WORKAROUND:
1580 reset_workaround[dev] = 1; 1592 reset_workaround[dev] = 1;
1581 break; 1593 break;
@@ -1632,6 +1644,11 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
1632 chip->reset_workaround = 1; 1644 chip->reset_workaround = 1;
1633 } 1645 }
1634 1646
1647 if (reset_workaround_2[dev]) {
1648 snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
1649 chip->reset_workaround_2 = 1;
1650 }
1651
1635 if ((err = snd_nm256_pcm(chip, 0)) < 0 || 1652 if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
1636 (err = snd_nm256_mixer(chip)) < 0) { 1653 (err = snd_nm256_mixer(chip)) < 0) {
1637 snd_card_free(card); 1654 snd_card_free(card);