diff options
Diffstat (limited to 'sound/pci/nm256/nm256.c')
-rw-r--r-- | sound/pci/nm256/nm256.c | 145 |
1 files changed, 75 insertions, 70 deletions
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 5c55a3b1d121..e7aa15178453 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -52,37 +52,43 @@ MODULE_SUPPORTED_DEVICE("{{NeoMagic,NM256AV}," | |||
52 | * some compile conditions. | 52 | * some compile conditions. |
53 | */ | 53 | */ |
54 | 54 | ||
55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 55 | static int index = SNDRV_DEFAULT_IDX1; /* Index */ |
56 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 56 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
57 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 57 | static int playback_bufsize = 16; |
58 | static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16}; | 58 | static int capture_bufsize = 16; |
59 | static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16}; | 59 | static int force_ac97; /* disabled as default */ |
60 | static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */ | 60 | static int buffer_top; /* not specified */ |
61 | static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */ | 61 | static int use_cache; /* disabled */ |
62 | static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ | 62 | static int vaio_hack; /* disabled */ |
63 | static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ | 63 | static int reset_workaround; |
64 | static int reset_workaround[SNDRV_CARDS]; | 64 | static int reset_workaround_2; |
65 | 65 | ||
66 | module_param_array(index, int, NULL, 0444); | 66 | module_param(index, int, 0444); |
67 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); | 67 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); |
68 | module_param_array(id, charp, NULL, 0444); | 68 | module_param(id, charp, 0444); |
69 | MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); | 69 | MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); |
70 | module_param_array(enable, bool, NULL, 0444); | 70 | module_param(playback_bufsize, int, 0444); |
71 | MODULE_PARM_DESC(enable, "Enable this soundcard."); | ||
72 | module_param_array(playback_bufsize, int, NULL, 0444); | ||
73 | MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard."); | 71 | MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard."); |
74 | module_param_array(capture_bufsize, int, NULL, 0444); | 72 | module_param(capture_bufsize, int, 0444); |
75 | MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard."); | 73 | MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard."); |
76 | module_param_array(force_ac97, bool, NULL, 0444); | 74 | module_param(force_ac97, bool, 0444); |
77 | MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard."); | 75 | MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard."); |
78 | module_param_array(buffer_top, int, NULL, 0444); | 76 | module_param(buffer_top, int, 0444); |
79 | MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard."); | 77 | MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard."); |
80 | module_param_array(use_cache, bool, NULL, 0444); | 78 | module_param(use_cache, bool, 0444); |
81 | MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access."); | 79 | MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access."); |
82 | module_param_array(vaio_hack, bool, NULL, 0444); | 80 | module_param(vaio_hack, bool, 0444); |
83 | MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks."); | 81 | MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks."); |
84 | module_param_array(reset_workaround, bool, NULL, 0444); | 82 | module_param(reset_workaround, bool, 0444); |
85 | MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops."); | 83 | MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops."); |
84 | module_param(reset_workaround_2, bool, 0444); | ||
85 | MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops."); | ||
86 | |||
87 | /* just for backward compatibility */ | ||
88 | static int enable; | ||
89 | module_param(enable, bool, 0444); | ||
90 | |||
91 | |||
86 | 92 | ||
87 | /* | 93 | /* |
88 | * hw definitions | 94 | * hw definitions |
@@ -226,6 +232,7 @@ struct snd_nm256 { | |||
226 | unsigned int coeffs_current: 1; /* coeff. table is loaded? */ | 232 | unsigned int coeffs_current: 1; /* coeff. table is loaded? */ |
227 | unsigned int use_cache: 1; /* use one big coef. table */ | 233 | unsigned int use_cache: 1; /* use one big coef. table */ |
228 | unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ | 234 | unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ |
235 | unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */ | ||
229 | 236 | ||
230 | int mixer_base; /* register offset of ac97 mixer */ | 237 | int mixer_base; /* register offset of ac97 mixer */ |
231 | int mixer_status_offset; /* offset of mixer status reg. */ | 238 | int mixer_status_offset; /* offset of mixer status reg. */ |
@@ -313,9 +320,9 @@ static inline void | |||
313 | snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size) | 320 | snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size) |
314 | { | 321 | { |
315 | offset -= chip->buffer_start; | 322 | offset -= chip->buffer_start; |
316 | #ifdef SNDRV_CONFIG_DEBUG | 323 | #ifdef CONFIG_SND_DEBUG |
317 | if (offset < 0 || offset >= chip->buffer_size) { | 324 | if (offset < 0 || offset >= chip->buffer_size) { |
318 | snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size); | 325 | snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size); |
319 | return; | 326 | return; |
320 | } | 327 | } |
321 | #endif | 328 | #endif |
@@ -459,7 +466,7 @@ static int snd_nm256_acquire_irq(nm256_t *chip) | |||
459 | if (chip->irq < 0) { | 466 | if (chip->irq < 0) { |
460 | if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, | 467 | if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, |
461 | chip->card->driver, (void*)chip)) { | 468 | chip->card->driver, (void*)chip)) { |
462 | snd_printk("unable to grab IRQ %d\n", chip->pci->irq); | 469 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq); |
463 | up(&chip->irq_mutex); | 470 | up(&chip->irq_mutex); |
464 | return -EBUSY; | 471 | return -EBUSY; |
465 | } | 472 | } |
@@ -1199,8 +1206,11 @@ snd_nm256_ac97_reset(ac97_t *ac97) | |||
1199 | /* Dell latitude LS will lock up by this */ | 1206 | /* Dell latitude LS will lock up by this */ |
1200 | snd_nm256_writeb(chip, 0x6cc, 0x87); | 1207 | snd_nm256_writeb(chip, 0x6cc, 0x87); |
1201 | } | 1208 | } |
1202 | snd_nm256_writeb(chip, 0x6cc, 0x80); | 1209 | if (! chip->reset_workaround_2) { |
1203 | snd_nm256_writeb(chip, 0x6cc, 0x0); | 1210 | /* Dell latitude CSx will lock up by this */ |
1211 | snd_nm256_writeb(chip, 0x6cc, 0x80); | ||
1212 | snd_nm256_writeb(chip, 0x6cc, 0x0); | ||
1213 | } | ||
1204 | } | 1214 | } |
1205 | 1215 | ||
1206 | /* create an ac97 mixer interface */ | 1216 | /* create an ac97 mixer interface */ |
@@ -1263,7 +1273,7 @@ snd_nm256_peek_for_sig(nm256_t *chip) | |||
1263 | 1273 | ||
1264 | temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16); | 1274 | temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16); |
1265 | if (temp == NULL) { | 1275 | if (temp == NULL) { |
1266 | snd_printk("Unable to scan for card signature in video RAM\n"); | 1276 | snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n"); |
1267 | return -EBUSY; | 1277 | return -EBUSY; |
1268 | } | 1278 | } |
1269 | 1279 | ||
@@ -1277,7 +1287,7 @@ snd_nm256_peek_for_sig(nm256_t *chip) | |||
1277 | if (pointer == 0xffffffff || | 1287 | if (pointer == 0xffffffff || |
1278 | pointer < chip->buffer_size || | 1288 | pointer < chip->buffer_size || |
1279 | pointer > chip->buffer_end) { | 1289 | pointer > chip->buffer_end) { |
1280 | snd_printk("invalid signature found: 0x%x\n", pointer); | 1290 | snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer); |
1281 | iounmap(temp); | 1291 | iounmap(temp); |
1282 | return -ENODEV; | 1292 | return -ENODEV; |
1283 | } else { | 1293 | } else { |
@@ -1347,14 +1357,8 @@ static int snd_nm256_free(nm256_t *chip) | |||
1347 | iounmap(chip->cport); | 1357 | iounmap(chip->cport); |
1348 | if (chip->buffer) | 1358 | if (chip->buffer) |
1349 | iounmap(chip->buffer); | 1359 | iounmap(chip->buffer); |
1350 | if (chip->res_cport) { | 1360 | release_and_free_resource(chip->res_cport); |
1351 | release_resource(chip->res_cport); | 1361 | release_and_free_resource(chip->res_buffer); |
1352 | kfree_nocheck(chip->res_cport); | ||
1353 | } | ||
1354 | if (chip->res_buffer) { | ||
1355 | release_resource(chip->res_buffer); | ||
1356 | kfree_nocheck(chip->res_buffer); | ||
1357 | } | ||
1358 | if (chip->irq >= 0) | 1362 | if (chip->irq >= 0) |
1359 | free_irq(chip->irq, (void*)chip); | 1363 | free_irq(chip->irq, (void*)chip); |
1360 | 1364 | ||
@@ -1420,14 +1424,14 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, | |||
1420 | chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE, | 1424 | chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE, |
1421 | card->driver); | 1425 | card->driver); |
1422 | if (chip->res_cport == NULL) { | 1426 | if (chip->res_cport == NULL) { |
1423 | snd_printk("memory region 0x%lx (size 0x%x) busy\n", | 1427 | snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n", |
1424 | chip->cport_addr, NM_PORT2_SIZE); | 1428 | chip->cport_addr, NM_PORT2_SIZE); |
1425 | err = -EBUSY; | 1429 | err = -EBUSY; |
1426 | goto __error; | 1430 | goto __error; |
1427 | } | 1431 | } |
1428 | chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE); | 1432 | chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE); |
1429 | if (chip->cport == NULL) { | 1433 | if (chip->cport == NULL) { |
1430 | snd_printk("unable to map control port %lx\n", chip->cport_addr); | 1434 | snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr); |
1431 | err = -ENOMEM; | 1435 | err = -ENOMEM; |
1432 | goto __error; | 1436 | goto __error; |
1433 | } | 1437 | } |
@@ -1485,7 +1489,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, | |||
1485 | chip->buffer_size, | 1489 | chip->buffer_size, |
1486 | card->driver); | 1490 | card->driver); |
1487 | if (chip->res_buffer == NULL) { | 1491 | if (chip->res_buffer == NULL) { |
1488 | snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n", | 1492 | snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n", |
1489 | chip->buffer_addr, chip->buffer_size); | 1493 | chip->buffer_addr, chip->buffer_size); |
1490 | err = -EBUSY; | 1494 | err = -EBUSY; |
1491 | goto __error; | 1495 | goto __error; |
@@ -1493,7 +1497,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, | |||
1493 | chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size); | 1497 | chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size); |
1494 | if (chip->buffer == NULL) { | 1498 | if (chip->buffer == NULL) { |
1495 | err = -ENOMEM; | 1499 | err = -ENOMEM; |
1496 | snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr); | 1500 | snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr); |
1497 | goto __error; | 1501 | goto __error; |
1498 | } | 1502 | } |
1499 | 1503 | ||
@@ -1542,7 +1546,7 @@ struct nm256_quirk { | |||
1542 | int type; | 1546 | int type; |
1543 | }; | 1547 | }; |
1544 | 1548 | ||
1545 | enum { NM_BLACKLISTED, NM_RESET_WORKAROUND }; | 1549 | enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 }; |
1546 | 1550 | ||
1547 | static struct nm256_quirk nm256_quirks[] __devinitdata = { | 1551 | static struct nm256_quirk nm256_quirks[] __devinitdata = { |
1548 | /* HP omnibook 4150 has cs4232 codec internally */ | 1552 | /* HP omnibook 4150 has cs4232 codec internally */ |
@@ -1551,6 +1555,8 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = { | |||
1551 | { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND }, | 1555 | { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND }, |
1552 | /* Dell Latitude LS */ | 1556 | /* Dell Latitude LS */ |
1553 | { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND }, | 1557 | { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND }, |
1558 | /* Dell Latitude CSx */ | ||
1559 | { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 }, | ||
1554 | { } /* terminator */ | 1560 | { } /* terminator */ |
1555 | }; | 1561 | }; |
1556 | 1562 | ||
@@ -1558,7 +1564,6 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = { | |||
1558 | static int __devinit snd_nm256_probe(struct pci_dev *pci, | 1564 | static int __devinit snd_nm256_probe(struct pci_dev *pci, |
1559 | const struct pci_device_id *pci_id) | 1565 | const struct pci_device_id *pci_id) |
1560 | { | 1566 | { |
1561 | static int dev; | ||
1562 | snd_card_t *card; | 1567 | snd_card_t *card; |
1563 | nm256_t *chip; | 1568 | nm256_t *chip; |
1564 | int err; | 1569 | int err; |
@@ -1566,13 +1571,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, | |||
1566 | struct nm256_quirk *q; | 1571 | struct nm256_quirk *q; |
1567 | u16 subsystem_vendor, subsystem_device; | 1572 | u16 subsystem_vendor, subsystem_device; |
1568 | 1573 | ||
1569 | if (dev >= SNDRV_CARDS) | ||
1570 | return -ENODEV; | ||
1571 | if (!enable[dev]) { | ||
1572 | dev++; | ||
1573 | return -ENOENT; | ||
1574 | } | ||
1575 | |||
1576 | pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); | 1574 | pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); |
1577 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); | 1575 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); |
1578 | 1576 | ||
@@ -1582,14 +1580,17 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, | |||
1582 | case NM_BLACKLISTED: | 1580 | case NM_BLACKLISTED: |
1583 | printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n"); | 1581 | printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n"); |
1584 | return -ENODEV; | 1582 | return -ENODEV; |
1583 | case NM_RESET_WORKAROUND_2: | ||
1584 | reset_workaround_2 = 1; | ||
1585 | /* Fall-through */ | ||
1585 | case NM_RESET_WORKAROUND: | 1586 | case NM_RESET_WORKAROUND: |
1586 | reset_workaround[dev] = 1; | 1587 | reset_workaround = 1; |
1587 | break; | 1588 | break; |
1588 | } | 1589 | } |
1589 | } | 1590 | } |
1590 | } | 1591 | } |
1591 | 1592 | ||
1592 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1593 | card = snd_card_new(index, id, THIS_MODULE, 0); |
1593 | if (card == NULL) | 1594 | if (card == NULL) |
1594 | return -ENOMEM; | 1595 | return -ENOMEM; |
1595 | 1596 | ||
@@ -1604,40 +1605,45 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, | |||
1604 | strcpy(card->driver, "NM256XL+"); | 1605 | strcpy(card->driver, "NM256XL+"); |
1605 | break; | 1606 | break; |
1606 | default: | 1607 | default: |
1607 | snd_printk("invalid device id 0x%x\n", pci->device); | 1608 | snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device); |
1608 | snd_card_free(card); | 1609 | snd_card_free(card); |
1609 | return -EINVAL; | 1610 | return -EINVAL; |
1610 | } | 1611 | } |
1611 | 1612 | ||
1612 | if (vaio_hack[dev]) | 1613 | if (vaio_hack) |
1613 | xbuffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */ | 1614 | xbuffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */ |
1614 | else | 1615 | else |
1615 | xbuffer_top = buffer_top[dev]; | 1616 | xbuffer_top = buffer_top; |
1616 | 1617 | ||
1617 | if (playback_bufsize[dev] < 4) | 1618 | if (playback_bufsize < 4) |
1618 | playback_bufsize[dev] = 4; | 1619 | playback_bufsize = 4; |
1619 | if (playback_bufsize[dev] > 128) | 1620 | if (playback_bufsize > 128) |
1620 | playback_bufsize[dev] = 128; | 1621 | playback_bufsize = 128; |
1621 | if (capture_bufsize[dev] < 4) | 1622 | if (capture_bufsize < 4) |
1622 | capture_bufsize[dev] = 4; | 1623 | capture_bufsize = 4; |
1623 | if (capture_bufsize[dev] > 128) | 1624 | if (capture_bufsize > 128) |
1624 | capture_bufsize[dev] = 128; | 1625 | capture_bufsize = 128; |
1625 | if ((err = snd_nm256_create(card, pci, | 1626 | if ((err = snd_nm256_create(card, pci, |
1626 | playback_bufsize[dev] * 1024, /* in bytes */ | 1627 | playback_bufsize * 1024, /* in bytes */ |
1627 | capture_bufsize[dev] * 1024, /* in bytes */ | 1628 | capture_bufsize * 1024, /* in bytes */ |
1628 | force_ac97[dev], | 1629 | force_ac97, |
1629 | xbuffer_top, | 1630 | xbuffer_top, |
1630 | use_cache[dev], | 1631 | use_cache, |
1631 | &chip)) < 0) { | 1632 | &chip)) < 0) { |
1632 | snd_card_free(card); | 1633 | snd_card_free(card); |
1633 | return err; | 1634 | return err; |
1634 | } | 1635 | } |
1635 | 1636 | ||
1636 | if (reset_workaround[dev]) { | 1637 | if (reset_workaround) { |
1637 | snd_printdd(KERN_INFO "nm256: reset_workaround activated\n"); | 1638 | snd_printdd(KERN_INFO "nm256: reset_workaround activated\n"); |
1638 | chip->reset_workaround = 1; | 1639 | chip->reset_workaround = 1; |
1639 | } | 1640 | } |
1640 | 1641 | ||
1642 | if (reset_workaround_2) { | ||
1643 | snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n"); | ||
1644 | chip->reset_workaround_2 = 1; | ||
1645 | } | ||
1646 | |||
1641 | if ((err = snd_nm256_pcm(chip, 0)) < 0 || | 1647 | if ((err = snd_nm256_pcm(chip, 0)) < 0 || |
1642 | (err = snd_nm256_mixer(chip)) < 0) { | 1648 | (err = snd_nm256_mixer(chip)) < 0) { |
1643 | snd_card_free(card); | 1649 | snd_card_free(card); |
@@ -1655,7 +1661,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, | |||
1655 | } | 1661 | } |
1656 | 1662 | ||
1657 | pci_set_drvdata(pci, card); | 1663 | pci_set_drvdata(pci, card); |
1658 | dev++; | ||
1659 | return 0; | 1664 | return 0; |
1660 | } | 1665 | } |
1661 | 1666 | ||