lkml.org 
[lkml]   [1999]   [Dec]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] maestro sound driver vs 2.3.34

This patch brings the maestro driver in 2.3 up to the stable one
in 2.2 and that has been available for testing for a while, specifically:

* add support for NEC Versa laptops
* fix stereo support so that mmap() works, volumes are now sane

* removes experimental flag
* adds Documentation/sound/Maestro, Config.help entry
* fixes up some ESS/Maestro PCI ID references

Zach Brown <zab@redhat.com> -- Software Princess
--- linux/drivers/sound/Config.in.prem Sun Dec 26 18:06:42 1999
+++ linux/drivers/sound/Config.in Sun Dec 26 18:07:50 1999
@@ -20,9 +20,7 @@
dep_tristate ' Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
dep_tristate ' Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
dep_tristate ' ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- dep_tristate ' ESS Maestro, Maestro2, Maestro2E driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO $CONFIG_SOUND
-fi
+dep_tristate ' ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND
dep_tristate ' S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND
if [ "$CONFIG_VISWS" = "y" ]; then
dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
--- linux/drivers/sound/maestro.c.prem Sun Dec 26 16:53:47 1999
+++ linux/drivers/sound/maestro.c Sun Dec 26 18:12:25 1999
@@ -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;
}

--- linux/drivers/pci/pci.ids.prem Sun Dec 26 18:55:07 1999
+++ linux/drivers/pci/pci.ids Sun Dec 26 18:55:42 1999
@@ -2150,7 +2150,7 @@
1948 Solo?
1968 ES1968 Maestro 2
1969 ES1969 Solo-1 Audiodrive
- 1978 ES1978 Maestro Audiodrive
+ 1978 ES1978 Maestro 2E
2808 ES336H Fax Modem (Later Model)
2898 ES2898 Modem
125e Specialvideo Engineering SRL
@@ -2216,7 +2216,7 @@
e886 IT8330G
1284 Sahara Networks, Inc.
1285 Platform Technologies, Inc.
- 0100 PT-201C-O-P AGOGO-XP sound chip
+ 0100 AGOGO sound chip (aka ESS Maestro 1)
1286 Mazet GmbH
1287 M-Pact, Inc.
001e LS220D DVD Decoder
--- linux/Documentation/sound/Maestro.prem Sun Dec 26 17:52:04 1999
+++ linux/Documentation/sound/Maestro Sun Dec 26 17:53:19 1999
@@ -0,0 +1,98 @@
+ An OSS/Lite Driver for the ESS Maestro family of sound cards
+
+ Zach Brown, December 1999
+
+Driver Status and Availability
+------------------------------
+
+The most recent version of this driver will hopefully always be available at
+ http://people.redhat.com/zab/maestro/
+
+I will try and maintain the most recent stable version of the driver
+in both the stable and development kernel lines.
+
+ESS Maestro Chip Family
+-----------------------
+
+There are 3 main variants of the ESS Maestro PCI sound chip. The first
+is the Maestro 1. It was originally produced by Platform Tech as the
+'AGOGO'. It can be recognized by Platform Tech's PCI ID 0x1285 with
+0x0100 as the device ID. It was put on some sound boards and a few laptops.
+ESS bought the design and cleaned it up as the Maestro 2. This starts
+their marking with the ESS vendor ID 0x125D and the 'year' device IDs.
+The Maestro 2 claims 0x1968 while the Maestro 2e has 0x1978.
+
+The various families of Maestro are mostly identical as far as this
+driver is concerned. It doesn't touch the DSP parts that differ (though
+it could for FM synthesis)
+
+Driver OSS Behavior
+--------------------
+
+This OSS driver exports /dev/mixer and /dev/dsp to applications, which
+mostly adhere to the OSS spec. This driver doesn't register itself
+with /dev/sndstat, so don't expect information to appear there.
+
+The /dev/dsp device exported behaves almost as expected. Playback is
+supported in all the various lovely formats. 8/16bit stereo/mono from
+8khz to 48khz, and mmap()ing for playback behaves. Capture/recording
+is limited due to oddities with the Maestro hardware. One can only
+record in 16bit stereo. For recording the maestro uses non interleaved
+stereo buffers so that mmap()ing the incoming data does not result in
+a ring buffer of LRLR data. mmap()ing of the read buffers is therefore
+disallowed until this can be cleaned up.
+
+/dev/mixer is an interface to the AC'97 codec on the Maestro. It is
+worth noting that there are a variety of AC'97s that can be wired to
+the Maestro. Which is used is entirely up to the hardware implementor.
+This should only be visible to the user by the presence, or lack, of
+'Bass' and 'Treble' sliders in the mixer. Not all AC'97s have them.
+
+The driver doesn't support MIDI or FM playback at the moment. Typically
+the Maestro is wired to an MPU MIDI chip, but some hardware implementations
+don't. We need to assemble a white list of hardware implementations that
+have MIDI wired properly before we can claim to support it safely.
+
+Compiling and Installing
+------------------------
+
+With the drivers inclusion into the kernel, compiling and installing
+is the same as most OSS/Lite modular sound drivers. Compilation
+of the driver is enabled through the CONFIG_SOUND_MAESTRO variable
+in the config system.
+
+It may be modular or statically linked. If it is modular it should be
+installed with the rest of the modules for the kernel on the system.
+Typically this will be in /lib/modules/ somewhere. 'alias sound maestro'
+should also be added to your module configs (typically /etc/conf.modules)
+if you're using modular OSS/Lite sound and want to default to using a
+maestro chip.
+
+As this is a PCI device, the module does not need to be informed of
+any IO or IRQ resources it should use, it devines these from the
+system. Somtimes, on sucky PCs, the BIOS fails to allocated resources
+for the maestro. This will result in a message like:
+ maestro: PCI subsystem reports IRQ 0, this might not be correct.
+from the kernel. Should this happen the sound chip most likely will
+not operate correctly. To solve this one has to dig through their BIOS
+(typically entered by hitting a hot key at boot time) and figure out
+what magic needs to happen so that the BIOS will reward the maestro with
+an IRQ. This operation is incredibly system specific, so you're on your
+own. Sometimes the magic lies in 'PNP Capable Operating System' settings.
+
+There are very few options to the driver. One is 'debug' which will
+tell the driver to print minimal debugging information as it runs. This
+can be collected with 'dmesg' or through the klogd daemon.
+
+The other, more interesting option, is 'dsps_order'. Typically at
+install time the driver will only register one available /dev/dsp device
+for its use. The 'dsps_order' module parameter allows for more devices
+to be allocated, as a power of two. Up to 4 devices can be registered
+( dsps_order=2 ). These devices act as fully distinct units and use
+separate channels in the maestro.
+
+.. more details ..
+-----------------
+
+drivers/sound/maestro.c contains comments that hopefully explain
+the maestro implementation.
--- linux/Documentation/Configure.help.prem Sun Dec 26 17:11:36 1999
+++ linux/Documentation/Configure.help Sun Dec 26 17:14:22 1999
@@ -11172,6 +11172,12 @@

