Deleted Added
full compact
channel.h (170521) channel.h (170815)
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 *
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: head/sys/dev/sound/pcm/channel.h 170521 2007-06-11 00:49:46Z ariff $
26 * $FreeBSD: head/sys/dev/sound/pcm/channel.h 170815 2007-06-16 03:37:28Z ariff $
27 */
28
29struct pcmchan_caps {
30 u_int32_t minspeed, maxspeed;
31 u_int32_t *fmtlist;
32 u_int32_t caps;
33};
34
35/* Forward declarations */
36struct pcm_channel;
37struct pcmchan_syncgroup;
38struct pcmchan_syncmember;
39
40extern struct mtx snd_pcm_syncgroups_mtx;
41extern SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups;
42
43#define PCM_SG_LOCK() mtx_lock(&snd_pcm_syncgroups_mtx)
44#define PCM_SG_TRYLOCK() mtx_trylock(&snd_pcm_syncgroups_mtx)
45#define PCM_SG_UNLOCK() mtx_unlock(&snd_pcm_syncgroups_mtx)
46#define PCM_SG_LOCKASSERT(arg) mtx_assert(&snd_pcm_syncgroups_mtx, arg)
47
48/**
49 * @brief Specifies an audio device sync group
50 */
51struct pcmchan_syncgroup {
52 SLIST_ENTRY(pcmchan_syncgroup) link;
53 SLIST_HEAD(, pcmchan_syncmember) members;
54 int id; /**< Group identifier; set to address of group. */
55};
56
57/**
58 * @brief Specifies a container for members of a sync group
59 */
60struct pcmchan_syncmember {
61 SLIST_ENTRY(pcmchan_syncmember) link;
62 struct pcmchan_syncgroup *parent; /**< group head */
63 struct pcm_channel *ch;
64};
65
66#define CHN_NAMELEN 32
67struct pcm_channel {
68 kobj_t methods;
69
70 pid_t pid;
71 int refcount;
72 struct pcm_feeder *feeder;
73 u_int32_t align;
74
75 int volume;
76 int latency;
77 u_int32_t speed;
78 u_int32_t format;
79 u_int32_t flags;
80 u_int32_t feederflags;
81 u_int32_t blocks;
82
83 int direction;
84 unsigned int interrupts, xruns, feedcount;
85 unsigned int timeout;
86 struct snd_dbuf *bufhard, *bufsoft;
87 struct snddev_info *parentsnddev;
88 struct pcm_channel *parentchannel;
89 void *devinfo;
90 device_t dev;
91 int unit;
92 char name[CHN_NAMELEN];
93 struct mtx *lock;
94 int trigger;
95 /**
27 */
28
29struct pcmchan_caps {
30 u_int32_t minspeed, maxspeed;
31 u_int32_t *fmtlist;
32 u_int32_t caps;
33};
34
35/* Forward declarations */
36struct pcm_channel;
37struct pcmchan_syncgroup;
38struct pcmchan_syncmember;
39
40extern struct mtx snd_pcm_syncgroups_mtx;
41extern SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups;
42
43#define PCM_SG_LOCK() mtx_lock(&snd_pcm_syncgroups_mtx)
44#define PCM_SG_TRYLOCK() mtx_trylock(&snd_pcm_syncgroups_mtx)
45#define PCM_SG_UNLOCK() mtx_unlock(&snd_pcm_syncgroups_mtx)
46#define PCM_SG_LOCKASSERT(arg) mtx_assert(&snd_pcm_syncgroups_mtx, arg)
47
48/**
49 * @brief Specifies an audio device sync group
50 */
51struct pcmchan_syncgroup {
52 SLIST_ENTRY(pcmchan_syncgroup) link;
53 SLIST_HEAD(, pcmchan_syncmember) members;
54 int id; /**< Group identifier; set to address of group. */
55};
56
57/**
58 * @brief Specifies a container for members of a sync group
59 */
60struct pcmchan_syncmember {
61 SLIST_ENTRY(pcmchan_syncmember) link;
62 struct pcmchan_syncgroup *parent; /**< group head */
63 struct pcm_channel *ch;
64};
65
66#define CHN_NAMELEN 32
67struct pcm_channel {
68 kobj_t methods;
69
70 pid_t pid;
71 int refcount;
72 struct pcm_feeder *feeder;
73 u_int32_t align;
74
75 int volume;
76 int latency;
77 u_int32_t speed;
78 u_int32_t format;
79 u_int32_t flags;
80 u_int32_t feederflags;
81 u_int32_t blocks;
82
83 int direction;
84 unsigned int interrupts, xruns, feedcount;
85 unsigned int timeout;
86 struct snd_dbuf *bufhard, *bufsoft;
87 struct snddev_info *parentsnddev;
88 struct pcm_channel *parentchannel;
89 void *devinfo;
90 device_t dev;
91 int unit;
92 char name[CHN_NAMELEN];
93 struct mtx *lock;
94 int trigger;
95 /**
96 * For interrupt manipulations.
97 */
98 struct cv intr_cv;
99 /**
96 * Increment,decrement this around operations that temporarily yield
97 * lock.
98 */
99 unsigned int inprog;
100 /**
101 * Special channel operations should examine @c inprog after acquiring
102 * lock. If zero, operations may continue. Else, thread should
103 * wait on this cv for previous operation to finish.
104 */
105 struct cv cv;
106 /**
107 * Low water mark for select()/poll().
108 *
109 * This is initialized to the channel's fragment size, and will be
110 * overwritten if a new fragment size is set. Users may alter this
111 * value directly with the @c SNDCTL_DSP_LOW_WATER ioctl.
112 */
113 unsigned int lw;
114 /**
115 * If part of a sync group, this will point to the syncmember
116 * container.
117 */
118 struct pcmchan_syncmember *sm;
119#ifdef OSSV4_EXPERIMENT
120 u_int16_t lpeak, rpeak; /**< Peak value from 0-32767. */
121#endif
122
123 struct {
124 SLIST_HEAD(, pcm_channel) head;
125 SLIST_ENTRY(pcm_channel) link;
126 struct {
127 SLIST_HEAD(, pcm_channel) head;
128 SLIST_ENTRY(pcm_channel) link;
129 } busy;
130 } children;
131
132 struct {
133 struct {
134 SLIST_ENTRY(pcm_channel) link;
135 struct {
136 SLIST_ENTRY(pcm_channel) link;
137 } busy;
138 } pcm;
139 } channels;
140
141 void *data1, *data2;
142};
143
144#define CHN_HEAD(x, y) &(x)->y.head
145#define CHN_INIT(x, y) SLIST_INIT(CHN_HEAD(x, y))
146#define CHN_LINK(y) y.link
147#define CHN_EMPTY(x, y) SLIST_EMPTY(CHN_HEAD(x, y))
148#define CHN_FIRST(x, y) SLIST_FIRST(CHN_HEAD(x, y))
149
150#define CHN_FOREACH(x, y, z) \
151 SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z))
152
153#define CHN_FOREACH_SAFE(w, x, y, z) \
154 SLIST_FOREACH_SAFE(w, CHN_HEAD(x, z), CHN_LINK(z), y)
155
156#define CHN_INSERT_HEAD(x, y, z) \
157 SLIST_INSERT_HEAD(CHN_HEAD(x, z), y, CHN_LINK(z))
158
159#define CHN_INSERT_AFTER(x, y, z) \
160 SLIST_INSERT_AFTER(x, y, CHN_LINK(z))
161
162#define CHN_REMOVE(x, y, z) \
163 SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z))
164
165#define CHN_INSERT_HEAD_SAFE(x, y, z) do { \
166 struct pcm_channel *t = NULL; \
167 CHN_FOREACH(t, x, z) { \
168 if (t == y) \
169 break; \
170 } \
171 if (t != y) { \
172 CHN_INSERT_HEAD(x, y, z); \
173 } \
174} while(0)
175
176#define CHN_INSERT_AFTER_SAFE(w, x, y, z) do { \
177 struct pcm_channel *t = NULL; \
178 CHN_FOREACH(t, w, z) { \
179 if (t == y) \
180 break; \
181 } \
182 if (t != y) { \
183 CHN_INSERT_AFTER(x, y, z); \
184 } \
185} while(0)
186
187#define CHN_REMOVE_SAFE(x, y, z) do { \
188 struct pcm_channel *t = NULL; \
189 CHN_FOREACH(t, x, z) { \
190 if (t == y) \
191 break; \
192 } \
193 if (t == y) { \
194 CHN_REMOVE(x, y, z); \
195 } \
196} while(0)
197
198#define CHN_UNIT(x) (snd_unit2u((x)->unit))
199#define CHN_DEV(x) (snd_unit2d((x)->unit))
200#define CHN_CHAN(x) (snd_unit2c((x)->unit))
201
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
127 struct {
128 SLIST_HEAD(, pcm_channel) head;
129 SLIST_ENTRY(pcm_channel) link;
130 struct {
131 SLIST_HEAD(, pcm_channel) head;
132 SLIST_ENTRY(pcm_channel) link;
133 } busy;
134 } children;
135
136 struct {
137 struct {
138 SLIST_ENTRY(pcm_channel) link;
139 struct {
140 SLIST_ENTRY(pcm_channel) link;
141 } busy;
142 } pcm;
143 } channels;
144
145 void *data1, *data2;
146};
147
148#define CHN_HEAD(x, y) &(x)->y.head
149#define CHN_INIT(x, y) SLIST_INIT(CHN_HEAD(x, y))
150#define CHN_LINK(y) y.link
151#define CHN_EMPTY(x, y) SLIST_EMPTY(CHN_HEAD(x, y))
152#define CHN_FIRST(x, y) SLIST_FIRST(CHN_HEAD(x, y))
153
154#define CHN_FOREACH(x, y, z) \
155 SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z))
156
157#define CHN_FOREACH_SAFE(w, x, y, z) \
158 SLIST_FOREACH_SAFE(w, CHN_HEAD(x, z), CHN_LINK(z), y)
159
160#define CHN_INSERT_HEAD(x, y, z) \
161 SLIST_INSERT_HEAD(CHN_HEAD(x, z), y, CHN_LINK(z))
162
163#define CHN_INSERT_AFTER(x, y, z) \
164 SLIST_INSERT_AFTER(x, y, CHN_LINK(z))
165
166#define CHN_REMOVE(x, y, z) \
167 SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z))
168
169#define CHN_INSERT_HEAD_SAFE(x, y, z) do { \
170 struct pcm_channel *t = NULL; \
171 CHN_FOREACH(t, x, z) { \
172 if (t == y) \
173 break; \
174 } \
175 if (t != y) { \
176 CHN_INSERT_HEAD(x, y, z); \
177 } \
178} while(0)
179
180#define CHN_INSERT_AFTER_SAFE(w, x, y, z) do { \
181 struct pcm_channel *t = NULL; \
182 CHN_FOREACH(t, w, z) { \
183 if (t == y) \
184 break; \
185 } \
186 if (t != y) { \
187 CHN_INSERT_AFTER(x, y, z); \
188 } \
189} while(0)
190
191#define CHN_REMOVE_SAFE(x, y, z) do { \
192 struct pcm_channel *t = NULL; \
193 CHN_FOREACH(t, x, z) { \
194 if (t == y) \
195 break; \
196 } \
197 if (t == y) { \
198 CHN_REMOVE(x, y, z); \
199 } \
200} while(0)
201
202#define CHN_UNIT(x) (snd_unit2u((x)->unit))
203#define CHN_DEV(x) (snd_unit2d((x)->unit))
204#define CHN_CHAN(x) (snd_unit2c((x)->unit))
205
206#define CHN_BUF_PARENT(x, y) \
207 (((x) != NULL && (x)->parentchannel != NULL && \
208 (x)->parentchannel->bufhard != NULL) ? \
209 (x)->parentchannel->bufhard : (y))
210
211#define CHN_BROADCAST(x) do { \
212 if ((x)->cv_waiters != 0) \
213 cv_broadcastpri(x, PRIBIO); \
214} while(0)
215
202#include "channel_if.h"
203
204int chn_reinit(struct pcm_channel *c);
205int chn_write(struct pcm_channel *c, struct uio *buf);
206int chn_read(struct pcm_channel *c, struct uio *buf);
207u_int32_t chn_start(struct pcm_channel *c, int force);
208int chn_sync(struct pcm_channel *c, int threshold);
209int chn_flush(struct pcm_channel *c);
210int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
211
212int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction);
213int chn_kill(struct pcm_channel *c);
214int chn_setdir(struct pcm_channel *c, int dir);
215int chn_reset(struct pcm_channel *c, u_int32_t fmt);
216int chn_setvolume(struct pcm_channel *c, int left, int right);
217int chn_setspeed(struct pcm_channel *c, int speed);
218int chn_setformat(struct pcm_channel *c, u_int32_t fmt);
219int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz);
220int chn_setlatency(struct pcm_channel *c, int latency);
221int chn_trigger(struct pcm_channel *c, int go);
222int chn_getptr(struct pcm_channel *c);
223struct pcmchan_caps *chn_getcaps(struct pcm_channel *c);
224u_int32_t chn_getformats(struct pcm_channel *c);
225
226void chn_resetbuf(struct pcm_channel *c);
227void chn_intr(struct pcm_channel *c);
228int chn_wrfeed(struct pcm_channel *c);
229int chn_rdfeed(struct pcm_channel *c);
230int chn_abort(struct pcm_channel *c);
231
232void chn_wrupdate(struct pcm_channel *c);
233void chn_rdupdate(struct pcm_channel *c);
234
235int chn_notify(struct pcm_channel *c, u_int32_t flags);
236void chn_lock(struct pcm_channel *c);
237void chn_unlock(struct pcm_channel *c);
238
239int chn_getrates(struct pcm_channel *c, int **rates);
240int chn_syncdestroy(struct pcm_channel *c);
241
242#ifdef OSSV4_EXPERIMENT
243int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
244#endif
245
246#ifdef USING_MUTEX
247#define CHN_LOCK(c) mtx_lock((struct mtx *)((c)->lock))
248#define CHN_UNLOCK(c) mtx_unlock((struct mtx *)((c)->lock))
249#define CHN_TRYLOCK(c) mtx_trylock((struct mtx *)((c)->lock))
250#define CHN_LOCKASSERT(c) mtx_assert((struct mtx *)((c)->lock), MA_OWNED)
251#else
252#define CHN_LOCK(c)
253#define CHN_UNLOCK(c)
254#define CHN_TRYLOCK(c)
255#define CHN_LOCKASSERT(c)
256#endif
257
258int fmtvalid(u_int32_t fmt, u_int32_t *fmtlist);
259
260#define AFMTSTR_NONE 0 /* "s16le" */
261#define AFMTSTR_SIMPLE 1 /* "s16le:s" */
262#define AFMTSTR_NUM 2 /* "s16le:2" */
263#define AFMTSTR_FULL 3 /* "s16le:stereo" */
264
265#define AFMTSTR_MAXSZ 13 /* include null terminator */
266
267#define AFMTSTR_MONO_RETURN 0
268#define AFMTSTR_STEREO_RETURN 1
269
270struct afmtstr_table {
271 char *fmtstr;
272 u_int32_t format;
273};
274
275int afmtstr_swap_sign(char *);
276int afmtstr_swap_endian(char *);
277u_int32_t afmtstr2afmt(struct afmtstr_table *, const char *, int);
278u_int32_t afmt2afmtstr(struct afmtstr_table *, u_int32_t, char *, size_t, int, int);
279
280extern int chn_latency;
281extern int chn_latency_profile;
282extern int report_soft_formats;
283
284#define PCMDIR_FAKE 0
285#define PCMDIR_PLAY 1
286#define PCMDIR_PLAY_VIRTUAL 2
287#define PCMDIR_REC -1
288#define PCMDIR_REC_VIRTUAL -2
289
290#define PCMTRIG_START 1
291#define PCMTRIG_EMLDMAWR 2
292#define PCMTRIG_EMLDMARD 3
293#define PCMTRIG_STOP 0
294#define PCMTRIG_ABORT -1
295
296#define PCMTRIG_COMMON(x) ((x) == PCMTRIG_START || \
297 (x) == PCMTRIG_STOP || \
298 (x) == PCMTRIG_ABORT)
299
300#define CHN_F_CLOSING 0x00000004 /* a pending close */
301#define CHN_F_ABORTING 0x00000008 /* a pending abort */
302#define CHN_F_RUNNING 0x00000010 /* dma is running */
303#define CHN_F_TRIGGERED 0x00000020
304#define CHN_F_NOTRIGGER 0x00000040
305#define CHN_F_SLEEPING 0x00000080
306
307#define CHN_F_BUSY 0x00001000 /* has been opened */
308#define CHN_F_HAS_SIZE 0x00002000 /* user set block size */
309#define CHN_F_NBIO 0x00004000 /* do non-blocking i/o */
310#define CHN_F_MAPPED 0x00010000 /* has been mmap()ed */
311#define CHN_F_DEAD 0x00020000
312#define CHN_F_BADSETTING 0x00040000
313#define CHN_F_SETBLOCKSIZE 0x00080000
314#define CHN_F_HAS_VCHAN 0x00100000
315
316#define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */
317
216#include "channel_if.h"
217
218int chn_reinit(struct pcm_channel *c);
219int chn_write(struct pcm_channel *c, struct uio *buf);
220int chn_read(struct pcm_channel *c, struct uio *buf);
221u_int32_t chn_start(struct pcm_channel *c, int force);
222int chn_sync(struct pcm_channel *c, int threshold);
223int chn_flush(struct pcm_channel *c);
224int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
225
226int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction);
227int chn_kill(struct pcm_channel *c);
228int chn_setdir(struct pcm_channel *c, int dir);
229int chn_reset(struct pcm_channel *c, u_int32_t fmt);
230int chn_setvolume(struct pcm_channel *c, int left, int right);
231int chn_setspeed(struct pcm_channel *c, int speed);
232int chn_setformat(struct pcm_channel *c, u_int32_t fmt);
233int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz);
234int chn_setlatency(struct pcm_channel *c, int latency);
235int chn_trigger(struct pcm_channel *c, int go);
236int chn_getptr(struct pcm_channel *c);
237struct pcmchan_caps *chn_getcaps(struct pcm_channel *c);
238u_int32_t chn_getformats(struct pcm_channel *c);
239
240void chn_resetbuf(struct pcm_channel *c);
241void chn_intr(struct pcm_channel *c);
242int chn_wrfeed(struct pcm_channel *c);
243int chn_rdfeed(struct pcm_channel *c);
244int chn_abort(struct pcm_channel *c);
245
246void chn_wrupdate(struct pcm_channel *c);
247void chn_rdupdate(struct pcm_channel *c);
248
249int chn_notify(struct pcm_channel *c, u_int32_t flags);
250void chn_lock(struct pcm_channel *c);
251void chn_unlock(struct pcm_channel *c);
252
253int chn_getrates(struct pcm_channel *c, int **rates);
254int chn_syncdestroy(struct pcm_channel *c);
255
256#ifdef OSSV4_EXPERIMENT
257int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
258#endif
259
260#ifdef USING_MUTEX
261#define CHN_LOCK(c) mtx_lock((struct mtx *)((c)->lock))
262#define CHN_UNLOCK(c) mtx_unlock((struct mtx *)((c)->lock))
263#define CHN_TRYLOCK(c) mtx_trylock((struct mtx *)((c)->lock))
264#define CHN_LOCKASSERT(c) mtx_assert((struct mtx *)((c)->lock), MA_OWNED)
265#else
266#define CHN_LOCK(c)
267#define CHN_UNLOCK(c)
268#define CHN_TRYLOCK(c)
269#define CHN_LOCKASSERT(c)
270#endif
271
272int fmtvalid(u_int32_t fmt, u_int32_t *fmtlist);
273
274#define AFMTSTR_NONE 0 /* "s16le" */
275#define AFMTSTR_SIMPLE 1 /* "s16le:s" */
276#define AFMTSTR_NUM 2 /* "s16le:2" */
277#define AFMTSTR_FULL 3 /* "s16le:stereo" */
278
279#define AFMTSTR_MAXSZ 13 /* include null terminator */
280
281#define AFMTSTR_MONO_RETURN 0
282#define AFMTSTR_STEREO_RETURN 1
283
284struct afmtstr_table {
285 char *fmtstr;
286 u_int32_t format;
287};
288
289int afmtstr_swap_sign(char *);
290int afmtstr_swap_endian(char *);
291u_int32_t afmtstr2afmt(struct afmtstr_table *, const char *, int);
292u_int32_t afmt2afmtstr(struct afmtstr_table *, u_int32_t, char *, size_t, int, int);
293
294extern int chn_latency;
295extern int chn_latency_profile;
296extern int report_soft_formats;
297
298#define PCMDIR_FAKE 0
299#define PCMDIR_PLAY 1
300#define PCMDIR_PLAY_VIRTUAL 2
301#define PCMDIR_REC -1
302#define PCMDIR_REC_VIRTUAL -2
303
304#define PCMTRIG_START 1
305#define PCMTRIG_EMLDMAWR 2
306#define PCMTRIG_EMLDMARD 3
307#define PCMTRIG_STOP 0
308#define PCMTRIG_ABORT -1
309
310#define PCMTRIG_COMMON(x) ((x) == PCMTRIG_START || \
311 (x) == PCMTRIG_STOP || \
312 (x) == PCMTRIG_ABORT)
313
314#define CHN_F_CLOSING 0x00000004 /* a pending close */
315#define CHN_F_ABORTING 0x00000008 /* a pending abort */
316#define CHN_F_RUNNING 0x00000010 /* dma is running */
317#define CHN_F_TRIGGERED 0x00000020
318#define CHN_F_NOTRIGGER 0x00000040
319#define CHN_F_SLEEPING 0x00000080
320
321#define CHN_F_BUSY 0x00001000 /* has been opened */
322#define CHN_F_HAS_SIZE 0x00002000 /* user set block size */
323#define CHN_F_NBIO 0x00004000 /* do non-blocking i/o */
324#define CHN_F_MAPPED 0x00010000 /* has been mmap()ed */
325#define CHN_F_DEAD 0x00020000
326#define CHN_F_BADSETTING 0x00040000
327#define CHN_F_SETBLOCKSIZE 0x00080000
328#define CHN_F_HAS_VCHAN 0x00100000
329
330#define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */
331
318#define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | \
319 CHN_F_HAS_VCHAN | CHN_F_VIRTUAL)
332#define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | \
333 CHN_F_HAS_VCHAN | CHN_F_VIRTUAL)
334
335#define CHN_F_MMAP_INVALID (CHN_F_DEAD | CHN_F_RUNNING)
336
320
321
322#define CHN_N_RATE 0x00000001
323#define CHN_N_FORMAT 0x00000002
324#define CHN_N_VOLUME 0x00000004
325#define CHN_N_BLOCKSIZE 0x00000008
326#define CHN_N_TRIGGER 0x00000010
327
328#define CHN_LATENCY_MIN 0
329#define CHN_LATENCY_MAX 10
330#define CHN_LATENCY_DEFAULT 5
331#define CHN_POLICY_MIN CHN_LATENCY_MIN
332#define CHN_POLICY_MAX CHN_LATENCY_MAX
333#define CHN_POLICY_DEFAULT CHN_LATENCY_DEFAULT
334
335#define CHN_LATENCY_PROFILE_MIN 0
336#define CHN_LATENCY_PROFILE_MAX 1
337#define CHN_LATENCY_PROFILE_DEFAULT CHN_LATENCY_PROFILE_MAX
338
337
338
339#define CHN_N_RATE 0x00000001
340#define CHN_N_FORMAT 0x00000002
341#define CHN_N_VOLUME 0x00000004
342#define CHN_N_BLOCKSIZE 0x00000008
343#define CHN_N_TRIGGER 0x00000010
344
345#define CHN_LATENCY_MIN 0
346#define CHN_LATENCY_MAX 10
347#define CHN_LATENCY_DEFAULT 5
348#define CHN_POLICY_MIN CHN_LATENCY_MIN
349#define CHN_POLICY_MAX CHN_LATENCY_MAX
350#define CHN_POLICY_DEFAULT CHN_LATENCY_DEFAULT
351
352#define CHN_LATENCY_PROFILE_MIN 0
353#define CHN_LATENCY_PROFILE_MAX 1
354#define CHN_LATENCY_PROFILE_DEFAULT CHN_LATENCY_PROFILE_MAX
355
356#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED)
357#define CHN_STOPPED(c) (!CHN_STARTED(c))
358#define CHN_DIRSTR(c) (((c)->direction == PCMDIR_PLAY) ? \
359 "PCMDIR_PLAY" : "PCMDIR_REC")
360
361#define CHN_TIMEOUT 5
362#define CHN_TIMEOUT_MIN 1
363#define CHN_TIMEOUT_MAX 10
364
339/*
340 * This should be large enough to hold all pcm data between
341 * tsleeps in chn_{read,write} at the highest sample rate.
342 * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec)
343 */
344#define CHN_2NDBUFBLKSIZE (2 * 1024)
345/* The total number of blocks per secondary bufhard. */
346#define CHN_2NDBUFBLKNUM (32)
347/* The size of a whole secondary bufhard. */
348#define CHN_2NDBUFMAXSIZE (131072)
349
350#define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj))
365/*
366 * This should be large enough to hold all pcm data between
367 * tsleeps in chn_{read,write} at the highest sample rate.
368 * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec)
369 */
370#define CHN_2NDBUFBLKSIZE (2 * 1024)
371/* The total number of blocks per secondary bufhard. */
372#define CHN_2NDBUFBLKNUM (32)
373/* The size of a whole secondary bufhard. */
374#define CHN_2NDBUFMAXSIZE (131072)
375
376#define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj))