patch-2.2.18 linux/drivers/sound/emu10k1/main.c
Next file: linux/drivers/sound/emu10k1/midi.c
Previous file: linux/drivers/sound/emu10k1/hwaccess.h
Back to the patch index
Back to the overall index
- Lines: 339
- Date:
Mon Sep 11 17:07:42 2000
- Orig file:
v2.2.17/drivers/sound/emu10k1/main.c
- Orig date:
Sat Sep 9 18:42:43 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
@@ -43,6 +43,9 @@
* 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.
+ *
**********************************************************************
*/
@@ -61,8 +64,9 @@
#include "cardmo.h"
#include "cardmi.h"
#include "recmgr.h"
+#include "ecard.h"
-#define DRIVER_VERSION "0.6"
+#define DRIVER_VERSION "0.7"
/* FIXME: is this right? */
/* does the card support 32 bit bus master?*/
@@ -76,6 +80,8 @@
#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
#endif
+#define EMU_APS_SUBID 0x40011102
+
enum {
EMU10K1 = 0,
};
@@ -103,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 -1;
- }
- 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;
-
- 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 -1;
- }
- memset(card->wavein, 0, sizeof(struct emu10k1_wavein));
+ /* 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] = 0x00;
+ card->waveout.send_c[1] = 0xff;
+ card->waveout.send_d[1] = 0x00;
+ card->waveout.send_routing[1] = 0xd01c;
+
+ card->waveout.send_a[2] = 0x00;
+ card->waveout.send_b[2] = 0xff;
+ card->waveout.send_c[2] = 0x00;
+ 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;
- card->wavein->recsrc = WAVERECORD_AC97;
+ card->wavein.fxwc = 0x0003;
- return 0;
+ return;
}
static void __devinit mixer_init(struct emu10k1_card *card)
@@ -160,46 +172,49 @@
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);
+
+#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);
- for (count = 0; count < sizeof(initdig) / sizeof(initdig[0]); count++) {
- card->digmix[initdig[count]] = 0x7fffffff;
- sblive_writeptr(card, FXGPREGBASE + 0x10 + initdig[count], 0, 0x7fffffff);
+ /* 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;
}
@@ -236,7 +251,7 @@
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 -1;
}
@@ -280,7 +295,10 @@
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++)
@@ -309,6 +327,7 @@
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 = 0x1a0 + i * 8 + j * 4;
@@ -327,10 +346,13 @@
OP(0, l + 2, 0x56, l + 2, 0x196 + j);
OP(4, l + 2, 0x40, l + 2, 0x46);
- if (i == 0)
- OP(0, 0x20 + (i * 2) + j, 0x40, l + 2, 0x4e); /* FIXME: Is this really needed? */
+ 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);
@@ -482,7 +504,7 @@
sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
if(card->model == 0x20 || card->model == 0xc400 ||
- (card->model == 0x21 && card->chiprev <= 3))
+ (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);
@@ -520,13 +542,6 @@
return 0;
}
-static void __devinit audio_exit(struct emu10k1_card *card)
-{
- kfree(card->waveout);
- kfree(card->wavein);
- return;
-}
-
static void __devexit midi_exit(struct emu10k1_card *card)
{
tasklet_unlock_wait(&card->mpuout->tasklet);
@@ -596,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");
@@ -644,18 +660,21 @@
card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
card->iobase + card->length - 1, card->irq);
+ pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
+ card->isaps = (subsysvid == EMU_APS_SUBID);
+
spin_lock_init(&card->lock);
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;
}
@@ -675,26 +694,22 @@
goto err_emu10k1_init;
}
- if (audio_init(card) < 0) {
- printk(KERN_ERR "emu10k1: cannot initialize audio!\n");
- goto err_audio_init;
- }
-
if (midi_init(card) < 0) {
printk(KERN_ERR "emu10k1: cannot initialize midi!\n");
goto err_midi_init;
}
+ audio_init(card);
mixer_init(card);
+ 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:
@@ -704,10 +719,10 @@
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);
@@ -724,13 +739,14 @@
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, card->length);
@@ -772,6 +788,6 @@
#ifndef MODULE
int __init init_emu10k1(void)
{
- return emu10k1_init_module();
+ return emu10k1_init_module();
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)