[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-sound
Subject:    PATCH: Looking for nm256 audio driver users to test this...
From:       Jeff Garzik <jgarzik () mandrakesoft ! com>
Date:       2000-06-02 9:21:59
[Download RAW message or body]

Anyone have any sound hardware (usually found on laptops) which uses the
nm256 audio driver?  The attached patch would allow us to hook this
nm256 driver into a more modern AC97 kernel interface, but unfortunately
I have no hardware for testing this change.

Any testing and "it works!" or "it doesn't work!" feedback would be
greatly appreciated.

Simple cookbook testing procedure:

1) download and unpack latest development kernel tarball from
ftp://ftp.us.kernel.org/pub/linux/kernel/v2.4/

2) download latest development kernel Alan Cox "ac" patch kit from
ftp://ftp.us.kernel.org/pub/linux/kernel/people/alan/2.4.0test/ and
apply this patch to the kernel unpacked in step #1.

3) build and test a "plain" kernel.  note how well your audio works. 
nothing fancy, just make sure MP3s play and stuff.  :)

4) apply the patch attached to this e-mail.

5) build and test a modified kernel.  note differences (hopefully
none...) in functioning of audio.  This patch changes the mixer code, so
testing the mixer is a good idea.

For more info see the Linux Kernel HOWTO: 
http://www.linuxdoc.org/HOWTO/Kernel-HOWTO.html

Thanks,

	Jeff




-- 
Jeff Garzik              | Liberty is always dangerous, but
Building 1024            | it is the safest thing we have.
MandrakeSoft, Inc.       |      -- Harry Emerson Fosdick
["nm256.patch" (text/plain)]

diff -urN vanilla/linux-2.4.0-test1-ac7/drivers/sound/Makefile linux/drivers/sound/Makefile
--- vanilla/linux-2.4.0-test1-ac7/drivers/sound/Makefile	Wed May 31 09:05:53 2000
+++ linux/drivers/sound/Makefile	Fri Jun  2 05:09:42 2000
@@ -71,7 +71,7 @@
 obj-$(CONFIG_SOUND_MSNDCLAS)	+= msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)	+= msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)	+= vwsnd.o
-obj-$(CONFIG_SOUND_NM256)	+= nm256_audio.o ac97.o
+obj-$(CONFIG_SOUND_NM256)	+= nm256_audio.o ac97_codec.o
 obj-$(CONFIG_SOUND_ICH)		+= i810_audio.o ac97_codec.o
 obj-$(CONFIG_SOUND_SONICVIBES)	+= sonicvibes.o
 obj-$(CONFIG_SOUND_CMPCI)	+= cmpci.o
diff -urN vanilla/linux-2.4.0-test1-ac7/drivers/sound/nm256.h linux/drivers/sound/nm256.h
--- vanilla/linux-2.4.0-test1-ac7/drivers/sound/nm256.h	Mon Oct 25 11:26:52 1999
+++ linux/drivers/sound/nm256.h	Fri Jun  2 05:09:26 2000
@@ -1,7 +1,6 @@
 #ifndef _NM256_H_
 #define _NM256_H_
 
