📄 maestro.c
字号:
/***************************************************************************** * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * (c) Copyright 1999 Alan Cox <alan.cox@linux.org> * * Based heavily on SonicVibes.c: * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * Heavily modified by Zach Brown <zab@zabbo.net> based on lunch * with ESS engineers. Many thanks to Howard Kim for providing * contacts and hardware. Honorable mention goes to Eric * Brombaugh for all sorts of things. Best regards to the * proprietors of Hack Central for fine lodging. * * Supported devices: * /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 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 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 ASSP, and initialization differences. * * Driver Operation * * We only drive the APU/Wavecache as typical DACs and drive the * mixers in the codecs. There are 64 APUs. We assign 6 to each * /dev/dsp? device. 2 channels for output, and 4 channels for * input. * * 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. * * 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 * useless on quite a few architectures. Secondly, its insane. * It claims to fetch from 4 regions of PCI space, each 4 meg in length. * But that doesn't really work. You can only use 1 region. So all our * allocations have to be in 4meg of each other. Booo. Hiss. * So we have a module parameter, dsps_order, that is the order of * the number of dsps to provide. All their buffer space is allocated * on open time. The sonicvibes OSS routines we inherited really want * power of 2 buffers, so we have all those next to each other, then * 512 byte regions for the recording wavecaches. This ends up * wasting quite a bit of memory. The only fixes I can see would be * getting a kernel allocator that could work in zones, or figuring out * just how to coerce the WP into doing what we want. * * The indirection of the various registers means we have to spinlock * nearly all register accesses. We have the main register indirection * like the wave cache, maestro registers, etc. Then we have beasts * like the APU interface that is indirect registers gotten at through * the main maestro indirection. Ouch. We spinlock around the actual * ports on a per card basis. This means spinlock activity at each IO * operation, but the only IO operation clusters are in non critical * paths and it makes the code far easier to follow. Interrupts are * blocked while holding the locks because the int handler has to * get at some of them :(. The mixer interface doesn't, however. * We also have an OSS state lock that is thrown around in a few * places. * * This driver has brute force APM suspend support. We catch suspend * notifications and stop all work being done on the chip. Any people * that try between this shutdown and the real suspend operation will * be put to sleep. When we resume we restore our software state on * the chip and wake up the people that were using it. The code thats * being used now is quite dirty and assumes we're on a uni-processor * machine. Much of it will need to be cleaned up for SMP ACPI or * similar. * * We also pay attention to PCI power management now. The driver * will power down units of the chip that it knows aren't needed. * The WaveProcessor and company are only powered on when people * have /dev/dsp*s open. On removal the driver will * power down the maestro entirely. There could still be * trouble with BIOSen that magically change power states * themselves, but we'll see. * * History * v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de> * Ported to Linux 2.4 PCI API. Some clean ups, global devs list * removed (now using pci device driver data). * PM needs to be polished still. Bumped version. * (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu> * Add support for 978 docking and basic hardware volume control * (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com> * Add clocking= for people with seriously warped hardware * (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> * add __init to maestro_ac97_init() and maestro_install() * (still based on v0.14) Mar 29 2000 - Zach Brown <zab@redhat.com> * move to 2.3 power management interface, which * required hacking some suspend/resume/check paths * make static compilation work * v0.14 - Jan 28 2000 - Zach Brown <zab@redhat.com> * add PCI power management through ACPI regs. * we now shut down on machine reboot/halt * leave scary PCI config items alone (isa stuff, mostly) * enable 1921s, it seems only mine was broke. * fix swapped left/right pcm dac. har har. * up bob freq, increase buffers, fix pointers at underflow * silly compilation problems * 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. * re-order something such that some 2Es now work. Magic! * new codec reset routine. made some codecs come to life. * fix clear_advance, sync some control with ESS. * now write to all base regs to be paranoid. * v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com> * Fix initial buflen bug. I am so smart. also smp compiling.. * I owe Eric yet another beer: fixed recmask, igain, * muting, and adc sync consistency. Go Team. * v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com> * tweak adc/dac, formating, and stuff to allow full duplex * allocate dsps memory at open() so we can fit in the wavecache window * fix wavecache braindamage. again. no more scribbling? * fix ess 1921 codec bug on some laptops. * fix dumb pci scanning bug * started 2.3 cleanup, redid spinlocks, little cleanups * v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com> * fix wavecache thinkos. limit to 1 /dev/dsp. * eric is wearing his thinking toque this week. * spotted apu mode bugs and gain ramping problem * don't touch weird mixer regs, make recmask optional * fixed igain inversion, defaults for mixers, clean up rec_start * make mono recording work. * report subsystem stuff, please send reports. * littles: parallel out, amp now * v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com> * merged and fixed up Eric's initial recording code * munged format handling to catch misuse, needs rewrite. * revert ring bus init, fixup shared int, add pci busmaster setting * fix mixer oss interface, fix mic mute and recmask * mask off unsupported mixers, reset with all 1s, modularize defaults * make sure bob is running while we need it * got rid of device limit, initial minimal apm hooks * pull out dead code/includes, only allow multimedia/audio maestros * v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com> * copied memory leak fix from sonicvibes driver * different ac97 reset, play with 2.0 ac97, simplify ring bus setup * bob freq code, region sanity, jitter sync fix; all from Eric * * TODO * fix bob frequency * endianness * do smart things with ac97 2.0 bits. * dual codecs * leave 54->61 open * * 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 * on architectures that don't like the maestro's pci dma ickiness. *//*****************************************************************************/#include <linux/version.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/smp_lock.h>#include <linux/wrapper.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/sound.h>#include <linux/slab.h>#include <linux/soundcard.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <asm/io.h>#include <asm/dma.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/reboot.h>#include <asm/uaccess.h>#include <asm/hardirq.h>#include <linux/bitops.h>#include <linux/pm.h>static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);#include "maestro.h"static struct pci_driver maestro_pci_driver;/* --------------------------------------------------------------------- */#define M_DEBUG 1#ifdef M_DEBUGstatic int debug=0;#define M_printk(args...) {if (debug) printk(args);}#else#define M_printk(x)#endif/* we try to setup 2^(dsps_order) /dev/dsp devices */static int dsps_order=0;/* wether or not we mess around with power management */static int use_pm=2; /* set to 1 for force *//* clocking for broken hardware - a few laptops seem to use a 50Khz clock ie insmod with clocking=50000 or so */ static int clocking=48000;MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");MODULE_DESCRIPTION("ESS Maestro Driver");MODULE_LICENSE("GPL");#ifdef M_DEBUGMODULE_PARM(debug,"i");#endifMODULE_PARM(dsps_order,"i");MODULE_PARM(use_pm,"i");MODULE_PARM(clocking, "i");/* --------------------------------------------------------------------- */#define DRIVER_VERSION "0.15"#ifndef PCI_VENDOR_ESS#define PCI_VENDOR_ESS 0x125D#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */#define PCI_VENDOR_ESS_OLD 0x1285 /* Platform Tech, the people the maestro was bought from */#define PCI_DEVICE_ID_ESS_ESS0100 0x0100 /* maestro 1 */#endif /* PCI_VENDOR_ESS */#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. */#define ESS_FMT_STEREO 0x01#define ESS_FMT_16BIT 0x02#define ESS_FMT_MASK 0x03#define ESS_DAC_SHIFT 0 #define ESS_ADC_SHIFT 4#define ESS_STATE_MAGIC 0x125D1968#define ESS_CARD_MAGIC 0x19283746#define DAC_RUNNING 1#define ADC_RUNNING 2#define MAX_DSP_ORDER 2#define MAX_DSPS (1<<MAX_DSP_ORDER)#define NR_DSPS (1<<dsps_order)#define NR_IDRS 32#define NR_APUS 64#define NR_APU_REGS 16/* acpi states */enum { ACPI_D0=0, ACPI_D1, ACPI_D2, ACPI_D3};/* bits in the acpi masks */#define ACPI_12MHZ ( 1 << 15)#define ACPI_24MHZ ( 1 << 14)#define ACPI_978 ( 1 << 13)#define ACPI_SPDIF ( 1 << 12)#define ACPI_GLUE ( 1 << 11)#define ACPI__10 ( 1 << 10) /* reserved */#define ACPI_PCIINT ( 1 << 9)#define ACPI_HV ( 1 << 8) /* hardware volume */#define ACPI_GPIO ( 1 << 7)#define ACPI_ASSP ( 1 << 6)#define ACPI_SB ( 1 << 5) /* sb emul */#define ACPI_FM ( 1 << 4) /* fm emul */#define ACPI_RB ( 1 << 3) /* ringbus / aclink */#define ACPI_MIDI ( 1 << 2) #define ACPI_GP ( 1 << 1) /* game port */#define ACPI_WP ( 1 << 0) /* wave processor */#define ACPI_ALL (0xffff)#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \ ACPI_MIDI|ACPI_GP|ACPI_WP))#define ACPI_NONE (ACPI__10)/* these masks indicate which units we care about at which states */u16 acpi_state_mask[] = { [ACPI_D0] = ACPI_ALL, [ACPI_D1] = ACPI_SLEEP, [ACPI_D2] = ACPI_SLEEP, [ACPI_D3] = ACPI_NONE};static char version[] __devinitdata =KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n";static const unsigned sample_size[] = { 1, 2, 2, 4 };static const unsigned sample_shift[] = { 0, 1, 1, 2 };enum card_types_t { TYPE_MAESTRO, TYPE_MAESTRO2, TYPE_MAESTRO2E};static const char *card_names[]={ [TYPE_MAESTRO] = "ESS Maestro", [TYPE_MAESTRO2] = "ESS Maestro 2", [TYPE_MAESTRO2E] = "ESS Maestro 2E"};static int clock_freq[]={ [TYPE_MAESTRO] = (49152000L / 1024L), [TYPE_MAESTRO2] = (50000000L / 1024L), [TYPE_MAESTRO2E] = (50000000L / 1024L)};static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf);static struct notifier_block maestro_nb = {maestro_notifier, NULL, 0};/* --------------------------------------------------------------------- */struct ess_state { unsigned int magic; /* FIXME: we probably want submixers in here, but only one record pair */ u8 apu[6]; /* l/r output, l/r intput converters, l/r input apus */ u8 apu_mode[6]; /* Running mode for this APU */ u8 apu_pan[6]; /* Panning setup for this APU */ u32 apu_base[6]; /* base address for this apu */ struct ess_card *card; /* Card info */ /* wave stuff */ unsigned int rateadc, ratedac; unsigned char fmt, enable; int index; /* this locks around the oss state in the driver */ spinlock_t lock; /* only let 1 be opening at a time */ struct semaphore open_sem; wait_queue_head_t open_wait; mode_t open_mode; /* soundcore stuff */ int dev_audio; struct dmabuf { void *rawbuf; unsigned buforder; unsigned numfrag; unsigned fragshift; /* XXX zab - swptr only in here so that it can be referenced by clear_advance, as far as I can tell :( */ unsigned hwptr, swptr; unsigned total_bytes; int count; unsigned error; /* over/underrun */ wait_queue_head_t wait; /* redundant, but makes calculations easier */ unsigned fragsize; unsigned dmasize; unsigned fragsamples; /* OSS stuff */ unsigned mapped:1; unsigned ready:1; /* our oss buffers are ready to go */ unsigned endcleared:1; unsigned ossfragshift; int ossmaxfrags; unsigned subdivision; u16 base; /* Offset for ptr */ } dma_dac, dma_adc; /* pointer to each dsp?s piece of the apu->src buffer page */ void *mixbuf;}; struct ess_card { unsigned int magic; /* We keep maestro cards in a linked list */ struct ess_card *next; int dev_mixer; int card_type; /* as most of this is static, perhaps it should be a pointer to a global struct */ struct mixer_goo { int modcnt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -