1 /*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 struct pcmchan_children { 30 SLIST_ENTRY(pcmchan_children) link; 31 struct pcm_channel *channel; 32 }; 33 34 struct pcmchan_caps { 35 u_int32_t minspeed, maxspeed; 36 u_int32_t *fmtlist; 37 u_int32_t caps; 38 }; 39 40 /* Forward declarations */ 41 struct pcm_channel; 42 struct pcmchan_syncgroup; 43 struct pcmchan_syncmember; 44 45 extern struct mtx snd_pcm_syncgroups_mtx; 46 extern SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups; 47 48 #define PCM_SG_LOCK() mtx_lock(&snd_pcm_syncgroups_mtx) 49 #define PCM_SG_TRYLOCK() mtx_trylock(&snd_pcm_syncgroups_mtx) 50 #define PCM_SG_UNLOCK() mtx_unlock(&snd_pcm_syncgroups_mtx) 51 #define PCM_SG_LOCKASSERT(arg) mtx_assert(&snd_pcm_syncgroups_mtx, arg) 52 53 /** 54 * @brief Specifies an audio device sync group 55 */ 56 struct pcmchan_syncgroup { 57 SLIST_ENTRY(pcmchan_syncgroup) link; 58 SLIST_HEAD(, pcmchan_syncmember) members; 59 int id; /**< Group identifier; set to address of group. */ 60 }; 61 62 /** 63 * @brief Specifies a container for members of a sync group 64 */ 65 struct pcmchan_syncmember { 66 SLIST_ENTRY(pcmchan_syncmember) link; 67 struct pcmchan_syncgroup *parent; /**< group head */ 68 struct pcm_channel *ch; 69 }; 70 71 #define CHN_NAMELEN 32 72 struct pcm_channel { 73 kobj_t methods; 74 75 int num; 76 pid_t pid; 77 int refcount; 78 struct pcm_feeder *feeder; 79 u_int32_t align; 80 81 int volume; 82 int latency; 83 u_int32_t speed; 84 u_int32_t format; 85 u_int32_t flags; 86 u_int32_t feederflags; 87 u_int32_t blocks; 88 89 int direction; 90 unsigned int interrupts, xruns, feedcount; 91 unsigned int timeout; 92 struct snd_dbuf *bufhard, *bufsoft; 93 struct snddev_info *parentsnddev; 94 struct pcm_channel *parentchannel; 95 void *devinfo; 96 device_t dev; 97 char name[CHN_NAMELEN]; 98 struct mtx *lock; 99 /** 100 * Increment,decrement this around operations that temporarily yield 101 * lock. 102 */ 103 unsigned int inprog; 104 /** 105 * Special channel operations should examine @c inprog after acquiring 106 * lock. If zero, operations may continue. Else, thread should 107 * wait on this cv for previous operation to finish. 108 */ 109 struct cv cv; 110 /** 111 * Low water mark for select()/poll(). 112 * 113 * This is initialized to the channel's fragment size, and will be 114 * overwritten if a new fragment size is set. Users may alter this 115 * value directly with the @c SNDCTL_DSP_LOW_WATER ioctl. 116 */ 117 unsigned int lw; 118 /** 119 * If part of a sync group, this will point to the syncmember 120 * container. 121 */ 122 struct pcmchan_syncmember *sm; 123 #ifdef OSSV4_EXPERIMENT 124 u_int16_t lpeak, rpeak; /**< Peak value from 0-32767. */ 125 #endif 126 SLIST_HEAD(, pcmchan_children) children; 127 }; 128 129 #include "channel_if.h" 130 131 int chn_reinit(struct pcm_channel *c); 132 int chn_write(struct pcm_channel *c, struct uio *buf); 133 int chn_read(struct pcm_channel *c, struct uio *buf); 134 u_int32_t chn_start(struct pcm_channel *c, int force); 135 int chn_sync(struct pcm_channel *c, int threshold); 136 int chn_flush(struct pcm_channel *c); 137 int chn_poll(struct pcm_channel *c, int ev, struct thread *td); 138 139 int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction); 140 int chn_kill(struct pcm_channel *c); 141 int chn_setdir(struct pcm_channel *c, int dir); 142 int chn_reset(struct pcm_channel *c, u_int32_t fmt); 143 int chn_setvolume(struct pcm_channel *c, int left, int right); 144 int chn_setspeed(struct pcm_channel *c, int speed); 145 int chn_setformat(struct pcm_channel *c, u_int32_t fmt); 146 int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz); 147 int chn_setlatency(struct pcm_channel *c, int latency); 148 int chn_trigger(struct pcm_channel *c, int go); 149 int chn_getptr(struct pcm_channel *c); 150 struct pcmchan_caps *chn_getcaps(struct pcm_channel *c); 151 u_int32_t chn_getformats(struct pcm_channel *c); 152 153 void chn_resetbuf(struct pcm_channel *c); 154 void chn_intr(struct pcm_channel *c); 155 int chn_wrfeed(struct pcm_channel *c); 156 int chn_rdfeed(struct pcm_channel *c); 157 int chn_abort(struct pcm_channel *c); 158 159 void chn_wrupdate(struct pcm_channel *c); 160 void chn_rdupdate(struct pcm_channel *c); 161 162 int chn_notify(struct pcm_channel *c, u_int32_t flags); 163 void chn_lock(struct pcm_channel *c); 164 void chn_unlock(struct pcm_channel *c); 165 166 int chn_getrates(struct pcm_channel *c, int **rates); 167 int chn_syncdestroy(struct pcm_channel *c); 168 169 #ifdef OSSV4_EXPERIMENT 170 int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak); 171 #endif 172 173 #ifdef USING_MUTEX 174 #define CHN_LOCK(c) mtx_lock((struct mtx *)((c)->lock)) 175 #define CHN_UNLOCK(c) mtx_unlock((struct mtx *)((c)->lock)) 176 #define CHN_TRYLOCK(c) mtx_trylock((struct mtx *)((c)->lock)) 177 #define CHN_LOCKASSERT(c) mtx_assert((struct mtx *)((c)->lock), MA_OWNED) 178 #else 179 #define CHN_LOCK(c) 180 #define CHN_UNLOCK(c) 181 #define CHN_TRYLOCK(c) 182 #define CHN_LOCKASSERT(c) 183 #endif 184 185 int fmtvalid(u_int32_t fmt, u_int32_t *fmtlist); 186 187 #define AFMTSTR_NONE 0 /* "s16le" */ 188 #define AFMTSTR_SIMPLE 1 /* "s16le:s" */ 189 #define AFMTSTR_NUM 2 /* "s16le:2" */ 190 #define AFMTSTR_FULL 3 /* "s16le:stereo" */ 191 192 #define AFMTSTR_MAXSZ 13 /* include null terminator */ 193 194 #define AFMTSTR_MONO_RETURN 0 195 #define AFMTSTR_STEREO_RETURN 1 196 197 struct afmtstr_table { 198 char *fmtstr; 199 u_int32_t format; 200 }; 201 202 int afmtstr_swap_sign(char *); 203 int afmtstr_swap_endian(char *); 204 u_int32_t afmtstr2afmt(struct afmtstr_table *, const char *, int); 205 u_int32_t afmt2afmtstr(struct afmtstr_table *, u_int32_t, char *, size_t, int, int); 206 207 extern int chn_latency; 208 extern int chn_latency_profile; 209 extern int report_soft_formats; 210 211 #define PCMDIR_VIRTUAL 2 212 #define PCMDIR_PLAY 1 213 #define PCMDIR_REC -1 214 215 #define PCMTRIG_START 1 216 #define PCMTRIG_EMLDMAWR 2 217 #define PCMTRIG_EMLDMARD 3 218 #define PCMTRIG_STOP 0 219 #define PCMTRIG_ABORT -1 220 221 #define CHN_F_CLOSING 0x00000004 /* a pending close */ 222 #define CHN_F_ABORTING 0x00000008 /* a pending abort */ 223 #define CHN_F_RUNNING 0x00000010 /* dma is running */ 224 #define CHN_F_TRIGGERED 0x00000020 225 #define CHN_F_NOTRIGGER 0x00000040 226 227 #define CHN_F_BUSY 0x00001000 /* has been opened */ 228 #define CHN_F_HAS_SIZE 0x00002000 /* user set block size */ 229 #define CHN_F_NBIO 0x00004000 /* do non-blocking i/o */ 230 #define CHN_F_MAPPED 0x00010000 /* has been mmap()ed */ 231 #define CHN_F_DEAD 0x00020000 232 #define CHN_F_BADSETTING 0x00040000 233 #define CHN_F_SETBLOCKSIZE 0x00080000 234 #define CHN_F_HAS_VCHAN 0x00100000 235 236 #define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */ 237 238 #define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | \ 239 CHN_F_HAS_VCHAN | CHN_F_VIRTUAL) 240 241 242 #define CHN_N_RATE 0x00000001 243 #define CHN_N_FORMAT 0x00000002 244 #define CHN_N_VOLUME 0x00000004 245 #define CHN_N_BLOCKSIZE 0x00000008 246 #define CHN_N_TRIGGER 0x00000010 247 248 #define CHN_LATENCY_MIN 0 249 #define CHN_LATENCY_MAX 10 250 #define CHN_LATENCY_DEFAULT 5 251 #define CHN_POLICY_MIN CHN_LATENCY_MIN 252 #define CHN_POLICY_MAX CHN_LATENCY_MAX 253 #define CHN_POLICY_DEFAULT CHN_LATENCY_DEFAULT 254 255 #define CHN_LATENCY_PROFILE_MIN 0 256 #define CHN_LATENCY_PROFILE_MAX 1 257 #define CHN_LATENCY_PROFILE_DEFAULT CHN_LATENCY_PROFILE_MAX 258 259 /* 260 * This should be large enough to hold all pcm data between 261 * tsleeps in chn_{read,write} at the highest sample rate. 262 * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec) 263 */ 264 #define CHN_2NDBUFBLKSIZE (2 * 1024) 265 /* The total number of blocks per secondary bufhard. */ 266 #define CHN_2NDBUFBLKNUM (32) 267 /* The size of a whole secondary bufhard. */ 268 #define CHN_2NDBUFMAXSIZE (131072) 269 270 #define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj)) 271