📄 audio.c
字号:
/*****************************************************************************/
/*
* audio.c -- USB Audio Class driver
*
* Copyright (C) 1999, 2000, 2001, 2003, 2004
* Alan Cox (alan@lxorguk.ukuu.org.uk)
* Thomas Sailer (sailer@ife.ee.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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Debugging:
* Use the 'lsusb' utility to dump the descriptors.
*
* 1999-09-07: Alan Cox
* Parsing Audio descriptor patch
* 1999-09-08: Thomas Sailer
* Added OSS compatible data io functions; both parts of the
* driver remain to be glued together
* 1999-09-10: Thomas Sailer
* Beautified the driver. Added sample format conversions.
* Still not properly glued with the parsing code.
* The parsing code seems to have its problems btw,
* Since it parses all available configs but doesn't
* store which iface/altsetting belongs to which config.
* 1999-09-20: Thomas Sailer
* Threw out Alan's parsing code and implemented my own one.
* You cannot reasonnably linearly parse audio descriptors,
* especially the AudioClass descriptors have to be considered
* pointer lists. Mixer parsing untested, due to lack of device.
* First stab at synch pipe implementation, the Dallas USB DAC
* wants to use an Asynch out pipe. usb_audio_state now basically
* only contains lists of mixer and wave devices. We can therefore
* now have multiple mixer/wave devices per USB device.
* 1999-10-28: Thomas Sailer
* Converted to URB API. Fixed a taskstate/wakeup semantics mistake
* that made the driver consume all available CPU cycles.
* Now runs stable on UHCI-Acher/Fliegl/Sailer.
* 1999-10-31: Thomas Sailer
* Audio can now be unloaded if it is not in use by any mixer
* or dsp client (formerly you had to disconnect the audio devices
* from the USB port)
* Finally, about three months after ordering, my "Maxxtro SPK222"
* speakers arrived, isn't disdata a great mail order company 8-)
* Parse class specific endpoint descriptor of the audiostreaming
* interfaces and take the endpoint attributes from there.
* Unbelievably, the Philips USB DAC has a sampling rate range
* of over a decade, yet does not support the sampling rate control!
* No wonder it sounds so bad, has very audible sampling rate
* conversion distortion. Don't try to listen to it using
* decent headphones!
* "Let's make things better" -> but please Philips start with your
* own stuff!!!!
* 1999-11-02: Thomas Sailer
* It takes the Philips boxes several seconds to acquire synchronisation
* that means they won't play short sounds. Should probably maintain
* the ISO datastream even if there's nothing to play.
* Fix counting the total_bytes counter, RealPlayer G2 depends on it.
* 1999-12-20: Thomas Sailer
* Fix bad bug in conversion to per interface probing.
* disconnect was called multiple times for the audio device,
* leading to a premature freeing of the audio structures
* 2000-05-13: Thomas Sailer
* I don't remember who changed the find_format routine,
* but the change was completely broken for the Dallas
* chip. Anyway taking sampling rate into account in find_format
* is bad and should not be done unless there are devices with
* completely broken audio descriptors. Unless someone shows
* me such a descriptor, I will not allow find_format to
* take the sampling rate into account.
* Also, the former find_format made:
* - mpg123 play mono instead of stereo
* - sox completely fail for wav's with sample rates < 44.1kHz
* for the Dallas chip.
* Also fix a rather long standing problem with applications that
* use "small" writes producing no sound at all.
* 2000-05-15: Thomas Sailer
* My fears came true, the Philips camera indeed has pretty stupid
* audio descriptors.
* 2000-05-17: Thomas Sailer
* Nemsoft spotted my stupid last minute change, thanks
* 2000-05-19: Thomas Sailer
* Fixed FEATURE_UNIT thinkos found thanks to the KC Technology
* Xtend device. Basically the driver treated FEATURE_UNIT's sourced
* by mono terminals as stereo.
* 2000-05-20: Thomas Sailer
* SELECTOR support (and thus selecting record channels from the mixer).
* Somewhat peculiar due to OSS interface limitations. Only works
* for channels where a "slider" is already in front of it (i.e.
* a MIXER unit or a FEATURE unit with volume capability).
* 2000-11-26: Thomas Sailer
* Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for
* its 8 bit modes, but expects signed data (and should therefore have used PCM).
* 2001-03-10: Thomas Sailer
* provide abs function, prevent picking up a bogus kernel macro
* for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
* 2001-06-16: Bryce Nesbitt <bryce@obviously.com>
* Fix SNDCTL_DSP_STEREO API violation
* 2003-04-08: Oliver Neukum (oliver@neukum.name):
* Setting a configuration is done by usbcore and must not be overridden
* 2004-02-27: Workaround for broken synch descriptors
* 2004-03-07: Alan Stern <stern@rowland.harvard.edu>
* Add usb_ifnum_to_if() and usb_altnum_to_altsetting() support.
* Use the in-memory descriptors instead of reading them from the device.
*
*/
/*
* Strategy:
*
* Alan Cox and Thomas Sailer are starting to dig at opposite ends and
* are hoping to meet in the middle, just like tunnel diggers :)
* Alan tackles the descriptor parsing, Thomas the actual data IO and the
* OSS compatible interface.
*
* Data IO implementation issues
*
* A mmap'able ring buffer per direction is implemented, because
* almost every OSS app expects it. It is however impractical to
* transmit/receive USB data directly into and out of the ring buffer,
* due to alignment and synchronisation issues. Instead, the ring buffer
* feeds a constant time delay line that handles the USB issues.
*
* Now we first try to find an alternate setting that exactly matches
* the sample format requested by the user. If we find one, we do not
* need to perform any sample rate conversions. If there is no matching
* altsetting, we choose the closest one and perform sample format
* conversions. We never do sample rate conversion; these are too
* expensive to be performed in the kernel.
*
* Current status: no known HCD-specific issues.
*
* Generally: Due to the brokenness of the Audio Class spec
* it seems generally impossible to write a generic Audio Class driver,
* so a reasonable driver should implement the features that are actually
* used.
*
* Parsing implementation issues
*
* One cannot reasonably parse the AudioClass descriptors linearly.
* Therefore the current implementation features routines to look
* for a specific descriptor in the descriptor list.
*
* How does the parsing work? First, all interfaces are searched
* for an AudioControl class interface. If found, the config descriptor
* that belongs to the current configuration is searched and
* the HEADER descriptor is found. It contains a list of
* all AudioStreaming and MIDIStreaming devices. This list is then walked,
* and all AudioStreaming interfaces are classified into input and output
* interfaces (according to the endpoint0 direction in altsetting1) (MIDIStreaming
* is currently not supported). The input & output list is then used
* to group inputs and outputs together and issued pairwise to the
* AudioStreaming class parser. Finally, all OUTPUT_TERMINAL descriptors
* are walked and issued to the mixer construction routine.
*
* The AudioStreaming parser simply enumerates all altsettings belonging
* to the specified interface. It looks for AS_GENERAL and FORMAT_TYPE
* class specific descriptors to extract the sample format/sample rate
* data. Only sample format types PCM and PCM8 are supported right now, and
* only FORMAT_TYPE_I is handled. The isochronous data endpoint needs to
* be the first endpoint of the interface, and the optional synchronisation
* isochronous endpoint the second one.
*
* Mixer construction works as follows: The various TERMINAL and UNIT
* descriptors span a tree from the root (OUTPUT_TERMINAL) through the
* intermediate nodes (UNITs) to the leaves (INPUT_TERMINAL). We walk
* that tree in a depth first manner. FEATURE_UNITs may contribute volume,
* bass and treble sliders to the mixer, MIXER_UNITs volume sliders.
* The terminal type encoded in the INPUT_TERMINALs feeds a heuristic
* to determine "meaningful" OSS slider numbers, however we will see
* how well this works in practice. Other features are not used at the
* moment, they seem less often used. Also, it seems difficult at least
* to construct recording source switches from SELECTOR_UNITs, but
* since there are not many USB ADC's available, we leave that for later.
*/
/*****************************************************************************/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/usb.h>
#include "audio.h"
/*
* Version Information
*/
#define DRIVER_VERSION "v1.0.0"
#define DRIVER_AUTHOR "Alan Cox <alan@lxorguk.ukuu.org.uk>, Thomas Sailer (sailer@ife.ee.ethz.ch)"
#define DRIVER_DESC "USB Audio Class driver"
#define AUDIO_DEBUG 1
#define SND_DEV_DSP16 5
#define dprintk(x)
/* --------------------------------------------------------------------- */
/*
* Linked list of all audio devices...
*/
static struct list_head audiodevs = LIST_HEAD_INIT(audiodevs);
static DECLARE_MUTEX(open_sem);
/*
* wait queue for processes wanting to open an USB audio device
*/
static DECLARE_WAIT_QUEUE_HEAD(open_wait);
#define MAXFORMATS MAX_ALT
#define DMABUFSHIFT 17 /* 128k worth of DMA buffer */
#define NRSGBUF (1U<<(DMABUFSHIFT-PAGE_SHIFT))
/*
* This influences:
* - Latency
* - Interrupt rate
* - Synchronisation behaviour
* Don't touch this if you don't understand all of the above.
*/
#define DESCFRAMES 5
#define SYNCFRAMES DESCFRAMES
#define MIXFLG_STEREOIN 1
#define MIXFLG_STEREOOUT 2
struct mixerchannel {
__u16 value;
__u16 osschannel; /* number of the OSS channel */
__s16 minval, maxval;
__u16 slctunitid;
__u8 unitid;
__u8 selector;
__u8 chnum;
__u8 flags;
};
struct audioformat {
unsigned int format;
unsigned int sratelo;
unsigned int sratehi;
unsigned char altsetting;
unsigned char attributes;
};
struct dmabuf {
/* buffer data format */
unsigned int format;
unsigned int srate;
/* physical buffer */
unsigned char *sgbuf[NRSGBUF];
unsigned bufsize;
unsigned numfrag;
unsigned fragshift;
unsigned wrptr, rdptr;
unsigned total_bytes;
int count;
unsigned error; /* over/underrun */
wait_queue_head_t wait;
/* redundant, but makes calculations easier */
unsigned fragsize;
unsigned dmasize;
/* OSS stuff */
unsigned mapped:1;
unsigned ready:1;
unsigned ossfragshift;
int ossmaxfrags;
unsigned subdivision;
};
struct usb_audio_state;
#define FLG_URB0RUNNING 1
#define FLG_URB1RUNNING 2
#define FLG_SYNC0RUNNING 4
#define FLG_SYNC1RUNNING 8
#define FLG_RUNNING 16
#define FLG_CONNECTED 32
struct my_data_urb {
struct urb *urb;
};
struct my_sync_urb {
struct urb *urb;
};
struct usb_audiodev {
struct list_head list;
struct usb_audio_state *state;
/* soundcore stuff */
int dev_audio;
/* wave stuff */
mode_t open_mode;
spinlock_t lock; /* DMA buffer access spinlock */
struct usbin {
int interface; /* Interface number, -1 means not used */
unsigned int format; /* USB data format */
unsigned int datapipe; /* the data input pipe */
unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but adaptive IN mode */
unsigned int syncinterval; /* P for adaptive IN mode, 0 otherwise */
unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */
unsigned int freqmax; /* maximum sampling rate, used for buffer management */
unsigned int phase; /* phase accumulator */
unsigned int flags; /* see FLG_ defines */
struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */
struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */
struct dmabuf dma;
} usbin;
struct usbout {
int interface; /* Interface number, -1 means not used */
unsigned int format; /* USB data format */
unsigned int datapipe; /* the data input pipe */
unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but asynchronous OUT mode */
unsigned int syncinterval; /* P for asynchronous OUT mode, 0 otherwise */
unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */
unsigned int freqm; /* momentary sampling rate in USB format, i.e. fs/1000 in Q10.14 */
unsigned int freqmax; /* maximum sampling rate, used for buffer management */
unsigned int phase; /* phase accumulator */
unsigned int flags; /* see FLG_ defines */
struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */
struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */
struct dmabuf dma;
} usbout;
unsigned int numfmtin, numfmtout;
struct audioformat fmtin[MAXFORMATS];
struct audioformat fmtout[MAXFORMATS];
};
struct usb_mixerdev {
struct list_head list;
struct usb_audio_state *state;
/* soundcore stuff */
int dev_mixer;
unsigned char iface; /* interface number of the AudioControl interface */
/* USB format descriptions */
unsigned int numch, modcnt;
/* mixch is last and gets allocated dynamically */
struct mixerchannel ch[0];
};
struct usb_audio_state {
struct list_head audiodev;
/* USB device */
struct usb_device *usbdev;
struct list_head audiolist;
struct list_head mixerlist;
unsigned count; /* usage counter; NOTE: the usb stack is also considered a user */
};
/* private audio format extensions */
#define AFMT_STEREO 0x80000000
#define AFMT_ISSTEREO(x) ((x) & AFMT_STEREO)
#define AFMT_IS16BIT(x) ((x) & (AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE))
#define AFMT_ISUNSIGNED(x) ((x) & (AFMT_U8|AFMT_U16_LE|AFMT_U16_BE))
#define AFMT_BYTESSHIFT(x) ((AFMT_ISSTEREO(x) ? 1 : 0) + (AFMT_IS16BIT(x) ? 1 : 0))
#define AFMT_BYTES(x) (1<<AFMT_BYTESSHFIT(x))
/* --------------------------------------------------------------------- */
static inline unsigned ld2(unsigned int x)
{
unsigned r = 0;
if (x >= 0x10000) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -