Commit 9f94a3c8 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] Add reset_workaround module option

Documentation,NM256 driver
- The workaround for some laptops like Dell Latitude LS can be
  specified via reset_workaround module option, too.
- The check of reset_workaround is merged into the quirk table.
- The spinlock in AC97 reset callback is removed.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 43e80011
......@@ -809,6 +809,7 @@ Module parameters
buffer_top - specify buffer top address
use_cache - 0 or 1 (disabled by default)
vaio_hack - alias buffer_top=0x25a800
reset_workaround - enable AC97 RESET workaround for some laptops
Module supports autoprobe and multiple chips (max 8).
......@@ -834,6 +835,11 @@ Module parameters
but some doesn't have ISA PnP. You'll need to speicfy isapnp=0
and proper hardware parameters in the case without ISA PnP.
Note: some laptops need a workaround for AC97 RESET. For the
known hardware like Dell Latitude LS and Sony PCG-F305, this
workaround is enabled automatically. For other laptops with a
hard freeze, you can try reset_workaround=1 option.
Note: This driver is really crappy. It's a porting from the
OSS driver, which is a result of black-magic reverse engineering.
The detection of codec will fail if the driver is loaded *after*
......
......@@ -61,6 +61,7 @@ static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disable
static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
static int reset_workaround[SNDRV_CARDS];
static int boot_devs;
module_param_array(index, int, boot_devs, 0444);
......@@ -81,6 +82,8 @@ module_param_array(use_cache, bool, boot_devs, 0444);
MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
module_param_array(vaio_hack, bool, boot_devs, 0444);
MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
module_param_array(reset_workaround, bool, boot_devs, 0444);
MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
/*
* hw definitions
......@@ -222,7 +225,7 @@ struct snd_nm256 {
unsigned int coeffs_current: 1; /* coeff. table is loaded? */
unsigned int use_cache: 1; /* use one big coef. table */
unsigned int latitude_workaround: 1; /* Dell Latitude LS workaround needed */
unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
int mixer_base; /* register offset of ac97 mixer */
int mixer_status_offset; /* offset of mixer status reg. */
......@@ -1162,16 +1165,14 @@ snd_nm256_ac97_reset(ac97_t *ac97)
{
nm256_t *chip = ac97->private_data;
spin_lock(&chip->reg_lock);
/* Reset the mixer. 'Tis magic! */
snd_nm256_writeb(chip, 0x6c0, 1);
if (chip->latitude_workaround) {
if (! chip->reset_workaround) {
/* Dell latitude LS will lock up by this */
snd_nm256_writeb(chip, 0x6cc, 0x87);
}
snd_nm256_writeb(chip, 0x6cc, 0x80);
snd_nm256_writeb(chip, 0x6cc, 0x0);
spin_unlock(&chip->reg_lock);
}
/* create an ac97 mixer interface */
......@@ -1343,7 +1344,6 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
.dev_free = snd_nm256_dev_free,
};
u32 addr;
u16 subsystem_vendor, subsystem_device;
*chip_ret = NULL;
......@@ -1480,19 +1480,6 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->coeffs_current = 0;
/* check workarounds */
chip->latitude_workaround = 1;
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
if (subsystem_vendor == 0x104d && subsystem_device == 0x8041) {
/* this workaround will cause lock-up after suspend/resume on Sony PCG-F305 */
chip->latitude_workaround = 0;
}
if (subsystem_vendor == 0x1028 && subsystem_device == 0x0080) {
/* this workaround will cause lock-up after suspend/resume on a Dell laptop */
chip->latitude_workaround = 0;
}
snd_nm256_init_chip(chip);
if ((err = snd_nm256_pcm(chip, 0)) < 0)
......@@ -1525,11 +1512,15 @@ struct nm256_quirk {
int type;
};
#define NM_BLACKLISTED 1
enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
static struct nm256_quirk nm256_quirks[] __devinitdata = {
/* HP omnibook 4150 has cs4232 codec internally */
{ .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED },
/* Sony PCG-F305 */
{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
/* Dell Latitude LS */
{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
{ } /* terminator */
};
......@@ -1560,9 +1551,13 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
for (q = nm256_quirks; q->vendor; q++) {
if (q->vendor == subsystem_vendor && q->device == subsystem_device) {
if (q->type == NM_BLACKLISTED) {
switch (q->type) {
case NM_BLACKLISTED:
printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n");
return -ENODEV;
case NM_RESET_WORKAROUND:
reset_workaround[dev] = 1;
break;
}
}
}
......@@ -1611,6 +1606,11 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
return err;
}
if (reset_workaround[dev]) {
snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
chip->reset_workaround = 1;
}
sprintf(card->shortname, "NeoMagic %s", card->driver);
sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %d",
card->shortname,
......
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