patch-2.4.0-test7 linux/drivers/sound/emu10k1/main.c
Next file: linux/drivers/sound/emu10k1/midi.c
Previous file: linux/drivers/sound/emu10k1/irqmgr.h
Back to the patch index
Back to the overall index
- Lines: 959
- Date:
Mon Aug 14 08:32:48 2000
- Orig file:
v2.4.0-test6/linux/drivers/sound/emu10k1/main.c
- Orig date:
Fri Jun 23 21:55:10 2000
diff -u --recursive --new-file v2.4.0-test6/linux/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
@@ -1,4 +1,3 @@
-
/*
**********************************************************************
* main.c - Creative EMU10K1 audio driver
@@ -42,24 +41,35 @@
* 0.4 Added rear-channel, SPDIF support.
* 0.5 Source cleanup, SMP fixes, multiopen support, 64 bit arch fixes,
* moved bh's to tasklets, moved to the new PCI driver initialization style.
+ * 0.6 Make use of pci_alloc_consistent, improve compatibility layer for 2.2 kernels,
+ * code reorganization and cleanup.
+ * 0.7 Support for the Emu-APS. Bug fixes for voice cache setup, mmaped sound + poll().
+ * Support for setting external TRAM size.
+ *
**********************************************************************
*/
/* These are only included once per module */
+#include <linux/version.h>
#include <linux/module.h>
+#include <linux/malloc.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include "hwaccess.h"
+#include "8010.h"
#include "efxmgr.h"
#include "cardwo.h"
#include "cardwi.h"
#include "cardmo.h"
#include "cardmi.h"
#include "recmgr.h"
+#include "ecard.h"
-#define DRIVER_VERSION "0.5"
+#define DRIVER_VERSION "0.7"
/* FIXME: is this right? */
+/* does the card support 32 bit bus master?*/
#define EMU10K1_DMA_MASK 0xffffffff /* DMA buffer mask for pci_alloc_consist */
#ifndef PCI_VENDOR_ID_CREATIVE
@@ -70,8 +80,8 @@
#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
#endif
-#define EMU10K1_EXTENT 0x20 /* 32 byte I/O space */
-
+#define EMU_APS_SUBID 0x40011102
+
enum {
EMU10K1 = 0,
};
@@ -80,7 +90,7 @@
"EMU10K1",
};
-static struct pci_device_id emu10k1_pci_tbl[] __devinitdata = {
+static struct pci_device_id emu10k1_pci_tbl[] = {
{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_EMU10K1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, EMU10K1},
{0,}
@@ -99,32 +109,38 @@
extern void emu10k1_interrupt(int, void *, struct pt_regs *s);
extern int emu10k1_mixer_wrch(struct emu10k1_card *, unsigned int, int);
-static int __devinit audio_init(struct emu10k1_card *card)
+static void __devinit audio_init(struct emu10k1_card *card)
{
- if ((card->waveout = kmalloc(sizeof(struct emu10k1_waveout), GFP_KERNEL)) == NULL) {
- printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_waveout: out of memory\n");
- return CTSTATUS_ERROR;
- }
- memset(card->waveout, 0, sizeof(struct emu10k1_waveout));
-
- /* Assign default global volume, reverb, chorus */
- card->waveout->globalvol = 0xffffffff;
- card->waveout->left = 0xffff;
- card->waveout->right = 0xffff;
- card->waveout->mute = 0;
- card->waveout->globalreverb = 0xffffffff;
- card->waveout->globalchorus = 0xffffffff;
+ /* Assign default playback voice parameters */
+ /* mono voice */
+ card->waveout.send_a[0] = 0x00;
+ card->waveout.send_b[0] = 0xff;
+ card->waveout.send_c[0] = 0xff;
+ card->waveout.send_d[0] = 0x00;
+ card->waveout.send_routing[0] = 0xd01c;
+
+ /* stereo voice */
+ card->waveout.send_a[1] = 0x00;
+ card->waveout.send_b[1] = 0xff;
+ card->waveout.send_c[1] = 0x00;
+ card->waveout.send_d[1] = 0x00;
+ card->waveout.send_routing[1] = 0xd01c;
+
+ card->waveout.send_a[2] = 0x00;
+ card->waveout.send_b[2] = 0x00;
+ card->waveout.send_c[2] = 0xff;
+ card->waveout.send_d[2] = 0x00;
+ card->waveout.send_routing[2] = 0xd01c;
+
+ /* Assign default recording parameters */
+ if(card->isaps)
+ card->wavein.recsrc = WAVERECORD_FX;
+ else
+ card->wavein.recsrc = WAVERECORD_AC97;
- if ((card->wavein = kmalloc(sizeof(struct emu10k1_wavein), GFP_KERNEL))
- == NULL) {
- printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_wavein: out of memory\n");
- return CTSTATUS_ERROR;
- }
- memset(card->wavein, 0, sizeof(struct emu10k1_wavein));
+ card->wavein.fxwc = 0x0003;
- card->wavein->recsrc = WAVERECORD_AC97;
-
- return CTSTATUS_SUCCESS;
+ return;
}
static void __devinit mixer_init(struct emu10k1_card *card)
@@ -141,61 +157,64 @@
SOUND_MIXER_PHONEIN, 0x3232}, {
SOUND_MIXER_MIC, 0x0000}, {
SOUND_MIXER_LINE, 0x0000}, {
- SOUND_MIXER_CD, 0x3232}, {
- SOUND_MIXER_LINE1, 0x3232}, {
+ SOUND_MIXER_CD, 0x4b4b}, {
+ SOUND_MIXER_LINE1, 0x4b4b}, {
SOUND_MIXER_LINE3, 0x3232}, {
SOUND_MIXER_DIGITAL1, 0x6464}, {
SOUND_MIXER_DIGITAL2, 0x6464}, {
SOUND_MIXER_PCM, 0x6464}, {
- SOUND_MIXER_RECLEV, 0x3232}, {
+ SOUND_MIXER_RECLEV, 0x0404}, {
SOUND_MIXER_TREBLE, 0x3232}, {
SOUND_MIXER_BASS, 0x3232}, {
- SOUND_MIXER_LINE2, 0x4b4b}};
+ SOUND_MIXER_LINE2, 0x4b4b}};
- int initdig[] = { 0, 1, 2, 3, 6, 7, 16, 17, 18, 19, 22, 23, 64, 65, 66, 67, 70, 71,
- 84, 85
+ int initdig[] = { 0, 1, 2, 3, 6, 7, 18, 19, 20, 21, 24, 25, 72, 73, 74, 75, 78, 79,
+ 94, 95
};
- /* Reset */
- sblive_writeac97(card, AC97_RESET, 0);
-
-#if 0
- /* Check status word */
- {
- u16 reg;
-
- sblive_readac97(card, AC97_RESET, ®);
- DPD(2, "RESET 0x%x\n", reg);
- sblive_readac97(card, AC97_MASTERTONE, ®);
- DPD(2, "MASTER_TONE 0x%x\n", reg);
+ for (count = 0; count < sizeof(card->digmix) / sizeof(card->digmix[0]); count++) {
+ card->digmix[count] = 0x80000000;
+ sblive_writeptr(card, FXGPREGBASE + 0x10 + count, 0, 0);
}
-#endif
- /* Set default recording source to mic in */
- sblive_writeac97(card, AC97_RECORDSELECT, 0);
+ card->modcnt = 0; // Should this be here or in open() ?
- /* Set default AC97 "PCM" volume to acceptable max */
- //sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
- //sblive_writeac97(card, AC97_LINE2, 0);
+ if (!card->isaps) {
- /* Set default volumes for all mixer channels */
+ for (count = 0; count < sizeof(initdig) / sizeof(initdig[0]); count++) {
+ card->digmix[initdig[count]] = 0x7fffffff;
+ sblive_writeptr(card, FXGPREGBASE + 0x10 + initdig[count], 0, 0x7fffffff);
+ }
- for (count = 0; count < sizeof(card->digmix) / sizeof(card->digmix[0]); count++) {
- card->digmix[count] = 0x80000000;
- sblive_writeptr(card, FXGPREGBASE + 0x10 + count, 0, 0);
- }
+ /* Reset */
+ sblive_writeac97(card, AC97_RESET, 0);
- for (count = 0; count < sizeof(initdig) / sizeof(initdig[0]); count++) {
- card->digmix[initdig[count]] = 0x7fffffff;
- sblive_writeptr(card, FXGPREGBASE + 0x10 + initdig[count], 0, 0x7fffffff);
+#if 0
+ /* Check status word */
+ {
+ u16 reg;
+
+ sblive_readac97(card, AC97_RESET, ®);
+ DPD(2, "RESET 0x%x\n", reg);
+ sblive_readac97(card, AC97_MASTERTONE, ®);
+ DPD(2, "MASTER_TONE 0x%x\n", reg);
+ }
+#endif
+
+ /* Set default recording source to mic in */
+ sblive_writeac97(card, AC97_RECORDSELECT, 0);
+
+ /* Set default AC97 "PCM" volume to acceptable max */
+ //sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
+ //sblive_writeac97(card, AC97_LINE2, 0);
}
+ /* Set default volumes for all mixer channels */
+
for (count = 0; count < sizeof(initvol) / sizeof(initvol[0]); count++) {
emu10k1_mixer_wrch(card, initvol[count].mixch, initvol[count].vol);
}
- card->modcnt = 0; // Should this be here or in open() ?
-
return;
}
@@ -204,7 +223,7 @@
if ((card->mpuout = kmalloc(sizeof(struct emu10k1_mpuout), GFP_KERNEL))
== NULL) {
printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuout: out of memory\n");
- return CTSTATUS_ERROR;
+ return -1;
}
memset(card->mpuout, 0, sizeof(struct emu10k1_mpuout));
@@ -220,7 +239,7 @@
if ((card->mpuin = kmalloc(sizeof(struct emu10k1_mpuin), GFP_KERNEL)) == NULL) {
kfree(card->mpuout);
printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuin: out of memory\n");
- return CTSTATUS_ERROR;
+ return -1;
}
memset(card->mpuin, 0, sizeof(struct emu10k1_mpuin));
@@ -232,31 +251,20 @@
spin_lock_init(&card->mpuin->lock);
/* Reset the MPU port */
- if (emu10k1_mpu_reset(card) != CTSTATUS_SUCCESS) {
+ if (emu10k1_mpu_reset(card) < 0) {
ERROR();
- return CTSTATUS_ERROR;
+ return -1;
}
- return CTSTATUS_SUCCESS;
+ return 0;
}
static void __devinit voice_init(struct emu10k1_card *card)
{
- struct voice_manager *voicemgr = &card->voicemgr;
- struct emu_voice *voice;
int i;
- voicemgr->card = card;
- voicemgr->lock = SPIN_LOCK_UNLOCKED;
-
- voice = voicemgr->voice;
- for (i = 0; i < NUM_G; i++) {
- voice->card = card;
- voice->usage = VOICEMGR_USAGE_FREE;
- voice->num = i;
- voice->linked_voice = NULL;
- voice++;
- }
+ for (i = 0; i < NUM_G; i++)
+ card->voicetable[i] = VOICE_USAGE_FREE;
return;
}
@@ -280,21 +288,27 @@
/* Mark first page as used */
/* This page is reserved by the driver */
card->emupagetable[0] = 0x8001;
- card->emupagetable[1] = MAXPAGES - RESERVED - 1;
+ card->emupagetable[1] = MAXPAGES - 1;
return;
}
static void __devinit fx_init(struct emu10k1_card *card)
{
- int i, j, k, l;
+ int i, j, k;
+#ifdef TONE_CONTROL
+ int l;
+#endif
u32 pc = 0;
for (i = 0; i < 512; i++)
OP(6, 0x40, 0x40, 0x40, 0x40);
for (i = 0; i < 256; i++)
- sblive_writeptr(card, FXGPREGBASE + i, 0, 0);
+ sblive_writeptr_tag(card, 0,
+ FXGPREGBASE + i, 0,
+ TANKMEMADDRREGBASE + i, 0,
+ TAGLIST_END);
pc = 0;
@@ -304,7 +318,7 @@
OP(4, 0x101, 0x40, j + 2, 0x44);
for (i = 0; i < 6; i++) {
- k = i * 16 + j;
+ k = i * 18 + j;
OP(0, 0x102, 0x40, 0x110 + k, 0x100);
OP(0, 0x102, 0x102, 0x112 + k, 0x101);
OP(0, 0x102, 0x102, 0x114 + k, 0x10 + j);
@@ -313,25 +327,32 @@
OP(0, 0x102, 0x102, 0x11a + k, 0x16 + j);
OP(0, 0x102, 0x102, 0x11c + k, 0x18 + j);
OP(0, 0x102, 0x102, 0x11e + k, 0x1a + j);
+#ifdef TONE_CONTROL
+ OP(0, 0x102, 0x102, 0x120 + k, 0x1c + j);
- k = 0x190 + i * 8 + j * 4;
- OP(0, 0x40, 0x40, 0x102, 0x170 + j);
- OP(7, k + 1, k, k + 1, 0x174 + j);
- OP(7, k, 0x102, k, 0x172 + j);
- OP(7, k + 3, k + 2, k + 3, 0x178 + j);
- OP(0, k + 2, 0x56, k + 2, 0x176 + j);
+ k = 0x1a0 + i * 8 + j * 4;
+ OP(0, 0x40, 0x40, 0x102, 0x180 + j);
+ OP(7, k + 1, k, k + 1, 0x184 + j);
+ OP(7, k, 0x102, k, 0x182 + j);
+ OP(7, k + 3, k + 2, k + 3, 0x188 + j);
+ OP(0, k + 2, 0x56, k + 2, 0x186 + j);
OP(6, k + 2, k + 2, k + 2, 0x40);
- l = 0x1c0 + i * 8 + j * 4;
- OP(0, 0x40, 0x40, k + 2, 0x180 + j);
- OP(7, l + 1, l, l + 1, 0x184 + j);
- OP(7, l, k + 2, l, 0x182 + j);
- OP(7, l + 3, l + 2, l + 3, 0x188 + j);
- OP(0, l + 2, 0x56, l + 2, 0x186 + j);
+ l = 0x1d0 + i * 8 + j * 4;
+ OP(0, 0x40, 0x40, k + 2, 0x190 + j);
+ OP(7, l + 1, l, l + 1, 0x194 + j);
+ OP(7, l, k + 2, l, 0x192 + j);
+ OP(7, l + 3, l + 2, l + 3, 0x198 + j);
+ OP(0, l + 2, 0x56, l + 2, 0x196 + j);
OP(4, l + 2, 0x40, l + 2, 0x46);
- OP(6, 0x20 + (i * 2) + j, l + 2, 0x40, 0x40);
-
+ if ((i == 0) && !card->isaps)
+ OP(4, 0x20 + (i * 2) + j, 0x40, l + 2, 0x50); /* FIXME: Is this really needed? */
+ else
+ OP(6, 0x20 + (i * 2) + j, l + 2, 0x40, 0x40);
+#else
+ OP(0, 0x20 + (i * 2) + j, 0x102, 0x120 + k, 0x1c + j);
+#endif
}
}
sblive_writeptr(card, DBG, 0, 0);
@@ -342,63 +363,64 @@
static int __devinit hw_init(struct emu10k1_card *card)
{
int nCh;
-
-#ifdef TANKMEM
- u32 size = 0;
-#endif
- u32 sizeIdx = 0;
- u32 pagecount, tmp;
+ u32 pagecount; /* tmp */
/* Disable audio and lock cache */
- sblive_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE);
+ emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
/* Reset recording buffers */
- sblive_writeptr(card, MICBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, MICBA, 0, 0);
- sblive_writeptr(card, FXBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, FXBA, 0, 0);
- sblive_writeptr(card, ADCBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, ADCBA, 0, 0);
+ sblive_writeptr_tag(card, 0,
+ MICBS, ADCBS_BUFSIZE_NONE,
+ MICBA, 0,
+ FXBS, ADCBS_BUFSIZE_NONE,
+ FXBA, 0,
+ ADCBS, ADCBS_BUFSIZE_NONE,
+ ADCBA, 0,
+ TAGLIST_END);
/* Disable channel interrupt */
- sblive_writefn0(card, INTE, DISABLE);
- sblive_writeptr(card, CLIEL, 0, 0);
- sblive_writeptr(card, CLIEH, 0, 0);
- sblive_writeptr(card, SOLEL, 0, 0);
- sblive_writeptr(card, SOLEH, 0, 0);
+ emu10k1_writefn0(card, INTE, 0);
+ sblive_writeptr_tag(card, 0,
+ CLIEL, 0,
+ CLIEH, 0,
+ SOLEL, 0,
+ SOLEH, 0,
+ TAGLIST_END);
/* Init envelope engine */
for (nCh = 0; nCh < NUM_G; nCh++) {
- sblive_writeptr(card, DCYSUSV, nCh, ENV_OFF);
- sblive_writeptr(card, IP, nCh, 0);
- sblive_writeptr(card, VTFT, nCh, 0xffff);
- sblive_writeptr(card, CVCF, nCh, 0xffff);
- sblive_writeptr(card, PTRX, nCh, 0);
- sblive_writeptr(card, CPF, nCh, 0);
- sblive_writeptr(card, CCR, nCh, 0);
-
- sblive_writeptr(card, PSST, nCh, 0);
- sblive_writeptr(card, DSL, nCh, 0x10);
- sblive_writeptr(card, CCCA, nCh, 0);
- sblive_writeptr(card, Z1, nCh, 0);
- sblive_writeptr(card, Z2, nCh, 0);
- sblive_writeptr(card, FXRT, nCh, 0xd01c0000);
-
- sblive_writeptr(card, ATKHLDM, nCh, 0);
- sblive_writeptr(card, DCYSUSM, nCh, 0);
- sblive_writeptr(card, IFATN, nCh, 0xffff);
- sblive_writeptr(card, PEFE, nCh, 0);
- sblive_writeptr(card, FMMOD, nCh, 0);
- sblive_writeptr(card, TREMFRQ, nCh, 24); /* 1 Hz */
- sblive_writeptr(card, FM2FRQ2, nCh, 24); /* 1 Hz */
- sblive_writeptr(card, TEMPENV, nCh, 0);
-
- /*** These are last so OFF prevents writing ***/
- sblive_writeptr(card, LFOVAL2, nCh, 0);
- sblive_writeptr(card, LFOVAL1, nCh, 0);
- sblive_writeptr(card, ATKHLDV, nCh, 0);
- sblive_writeptr(card, ENVVOL, nCh, 0);
- sblive_writeptr(card, ENVVAL, nCh, 0);
+ sblive_writeptr_tag(card, nCh,
+ DCYSUSV, 0,
+ IP, 0,
+ VTFT, 0xffff,
+ CVCF, 0xffff,
+ PTRX, 0,
+ CPF, 0,
+ CCR, 0,
+
+ PSST, 0,
+ DSL, 0x10,
+ CCCA, 0,
+ Z1, 0,
+ Z2, 0,
+ FXRT, 0xd01c0000,
+
+ ATKHLDM, 0,
+ DCYSUSM, 0,
+ IFATN, 0xffff,
+ PEFE, 0,
+ FMMOD, 0,
+ TREMFRQ, 24, /* 1 Hz */
+ FM2FRQ2, 24, /* 1 Hz */
+ TEMPENV, 0,
+
+ /*** These are last so OFF prevents writing ***/
+ LFOVAL2, 0,
+ LFOVAL1, 0,
+ ATKHLDV, 0,
+ ENVVOL, 0,
+ ENVVAL, 0,
+ TAGLIST_END);
}
/*
@@ -416,73 +438,57 @@
** P = 0 (Consumer)
*/
- /* SPDIF0 */
- sblive_writeptr(card, SPCS0, 0, SPCS_CLKACCY_1000PPM | 0x002000000 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
-
- /* SPDIF1 */
- sblive_writeptr(card, SPCS1, 0, SPCS_CLKACCY_1000PPM | 0x002000000 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
-
- /* SPDIF2 & SPDIF3 */
- sblive_writeptr(card, SPCS2, 0, SPCS_CLKACCY_1000PPM | 0x002000000 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+ sblive_writeptr_tag(card, 0,
- fx_init(card); /* initialize effects engine */
+ /* SPDIF0 */
+ SPCS0, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+ SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
- card->tankmem = NULL;
+ /* SPDIF1 */
+ SPCS1, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+ SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
-#ifdef TANKMEM
- size = TMEMSIZE;
- sizeIdx = TMEMSIZEREG;
- while (size > 16384) {
- if ((card->tankmem = emu10k1_alloc_memphysical(size)) != NULL)
- break;
+ /* SPDIF2 & SPDIF3 */
+ SPCS2, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+ SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
- size /= 2;
- sizeIdx -= 1;
- }
+ TAGLIST_END);
- if (card->tankmem == NULL) {
- card->tmemsize = 0;
- return CTSTATUS_ERROR;
- }
+ fx_init(card); /* initialize effects engine */
+
+ card->tankmem.size = 0;
- card->tmemsize = size;
-#else /* !TANKMEM */
- card->tmemsize = 0;
-#endif /* TANKMEM */
+ card->virtualpagetable.size = MAXPAGES * sizeof(u32);
- if ((card->virtualpagetable = emu10k1_alloc_memphysical((MAXPAGES - RESERVED) * sizeof(u32))) == NULL) {
+ if ((card->virtualpagetable.addr = pci_alloc_consistent(card->pci_dev, card->virtualpagetable.size, &card->virtualpagetable.dma_handle)) ==
+ NULL) {
ERROR();
- emu10k1_free_memphysical(card->tankmem);
- return CTSTATUS_ERROR;
+ return -1;
}
- if ((card->silentpage = emu10k1_alloc_memphysical(EMUPAGESIZE)) == NULL) {
- ERROR();
- emu10k1_free_memphysical(card->tankmem);
- emu10k1_free_memphysical(card->virtualpagetable);
- return CTSTATUS_ERROR;
- } else
- memset(card->silentpage->virtaddx, 0, EMUPAGESIZE);
+ card->silentpage.size = EMUPAGESIZE;
- for (pagecount = 0; pagecount < (MAXPAGES - RESERVED); pagecount++)
+ if ((card->silentpage.addr = pci_alloc_consistent(card->pci_dev, card->silentpage.size, &card->silentpage.dma_handle)) == NULL) {
+ ERROR();
+ pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
+ return -1;
+ }
- ((u32 *) card->virtualpagetable->virtaddx)[pagecount] = (card->silentpage->busaddx * 2) | pagecount;
+ for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
+ ((u32 *) card->virtualpagetable.addr)[pagecount] = (card->silentpage.dma_handle * 2) | pagecount;
/* Init page table & tank memory base register */
- sblive_writeptr(card, PTB, 0, card->virtualpagetable->busaddx);
-#ifdef TANKMEM
- sblive_writeptr(card, TCB, 0, card->tankmem->busaddx);
-#else
- sblive_writeptr(card, TCB, 0, 0);
-#endif
- sblive_writeptr(card, TCBS, 0, sizeIdx);
+ sblive_writeptr_tag(card, 0,
+ PTB, card->virtualpagetable.dma_handle,
+ TCB, 0,
+ TCBS, 0,
+ TAGLIST_END);
for (nCh = 0; nCh < NUM_G; nCh++) {
- sblive_writeptr(card, MAPA, nCh, MAP_PTI_MASK | (card->silentpage->busaddx * 2));
- sblive_writeptr(card, MAPB, nCh, MAP_PTI_MASK | (card->silentpage->busaddx * 2));
+ sblive_writeptr_tag(card, nCh,
+ MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+ MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+ TAGLIST_END);
}
/* Hokay, now enable the AUD bit */
@@ -497,12 +503,16 @@
sblive_writeac97(card, AC97_MASTERVOLUME, 0);
sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
- sblive_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE | HCFG_JOYENABLE);
+ if(card->model == 0x20 || card->model == 0xc400 ||
+ (card->model == 0x21 && card->chiprev < 6))
+ emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE);
+ else
+ emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE);
- /* TOSLink detection */
+ /* FIXME: TOSLink detection */
card->has_toslink = 0;
- tmp = sblive_readfn0(card, HCFG);
+/* tmp = sblive_readfn0(card, HCFG);
if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
sblive_writefn0(card, HCFG, tmp | 0x800);
@@ -513,30 +523,23 @@
sblive_writefn0(card, HCFG, tmp);
}
}
-
- return CTSTATUS_SUCCESS;
+*/
+ return 0;
}
static int __devinit emu10k1_init(struct emu10k1_card *card)
{
/* Init Card */
- if (hw_init(card) != CTSTATUS_SUCCESS)
- return CTSTATUS_ERROR;
+ if (hw_init(card) < 0)
+ return -1;
voice_init(card);
timer_init(card);
addxmgr_init(card);
- DPD(2, " hw control register -> %x\n", sblive_readfn0(card, HCFG));
-
- return CTSTATUS_SUCCESS;
-}
+ DPD(2, " hw control register -> 0x%x\n", emu10k1_readfn0(card, HCFG));
-static void __devexit audio_exit(struct emu10k1_card *card)
-{
- kfree(card->waveout);
- kfree(card->wavein);
- return;
+ return 0;
}
static void __devexit midi_exit(struct emu10k1_card *card)
@@ -550,50 +553,57 @@
return;
}
-static void __devexit emu10k1_exit(struct emu10k1_card *card)
+static void __devinit emu10k1_exit(struct emu10k1_card *card)
{
int ch;
- sblive_writefn0(card, INTE, DISABLE);
+ emu10k1_writefn0(card, INTE, 0);
/** Shutdown the chip **/
for (ch = 0; ch < NUM_G; ch++)
- sblive_writeptr(card, DCYSUSV, ch, ENV_OFF);
+ sblive_writeptr(card, DCYSUSV, ch, 0);
for (ch = 0; ch < NUM_G; ch++) {
- sblive_writeptr(card, VTFT, ch, 0);
- sblive_writeptr(card, CVCF, ch, 0);
- sblive_writeptr(card, PTRX, ch, 0);
- sblive_writeptr(card, CPF, ch, 0);
+ sblive_writeptr_tag(card, ch,
+ VTFT, 0,
+ CVCF, 0,
+ PTRX, 0,
+ CPF, 0,
+ TAGLIST_END);
}
- /* Reset recording buffers */
- sblive_writeptr(card, MICBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, MICBA, 0, 0);
- sblive_writeptr(card, FXBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, FXBA, 0, 0);
- sblive_writeptr(card, FXWC, 0, 0);
- sblive_writeptr(card, ADCBS, 0, ADCBS_BUFSIZE_NONE);
- sblive_writeptr(card, ADCBA, 0, 0);
- sblive_writeptr(card, TCBS, 0, TCBS_BUFFSIZE_16K);
- sblive_writeptr(card, TCB, 0, 0);
- sblive_writeptr(card, DBG, 0, 0x8000);
+ /* Disable audio and lock cache */
+ emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
- /* Disable channel interrupt */
- sblive_writeptr(card, CLIEL, 0, 0);
- sblive_writeptr(card, CLIEH, 0, 0);
- sblive_writeptr(card, SOLEL, 0, 0);
- sblive_writeptr(card, SOLEH, 0, 0);
+ sblive_writeptr_tag(card, 0,
+ PTB, 0,
- /* Disable audio and lock cache */
- sblive_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE);
- sblive_writeptr(card, PTB, 0, 0);
+ /* Reset recording buffers */
+ MICBS, ADCBS_BUFSIZE_NONE,
+ MICBA, 0,
+ FXBS, ADCBS_BUFSIZE_NONE,
+ FXBA, 0,
+ FXWC, 0,
+ ADCBS, ADCBS_BUFSIZE_NONE,
+ ADCBA, 0,
+ TCBS, 0,
+ TCB, 0,
+ DBG, 0x8000,
+
+ /* Disable channel interrupt */
+ CLIEL, 0,
+ CLIEH, 0,
+ SOLEL, 0,
+ SOLEH, 0,
+ TAGLIST_END);
+
+
+ pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
+ pci_free_consistent(card->pci_dev, card->silentpage.size, card->silentpage.addr, card->silentpage.dma_handle);
+
+ if(card->tankmem.size != 0)
+ pci_free_consistent(card->pci_dev, card->tankmem.size, card->tankmem.addr, card->tankmem.dma_handle);
- emu10k1_free_memphysical(card->silentpage);
- emu10k1_free_memphysical(card->virtualpagetable);
-#ifdef TANKMEM
- emu10k1_free_memphysical(card->tankmem);
-#endif
return;
}
@@ -601,6 +611,7 @@
static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
{
struct emu10k1_card *card;
+ u32 subsysvid;
if ((card = kmalloc(sizeof(struct emu10k1_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "emu10k1: out of memory\n");
@@ -608,7 +619,6 @@
}
memset(card, 0, sizeof(struct emu10k1_card));
-#if LINUX_VERSION_CODE > 0x020320
if (!pci_dma_supported(pci_dev, EMU10K1_DMA_MASK)) {
printk(KERN_ERR "emu10k1: architecture does not support 32bit PCI busmaster DMA\n");
kfree(card);
@@ -623,27 +633,17 @@
pci_set_master(pci_dev);
card->iobase = pci_resource_start(pci_dev, 0);
+ card->length = pci_resource_len(pci_dev, 0);
- if (request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]) == NULL) {
+ if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
printk(KERN_ERR "emu10k1: IO space in use\n");
kfree(card);
return -ENODEV;
}
- pci_dev->driver_data = card;
- pci_dev->dma_mask = EMU10K1_DMA_MASK;
-#else
- pci_set_master(pci_dev);
-
- card->iobase = pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
- if (check_region(card->iobase, EMU10K1_EXTENT)) {
- printk(KERN_ERR "emu10k1: IO space in use\n");
- kfree(card);
- return -ENODEV;
- }
+ PCI_SET_DRIVER_DATA(pci_dev, card);
+ PCI_SET_DMA_MASK(pci_dev, EMU10K1_DMA_MASK);
- request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]);
-#endif
card->irq = pci_dev->irq;
card->pci_dev = pci_dev;
@@ -654,22 +654,27 @@
}
pci_read_config_byte(pci_dev, PCI_REVISION_ID, &card->chiprev);
+ pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &card->model);
+
+ printk(KERN_INFO "emu10k1: %s rev %d model 0x%x found, IO at 0x%04lx-0x%04lx, IRQ %d\n",
+ card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
+ card->iobase + card->length - 1, card->irq);
- printk(KERN_INFO "emu10k1: %s rev %d found at IO 0x%04lx, IRQ %d\n", card_names[pci_id->driver_data], card->chiprev, card->iobase, card->irq);
+ pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
+ card->isaps = (subsysvid == EMU_APS_SUBID);
spin_lock_init(&card->lock);
- card->mixeraddx = card->iobase + AC97DATA;
init_MUTEX(&card->open_sem);
card->open_mode = 0;
init_waitqueue_head(&card->open_wait);
/* Register devices */
- if ((card->audio1_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
+ if ((card->audio_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
printk(KERN_ERR "emu10k1: cannot register first audio device!\n");
goto err_dev0;
}
- if ((card->audio2_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
+ if ((card->audio1_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
printk(KERN_ERR "emu10k1: cannot register second audio device!\n");
goto err_dev1;
}
@@ -684,33 +689,27 @@
goto err_dev3;
}
- if (emu10k1_init(card) != CTSTATUS_SUCCESS) {
+ if (emu10k1_init(card) < 0) {
printk(KERN_ERR "emu10k1: cannot initialize device!\n");
goto err_emu10k1_init;
}
- if (audio_init(card) != CTSTATUS_SUCCESS) {
- printk(KERN_ERR "emu10k1: cannot initialize audio!\n");
- goto err_audio_init;
- }
-
- if (midi_init(card) != CTSTATUS_SUCCESS) {
+ if (midi_init(card) < 0) {
printk(KERN_ERR "emu10k1: cannot initialize midi!\n");
goto err_midi_init;
}
+ audio_init(card);
mixer_init(card);
- DPD(2, "Hardware initialized. TRAM allocated: %u bytes\n", (unsigned int) card->tmemsize);
+ if (card->isaps)
+ emu10k1_ecard_init(card);
list_add(&card->list, &emu10k1_devs);
return 0;
err_midi_init:
- audio_exit(card);
-
- err_audio_init:
emu10k1_exit(card);
err_emu10k1_init:
@@ -720,16 +719,16 @@
unregister_sound_mixer(card->mixer_num);
err_dev2:
- unregister_sound_dsp(card->audio2_num);
+ unregister_sound_dsp(card->audio1_num);
err_dev1:
- unregister_sound_dsp(card->audio1_num);
+ unregister_sound_dsp(card->audio_num);
err_dev0:
free_irq(card->irq, card);
err_irq:
- release_region(card->iobase, EMU10K1_EXTENT);
+ release_region(card->iobase, card->length);
kfree(card);
return -ENODEV;
@@ -737,26 +736,25 @@
static void __devexit emu10k1_remove(struct pci_dev *pci_dev)
{
-#if LINUX_VERSION_CODE > 0x020320
- struct emu10k1_card *card = pci_dev->driver_data;
-#else
- struct emu10k1_card *card = list_entry(emu10k1_devs.next, struct emu10k1_card, list);
-#endif
+ struct emu10k1_card *card = PCI_GET_DRIVER_DATA(pci_dev);
+
midi_exit(card);
- audio_exit(card);
emu10k1_exit(card);
unregister_sound_midi(card->midi_num);
+
unregister_sound_mixer(card->mixer_num);
- unregister_sound_dsp(card->audio2_num);
+
unregister_sound_dsp(card->audio1_num);
+ unregister_sound_dsp(card->audio_num);
free_irq(card->irq, card);
- release_region(card->iobase, EMU10K1_EXTENT);
+ release_region(card->iobase, card->length);
list_del(&card->list);
kfree(card);
+
return;
}
@@ -770,7 +768,6 @@
remove:emu10k1_remove,
};
-#if LINUX_VERSION_CODE > 0x020320
static int __init emu10k1_init_module(void)
{
printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
@@ -781,44 +778,9 @@
static void __exit emu10k1_cleanup_module(void)
{
pci_unregister_driver(&emu10k1_pci_driver);
- return;
-}
-
-#else
-
-static int __init emu10k1_init_module(void)
-{
- struct pci_dev *dev = NULL;
- const struct pci_device_id *pci_id = emu10k1_pci_driver.id_table;
-
- printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
-
- if (!pci_present())
- return -ENODEV;
-
- while (pci_id->vendor) {
- while ((dev = pci_find_device(pci_id->vendor, pci_id->device, dev)))
- emu10k1_probe(dev, pci_id);
-
- pci_id++;
- }
- return 0;
-}
-
-static void __exit emu10k1_cleanup_module(void)
-{
- struct emu10k1_card *card;
-
- while (!list_empty(&emu10k1_devs)) {
- card = list_entry(emu10k1_devs.next, struct emu10k1_card, list);
-
- emu10k1_remove(card->pci_dev);
- }
return;
}
-
-#endif
module_init(emu10k1_init_module);
module_exit(emu10k1_cleanup_module);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)