aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-11-30 01:46:56 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-30 05:26:30 -0500
commit306ecee926cf79f1b3b5f6035be09ef3d83f1b76 (patch)
tree01055d6824b1ffe99ba2af2157d508f417cb877a /sound
parent70a5f1187bcb3fac93a7d5c5fcfc5fc76b9c3f55 (diff)
ALSA: opti-miro: add PnP detection
The PCM12 and PCM20 can be set into the ISA PnP mode. The PCM12 PnP was sold as the PnP device. Add code to handle detection of these cards using ISA PnP framework. Tested on the PCM20 in PnP mode. The PCM12 PnP has the same MS Windows INF file except for a card name displayed for user. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/isa/opti9xx/miro.c203
1 files changed, 192 insertions, 11 deletions
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index c67bc3cd2c65..6123c7531110 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -25,6 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/isa.h> 27#include <linux/isa.h>
28#include <linux/pnp.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/ioport.h> 31#include <linux/ioport.h>
@@ -60,6 +61,9 @@ static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
60static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ 61static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
61static int wss; 62static int wss;
62static int ide; 63static int ide;
64#ifdef CONFIG_PNP
65static int isapnp = 1; /* Enable ISA PnP detection */
66#endif
63 67
64module_param(index, int, 0444); 68module_param(index, int, 0444);
65MODULE_PARM_DESC(index, "Index value for miro soundcard."); 69MODULE_PARM_DESC(index, "Index value for miro soundcard.");
@@ -83,6 +87,10 @@ module_param(wss, int, 0444);
83MODULE_PARM_DESC(wss, "wss mode"); 87MODULE_PARM_DESC(wss, "wss mode");
84module_param(ide, int, 0444); 88module_param(ide, int, 0444);
85MODULE_PARM_DESC(ide, "enable ide port"); 89MODULE_PARM_DESC(ide, "enable ide port");
90#ifdef CONFIG_PNP
91module_param(isapnp, bool, 0444);
92MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
93#endif
86 94
87#define OPTi9XX_HW_DETECT 0 95#define OPTi9XX_HW_DETECT 0
88#define OPTi9XX_HW_82C928 1 96#define OPTi9XX_HW_82C928 1
@@ -131,6 +139,21 @@ static char * snd_opti9xx_names[] = {
131 "82C930", "82C931", "82C933" 139 "82C930", "82C931", "82C933"
132}; 140};
133 141
142static int snd_miro_pnp_is_probed;
143
144#ifdef CONFIG_PNP
145
146static struct pnp_card_device_id snd_miro_pnpids[] = {
147 /* PCM20 and PCM12 in PnP mode */
148 { .id = "MIR0924",
149 .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
150 { .id = "" }
151};
152
153MODULE_DEVICE_TABLE(pnp_card, snd_miro_pnpids);
154
155#endif /* CONFIG_PNP */
156
134/* 157/*
135 * ACI control 158 * ACI control
136 */ 159 */
@@ -781,17 +804,23 @@ static int __devinit snd_miro_init(struct snd_miro *chip,
781 chip->mpu_port = -1; 804 chip->mpu_port = -1;
782 chip->mpu_irq = -1; 805 chip->mpu_irq = -1;
783 806
807 chip->pwd_reg = 3;
808
809#ifdef CONFIG_PNP
810 if (isapnp && chip->mc_base)
811 /* PnP resource gives the least 10 bits */
812 chip->mc_base |= 0xc00;
813 else
814#endif
815 chip->mc_base = 0xf8c;
816
784 switch (hardware) { 817 switch (hardware) {
785 case OPTi9XX_HW_82C929: 818 case OPTi9XX_HW_82C929:
786 chip->mc_base = 0xf8c;
787 chip->password = 0xe3; 819 chip->password = 0xe3;
788 chip->pwd_reg = 3;
789 break; 820 break;
790 821
791 case OPTi9XX_HW_82C924: 822 case OPTi9XX_HW_82C924:
792 chip->mc_base = 0xf8c;
793 chip->password = 0xe5; 823 chip->password = 0xe5;
794 chip->pwd_reg = 3;
795 break; 824 break;
796 825
797 default: 826 default:
@@ -1014,17 +1043,22 @@ static int __devinit snd_miro_configure(struct snd_miro *chip)
1014 return -EINVAL; 1043 return -EINVAL;
1015 } 1044 }
1016 1045
1017 switch (chip->wss_base) { 1046 /* PnP resource says it decodes only 10 bits of address */
1018 case 0x530: 1047 switch (chip->wss_base & 0x3ff) {
1048 case 0x130:
1049 chip->wss_base = 0x530;
1019 wss_base_bits = 0x00; 1050 wss_base_bits = 0x00;
1020 break; 1051 break;
1021 case 0x604: 1052 case 0x204:
1053 chip->wss_base = 0x604;
1022 wss_base_bits = 0x03; 1054 wss_base_bits = 0x03;
1023 break; 1055 break;
1024 case 0xe80: 1056 case 0x280:
1057 chip->wss_base = 0xe80;
1025 wss_base_bits = 0x01; 1058 wss_base_bits = 0x01;
1026 break; 1059 break;
1027 case 0xf40: 1060 case 0x340:
1061 chip->wss_base = 0xf40;
1028 wss_base_bits = 0x02; 1062 wss_base_bits = 0x02;
1029 break; 1063 break;
1030 default: 1064 default:
@@ -1238,7 +1272,7 @@ static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1238static void snd_card_miro_free(struct snd_card *card) 1272static void snd_card_miro_free(struct snd_card *card)
1239{ 1273{
1240 struct snd_miro *miro = card->private_data; 1274 struct snd_miro *miro = card->private_data;
1241 1275
1242 release_and_free_resource(miro->res_aci_port); 1276 release_and_free_resource(miro->res_aci_port);
1243 if (miro->aci) 1277 if (miro->aci)
1244 miro->aci->aci_port = 0; 1278 miro->aci->aci_port = 0;
@@ -1370,6 +1404,12 @@ static int __devinit snd_miro_probe(struct snd_card *card)
1370 1404
1371static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n) 1405static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
1372{ 1406{
1407#ifdef CONFIG_PNP
1408 if (snd_miro_pnp_is_probed)
1409 return 0;
1410 if (isapnp)
1411 return 0;
1412#endif
1373 return 1; 1413 return 1;
1374} 1414}
1375 1415
@@ -1487,14 +1527,155 @@ static struct isa_driver snd_miro_driver = {
1487 }, 1527 },
1488}; 1528};
1489 1529
1530#ifdef CONFIG_PNP
1531
1532static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
1533 struct pnp_card_link *card,
1534 const struct pnp_card_device_id *pid)
1535{
1536 struct pnp_dev *pdev;
1537 int err;
1538 struct pnp_dev *devmpu;
1539 struct pnp_dev *devmc;
1540
1541 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
1542 if (pdev == NULL)
1543 return -EBUSY;
1544
1545 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
1546 if (devmpu == NULL)
1547 return -EBUSY;
1548
1549 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
1550 if (devmc == NULL)
1551 return -EBUSY;
1552
1553 err = pnp_activate_dev(pdev);
1554 if (err < 0) {
1555 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
1556 return err;
1557 }
1558
1559 err = pnp_activate_dev(devmc);
1560 if (err < 0) {
1561 snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n",
1562 err);
1563 return err;
1564 }
1565
1566 port = pnp_port_start(pdev, 1);
1567 fm_port = pnp_port_start(pdev, 2) + 8;
1568
1569 /*
1570 * The MC(0) is never accessed and the miroSOUND PCM20 card does not
1571 * include it in the PnP resource range. OPTI93x include it.
1572 */
1573 chip->mc_base = pnp_port_start(devmc, 0) - 1;
1574 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
1575
1576 irq = pnp_irq(pdev, 0);
1577 dma1 = pnp_dma(pdev, 0);
1578 dma2 = pnp_dma(pdev, 1);
1579
1580 if (mpu_port > 0) {
1581 err = pnp_activate_dev(devmpu);
1582 if (err < 0) {
1583 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
1584 mpu_port = -1;
1585 return err;
1586 }
1587 mpu_port = pnp_port_start(devmpu, 0);
1588 mpu_irq = pnp_irq(devmpu, 0);
1589 }
1590 return 0;
1591}
1592
1593static int __devinit snd_miro_pnp_probe(struct pnp_card_link *pcard,
1594 const struct pnp_card_device_id *pid)
1595{
1596 struct snd_card *card;
1597 int err;
1598 struct snd_miro *miro;
1599
1600 if (snd_miro_pnp_is_probed)
1601 return -EBUSY;
1602 if (!isapnp)
1603 return -ENODEV;
1604 err = snd_card_create(index, id, THIS_MODULE,
1605 sizeof(struct snd_miro), &card);
1606 if (err < 0)
1607 return err;
1608
1609 card->private_free = snd_card_miro_free;
1610 miro = card->private_data;
1611
1612 err = snd_card_miro_pnp(miro, pcard, pid);
1613 if (err) {
1614 snd_card_free(card);
1615 return err;
1616 }
1617
1618 /* only miroSOUND PCM20 and PCM12 == OPTi924 */
1619 err = snd_miro_init(miro, OPTi9XX_HW_82C924);
1620 if (err) {
1621 snd_card_free(card);
1622 return err;
1623 }
1624
1625 err = snd_miro_opti_check(miro);
1626 if (err) {
1627 snd_printk(KERN_ERR "OPTI chip not found\n");
1628 snd_card_free(card);
1629 return err;
1630 }
1631
1632 snd_card_set_dev(card, &pcard->card->dev);
1633 err = snd_miro_probe(card);
1634 if (err < 0) {
1635 snd_card_free(card);
1636 return err;
1637 }
1638 pnp_set_card_drvdata(pcard, card);
1639 snd_miro_pnp_is_probed = 1;
1640 return 0;
1641}
1642
1643static void __devexit snd_miro_pnp_remove(struct pnp_card_link * pcard)
1644{
1645 snd_card_free(pnp_get_card_drvdata(pcard));
1646 pnp_set_card_drvdata(pcard, NULL);
1647 snd_miro_pnp_is_probed = 0;
1648}
1649
1650static struct pnp_card_driver miro_pnpc_driver = {
1651 .flags = PNP_DRIVER_RES_DISABLE,
1652 .name = "miro",
1653 .id_table = snd_miro_pnpids,
1654 .probe = snd_miro_pnp_probe,
1655 .remove = __devexit_p(snd_miro_pnp_remove),
1656};
1657#endif
1658
1490static int __init alsa_card_miro_init(void) 1659static int __init alsa_card_miro_init(void)
1491{ 1660{
1661#ifdef CONFIG_PNP
1662 pnp_register_card_driver(&miro_pnpc_driver);
1663 if (snd_miro_pnp_is_probed)
1664 return 0;
1665 pnp_unregister_card_driver(&miro_pnpc_driver);
1666#endif
1492 return isa_register_driver(&snd_miro_driver, 1); 1667 return isa_register_driver(&snd_miro_driver, 1);
1493} 1668}
1494 1669
1495static void __exit alsa_card_miro_exit(void) 1670static void __exit alsa_card_miro_exit(void)
1496{ 1671{
1497 isa_unregister_driver(&snd_miro_driver); 1672 if (!snd_miro_pnp_is_probed) {
1673 isa_unregister_driver(&snd_miro_driver);
1674 return;
1675 }
1676#ifdef CONFIG_PNP
1677 pnp_unregister_card_driver(&miro_pnpc_driver);
1678#endif
1498} 1679}
1499 1680
1500module_init(alsa_card_miro_init) 1681module_init(alsa_card_miro_init)