xref: /freebsd/sys/dev/sound/usb/uaudio_pcm.c (revision f0a75d274af375d15b97b830966b99a02b7db911)
1 /* $FreeBSD$ */
2 
3 /*-
4  * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 
29 #include <sys/soundcard.h>
30 #include <dev/sound/pcm/sound.h>
31 #include <dev/sound/chip.h>
32 
33 #include <dev/sound/usb/uaudio.h>
34 
35 #include "mixer_if.h"
36 
37 struct ua_info;
38 
39 struct ua_chinfo {
40 	struct ua_info *parent;
41 	struct pcm_channel *channel;
42 	struct snd_dbuf *buffer;
43 	u_char *buf;
44 	int dir, hwch;
45 	u_int32_t fmt, spd, blksz;	/* XXXXX */
46 };
47 
48 struct ua_info {
49 	device_t sc_dev;
50 	u_int32_t bufsz;
51 	struct ua_chinfo pch, rch;
52 #define FORMAT_NUM	32
53 	u_int32_t ua_playfmt[FORMAT_NUM*2+1]; /* FORMAT_NUM format * (stereo or mono) + endptr */
54 	u_int32_t ua_recfmt[FORMAT_NUM*2+1]; /* FORMAT_NUM format * (stereo or mono) + endptr */
55 	struct pcmchan_caps ua_playcaps;
56 	struct pcmchan_caps ua_reccaps;
57 	int vendor, product, release;
58 };
59 
60 #define UAUDIO_DEFAULT_BUFSZ		16*1024
61 
62 static const struct {
63 	int vendor;
64 	int product;
65 	int release;
66 	uint32_t dflags;
67 } ua_quirks[] = {
68 	{ 0x1130, 0xf211, 0x0101, SD_F_PSWAPLR },
69 };
70 
71 /************************************************************/
72 static void *
73 ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
74 {
75 	device_t pa_dev;
76 
77 	struct ua_info *sc = devinfo;
78 	struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
79 
80 	ch->parent = sc;
81 	ch->channel = c;
82 	ch->buffer = b;
83 	ch->dir = dir;
84 
85 	pa_dev = device_get_parent(sc->sc_dev);
86 
87 	ch->buf = malloc(sc->bufsz, M_DEVBUF, M_NOWAIT);
88 	if (ch->buf == NULL)
89 		return NULL;
90 	if (sndbuf_setup(b, ch->buf, sc->bufsz) != 0) {
91 		free(ch->buf, M_DEVBUF);
92 		return NULL;
93 	}
94 	uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf, ch->buf+sc->bufsz, ch->channel, dir);
95 	if (bootverbose)
96 		device_printf(pa_dev, "%s buf %p\n", (dir == PCMDIR_PLAY)?
97 			      "play" : "rec", sndbuf_getbuf(ch->buffer));
98 
99 	ch->dir = dir;
100 #ifndef NO_RECORDING
101 	ch->hwch = 1;
102 	if (dir == PCMDIR_PLAY)
103 		ch->hwch = 2;
104 #else
105 	ch->hwch = 2;
106 #endif
107 
108 	return ch;
109 }
110 
111 static int
112 ua_chan_free(kobj_t obj, void *data)
113 {
114 	struct ua_chinfo *ua = data;
115 
116 	if (ua->buf != NULL)
117 		free(ua->buf, M_DEVBUF);
118 	return 0;
119 }
120 
121 static int
122 ua_chan_setformat(kobj_t obj, void *data, u_int32_t format)
123 {
124 	device_t pa_dev;
125 	struct ua_info *ua;
126 
127 	struct ua_chinfo *ch = data;
128 
129 	/*
130 	 * At this point, no need to query as we shouldn't select an unsorted format
131 	 */
132 	ua = ch->parent;
133 	pa_dev = device_get_parent(ua->sc_dev);
134 	uaudio_chan_set_param_format(pa_dev, format, ch->dir);
135 
136 	ch->fmt = format;
137 	return 0;
138 }
139 
140 static int
141 ua_chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
142 {
143 	struct ua_chinfo *ch;
144 	device_t pa_dev;
145 	int bestspeed;
146 
147 	ch = data;
148 	pa_dev = device_get_parent(ch->parent->sc_dev);
149 
150 	if ((bestspeed = uaudio_chan_set_param_speed(pa_dev, speed, ch->dir)))
151 		ch->spd = bestspeed;
152 
153 	return ch->spd;
154 }
155 
156 static int
157 ua_chan_setfragments(kobj_t obj, void *data, u_int32_t blksz, u_int32_t blkcnt)
158 {
159 	device_t pa_dev;
160 	struct ua_chinfo *ch = data;
161 	struct ua_info *ua = ch->parent;
162 
163 	RANGE(blksz, 128, sndbuf_getmaxsize(ch->buffer) / 2);
164 	RANGE(blkcnt, 2, 512);
165 
166 	while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
167 		if ((blkcnt >> 1) >= 2)
168 			blkcnt >>= 1;
169 		else if ((blksz >> 1) >= 128)
170 			blksz >>= 1;
171 		else
172 			break;
173 	}
174 
175 	if ((sndbuf_getblksz(ch->buffer) != blksz ||
176 	    sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
177 	    sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
178 		device_printf(ua->sc_dev, "%s: failed blksz=%u blkcnt=%u\n",
179 		    __func__, blksz, blkcnt);
180 
181 	ch->blksz = sndbuf_getblksz(ch->buffer);
182 
183 	pa_dev = device_get_parent(ua->sc_dev);
184 	uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf,
185 	    ch->buf + sndbuf_getsize(ch->buffer), ch->channel, ch->dir);
186 	uaudio_chan_set_param_blocksize(pa_dev, ch->blksz, ch->dir);
187 
188 	return 1;
189 }
190 
191 static int
192 ua_chan_setblocksize(kobj_t obj, void *data, u_int32_t blksz)
193 {
194 	struct ua_chinfo *ch = data;
195 
196 	ua_chan_setfragments(obj, data, blksz,
197 	    sndbuf_getmaxsize(ch->buffer) / blksz);
198 
199 	return ch->blksz;
200 }
201 
202 static int
203 ua_chan_trigger(kobj_t obj, void *data, int go)
204 {
205 	device_t pa_dev;
206 	struct ua_info *ua;
207 	struct ua_chinfo *ch = data;
208 
209 	if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
210 		return 0;
211 
212 	ua = ch->parent;
213 	pa_dev = device_get_parent(ua->sc_dev);
214 
215 	/* XXXXX */
216 	if (ch->dir == PCMDIR_PLAY) {
217 		if (go == PCMTRIG_START) {
218 			uaudio_trigger_output(pa_dev);
219 		} else {
220 			uaudio_halt_out_dma(pa_dev);
221 		}
222 	} else {
223 #ifndef NO_RECORDING
224 		if (go == PCMTRIG_START)
225 			uaudio_trigger_input(pa_dev);
226 		else
227 			uaudio_halt_in_dma(pa_dev);
228 #endif
229 	}
230 
231 	return 0;
232 }
233 
234 static int
235 ua_chan_getptr(kobj_t obj, void *data)
236 {
237 	device_t pa_dev;
238 	struct ua_info *ua;
239 	struct ua_chinfo *ch = data;
240 
241 	ua = ch->parent;
242 	pa_dev = device_get_parent(ua->sc_dev);
243 
244 	return uaudio_chan_getptr(pa_dev, ch->dir);
245 }
246 
247 static struct pcmchan_caps *
248 ua_chan_getcaps(kobj_t obj, void *data)
249 {
250 	struct ua_chinfo *ch;
251 
252 	ch = data;
253 	return (ch->dir == PCMDIR_PLAY) ? &(ch->parent->ua_playcaps) : &(ch->parent->ua_reccaps);
254 }
255 
256 static kobj_method_t ua_chan_methods[] = {
257 	KOBJMETHOD(channel_init,		ua_chan_init),
258 	KOBJMETHOD(channel_free,                ua_chan_free),
259 	KOBJMETHOD(channel_setformat,		ua_chan_setformat),
260 	KOBJMETHOD(channel_setspeed,		ua_chan_setspeed),
261 	KOBJMETHOD(channel_setblocksize,	ua_chan_setblocksize),
262 	KOBJMETHOD(channel_setfragments,	ua_chan_setfragments),
263 	KOBJMETHOD(channel_trigger,		ua_chan_trigger),
264 	KOBJMETHOD(channel_getptr,		ua_chan_getptr),
265 	KOBJMETHOD(channel_getcaps,		ua_chan_getcaps),
266 	{ 0, 0 }
267 };
268 
269 CHANNEL_DECLARE(ua_chan);
270 
271 /************************************************************/
272 static int
273 ua_mixer_init(struct snd_mixer *m)
274 {
275 	u_int32_t mask;
276 	device_t pa_dev;
277 	struct snddev_info *d;
278 	struct ua_info *ua = mix_getdevinfo(m);
279 
280 	pa_dev = device_get_parent(ua->sc_dev);
281 	d = device_get_softc(ua->sc_dev);
282 
283 	mask = uaudio_query_mix_info(pa_dev);
284 	if (d != NULL) {
285 		if (!(mask & SOUND_MASK_PCM)) {
286 			/*
287 			 * Emulate missing pcm mixer controller
288 			 * through FEEDER_VOLUME
289 			 */
290 			 d->flags |= SD_F_SOFTPCMVOL;
291 		}
292 		if (!(mask & SOUND_MASK_VOLUME)) {
293 			mix_setparentchild(m, SOUND_MIXER_VOLUME,
294 			    SOUND_MASK_PCM);
295 			mix_setrealdev(m, SOUND_MIXER_VOLUME,
296 			    SOUND_MIXER_NONE);
297 		}
298 	}
299 	mix_setdevs(m,	mask);
300 
301 	mask = uaudio_query_recsrc_info(pa_dev);
302 	mix_setrecdevs(m, mask);
303 
304 	return 0;
305 }
306 
307 static int
308 ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
309 {
310 	device_t pa_dev;
311 	struct ua_info *ua = mix_getdevinfo(m);
312 
313 	pa_dev = device_get_parent(ua->sc_dev);
314 	uaudio_mixer_set(pa_dev, type, left, right);
315 
316 	return left | (right << 8);
317 }
318 
319 static int
320 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
321 {
322 	device_t pa_dev;
323 	struct ua_info *ua = mix_getdevinfo(m);
324 
325 	pa_dev = device_get_parent(ua->sc_dev);
326 	return uaudio_mixer_setrecsrc(pa_dev, src);
327 }
328 
329 static kobj_method_t ua_mixer_methods[] = {
330 	KOBJMETHOD(mixer_init,		ua_mixer_init),
331 	KOBJMETHOD(mixer_set,		ua_mixer_set),
332 	KOBJMETHOD(mixer_setrecsrc,	ua_mixer_setrecsrc),
333 
334 	{ 0, 0 }
335 };
336 MIXER_DECLARE(ua_mixer);
337 /************************************************************/
338 
339 
340 static int
341 ua_probe(device_t dev)
342 {
343 	char *s;
344 	struct sndcard_func *func;
345 
346 	/* The parent device has already been probed. */
347 
348 	func = device_get_ivars(dev);
349 	if (func == NULL || func->func != SCF_PCM)
350 		return (ENXIO);
351 
352 	s = "USB Audio";
353 
354 	device_set_desc(dev, s);
355 	return BUS_PROBE_DEFAULT;
356 }
357 
358 static int
359 ua_attach(device_t dev)
360 {
361 	struct ua_info *ua;
362 	struct sndcard_func *func;
363 	struct snddev_info *d;
364 	char status[SND_STATUSLEN];
365 	device_t pa_dev;
366 	u_int32_t nplay, nrec;
367 	int i;
368 
369 	ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_ZERO | M_NOWAIT);
370 	if (ua == NULL)
371 		return ENXIO;
372 
373 	ua->sc_dev = dev;
374 
375 	/* Mark for existence */
376 	func = device_get_ivars(dev);
377 	if (func != NULL)
378 		func->varinfo = (void *)ua;
379 
380 	pa_dev = device_get_parent(dev);
381 	ua->vendor = uaudio_get_vendor(pa_dev);
382 	ua->product = uaudio_get_product(pa_dev);
383 	ua->release = uaudio_get_release(pa_dev);
384 
385 	if (bootverbose)
386 		device_printf(dev,
387 		    "USB Audio: "
388 		    "vendor=0x%04x, product=0x%04x, release=0x%04x\n",
389 		    ua->vendor, ua->product, ua->release);
390 
391 	ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536);
392 	if (bootverbose)
393 		device_printf(dev, "using a default buffer size of %jd\n", (intmax_t)ua->bufsz);
394 
395 	if (mixer_init(dev, &ua_mixer_class, ua)) {
396 		goto bad;
397 	}
398 
399 	snprintf(status, SND_STATUSLEN, "at ? %s", PCM_KLDSTRING(snd_uaudio));
400 
401 	ua->ua_playcaps.fmtlist = ua->ua_playfmt;
402 	ua->ua_reccaps.fmtlist = ua->ua_recfmt;
403 	nplay = uaudio_query_formats(pa_dev, PCMDIR_PLAY, FORMAT_NUM * 2, &ua->ua_playcaps);
404 	nrec = uaudio_query_formats(pa_dev, PCMDIR_REC, FORMAT_NUM * 2, &ua->ua_reccaps);
405 
406 	if (nplay > 1)
407 		nplay = 1;
408 	if (nrec > 1)
409 		nrec = 1;
410 
411 	d = device_get_softc(dev);
412 	for (i = 0; d != NULL &&
413 	    i < (sizeof(ua_quirks) / sizeof(ua_quirks[0])); i++) {
414 		if (ua->vendor == ua_quirks[i].vendor &&
415 		    ua->product == ua_quirks[i].product &&
416 		    ua->release == ua_quirks[i].release)
417 			d->flags |= ua_quirks[i].dflags;
418 	}
419 
420 #ifndef NO_RECORDING
421 	if (pcm_register(dev, ua, nplay, nrec)) {
422 #else
423 	if (pcm_register(dev, ua, nplay, 0)) {
424 #endif
425 		goto bad;
426 	}
427 
428 	sndstat_unregister(dev);
429 	uaudio_sndstat_register(dev);
430 
431 	for (i = 0; i < nplay; i++) {
432 		pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
433 	}
434 #ifndef NO_RECORDING
435 	for (i = 0; i < nrec; i++) {
436 		pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
437 	}
438 #endif
439 	pcm_setstatus(dev, status);
440 
441 	return 0;
442 
443 bad:	free(ua, M_DEVBUF);
444 	return ENXIO;
445 }
446 
447 static int
448 ua_detach(device_t dev)
449 {
450 	struct ua_info *sc;
451 	struct sndcard_func *func;
452 	int r;
453 
454 	r = pcm_unregister(dev);
455 	if (r)
456 		return r;
457 
458 	sc = pcm_getdevinfo(dev);
459 	free(sc, M_DEVBUF);
460 
461 	/* Mark for deletion */
462 	func = device_get_ivars(dev);
463 	if (func != NULL)
464 		func->varinfo = NULL;
465 
466 	return 0;
467 }
468 
469 /************************************************************/
470 
471 static device_method_t ua_pcm_methods[] = {
472 	/* Device interface */
473 	DEVMETHOD(device_probe,		ua_probe),
474 	DEVMETHOD(device_attach,	ua_attach),
475 	DEVMETHOD(device_detach,	ua_detach),
476 
477 	{ 0, 0 }
478 };
479 
480 static driver_t ua_pcm_driver = {
481 	"pcm",
482 	ua_pcm_methods,
483 	PCM_SOFTC_SIZE,
484 };
485 
486 
487 DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0);
488 MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1);
489 MODULE_DEPEND(ua_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
490 MODULE_VERSION(ua_pcm, 1);
491