]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/sound/usb/uaudio_pcm.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / sound / usb / uaudio_pcm.c
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 (!PCMTRIG_COMMON(go))
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 ua_info *ua = mix_getdevinfo(m);
278
279         pa_dev = device_get_parent(ua->sc_dev);
280
281         mask = uaudio_query_mix_info(pa_dev);
282         if (!(mask & SOUND_MASK_PCM)) {
283                 /*
284                  * Emulate missing pcm mixer controller
285                  * through FEEDER_VOLUME
286                  */
287                 pcm_setflags(ua->sc_dev, pcm_getflags(ua->sc_dev) |
288                     SD_F_SOFTPCMVOL);
289         }
290         if (!(mask & SOUND_MASK_VOLUME)) {
291                 mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM);
292                 mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
293         }
294         mix_setdevs(m,  mask);
295
296         mask = uaudio_query_recsrc_info(pa_dev);
297         mix_setrecdevs(m, mask);
298
299         return 0;
300 }
301
302 static int
303 ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
304 {
305         device_t pa_dev;
306         struct ua_info *ua = mix_getdevinfo(m);
307
308         pa_dev = device_get_parent(ua->sc_dev);
309         uaudio_mixer_set(pa_dev, type, left, right);
310
311         return left | (right << 8);
312 }
313
314 static int
315 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
316 {
317         device_t pa_dev;
318         struct ua_info *ua = mix_getdevinfo(m);
319
320         pa_dev = device_get_parent(ua->sc_dev);
321         return uaudio_mixer_setrecsrc(pa_dev, src);
322 }
323
324 static kobj_method_t ua_mixer_methods[] = {
325         KOBJMETHOD(mixer_init,          ua_mixer_init),
326         KOBJMETHOD(mixer_set,           ua_mixer_set),
327         KOBJMETHOD(mixer_setrecsrc,     ua_mixer_setrecsrc),
328
329         { 0, 0 }
330 };
331 MIXER_DECLARE(ua_mixer);
332 /************************************************************/
333
334
335 static int
336 ua_probe(device_t dev)
337 {
338         char *s;
339         struct sndcard_func *func;
340
341         /* The parent device has already been probed. */
342
343         func = device_get_ivars(dev);
344         if (func == NULL || func->func != SCF_PCM)
345                 return (ENXIO);
346
347         s = "USB Audio";
348
349         device_set_desc(dev, s);
350         return BUS_PROBE_DEFAULT;
351 }
352
353 static int
354 ua_attach(device_t dev)
355 {
356         struct ua_info *ua;
357         struct sndcard_func *func;
358         char status[SND_STATUSLEN];
359         device_t pa_dev;
360         u_int32_t nplay, nrec, flags;
361         int i;
362
363         ua = malloc(sizeof(*ua), M_DEVBUF, M_WAITOK | M_ZERO);
364         ua->sc_dev = dev;
365
366         /* Mark for existence */
367         func = device_get_ivars(dev);
368         if (func != NULL)
369                 func->varinfo = (void *)ua;
370
371         pa_dev = device_get_parent(dev);
372         ua->vendor = uaudio_get_vendor(pa_dev);
373         ua->product = uaudio_get_product(pa_dev);
374         ua->release = uaudio_get_release(pa_dev);
375
376         if (bootverbose)
377                 device_printf(dev,
378                     "USB Audio: "
379                     "vendor=0x%04x, product=0x%04x, release=0x%04x\n",
380                     ua->vendor, ua->product, ua->release);
381
382         ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536);
383         if (bootverbose)
384                 device_printf(dev, "using a default buffer size of %jd\n", (intmax_t)ua->bufsz);
385
386         if (mixer_init(dev, &ua_mixer_class, ua)) {
387                 goto bad;
388         }
389
390         snprintf(status, SND_STATUSLEN, "at ? %s", PCM_KLDSTRING(snd_uaudio));
391
392         ua->ua_playcaps.fmtlist = ua->ua_playfmt;
393         ua->ua_reccaps.fmtlist = ua->ua_recfmt;
394         nplay = uaudio_query_formats(pa_dev, PCMDIR_PLAY, FORMAT_NUM * 2, &ua->ua_playcaps);
395         nrec = uaudio_query_formats(pa_dev, PCMDIR_REC, FORMAT_NUM * 2, &ua->ua_reccaps);
396
397         if (nplay > 1)
398                 nplay = 1;
399         if (nrec > 1)
400                 nrec = 1;
401
402         flags = pcm_getflags(dev);
403         for (i = 0; i < (sizeof(ua_quirks) / sizeof(ua_quirks[0])); i++) {
404                 if (ua->vendor == ua_quirks[i].vendor &&
405                     ua->product == ua_quirks[i].product &&
406                     ua->release == ua_quirks[i].release)
407                         flags |= ua_quirks[i].dflags;
408         }
409         pcm_setflags(dev, flags);
410
411 #ifndef NO_RECORDING
412         if (pcm_register(dev, ua, nplay, nrec)) {
413 #else
414         if (pcm_register(dev, ua, nplay, 0)) {
415 #endif
416                 goto bad;
417         }
418
419         sndstat_unregister(dev);
420         uaudio_sndstat_register(dev);
421
422         for (i = 0; i < nplay; i++) {
423                 pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
424         }
425 #ifndef NO_RECORDING
426         for (i = 0; i < nrec; i++) {
427                 pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
428         }
429 #endif
430         pcm_setstatus(dev, status);
431
432         return 0;
433
434 bad:    free(ua, M_DEVBUF);
435         return ENXIO;
436 }
437
438 static int
439 ua_detach(device_t dev)
440 {
441         struct ua_info *sc;
442         struct sndcard_func *func;
443         int r;
444
445         r = pcm_unregister(dev);
446         if (r)
447                 return r;
448
449         sc = pcm_getdevinfo(dev);
450         free(sc, M_DEVBUF);
451
452         /* Mark for deletion */
453         func = device_get_ivars(dev);
454         if (func != NULL)
455                 func->varinfo = NULL;
456
457         return 0;
458 }
459
460 /************************************************************/
461
462 static device_method_t ua_pcm_methods[] = {
463         /* Device interface */
464         DEVMETHOD(device_probe,         ua_probe),
465         DEVMETHOD(device_attach,        ua_attach),
466         DEVMETHOD(device_detach,        ua_detach),
467
468         { 0, 0 }
469 };
470
471 static driver_t ua_pcm_driver = {
472         "pcm",
473         ua_pcm_methods,
474         PCM_SOFTC_SIZE,
475 };
476
477
478 DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0);
479 MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1);
480 MODULE_DEPEND(ua_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
481 MODULE_VERSION(ua_pcm, 1);