See Documentation/sound/NM256 for further information.

+ESS Maestro sound chipsets
+CONFIG_SOUND_MAESTRO
+ Say Y or M if you have a sound system driven by ESS's Maestro line
+ of PCI sound chips. These include the Maestro 1, Maestro 2, and
+ Maestro 2E. See Documentation/sound/Maestro for more details.
+
Are you using a crosscompiler
CONFIG_CROSSCOMPILE
Say Y here if you are compiling the kernel on a different
--- linux/MAINTAINERS.prem Sun Dec 26 17:53:53 1999
+++ linux/MAINTAINERS Sun Dec 26 18:01:48 1999
@@ -529,6 +529,12 @@
L: linuxppc-dev@lists.linuxppc.org
S: Maintained

+MAESTRO PCI SOUND DRIVER
+P: Zach Brown
+M: zab@redhat.com
+W: http://people.redhat.com/zab/maestro/
+S: Supported
+
M68K
P: Jes Sorensen
M: Jes.Sorensen@cern.ch
--- linux/CREDITS.prem Sun Dec 26 17:58:27 1999
+++ linux/CREDITS Sun Dec 26 18:00:28 1999
@@ -331,6 +331,10 @@
S: Amsterdam
S: The Netherlands

+N: Zach Brown
+E: zab@zabbo.net
+D: maestro pci sound
+
N: Ray Burr
E: ryb@nightmare.com
D: Original author of Amiga FFS filesystem
\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.044 / U:0.224 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site