lkml.org 
[lkml]   [2001]   [May]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectPATCH 2.4.4: nm256 audio use ac97_codec
Attached is a patch against 2.4.4 which updates nm256_audio driver to
use the newer, and maintained, ac97 codec driver.

I'm interested in feedback and testing on this patch -- there should be
_no_ change in behavior. If nm256 worked before, it should work now.
If nm256 didn't work before, it probably will remain broken after this
patch. [there is a slight chance this patch fixes problems, though....]

Note this patch includes changes found in the 'ac' tree, notably Marcus'
update to the new PCI API.

--
Jeff Garzik | Game called on account of naked chick
Building 1024 |
MandrakeSoft |diff -urN linux-2.4.4/drivers/sound/Makefile linux-nm/drivers/sound/Makefile
--- linux-2.4.4/drivers/sound/Makefile Fri Apr 13 23:26:07 2001
+++ linux-nm/drivers/sound/Makefile Thu May 3 15:25:10 2001
@@ -54,7 +54,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 linux-2.4.4/drivers/sound/nm256.h linux-nm/drivers/sound/nm256.h
--- linux-2.4.4/drivers/sound/nm256.h Mon Dec 11 16:02:32 2000
+++ linux-nm/drivers/sound/nm256.h Thu May 3 15:22:42 2001
@@ -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 linux-2.4.4/drivers/sound/nm256_audio.c linux-nm/drivers/sound/nm256_audio.c
--- linux-2.4.4/drivers/sound/nm256_audio.c Sat Nov 11 21:33:14 2000
+++ linux-nm/drivers/sound/nm256_audio.c Thu May 3 15:22:42 2001
@@ -15,6 +15,8 @@
* Changes:
* 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
* Added some __init
+ * 19-04-2001 Marcus Meissner <mm@caldera.de>
+ * Ported to 2.4 PCI API.
*/

#define __NO_VERSION__
@@ -23,6 +25,8 @@
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/delay.h>
+#include <linux/soundcard.h>
+#include <linux/ac97_codec.h>
#include "sound_config.h"
#include "nm256.h"
#include "nm256_coeff.h"
@@ -49,8 +53,6 @@
#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006

-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
-
/* List of cards. */
static struct nm256_info *nmcard_list;

@@ -125,7 +127,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;
@@ -753,9 +755,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;
@@ -783,48 +785,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;
@@ -832,12 +832,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;
}
@@ -846,8 +846,6 @@

restore_flags (flags);
udelay (1000);
-
- return ! done;
}

/*
@@ -884,9 +882,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) {
@@ -902,7 +900,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;
@@ -912,41 +910,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 = {
- owner: THIS_MODULE,
- id: "NeoMagic",
- name: "NM256AC97Mixer",
- ioctl: 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 __init
@@ -954,28 +961,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
@@ -984,7 +999,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);
}

/*
@@ -1042,6 +1060,9 @@
struct pm_dev *pmdev;
int x;

+ if (pci_enable_device(pcidev))
+ return 0;
+
card = kmalloc (sizeof (struct nm256_info), GFP_KERNEL);
if (card == NULL) {
printk (KERN_ERR "NM256: out of memory!\n");
@@ -1055,7 +1076,7 @@

/* Init the memory port info. */
for (x = 0; x < 2; x++) {
- card->port[x].physaddr = RSRCADDRESS (pcidev, x);
+ card->port[x].physaddr = pci_resource_start (pcidev, x);
card->port[x].ptr = NULL;
card->port[x].start_offset = 0;
card->port[x].end_offset = 0;
@@ -1201,6 +1222,8 @@
}
}

+ pci_set_drvdata(pcidev,card);
+
/* Insert the card in the list. */
card->next_card = nmcard_list;
nmcard_list = card;
@@ -1212,7 +1235,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)
@@ -1251,37 +1274,38 @@
return 0;
}

-/*
- * This loop walks the PCI configuration database and finds where
- * the sound cards are.
- */
-
-int __init
-init_nm256(void)
+static int __devinit
+nm256_probe(struct pci_dev *pcidev,const struct pci_device_id *pciid)
{
- struct pci_dev *pcidev = NULL;
- int count = 0;
-
- if(! pci_present())
- return -ENODEV;
-
- while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC,
- PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO,
- pcidev)) != NULL) {
- count += nm256_install(pcidev, REV_NM256AV, "256AV");
- }
-
- while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC,
- PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO,
- pcidev)) != NULL) {
- count += nm256_install(pcidev, REV_NM256ZX, "256ZX");
+ if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO)
+ return nm256_install(pcidev, REV_NM256AV, "256AV");
+ if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO)
+ return nm256_install(pcidev, REV_NM256ZX, "256ZX");
+ return -1; /* should not come here ... */
+}
+
+static void __devinit
+nm256_remove(struct pci_dev *pcidev) {
+ struct nm256_info *xcard = pci_get_drvdata(pcidev);
+ struct nm256_info *card,*next_card = NULL;
+
+ for (card = nmcard_list; card != NULL; card = next_card) {
+ next_card = card->next_card;
+ if (card == xcard) {
+ stopPlay (card);
+ stopRecord (card);
+ if (card->has_irq)
+ free_irq (card->irq, card);
+ nm256_release_ports (card);
+ unregister_sound_mixer (card->ac97.dev_mixer);
+ sound_unload_audiodev (card->dev[0]);
+ sound_unload_audiodev (card->dev[1]);
+ kfree (card);
+ break;
+ }
}
-
- if (count == 0)
- return -ENODEV;
-
- printk (KERN_INFO "Done installing NM256 audio driver.\n");
- return 0;
+ if (nmcard_list == card)
+ nmcard_list = next_card;
}

/*
@@ -1639,9 +1663,21 @@
local_qlen: nm256_audio_local_qlen,
};

-EXPORT_SYMBOL(init_nm256);
+static struct pci_device_id nm256_pci_tbl[] __devinitdata = {
+ {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0},
+ {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0},
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, nm256_pci_tbl);

-static int loaded = 0;
+struct pci_driver nm256_pci_driver = {
+ name:"nm256_audio",
+ id_table:nm256_pci_tbl,
+ probe:nm256_probe,
+ remove:nm256_remove,
+};

MODULE_PARM (usecache, "i");
MODULE_PARM (buffertop, "i");
@@ -1650,37 +1686,13 @@

static int __init do_init_nm256(void)
{
- nmcard_list = NULL;
- printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1\n");
-
- if (init_nm256 () == 0) {
- loaded = 1;
- return 0;
- }
- else
- return -ENODEV;
+ printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");
+ return pci_module_init(&nm256_pci_driver);
}

static void __exit cleanup_nm256 (void)
{
- if (loaded) {
- struct nm256_info *card;
- struct nm256_info *next_card;
-
- for (card = nmcard_list; card != NULL; card = next_card) {
- stopPlay (card);
- stopRecord (card);
- if (card->has_irq)
- free_irq (card->irq, card);
- nm256_release_ports (card);
- sound_unload_mixerdev (card->mixer_oss_dev);
- sound_unload_audiodev (card->dev[0]);
- sound_unload_audiodev (card->dev[1]);
- next_card = card->next_card;
- kfree (card);
- }
- nmcard_list = NULL;
- }
+ pci_unregister_driver(&nm256_pci_driver);
pm_unregister_all (&handle_pm_event);
}
\
 
 \ /
  Last update: 2005-03-22 12:52    [W:0.026 / U:2.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site