Changes:
- esssolo1: recording might now work, also MIDI shouldn't cause the driver
to lock up hard
- es1371: (actually es1373) SPDIF output can now be enabled
- rest: module_init/__setup changes
Note: The makefiles-2.3.13 patch posted a moment ago to linux-kernel
is necessary for the drivers if built-in (modules work fine without)
Tom
--- drivers/sound/es1370.c 1999/08/10 11:13:08 0.26
+++ drivers/sound/es1370.c 1999/08/12 19:06:08
@@ -106,6 +106,7 @@
* 03.08.99 0.26 adapt to Linus' new __setup/__initcall
* added kernel command line option
"es1370=joystick[,lineout[,micbias]]"
* removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge
+ * 12.08.99 0.27 module_init/__setup fixes
*
* some important things missing in Ensoniq documentation:
*
@@ -1067,9 +1068,10 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >>
CTRL_SH_WTSRSEL];
+ tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2
+ / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
}
remove_wait_queue(&s->dma_dac1.wait, &wait);
@@ -1102,9 +1104,10 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >>
CTRL_SH_PCLKDIV);
+ tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2
+ / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV);
tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
}
remove_wait_queue(&s->dma_dac2.wait, &wait);
@@ -2300,6 +2303,16 @@
static int lineout[NR_DEVICE] = { 0, };
static int micbias[NR_DEVICE] = { 0, };
+MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate
+driver)");
+MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
+MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
+
+MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
+MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
+
/* --------------------------------------------------------------------- */
static struct initvol {
@@ -2318,10 +2331,7 @@
{ SOUND_MIXER_WRITE_OGAIN, 0x4040 }
};
-#ifndef MODULE
-static
-#endif
-int __init init_module(void)
+static int __init init_es1370(void)
{
struct es1370_state *s;
struct pci_dev *pcidev = NULL;
@@ -2330,7 +2340,7 @@
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "es1370: version v0.26 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1370: version v0.27 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE &&
(pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ,
PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) {
if (pcidev->resource[0].flags == 0 ||
@@ -2438,21 +2448,7 @@
return 0;
}
-/* --------------------------------------------------------------------- */
-
-#ifdef MODULE
-
-MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate
driver)");
-MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
-
-MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
-MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
-
-void cleanup_module(void)
+static void __exit cleanup_es1370(void)
{
struct es1370_state *s;
@@ -2472,7 +2468,12 @@
printk(KERN_INFO "es1370: unloading\n");
}
-#else /* MODULE */
+module_init(init_es1370);
+module_exit(cleanup_es1370);
+
+/* --------------------------------------------------------------------- */
+
+#ifndef MODULE
/* format is: es1370=[joystick[,lineout[,micbias]]] */
@@ -2493,6 +2494,5 @@
}
__setup("es1370=", es1370_setup);
-__initcall(init_module);
#endif /* MODULE */
--- drivers/sound/es1371.c 1999/08/10 11:13:46 0.14
+++ drivers/sound/es1371.c 1999/08/12 19:05:51
@@ -3,7 +3,7 @@
/*
* es1371.c -- Creative Ensoniq ES1371.
*
- * Copyright (C) 1998 Thomas Sailer ([EMAIL PROTECTED])
+ * Copyright (C) 1998-1999 Thomas Sailer ([EMAIL PROTECTED])
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -71,6 +71,9 @@
* 03.08.99 0.14 adapt to Linus' new __setup/__initcall
* added kernel command line option "es1371=joystickaddr"
* removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge
+ * 10.08.99 0.15 (Re)added S/PDIF module option for cards revision >= 4.
+ * Initial version by Dave Platt <[EMAIL PROTECTED]>.
+ * module_init/__setup fixes
*
*/
@@ -145,6 +148,7 @@
static const unsigned sample_size[] = { 1, 2, 2, 4 };
static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+#define CTRL_SPDIFEN_B 0x04000000
#define CTRL_JOY_SHIFT 24
#define CTRL_JOY_MASK 3
#define CTRL_JOY_200 0x00000000 /* joystick base address */
@@ -180,6 +184,9 @@
#define STAT_INTR 0x80000000 /* wired or of all interrupt bits */
+#define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */
+#define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */
+#define STAT_TESTMODE 0x00010000 /* test ASIC */
#define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */
#define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef
*/
#define STAT_SH_VC 6
@@ -1481,9 +1488,9 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / s->dac1rate;
+ tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;
tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
printk(KERN_DEBUG "es1371: dma timed out??\n");
}
remove_wait_queue(&s->dma_dac1.wait, &wait);
@@ -1516,9 +1523,9 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / s->dac2rate;
+ tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;
tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
printk(KERN_DEBUG "es1371: dma timed out??\n");
}
remove_wait_queue(&s->dma_dac2.wait, &wait);
@@ -2697,6 +2704,15 @@
#define NR_DEVICE 5
static int joystick[NR_DEVICE] = { 0, };
+static int spdif[NR_DEVICE] = { 0, };
+
+MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need
+separate driver)");
+MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
+
+MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
+MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
/* --------------------------------------------------------------------- */
@@ -2719,19 +2735,18 @@
{ SOUND_MIXER_WRITE_IGAIN, 0x4040 }
};
-#ifndef MODULE
-static
-#endif
-int __init init_module(void)
+static int __init init_es1371(void)
{
struct es1371_state *s;
struct pci_dev *pcidev = NULL;
mm_segment_t fs;
int i, val, val2, index = 0;
+ u8 revision;
+ unsigned cssr;
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "es1371: version v0.14 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1371: version v0.15 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE &&
(pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ,
PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) {
if (pcidev->resource[0].flags == 0 ||
@@ -2784,6 +2799,18 @@
}
}
s->sctrl = 0;
+ cssr = 0;
+ /* check to see if s/pdif mode is being requested */
+ pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision);
+ if (spdif[index]) {
+ if (revision >= 4) {
+ printk(KERN_INFO "es1371: enabling S/PDIF output\n");
+ cssr |= STAT_EN_SPDIF;
+ s->ctrl |= CTRL_SPDIFEN_B;
+ } else {
+ printk(KERN_ERR "es1371: revision %d does not support
+S/PDIF\n", revision);
+ }
+ }
/* initialize the chips */
outl(s->ctrl, s->io+ES1371_REG_CONTROL);
outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
@@ -2858,6 +2885,8 @@
mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
}
set_fs(fs);
+ /* turn on S/PDIF output driver if requested */
+ outl(cssr, s->io+ES1371_REG_STATUS);
/* queue it for later freeing */
s->next = devs;
devs = s;
@@ -2883,17 +2912,7 @@
return 0;
}
-/* --------------------------------------------------------------------- */
-
-#ifdef MODULE
-
-MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need
separate driver)");
-
-MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
-MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
-
-void cleanup_module(void)
+static void __exit cleanup_es1371(void)
{
struct es1371_state *s;
@@ -2913,23 +2932,27 @@
printk(KERN_INFO "es1371: unloading\n");
}
-#else /* MODULE */
+module_init(init_es1371);
+module_exit(cleanup_es1371);
+
+/* --------------------------------------------------------------------- */
+
+#ifndef MODULE
/* format is: es1371=[joystick] */
static int __init es1371_setup(char *str)
{
static unsigned __initdata nr_dev = 0;
- int ints[11];
if (nr_dev >= NR_DEVICE)
return 0;
- get_option(&str, &joystick[nr_dev]);
+ if (get_option(&str, &joystick[nr_dev]) == 2)
+ get_option(&str, &spdif[nr_dev]);
nr_dev++;
return 1;
}
__setup("es1371=", es1371_setup);
-__initcall(init_module);
#endif /* MODULE */
--- drivers/sound/sonicvibes.c 1999/08/10 11:14:09 0.17
+++ drivers/sound/sonicvibes.c 1999/08/12 19:06:41
@@ -73,6 +73,7 @@
* 28.06.99 0.16 Add pci_set_master
* 03.08.99 0.17 adapt to Linus' new __setup/__initcall
* added kernel command line options "sonicvibes=reverb" and
"sonicvibesdmaio=dmaioaddr"
+ * 12.08.99 0.18 module_init/__setup fixes
*
*/
@@ -1268,9 +1269,9 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / s->ratedac;
+ tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK];
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
printk(KERN_DEBUG "sv: dma timed out??\n");
}
remove_wait_queue(&s->dma_dac.wait, &wait);
@@ -2297,6 +2298,19 @@
static unsigned dmaio = 0xac00;
+MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must
+have the reverb RAM");
+#if 0
+MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
+#endif
+
+MODULE_PARM(dmaio, "i");
+MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate
+them starting at this address");
+
+MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
+MODULE_DESCRIPTION("S3 SonicVibes Driver");
+
/* --------------------------------------------------------------------- */
static struct initvol {
@@ -2314,10 +2328,7 @@
{ SOUND_MIXER_WRITE_PCM, 0x4040 }
};
-#ifndef MODULE
-static
-#endif
-int __init init_module(void)
+static int __init init_sonicvibes(void)
{
struct sv_state *s;
struct pci_dev *pcidev = NULL;
@@ -2326,7 +2337,7 @@
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "sv: version v0.17 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "sv: version v0.18 time " __TIME__ " " __DATE__ "\n");
#if 0
if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable
memory for wavetable data\n");
@@ -2499,24 +2510,7 @@
return 0;
}
-/* --------------------------------------------------------------------- */
-
-#ifdef MODULE
-
-MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must
have the reverb RAM");
-#if 0
-MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
-#endif
-
-MODULE_PARM(dmaio, "i");
-MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate
them starting at this address");
-
-MODULE_AUTHOR("Thomas M. Sailer, [EMAIL PROTECTED], [EMAIL PROTECTED]");
-MODULE_DESCRIPTION("S3 SonicVibes Driver");
-
-void cleanup_module(void)
+static void __exit cleanup_sonicvibes(void)
{
struct sv_state *s;
@@ -2545,7 +2539,12 @@
printk(KERN_INFO "sv: unloading\n");
}
-#else /* MODULE */
+module_init(init_sonicvibes);
+module_exit(cleanup_sonicvibes);
+
+/* --------------------------------------------------------------------- */
+
+#ifndef MODULE
/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */
@@ -2555,12 +2554,12 @@
if (nr_dev >= NR_DEVICE)
return 0;
-
- ( (get_option(&str, &reverb [nr_dev]) == 2)
#if 0
- && get_option(&str, &wavetable[nr_dev])
+ if (get_option(&str, &reverb[nr_dev]) == 2)
+ get_option(&str, &wavetable[nr_dev]);
+#else
+ get_option(&str, &reverb[nr_dev]);
#endif
- };
nr_dev++;
return 1;
@@ -2568,16 +2567,14 @@
static int __init sonicvibesdmaio_setup(char *str)
{
- int ints[11];
+ int io;
- get_options(str, ints);
- if (ints[0] >= 1)
- dmaio = ints[1];
+ if (get_option(&str, &io))
+ dmaio = io;
return 1;
}
__setup("sonicvibes=", sonicvibes_setup);
__setup("sonicvibesdmaio=", sonicvibesdmaio_setup);
-__initcall(init_module);
#endif /* MODULE */
--- drivers/sound/esssolo1.c 1999/08/10 11:14:43 0.5
+++ drivers/sound/esssolo1.c 1999/08/12 17:57:24
@@ -39,7 +39,21 @@
* 15.06.99 0.4 Fix bad allocation bug.
* Thanks to Deti Fliegl <[EMAIL PROTECTED]>
* 28.06.99 0.5 Add pci_set_master
- *
+ * 12.08.99 0.6 Fix MIDI UART crashing the driver
+ * Changed mixer semantics from OSS documented
+ * behaviour to OSS "code behaviour".
+ * Recording might actually work now.
+ * The real DDMA controller address register is at PCI config
+ * 0x60, while the register at 0x18 is used as a placeholder
+ * register for BIOS address allocation. This register
+ * is supposed to be copied into 0x60, according
+ * to the Solo1 datasheet. When I do that, I can access
+ * the DDMA registers except the mask bit, which
+ * is stuck at 1. When I copy the contents of 0x18 +0x10
+ * to the DDMA base register, everything seems to work.
+ * The fun part is that the Windows Solo1 driver doesn't
+ * seem to do these tricks.
+ * Bugs remaining: plops and clicks when starting/stopping
+playback
*
*/
@@ -69,6 +83,10 @@
/* --------------------------------------------------------------------- */
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+/* --------------------------------------------------------------------- */
+
#ifndef PCI_VENDOR_ID_ESS
#define PCI_VENDOR_ID_ESS 0x125d
#endif
@@ -78,9 +96,12 @@
#define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1)
+#define DDMABASE_OFFSET 0x10 /* chip bug workaround kludge */
+#define DDMABASE_EXTENT 16
+
#define IOBASE_EXTENT 16
#define SBBASE_EXTENT 16
-#define VCBASE_EXTENT 16
+#define VCBASE_EXTENT (DDMABASE_EXTENT+DDMABASE_OFFSET)
#define MPUBASE_EXTENT 4
#define GPBASE_EXTENT 4
@@ -98,16 +119,15 @@
/* --------------------------------------------------------------------- */
-#define DEBUGREC
-
-/* --------------------------------------------------------------------- */
-
struct solo1_state {
/* magic */
unsigned int magic;
- /* we keep sb cards in a linked list */
+ /* we keep the cards in a linked list */
struct solo1_state *next;
+
+ /* pcidev is needed to turn off the DDMA controller at driver shutdown */
+ struct pci_dev *pcidev;
/* soundcore stuff */
int dev_audio;
@@ -116,10 +136,10 @@
int dev_dmfm;
/* hardware resources */
- unsigned long iobase, sbbase, vcbase, mpubase, gpbase; /* long for SPARC */
+ unsigned long iobase, sbbase, vcbase, ddmabase, mpubase, gpbase; /* long for
+SPARC */
unsigned int irq;
- /* mixer registers; there is no HW readback */
+ /* mixer registers */
struct {
unsigned short vol[10];
unsigned int recsrc;
@@ -302,6 +322,8 @@
spin_lock_irqsave(&s->lock, flags);
if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) &&
s->dma_dac.ready) {
s->ena |= FMODE_WRITE;
+ write_mixer(s, 0x78, 0x12);
+ udelay(10);
write_mixer(s, 0x78, 0x13);
}
spin_unlock_irqrestore(&s->lock, flags);
@@ -326,47 +348,24 @@
&& s->dma_adc.ready) {
s->ena |= FMODE_READ;
write_ctrl(s, 0xb8, 0xf);
-#ifdef DEBUGREC
+#if 0
printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n",
(long)s->dma_adc.rawbuf);
printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(0, s->vcbase+0xd); /* master reset */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. clr)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(1, s->vcbase+0xf); /* mask */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. mask)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(0x54/*0x14*/, s->vcbase+0xb); /* DMA_MODE_READ |
DMA_MODE_AUTOINIT */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. wrmode)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outl(virt_to_bus(s->dma_adc.rawbuf), s->vcbase);
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. wrbase)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outw(s->dma_adc.dmasize-1, s->vcbase+4);
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. wrcnt)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(0, s->vcbase+0xf);
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x (a. clrmask)\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
+ inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase),
+inb(s->ddmabase+8));
#endif
+ outb(0, s->ddmabase+0xd); /* master reset */
+ outb(1, s->ddmabase+0xf); /* mask */
+ outb(0x54/*0x14*/, s->ddmabase+0xb); /* DMA_MODE_READ |
+DMA_MODE_AUTOINIT */
+ outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase);
+ outw(s->dma_adc.dmasize-1, s->ddmabase+4);
+ outb(0, s->ddmabase+0xf);
}
spin_unlock_irqrestore(&s->lock, flags);
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt:
0x%04x DMAmask: 0x%02x SBstat: 0x%02x\n",
- read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4),
inb(s->vcbase+0xf), inb(s->sbbase+0xc));
-
+#if 0
+ printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x SBstat: 0x%02x\n"
+ KERN_DEBUG "solo1: DMA: stat: 0x%02x cnt: 0x%04x mask: 0x%02x\n",
+ read_ctrl(s, 0xb8), inb(s->sbbase+0xc),
+ inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf));
printk(KERN_DEBUG "solo1: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8:
0x%02x\n"
KERN_DEBUG "solo1: B1: 0x%02x B2: 0x%02x B4: 0x%02x B7: 0x%02x B8:
0x%02x B9: 0x%02x\n",
read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4),
read_ctrl(s, 0xa5), read_ctrl(s, 0xa8),
@@ -456,16 +455,16 @@
va = virt_to_bus(s->dma_adc.rawbuf);
if ((va & ~((1<<24)-1)))
panic("solo1: buffer above 16M boundary");
- outb(0, s->vcbase+0xd); /* clear */
- outb(1, s->vcbase+0xf); /* mask */
- //outb(0, s->vcbase+8); /* enable (enable is active low!) */
- outb(0x54, s->vcbase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
- outl(va, s->vcbase);
- outw(s->dma_adc.dmasize-1, s->vcbase+4);
+ outb(0, s->ddmabase+0xd); /* clear */
+ outb(1, s->ddmabase+0xf); /* mask */
+ /*outb(0, s->ddmabase+8);*/ /* enable (enable is active low!) */
+ outb(0x54, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
+ outl(va, s->ddmabase);
+ outw(s->dma_adc.dmasize-1, s->ddmabase+4);
c = - s->dma_adc.fragsamples;
write_ctrl(s, 0xa4, c);
write_ctrl(s, 0xa5, c >> 8);
- outb(0, s->vcbase+0xf);
+ outb(0, s->ddmabase+0xf);
s->dma_adc.ready = 1;
return 0;
}
@@ -513,12 +512,12 @@
/* update ADC pointer */
if (s->ena & FMODE_READ) {
- hwptr = (s->dma_adc.dmasize - 1 - inw(s->vcbase+4)) %
s->dma_adc.dmasize;
+ hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) %
+s->dma_adc.dmasize;
diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) %
s->dma_adc.dmasize;
s->dma_adc.hwptr = hwptr;
s->dma_adc.total_bytes += diff;
s->dma_adc.count += diff;
-#ifdef DEBUGREC
+#if 0
printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n",
s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize,
s->dma_adc.count);
#endif
@@ -633,16 +632,28 @@
SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME,
SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0
};
- static const unsigned char mixtable[SOUND_MIXER_NRDEVICES] = {
- [SOUND_MIXER_PCM] = 0x7c, /* voice */
- [SOUND_MIXER_SYNTH] = 0x36, /* FM */
- [SOUND_MIXER_CD] = 0x38, /* CD */
- [SOUND_MIXER_LINE] = 0x3e, /* Line */
- [SOUND_MIXER_LINE1] = 0x3a, /* AUX */
- [SOUND_MIXER_MIC] = 0x1a, /* Mic */
- [SOUND_MIXER_LINE2] = 0x6d /* Mono in */
+ static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+ [SOUND_MIXER_PCM] = 1, /* voice */
+ [SOUND_MIXER_SYNTH] = 2, /* FM */
+ [SOUND_MIXER_CD] = 3, /* CD */
+ [SOUND_MIXER_LINE] = 4, /* Line */
+ [SOUND_MIXER_LINE1] = 5, /* AUX */
+ [SOUND_MIXER_MIC] = 6, /* Mic */
+ [SOUND_MIXER_LINE2] = 7, /* Mono in */
+ [SOUND_MIXER_SPEAKER] = 8, /* Speaker */
+ [SOUND_MIXER_RECLEV] = 9, /* Recording level */
+ [SOUND_MIXER_VOLUME] = 10 /* Master Volume */
};
- unsigned char l, r, rl, rr;
+ static const unsigned char mixreg[] = {
+ 0x7c, /* voice */
+ 0x36, /* FM */
+ 0x38, /* CD */
+ 0x3e, /* Line */
+ 0x3a, /* AUX */
+ 0x1a, /* Mic */
+ 0x6d /* Mono in */
+ };
+ unsigned char l, r, rl, rr, vidx;
int i, val;
VALIDATE_STATE(s);
@@ -657,16 +668,6 @@
val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
return put_user(val, (int *)arg);
}
- if (cmd == SOUND_MIXER_PRIVATE1) {
- /* enable/disable/query mixer preamp */
- get_user_ret(val, (int *)arg, -EFAULT);
- if (val != -1) {
- val = val ? 0xff : 0xf7;
- write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
- }
- val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
- return put_user(val, (int *)arg);
- }
if (cmd == SOUND_MIXER_PRIVATE2) {
/* enable/disable/query spatializer */
get_user_ret(val, (int *)arg, -EFAULT);
@@ -720,36 +721,11 @@
case SOUND_MIXER_CAPS:
return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
- case SOUND_MIXER_VOLUME:
- rl = read_mixer(s, 0x60);
- rr = read_mixer(s, 0x62);
- l = (rl * 3 + 11) / 2;
- if (rl & 0x40)
- l = 0;
- r = (rr * 3 + 11) / 2;
- if (rr & 0x40)
- r = 0;
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
-
- case SOUND_MIXER_SPEAKER:
- rl = read_mixer(s, 0x3c);
- l = (rl & 7) * 14 + 2;
- return put_user(l * 0x101, (int *)arg);
-
- case SOUND_MIXER_RECLEV:
- rl = read_ctrl(s, 0xb4);
- r = ((rl & 0xf) * 13 + 5) / 2;
- l = (((rl >> 4) & 0xf) * 13 + 5) / 2;
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
-
default:
i = _IOC_NR(cmd);
- if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i])
+ if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
return -EINVAL;
- rl = read_mixer(s, mixtable[i]);
- r = ((rl & 0xf) * 13 + 5) / 2;
- l = (((rl >> 4) & 0xf) * 13 + 5) / 2;
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
+ return put_user(s->mix.vol[vidx-1], (int *)arg);
}
}
if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
@@ -757,21 +733,21 @@
s->mix.modcnt++;
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-
- {
- static const unsigned char regs[] = {
- 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d,
0x7c
- };
- int i;
-
- for (i = 0; i < sizeof(regs); i++)
- printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n",
- regs[i], read_mixer(s, regs[i]));
- printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n",
- 0xb4, read_ctrl(s, 0xb4));
- }
-
- get_user_ret(val, (int *)arg, -EFAULT);
+#if 0
+ {
+ static const unsigned char regs[] = {
+ 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62,
+0x6d, 0x7c
+ };
+ int i;
+
+ for (i = 0; i < sizeof(regs); i++)
+ printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n",
+ regs[i], read_mixer(s, regs[i]));
+ printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n",
+ 0xb4, read_ctrl(s, 0xb4));
+ }
+#endif
+ get_user_ret(val, (int *)arg, -EFAULT);
i = hweight32(val);
if (i == 0)
return 0;
@@ -810,7 +786,12 @@
}
write_mixer(s, 0x60, rl);
write_mixer(s, 0x62, rr);
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[9] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[9] = val;
+#endif
+ return put_user(s->mix.vol[9], (int *)arg);
case SOUND_MIXER_SPEAKER:
get_user_ret(val, (int *)arg, -EFAULT);
@@ -822,7 +803,12 @@
rl = (l - 2) / 14;
l = rl * 14 + 2;
write_mixer(s, 0x3c, rl);
- return put_user(l * 0x101, (int *)arg);
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[7] = l * 0x101;
+#else
+ s->mix.vol[7] = val;
+#endif
+ return put_user(s->mix.vol[7], (int *)arg);
case SOUND_MIXER_RECLEV:
get_user_ret(val, (int *)arg, -EFAULT);
@@ -841,11 +827,16 @@
r = (rl * 13 + 5) / 2;
l = (rr * 13 + 5) / 2;
write_ctrl(s, 0xb4, (rl << 4) | rr);
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[8] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[8] = val;
+#endif
+ return put_user(s->mix.vol[8], (int *)arg);
default:
i = _IOC_NR(cmd);
- if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i])
+ if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
return -EINVAL;
get_user_ret(val, (int *)arg, -EFAULT);
l = (val << 1) & 0x1fe;
@@ -862,8 +853,13 @@
rr = (r - 5) / 13;
r = (rl * 13 + 5) / 2;
l = (rr * 13 + 5) / 2;
- write_mixer(s, mixtable[i], (rl << 4) | rr);
- return put_user((((unsigned int)r) << 8) | l, (int *)arg);
+ write_mixer(s, mixreg[vidx-1], (rl << 4) | rr);
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[vidx-1] = val;
+#endif
+ return put_user(s->mix.vol[vidx-1], (int *)arg);
}
}
@@ -919,10 +915,8 @@
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
-#if 0
NULL, /* revalidate */
NULL, /* lock */
-#endif
};
/* --------------------------------------------------------------------- */
@@ -931,7 +925,8 @@
{
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
- int count, tmo;
+ int count;
+ unsigned tmo;
if (s->dma_dac.mapped)
return 0;
@@ -950,12 +945,12 @@
current->state = TASK_RUNNING;
return -EBUSY;
}
- tmo = (count * HZ) / s->rate;
+ tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
tmo >>= 1;
if (s->channels > 1)
tmo >>= 1;
- if (!schedule_timeout(tmo ? : 1) && tmo)
+ if (!schedule_timeout(tmo + 1))
printk(KERN_DEBUG "solo1: dma timed out??\n");
}
remove_wait_queue(&s->dma_dac.wait, &wait);
@@ -996,7 +991,7 @@
cnt = count;
#ifdef DEBUGREC
printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x
DMAcnt: 0x%04x SBstat: 0x%02x cnt: %u\n",
- read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4),
inb(s->sbbase+0xc), cnt);
+ read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4),
+inb(s->sbbase+0xc), cnt);
#endif
if (cnt <= 0) {
start_adc(s);
@@ -1007,12 +1002,10 @@
KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n",
read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s,
0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8),
read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s,
0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9),
- inl(s->vcbase), inw(s->vcbase+4), inb(s->vcbase+8),
inb(s->vcbase+15), inb(s->sbbase+0xc), cnt);
+ inl(s->ddmabase), inw(s->ddmabase+4),
+inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
#endif
- if (inb(s->vcbase+15) & 1) {
+ if (inb(s->ddmabase+15) & 1)
printk(KERN_ERR "solo1: cannot start recording, DDMA
mask bit stuck at 1\n");
- return -EIO;
- }
if (file->f_flags & O_NONBLOCK)
return ret ? ret : -EAGAIN;
interruptible_sleep_on(&s->dma_adc.wait);
@@ -1023,7 +1016,7 @@
KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n",
read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s,
0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8),
read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s,
0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9),
- inl(s->vcbase), inw(s->vcbase+4), inb(s->vcbase+8),
inb(s->vcbase+15), inb(s->sbbase+0xc), cnt);
+ inl(s->ddmabase), inw(s->ddmabase+4),
+inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
#endif
if (signal_pending(current))
return ret ? ret : -ERESTARTSYS;
@@ -1042,7 +1035,7 @@
start_adc(s);
#ifdef DEBUGREC
printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x
DMAcnt: 0x%04x SBstat: 0x%02x\n",
- read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4),
inb(s->sbbase+0xc));
+ read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4),
+inb(s->sbbase+0xc));
#endif
}
return ret;
@@ -1304,7 +1297,7 @@
if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
return ret;
start_adc(s);
- if (inb(s->vcbase+15) & 1)
+ if (inb(s->ddmabase+15) & 1)
printk(KERN_ERR "solo1: cannot start
recording, DDMA mask bit stuck at 1\n");
} else
stop_adc(s);
@@ -1466,8 +1459,8 @@
}
if (file->f_mode & FMODE_READ) {
stop_adc(s);
- outb(1, s->vcbase+0xf); /* mask DMA channel */
- //outb(0, s->vcbase+0xd); /* DMA master clear */
+ outb(1, s->ddmabase+0xf); /* mask DMA channel */
+ outb(0, s->ddmabase+0xd); /* DMA master clear */
dealloc_dmabuf(&s->dma_adc);
}
s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
@@ -1533,10 +1526,8 @@
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
-#if 0
NULL, /* revalidate */
NULL, /* lock */
-#endif
};
/* --------------------------------------------------------------------- */
@@ -1550,7 +1541,7 @@
if (!(s->mpubase))
return;
wake = 0;
- while (inb(s->mpubase+1) & 0x80) {
+ while (!(inb(s->mpubase+1) & 0x80)) {
ch = inb(s->mpubase);
if (s->midi.icnt < MIDIINBUF) {
s->midi.ibuf[s->midi.iwr] = ch;
@@ -1562,7 +1553,7 @@
if (wake)
wake_up(&s->midi.iwait);
wake = 0;
- while ((inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) {
+ while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) {
outb(s->midi.obuf[s->midi.ord], s->mpubase);
s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
s->midi.ocnt--;
@@ -1577,22 +1568,12 @@
{
struct solo1_state *s = (struct solo1_state *)dev_id;
unsigned int intsrc;
-
- static unsigned lim = 0;
/* fastpath out, to ease interrupt sharing */
intsrc = inb(s->iobase+7); /* get interrupt source(s) */
if (!intsrc)
return;
(void)inb(s->sbbase+0xe); /* clear interrupt */
-#ifdef DEBUGREC
- if (intsrc & 0x10 && lim < 20) {
- lim++;
- printk(KERN_DEBUG "solo1: audio1int reg B8: 0x%02x DMAstat: 0x%02x
DMAcnt: 0x%04x SBstat: 0x%02x\n",
- read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4),
inb(s->sbbase+0xc));
- }
- //printk(KERN_DEBUG "solo1: interrupt 0x%02x\n", intsrc);
-#endif
spin_lock(&s->lock);
/* clear audio interrupts first */
if (intsrc & 0x20)
@@ -1849,10 +1830,8 @@
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
-#if 0
NULL, /* revalidate */
NULL, /* lock */
-#endif
};
/* --------------------------------------------------------------------- */
@@ -2025,10 +2004,8 @@
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
-#if 0
NULL, /* revalidate */
NULL, /* lock */
-#endif
};
/* --------------------------------------------------------------------- */
@@ -2060,11 +2037,10 @@
struct pci_dev *pcidev = NULL;
mm_segment_t fs;
int i, val, index = 0;
- u16 ddmabase;
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "solo1: version v0.5 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "solo1: version v0.6 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE &&
(pcidev = pci_find_device(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1,
pcidev))) {
if (pcidev->resource[0].start == 0 ||
@@ -2090,35 +2066,32 @@
init_waitqueue_head(&s->midi.owait);
init_MUTEX(&s->open_sem);
s->magic = SOLO1_MAGIC;
+ s->pcidev = pcidev;
s->iobase = pcidev->resource[0].start;
s->sbbase = pcidev->resource[1].start;
s->vcbase = pcidev->resource[2].start;
+ s->ddmabase = s->vcbase + DDMABASE_OFFSET;
s->mpubase = pcidev->resource[3].start;
s->gpbase = pcidev->resource[4].start;
s->irq = pcidev->irq;
if (check_region(s->iobase, IOBASE_EXTENT) ||
check_region(s->sbbase, SBBASE_EXTENT) ||
- check_region(s->vcbase, VCBASE_EXTENT) ||
+ check_region(s->ddmabase, DDMABASE_EXTENT) ||
check_region(s->mpubase, MPUBASE_EXTENT)) {
printk(KERN_ERR "solo1: io ports in use\n");
goto err_region;
}
request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1");
request_region(s->sbbase, SBBASE_EXTENT, "ESS Solo1");
- request_region(s->vcbase, VCBASE_EXTENT, "ESS Solo1");
+ request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1");
request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1");
if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) {
printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
goto err_irq;
}
/* initialize DDMA base address */
- /* use PCI config reg, and not vcbase, we need the bus view */
- pci_read_config_word(pcidev, 0x18, &ddmabase);
- pci_write_config_word(pcidev, 0x60, (ddmabase & (~0xf)) | 1);
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
+ printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
+ pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
/* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now)
*/
pci_write_config_dword(pcidev, 0x50, 0);
/* disable legacy audio address decode */
@@ -2147,21 +2120,9 @@
write_mixer(s, 0x52, 0);
write_mixer(s, 0x14, 0); /* DAC1 minimum volume */
write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(0, s->vcbase+0xd); /* DMA master clear */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- outb(1, s->vcbase+0xf); /* mask channel */
-#ifdef DEBUGREC
- printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x
stat: 0x%02x\n",
- inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase),
inb(s->vcbase+8));
-#endif
- //outb(0, s->vcbase+0x8); /* enable controller (enable is low
active!!) */
+ outb(0, s->ddmabase+0xd); /* DMA master clear */
+ outb(1, s->ddmabase+0xf); /* mask channel */
+ /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low
+active!!) */
pci_set_master(pcidev); /* enable bus mastering */
@@ -2173,6 +2134,8 @@
val = initvol[i].vol;
mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
}
+ val = 1; /* enable mic preamp */
+ mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
set_fs(fs);
/* queue it for later freeing */
s->next = devs;
@@ -2192,7 +2155,7 @@
err_irq:
release_region(s->iobase, IOBASE_EXTENT);
release_region(s->sbbase, SBBASE_EXTENT);
- release_region(s->vcbase, VCBASE_EXTENT);
+ release_region(s->ddmabase, DDMABASE_EXTENT);
release_region(s->mpubase, MPUBASE_EXTENT);
err_region:
kfree_s(s, sizeof(struct solo1_state));
@@ -2215,13 +2178,14 @@
devs = devs->next;
/* stop DMA controller */
outb(0, s->iobase+6);
- outb(0, s->vcbase+0xd); /* DMA master clear */
+ outb(0, s->ddmabase+0xd); /* DMA master clear */
outb(3, s->sbbase+6); /* reset sequencer and FIFO */
synchronize_irq();
+ pci_write_config_word(s->pcidev, 0x60, 0); /* turn off DDMA controller
+address space */
free_irq(s->irq, s);
release_region(s->iobase, IOBASE_EXTENT);
release_region(s->sbbase, SBBASE_EXTENT);
- release_region(s->vcbase, VCBASE_EXTENT);
+ release_region(s->ddmabase, DDMABASE_EXTENT);
release_region(s->mpubase, MPUBASE_EXTENT);
unregister_sound_dsp(s->dev_audio);
unregister_sound_mixer(s->dev_mixer);