FreeBSD kernel sound device code
uaudio_pcm.c
Go to the documentation of this file.
1/* $FreeBSD$ */
2
3/*-
4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 *
6 * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
7 * Copyright (c) 2006 Hans Petter Selasky
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#ifdef HAVE_KERNEL_OPTION_HEADERS
32#include "opt_snd.h"
33#endif
34
35#include <dev/sound/pcm/sound.h>
36#include <dev/sound/chip.h>
38
39#include "mixer_if.h"
40
41/************************************************************/
42static void *
43ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
44{
45 return (uaudio_chan_init(devinfo, b, c, dir));
46}
47
48static int
49ua_chan_free(kobj_t obj, void *data)
50{
51 return (uaudio_chan_free(data));
52}
53
54static int
55ua_chan_setformat(kobj_t obj, void *data, uint32_t format)
56{
57 /*
58 * At this point, no need to query as we
59 * shouldn't select an unsorted format
60 */
62}
63
64static uint32_t
65ua_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
66{
68}
69
70static uint32_t
71ua_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
72{
74}
75
76static int
77ua_chan_setfragments(kobj_t obj, void *data, uint32_t blocksize, uint32_t blockcount)
78{
80}
81
82static int
83ua_chan_trigger(kobj_t obj, void *data, int go)
84{
85 if (PCMTRIG_COMMON(go)) {
86 if (go == PCMTRIG_START) {
88 } else {
90 }
91 }
92 return (0);
93}
94
95static uint32_t
96ua_chan_getptr(kobj_t obj, void *data)
97{
98 return (uaudio_chan_getptr(data));
99}
100
101static struct pcmchan_caps *
102ua_chan_getcaps(kobj_t obj, void *data)
103{
104 return (uaudio_chan_getcaps(data));
105}
106
107static struct pcmchan_matrix *
108ua_chan_getmatrix(kobj_t obj, void *data, uint32_t format)
109{
111}
112
113static kobj_method_t ua_chan_methods[] = {
114 KOBJMETHOD(channel_init, ua_chan_init),
115 KOBJMETHOD(channel_free, ua_chan_free),
116 KOBJMETHOD(channel_setformat, ua_chan_setformat),
117 KOBJMETHOD(channel_setspeed, ua_chan_setspeed),
118 KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize),
119 KOBJMETHOD(channel_setfragments, ua_chan_setfragments),
120 KOBJMETHOD(channel_trigger, ua_chan_trigger),
121 KOBJMETHOD(channel_getptr, ua_chan_getptr),
122 KOBJMETHOD(channel_getcaps, ua_chan_getcaps),
123 KOBJMETHOD(channel_getmatrix, ua_chan_getmatrix),
125};
126
128
129/************************************************************/
130static int
132{
134}
135
136static int
137ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
138{
139 struct mtx *mtx = mixer_get_lock(m);
140 uint8_t do_unlock;
141
142 if (mtx_owned(mtx)) {
143 do_unlock = 0;
144 } else {
145 do_unlock = 1;
146 mtx_lock(mtx);
147 }
149 if (do_unlock) {
150 mtx_unlock(mtx);
151 }
152 return (left | (right << 8));
153}
154
155static uint32_t
157{
158 struct mtx *mtx = mixer_get_lock(m);
159 int retval;
160 uint8_t do_unlock;
161
162 if (mtx_owned(mtx)) {
163 do_unlock = 0;
164 } else {
165 do_unlock = 1;
166 mtx_lock(mtx);
167 }
169 if (do_unlock) {
170 mtx_unlock(mtx);
171 }
172 return (retval);
173}
174
175static int
177{
179}
180
181static kobj_method_t ua_mixer_methods[] = {
182 KOBJMETHOD(mixer_init, ua_mixer_init),
183 KOBJMETHOD(mixer_uninit, ua_mixer_uninit),
184 KOBJMETHOD(mixer_set, ua_mixer_set),
187};
188
190/************************************************************/
191
192static int
193ua_probe(device_t dev)
194{
195 struct sndcard_func *func;
196
197 /* the parent device has already been probed */
198
199 func = device_get_ivars(dev);
200
201 if ((func == NULL) ||
202 (func->func != SCF_PCM)) {
203 return (ENXIO);
204 }
205 device_set_desc(dev, "USB audio");
206
207 return (BUS_PROBE_DEFAULT);
208}
209
210static int
211ua_attach(device_t dev)
212{
213 return (uaudio_attach_sub(dev, &ua_mixer_class, &ua_chan_class));
214}
215
216static int
217ua_detach(device_t dev)
218{
219 return (uaudio_detach_sub(dev));
220}
221
222/************************************************************/
223
224static device_method_t ua_pcm_methods[] = {
225 /* Device interface */
226 DEVMETHOD(device_probe, ua_probe),
227 DEVMETHOD(device_attach, ua_attach),
228 DEVMETHOD(device_detach, ua_detach),
229
230 DEVMETHOD_END
231};
232
233static driver_t ua_pcm_driver = {
234 "pcm",
237};
238
240MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1);
242MODULE_VERSION(ua_pcm, 1);
u_int32_t data
Definition: ac97_if.m:60
void * devinfo
Definition: ac97_if.m:47
uint32_t format
Definition: audio_dai_if.m:39
uint32_t speed
Definition: audio_dai_if.m:86
int go
Definition: audio_dai_if.m:64
#define PCMTRIG_START
Definition: channel.h:344
#define PCMTRIG_COMMON(x)
Definition: channel.h:350
struct pcm_channel * c
Definition: channel_if.m:106
u_int32_t blockcount
Definition: channel_if.m:147
u_int32_t blocksize
Definition: channel_if.m:140
struct pcmchan_matrix * m
Definition: channel_if.m:232
struct snd_dbuf * b
Definition: channel_if.m:105
@ SCF_PCM
Definition: chip.h:36
int type
Definition: dsp.c:386
unsigned right
Definition: es137x.c:261
unsigned left
Definition: es137x.c:260
int dir
Definition: hdac_if.m:45
#define KOBJMETHOD_END
Definition: midi.c:76
static int mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
Definition: mixer.c:373
struct mtx * mixer_get_lock(struct snd_mixer *m)
Definition: mixer.c:1567
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
Definition: mixer.c:725
static int mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
Definition: mixer.c:247
int mixer_uninit(device_t dev)
Definition: mixer.c:805
void * mix_getdevinfo(struct snd_mixer *m)
Definition: mixer.c:645
unsigned dev
Definition: mixer_if.m:59
u_int32_t src
Definition: mixer_if.m:66
devclass_t pcm_devclass
Definition: sound.c:49
#define SOUND_PREFVER
Definition: sound.h:103
#define SOUND_MAXVER
Definition: sound.h:104
#define SOUND_MINVER
Definition: sound.h:102
#define PCM_SOFTC_SIZE
Definition: sound.h:96
int func
Definition: chip.h:47
void * uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, struct pcm_channel *c, int dir)
Definition: uaudio.c:2614
int uaudio_chan_set_param_format(struct uaudio_chan *ch, uint32_t format)
Definition: uaudio.c:2776
int uaudio_detach_sub(device_t dev)
Definition: uaudio.c:1246
int uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed)
Definition: uaudio.c:2692
struct pcmchan_caps * uaudio_chan_getcaps(struct uaudio_chan *ch)
Definition: uaudio.c:2725
void uaudio_mixer_set(struct uaudio_softc *sc, struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
Definition: uaudio.c:5445
void uaudio_chan_start(struct uaudio_chan *ch)
Definition: uaudio.c:2823
int uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class)
Definition: uaudio.c:1175
void uaudio_chan_stop(struct uaudio_chan *ch)
Definition: uaudio.c:2865
int uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize, uint32_t blockcount)
Definition: uaudio.c:2685
int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize)
Definition: uaudio.c:2677
uint32_t uaudio_mixer_setrecsrc(struct uaudio_softc *sc, struct snd_mixer *m, uint32_t src)
Definition: uaudio.c:5465
int uaudio_mixer_uninit_sub(struct uaudio_softc *sc, struct snd_mixer *m)
Definition: uaudio.c:5430
int uaudio_mixer_init_sub(struct uaudio_softc *sc, struct snd_mixer *m)
Definition: uaudio.c:5402
int uaudio_chan_getptr(struct uaudio_chan *ch)
Definition: uaudio.c:2719
struct pcmchan_matrix * uaudio_chan_getmatrix(struct uaudio_chan *ch, uint32_t format)
Definition: uaudio.c:2762
int uaudio_chan_free(struct uaudio_chan *ch)
Definition: uaudio.c:2663
static uint32_t ua_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
Definition: uaudio_pcm.c:71
static int ua_mixer_uninit(struct snd_mixer *m)
Definition: uaudio_pcm.c:176
CHANNEL_DECLARE(ua_chan)
static int ua_mixer_init(struct snd_mixer *m)
Definition: uaudio_pcm.c:131
static int ua_probe(device_t dev)
Definition: uaudio_pcm.c:193
static uint32_t ua_chan_getptr(kobj_t obj, void *data)
Definition: uaudio_pcm.c:96
static int ua_detach(device_t dev)
Definition: uaudio_pcm.c:217
static int ua_chan_setformat(kobj_t obj, void *data, uint32_t format)
Definition: uaudio_pcm.c:55
static driver_t ua_pcm_driver
Definition: uaudio_pcm.c:233
static int ua_attach(device_t dev)
Definition: uaudio_pcm.c:211
static struct pcmchan_caps * ua_chan_getcaps(kobj_t obj, void *data)
Definition: uaudio_pcm.c:102
static kobj_method_t ua_chan_methods[]
Definition: uaudio_pcm.c:113
static uint32_t ua_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
Definition: uaudio_pcm.c:65
static void * ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
Definition: uaudio_pcm.c:43
static kobj_method_t ua_mixer_methods[]
Definition: uaudio_pcm.c:181
static uint32_t ua_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
Definition: uaudio_pcm.c:156
MODULE_VERSION(ua_pcm, 1)
static int ua_chan_free(kobj_t obj, void *data)
Definition: uaudio_pcm.c:49
static int ua_chan_setfragments(kobj_t obj, void *data, uint32_t blocksize, uint32_t blockcount)
Definition: uaudio_pcm.c:77
MIXER_DECLARE(ua_mixer)
static int ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
Definition: uaudio_pcm.c:137
static struct pcmchan_matrix * ua_chan_getmatrix(kobj_t obj, void *data, uint32_t format)
Definition: uaudio_pcm.c:108
MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1)
DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0)
static device_method_t ua_pcm_methods[]
Definition: uaudio_pcm.c:224
static int ua_chan_trigger(kobj_t obj, void *data, int go)
Definition: uaudio_pcm.c:83