Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6960e19 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Takashi Iwai
Browse files

ALSA: opti93x: set MC indirect registers base from PnP data



The PnP data on the OPTI931 and OPTI933 contains io port
range for the MC indirect registers. Use the PnP range
instead of hardwired value 0xE0E.

Also, request region of MC indirect registers so it is
marked as used to other drivers (this was missing previously).

Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 86e1d57e
Loading
Loading
Loading
Loading
+67 −45
Original line number Original line Diff line number Diff line
@@ -135,6 +135,8 @@ struct snd_opti9xx {
	unsigned long mc_base_size;
	unsigned long mc_base_size;
#ifdef OPTi93X
#ifdef OPTi93X
	unsigned long mc_indir_index;
	unsigned long mc_indir_index;
	unsigned long mc_indir_size;
	struct resource *res_mc_indir;
	struct snd_wss *codec;
	struct snd_wss *codec;
#endif	/* OPTi93X */
#endif	/* OPTi93X */
	unsigned long pwd_reg;
	unsigned long pwd_reg;
@@ -231,7 +233,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
	case OPTi9XX_HW_82C931:
	case OPTi9XX_HW_82C931:
	case OPTi9XX_HW_82C933:
	case OPTi9XX_HW_82C933:
		chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
		chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
		if (!chip->mc_indir_index) {
			chip->mc_indir_index = 0xe0e;
			chip->mc_indir_index = 0xe0e;
			chip->mc_indir_size = 2;
		}
		chip->password = 0xe4;
		chip->password = 0xe4;
		chip->pwd_reg = 0;
		chip->pwd_reg = 0;
		break;
		break;
@@ -560,57 +565,69 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)


#endif /* OPTi93X */
#endif /* OPTi93X */


static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
					     struct snd_opti9xx *chip)
{
{
	int i, err;

#ifndef OPTi93X
	for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
	unsigned char value;
	unsigned char value;
#ifdef OPTi93X
	unsigned long flags;
#endif


		if ((err = snd_opti9xx_init(chip, i)) < 0)
	chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
			return err;
					   "OPTi9xx MC");

	if (chip->res_mc_base == NULL)
		if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
		return -EBUSY;
			continue;
#ifndef OPTi93X

	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
		if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
	if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
		if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
		if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
				return 1;
			return 0;

		release_and_free_resource(chip->res_mc_base);
		chip->res_mc_base = NULL;

	}
#else	/* OPTi93X */
#else	/* OPTi93X */
	for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
	chip->res_mc_indir = request_region(chip->mc_indir_index,
		unsigned long flags;
					    chip->mc_indir_size,
		unsigned char value;
					    "OPTi93x MC");

	if (chip->res_mc_indir == NULL)
		if ((err = snd_opti9xx_init(chip, i)) < 0)
		return -EBUSY;
			return err;

		if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
			continue;


	spin_lock_irqsave(&chip->lock, flags);
	spin_lock_irqsave(&chip->lock, flags);
	outb(chip->password, chip->mc_base + chip->pwd_reg);
	outb(chip->password, chip->mc_base + chip->pwd_reg);
		outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
	outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
			((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
	spin_unlock_irqrestore(&chip->lock, flags);
	spin_unlock_irqrestore(&chip->lock, flags);


	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
	snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
	snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
	if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
	if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
			return 1;
		return 0;


	release_and_free_resource(chip->res_mc_indir);
	chip->res_mc_indir = NULL;
#endif	/* OPTi93X */
	release_and_free_resource(chip->res_mc_base);
	release_and_free_resource(chip->res_mc_base);
	chip->res_mc_base = NULL;
	chip->res_mc_base = NULL;

	return -ENODEV;
}
}
#endif	/* OPTi93X */


static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
					     struct snd_opti9xx *chip)
{
	int i, err;

#ifndef OPTi93X
	for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
#else
	for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
#endif
		err = snd_opti9xx_init(chip, i);
		if (err < 0)
			return err;

		err = snd_opti9xx_read_check(chip);
		if (err == 0)
			return 1;
#ifdef OPTi93X
		chip->mc_indir_index = 0;
#endif
	}
	return -ENODEV;
	return -ENODEV;
}
}


@@ -639,6 +656,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
#ifdef OPTi93X
#ifdef OPTi93X
	port = pnp_port_start(pdev, 0) - 4;
	port = pnp_port_start(pdev, 0) - 4;
	fm_port = pnp_port_start(pdev, 1) + 8;
	fm_port = pnp_port_start(pdev, 1) + 8;
	chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
	chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
#else
#else
	if (pid->driver_data != 0x0924)
	if (pid->driver_data != 0x0924)
		port = pnp_port_start(pdev, 1);
		port = pnp_port_start(pdev, 1);
@@ -677,6 +696,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
			disable_irq(codec->irq);
			disable_irq(codec->irq);
			free_irq(codec->irq, codec);
			free_irq(codec->irq, codec);
		}
		}
		release_and_free_resource(chip->res_mc_indir);
#endif
#endif
		release_and_free_resource(chip->res_mc_base);
		release_and_free_resource(chip->res_mc_base);
	}
	}
@@ -696,11 +716,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
	struct snd_rawmidi *rmidi;
	struct snd_rawmidi *rmidi;
	struct snd_hwdep *synth;
	struct snd_hwdep *synth;


	if (! chip->res_mc_base &&
	    (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
						"OPTi9xx MC")) == NULL)
		return -ENOMEM;

#if defined(CS4231) || defined(OPTi93X)
#if defined(CS4231) || defined(OPTi93X)
	xdma2 = dma2;
	xdma2 = dma2;
#else
#else
@@ -954,6 +969,13 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
	}
	}
	if (hw <= OPTi9XX_HW_82C930)
	if (hw <= OPTi9XX_HW_82C930)
		chip->mc_base -= 0x80;
		chip->mc_base -= 0x80;

	error = snd_opti9xx_read_check(chip);
	if (error) {
		snd_printk(KERN_ERR "OPTI chip not found\n");
		snd_card_free(card);
		return error;
	}
	snd_card_set_dev(card, &pcard->card->dev);
	snd_card_set_dev(card, &pcard->card->dev);
	if ((error = snd_opti9xx_probe(card)) < 0) {
	if ((error = snd_opti9xx_probe(card)) < 0) {
		snd_card_free(card);
		snd_card_free(card);