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