[alsa-devel] [PATCH 2/2] opti93x: set MC indirect registers base from PnP data
From: Krzysztof Helt krzysztof.h1@wp.pl
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: Krzysztof Helt krzysztof.h1@wp.pl --- sound/isa/opti9xx/opti92x-ad1848.c | 53 +++++++++++++++++++++++++++++------ 1 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 438c1da..07ab288 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -135,6 +135,8 @@ struct snd_opti9xx { unsigned long mc_base_size; #ifdef OPTi93X unsigned long mc_indir_index; + unsigned long mc_indir_size; + struct resource *res_mc_indir; struct snd_wss *codec; #endif /* OPTi93X */ unsigned long pwd_reg; @@ -245,7 +247,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, case OPTi9XX_HW_82C931: case OPTi9XX_HW_82C933: chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; - chip->mc_indir_index = 0xe0e; + if (!chip->mc_indir_index) { + chip->mc_indir_index = 0xe0e; + chip->mc_indir_size = 2; + } chip->password = 0xe4; chip->pwd_reg = 0; break; @@ -579,10 +584,10 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip) { int i, err; + unsigned char value;
#ifndef OPTi93X for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) { - unsigned char value;
if ((err = snd_opti9xx_init(chip, i)) < 0) return err; @@ -602,18 +607,26 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, #else /* OPTi93X */ for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { unsigned long flags; - unsigned char value;
- if ((err = snd_opti9xx_init(chip, i)) < 0) + err = snd_opti9xx_init(chip, i); + if (err < 0) return err;
- if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) - continue; + chip->res_mc_base = request_region(chip->mc_base, + chip->mc_base_size, + "OPTi9xx MC"); + if (chip->res_mc_base == NULL) + return -EBUSY; + + chip->res_mc_indir = request_region(chip->mc_indir_index, + chip->mc_indir_size, + "OPTi93x MC"); + if (chip->res_mc_indir == NULL) + return -EBUSY;
spin_lock_irqsave(&chip->lock, flags); outb(chip->password, chip->mc_base + chip->pwd_reg); - outb(((chip->mc_indir_index & (1 << 8)) >> 4) | - ((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base); + outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base); spin_unlock_irqrestore(&chip->lock, flags);
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)); @@ -621,6 +634,8 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value) return 1;
+ release_and_free_resource(chip->res_mc_indir); + chip->res_mc_indir = NULL; release_and_free_resource(chip->res_mc_base); chip->res_mc_base = NULL; } @@ -654,6 +669,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, #ifdef OPTi93X port = pnp_port_start(pdev, 0) - 4; 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 if (pid->driver_data != 0x0924) port = pnp_port_start(pdev, 1); @@ -684,7 +701,7 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, static void snd_card_opti9xx_free(struct snd_card *card) { struct snd_opti9xx *chip = card->private_data; - + if (chip) { #ifdef OPTi93X struct snd_wss *codec = chip->codec; @@ -692,6 +709,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) disable_irq(chip->irq); free_irq(chip->irq, codec); } + release_and_free_resource(chip->res_mc_indir); #endif release_and_free_resource(chip->res_mc_base); } @@ -709,12 +727,29 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) struct snd_pcm *pcm; struct snd_rawmidi *rmidi; struct snd_hwdep *synth; +#ifdef OPTi93X + unsigned long flags; +#endif
if (! chip->res_mc_base && (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) return -ENOMEM;
+#ifdef OPTi93X + if (chip->res_mc_indir == NULL) { + chip->res_mc_indir = request_region(chip->mc_indir_index, + chip->mc_indir_size, + "OPTi93x MC"); + if (chip->res_mc_indir == NULL) + return -ENOMEM; + } + /* store MC indirect range address */ + spin_lock_irqsave(&chip->lock, flags); + outb(chip->password, chip->mc_base + chip->pwd_reg); + outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base); + spin_unlock_irqrestore(&chip->lock, flags); +#endif chip->wss_base = port; chip->fm_port = fm_port; chip->mpu_port = mpu_port;
At Sun, 29 Nov 2009 20:23:28 +0100, Krzysztof Helt wrote:
From: Krzysztof Helt krzysztof.h1@wp.pl
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).
I would create a function to call request_region()s for chip->res_mc_base and chip->res_mc_indir and do initializations, instead of spreading each request_region() in separate places.
thanks,
Takashi
Signed-off-by: Krzysztof Helt krzysztof.h1@wp.pl
sound/isa/opti9xx/opti92x-ad1848.c | 53 +++++++++++++++++++++++++++++------ 1 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 438c1da..07ab288 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -135,6 +135,8 @@ struct snd_opti9xx { unsigned long mc_base_size; #ifdef OPTi93X unsigned long mc_indir_index;
- unsigned long mc_indir_size;
- struct resource *res_mc_indir; struct snd_wss *codec;
#endif /* OPTi93X */ unsigned long pwd_reg; @@ -245,7 +247,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, case OPTi9XX_HW_82C931: case OPTi9XX_HW_82C933: chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
chip->mc_indir_index = 0xe0e;
if (!chip->mc_indir_index) {
chip->mc_indir_index = 0xe0e;
chip->mc_indir_size = 2;
chip->password = 0xe4; chip->pwd_reg = 0; break;}
@@ -579,10 +584,10 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip) { int i, err;
- unsigned char value;
#ifndef OPTi93X for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
unsigned char value;
if ((err = snd_opti9xx_init(chip, i)) < 0) return err;
@@ -602,18 +607,26 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, #else /* OPTi93X */ for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { unsigned long flags;
unsigned char value;
if ((err = snd_opti9xx_init(chip, i)) < 0)
err = snd_opti9xx_init(chip, i);
if (err < 0) return err;
if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
continue;
chip->res_mc_base = request_region(chip->mc_base,
chip->mc_base_size,
"OPTi9xx MC");
if (chip->res_mc_base == NULL)
return -EBUSY;
chip->res_mc_indir = request_region(chip->mc_indir_index,
chip->mc_indir_size,
"OPTi93x MC");
if (chip->res_mc_indir == NULL)
return -EBUSY;
spin_lock_irqsave(&chip->lock, flags); outb(chip->password, chip->mc_base + chip->pwd_reg);
outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
spin_unlock_irqrestore(&chip->lock, flags);
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
@@ -621,6 +634,8 @@ static int __devinit snd_card_opti9xx_detect(struct snd_card *card, if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value) return 1;
release_and_free_resource(chip->res_mc_indir);
release_and_free_resource(chip->res_mc_base); chip->res_mc_base = NULL; }chip->res_mc_indir = NULL;
@@ -654,6 +669,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, #ifdef OPTi93X port = pnp_port_start(pdev, 0) - 4; 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 if (pid->driver_data != 0x0924) port = pnp_port_start(pdev, 1); @@ -684,7 +701,7 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, static void snd_card_opti9xx_free(struct snd_card *card) { struct snd_opti9xx *chip = card->private_data;
- if (chip) {
#ifdef OPTi93X struct snd_wss *codec = chip->codec; @@ -692,6 +709,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) disable_irq(chip->irq); free_irq(chip->irq, codec); }
release_and_free_resource(chip->res_mc_indir);
#endif release_and_free_resource(chip->res_mc_base); } @@ -709,12 +727,29 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) struct snd_pcm *pcm; struct snd_rawmidi *rmidi; struct snd_hwdep *synth; +#ifdef OPTi93X
- unsigned long flags;
+#endif
if (! chip->res_mc_base && (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) return -ENOMEM;
+#ifdef OPTi93X
- if (chip->res_mc_indir == NULL) {
chip->res_mc_indir = request_region(chip->mc_indir_index,
chip->mc_indir_size,
"OPTi93x MC");
if (chip->res_mc_indir == NULL)
return -ENOMEM;
- }
- /* store MC indirect range address */
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
- spin_unlock_irqrestore(&chip->lock, flags);
+#endif chip->wss_base = port; chip->fm_port = fm_port; chip->mpu_port = mpu_port; -- 1.6.4
Codziennie 11 tys. ofert pracy! Sprawdz: http://link.interia.pl/f2447
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (2)
-
Krzysztof Helt
-
Takashi Iwai