-#include "ac97.h"
 
 /* The revisions that we currently handle.  */
 enum nm256rev {
@@ -18,7 +17,7 @@
     /* Revision number */
     enum nm256rev rev;
 
-    struct ac97_hwint mdev;
+    struct ac97_codec ac97;
 
     /* Our audio device numbers. */
     int dev[2];
@@ -32,9 +31,6 @@
        these are the actual device numbers. */
     int dev_for_play;
     int dev_for_record;
-
-    /* The mixer device. */
-    int mixer_oss_dev;
 
     /* 
      * Can only be opened once for each operation.  These aren't set
diff -urN vanilla/linux-2.4.0-test1-ac7/drivers/sound/nm256_audio.c linux/drivers/sound/nm256_audio.c
--- vanilla/linux-2.4.0-test1-ac7/drivers/sound/nm256_audio.c	Tue Mar  7 16:40:24 2000
+++ linux/drivers/sound/nm256_audio.c	Fri Jun  2 05:09:26 2000
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pm.h>
+#include <linux/ac97_codec.h>
 #include "sound_config.h"
 #include "soundmodule.h"
 #include "nm256.h"
@@ -123,7 +124,7 @@
     struct nm256_info *card;
 
     for (card = nmcard_list; card != NULL; card = card->next_card)
-	if (card->mixer_oss_dev == dev)
+	if (card->ac97.dev_mixer == dev)
 	    return card;
 
     return NULL;
@@ -751,9 +752,9 @@
  */
 
 static int
-nm256_isReady (struct ac97_hwint *dev)
+nm256_isReady (struct ac97_codec *ac97)
 {
-    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
+    struct nm256_info *card = (struct nm256_info *)ac97->private_data;
     int t2 = 10;
     u32 testaddr;
     u16 testb;
@@ -781,48 +782,46 @@
 
 /*
  * Return the contents of the AC97 mixer register REG.  Returns a positive
- * value if successful, or a negative error code.
+ * value if successful, or zero.
  */
-static int
-nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg)
+static u16
+nm256_readAC97Reg (struct ac97_codec *ac97, u8 reg)
 {
-    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
+    struct nm256_info *card = (struct nm256_info *)ac97->private_data;
 
     if (card->magsig != NM_MAGIC_SIG) {
 	printk (KERN_ERR "NM256: Bad magic signature in readAC97Reg!\n");
-	return -EINVAL;
+	return 0;
     }
 
     if (reg < 128) {
 	int res;
 
-	nm256_isReady (dev);
+	nm256_isReady (ac97);
 	res = nm256_readPort16 (card, 2, card->mixer + reg);
 	/* Magic delay.  Bleah yucky.  */
         udelay (1000);
 	return res;
     }
-    else
-	return -EINVAL;
+    return 0;
 }
 
 /* 
  * Writes VALUE to AC97 mixer register REG.  Returns 0 if successful, or
  * a negative error code. 
  */
-static int
-nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value)
+static void
+nm256_writeAC97Reg (struct ac97_codec *ac97, u8 reg, u16 value)
 {
     unsigned long flags;
     int tries = 2;
     int done = 0;
     u32 base;
-
-    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
+    struct nm256_info *card = (struct nm256_info *)ac97->private_data;
 
     if (card->magsig != NM_MAGIC_SIG) {
 	printk (KERN_ERR "NM256: Bad magic signature in writeAC97Reg!\n");
-	return -EINVAL;
+	return;
     }
 
     base = card->mixer;
@@ -830,12 +829,12 @@
     save_flags (flags);
     cli ();
 
-    nm256_isReady (dev);
+    nm256_isReady (ac97);
 
     /* Wait for the write to take, too. */
     while ((tries-- > 0) && !done) {
 	nm256_writePort16 (card, 2, base + reg, value);
-	if (nm256_isReady (dev)) {
+	if (nm256_isReady (ac97)) {
 	    done = 1;
 	    break;
 	}
@@ -844,8 +843,6 @@
 
     restore_flags (flags);
     udelay (1000);
-
-    return ! done;
 }
 
 /* 
@@ -882,9 +879,9 @@
 
 /* Initialize the AC97 into a known state.  */
 static int
-nm256_resetAC97 (struct ac97_hwint *dev)
+nm256_resetAC97 (struct ac97_codec *ac97)
 {
-    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
+    struct nm256_info *card = (struct nm256_info *)ac97->private_data;
     int x;
 
     if (card->magsig != NM_MAGIC_SIG) {
@@ -900,7 +897,7 @@
 
     if (! card->mixer_values_init) {
 	for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) {
-	    ac97_put_register (dev,
+	    nm256_writeAC97Reg (ac97,
 			       nm256_ac97_initial_values[x].port,
 			       nm256_ac97_initial_values[x].value);
 	    card->mixer_values_init = 1;
@@ -910,40 +907,50 @@
     return 0;
 }
 
-/*
- * We don't do anything particularly special here; it just passes the
- * mixer ioctl to the AC97 driver.
- */
-static int
-nm256_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
+static int nm256_mixer_open (struct inode *inode, struct file *file)
 {
-    struct nm256_info *card = nm256_find_card_for_mixer (dev);
-    if (card != NULL)
-	return ac97_mixer_ioctl (&(card->mdev), cmd, arg);
-    else
+	int minor = MINOR(inode->i_rdev);
+	struct nm256_info *card;
+	
+	MOD_INC_USE_COUNT;
+
+	card = nm256_find_card_for_mixer (minor);
+	if (card)
+		goto match;
+
+	MOD_DEC_USE_COUNT;
 	return -ENODEV;
+
+match:
+	file->private_data = &card->ac97;
+	return 0;
 }
 
-static struct mixer_operations nm256_mixer_operations = {
-    "NeoMagic",
-    "NM256AC97Mixer",
-    nm256_default_mixer_ioctl
-};
+static int nm256_mixer_release (struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
 
-/*
- * Default settings for the OSS mixer.  These are set last, after the
- * mixer is initialized.
- *
- * I "love" C sometimes.  Got braces?
- */
-static struct ac97_mixer_value_list mixer_defaults[] = {
-    { SOUND_MIXER_VOLUME,  { { 85, 85 } } },
-    { SOUND_MIXER_SPEAKER, { { 100 } } },
-    { SOUND_MIXER_PCM,     { { 65, 65 } } },
-    { SOUND_MIXER_CD,      { { 65, 65 } } },
-    { -1,                  {  { 0,  0 } } }
-};
+static int nm256_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	struct ac97_codec *codec = file->private_data;
+
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
 
+static loff_t nm256_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static struct file_operations nm256_mixer_fops = {
+	open:		nm256_mixer_open,
+	release:	nm256_mixer_release,
+	llseek:		nm256_llseek,
+	ioctl:		nm256_mixer_ioctl,
+};
 
 /* Installs the AC97 mixer into CARD.  */
 static int
@@ -951,28 +958,36 @@
 {
     int mixer;
 
-    card->mdev.reset_device = nm256_resetAC97;
-    card->mdev.read_reg = nm256_readAC97Reg;
-    card->mdev.write_reg = nm256_writeAC97Reg;
-    card->mdev.driver_private = (void *)card;
-
-    if (ac97_init (&(card->mdev)))
-	return -1;
-
-    mixer = sound_alloc_mixerdev();
-    if (num_mixers >= MAX_MIXER_DEV) {
-	printk ("NM256 mixer: Unable to alloc mixerdev\n");
-	return -1;
+    memset (&card->ac97, 0, sizeof (card->ac97));
+    card->ac97.private_data = (void *)card;
+    card->ac97.codec_read = nm256_readAC97Reg;
+    card->ac97.codec_write = nm256_writeAC97Reg;
+    
+    mixer = register_sound_mixer (&nm256_mixer_fops, -1);
+    if (mixer < 0) {
+	printk (KERN_ERR "NM256 mixer: Unable to alloc mixerdev\n");
+	goto err_out;
+    }
+    
+    card->ac97.dev_mixer = mixer;
+    
+    if (nm256_resetAC97 (&card->ac97)) {
+	printk (KERN_ERR "NM256 mixer: Unable to reset AC97 codec\n");
+    	goto err_out_mixer;
+    }
+
+    if (!ac97_probe_codec(&card->ac97)) {
+	printk (KERN_ERR "NM256 mixer: Unable to probe AC97 codec\n");
+	goto err_out_mixer;
     }
 
-    mixer_devs[mixer] = &nm256_mixer_operations;
-    card->mixer_oss_dev = mixer;
-
-    /* Some reasonable default values.  */
-    ac97_set_values (&(card->mdev), mixer_defaults);
-
     printk(KERN_INFO "Initialized AC97 mixer\n");
     return 0;
+
+err_out_mixer:
+    unregister_sound_mixer (mixer);
+err_out:
+    return -1;
 }
 
 /* Perform a full reset on the hardware; this is invoked when an APM
@@ -981,7 +996,10 @@
 nm256_full_reset (struct nm256_info *card)
 {
     nm256_initHw (card);
-    ac97_reset (&(card->mdev));
+    
+    /* note! this depends on ac97_probe_codec not allocating
+     * or registering anything... */
+    ac97_probe_codec (&card->ac97);
 }
 
 /* 
@@ -1209,7 +1227,7 @@
      * And our mixer.  (We should allow support for other mixers, maybe.)
      */
 
-    nm256_install_mixer (card);
+    nm256_install_mixer (card); /* XXX check return value */
 
     pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), handle_pm_event);
     if (pmdev)
@@ -1265,12 +1283,16 @@
     while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC,
 				    PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO,
 				    pcidev)) != NULL) {
+	if (pci_enable_device(pcidev))
+		continue;
 	count += nm256_install(pcidev, REV_NM256AV, "256AV");
     }
 
     while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC,
 				    PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO,
 				    pcidev)) != NULL) {
+	if (pci_enable_device(pcidev))
+		continue;
 	count += nm256_install(pcidev, REV_NM256ZX, "256ZX");
     }
 
@@ -1675,7 +1697,7 @@
 	    if (card->has_irq)
 		free_irq (card->irq, card);
 	    nm256_release_ports (card);
-	    sound_unload_mixerdev (card->mixer_oss_dev);
+	    unregister_sound_mixer (card->ac97.dev_mixer);
 	    sound_unload_audiodev (card->dev[0]);
 	    sound_unload_audiodev (card->dev[1]);
 	    next_card = card->next_card;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic