1139749Simp/*-
2193640Sariff * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org>
3193640Sariff * Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006
4193640Sariff * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
550724Scg * All rights reserved.
650724Scg *
750724Scg * Redistribution and use in source and binary forms, with or without
850724Scg * modification, are permitted provided that the following conditions
950724Scg * are met:
1050724Scg * 1. Redistributions of source code must retain the above copyright
1150724Scg *    notice, this list of conditions and the following disclaimer.
1250724Scg * 2. Redistributions in binary form must reproduce the above copyright
1350724Scg *    notice, this list of conditions and the following disclaimer in the
1450724Scg *    documentation and/or other materials provided with the distribution.
1550724Scg *
1650724Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1750724Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1850724Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1950724Scg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2050724Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2150724Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2250724Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2350724Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2450724Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2550724Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2650724Scg * SUCH DAMAGE.
2750724Scg *
2850733Speter * $FreeBSD: stable/11/sys/dev/sound/pcm/channel.h 352326 2019-09-14 13:31:07Z hselasky $
2950724Scg */
3050724Scg
3174763Scgstruct pcmchan_caps {
3274763Scg	u_int32_t minspeed, maxspeed;
3374763Scg	u_int32_t *fmtlist;
3474763Scg	u_int32_t caps;
3574763Scg};
3674763Scg
37193640Sariffstruct pcmchan_matrix {
38193640Sariff	int id;
39193640Sariff	uint8_t channels, ext;
40193640Sariff	struct {
41193640Sariff		int type;
42193640Sariff		uint32_t members;
43193640Sariff	} map[SND_CHN_T_MAX + 1];
44193640Sariff	uint32_t mask;
45193640Sariff	int8_t offset[SND_CHN_T_MAX];
46193640Sariff};
47193640Sariff
48162588Snetchild/* Forward declarations */
49162588Snetchildstruct pcm_channel;
50162588Snetchildstruct pcmchan_syncgroup;
51162588Snetchildstruct pcmchan_syncmember;
52162588Snetchild
53162588Snetchildextern struct mtx snd_pcm_syncgroups_mtx;
54162588Snetchildextern SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups;
55162588Snetchild
56162588Snetchild#define PCM_SG_LOCK()	    mtx_lock(&snd_pcm_syncgroups_mtx)
57162588Snetchild#define PCM_SG_TRYLOCK()    mtx_trylock(&snd_pcm_syncgroups_mtx)
58162588Snetchild#define PCM_SG_UNLOCK()	    mtx_unlock(&snd_pcm_syncgroups_mtx)
59162588Snetchild#define PCM_SG_LOCKASSERT(arg)	mtx_assert(&snd_pcm_syncgroups_mtx, arg)
60162588Snetchild
61162588Snetchild/**
62162588Snetchild * @brief Specifies an audio device sync group
63162588Snetchild */
64162588Snetchildstruct pcmchan_syncgroup {
65162588Snetchild	SLIST_ENTRY(pcmchan_syncgroup) link;
66162588Snetchild	SLIST_HEAD(, pcmchan_syncmember) members;
67162588Snetchild	int id; /**< Group identifier; set to address of group. */
68162588Snetchild};
69162588Snetchild
70162588Snetchild/**
71162588Snetchild * @brief Specifies a container for members of a sync group
72162588Snetchild */
73162588Snetchildstruct pcmchan_syncmember {
74162588Snetchild	SLIST_ENTRY(pcmchan_syncmember) link;
75162588Snetchild	struct pcmchan_syncgroup *parent; /**< group head */
76162588Snetchild	struct pcm_channel *ch;
77162588Snetchild};
78162588Snetchild
79193640Sariff#define	CHN_NAMELEN		32
80193640Sariff#define	CHN_COMM_UNUSED		"<UNUSED>"
81193640Sariff#define	CHN_COMM_UNKNOWN	"<UNKNOWN>"
82193640Sariff
8374763Scgstruct pcm_channel {
8474763Scg	kobj_t methods;
8574763Scg
8677269Scg	pid_t pid;
8777269Scg	int refcount;
8874763Scg	struct pcm_feeder *feeder;
8974763Scg	u_int32_t align;
9074763Scg
91164614Sariff	int latency;
9274763Scg	u_int32_t speed;
9374763Scg	u_int32_t format;
9474763Scg	u_int32_t flags;
9574763Scg	u_int32_t feederflags;
96193640Sariff	u_int64_t blocks;
9774763Scg
9874763Scg	int direction;
99164614Sariff	unsigned int interrupts, xruns, feedcount;
100164614Sariff	unsigned int timeout;
10174763Scg	struct snd_dbuf *bufhard, *bufsoft;
10277269Scg	struct snddev_info *parentsnddev;
10377269Scg	struct pcm_channel *parentchannel;
10474763Scg	void *devinfo;
10589774Sscottl	device_t dev;
106170161Sariff	int unit;
10774763Scg	char name[CHN_NAMELEN];
108193640Sariff	char comm[MAXCOMLEN + 1];
109107285Scg	struct mtx *lock;
110170161Sariff	int trigger;
111162588Snetchild	/**
112170815Sariff	 * For interrupt manipulations.
113170815Sariff	 */
114170815Sariff	struct cv intr_cv;
115170815Sariff	/**
116162588Snetchild	 * Increment,decrement this around operations that temporarily yield
117162588Snetchild	 * lock.
118162588Snetchild	 */
119162588Snetchild	unsigned int inprog;
120162588Snetchild	/**
121162588Snetchild	 * Special channel operations should examine @c inprog after acquiring
122162588Snetchild	 * lock.  If zero, operations may continue.  Else, thread should
123162588Snetchild	 * wait on this cv for previous operation to finish.
124162588Snetchild	 */
125162588Snetchild	struct cv cv;
126162588Snetchild	/**
127162588Snetchild	 * Low water mark for select()/poll().
128162588Snetchild	 *
129162588Snetchild	 * This is initialized to the channel's fragment size, and will be
130162588Snetchild	 * overwritten if a new fragment size is set.  Users may alter this
131162588Snetchild	 * value directly with the @c SNDCTL_DSP_LOW_WATER ioctl.
132162588Snetchild	 */
133162588Snetchild	unsigned int lw;
134162588Snetchild	/**
135162588Snetchild	 * If part of a sync group, this will point to the syncmember
136162588Snetchild	 * container.
137162588Snetchild	 */
138162588Snetchild	struct pcmchan_syncmember *sm;
139162588Snetchild#ifdef OSSV4_EXPERIMENT
140162588Snetchild	u_int16_t lpeak, rpeak;	/**< Peak value from 0-32767. */
141162588Snetchild#endif
142170161Sariff
143170161Sariff	struct {
144170161Sariff		SLIST_HEAD(, pcm_channel) head;
145170161Sariff		SLIST_ENTRY(pcm_channel) link;
146170161Sariff		struct {
147170161Sariff			SLIST_HEAD(, pcm_channel) head;
148170161Sariff			SLIST_ENTRY(pcm_channel) link;
149170161Sariff		} busy;
150170161Sariff	} children;
151170161Sariff
152170161Sariff	struct {
153170161Sariff		struct {
154170161Sariff			SLIST_ENTRY(pcm_channel) link;
155170161Sariff			struct {
156170161Sariff				SLIST_ENTRY(pcm_channel) link;
157170161Sariff			} busy;
158193640Sariff			struct {
159193640Sariff				SLIST_ENTRY(pcm_channel) link;
160193640Sariff			} opened;
161170161Sariff		} pcm;
162170161Sariff	} channels;
163170161Sariff
164193640Sariff	struct pcmchan_matrix matrix;
165282650Shselasky  	struct pcmchan_matrix matrix_scratch;
166193640Sariff
167193640Sariff	int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
168193640Sariff
169170161Sariff	void *data1, *data2;
17074763Scg};
17174763Scg
172170161Sariff#define CHN_HEAD(x, y)			&(x)->y.head
173170161Sariff#define CHN_INIT(x, y)			SLIST_INIT(CHN_HEAD(x, y))
174170161Sariff#define CHN_LINK(y)			y.link
175170161Sariff#define CHN_EMPTY(x, y)			SLIST_EMPTY(CHN_HEAD(x, y))
176170161Sariff#define CHN_FIRST(x, y)			SLIST_FIRST(CHN_HEAD(x, y))
177170161Sariff
178170161Sariff#define CHN_FOREACH(x, y, z)						\
179170161Sariff	SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z))
180170161Sariff
181170161Sariff#define CHN_FOREACH_SAFE(w, x, y, z)					\
182170161Sariff	SLIST_FOREACH_SAFE(w, CHN_HEAD(x, z), CHN_LINK(z), y)
183170161Sariff
184170161Sariff#define CHN_INSERT_HEAD(x, y, z)					\
185170161Sariff	SLIST_INSERT_HEAD(CHN_HEAD(x, z), y, CHN_LINK(z))
186170161Sariff
187170161Sariff#define CHN_INSERT_AFTER(x, y, z)					\
188170161Sariff	SLIST_INSERT_AFTER(x, y, CHN_LINK(z))
189170161Sariff
190170161Sariff#define CHN_REMOVE(x, y, z)						\
191170161Sariff	SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z))
192170161Sariff
193170161Sariff#define CHN_INSERT_HEAD_SAFE(x, y, z)		do {			\
194170161Sariff	struct pcm_channel *t = NULL;					\
195170161Sariff	CHN_FOREACH(t, x, z) {						\
196170161Sariff		if (t == y)						\
197170161Sariff			break;						\
198170161Sariff	} 								\
199193640Sariff	if (t != y)							\
200170161Sariff		CHN_INSERT_HEAD(x, y, z);				\
201193640Sariff} while (0)
202170161Sariff
203170161Sariff#define CHN_INSERT_AFTER_SAFE(w, x, y, z)	do {			\
204170161Sariff	struct pcm_channel *t = NULL;					\
205170161Sariff	CHN_FOREACH(t, w, z) {						\
206170161Sariff		if (t == y)						\
207170161Sariff			break;						\
208170161Sariff	} 								\
209193640Sariff	if (t != y)							\
210170161Sariff		CHN_INSERT_AFTER(x, y, z);				\
211193640Sariff} while (0)
212170161Sariff
213170161Sariff#define CHN_REMOVE_SAFE(x, y, z)		do {			\
214170161Sariff	struct pcm_channel *t = NULL;					\
215170161Sariff	CHN_FOREACH(t, x, z) {						\
216170161Sariff		if (t == y)						\
217170161Sariff			break;						\
218170161Sariff	} 								\
219193640Sariff	if (t == y)							\
220170161Sariff		CHN_REMOVE(x, y, z);					\
221193640Sariff} while (0)
222193640Sariff
223193640Sariff#define CHN_INSERT_SORT(w, x, y, z)		do {			\
224193640Sariff	struct pcm_channel *t, *a = NULL;				\
225193640Sariff	CHN_FOREACH(t, x, z) {						\
226193640Sariff		if ((y)->unit w t->unit)				\
227193640Sariff			a = t;						\
228193640Sariff		else							\
229193640Sariff			break;						\
230170161Sariff	}								\
231193640Sariff	if (a != NULL)							\
232193640Sariff		CHN_INSERT_AFTER(a, y, z);				\
233193640Sariff	else								\
234193640Sariff		CHN_INSERT_HEAD(x, y, z);				\
235193640Sariff} while (0)
236170161Sariff
237193640Sariff#define CHN_INSERT_SORT_ASCEND(x, y, z)		CHN_INSERT_SORT(>, x, y, z)
238193640Sariff#define CHN_INSERT_SORT_DESCEND(x, y, z)	CHN_INSERT_SORT(<, x, y, z)
239193640Sariff
240170161Sariff#define CHN_UNIT(x)	(snd_unit2u((x)->unit))
241170161Sariff#define CHN_DEV(x)	(snd_unit2d((x)->unit))
242170161Sariff#define CHN_CHAN(x)	(snd_unit2c((x)->unit))
243170161Sariff
244170815Sariff#define CHN_BUF_PARENT(x, y)						\
245170815Sariff	(((x) != NULL && (x)->parentchannel != NULL &&			\
246170815Sariff	(x)->parentchannel->bufhard != NULL) ?				\
247170815Sariff	(x)->parentchannel->bufhard : (y))
248170815Sariff
249170815Sariff#define CHN_BROADCAST(x)	do {					\
250170815Sariff	if ((x)->cv_waiters != 0)					\
251170815Sariff		cv_broadcastpri(x, PRIBIO);				\
252193640Sariff} while (0)
253170815Sariff
25470134Scg#include "channel_if.h"
25570134Scg
25674763Scgint chn_reinit(struct pcm_channel *c);
25774763Scgint chn_write(struct pcm_channel *c, struct uio *buf);
25874763Scgint chn_read(struct pcm_channel *c, struct uio *buf);
25974763Scgu_int32_t chn_start(struct pcm_channel *c, int force);
26074763Scgint chn_sync(struct pcm_channel *c, int threshold);
26174763Scgint chn_flush(struct pcm_channel *c);
26283366Sjulianint chn_poll(struct pcm_channel *c, int ev, struct thread *td);
26350724Scg
264126367Struckmanint chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction);
26574763Scgint chn_kill(struct pcm_channel *c);
266193640Sariffint chn_reset(struct pcm_channel *c, u_int32_t fmt, u_int32_t spd);
26774763Scgint chn_setvolume(struct pcm_channel *c, int left, int right);
268193640Sariffint chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right,
269193640Sariff    int center);
270193640Sariffint chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val);
271193640Sariffint chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt);
272193640Sariffvoid chn_vpc_reset(struct pcm_channel *c, int vc, int force);
273193640Sariffint chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed);
274193640Sariffint chn_setspeed(struct pcm_channel *c, uint32_t speed);
275193640Sariffint chn_setformat(struct pcm_channel *c, uint32_t format);
27674763Scgint chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz);
277164614Sariffint chn_setlatency(struct pcm_channel *c, int latency);
278193640Sariffvoid chn_syncstate(struct pcm_channel *c);
27974763Scgint chn_trigger(struct pcm_channel *c, int go);
28074763Scgint chn_getptr(struct pcm_channel *c);
28174763Scgstruct pcmchan_caps *chn_getcaps(struct pcm_channel *c);
28274763Scgu_int32_t chn_getformats(struct pcm_channel *c);
28350724Scg
284193640Sariffstruct pcmchan_matrix *chn_getmatrix(struct pcm_channel *);
285193640Sariffint chn_setmatrix(struct pcm_channel *, struct pcmchan_matrix *);
286193640Sariff
287193640Sariffint chn_oss_getorder(struct pcm_channel *, unsigned long long *);
288193640Sariffint chn_oss_setorder(struct pcm_channel *, unsigned long long *);
289193640Sariffint chn_oss_getmask(struct pcm_channel *, uint32_t *);
290193640Sariff
29174763Scgvoid chn_resetbuf(struct pcm_channel *c);
292193640Sariffvoid chn_intr_locked(struct pcm_channel *c);
29374763Scgvoid chn_intr(struct pcm_channel *c);
29474763Scgint chn_abort(struct pcm_channel *c);
29550724Scg
29677269Scgint chn_notify(struct pcm_channel *c, u_int32_t flags);
29777269Scg
298162588Snetchildint chn_getrates(struct pcm_channel *c, int **rates);
299162588Snetchildint chn_syncdestroy(struct pcm_channel *c);
300162588Snetchild
301193640Sariff#define CHN_SETVOLUME(...)		chn_setvolume_matrix(__VA_ARGS__)
302193640Sariff#if defined(SND_DIAGNOSTIC) || defined(INVARIANTS)
303193640Sariff#define CHN_GETVOLUME(...)		chn_getvolume_matrix(__VA_ARGS__)
304193640Sariff#else
305193640Sariff#define CHN_GETVOLUME(x, y, z)		((x)->volume[y][z])
306193640Sariff#endif
307193640Sariff
308162588Snetchild#ifdef OSSV4_EXPERIMENT
309162588Snetchildint chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
310162588Snetchild#endif
311162588Snetchild
312193640Sariff#define CHN_LOCKOWNED(c)	mtx_owned((c)->lock)
313193640Sariff#define CHN_LOCK(c)		mtx_lock((c)->lock)
314193640Sariff#define CHN_UNLOCK(c)		mtx_unlock((c)->lock)
315193640Sariff#define CHN_TRYLOCK(c)		mtx_trylock((c)->lock)
316193640Sariff#define CHN_LOCKASSERT(c)	mtx_assert((c)->lock, MA_OWNED)
317193640Sariff#define CHN_UNLOCKASSERT(c)	mtx_assert((c)->lock, MA_NOTOWNED)
31874763Scg
319193640Sariffint snd_fmtvalid(uint32_t fmt, uint32_t *fmtlist);
32064881Scg
321193640Sariffuint32_t snd_str2afmt(const char *);
322193640Sariffuint32_t snd_afmt2str(uint32_t, char *, size_t);
323164614Sariff
324193640Sariff#define AFMTSTR_LEN	16
325164614Sariff
326164614Sariff
327164614Sariffextern int chn_latency;
328164614Sariffextern int chn_latency_profile;
329164614Sariffextern int report_soft_formats;
330193640Sariffextern int report_soft_matrix;
331164614Sariff
332170161Sariff#define PCMDIR_PLAY		1
333170161Sariff#define PCMDIR_PLAY_VIRTUAL	2
334170161Sariff#define PCMDIR_REC		-1
335170161Sariff#define PCMDIR_REC_VIRTUAL	-2
33650724Scg
33750724Scg#define PCMTRIG_START 1
33855204Scg#define PCMTRIG_EMLDMAWR 2
33960958Scg#define PCMTRIG_EMLDMARD 3
34050724Scg#define PCMTRIG_STOP 0
34150724Scg#define PCMTRIG_ABORT -1
34250724Scg
343170521Sariff#define PCMTRIG_COMMON(x)	((x) == PCMTRIG_START ||		\
344170521Sariff				 (x) == PCMTRIG_STOP ||			\
345170521Sariff				 (x) == PCMTRIG_ABORT)
346170521Sariff
347193640Sariff#define CHN_F_CLOSING           0x00000001  /* a pending close */
348193640Sariff#define CHN_F_ABORTING          0x00000002  /* a pending abort */
349193640Sariff#define CHN_F_RUNNING		0x00000004  /* dma is running */
350193640Sariff#define CHN_F_TRIGGERED		0x00000008
351193640Sariff#define CHN_F_NOTRIGGER		0x00000010
352193640Sariff#define CHN_F_SLEEPING		0x00000020
35350724Scg
354193640Sariff#define CHN_F_NBIO              0x00000040  /* do non-blocking i/o */
355193640Sariff#define CHN_F_MMAP		0x00000080  /* has been mmap()ed */
35650724Scg
357193640Sariff#define CHN_F_BUSY              0x00000100  /* has been opened 	*/
358193640Sariff#define CHN_F_DIRTY		0x00000200  /* need re-config */
359193640Sariff#define CHN_F_DEAD		0x00000400  /* too many errors, dead, mdk */
360193640Sariff#define CHN_F_SILENCE		0x00000800  /* silence, nil, null, yada */
361193640Sariff
362193640Sariff#define	CHN_F_HAS_SIZE		0x00001000  /* user set block size */
363193640Sariff#define CHN_F_HAS_VCHAN		0x00002000  /* vchan master */
364193640Sariff
365193640Sariff#define CHN_F_VCHAN_PASSTHROUGH	0x00004000  /* digital ac3/dts passthrough */
366193640Sariff#define CHN_F_VCHAN_ADAPTIVE	0x00008000  /* adaptive format/rate selection */
367193640Sariff#define CHN_F_VCHAN_DYNAMIC	(CHN_F_VCHAN_PASSTHROUGH | CHN_F_VCHAN_ADAPTIVE)
368193640Sariff
36977269Scg#define	CHN_F_VIRTUAL		0x10000000  /* not backed by hardware */
370193640Sariff#define CHN_F_BITPERFECT	0x20000000  /* un-cooked, Heh.. */
371193640Sariff#define CHN_F_PASSTHROUGH	0x40000000  /* passthrough re-config */
372193640Sariff#define CHN_F_EXCLUSIVE		0x80000000  /* exclusive access */
37354535Scg
374193640Sariff#define CHN_F_BITS		"\020"					\
375193640Sariff				"\001CLOSING"				\
376193640Sariff				"\002ABORTING"				\
377193640Sariff				"\003RUNNING"				\
378193640Sariff				"\004TRIGGERED"				\
379193640Sariff				"\005NOTRIGGER"				\
380193640Sariff				"\006SLEEPING"				\
381193640Sariff				"\007NBIO"				\
382193640Sariff				"\010MMAP"				\
383193640Sariff				"\011BUSY"				\
384193640Sariff				"\012DIRTY"				\
385193640Sariff				"\013DEAD"				\
386193640Sariff				"\014SILENCE"				\
387193640Sariff				"\015HAS_SIZE"				\
388193640Sariff				"\016HAS_VCHAN"				\
389193640Sariff				"\017VCHAN_PASSTHROUGH"			\
390193640Sariff				"\020VCHAN_ADAPTIVE"			\
391193640Sariff				"\035VIRTUAL"				\
392193640Sariff				"\036BITPERFECT"			\
393193640Sariff				"\037PASSTHROUGH"			\
394193640Sariff				"\040EXCLUSIVE"
395193640Sariff
396193640Sariff
397170815Sariff#define CHN_F_RESET		(CHN_F_BUSY | CHN_F_DEAD |		\
398193640Sariff				 CHN_F_VIRTUAL | CHN_F_HAS_VCHAN |	\
399193640Sariff				 CHN_F_VCHAN_DYNAMIC |			\
400193640Sariff				 CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE)
401170815Sariff
402170815Sariff#define CHN_F_MMAP_INVALID	(CHN_F_DEAD | CHN_F_RUNNING)
403170815Sariff
404149953Snetchild
40577269Scg
40677269Scg#define CHN_N_RATE		0x00000001
40777269Scg#define CHN_N_FORMAT		0x00000002
40877269Scg#define CHN_N_VOLUME		0x00000004
40977269Scg#define CHN_N_BLOCKSIZE		0x00000008
41077269Scg#define CHN_N_TRIGGER		0x00000010
41177269Scg
412164614Sariff#define CHN_LATENCY_MIN		0
413164614Sariff#define CHN_LATENCY_MAX		10
414352326Shselasky#define	CHN_LATENCY_DEFAULT	2	/* 21.3ms total buffering */
415164614Sariff#define CHN_POLICY_MIN		CHN_LATENCY_MIN
416164614Sariff#define CHN_POLICY_MAX		CHN_LATENCY_MAX
417164614Sariff#define CHN_POLICY_DEFAULT	CHN_LATENCY_DEFAULT
418164614Sariff
419164614Sariff#define CHN_LATENCY_PROFILE_MIN		0
420164614Sariff#define CHN_LATENCY_PROFILE_MAX		1
421164614Sariff#define CHN_LATENCY_PROFILE_DEFAULT	CHN_LATENCY_PROFILE_MAX
422164614Sariff
423170815Sariff#define CHN_STARTED(c)		((c)->flags & CHN_F_TRIGGERED)
424170815Sariff#define CHN_STOPPED(c)		(!CHN_STARTED(c))
425170815Sariff#define CHN_DIRSTR(c)		(((c)->direction == PCMDIR_PLAY) ? \
426170815Sariff				"PCMDIR_PLAY" : "PCMDIR_REC")
427193640Sariff#define CHN_BITPERFECT(c)	((c)->flags & CHN_F_BITPERFECT)
428193640Sariff#define CHN_PASSTHROUGH(c)	((c)->flags & CHN_F_PASSTHROUGH)
429170815Sariff
430170815Sariff#define CHN_TIMEOUT		5
431170815Sariff#define CHN_TIMEOUT_MIN		1
432170815Sariff#define CHN_TIMEOUT_MAX		10
433170815Sariff
43454535Scg/*
43554535Scg * This should be large enough to hold all pcm data between
43654535Scg * tsleeps in chn_{read,write} at the highest sample rate.
43754535Scg * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec)
43854535Scg */
43955204Scg#define CHN_2NDBUFBLKSIZE	(2 * 1024)
44074763Scg/* The total number of blocks per secondary bufhard. */
44159020Scg#define CHN_2NDBUFBLKNUM	(32)
44274763Scg/* The size of a whole secondary bufhard. */
44359246Scg#define CHN_2NDBUFMAXSIZE	(131072)
44470134Scg
44570134Scg#define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj))
446