patch-2.3.35 linux/drivers/sound/maestro.c
Next file: linux/drivers/usb/.indent.pro
Previous file: linux/drivers/sound/Config.in
Back to the patch index
Back to the overall index
- Lines: 756
- Date:
Sun Dec 26 19:34:04 1999
- Orig file:
v2.3.34/linux/drivers/sound/maestro.c
- Orig date:
Thu Nov 18 20:25:37 1999
diff -u --recursive --new-file v2.3.34/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c
@@ -1,6 +1,6 @@
/*****************************************************************************
*
- * ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.2.x
+ * ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.[23].x
*
* 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
@@ -28,25 +28,25 @@
* proprietors of Hack Central for fine lodging.
*
* Supported devices:
- * /dev/dsp0-7 standard /dev/dsp device, (mostly) OSS compatible
+ * /dev/dsp0-3 standard /dev/dsp device, (mostly) OSS compatible
* /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
*
* Hardware Description
*
* A working Maestro setup contains the Maestro chip wired to a
- * codec or 2. In the Maestro we have the APUs, the ASP, and the
+ * codec or 2. In the Maestro we have the APUs, the ASSP, and the
* Wavecache. The APUs can be though of as virtual audio routing
* channels. They can take data from a number of sources and perform
* basic encodings of the data. The wavecache is a storehouse for
* PCM data. Typically it deals with PCI and interracts with the
- * APUs. The ASP is a wacky DSP like device that ESS is loth
+ * APUs. The ASSP is a wacky DSP like device that ESS is loth
* to release docs on. Thankfully it isn't required on the Maestro
* until you start doing insane things like FM emulation and surround
* encoding. The codecs are almost always AC-97 compliant codecs,
* but it appears that early Maestros may have had PT101 (an ESS
* part?) wired to them. The only real difference in the Maestro
* families is external goop like docking capability, memory for
- * the ASP, and initialization differences.
+ * the ASSP, and initialization differences.
*
* Driver Operation
*
@@ -55,25 +55,19 @@
* /dev/dsp? device. 2 channels for output, and 4 channels for
* input.
*
- * For output we maintain a ring buffer of data that we are DMAing
- * to the card. In mono operation this is nice and easy. When
- * we receive data we tack it onto the ring buffer and make sure
- * the APU assigned to it is playing over the data. When we fill
- * the ring buffer we put the client to sleep until there is
- * room again. Easy.
+ * Each APU can do a number of things, but we only really use
+ * 3 basic functions. For playback we use them to convert PCM
+ * data fetched over PCI by the wavecahche into analog data that
+ * is handed to the codec. One APU for mono, and a pair for stereo.
+ * When in stereo, the combination of smarts in the APU and Wavecache
+ * decide which wavecache gets the left or right channel.
*
- * However, this starts to stink when we use stereo. The APUs
- * supposedly can decode LRLR packed stereo data, but it
- * doesn't work. So we're forced to use dual mono APUs walking over
- * mono encoded data. This requires us to split the input from
- * the client and complicates the buffer maths tremendously. Ick.
- *
- * This also pollutes the recording paths as well. We have to use
- * 2 L/R incoming APUs that are fixed at 16bit/48khz. We then pipe
- * these through 2 rate converion apus that mix them down to the
- * requested frequency and write them to memory through the wavecache.
- * We also apparently need a 512byte region thats used as temp space
- * between the incoming APUs and the rate converters.
+ * For record we still use the old overly mono system. For each in
+ * coming channel the data comes in from the codec, through a 'input'
+ * APU, through another rate converter APU, and then into memory via
+ * the wavecache and PCI. If its stereo, we mash it back into LRLR in
+ * software. The pass between the 2 APUs is supposedly what requires us
+ * to have a 512 byte buffer sitting around in wavecache/memory.
*
* The wavecache makes our life even more fun. First off, it can
* only address the first 28 bits of PCI address space, making it
@@ -113,9 +107,19 @@
* similar.
*
* History
+ * v0.13 - Nov 18 1999 - Zach Brown <zab@redhat.com>
+ * fix nec Versas? man would that be cool.
+ * v0.12 - Nov 12 1999 - Zach Brown <zab@redhat.com>
+ * brown bag volume max fix..
+ * v0.11 - Nov 11 1999 - Zach Brown <zab@redhat.com>
+ * use proper stereo apu decoding, mmap/write should work.
+ * make volume sliders more useful, tweak rate calculation.
+ * fix lame 8bit format reporting bug. duh. apm apu saving buglet also
+ * fix maestro 1 clock freq "bug", remove pt101 support
* v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com>
* aha, so, sometimes the WP writes a status word to offset 0
* from one of the PCMBARs. rearrange allocation accordingly..
+ * cheers again to Eric for being a good hacker in investigating this.
* Jeroen Hoogervorst submits 7500 fix out of nowhere. yay. :)
* v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com>
* added APM support.
@@ -159,16 +163,12 @@
*
* TODO
* some people get indir reg timeouts?
- * anyone have a pt101 codec?
- * mmap(), but beware stereo encoding nastiness.
- * actually post pci writes
* fix bob frequency
+ * endianness
* do smart things with ac97 2.0 bits.
- * ugh.. non aligned writes in the middle of a data stream.. ugh
- * sort out 0x34->0x36 crap in init
* docking and dual codecs and 978?
- * pcm_sync?
- * actually use LRLR
+ * leave 54->61 open
+ * resolve 2.3/2.2 stuff
*
* it also would be fun to have a mode that would not use pci dma at all
* but would copy into the wavecache on board memory and use that
@@ -189,12 +189,14 @@
#define SILLY_INIT_SEM(SEM) SEM=MUTEX;
#define init_waitqueue_head init_waitqueue
#define SILLY_MAKE_INIT(FUNC) __initfunc(FUNC)
+ #define SILLY_OFFSET(VMA) ((VMA)->vm_offset)
#else
#define SILLY_PCI_BASE_ADDRESS(PCIDEV) (PCIDEV->resource[0].start)
#define SILLY_INIT_SEM(SEM) init_MUTEX(&SEM)
#define SILLY_MAKE_INIT(FUNC) __init FUNC
+ #define SILLY_OFFSET(VMA) ((VMA)->vm_pgoff)
#endif
@@ -241,7 +243,7 @@
#endif
/* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.10"
+#define DRIVER_VERSION "0.13"
#ifndef PCI_VENDOR_ESS
#define PCI_VENDOR_ESS 0x125D
@@ -256,6 +258,10 @@
#define ESS_CHAN_HARD 0x100
+/* NEC Versas ? */
+#define NEC_VERSA_SUBID1 0x80581033
+#define NEC_VERSA_SUBID2 0x803c1033
+
/* changed so that I could actually find all the
references and fix them up. its a little more readable now. */
@@ -271,8 +277,8 @@
#define DAC_RUNNING 1
#define ADC_RUNNING 2
-#define MAX_DSP_ORDER 3
-#define MAX_DSPS (1<<3)
+#define MAX_DSP_ORDER 2
+#define MAX_DSPS (1<<MAX_DSP_ORDER)
#define NR_DSPS (1<<dsps_order)
#define NR_IDRS 32
@@ -296,6 +302,11 @@
[TYPE_MAESTRO2E] = "ESS Maestro 2E"
};
+static int clock_freq[]={
+ [TYPE_MAESTRO] = (49152000L / 1024L),
+ [TYPE_MAESTRO2] = (50000000L / 1024L),
+ [TYPE_MAESTRO2E] = (50000000L / 1024L)
+};
/* --------------------------------------------------------------------- */
@@ -521,7 +532,7 @@
[SOUND_MIXER_BASS] = 0x3232,
[SOUND_MIXER_TREBLE] = 0x3232,
[SOUND_MIXER_SPEAKER] = 0x3232,
- [SOUND_MIXER_MIC] = 0x3232,
+ [SOUND_MIXER_MIC] = 0x8000, /* annoying */
[SOUND_MIXER_LINE] = 0x3232,
[SOUND_MIXER_CD] = 0x3232,
[SOUND_MIXER_VIDEO] = 0x3232,
@@ -599,6 +610,23 @@
/* write the OSS encoded volume to the given OSS encoded mixer,
again caller's job to make sure all is well in arg land,
call with spinlock held */
+
+/* linear scale -> log */
+unsigned char lin2log[101] =
+{
+0, 0 , 15 , 23 , 30 , 34 , 38 , 42 , 45 , 47 ,
+50 , 52 , 53 , 55 , 57 , 58 , 60 , 61 , 62 ,
+63 , 65 , 66 , 67 , 68 , 69 , 69 , 70 , 71 ,
+72 , 73 , 73 , 74 , 75 , 75 , 76 , 77 , 77 ,
+78 , 78 , 79 , 80 , 80 , 81 , 81 , 82 , 82 ,
+83 , 83 , 84 , 84 , 84 , 85 , 85 , 86 , 86 ,
+87 , 87 , 87 , 88 , 88 , 88 , 89 , 89 , 89 ,
+90 , 90 , 90 , 91 , 91 , 91 , 92 , 92 , 92 ,
+93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 ,
+95 , 95 , 96 , 96 , 96 , 96 , 97 , 97 , 97 ,
+97 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99
+};
+
static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right)
{
u16 val=0;
@@ -614,12 +642,13 @@
right = (right * mh->scale) / 100;
left = (left * mh->scale) / 100;
if ((left == 0) && (right == 0))
- val |= 0x8000;
- } else {
- right = ((100 - right) * mh->scale) / 100;
- left = ((100 - left) * mh->scale) / 100;
- if((left == mh->scale) && (right == mh->scale))
val |= 0x8000;
+ } else {
+ /* log conversion for the stereo controls */
+ if((left == 0) && (right == 0))
+ val = 0x8000;
+ right = ((100 - lin2log[right]) * mh->scale) / 100;
+ left = ((100 - lin2log[left]) * mh->scale) / 100;
}
val |= (left << 8) | right;
@@ -772,6 +801,8 @@
return 0;
}
+#if 0 /* there has been 1 person on the planet with a pt101 that we
+ know of. If they care, they can put this back in :) */
static u16 maestro_pt101_init(struct ess_card *card,int iobase)
{
printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
@@ -792,6 +823,7 @@
maestro_ac97_set(iobase, 0x0E, 0x801F);
return 0;
}
+#endif
/* this is very magic, and very slow.. */
static void
@@ -799,6 +831,7 @@
{
u16 save_68;
u16 w;
+ u32 vend;
outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
@@ -808,6 +841,7 @@
outw(0x0000, ioaddr+0x36);
save_68 = inw(ioaddr+0x68);
pci_read_config_word(pcidev, 0x58, &w); /* something magical with gpio and bus arb. */
+ pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &vend);
if( w & 0x1)
save_68 |= 0x10;
outw(0xfffe, ioaddr + 0x64); /* tickly gpio 0.. */
@@ -861,6 +895,12 @@
}
}
#endif
+ if ( vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
+ /* turn on external amp? */
+ outw(0xf9ff, ioaddr + 0x64);
+ outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68);
+ outw(0x0209, ioaddr + 0x60);
+ }
}
/*
* Indirect register access. Not all registers are readable so we
@@ -1065,13 +1105,12 @@
/* sets the play formats of these apus, should be passed the already shifted format */
static void set_apu_fmt(struct ess_state *s, int apu, int mode)
{
- if(mode&ESS_FMT_16BIT) {
- s->apu_mode[apu] = 0x10;
- s->apu_mode[apu+1] = 0x10;
- } else {
- s->apu_mode[apu] = 0x30;
- s->apu_mode[apu+1] = 0x30;
- }
+ int apu_fmt = 0x10;
+
+ if(!(mode&ESS_FMT_16BIT)) apu_fmt+=0x20;
+ if((mode&ESS_FMT_STEREO)) apu_fmt+=0x10;
+ s->apu_mode[apu] = apu_fmt;
+ s->apu_mode[apu+1] = apu_fmt;
}
/* this only fixes the output apu mode to be later set by start_dac and
@@ -1082,18 +1121,21 @@
set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK);
}
-static u16 compute_rate(u32 freq)
+/* this is off by a little bit.. */
+static u32 compute_rate(struct ess_state *s, u32 freq)
{
- if(freq==48000)
- return 0xFFFF;
- freq<<=16;
- freq/=48000;
- return freq;
+ u32 clock = clock_freq[s->card->card_type];
+
+ if (freq == 48000) return 0x10000;
+
+ return ((freq / clock) <<16 )+
+ (((freq % clock) << 16) / clock);
}
-static void set_dac_rate(struct ess_state *s, unsigned rate)
+static void set_dac_rate(struct ess_state *s, unsigned int rate)
{
u32 freq;
+ int fmt = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
if (rate > 48000)
rate = 48000;
@@ -1102,12 +1144,12 @@
s->ratedac = rate;
- if(!((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT))
- rate >>= 1; /* who knows */
+ if(! (fmt & ESS_FMT_16BIT) && !(fmt & ESS_FMT_STEREO))
+ rate >>= 1;
/* M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/
- freq = compute_rate(rate);
+ freq = compute_rate(s, rate);
/* Load the frequency, turn on 6dB */
apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)|
@@ -1122,14 +1164,15 @@
{
u32 freq;
- if (rate > 48000)
- rate = 48000;
+ /* Sample Rate conversion APUs don't like 0x10000 for their rate */
+ if (rate > 47999)
+ rate = 47999;
if (rate < 4000)
rate = 4000;
s->rateadc = rate;
- freq = compute_rate(rate);
+ freq = compute_rate(s, rate);
/* Load the frequency, turn on 6dB */
apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)|
@@ -1234,27 +1277,21 @@
/* all maestro sizes are in 16bit words */
size >>=1;
- /* we're given the full size of the buffer, but
- in stereo each channel will only play its half */
if(mode&ESS_FMT_STEREO) {
- size >>=1;
high_apu++;
+ /* only 16/stereo gets size divided */
+ if(mode&ESS_FMT_16BIT)
+ size>>=1;
}
for(channel=0; channel <= high_apu; channel++)
{
- int i;
-
- if(!channel)
- pa = virt_to_bus(buffer);
- else
- /* right channel plays its split half.
- *2 accomodates for rampant shifting earlier */
- pa = virt_to_bus(buffer + size*2);
+ pa = virt_to_bus(buffer);
/* set the wavecache control reg */
tmpval = (pa - 0x10) & 0xFFF8;
- if(!(mode & 2)) tmpval |= 4; /* 8bit */
+ if(!(mode & ESS_FMT_16BIT)) tmpval |= 4;
+ if(mode & ESS_FMT_STEREO) tmpval |= 2;
ess->apu_base[channel]=tmpval;
wave_set_register(ess, ess->apu[channel]<<3, tmpval);
@@ -1262,14 +1299,17 @@
pa>>=1; /* words */
/* base offset of dma calcs when reading the pointer
- on this left one */
+ on the left one */
if(!channel) ess->dma_dac.base = pa&0xFFFF;
pa|=0x00400000; /* System RAM */
-
- /* Begin loading the APU */
- for(i=0;i<15;i++) /* clear all PBRs */
- apu_set_register(ess, channel, i, 0x0000);
+
+ /* XXX the 16bit here might not be needed.. */
+ if((mode & ESS_FMT_STEREO) && (mode & ESS_FMT_16BIT)) {
+ if(channel)
+ pa|=0x00800000; /* Stereo */
+ pa>>=1;
+ }
/* XXX think about endianess when writing these registers */
M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa);
@@ -1290,16 +1330,17 @@
/* dma on, no envelopes, filter to all 1s) */
apu_set_register(ess, channel, 0, 0x400F);
- if(mode&ESS_FMT_STEREO)
- /* set panning: left or right */
- apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0x10 : 0));
- else
- apu_set_register(ess, channel, 10, 0x8F08);
-
if(mode&ESS_FMT_16BIT)
ess->apu_mode[channel]=0x10;
else
ess->apu_mode[channel]=0x30;
+
+ if(mode&ESS_FMT_STEREO) {
+ /* set panning: left or right */
+ apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0x10 : 0));
+ ess->apu_mode[channel] += 0x10;
+ } else
+ apu_set_register(ess, channel, 10, 0x8F08);
}
/* clear WP interupts */
@@ -1660,29 +1701,20 @@
clear_advance(struct ess_state *s)
{
unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
+
unsigned char *buf = s->dma_dac.rawbuf;
unsigned bsize = s->dma_dac.dmasize;
- /* swptr is always in bytes as read from an apu.. */
unsigned bptr = s->dma_dac.swptr;
unsigned len = s->dma_dac.fragsize;
- int i=1;
-
- if((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_STEREO) {
- i++;
- bsize >>=1;
- }
-
- for ( ;i; i-- , buf += bsize) {
-
- if (bptr + len > bsize) {
- unsigned x = bsize - bptr;
- memset(buf + bptr, c, x);
- /* account for wrapping? */
- bptr = 0;
- len -= x;
- }
- memset(buf + bptr, c, len);
+
+ if (bptr + len > bsize) {
+ unsigned x = bsize - bptr;
+ memset(buf + bptr, c, x);
+ /* account for wrapping? */
+ bptr = 0;
+ len -= x;
}
+ memset(buf + bptr, c, len);
}
/* call with spinlock held! */
@@ -1725,8 +1757,13 @@
}
/* update DAC pointer */
if (s->dma_dac.ready) {
- /* this is so gross. */
- hwptr = (/*s->dma_dac.dmasize -*/ get_dmaa(s)) % s->dma_dac.dmasize;
+ hwptr = get_dmaa(s) % s->dma_dac.dmasize;
+ /* the apu only reports the length it has seen, not the
+ length of the memory that has been used (the WP
+ knows that */
+ if ( ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK) == (ESS_FMT_STEREO|ESS_FMT_16BIT))
+ hwptr<<=1;
+
diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
/* M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/
s->dma_dac.hwptr = hwptr;
@@ -2190,42 +2227,6 @@
return ret;
}
-/* god this is gross..*/
-/* again, the mode passed is shifted/masked */
-static int
-split_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset,
- int count, int bufsize, int mode)
-{
- /* oh, bother. stereo decoding APU's don't work in 16bit so we
- use dual linear decoders. which means we have to hack up stereo
- buffer's we're given. yuck. */
-
- unsigned char *so,*left,*right;
- int i;
-
- so = tmp_buffer;
- left = real_buffer + offset;
- right = real_buffer + bufsize/2 + offset;
-
- if(mode & ESS_FMT_16BIT) {
- for(i=count/4; i ; i--) {
- *(right++) = (*(so+2));
- *(right++) = (*(so+3));
- *(left++) = (*so);
- *(left++) = (*(so+1));
- so+=4;
- }
- } else {
- for(i=count/2; i ; i--) {
- *(right++) = (*(so+1));
- *(left++) = (*so);
- so+=2;
- }
- }
-
- return 0;
-}
-
static ssize_t
ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
@@ -2233,9 +2234,7 @@
ssize_t ret;
unsigned long flags;
unsigned swptr;
- unsigned char *splitbuf = NULL;
int cnt;
- int mode = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
VALIDATE_STATE(s);
if (ppos != &file->f_pos)
@@ -2246,9 +2245,6 @@
return ret;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
- /* XXX be more clever than this.. */
- if (!(splitbuf = kmalloc(count,GFP_KERNEL)))
- return -ENOMEM;
ret = 0;
calc_bob_rate(s);
@@ -2262,12 +2258,8 @@
}
swptr = s->dma_dac.swptr;
- if(mode & ESS_FMT_STEREO) {
- /* in stereo we have the 'dual' buffers.. */
- cnt = ((s->dma_dac.dmasize/2)-swptr)*2;
- } else {
- cnt = s->dma_dac.dmasize-swptr;
- }
+ cnt = s->dma_dac.dmasize-swptr;
+
if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
cnt = s->dma_dac.dmasize - s->dma_dac.count;
@@ -2276,10 +2268,6 @@
if (cnt > count)
cnt = count;
- /* our goofball stereo splitter can only deal in mults of 4 */
- if (cnt > 0)
- cnt &= ~3;
-
if (cnt <= 0) {
start_dac(s);
if (file->f_flags & O_NONBLOCK) {
@@ -2309,26 +2297,13 @@
}
continue;
}
- if(mode & ESS_FMT_STEREO) {
- if (copy_from_user(splitbuf, buffer, cnt)) {
- if (!ret) ret = -EFAULT;
- goto return_free;
- }
- split_stereo(s->dma_dac.rawbuf,splitbuf,swptr,cnt,s->dma_dac.dmasize,
- mode);
- } else {
- if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
- if (!ret) ret = -EFAULT;
- goto return_free;
- }
+ if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
+ if (!ret) ret = -EFAULT;
+ goto return_free;
}
- if(mode & ESS_FMT_STEREO) {
- /* again with the weird pointer magic */
- swptr = (swptr + (cnt/2)) % (s->dma_dac.dmasize/2);
- } else {
- swptr = (swptr + cnt) % s->dma_dac.dmasize;
- }
+ swptr = (swptr + cnt) % s->dma_dac.dmasize;
+
spin_lock_irqsave(&s->lock, flags);
s->dma_dac.swptr = swptr;
s->dma_dac.count += cnt;
@@ -2340,7 +2315,6 @@
start_dac(s);
}
return_free:
- if (splitbuf) kfree(splitbuf);
return ret;
}
@@ -2374,8 +2348,6 @@
return mask;
}
-/* this needs to be fixed to deal with the dual apus/buffers */
-#if 0
static int ess_mmap(struct file *file, struct vm_area_struct *vma)
{
struct ess_state *s = (struct ess_state *)file->private_data;
@@ -2388,13 +2360,18 @@
if ((ret = prog_dmabuf(s, 1)) != 0)
return ret;
db = &s->dma_dac;
- } else if (vma->vm_flags & VM_READ) {
+ } else
+#if 0
+ /* if we can have the wp/wc do the combining
+ we can turn this back on. */
+ if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(s, 0)) != 0)
return ret;
db = &s->dma_adc;
- } else
+ } else
+#endif
return -EINVAL;
- if (vma->vm_pgofft != 0)
+ if (SILLY_OFFSET(vma) != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
@@ -2404,7 +2381,6 @@
db->mapped = 1;
return 0;
}
-#endif
static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -2434,7 +2410,7 @@
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER /*| DSP_CAP_MMAP*/, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
@@ -2515,7 +2491,7 @@
: (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S8|AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
get_user_ret(val, (int *)arg, -EFAULT);
@@ -2548,7 +2524,7 @@
(ESS_FMT_16BIT << ESS_ADC_SHIFT)
: (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ?
AFMT_S16_LE :
- AFMT_S8,
+ AFMT_U8,
(int *)arg);
case SNDCTL_DSP_POST:
@@ -2938,7 +2914,7 @@
NULL, /* readdir */
&ess_poll,
&ess_ioctl,
- NULL, /* XXX &ess_mmap, */
+ &ess_mmap,
&ess_open,
NULL, /* flush */
&ess_release,
@@ -3000,7 +2976,7 @@
w&=~(1<<7); /* HWV off */
w&=~(1<<6); /* Debounce off */
w&=~(1<<5); /* GPIO 4:5 */
- w|= (1<<4); /* Disconnect from the CHI. Enabling this in made a dell 7500 work. */
+ w|= (1<<4); /* Disconnect from the CHI. Enabling this made a dell 7500 work. */
w&=~(1<<3); /* IDMA off (undocumented) */
w&=~(1<<2); /* MIDI fix off (undoc) */
w&=~(1<<1); /* reserved, always write 0 */
@@ -3303,7 +3279,8 @@
maestro_config(card);
if(maestro_ac97_get(iobase, 0x00)==0x0080) {
- maestro_pt101_init(card,iobase);
+ printk(KERN_ERR "maestro: my goodness! you seem to have a pt101 codec, which is quite rare.\n"
+ "\tyou should tell someone about this.\n");
} else {
maestro_ac97_init(card,iobase);
}
@@ -3451,7 +3428,7 @@
}
static int
-maestro_apm_suspend(void)
+maestro_suspend(void)
{
struct ess_card *card;
unsigned long flags;
@@ -3474,7 +3451,7 @@
stop_dac(s);
stop_adc(s);
for(j=0;j<6;j++)
- card->apu_map[s->apu[i]][5]=apu_get_register(s,i,5);
+ card->apu_map[s->apu[j]][5]=apu_get_register(s,j,5);
}
@@ -3491,7 +3468,7 @@
return 0;
}
static int
-maestro_apm_resume(void)
+maestro_resume(void)
{
struct ess_card *card;
unsigned long flags;
@@ -3565,11 +3542,11 @@
case APM_SYS_SUSPEND:
case APM_CRITICAL_SUSPEND:
case APM_USER_SUSPEND:
- maestro_apm_suspend();break;
+ maestro_suspend();break;
case APM_NORMAL_RESUME:
case APM_CRITICAL_RESUME:
case APM_STANDBY_RESUME:
- maestro_apm_resume();break;
+ maestro_resume();break;
default: break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)