[alsa-devel] [RESEND] opti92x: use PnP data to select Master Control port
From: Krzysztof Helt krzysztof.h1@wp.pl
The Master Control port (MC) is available as the last PnP resource (OPT005). Use this value instead fo guessing.
Also, add some comments to the code.
Signed-off-by: Krzysztof Helt krzysztof.h1@wp.pl --- sound/isa/opti9xx/miro.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 120 +++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 43 deletions(-)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index b865e45..5913717 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -1558,7 +1558,7 @@ static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
err = pnp_activate_dev(devmc); if (err < 0) { - snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n", + snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err); return err; } diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index a4af53b..becd90d 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -144,12 +144,8 @@ struct snd_opti9xx {
spinlock_t lock;
+ long wss_base; int irq; - -#ifdef CONFIG_PNP - struct pnp_dev *dev; - struct pnp_dev *devmpu; -#endif /* CONFIG_PNP */ };
static int snd_opti9xx_pnp_is_probed; @@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed; static struct pnp_card_device_id snd_opti9xx_pnpids[] = { #ifndef OPTi93X /* OPTi 82C924 */ - { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, + { .id = "OPT0924", + .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } }, + .driver_data = 0x0924 }, /* OPTi 82C925 */ - { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, + { .id = "OPT0925", + .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } }, + .driver_data = 0x0925 }, #else /* OPTi 82C931/3 */ - { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, + { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, + .driver_data = 0x0931 }, #endif /* OPTi93X */ { .id = "" } }; @@ -207,24 +208,34 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, chip->hardware = hardware; strcpy(chip->name, snd_opti9xx_names[hardware]);
- chip->mc_base_size = opti9xx_mc_size[hardware]; - spin_lock_init(&chip->lock);
chip->irq = -1;
+#ifndef OPTi93X +#ifdef CONFIG_PNP + if (isapnp && chip->mc_base) + /* PnP resource gives the least 10 bits */ + chip->mc_base |= 0xc00; +#endif /* CONFIG_PNP */ + else { + chip->mc_base = 0xf8c; + chip->mc_base_size = opti9xx_mc_size[hardware]; + } +#else + chip->mc_base_size = opti9xx_mc_size[hardware]; +#endif + switch (hardware) { #ifndef OPTi93X case OPTi9XX_HW_82C928: case OPTi9XX_HW_82C929: - chip->mc_base = 0xf8c; chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; chip->pwd_reg = 3; break;
case OPTi9XX_HW_82C924: case OPTi9XX_HW_82C925: - chip->mc_base = 0xf8c; chip->password = 0xe5; chip->pwd_reg = 3; break; @@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, spin_unlock_irqrestore(&chip->lock, flags); return retval; } - + static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, unsigned char value) { @@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, - long wss_base, + long port, int irq, int dma1, int dma2, long mpu_port, int mpu_irq) { @@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, switch (chip->hardware) { #ifndef OPTi93X case OPTi9XX_HW_82C924: + /* opti 929 mode (?), OPL3 clock output, audio enable */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); + /* enable wave audio */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
case OPTi9XX_HW_82C925: + /* enable WSS mode */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); + /* OPL3 FM synthesis */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); + /* disable Sound Blaster IRQ and DMA */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); #ifdef CS4231 + /* cs4231/4248 fix enabled */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); #else + /* cs4231/4248 fix disabled */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); #endif /* CS4231 */ break; @@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, return -EINVAL; }
- switch (wss_base) { - case 0x530: + /* PnP resource says it decodes only 10 bits of address */ + switch (port & 0x3ff) { + case 0x130: + chip->wss_base = 0x530; wss_base_bits = 0x00; break; - case 0x604: + case 0x204: + chip->wss_base = 0x604; wss_base_bits = 0x03; break; - case 0xe80: + case 0x280: + chip->wss_base = 0xe80; wss_base_bits = 0x01; break; - case 0xf40: + case 0x340: + chip->wss_base = 0xf40; wss_base_bits = 0x02; break; default: - snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); + snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port); goto __skip_base; } snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); @@ -487,7 +510,7 @@ __skip_base: #endif /* CS4231 || OPTi93X */
#ifndef OPTi93X - outb(irq_bits << 3 | dma_bits, wss_base); + outb(irq_bits << 3 | dma_bits, chip->wss_base); #else /* OPTi93X */ snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); #endif /* OPTi93X */ @@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, { struct pnp_dev *pdev; int err; + struct pnp_dev *devmpu; +#ifndef OPTi93X + struct pnp_dev *devmc; +#endif
- chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); - if (chip->dev == NULL) + pdev = pnp_request_card_device(card, pid->devs[0].id, NULL); + if (pdev == NULL) return -EBUSY;
- chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL); - - pdev = chip->dev; - err = pnp_activate_dev(pdev); if (err < 0) { snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); @@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; #else - if (pid->driver_data != 0x0924) - port = pnp_port_start(pdev, 1); + devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); + if (devmc == NULL) + return -EBUSY; + + err = pnp_activate_dev(devmc); + if (err < 0) { + snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err); + return err; + } + + port = pnp_port_start(pdev, 1); fm_port = pnp_port_start(pdev, 2) + 8; + /* + * The MC(0) is never accessed and card does not + * include it in the PnP resource range. OPTI93x include it. + */ + chip->mc_base = pnp_port_start(devmc, 0) - 1; + chip->mc_base_size = pnp_port_len(devmc, 0) + 1; #endif /* OPTi93X */ irq = pnp_irq(pdev, 0); dma1 = pnp_dma(pdev, 0); @@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, dma2 = pnp_dma(pdev, 1); #endif /* CS4231 || OPTi93X */
- pdev = chip->devmpu; - if (pdev && mpu_port > 0) { - err = pnp_activate_dev(pdev); + devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL); + + if (devmpu && mpu_port > 0) { + err = pnp_activate_dev(devmpu); if (err < 0) { - snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); + snd_printk(KERN_ERR "MPU401 pnp configure failure\n"); mpu_port = -1; - chip->devmpu = NULL; } else { - mpu_port = pnp_port_start(pdev, 0); - mpu_irq = pnp_irq(pdev, 0); + mpu_port = pnp_port_start(devmpu, 0); + mpu_irq = pnp_irq(devmpu, 0); } } return pid->driver_data; @@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) if (error) return error;
- error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, + error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2, #ifdef OPTi93X WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, #else @@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) sprintf(card->shortname, "OPTi %s", card->driver); #if defined(CS4231) || defined(OPTi93X) sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, pcm->name, port + 4, irq, dma1, xdma2); + card->shortname, pcm->name, + chip->wss_base + 4, irq, dma1, xdma2); #else sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", - card->shortname, pcm->name, port + 4, irq, dma1); + card->shortname, pcm->name, chip->wss_base + 4, irq, dma1); #endif /* CS4231 || OPTi93X */
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) @@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, snd_card_free(card); return error; } - if (hw <= OPTi9XX_HW_82C930) - chip->mc_base -= 0x80; - error = snd_opti9xx_read_check(chip); if (error) { snd_printk(KERN_ERR "OPTI chip not found\n");
At Wed, 3 Mar 2010 19:41:44 +0100, Krzysztof Helt wrote:
From: Krzysztof Helt krzysztof.h1@wp.pl
The Master Control port (MC) is available as the last PnP resource (OPT005). Use this value instead fo guessing.
Also, add some comments to the code.
Signed-off-by: Krzysztof Helt krzysztof.h1@wp.pl
Applied now. Thanks.
Takashi
sound/isa/opti9xx/miro.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 120 +++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 43 deletions(-)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index b865e45..5913717 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -1558,7 +1558,7 @@ static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
err = pnp_activate_dev(devmc); if (err < 0) {
snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n",
return err; }snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index a4af53b..becd90d 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -144,12 +144,8 @@ struct snd_opti9xx {
spinlock_t lock;
- long wss_base; int irq;
-#ifdef CONFIG_PNP
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
-#endif /* CONFIG_PNP */ };
static int snd_opti9xx_pnp_is_probed; @@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed; static struct pnp_card_device_id snd_opti9xx_pnpids[] = { #ifndef OPTi93X /* OPTi 82C924 */
- { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 },
- { .id = "OPT0924",
.devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
/* OPTi 82C925 */.driver_data = 0x0924 },
- { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 },
- { .id = "OPT0925",
.devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
.driver_data = 0x0925 },
#else /* OPTi 82C931/3 */
- { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 },
- { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
.driver_data = 0x0931 },
#endif /* OPTi93X */ { .id = "" } }; @@ -207,24 +208,34 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, chip->hardware = hardware; strcpy(chip->name, snd_opti9xx_names[hardware]);
chip->mc_base_size = opti9xx_mc_size[hardware];
spin_lock_init(&chip->lock);
chip->irq = -1;
+#ifndef OPTi93X +#ifdef CONFIG_PNP
- if (isapnp && chip->mc_base)
/* PnP resource gives the least 10 bits */
chip->mc_base |= 0xc00;
+#endif /* CONFIG_PNP */
- else {
chip->mc_base = 0xf8c;
chip->mc_base_size = opti9xx_mc_size[hardware];
- }
+#else
chip->mc_base_size = opti9xx_mc_size[hardware];
+#endif
- switch (hardware) {
#ifndef OPTi93X case OPTi9XX_HW_82C928: case OPTi9XX_HW_82C929:
chip->mc_base = 0xf8c;
chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; chip->pwd_reg = 3; break;
case OPTi9XX_HW_82C924: case OPTi9XX_HW_82C925:
chip->mc_base = 0xf8c;
chip->password = 0xe5; chip->pwd_reg = 3; break;
@@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, spin_unlock_irqrestore(&chip->lock, flags); return retval; }
static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, unsigned char value) { @@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
long wss_base,
long port, int irq, int dma1, int dma2, long mpu_port, int mpu_irq)
{ @@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, switch (chip->hardware) { #ifndef OPTi93X case OPTi9XX_HW_82C924:
/* opti 929 mode (?), OPL3 clock output, audio enable */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
/* enable wave audio */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
case OPTi9XX_HW_82C925:
/* enable WSS mode */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
/* OPL3 FM synthesis */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
/* disable Sound Blaster IRQ and DMA */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
#ifdef CS4231
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);/* cs4231/4248 fix enabled */
#else
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);/* cs4231/4248 fix disabled */
#endif /* CS4231 */ break; @@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, return -EINVAL; }
- switch (wss_base) {
- case 0x530:
- /* PnP resource says it decodes only 10 bits of address */
- switch (port & 0x3ff) {
- case 0x130:
wss_base_bits = 0x00; break;chip->wss_base = 0x530;
- case 0x604:
- case 0x204:
wss_base_bits = 0x03; break;chip->wss_base = 0x604;
- case 0xe80:
- case 0x280:
wss_base_bits = 0x01; break;chip->wss_base = 0xe80;
- case 0xf40:
- case 0x340:
wss_base_bits = 0x02; break; default:chip->wss_base = 0xf40;
snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base);
goto __skip_base; } snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
@@ -487,7 +510,7 @@ __skip_base: #endif /* CS4231 || OPTi93X */
#ifndef OPTi93X
outb(irq_bits << 3 | dma_bits, wss_base);
outb(irq_bits << 3 | dma_bits, chip->wss_base);
#else /* OPTi93X */ snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); #endif /* OPTi93X */ @@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, { struct pnp_dev *pdev; int err;
- struct pnp_dev *devmpu;
+#ifndef OPTi93X
- struct pnp_dev *devmc;
+#endif
- chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
- if (chip->dev == NULL)
- pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
- if (pdev == NULL) return -EBUSY;
- chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
- pdev = chip->dev;
- err = pnp_activate_dev(pdev); if (err < 0) { snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; #else
- if (pid->driver_data != 0x0924)
port = pnp_port_start(pdev, 1);
- devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
- if (devmc == NULL)
return -EBUSY;
- err = pnp_activate_dev(devmc);
- if (err < 0) {
snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
return err;
- }
- port = pnp_port_start(pdev, 1); fm_port = pnp_port_start(pdev, 2) + 8;
- /*
* The MC(0) is never accessed and card does not
* include it in the PnP resource range. OPTI93x include it.
*/
- chip->mc_base = pnp_port_start(devmc, 0) - 1;
- chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
#endif /* OPTi93X */ irq = pnp_irq(pdev, 0); dma1 = pnp_dma(pdev, 0); @@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, dma2 = pnp_dma(pdev, 1); #endif /* CS4231 || OPTi93X */
- pdev = chip->devmpu;
- if (pdev && mpu_port > 0) {
err = pnp_activate_dev(pdev);
- devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
- if (devmpu && mpu_port > 0) {
if (err < 0) {err = pnp_activate_dev(devmpu);
snd_printk(KERN_ERR "AUDIO pnp configure failure\n");
snd_printk(KERN_ERR "MPU401 pnp configure failure\n"); mpu_port = -1;
} else {chip->devmpu = NULL;
mpu_port = pnp_port_start(pdev, 0);
mpu_irq = pnp_irq(pdev, 0);
mpu_port = pnp_port_start(devmpu, 0);
} } return pid->driver_data;mpu_irq = pnp_irq(devmpu, 0);
@@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) if (error) return error;
- error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2,
- error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
#ifdef OPTi93X WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, #else @@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) sprintf(card->shortname, "OPTi %s", card->driver); #if defined(CS4231) || defined(OPTi93X) sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
card->shortname, pcm->name, port + 4, irq, dma1, xdma2);
card->shortname, pcm->name,
chip->wss_base + 4, irq, dma1, xdma2);
#else sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
card->shortname, pcm->name, port + 4, irq, dma1);
card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
#endif /* CS4231 || OPTi93X */
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) @@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, snd_card_free(card); return error; }
- if (hw <= OPTi9XX_HW_82C930)
chip->mc_base -= 0x80;
- error = snd_opti9xx_read_check(chip); if (error) { snd_printk(KERN_ERR "OPTI chip not found\n");
-- 1.6.4
Wygraj z armia wampirow! Kliknij >>> http://link.interia.pl/f23a0
participants (2)
-
Krzysztof Helt
-
Takashi Iwai