[alsa-devel] [RESEND] opti92x: use PnP data to select Master Control port
Takashi Iwai
tiwai at suse.de
Wed Mar 3 22:51:38 CET 2010
At Wed, 3 Mar 2010 19:41:44 +0100,
Krzysztof Helt wrote:
>
> From: Krzysztof Helt <krzysztof.h1 at 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 at 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",
> + 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");
> --
> 1.6.4
>
>
> ----------------------------------------------------------------------
> Wygraj z armia wampirow!
> Kliknij >>> http://link.interia.pl/f23a0
>
More information about the Alsa-devel
mailing list