⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* *	audio.c  --  USB Audio Class driver * *	Copyright (C) 1999, 2000, 2001 *	    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 *//* * 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: * - Pretty stable on UHCI-Acher/Fliegl/Sailer * - Does not work on OHCI due to lack of OHCI driver supporting URB's * * 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 fetched from the device. * Then the HEADER descriptor is fetched. 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/version.h>#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/wrapper.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)#undef absextern int abs(int __x) __attribute__ ((__const__)); /* Shut up warning *//* --------------------------------------------------------------------- *//* * 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  2struct 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    32struct my_data_urb {	urb_t urb;	iso_packet_descriptor_t isoframe[DESCFRAMES];};struct my_sync_urb {	urb_t urb;	iso_packet_descriptor_t isoframe[SYNCFRAMES];};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))/* --------------------------------------------------------------------- *//* prevent picking up a bogus abs macro */#undef absextern inline int abs(int x){        if (x < 0)		return -x;	return x;}                                /* --------------------------------------------------------------------- */extern inline unsigned ld2(unsigned int x){	unsigned r = 0;		if (x >= 0x10000) {		x >>= 16;		r += 16;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -