]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sound/pcm/channel.h
This commit was generated by cvs2svn to compensate for changes in r162911,
[FreeBSD/FreeBSD.git] / sys / dev / sound / pcm / channel.h
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         u_int32_t speed;
83         u_int32_t format;
84         u_int32_t flags;
85         u_int32_t feederflags;
86         u_int32_t blocks;
87
88         int direction;
89         unsigned int interrupts, xruns;
90         struct snd_dbuf *bufhard, *bufsoft;
91         struct snddev_info *parentsnddev;
92         struct pcm_channel *parentchannel;
93         void *devinfo;
94         device_t dev;
95         char name[CHN_NAMELEN];
96         struct mtx *lock;
97         /**
98          * Increment,decrement this around operations that temporarily yield
99          * lock.
100          */
101         unsigned int inprog;
102         /**
103          * Special channel operations should examine @c inprog after acquiring
104          * lock.  If zero, operations may continue.  Else, thread should
105          * wait on this cv for previous operation to finish.
106          */
107         struct cv cv;
108         /**
109          * Low water mark for select()/poll().
110          *
111          * This is initialized to the channel's fragment size, and will be
112          * overwritten if a new fragment size is set.  Users may alter this
113          * value directly with the @c SNDCTL_DSP_LOW_WATER ioctl.
114          */
115         unsigned int lw;
116         /**
117          * If part of a sync group, this will point to the syncmember
118          * container.
119          */
120         struct pcmchan_syncmember *sm;
121 #ifdef OSSV4_EXPERIMENT
122         u_int16_t lpeak, rpeak; /**< Peak value from 0-32767. */
123 #endif
124         SLIST_HEAD(, pcmchan_children) children;
125 };
126
127 #include "channel_if.h"
128
129 int chn_reinit(struct pcm_channel *c);
130 int chn_write(struct pcm_channel *c, struct uio *buf);
131 int chn_read(struct pcm_channel *c, struct uio *buf);
132 u_int32_t chn_start(struct pcm_channel *c, int force);
133 int chn_sync(struct pcm_channel *c, int threshold);
134 int chn_flush(struct pcm_channel *c);
135 int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
136
137 int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction);
138 int chn_kill(struct pcm_channel *c);
139 int chn_setdir(struct pcm_channel *c, int dir);
140 int chn_reset(struct pcm_channel *c, u_int32_t fmt);
141 int chn_setvolume(struct pcm_channel *c, int left, int right);
142 int chn_setspeed(struct pcm_channel *c, int speed);
143 int chn_setformat(struct pcm_channel *c, u_int32_t fmt);
144 int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz);
145 int chn_trigger(struct pcm_channel *c, int go);
146 int chn_getptr(struct pcm_channel *c);
147 struct pcmchan_caps *chn_getcaps(struct pcm_channel *c);
148 u_int32_t chn_getformats(struct pcm_channel *c);
149
150 void chn_resetbuf(struct pcm_channel *c);
151 void chn_intr(struct pcm_channel *c);
152 int chn_wrfeed(struct pcm_channel *c);
153 int chn_rdfeed(struct pcm_channel *c);
154 int chn_abort(struct pcm_channel *c);
155
156 void chn_wrupdate(struct pcm_channel *c);
157 void chn_rdupdate(struct pcm_channel *c);
158
159 int chn_notify(struct pcm_channel *c, u_int32_t flags);
160 void chn_lock(struct pcm_channel *c);
161 void chn_unlock(struct pcm_channel *c);
162
163 int chn_getrates(struct pcm_channel *c, int **rates);
164 int chn_syncdestroy(struct pcm_channel *c);
165
166 #ifdef OSSV4_EXPERIMENT
167 int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
168 #endif
169
170 #ifdef  USING_MUTEX
171 #define CHN_LOCK(c) mtx_lock((struct mtx *)((c)->lock))
172 #define CHN_UNLOCK(c) mtx_unlock((struct mtx *)((c)->lock))
173 #define CHN_TRYLOCK(c) mtx_trylock((struct mtx *)((c)->lock))
174 #define CHN_LOCKASSERT(c) mtx_assert((struct mtx *)((c)->lock), MA_OWNED)
175 #else
176 #define CHN_LOCK(c)
177 #define CHN_UNLOCK(c)
178 #define CHN_TRYLOCK(c)
179 #define CHN_LOCKASSERT(c)
180 #endif
181
182 int fmtvalid(u_int32_t fmt, u_int32_t *fmtlist);
183
184 #define PCMDIR_VIRTUAL 2
185 #define PCMDIR_PLAY 1
186 #define PCMDIR_REC -1
187
188 #define PCMTRIG_START 1
189 #define PCMTRIG_EMLDMAWR 2
190 #define PCMTRIG_EMLDMARD 3
191 #define PCMTRIG_STOP 0
192 #define PCMTRIG_ABORT -1
193
194 #define CHN_F_CLOSING           0x00000004  /* a pending close */
195 #define CHN_F_ABORTING          0x00000008  /* a pending abort */
196 #define CHN_F_RUNNING           0x00000010  /* dma is running */
197 #define CHN_F_TRIGGERED         0x00000020
198 #define CHN_F_NOTRIGGER         0x00000040
199
200 #define CHN_F_BUSY              0x00001000  /* has been opened  */
201 #define CHN_F_HAS_SIZE          0x00002000  /* user set block size */
202 #define CHN_F_NBIO              0x00004000  /* do non-blocking i/o */
203 #define CHN_F_MAPPED            0x00010000  /* has been mmap()ed */
204 #define CHN_F_DEAD              0x00020000
205 #define CHN_F_BADSETTING        0x00040000
206 #define CHN_F_SETBLOCKSIZE      0x00080000
207 #define CHN_F_HAS_VCHAN         0x00100000
208
209 #define CHN_F_VIRTUAL           0x10000000  /* not backed by hardware */
210
211 #define CHN_F_RESET             (CHN_F_BUSY | CHN_F_DEAD | \
212                                         CHN_F_HAS_VCHAN | CHN_F_VIRTUAL)
213                                         
214
215 #define CHN_N_RATE              0x00000001
216 #define CHN_N_FORMAT            0x00000002
217 #define CHN_N_VOLUME            0x00000004
218 #define CHN_N_BLOCKSIZE         0x00000008
219 #define CHN_N_TRIGGER           0x00000010
220
221 /*
222  * This should be large enough to hold all pcm data between
223  * tsleeps in chn_{read,write} at the highest sample rate.
224  * (which is usually 48kHz * 16bit * stereo = 192000 bytes/sec)
225  */
226 #define CHN_2NDBUFBLKSIZE       (2 * 1024)
227 /* The total number of blocks per secondary bufhard. */
228 #define CHN_2NDBUFBLKNUM        (32)
229 /* The size of a whole secondary bufhard. */
230 #define CHN_2NDBUFMAXSIZE       (131072)
231
232 #define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj))