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