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 int dir, hwch; 44 u_int32_t fmt, spd, blksz; /* XXXXX */ 45 }; 46 47 struct ua_info { 48 device_t sc_dev; 49 struct ua_chinfo pch, rch; 50 bus_dma_tag_t parent_dmat; 51 }; 52 53 static u_int32_t ua_playfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */ 54 55 static struct pcmchan_caps ua_playcaps = {8000, 48000, ua_playfmt, 0}; 56 57 static u_int32_t ua_recfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */ 58 59 static struct pcmchan_caps ua_reccaps = {8000, 48000, ua_recfmt, 0}; 60 61 #define UAUDIO_PCM_BUFF_SIZE 16*1024 62 63 /************************************************************/ 64 static void * 65 ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 66 { 67 device_t pa_dev; 68 u_char *buf,*end; 69 70 struct ua_info *sc = devinfo; 71 struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 72 73 ch->parent = sc; 74 ch->channel = c; 75 ch->buffer = b; 76 ch->dir = dir; 77 78 pa_dev = device_get_parent(sc->sc_dev); 79 /* Create ua_playfmt[] & ua_recfmt[] */ 80 uaudio_query_formats(pa_dev, (u_int32_t *)&ua_playfmt, (u_int32_t *)&ua_recfmt); 81 if (ua_playfmt[0] == 0) { 82 printf("%s channel supported format list invalid\n", dir == PCMDIR_PLAY? "play" : "record"); 83 return NULL; 84 } 85 86 /* allocate PCM side DMA buffer */ 87 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, UAUDIO_PCM_BUFF_SIZE) != 0) { 88 return NULL; 89 } 90 91 buf = end = sndbuf_getbuf(b); 92 end += sndbuf_getsize(b); 93 uaudio_chan_set_param_pcm_dma_buff(pa_dev, buf, end, ch->channel, dir); 94 95 ch->dir = dir; 96 #ifndef NO_RECORDING 97 ch->hwch = 1; 98 if (dir == PCMDIR_PLAY) 99 ch->hwch = 2; 100 #else 101 ch->hwch = 2; 102 #endif 103 104 return ch; 105 } 106 107 static int 108 ua_chan_setformat(kobj_t obj, void *data, u_int32_t format) 109 { 110 device_t pa_dev; 111 struct ua_info *ua; 112 113 struct ua_chinfo *ch = data; 114 115 ua = ch->parent; 116 pa_dev = device_get_parent(ua->sc_dev); 117 uaudio_chan_set_param_format(pa_dev, format, ch->dir); 118 119 ch->fmt = format; 120 return 0; 121 } 122 123 static int 124 ua_chan_setspeed(kobj_t obj, void *data, u_int32_t speed) 125 { 126 device_t pa_dev; 127 struct ua_info *ua; 128 129 struct ua_chinfo *ch = data; 130 ch->spd = speed; 131 132 ua = ch->parent; 133 pa_dev = device_get_parent(ua->sc_dev); 134 uaudio_chan_set_param_speed(pa_dev, speed, ch->dir); 135 136 return ch->spd; 137 } 138 139 static int 140 ua_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 141 { 142 device_t pa_dev; 143 struct ua_info *ua; 144 struct ua_chinfo *ch = data; 145 /* ch->blksz = blocksize; */ 146 if (blocksize) { 147 ch->blksz = blocksize; 148 } else { 149 ch->blksz = UAUDIO_PCM_BUFF_SIZE/2; 150 } 151 152 /* XXXXX */ 153 ua = ch->parent; 154 pa_dev = device_get_parent(ua->sc_dev); 155 uaudio_chan_set_param_blocksize(pa_dev, blocksize, ch->dir); 156 157 return ch->blksz; 158 } 159 160 static int 161 ua_chan_trigger(kobj_t obj, void *data, int go) 162 { 163 device_t pa_dev; 164 struct ua_info *ua; 165 struct ua_chinfo *ch = data; 166 167 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 168 return 0; 169 170 ua = ch->parent; 171 pa_dev = device_get_parent(ua->sc_dev); 172 173 /* XXXXX */ 174 if (ch->dir == PCMDIR_PLAY) { 175 if (go == PCMTRIG_START) { 176 uaudio_trigger_output(pa_dev); 177 } else { 178 uaudio_halt_out_dma(pa_dev); 179 } 180 } else { 181 #ifndef NO_RECORDING 182 if (go == PCMTRIG_START) 183 uaudio_trigger_input(pa_dev); 184 else 185 uaudio_halt_in_dma(pa_dev); 186 #endif 187 } 188 189 return 0; 190 } 191 192 static int 193 ua_chan_getptr(kobj_t obj, void *data) 194 { 195 device_t pa_dev; 196 struct ua_info *ua; 197 struct ua_chinfo *ch = data; 198 199 ua = ch->parent; 200 pa_dev = device_get_parent(ua->sc_dev); 201 202 return uaudio_chan_getptr(pa_dev, ch->dir); 203 } 204 205 static struct pcmchan_caps * 206 ua_chan_getcaps(kobj_t obj, void *data) 207 { 208 struct ua_chinfo *ch = data; 209 210 return (ch->dir == PCMDIR_PLAY) ? &ua_playcaps : & ua_reccaps; 211 } 212 213 static kobj_method_t ua_chan_methods[] = { 214 KOBJMETHOD(channel_init, ua_chan_init), 215 KOBJMETHOD(channel_setformat, ua_chan_setformat), 216 KOBJMETHOD(channel_setspeed, ua_chan_setspeed), 217 KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize), 218 KOBJMETHOD(channel_trigger, ua_chan_trigger), 219 KOBJMETHOD(channel_getptr, ua_chan_getptr), 220 KOBJMETHOD(channel_getcaps, ua_chan_getcaps), 221 { 0, 0 } 222 }; 223 224 CHANNEL_DECLARE(ua_chan); 225 226 /************************************************************/ 227 static int 228 ua_mixer_init(struct snd_mixer *m) 229 { 230 u_int32_t mask; 231 device_t pa_dev; 232 struct ua_info *ua = mix_getdevinfo(m); 233 234 pa_dev = device_get_parent(ua->sc_dev); 235 236 mask = uaudio_query_mix_info(pa_dev); 237 mix_setdevs(m, mask); 238 239 mask = uaudio_query_recsrc_info(pa_dev); 240 mix_setrecdevs(m, mask); 241 242 return 0; 243 } 244 245 static int 246 ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right) 247 { 248 device_t pa_dev; 249 struct ua_info *ua = mix_getdevinfo(m); 250 251 pa_dev = device_get_parent(ua->sc_dev); 252 uaudio_mixer_set(pa_dev, type, left, right); 253 254 return left | (right << 8); 255 } 256 257 static int 258 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src) 259 { 260 device_t pa_dev; 261 struct ua_info *ua = mix_getdevinfo(m); 262 263 pa_dev = device_get_parent(ua->sc_dev); 264 return uaudio_mixer_setrecsrc(pa_dev, src); 265 } 266 267 static kobj_method_t ua_mixer_methods[] = { 268 KOBJMETHOD(mixer_init, ua_mixer_init), 269 KOBJMETHOD(mixer_set, ua_mixer_set), 270 KOBJMETHOD(mixer_setrecsrc, ua_mixer_setrecsrc), 271 272 { 0, 0 } 273 }; 274 MIXER_DECLARE(ua_mixer); 275 /************************************************************/ 276 277 278 static int 279 ua_probe(device_t dev) 280 { 281 char *s; 282 struct sndcard_func *func; 283 284 /* The parent device has already been probed. */ 285 286 func = device_get_ivars(dev); 287 if (func == NULL || func->func != SCF_PCM) 288 return (ENXIO); 289 290 s = "USB Audio"; 291 292 device_set_desc(dev, s); 293 return 0; 294 } 295 296 static int 297 ua_attach(device_t dev) 298 { 299 struct ua_info *ua; 300 char status[SND_STATUSLEN]; 301 unsigned int bufsz; 302 303 ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_NOWAIT); 304 if (!ua) 305 return ENXIO; 306 bzero(ua, sizeof *ua); 307 308 ua->sc_dev = dev; 309 310 bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_PCM_BUFF_SIZE, 65536); 311 312 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 313 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 314 /*highaddr*/BUS_SPACE_MAXADDR, 315 /*filter*/NULL, /*filterarg*/NULL, 316 /*maxsize*/bufsz, /*nsegments*/1, 317 /*maxsegz*/0x3fff, /*flags*/0, 318 /*lockfunc*/busdma_lock_mutex, 319 /*lockarg*/&Giant, 320 &ua->parent_dmat) != 0) { 321 device_printf(dev, "unable to create dma tag\n"); 322 goto bad; 323 } 324 325 if (mixer_init(dev, &ua_mixer_class, ua)) { 326 return(ENXIO); 327 } 328 329 snprintf(status, SND_STATUSLEN, "at addr ?"); 330 331 #ifndef NO_RECORDING 332 if (pcm_register(dev, ua, 1, 1)) { 333 #else 334 if (pcm_register(dev, ua, 1, 0)) { 335 #endif 336 return(ENXIO); 337 } 338 339 pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua); 340 #ifndef NO_RECORDING 341 pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua); 342 #endif 343 pcm_setstatus(dev, status); 344 345 return 0; 346 bad: 347 if (ua->parent_dmat) 348 bus_dma_tag_destroy(ua->parent_dmat); 349 free(ua, M_DEVBUF); 350 351 return ENXIO; 352 } 353 354 static int 355 ua_detach(device_t dev) 356 { 357 int r; 358 struct ua_info *sc; 359 360 r = pcm_unregister(dev); 361 if (r) 362 return r; 363 364 sc = pcm_getdevinfo(dev); 365 bus_dma_tag_destroy(sc->parent_dmat); 366 free(sc, M_DEVBUF); 367 368 return 0; 369 } 370 371 /************************************************************/ 372 373 static device_method_t ua_pcm_methods[] = { 374 /* Device interface */ 375 DEVMETHOD(device_probe, ua_probe), 376 DEVMETHOD(device_attach, ua_attach), 377 DEVMETHOD(device_detach, ua_detach), 378 379 { 0, 0 } 380 }; 381 382 static driver_t ua_pcm_driver = { 383 "pcm", 384 ua_pcm_methods, 385 PCM_SOFTC_SIZE, 386 }; 387 388 389 DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0); 390 MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1); 391 MODULE_DEPEND(ua_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 392 MODULE_VERSION(ua_pcm, 1); 393