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 }; 58 59 #define UAUDIO_DEFAULT_BUFSZ 16*1024 60 61 /************************************************************/ 62 static void * 63 ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 64 { 65 device_t pa_dev; 66 67 struct ua_info *sc = devinfo; 68 struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 69 70 ch->parent = sc; 71 ch->channel = c; 72 ch->buffer = b; 73 ch->dir = dir; 74 75 pa_dev = device_get_parent(sc->sc_dev); 76 77 ch->buf = malloc(sc->bufsz, M_DEVBUF, M_NOWAIT); 78 if (ch->buf == NULL) 79 return NULL; 80 if (sndbuf_setup(b, ch->buf, sc->bufsz) != 0) { 81 free(ch->buf, M_DEVBUF); 82 return NULL; 83 } 84 uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf, ch->buf+sc->bufsz, ch->channel, dir); 85 if (bootverbose) 86 device_printf(pa_dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? 87 "play" : "rec", sndbuf_getbuf(ch->buffer)); 88 89 ch->dir = dir; 90 #ifndef NO_RECORDING 91 ch->hwch = 1; 92 if (dir == PCMDIR_PLAY) 93 ch->hwch = 2; 94 #else 95 ch->hwch = 2; 96 #endif 97 98 return ch; 99 } 100 101 static int 102 ua_chan_free(kobj_t obj, void *data) 103 { 104 struct ua_chinfo *ua = data; 105 106 if (ua->buf != NULL) 107 free(ua->buf, M_DEVBUF); 108 return 0; 109 } 110 111 static int 112 ua_chan_setformat(kobj_t obj, void *data, u_int32_t format) 113 { 114 device_t pa_dev; 115 struct ua_info *ua; 116 117 struct ua_chinfo *ch = data; 118 119 /* 120 * At this point, no need to query as we shouldn't select an unsorted format 121 */ 122 ua = ch->parent; 123 pa_dev = device_get_parent(ua->sc_dev); 124 uaudio_chan_set_param_format(pa_dev, format, ch->dir); 125 126 ch->fmt = format; 127 return 0; 128 } 129 130 static int 131 ua_chan_setspeed(kobj_t obj, void *data, u_int32_t speed) 132 { 133 struct ua_chinfo *ch; 134 device_t pa_dev; 135 int bestspeed; 136 137 ch = data; 138 pa_dev = device_get_parent(ch->parent->sc_dev); 139 140 if ((bestspeed = uaudio_chan_set_param_speed(pa_dev, speed, ch->dir))) 141 ch->spd = bestspeed; 142 143 return ch->spd; 144 } 145 146 static int 147 ua_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 148 { 149 device_t pa_dev; 150 struct ua_chinfo *ch = data; 151 struct ua_info *ua = ch->parent; 152 u_int32_t blkcnt; 153 154 RANGE(blocksize, 128, ua->bufsz / 2); 155 blkcnt = ua->bufsz / blocksize; 156 157 if ((sndbuf_getblksz(ch->buffer) != blocksize || 158 sndbuf_getblkcnt(ch->buffer) != blkcnt) && 159 sndbuf_resize(ch->buffer, blkcnt, blocksize) != 0) 160 device_printf(ua->sc_dev, "%s: failed blksz=%u blkcnt=%u\n", 161 __func__, blocksize, blkcnt); 162 163 ch->blksz = sndbuf_getblksz(ch->buffer); 164 165 pa_dev = device_get_parent(ua->sc_dev); 166 uaudio_chan_set_param_blocksize(pa_dev, ch->blksz, ch->dir); 167 168 return ch->blksz; 169 } 170 171 static int 172 ua_chan_trigger(kobj_t obj, void *data, int go) 173 { 174 device_t pa_dev; 175 struct ua_info *ua; 176 struct ua_chinfo *ch = data; 177 178 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 179 return 0; 180 181 ua = ch->parent; 182 pa_dev = device_get_parent(ua->sc_dev); 183 184 /* XXXXX */ 185 if (ch->dir == PCMDIR_PLAY) { 186 if (go == PCMTRIG_START) { 187 uaudio_trigger_output(pa_dev); 188 } else { 189 uaudio_halt_out_dma(pa_dev); 190 } 191 } else { 192 #ifndef NO_RECORDING 193 if (go == PCMTRIG_START) 194 uaudio_trigger_input(pa_dev); 195 else 196 uaudio_halt_in_dma(pa_dev); 197 #endif 198 } 199 200 return 0; 201 } 202 203 static int 204 ua_chan_getptr(kobj_t obj, void *data) 205 { 206 device_t pa_dev; 207 struct ua_info *ua; 208 struct ua_chinfo *ch = data; 209 210 ua = ch->parent; 211 pa_dev = device_get_parent(ua->sc_dev); 212 213 return uaudio_chan_getptr(pa_dev, ch->dir); 214 } 215 216 static struct pcmchan_caps * 217 ua_chan_getcaps(kobj_t obj, void *data) 218 { 219 struct ua_chinfo *ch; 220 221 ch = data; 222 return (ch->dir == PCMDIR_PLAY) ? &(ch->parent->ua_playcaps) : &(ch->parent->ua_reccaps); 223 } 224 225 static kobj_method_t ua_chan_methods[] = { 226 KOBJMETHOD(channel_init, ua_chan_init), 227 KOBJMETHOD(channel_free, ua_chan_free), 228 KOBJMETHOD(channel_setformat, ua_chan_setformat), 229 KOBJMETHOD(channel_setspeed, ua_chan_setspeed), 230 KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize), 231 KOBJMETHOD(channel_trigger, ua_chan_trigger), 232 KOBJMETHOD(channel_getptr, ua_chan_getptr), 233 KOBJMETHOD(channel_getcaps, ua_chan_getcaps), 234 { 0, 0 } 235 }; 236 237 CHANNEL_DECLARE(ua_chan); 238 239 /************************************************************/ 240 static int 241 ua_mixer_init(struct snd_mixer *m) 242 { 243 u_int32_t mask; 244 device_t pa_dev; 245 struct snddev_info *d; 246 struct ua_info *ua = mix_getdevinfo(m); 247 248 pa_dev = device_get_parent(ua->sc_dev); 249 d = device_get_softc(ua->sc_dev); 250 251 mask = uaudio_query_mix_info(pa_dev); 252 if (d != NULL) { 253 if (!(mask & SOUND_MASK_PCM)) { 254 /* 255 * Emulate missing pcm mixer controller 256 * through FEEDER_VOLUME 257 */ 258 d->flags |= SD_F_SOFTPCMVOL; 259 } 260 if (!(mask & SOUND_MASK_VOLUME)) { 261 mix_setparentchild(m, SOUND_MIXER_VOLUME, 262 SOUND_MASK_PCM); 263 mix_setrealdev(m, SOUND_MIXER_VOLUME, 264 SOUND_MIXER_NONE); 265 } 266 } 267 mix_setdevs(m, mask); 268 269 mask = uaudio_query_recsrc_info(pa_dev); 270 mix_setrecdevs(m, mask); 271 272 return 0; 273 } 274 275 static int 276 ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right) 277 { 278 device_t pa_dev; 279 struct ua_info *ua = mix_getdevinfo(m); 280 281 pa_dev = device_get_parent(ua->sc_dev); 282 uaudio_mixer_set(pa_dev, type, left, right); 283 284 return left | (right << 8); 285 } 286 287 static int 288 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src) 289 { 290 device_t pa_dev; 291 struct ua_info *ua = mix_getdevinfo(m); 292 293 pa_dev = device_get_parent(ua->sc_dev); 294 return uaudio_mixer_setrecsrc(pa_dev, src); 295 } 296 297 static kobj_method_t ua_mixer_methods[] = { 298 KOBJMETHOD(mixer_init, ua_mixer_init), 299 KOBJMETHOD(mixer_set, ua_mixer_set), 300 KOBJMETHOD(mixer_setrecsrc, ua_mixer_setrecsrc), 301 302 { 0, 0 } 303 }; 304 MIXER_DECLARE(ua_mixer); 305 /************************************************************/ 306 307 308 static int 309 ua_probe(device_t dev) 310 { 311 char *s; 312 struct sndcard_func *func; 313 314 /* The parent device has already been probed. */ 315 316 func = device_get_ivars(dev); 317 if (func == NULL || func->func != SCF_PCM) 318 return (ENXIO); 319 320 s = "USB Audio"; 321 322 device_set_desc(dev, s); 323 return BUS_PROBE_DEFAULT; 324 } 325 326 static int 327 ua_attach(device_t dev) 328 { 329 struct ua_info *ua; 330 char status[SND_STATUSLEN]; 331 device_t pa_dev; 332 u_int32_t nplay, nrec; 333 int i; 334 335 ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_ZERO | M_NOWAIT); 336 if (ua == NULL) 337 return ENXIO; 338 339 ua->sc_dev = dev; 340 341 pa_dev = device_get_parent(dev); 342 343 ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536); 344 if (bootverbose) 345 device_printf(dev, "using a default buffer size of %jd\n", (intmax_t)ua->bufsz); 346 347 if (mixer_init(dev, &ua_mixer_class, ua)) { 348 goto bad; 349 } 350 351 snprintf(status, SND_STATUSLEN, "at ? %s", PCM_KLDSTRING(snd_uaudio)); 352 353 ua->ua_playcaps.fmtlist = ua->ua_playfmt; 354 ua->ua_reccaps.fmtlist = ua->ua_recfmt; 355 nplay = uaudio_query_formats(pa_dev, PCMDIR_PLAY, FORMAT_NUM * 2, &ua->ua_playcaps); 356 nrec = uaudio_query_formats(pa_dev, PCMDIR_REC, FORMAT_NUM * 2, &ua->ua_reccaps); 357 358 if (nplay > 1) 359 nplay = 1; 360 if (nrec > 1) 361 nrec = 1; 362 363 #ifndef NO_RECORDING 364 if (pcm_register(dev, ua, nplay, nrec)) { 365 #else 366 if (pcm_register(dev, ua, nplay, 0)) { 367 #endif 368 goto bad; 369 } 370 371 sndstat_unregister(dev); 372 uaudio_sndstat_register(dev); 373 374 for (i = 0; i < nplay; i++) { 375 pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua); 376 } 377 #ifndef NO_RECORDING 378 for (i = 0; i < nrec; i++) { 379 pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua); 380 } 381 #endif 382 pcm_setstatus(dev, status); 383 384 return 0; 385 386 bad: free(ua, M_DEVBUF); 387 return ENXIO; 388 } 389 390 static int 391 ua_detach(device_t dev) 392 { 393 int r; 394 struct ua_info *sc; 395 396 r = pcm_unregister(dev); 397 if (r) 398 return r; 399 400 sc = pcm_getdevinfo(dev); 401 free(sc, M_DEVBUF); 402 403 return 0; 404 } 405 406 /************************************************************/ 407 408 static device_method_t ua_pcm_methods[] = { 409 /* Device interface */ 410 DEVMETHOD(device_probe, ua_probe), 411 DEVMETHOD(device_attach, ua_attach), 412 DEVMETHOD(device_detach, ua_detach), 413 414 { 0, 0 } 415 }; 416 417 static driver_t ua_pcm_driver = { 418 "pcm", 419 ua_pcm_methods, 420 PCM_SOFTC_SIZE, 421 }; 422 423 424 DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0); 425 MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1); 426 MODULE_DEPEND(ua_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 427 MODULE_VERSION(ua_pcm, 1); 428