Commit | Line | Data |
---|---|---|
558a398b | 1 | /*- |
2a1ad637 FT |
2 | * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org> |
3 | * Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006 | |
4 | * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org> | |
984263bc MD |
5 | * All rights reserved. |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
26 | * SUCH DAMAGE. | |
27 | * | |
2a1ad637 | 28 | * $FreeBSD: head/sys/dev/sound/pcm/channel.h 193979 2009-06-11 09:06:09Z ariff $ |
984263bc MD |
29 | */ |
30 | ||
984263bc MD |
31 | struct pcmchan_caps { |
32 | u_int32_t minspeed, maxspeed; | |
33 | u_int32_t *fmtlist; | |
34 | u_int32_t caps; | |
35 | }; | |
36 | ||
2a1ad637 FT |
37 | struct pcmchan_matrix { |
38 | int id; | |
39 | uint8_t channels, ext; | |
40 | struct { | |
41 | int type; | |
42 | uint32_t members; | |
43 | } map[SND_CHN_T_MAX + 1]; | |
44 | uint32_t mask; | |
45 | int8_t offset[SND_CHN_T_MAX]; | |
46 | }; | |
47 | ||
48 | /* Forward declarations */ | |
49 | struct pcm_channel; | |
50 | struct pcmchan_syncgroup; | |
51 | struct pcmchan_syncmember; | |
52 | ||
67931cc4 | 53 | extern struct lock snd_pcm_syncgroups_mtx; |
2a1ad637 FT |
54 | extern SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups; |
55 | ||
67931cc4 | 56 | #define PCM_SG_LOCK() lockmgr(&snd_pcm_syncgroups_mtx, LK_EXCLUSIVE) |
833eb915 | 57 | #define PCM_SG_TRYLOCK() lockmgr_try(&snd_pcm_syncgroups_mtx, LK_EXCLUSIVE) |
67931cc4 | 58 | #define PCM_SG_UNLOCK() lockmgr(&snd_pcm_syncgroups_mtx, LK_RELEASE) |
5f097292 MD |
59 | #define PCM_SG_ASSERTOWNED KKASSERT(lockstatus(&snd_pcm_syncgroups_mtx, curthread) == LK_EXCLUSIVE) |
60 | #define PCM_SG_ASSERTNOTOWNED KKASSERT(lockstatus(&snd_pcm_syncgroups_mtx, curthread) != LK_EXCLUSIVE) | |
2a1ad637 FT |
61 | |
62 | /** | |
63 | * @brief Specifies an audio device sync group | |
64 | */ | |
65 | struct pcmchan_syncgroup { | |
66 | SLIST_ENTRY(pcmchan_syncgroup) link; | |
67 | SLIST_HEAD(, pcmchan_syncmember) members; | |
68 | int id; /**< Group identifier; set to address of group. */ | |
69 | }; | |
70 | ||
71 | /** | |
72 | * @brief Specifies a container for members of a sync group | |
73 | */ | |
74 | struct pcmchan_syncmember { | |
75 | SLIST_ENTRY(pcmchan_syncmember) link; | |
76 | struct pcmchan_syncgroup *parent; /**< group head */ | |
77 | struct pcm_channel *ch; | |
78 | }; | |
79 | ||
80 | #define CHN_NAMELEN 32 | |
81 | #define CHN_COMM_UNUSED "<UNUSED>" | |
82 | #define CHN_COMM_UNKNOWN "<UNKNOWN>" | |
83 | ||
984263bc MD |
84 | struct pcm_channel { |
85 | kobj_t methods; | |
86 | ||
984263bc MD |
87 | pid_t pid; |
88 | int refcount; | |
89 | struct pcm_feeder *feeder; | |
90 | u_int32_t align; | |
91 | ||
2a1ad637 | 92 | int latency; |
984263bc MD |
93 | u_int32_t speed; |
94 | u_int32_t format; | |
95 | u_int32_t flags; | |
96 | u_int32_t feederflags; | |
2a1ad637 | 97 | u_int64_t blocks; |
984263bc MD |
98 | |
99 | int direction; | |
2a1ad637 FT |
100 | unsigned int interrupts, xruns, feedcount; |
101 | unsigned int timeout; | |
984263bc MD |
102 | struct snd_dbuf *bufhard, *bufsoft; |
103 | struct snddev_info *parentsnddev; | |
104 | struct pcm_channel *parentchannel; | |
105 | void *devinfo; | |
106 | device_t dev; | |
2a1ad637 | 107 | int unit; |
984263bc | 108 | char name[CHN_NAMELEN]; |
2a1ad637 | 109 | char comm[MAXCOMLEN + 1]; |
67931cc4 | 110 | struct lock *lock; |
2a1ad637 FT |
111 | int trigger; |
112 | /** | |
113 | * For interrupt manipulations. | |
114 | */ | |
115 | struct cv intr_cv; | |
116 | /** | |
117 | * Increment,decrement this around operations that temporarily yield | |
118 | * lock. | |
119 | */ | |
120 | unsigned int inprog; | |
121 | /** | |
122 | * Special channel operations should examine @c inprog after acquiring | |
123 | * lock. If zero, operations may continue. Else, thread should | |
124 | * wait on this cv for previous operation to finish. | |
125 | */ | |
126 | struct cv cv; | |
127 | /** | |
128 | * Low water mark for select()/poll(). | |
129 | * | |
130 | * This is initialized to the channel's fragment size, and will be | |
131 | * overwritten if a new fragment size is set. Users may alter this | |
132 | * value directly with the @c SNDCTL_DSP_LOW_WATER ioctl. | |
133 | */ | |
134 | unsigned int lw; | |
135 | /** | |
136 | * If part of a sync group, this will point to the syncmember | |
137 | * container. | |
138 | */ | |
139 | struct pcmchan_syncmember *sm; | |
140 | #ifdef OSSV4_EXPERIMENT | |
141 | u_int16_t lpeak, rpeak; /**< Peak value from 0-32767. */ | |
142 | #endif | |
143 | ||
144 | struct { | |
145 | SLIST_HEAD(, pcm_channel) head; | |
146 | SLIST_ENTRY(pcm_channel) link; | |
147 | struct { | |
148 | SLIST_HEAD(, pcm_channel) head; | |
149 | SLIST_ENTRY(pcm_channel) link; | |
150 | } busy; | |
151 | } children; | |
152 | ||
153 | struct { | |
154 | struct { | |
155 | SLIST_ENTRY(pcm_channel) link; | |
156 | struct { | |
157 | SLIST_ENTRY(pcm_channel) link; | |
158 | } busy; | |
159 | struct { | |
160 | SLIST_ENTRY(pcm_channel) link; | |
161 | } opened; | |
162 | } pcm; | |
163 | } channels; | |
164 | ||
165 | struct pcmchan_matrix matrix; | |
166 | ||
167 | int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX]; | |
168 | ||
169 | void *data1, *data2; | |
984263bc MD |
170 | }; |
171 | ||
2a1ad637 FT |
172 | #define CHN_HEAD(x, y) &(x)->y.head |
173 | #define CHN_INIT(x, y) SLIST_INIT(CHN_HEAD(x, y)) | |
174 | #define CHN_LINK(y) y.link | |
175 | #define CHN_EMPTY(x, y) SLIST_EMPTY(CHN_HEAD(x, y)) | |
176 | #define CHN_FIRST(x, y) SLIST_FIRST(CHN_HEAD(x, y)) | |
177 | ||
178 | #define CHN_FOREACH(x, y, z) \ | |
179 | SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z)) | |
180 | ||
181 | #define CHN_FOREACH_SAFE(w, x, y, z) \ | |
67931cc4 | 182 | SLIST_FOREACH_MUTABLE(w, CHN_HEAD(x, z), CHN_LINK(z), y) |
2a1ad637 FT |
183 | |
184 | #define CHN_INSERT_HEAD(x, y, z) \ | |
185 | SLIST_INSERT_HEAD(CHN_HEAD(x, z), y, CHN_LINK(z)) | |
186 | ||
187 | #define CHN_INSERT_AFTER(x, y, z) \ | |
188 | SLIST_INSERT_AFTER(x, y, CHN_LINK(z)) | |
189 | ||
190 | #define CHN_REMOVE(x, y, z) \ | |
191 | SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z)) | |
192 | ||
193 | #define CHN_INSERT_HEAD_SAFE(x, y, z) do { \ | |
194 | struct pcm_channel *t = NULL; \ | |
195 | CHN_FOREACH(t, x, z) { \ | |
196 | if (t == y) \ | |
197 | break; \ | |
198 | } \ | |
199 | if (t != y) \ | |
200 | CHN_INSERT_HEAD(x, y, z); \ | |
201 | } while (0) | |
202 | ||
203 | #define CHN_INSERT_AFTER_SAFE(w, x, y, z) do { \ | |
204 | struct pcm_channel *t = NULL; \ | |
205 | CHN_FOREACH(t, w, z) { \ | |
206 | if (t == y) \ | |
207 | break; \ | |
208 | } \ | |
209 | if (t != y) \ | |
210 | CHN_INSERT_AFTER(x, y, z); \ | |
211 | } while (0) | |
212 | ||
213 | #define CHN_REMOVE_SAFE(x, y, z) do { \ | |
214 | struct pcm_channel *t = NULL; \ | |
215 | CHN_FOREACH(t, x, z) { \ | |
216 | if (t == y) \ | |
217 | break; \ | |
218 | } \ | |
219 | if (t == y) \ | |
220 | CHN_REMOVE(x, y, z); \ | |
221 | } while (0) | |
222 | ||
223 | #define CHN_INSERT_SORT(w, x, y, z) do { \ | |
224 | struct pcm_channel *t, *a = NULL; \ | |
225 | CHN_FOREACH(t, x, z) { \ | |
226 | if ((y)->unit w t->unit) \ | |
227 | a = t; \ | |
228 | else \ | |
229 | break; \ | |
230 | } \ | |
231 | if (a != NULL) \ | |
232 | CHN_INSERT_AFTER(a, y, z); \ | |
233 | else \ | |
234 | CHN_INSERT_HEAD(x, y, z); \ | |
235 | } while (0) | |
236 | ||
237 | #define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>, x, y, z) | |
238 | #define CHN_INSERT_SORT_DESCEND(x, y, z) CHN_INSERT_SORT(<, x, y, z) | |
239 | ||
240 | #define CHN_UNIT(x) (snd_unit2u((x)->unit)) | |
241 | #define CHN_DEV(x) (snd_unit2d((x)->unit)) | |
242 | #define CHN_CHAN(x) (snd_unit2c((x)->unit)) | |
243 | ||
244 | #define CHN_BUF_PARENT(x, y) \ | |
245 | (((x) != NULL && (x)->parentchannel != NULL && \ | |
246 | (x)->parentchannel->bufhard != NULL) ? \ | |
247 | (x)->parentchannel->bufhard : (y)) | |
248 | ||
249 | #define CHN_BROADCAST(x) do { \ | |
250 | if ((x)->cv_waiters != 0) \ | |
251 | cv_broadcastpri(x, PRIBIO); \ | |
252 | } while (0) | |
253 | ||
984263bc MD |
254 | #include "channel_if.h" |
255 | ||
256 | int chn_reinit(struct pcm_channel *c); | |
bb3a8342 SZ |
257 | int chn_write(struct pcm_channel *c, struct uio *buf, int ioflags); |
258 | int chn_read(struct pcm_channel *c, struct uio *buf, int ioflags); | |
984263bc MD |
259 | u_int32_t chn_start(struct pcm_channel *c, int force); |
260 | int chn_sync(struct pcm_channel *c, int threshold); | |
261 | int chn_flush(struct pcm_channel *c); | |
558a398b | 262 | int chn_poll(struct pcm_channel *c, int ev, struct thread *td); |
984263bc | 263 | |
558a398b | 264 | int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction); |
984263bc | 265 | int chn_kill(struct pcm_channel *c); |
2a1ad637 | 266 | int chn_reset(struct pcm_channel *c, u_int32_t fmt, u_int32_t spd); |
984263bc | 267 | int chn_setvolume(struct pcm_channel *c, int left, int right); |
2a1ad637 FT |
268 | int chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right, |
269 | int center); | |
270 | int chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val); | |
271 | int chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt); | |
272 | void chn_vpc_reset(struct pcm_channel *c, int vc, int force); | |
273 | int chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed); | |
274 | int chn_setspeed(struct pcm_channel *c, uint32_t speed); | |
275 | int chn_setformat(struct pcm_channel *c, uint32_t format); | |
984263bc | 276 | int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz); |
2a1ad637 FT |
277 | int chn_setlatency(struct pcm_channel *c, int latency); |
278 | void chn_syncstate(struct pcm_channel *c); | |
984263bc MD |
279 | int chn_trigger(struct pcm_channel *c, int go); |
280 | int chn_getptr(struct pcm_channel *c); | |
281 | struct pcmchan_caps *chn_getcaps(struct pcm_channel *c); | |
282 | u_int32_t chn_getformats(struct pcm_channel *c); | |
283 | ||
2a1ad637 FT |
284 | struct pcmchan_matrix *chn_getmatrix(struct pcm_channel *); |
285 | int chn_setmatrix(struct pcm_channel *, struct pcmchan_matrix *); | |
286 | ||
287 | int chn_oss_getorder(struct pcm_channel *, unsigned long long *); | |
288 | int chn_oss_setorder(struct pcm_channel *, unsigned long long *); | |
289 | int chn_oss_getmask(struct pcm_channel *, uint32_t *); | |
290 | ||
984263bc | 291 | void chn_resetbuf(struct pcm_channel *c); |
2a1ad637 | 292 | void chn_intr_locked(struct pcm_channel *c); |
984263bc | 293 | void chn_intr(struct pcm_channel *c); |
984263bc MD |
294 | int chn_abort(struct pcm_channel *c); |
295 | ||
984263bc MD |
296 | int chn_notify(struct pcm_channel *c, u_int32_t flags); |
297 | ||
2a1ad637 FT |
298 | int chn_getrates(struct pcm_channel *c, int **rates); |
299 | int chn_syncdestroy(struct pcm_channel *c); | |
300 | ||
301 | #define CHN_SETVOLUME(...) chn_setvolume_matrix(__VA_ARGS__) | |
302 | #if defined(SND_DIAGNOSTIC) || defined(INVARIANTS) | |
303 | #define CHN_GETVOLUME(...) chn_getvolume_matrix(__VA_ARGS__) | |
984263bc | 304 | #else |
2a1ad637 FT |
305 | #define CHN_GETVOLUME(x, y, z) ((x)->volume[y][z]) |
306 | #endif | |
307 | ||
308 | #ifdef OSSV4_EXPERIMENT | |
309 | int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak); | |
984263bc MD |
310 | #endif |
311 | ||
5f097292 | 312 | #define CHN_LOCKOWNED(c) (lockstatus((c)->lock, curthread) == LK_EXCLUSIVE) |
67931cc4 FT |
313 | #define CHN_LOCK(c) lockmgr((c)->lock, LK_EXCLUSIVE) |
314 | #define CHN_UNLOCK(c) lockmgr((c)->lock, LK_RELEASE) | |
7968600a | 315 | #define CHN_TRYLOCK(c) lockmgr_try((c)->lock, LK_EXCLUSIVE) |
5f097292 MD |
316 | #define CHN_LOCKASSERT(c) KKASSERT(lockstatus((c)->lock, curthread) == LK_EXCLUSIVE) |
317 | #define CHN_UNLOCKASSERT(c) KKASSERT(lockstatus((c)->lock, curthread) != LK_EXCLUSIVE) | |
2a1ad637 FT |
318 | |
319 | int snd_fmtvalid(uint32_t fmt, uint32_t *fmtlist); | |
320 | ||
321 | uint32_t snd_str2afmt(const char *); | |
322 | uint32_t snd_afmt2str(uint32_t, char *, size_t); | |
323 | ||
324 | #define AFMTSTR_LEN 16 | |
984263bc | 325 | |
2a1ad637 FT |
326 | |
327 | extern int chn_latency; | |
328 | extern int chn_latency_profile; | |
329 | extern int report_soft_formats; | |
330 | extern int report_soft_matrix; | |
331 | ||
332 | #define PCMDIR_PLAY 1 | |
333 | #define PCMDIR_PLAY_VIRTUAL 2 | |
334 | #define PCMDIR_REC -1 | |
335 | #define PCMDIR_REC_VIRTUAL -2 | |
984263bc MD |
336 | |
337 | #define PCMTRIG_START 1 | |
338 | #define PCMTRIG_EMLDMAWR 2 | |
339 | #define PCMTRIG_EMLDMARD 3 | |
340 | #define PCMTRIG_STOP 0 | |
341 | #define PCMTRIG_ABORT -1 | |
342 | ||
d3474664 SW |
343 | #define PCMTRIG_COMMON(x) ((x) == PCMTRIG_START || \ |
344 | (x) == PCMTRIG_STOP || \ | |
345 | (x) == PCMTRIG_ABORT) | |
346 | ||
2a1ad637 FT |
347 | #define CHN_F_CLOSING 0x00000001 /* a pending close */ |
348 | #define CHN_F_ABORTING 0x00000002 /* a pending abort */ | |
349 | #define CHN_F_RUNNING 0x00000004 /* dma is running */ | |
350 | #define CHN_F_TRIGGERED 0x00000008 | |
351 | #define CHN_F_NOTRIGGER 0x00000010 | |
352 | #define CHN_F_SLEEPING 0x00000020 | |
353 | ||
bb3a8342 | 354 | #define CHN_F_UNUSED1 0x00000040 |
2a1ad637 FT |
355 | #define CHN_F_MMAP 0x00000080 /* has been mmap()ed */ |
356 | ||
357 | #define CHN_F_BUSY 0x00000100 /* has been opened */ | |
358 | #define CHN_F_DIRTY 0x00000200 /* need re-config */ | |
359 | #define CHN_F_DEAD 0x00000400 /* too many errors, dead, mdk */ | |
360 | #define CHN_F_SILENCE 0x00000800 /* silence, nil, null, yada */ | |
361 | ||
362 | #define CHN_F_HAS_SIZE 0x00001000 /* user set block size */ | |
363 | #define CHN_F_HAS_VCHAN 0x00002000 /* vchan master */ | |
364 | ||
365 | #define CHN_F_VCHAN_PASSTHROUGH 0x00004000 /* digital ac3/dts passthrough */ | |
366 | #define CHN_F_VCHAN_ADAPTIVE 0x00008000 /* adaptive format/rate selection */ | |
367 | #define CHN_F_VCHAN_DYNAMIC (CHN_F_VCHAN_PASSTHROUGH | CHN_F_VCHAN_ADAPTIVE) | |
984263bc MD |
368 | |
369 | #define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */ | |
2a1ad637 FT |
370 | #define CHN_F_BITPERFECT 0x20000000 /* un-cooked, Heh.. */ |
371 | #define CHN_F_PASSTHROUGH 0x40000000 /* passthrough re-config */ | |
372 | #define CHN_F_EXCLUSIVE 0x80000000 /* exclusive access */ | |
373 | ||
374 | #define CHN_F_BITS "\020" \ | |
375 | "\001CLOSING" \ | |
376 | "\002ABORTING" \ | |
377 | "\003RUNNING" \ | |
378 | "\004TRIGGERED" \ | |
379 | "\005NOTRIGGER" \ | |
380 | "\006SLEEPING" \ | |
381 | "\007NBIO" \ | |
382 | "\010MMAP" \ | |
383 | "\011BUSY" \ | |
384 | "\012DIRTY" \ | |
385 | "\013DEAD" \ | |
386 | "\014SILENCE" \ | |
387 | "\015HAS_SIZE" \ | |
388 | "\016HAS_VCHAN" \ | |
389 | "\017VCHAN_PASSTHROUGH" \ | |
390 | "\020VCHAN_ADAPTIVE" \ | |
391 | "\035VIRTUAL" \ | |
392 | "\036BITPERFECT" \ | |
393 | "\037PASSTHROUGH" \ | |
394 | "\040EXCLUSIVE" | |
395 | ||
396 | ||
397 | #define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | \ | |
398 | CHN_F_VIRTUAL | CHN_F_HAS_VCHAN | \ | |
399 | CHN_F_VCHAN_DYNAMIC | \ | |
400 | CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE) | |
401 | ||
402 | #define CHN_F_MMAP_INVALID (CHN_F_DEAD | CHN_F_RUNNING) | |
984263bc | 403 | |
558a398b | 404 | |
984263bc MD |
405 | |
406 | #define CHN_N_RATE 0x00000001 | |
407 | #define CHN_N_FORMAT 0x00000002 | |
408 | #define CHN_N_VOLUME 0x00000004 | |
409 | #define CHN_N_BLOCKSIZE 0x00000008 | |
410 | #define CHN_N_TRIGGER 0x00000010 | |
411 | ||
2a1ad637 FT |
412 | #define CHN_LATENCY_MIN 0 |
413 | #define CHN_LATENCY_MAX 10 | |
414 | #define CHN_LATENCY_DEFAULT 5 | |
415 | #define CHN_POLICY_MIN CHN_LATENCY_MIN | |
416 | #define CHN_POLICY_MAX CHN_LATENCY_MAX | |
417 | #define CHN_POLICY_DEFAULT CHN_LATENCY_DEFAULT | |
418 | ||
419 | #define CHN_LATENCY_PROFILE_MIN 0 | |
420 | #define CHN_LATENCY_PROFILE_MAX 1 | |
421 | #define CHN_LATENCY_PROFILE_DEFAULT CHN_LATENCY_PROFILE_MAX | |
422 | ||
423 | #define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED) | |
424 | #define CHN_STOPPED(c) (!CHN_STARTED(c)) | |
425 | #define CHN_DIRSTR(c) (((c)->direction == PCMDIR_PLAY) ? \ | |
426 | "PCMDIR_PLAY" : "PCMDIR_REC") | |
427 | #define CHN_BITPERFECT(c) ((c)->flags & CHN_F_BITPERFECT) | |
428 | #define CHN_PASSTHROUGH(c) ((c)->flags & CHN_F_PASSTHROUGH) | |
429 | ||
430 | #define CHN_TIMEOUT 5 | |
431 | #define CHN_TIMEOUT_MIN 1 | |
432 | #define CHN_TIMEOUT_MAX 10 | |
433 | ||
984263bc MD |
434 | /* |
435 | * This should be large enough to hold all pcm data between | |
436 | * tsleeps in chn_{read,write} at the highest sample rate. | |
437 | * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec) | |
438 | */ | |
439 | #define CHN_2NDBUFBLKSIZE (2 * 1024) | |
440 | /* The total number of blocks per secondary bufhard. */ | |
441 | #define CHN_2NDBUFBLKNUM (32) | |
442 | /* The size of a whole secondary bufhard. */ | |
443 | #define CHN_2NDBUFMAXSIZE (131072) | |
444 | ||
445 | #define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj)) |