sound.h revision 162738
1156136Sdavidxu/*- 2156136Sdavidxu * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3156136Sdavidxu * Copyright by Hannu Savolainen 1995 4156136Sdavidxu * All rights reserved. 5156136Sdavidxu * 6156136Sdavidxu * Redistribution and use in source and binary forms, with or without 7156136Sdavidxu * modification, are permitted provided that the following conditions 8156136Sdavidxu * are met: 9156136Sdavidxu * 1. Redistributions of source code must retain the above copyright 10156136Sdavidxu * notice, this list of conditions and the following disclaimer. 11156136Sdavidxu * 2. Redistributions in binary form must reproduce the above copyright 12156136Sdavidxu * notice, this list of conditions and the following disclaimer in the 13156136Sdavidxu * documentation and/or other materials provided with the distribution. 14156136Sdavidxu * 15156136Sdavidxu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16156136Sdavidxu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17156136Sdavidxu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18156136Sdavidxu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19156136Sdavidxu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20156136Sdavidxu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21156136Sdavidxu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22156136Sdavidxu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23156136Sdavidxu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24156136Sdavidxu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25156136Sdavidxu * SUCH DAMAGE. 26156136Sdavidxu * 27156136Sdavidxu * $FreeBSD: head/sys/dev/sound/pcm/sound.h 162738 2006-09-28 17:29:00Z ariff $ 28156136Sdavidxu */ 29156136Sdavidxu 30156136Sdavidxu/* 31156136Sdavidxu * first, include kernel header files. 32156136Sdavidxu */ 33156136Sdavidxu 34156136Sdavidxu#ifndef _OS_H_ 35156267Sdavidxu#define _OS_H_ 36156136Sdavidxu 37156136Sdavidxu#ifdef _KERNEL 38156136Sdavidxu#include <sys/param.h> 39156136Sdavidxu#include <sys/systm.h> 40156136Sdavidxu#include <sys/ioccom.h> 41156136Sdavidxu#include <sys/filio.h> 42156136Sdavidxu#include <sys/sockio.h> 43156136Sdavidxu#include <sys/fcntl.h> 44156136Sdavidxu#include <sys/tty.h> 45156136Sdavidxu#include <sys/proc.h> 46156136Sdavidxu#include <sys/kernel.h> /* for DATA_SET */ 47156136Sdavidxu#include <sys/module.h> 48156136Sdavidxu#include <sys/conf.h> 49156136Sdavidxu#include <sys/file.h> 50156267Sdavidxu#include <sys/uio.h> 51156136Sdavidxu#include <sys/syslog.h> 52156136Sdavidxu#include <sys/errno.h> 53156383Sdavidxu#include <sys/malloc.h> 54181778Skmacy#include <sys/bus.h> 55156136Sdavidxu#if __FreeBSD_version < 500000 56156267Sdavidxu#include <sys/buf.h> 57156267Sdavidxu#endif 58156383Sdavidxu#include <machine/resource.h> 59156136Sdavidxu#include <machine/bus.h> 60156267Sdavidxu#include <sys/rman.h> 61156136Sdavidxu#include <sys/mman.h> 62156383Sdavidxu#include <sys/poll.h> 63156383Sdavidxu#include <sys/sbuf.h> 64156383Sdavidxu#include <sys/soundcard.h> 65156383Sdavidxu#include <sys/sysctl.h> 66156383Sdavidxu#include <sys/kobj.h> 67156383Sdavidxu#include <vm/vm.h> 68156383Sdavidxu#include <vm/pmap.h> 69156136Sdavidxu 70157242Sdeischen#undef USING_MUTEX 71156136Sdavidxu#undef USING_DEVFS 72156383Sdavidxu 73156383Sdavidxu#if __FreeBSD_version > 500000 74156136Sdavidxu#include <sys/lock.h> 75156383Sdavidxu#include <sys/mutex.h> 76156383Sdavidxu#include <sys/condvar.h> 77156383Sdavidxu 78156383Sdavidxu#define USING_MUTEX 79156136Sdavidxu#define USING_DEVFS 80156383Sdavidxu#else 81156383Sdavidxu#define INTR_TYPE_AV INTR_TYPE_TTY 82156136Sdavidxu#define INTR_MPSAFE 0 83156383Sdavidxu#endif 84156383Sdavidxu 85156383Sdavidxu#define SND_DYNSYSCTL 86156383Sdavidxu 87156383Sdavidxustruct pcm_channel; 88156383Sdavidxustruct pcm_feeder; 89156383Sdavidxustruct snd_dbuf; 90156383Sdavidxustruct snd_mixer; 91156383Sdavidxu 92156383Sdavidxu#include <dev/sound/pcm/buffer.h> 93156383Sdavidxu#include <dev/sound/pcm/channel.h> 94156383Sdavidxu#include <dev/sound/pcm/feeder.h> 95156383Sdavidxu#include <dev/sound/pcm/mixer.h> 96156383Sdavidxu#include <dev/sound/pcm/dsp.h> 97156383Sdavidxu 98156383Sdavidxu#define PCM_SOFTC_SIZE 512 99156383Sdavidxu 100156136Sdavidxu#define SND_STATUSLEN 64 101156136Sdavidxu 102156136Sdavidxu#define SOUND_MODVER 1 103156136Sdavidxu 104156136Sdavidxu#define SOUND_MINVER 1 105157242Sdeischen#define SOUND_PREFVER SOUND_MODVER 106156136Sdavidxu#define SOUND_MAXVER 1 107156136Sdavidxu 108156136Sdavidxu/* 109156136SdavidxuPROPOSAL: 110156136Sdavidxueach unit needs: 111156267Sdavidxustatus, mixer, dsp, dspW, audio, sequencer, midi-in, seq2, sndproc = 9 devices 112156383SdavidxudspW and audio are deprecated. 113156136Sdavidxudsp needs min 64 channels, will give it 256 114156136Sdavidxu 115156383Sdavidxuminor = (unit << 20) + (dev << 16) + channel 116156383Sdavidxucurrently minor = (channel << 16) + (unit << 4) + dev 117156136Sdavidxu 118156383Sdavidxunomenclature: 119156383Sdavidxu /dev/pcmX/dsp.(0..255) 120156383Sdavidxu /dev/pcmX/dspW 121156136Sdavidxu /dev/pcmX/audio 122156136Sdavidxu /dev/pcmX/status 123156136Sdavidxu /dev/pcmX/mixer 124156383Sdavidxu [etc.] 125156267Sdavidxu*/ 126156267Sdavidxu 127156383Sdavidxu#define PCMMAXCHAN 0xff 128156267Sdavidxu#define PCMMAXDEV 0x0f 129156267Sdavidxu#define PCMMAXUNIT 0x0f 130156267Sdavidxu#define PCMMINOR(x) (minor(x)) 131156267Sdavidxu#define PCMCHAN(x) ((PCMMINOR(x) >> 16) & PCMMAXCHAN) 132156267Sdavidxu#define PCMUNIT(x) ((PCMMINOR(x) >> 4) & PCMMAXUNIT) 133156267Sdavidxu#define PCMDEV(x) (PCMMINOR(x) & PCMMAXDEV) 134156383Sdavidxu#define PCMMKMINOR(u, d, c) ((((c) & PCMMAXCHAN) << 16) | \ 135156383Sdavidxu (((u) & PCMMAXUNIT) << 4) | ((d) & PCMMAXDEV)) 136156267Sdavidxu 137156383Sdavidxu#define SD_F_SIMPLEX 0x00000001 138156136Sdavidxu#define SD_F_AUTOVCHAN 0x00000002 139156267Sdavidxu#define SD_F_SOFTPCMVOL 0x00000004 140156136Sdavidxu#define SD_F_PRIO_RD 0x10000000 141156383Sdavidxu#define SD_F_PRIO_WR 0x20000000 142156136Sdavidxu#define SD_F_PRIO_SET (SD_F_PRIO_RD | SD_F_PRIO_WR) 143156136Sdavidxu#define SD_F_DIR_SET 0x40000000 144156136Sdavidxu#define SD_F_TRANSIENT 0xf0000000 145156136Sdavidxu 146156136Sdavidxu/* many variables should be reduced to a range. Here define a macro */ 147156136Sdavidxu#define RANGE(var, low, high) (var) = \ 148156136Sdavidxu (((var)<(low))? (low) : ((var)>(high))? (high) : (var)) 149156136Sdavidxu#define DSP_BUFFSIZE (8192) 150156136Sdavidxu 151156267Sdavidxu/* make figuring out what a format is easier. got AFMT_STEREO already */ 152156136Sdavidxu#define AFMT_32BIT (AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE) 153156136Sdavidxu#define AFMT_24BIT (AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE) 154156267Sdavidxu#define AFMT_16BIT (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE) 155156136Sdavidxu#define AFMT_8BIT (AFMT_MU_LAW | AFMT_A_LAW | AFMT_U8 | AFMT_S8) 156156136Sdavidxu#define AFMT_SIGNED (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE | \ 157156136Sdavidxu AFMT_S16_LE | AFMT_S16_BE | AFMT_S8) 158156136Sdavidxu#define AFMT_BIGENDIAN (AFMT_S32_BE | AFMT_U32_BE | AFMT_S24_BE | AFMT_U24_BE | \ 159156267Sdavidxu AFMT_S16_BE | AFMT_U16_BE) 160156136Sdavidxu 161156136Sdavidxustruct pcm_channel *fkchan_setup(device_t dev); 162156136Sdavidxuint fkchan_kill(struct pcm_channel *c); 163156136Sdavidxu 164156267Sdavidxu/* XXX Flawed definition. I'll fix it someday. */ 165156136Sdavidxu#define SND_MAXVCHANS PCMMAXCHAN 166156136Sdavidxu 167156267Sdavidxu/* 168156267Sdavidxu * Minor numbers for the sound driver. 169156267Sdavidxu * 170156267Sdavidxu * Unfortunately Creative called the codec chip of SB as a DSP. For this 171156267Sdavidxu * reason the /dev/dsp is reserved for digitized audio use. There is a 172156267Sdavidxu * device for true DSP processors but it will be called something else. 173156267Sdavidxu * In v3.0 it's /dev/sndproc but this could be a temporary solution. 174156136Sdavidxu */ 175156136Sdavidxu 176156136Sdavidxu#define SND_DEV_CTL 0 /* Control port /dev/mixer */ 177156383Sdavidxu#define SND_DEV_SEQ 1 /* Sequencer /dev/sequencer */ 178156136Sdavidxu#define SND_DEV_MIDIN 2 /* Raw midi access */ 179156136Sdavidxu#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ 180156383Sdavidxu#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ 181156136Sdavidxu#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ 182156136Sdavidxu#define SND_DEV_STATUS 6 /* /dev/sndstat */ 183156383Sdavidxu /* #7 not in use now. */ 184156136Sdavidxu#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ 185156136Sdavidxu#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ 186156383Sdavidxu#define SND_DEV_PSS SND_DEV_SNDPROC /* ? */ 187156136Sdavidxu#define SND_DEV_NORESET 10 188156136Sdavidxu#define SND_DEV_DSPREC 11 /* recording channels */ 189156136Sdavidxu 190156267Sdavidxu#define DSP_DEFAULT_SPEED 8000 191156383Sdavidxu 192156136Sdavidxu#define ON 1 193156136Sdavidxu#define OFF 0 194156136Sdavidxu 195156136Sdavidxuextern int pcm_veto_load; 196156136Sdavidxuextern int snd_unit; 197156136Sdavidxuextern devclass_t pcm_devclass; 198156383Sdavidxuextern struct unrhdr *pcmsg_unrhdr; 199156383Sdavidxu 200156383Sdavidxu/* 201156383Sdavidxu * some macros for debugging purposes 202156383Sdavidxu * DDB/DEB to enable/disable debugging stuff 203156383Sdavidxu * BVDDB to enable debugging when bootverbose 204156383Sdavidxu */ 205156383Sdavidxu#define BVDDB(x) if (bootverbose) x 206156383Sdavidxu 207156383Sdavidxu#ifndef DEB 208156383Sdavidxu#define DEB(x) 209156383Sdavidxu#endif 210156383Sdavidxu 211156383SdavidxuSYSCTL_DECL(_hw_snd); 212156383Sdavidxu 213156383Sdavidxustruct sysctl_ctx_list *snd_sysctl_tree(device_t dev); 214156383Sdavidxustruct sysctl_oid *snd_sysctl_tree_top(device_t dev); 215156383Sdavidxu 216156383Sdavidxustruct pcm_channel *pcm_getfakechan(struct snddev_info *d); 217156136Sdavidxuint pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, int chnum); 218156136Sdavidxuint pcm_chnrelease(struct pcm_channel *c); 219156136Sdavidxuint pcm_chnref(struct pcm_channel *c, int ref); 220156136Sdavidxuint pcm_inprog(struct snddev_info *d, int delta); 221156136Sdavidxu 222156136Sdavidxustruct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo); 223156136Sdavidxuint pcm_chn_destroy(struct pcm_channel *ch); 224156136Sdavidxuint pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch); 225156136Sdavidxuint pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch); 226156136Sdavidxu 227156383Sdavidxuint pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo); 228156136Sdavidxuunsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz); 229156136Sdavidxuint pcm_register(device_t dev, void *devinfo, int numplay, int numrec); 230156136Sdavidxuint pcm_unregister(device_t dev); 231156383Sdavidxuint pcm_setstatus(device_t dev, char *str); 232156136Sdavidxuu_int32_t pcm_getflags(device_t dev); 233156136Sdavidxuvoid pcm_setflags(device_t dev, u_int32_t val); 234156136Sdavidxuvoid *pcm_getdevinfo(device_t dev); 235156136Sdavidxu 236156136Sdavidxu 237156136Sdavidxuint snd_setup_intr(device_t dev, struct resource *res, int flags, 238156136Sdavidxu driver_intr_t hand, void *param, void **cookiep); 239156383Sdavidxu 240156136Sdavidxuvoid *snd_mtxcreate(const char *desc, const char *type); 241156136Sdavidxuvoid snd_mtxfree(void *m); 242156136Sdavidxuvoid snd_mtxassert(void *m); 243156136Sdavidxu#define snd_mtxlock(m) mtx_lock(m) 244156136Sdavidxu#define snd_mtxunlock(m) mtx_unlock(m) 245156136Sdavidxu 246156136Sdavidxuint sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS); 247156136Sdavidxu 248156136Sdavidxutypedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose); 249156136Sdavidxuint sndstat_acquire(void); 250156136Sdavidxuint sndstat_release(void); 251156136Sdavidxuint sndstat_register(device_t dev, char *str, sndstat_handler handler); 252156136Sdavidxuint sndstat_registerfile(char *str); 253156136Sdavidxuint sndstat_unregister(device_t dev); 254156136Sdavidxuint sndstat_unregisterfile(char *str); 255156136Sdavidxu 256156136Sdavidxu#define SND_DECLARE_FILE(version) \ 257156136Sdavidxu _SND_DECLARE_FILE(__LINE__, version) 258156136Sdavidxu 259156136Sdavidxu#define _SND_DECLARE_FILE(uniq, version) \ 260156136Sdavidxu __SND_DECLARE_FILE(uniq, version) 261156136Sdavidxu 262156136Sdavidxu#define __SND_DECLARE_FILE(uniq, version) \ 263156136Sdavidxu static char sndstat_vinfo[] = version; \ 264156136Sdavidxu SYSINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_registerfile, sndstat_vinfo); \ 265156136Sdavidxu SYSUNINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_unregisterfile, sndstat_vinfo); 266156136Sdavidxu 267156136Sdavidxu/* usage of flags in device config entry (config file) */ 268156136Sdavidxu#define DV_F_DRQ_MASK 0x00000007 /* mask for secondary drq */ 269156136Sdavidxu#define DV_F_DUAL_DMA 0x00000010 /* set to use secondary dma channel */ 270156136Sdavidxu 271156136Sdavidxu/* ought to be made obsolete but still used by mss */ 272156136Sdavidxu#define DV_F_DEV_MASK 0x0000ff00 /* force device type/class */ 273156136Sdavidxu#define DV_F_DEV_SHIFT 8 /* force device type/class */ 274156136Sdavidxu 275156136Sdavidxu#define PCM_DEBUG_MTX 276156136Sdavidxu 277156136Sdavidxu/* 278156136Sdavidxu * this is rather kludgey- we need to duplicate these struct def'ns from sound.c 279156136Sdavidxu * so that the macro versions of pcm_{,un}lock can dereference them. 280156136Sdavidxu * we also have to do this now makedev() has gone away. 281156267Sdavidxu */ 282156383Sdavidxu 283156136Sdavidxustruct snddev_channel { 284156136Sdavidxu SLIST_ENTRY(snddev_channel) link; 285156383Sdavidxu struct pcm_channel *channel; 286156136Sdavidxu int chan_num; 287156136Sdavidxu struct cdev *dsp_devt; 288156136Sdavidxu struct cdev *dspW_devt; 289156136Sdavidxu struct cdev *audio_devt; 290156383Sdavidxu struct cdev *dspr_devt; 291156136Sdavidxu}; 292156136Sdavidxu 293156136Sdavidxustruct snddev_info { 294156136Sdavidxu SLIST_HEAD(, snddev_channel) channels; 295156136Sdavidxu struct pcm_channel *fakechan; 296156136Sdavidxu unsigned devcount, playcount, reccount, vchancount; 297156136Sdavidxu unsigned flags; 298156136Sdavidxu int inprog; 299156136Sdavidxu unsigned int bufsz; 300156136Sdavidxu void *devinfo; 301156136Sdavidxu device_t dev; 302156136Sdavidxu char status[SND_STATUSLEN]; 303156136Sdavidxu struct sysctl_ctx_list sysctl_tree; 304156383Sdavidxu struct sysctl_oid *sysctl_tree_top; 305156383Sdavidxu struct mtx *lock; 306156136Sdavidxu struct cdev *mixer_dev; 307156383Sdavidxu 308156529Sdavidxu}; 309156136Sdavidxu 310156136Sdavidxuvoid sound_oss_sysinfo(oss_sysinfo *); 311156383Sdavidxu 312156383Sdavidxu#ifdef PCM_DEBUG_MTX 313156267Sdavidxu#define pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock) 314156383Sdavidxu#define pcm_unlock(d) mtx_unlock(((struct snddev_info *)(d))->lock) 315156383Sdavidxu#else 316156267Sdavidxuvoid pcm_lock(struct snddev_info *d); 317156267Sdavidxuvoid pcm_unlock(struct snddev_info *d); 318156136Sdavidxu#endif 319156136Sdavidxu 320156267Sdavidxu#ifdef KLD_MODULE 321156267Sdavidxu#define PCM_KLDSTRING(a) ("kld " # a) 322156383Sdavidxu#else 323156383Sdavidxu#define PCM_KLDSTRING(a) "" 324156383Sdavidxu#endif 325156383Sdavidxu 326156383Sdavidxu#endif /* _KERNEL */ 327156383Sdavidxu 328156383Sdavidxu#endif /* _OS_H_ */ 329156529Sdavidxu