patch-2.4.4 linux/drivers/sound/es1371.c
Next file: linux/drivers/sound/esssolo1.c
Previous file: linux/drivers/sound/es1370.c
Back to the patch index
Back to the overall index
- Lines: 373
- Date:
Thu Apr 12 12:16:36 2001
- Orig file:
v2.4.3/linux/drivers/sound/es1371.c
- Orig date:
Tue Mar 20 12:04:58 2001
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
@@ -3,7 +3,7 @@
/*
* es1371.c -- Creative Ensoniq ES1371.
*
- * Copyright (C) 1998-2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Copyright (C) 1998-2001 Thomas Sailer (t.sailer@alumni.ethz.ch)
*
* 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
@@ -102,6 +102,13 @@
* 01.03.2000 0.26 SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
* Use pci_module_init
* 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask
+ * 12.12.2000 0.28 More dma buffer initializations, patch from
+ * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
+ * 05.01.2001 0.29 Hopefully updates will not be required anymore when Creative bumps
+ * the CT5880 revision.
+ * suggested by Stephan Müller <smueller@chronox.de>
+ * 31.01.2001 0.30 Register/Unregister gameport
+ * Fix SETTRIGGER non OSS API conformity
*/
/*****************************************************************************/
@@ -129,6 +136,23 @@
#include <asm/uaccess.h>
#include <asm/hardirq.h>
+#if defined(CONFIG_INPUT_ANALOG) || defined(CONFIG_INPUT_ANALOG_MODULE)
+#include <linux/gameport.h>
+#else
+struct gameport {
+ int io;
+ int size;
+};
+
+extern inline void gameport_register_port(struct gameport *gameport)
+{
+}
+
+extern inline void gameport_unregister_port(struct gameport *gameport)
+{
+}
+#endif
+
/* --------------------------------------------------------------------- */
#undef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -168,6 +192,7 @@
#define ES1371REV_ES1373_B 0x06
#define ES1371REV_CT5880_A 0x07
#define CT5880REV_CT5880_C 0x02
+#define CT5880REV_CT5880_D 0x03
#define ES1371REV_ES1371_B 0x09
#define EV1938REV_EV1938_A 0x00
#define ES1371REV_ES1373_8 0x08
@@ -432,6 +457,7 @@
unsigned mapped:1;
unsigned ready:1;
unsigned endcleared:1;
+ unsigned enabled:1;
unsigned ossfragshift;
int ossmaxfrags;
unsigned subdivision;
@@ -446,6 +472,8 @@
unsigned char ibuf[MIDIINBUF];
unsigned char obuf[MIDIOUTBUF];
} midi;
+
+ struct gameport gameport;
};
/* --------------------------------------------------------------------- */
@@ -932,6 +960,7 @@
outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
outl(db->dmaaddr, s->io+(reg & 0xff));
outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
+ db->enabled = 1;
db->ready = 1;
return 0;
}
@@ -1351,7 +1380,8 @@
if (cnt > count)
cnt = count;
if (cnt <= 0) {
- start_adc(s);
+ if (s->dma_adc.enabled)
+ start_adc(s);
if (file->f_flags & O_NONBLOCK) {
if (!ret)
ret = -EAGAIN;
@@ -1378,7 +1408,8 @@
count -= cnt;
buffer += cnt;
ret += cnt;
- start_adc(s);
+ if (s->dma_adc.enabled)
+ start_adc(s);
}
remove_wait_queue(&s->dma_adc.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1421,7 +1452,8 @@
if (cnt > count)
cnt = count;
if (cnt <= 0) {
- start_dac2(s);
+ if (s->dma_dac2.enabled)
+ start_dac2(s);
if (file->f_flags & O_NONBLOCK) {
if (!ret)
ret = -EAGAIN;
@@ -1449,7 +1481,8 @@
count -= cnt;
buffer += cnt;
ret += cnt;
- start_dac2(s);
+ if (s->dma_dac2.enabled)
+ start_dac2(s);
}
remove_wait_queue(&s->dma_dac2.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1700,25 +1733,31 @@
if (val & PCM_ENABLE_INPUT) {
if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
return ret;
+ s->dma_adc.enabled = 1;
start_adc(s);
- } else
+ } else {
+ s->dma_adc.enabled = 0;
stop_adc(s);
+ }
}
if (file->f_mode & FMODE_WRITE) {
if (val & PCM_ENABLE_OUTPUT) {
if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
return ret;
+ s->dma_dac2.enabled = 1;
start_dac2(s);
- } else
+ } else {
+ s->dma_dac2.enabled = 0;
stop_dac2(s);
+ }
}
return 0;
case SNDCTL_DSP_GETOSPACE:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
- if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
- return ret;
+ if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
abinfo.fragsize = s->dma_dac2.fragsize;
@@ -1734,8 +1773,8 @@
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- return ret;
+ if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
abinfo.fragsize = s->dma_adc.fragsize;
@@ -1755,8 +1794,8 @@
case SNDCTL_DSP_GETODELAY:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
- if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
- return ret;
+ if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
count = s->dma_dac2.count;
@@ -1768,8 +1807,8 @@
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- return ret;
+ if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_adc.total_bytes;
@@ -1786,8 +1825,8 @@
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
- if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
- return ret;
+ if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_dac2.total_bytes;
@@ -1904,10 +1943,12 @@
}
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
+ s->dma_adc.enabled = 1;
set_adc_rate(s, 8000);
}
if (file->f_mode & FMODE_WRITE) {
s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
+ s->dma_dac2.enabled = 1;
set_dac2_rate(s, 8000);
}
spin_lock_irqsave(&s->lock, flags);
@@ -2005,7 +2046,8 @@
if (cnt > count)
cnt = count;
if (cnt <= 0) {
- start_dac1(s);
+ if (s->dma_dac1.enabled)
+ start_dac1(s);
if (file->f_flags & O_NONBLOCK) {
if (!ret)
ret = -EAGAIN;
@@ -2033,7 +2075,8 @@
count -= cnt;
buffer += cnt;
ret += cnt;
- start_dac1(s);
+ if (s->dma_dac1.enabled)
+ start_dac1(s);
}
remove_wait_queue(&s->dma_dac1.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -2192,13 +2235,16 @@
if (val & PCM_ENABLE_OUTPUT) {
if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
return ret;
+ s->dma_dac1.enabled = 1;
start_dac1(s);
- } else
+ } else {
+ s->dma_dac1.enabled = 0;
stop_dac1(s);
+ }
return 0;
case SNDCTL_DSP_GETOSPACE:
- if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0)
+ if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
@@ -2217,6 +2263,8 @@
return 0;
case SNDCTL_DSP_GETODELAY:
+ if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
count = s->dma_dac1.count;
@@ -2226,8 +2274,8 @@
return put_user(count, (int *)arg);
case SNDCTL_DSP_GETOPTR:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
+ if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
+ return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
cinfo.bytes = s->dma_dac1.total_bytes;
@@ -2329,6 +2377,7 @@
down(&s->open_sem);
}
s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
+ s->dma_dac1.enabled = 1;
set_dac1_rate(s, 8000);
spin_lock_irqsave(&s->lock, flags);
s->sctrl &= ~SCTRL_P1FMT;
@@ -2608,6 +2657,7 @@
if (file->f_flags & O_NONBLOCK) {
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
+ unlock_kernel();
return -EBUSY;
}
tmo = (count * HZ) / 3100;
@@ -2800,12 +2850,26 @@
s->ctrl |= CTRL_GPIO_OUT0;
printk(KERN_INFO PFX "Running On Gateway 2000 Solo 2510 - Amp On \n");
}
+ s->gameport.io = s->gameport.size = 0;
if ((joystick[devindex] & ~0x18) == 0x200) {
- if (check_region(joystick[devindex], JOY_EXTENT))
+ if (!request_region(joystick[devindex], JOY_EXTENT, "es1371"))
printk(KERN_ERR PFX "joystick address 0x%x already in use\n", joystick[devindex]);
else {
s->ctrl |= CTRL_JYSTK_EN | (((joystick[devindex] >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
+ s->gameport.io = joystick[devindex];
+ s->gameport.size = JOY_EXTENT;
}
+ } else if (joystick[devindex] == 1) {
+ for (i = 0x218; i >= 0x200; i -= 0x08) {
+ if (request_region(i, JOY_EXTENT, "es1371")) {
+ s->ctrl |= CTRL_JYSTK_EN | (((i >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
+ s->gameport.io = i;
+ s->gameport.size = JOY_EXTENT;
+ break;
+ }
+ }
+ if (!s->gameport.io)
+ printk(KERN_ERR PFX "no free joystick address found\n");
}
s->sctrl = 0;
cssr = 0;
@@ -2830,7 +2894,7 @@
pci_set_master(pcidev); /* enable bus mastering */
/* if we are a 5880 turn on the AC97 */
if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
- ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev == CT5880REV_CT5880_C) ||
+ ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) ||
(s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) ||
(s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) {
cssr |= CSTAT_5880_AC97_RST;
@@ -2853,7 +2917,7 @@
src_init(s);
/* codec init */
if (!ac97_probe_codec(&s->codec))
- goto err_dev4;
+ goto err_gp;
/* set default values */
fs = get_fs();
@@ -2873,6 +2937,8 @@
set_fs(fs);
/* turn on S/PDIF output driver if requested */
outl(cssr, s->io+ES1371_REG_STATUS);
+ /* register gameport */
+ gameport_register_port(&s->gameport);
/* store it in the driver field */
pci_set_drvdata(pcidev, s);
/* put it into driver list */
@@ -2882,6 +2948,9 @@
devindex++;
return 0;
+ err_gp:
+ if (s->gameport.io)
+ release_region(s->gameport.io, s->gameport.size);
err_dev4:
unregister_sound_dsp(s->dev_dac);
err_dev3:
@@ -2913,6 +2982,10 @@
outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
synchronize_irq();
free_irq(s->irq, s);
+ if (s->gameport.io) {
+ gameport_unregister_port(&s->gameport);
+ release_region(s->gameport.io, s->gameport.size);
+ }
release_region(s->io, ES1371_EXTENT);
unregister_sound_dsp(s->dev_audio);
unregister_sound_mixer(s->codec.dev_mixer);
@@ -2942,7 +3015,7 @@
{
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO PFX "version v0.27 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO PFX "version v0.30 time " __TIME__ " " __DATE__ "\n");
return pci_module_init(&es1371_driver);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)