1 /* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include "pci.h" 30 #include "pcm.h" 31 32 #include <dev/sound/pcm/sound.h> 33 #include <dev/sound/pcm/ac97.h> 34 #include <gnu/dev/sound/pci/emu10k1.h> 35 36 #include <pci/pcireg.h> 37 #include <pci/pcivar.h> 38 #include <sys/queue.h> 39 40 /* -------------------------------------------------------------------- */ 41 42 #define EMU10K1_PCI_ID 0x00021102 43 #define EMU_BUFFSIZE 4096 44 #undef EMUDEBUG 45 46 struct emu_memblk { 47 SLIST_ENTRY(emu_memblk) link; 48 void *buf; 49 u_int32_t pte_start, pte_size; 50 }; 51 52 struct emu_mem { 53 u_int8_t bmap[MAXPAGES / 8]; 54 u_int32_t *ptb_pages; 55 void *silent_page; 56 SLIST_HEAD(, emu_memblk) blocks; 57 }; 58 59 struct emu_voice { 60 int vnum; 61 int b16:1, stereo:1, busy:1, running:1, ismaster:1, istracker:1; 62 int speed; 63 int start, end, vol; 64 u_int32_t buf; 65 struct emu_voice *slave, *tracker; 66 pcm_channel *channel; 67 }; 68 69 struct sc_info; 70 71 /* channel registers */ 72 struct sc_chinfo { 73 int spd, dir, fmt; 74 struct emu_voice *master, *slave, *tracker; 75 snd_dbuf *buffer; 76 pcm_channel *channel; 77 struct sc_info *parent; 78 }; 79 80 /* device private data */ 81 struct sc_info { 82 device_t dev; 83 u_int32_t type, rev; 84 u_int32_t tos_link:1, APS:1; 85 86 bus_space_tag_t st; 87 bus_space_handle_t sh; 88 bus_dma_tag_t parent_dmat; 89 90 struct resource *reg, *irq; 91 int regtype, regid, irqid; 92 void *ih; 93 94 struct emu_mem mem; 95 struct emu_voice voice[64]; 96 struct sc_chinfo pch, rch; 97 }; 98 99 /* -------------------------------------------------------------------- */ 100 101 /* 102 * prototypes 103 */ 104 105 /* channel interface */ 106 static void *emuchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 107 static int emuchan_setdir(void *data, int dir); 108 static int emuchan_setformat(void *data, u_int32_t format); 109 static int emuchan_setspeed(void *data, u_int32_t speed); 110 static int emuchan_setblocksize(void *data, u_int32_t blocksize); 111 static int emuchan_trigger(void *data, int go); 112 static int emuchan_getptr(void *data); 113 static pcmchan_caps *emuchan_getcaps(void *data); 114 115 /* talk to the codec - called from ac97.c */ 116 static u_int32_t emu_rdcd(void *, int); 117 static void emu_wrcd(void *, int, u_int32_t); 118 119 /* stuff */ 120 static int emu_init(struct sc_info *); 121 static void emu_intr(void *); 122 static void *emu_malloc(struct sc_info *sc, u_int32_t sz); 123 static void *emu_memalloc(struct sc_info *sc, u_int32_t sz); 124 #ifdef notyet 125 static int emu_memfree(struct sc_info *sc, void *buf); 126 #endif 127 static int emu_memstart(struct sc_info *sc, void *buf); 128 #ifdef EMUDEBUG 129 static void emu_vdump(struct sc_info *sc, struct emu_voice *v); 130 #endif 131 132 /* talk to the card */ 133 static u_int32_t emu_rd(struct sc_info *, int, int); 134 static void emu_wr(struct sc_info *, int, u_int32_t, int); 135 136 /* -------------------------------------------------------------------- */ 137 138 static pcmchan_caps emu_reccaps = { 139 4000, 48000, 140 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 141 AFMT_STEREO | AFMT_S16_LE 142 }; 143 144 static pcmchan_caps emu_playcaps = { 145 4000, 48000, 146 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 147 AFMT_STEREO | AFMT_S16_LE 148 }; 149 150 static pcm_channel emu_chantemplate = { 151 emuchan_init, 152 emuchan_setdir, 153 emuchan_setformat, 154 emuchan_setspeed, 155 emuchan_setblocksize, 156 emuchan_trigger, 157 emuchan_getptr, 158 emuchan_getcaps, 159 }; 160 161 /* -------------------------------------------------------------------- */ 162 /* Hardware */ 163 static u_int32_t 164 emu_rd(struct sc_info *sc, int regno, int size) 165 { 166 switch (size) { 167 case 1: 168 return bus_space_read_1(sc->st, sc->sh, regno); 169 case 2: 170 return bus_space_read_2(sc->st, sc->sh, regno); 171 case 4: 172 return bus_space_read_4(sc->st, sc->sh, regno); 173 default: 174 return 0xffffffff; 175 } 176 } 177 178 static void 179 emu_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 180 { 181 switch (size) { 182 case 1: 183 bus_space_write_1(sc->st, sc->sh, regno, data); 184 break; 185 case 2: 186 bus_space_write_2(sc->st, sc->sh, regno, data); 187 break; 188 case 4: 189 bus_space_write_4(sc->st, sc->sh, regno, data); 190 break; 191 } 192 } 193 194 static u_int32_t 195 emu_rdptr(struct sc_info *sc, int chn, int reg) 196 { 197 u_int32_t ptr, val, mask, size, offset; 198 199 ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK); 200 emu_wr(sc, PTR, ptr, 4); 201 val = emu_rd(sc, DATA, 4); 202 if (reg & 0xff000000) { 203 size = (reg >> 24) & 0x3f; 204 offset = (reg >> 16) & 0x1f; 205 mask = ((1 << size) - 1) << offset; 206 val &= mask; 207 val >>= offset; 208 } 209 return val; 210 } 211 212 static void 213 emu_wrptr(struct sc_info *sc, int chn, int reg, u_int32_t data) 214 { 215 u_int32_t ptr, mask, size, offset; 216 217 ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK); 218 emu_wr(sc, PTR, ptr, 4); 219 if (reg & 0xff000000) { 220 size = (reg >> 24) & 0x3f; 221 offset = (reg >> 16) & 0x1f; 222 mask = ((1 << size) - 1) << offset; 223 data <<= offset; 224 data &= mask; 225 data |= emu_rd(sc, DATA, 4) & ~mask; 226 } 227 emu_wr(sc, DATA, data, 4); 228 } 229 230 static void 231 emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data) 232 { 233 emu_wrptr(sc, 0, MICROCODEBASE + pc, data); 234 } 235 236 /* playback channel interrupts */ 237 static u_int32_t 238 emu_testint(struct sc_info *sc, char channel) 239 { 240 int reg = (channel & 0x20)? CLIPH : CLIPL; 241 channel &= 0x1f; 242 reg |= 1 << 24; 243 reg |= channel << 16; 244 return emu_rdptr(sc, 0, reg); 245 } 246 247 static void 248 emu_clrint(struct sc_info *sc, char channel) 249 { 250 int reg = (channel & 0x20)? CLIPH : CLIPL; 251 channel &= 0x1f; 252 reg |= 1 << 24; 253 reg |= channel << 16; 254 emu_wrptr(sc, 0, reg, 1); 255 } 256 257 static void 258 emu_enaint(struct sc_info *sc, char channel, int enable) 259 { 260 int reg = (channel & 0x20)? CLIEH : CLIEL; 261 channel &= 0x1f; 262 reg |= 1 << 24; 263 reg |= channel << 16; 264 emu_wrptr(sc, 0, reg, enable); 265 } 266 267 static void 268 emu_enastop(struct sc_info *sc, char channel, int enable) 269 { 270 int reg = (channel & 0x20)? SOLEH : SOLEL; 271 channel &= 0x1f; 272 reg |= 1 << 24; 273 reg |= channel << 16; 274 emu_wrptr(sc, 0, reg, enable); 275 } 276 277 /* ac97 codec */ 278 static u_int32_t 279 emu_rdcd(void *devinfo, int regno) 280 { 281 struct sc_info *sc = (struct sc_info *)devinfo; 282 283 emu_wr(sc, AC97ADDRESS, regno, 1); 284 return emu_rd(sc, AC97DATA, 2); 285 } 286 287 static void 288 emu_wrcd(void *devinfo, int regno, u_int32_t data) 289 { 290 struct sc_info *sc = (struct sc_info *)devinfo; 291 292 emu_wr(sc, AC97ADDRESS, regno, 1); 293 emu_wr(sc, AC97DATA, data, 2); 294 } 295 296 static u_int32_t 297 emu_rate_to_pitch(u_int32_t rate) 298 { 299 static u_int32_t logMagTable[128] = { 300 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2, 301 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5, 302 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081, 303 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191, 304 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7, 305 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829, 306 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e, 307 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26, 308 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d, 309 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885, 310 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899, 311 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c, 312 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3, 313 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3, 314 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83, 315 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df 316 }; 317 static char logSlopeTable[128] = { 318 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58, 319 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53, 320 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f, 321 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b, 322 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47, 323 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44, 324 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41, 325 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e, 326 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, 327 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 328 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37, 329 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35, 330 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34, 331 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, 332 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30, 333 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f 334 }; 335 int i; 336 337 if (rate == 0) 338 return 0; /* Bail out if no leading "1" */ 339 rate *= 11185; /* Scale 48000 to 0x20002380 */ 340 for (i = 31; i > 0; i--) { 341 if (rate & 0x80000000) { /* Detect leading "1" */ 342 return (((u_int32_t) (i - 15) << 20) + 343 logMagTable[0x7f & (rate >> 24)] + 344 (0x7f & (rate >> 17)) * 345 logSlopeTable[0x7f & (rate >> 24)]); 346 } 347 rate <<= 1; 348 } 349 350 return 0; /* Should never reach this point */ 351 } 352 353 static struct emu_voice * 354 emu_valloc(struct sc_info *sc) 355 { 356 struct emu_voice *v; 357 int i; 358 359 v = NULL; 360 for (i = 0; i < 64 && sc->voice[i].busy; i++); 361 if (i < 64) { 362 v = &sc->voice[i]; 363 v->busy = 1; 364 } 365 return v; 366 } 367 368 static int 369 emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s, struct emu_voice *t, 370 u_int32_t sz, pcm_channel *c) 371 { 372 void *buf; 373 374 buf = emu_memalloc(sc, sz); 375 if (buf == NULL) 376 return -1; 377 m->start = emu_memstart(sc, buf) * EMUPAGESIZE; 378 m->end = m->start + sz; 379 m->channel = NULL; 380 m->speed = 0; 381 m->b16 = 0; 382 m->stereo = 0; 383 m->running = 0; 384 m->ismaster = 1; 385 m->istracker = 0; 386 m->vol = 0xff; 387 m->buf = vtophys(buf); 388 m->slave = s; 389 m->tracker = t; 390 if (s != NULL) { 391 s->start = m->start; 392 s->end = m->end; 393 s->channel = NULL; 394 s->speed = 0; 395 s->b16 = 0; 396 s->stereo = 0; 397 s->running = 0; 398 s->ismaster = 0; 399 s->istracker = 0; 400 s->vol = m->vol; 401 s->buf = m->buf; 402 s->slave = NULL; 403 s->tracker = NULL; 404 } 405 if (t != NULL) { 406 t->start = m->start; 407 t->end = t->start + sz / 2; 408 t->channel = c; 409 t->speed = 0; 410 t->b16 = 0; 411 t->stereo = 0; 412 t->running = 0; 413 t->ismaster = 0; 414 t->istracker = 1; 415 t->vol = 0; 416 t->buf = m->buf; 417 t->slave = NULL; 418 t->tracker = NULL; 419 } 420 if (c != NULL) { 421 c->buffer.buf = buf; 422 c->buffer.bufsize = sz; 423 } 424 return 0; 425 } 426 427 static void 428 emu_vsetup(struct sc_chinfo *ch) 429 { 430 struct emu_voice *v = ch->master; 431 432 if (ch->fmt) { 433 v->b16 = (ch->fmt & AFMT_16BIT)? 1 : 0; 434 v->stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 435 if (v->slave != NULL) { 436 v->slave->b16 = v->b16; 437 v->slave->stereo = v->stereo; 438 } 439 if (v->tracker != NULL) { 440 v->tracker->b16 = v->b16; 441 v->tracker->stereo = v->stereo; 442 } 443 } 444 if (ch->spd) { 445 v->speed = ch->spd; 446 if (v->slave != NULL) 447 v->slave->speed = v->speed; 448 if (v->tracker != NULL) 449 v->tracker->speed = v->speed; 450 } 451 } 452 453 static void 454 emu_vwrite(struct sc_info *sc, struct emu_voice *v) 455 { 456 int s, l, r, p, x; 457 u_int32_t sa, ea, start = 0, val = 0, v2 = 0, sample, silent_page, i; 458 459 s = (v->stereo? 1 : 0) + (v->b16? 1 : 0); 460 sa = v->start >> s; 461 ea = v->end >> s; 462 l = r = x = v->vol; 463 if (v->stereo) { 464 l = v->ismaster? l : 0; 465 r = v->ismaster? 0 : r; 466 } 467 p = emu_rate_to_pitch(v->speed) >> 8; 468 sample = v->b16? 0 : 0x80808080; 469 470 emu_wrptr(sc, v->vnum, DCYSUSV, ENV_OFF); 471 emu_wrptr(sc, v->vnum, VTFT, VTFT_FILTERTARGET_MASK); 472 emu_wrptr(sc, v->vnum, CVCF, CVCF_CURRENTFILTER_MASK); 473 emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000); 474 475 emu_wrptr(sc, v->vnum, PTRX, (x << 8) | r); 476 if (v->ismaster) { 477 val = 0x20; 478 if (v->stereo) { 479 val <<= 1; 480 emu_wrptr(sc, v->vnum, CPF, CPF_STEREO_MASK); 481 emu_wrptr(sc, v->slave->vnum, CPF, CPF_STEREO_MASK); 482 } else 483 emu_wrptr(sc, v->vnum, CPF, 0); 484 sample = 0x80808080; 485 if (!v->b16) 486 val <<= 1; 487 val -= 4; 488 /* 489 * mono 8bit: val = 0x3c 490 * stereo 8bit: val = 0x7c 491 * mono 16bit: val = 0x1c 492 * stereo 16bit: val = 0x3c 493 */ 494 if (v->stereo) { 495 v2 = 0x3c << 16; 496 emu_wrptr(sc, v->vnum, CCR, v2); 497 emu_wrptr(sc, v->slave->vnum, CCR, val << 16); 498 emu_wrptr(sc, v->slave->vnum, CDE, sample); 499 emu_wrptr(sc, v->slave->vnum, CDF, sample); 500 start = sa + val / 2; 501 } else { 502 v2 = 0x1c << 16; 503 emu_wrptr(sc, v->vnum, CCR, v2); 504 emu_wrptr(sc, v->vnum, CDE, sample); 505 emu_wrptr(sc, v->vnum, CDF, sample); 506 start = sa + val; 507 } 508 val <<= 25; 509 val |= v2; 510 /* 511 * mono 8bit: val = 0x781c0000 512 * stereo 8bit: val = 0xf83c0000 513 * mono 16bit: val = 0x381c0000 514 * stereo 16bit: val = 0x783c0000 515 */ 516 start |= CCCA_INTERPROM_0; 517 } 518 emu_wrptr(sc, v->vnum, DSL, ea); 519 emu_wrptr(sc, v->vnum, PSST, sa | (l << 24)); 520 emu_wrptr(sc, v->vnum, CCCA, start | (v->b16? 0 : CCCA_8BITSELECT)); 521 522 emu_wrptr(sc, v->vnum, Z1, 0); 523 emu_wrptr(sc, v->vnum, Z2, 0); 524 525 silent_page = ((u_int32_t)v->buf << 1) | (v->start / EMUPAGESIZE); 526 emu_wrptr(sc, v->vnum, MAPA, silent_page); 527 emu_wrptr(sc, v->vnum, MAPB, silent_page); 528 529 if (v->ismaster) 530 emu_wrptr(sc, v->vnum, CCR, val); 531 532 for (i = CD0; i < CDF; i++) 533 emu_wrptr(sc, v->vnum, i, sample); 534 535 emu_wrptr(sc, v->vnum, ATKHLDV, ATKHLDV_HOLDTIME_MASK | ATKHLDV_ATTACKTIME_MASK); 536 emu_wrptr(sc, v->vnum, LFOVAL1, 0x8000); 537 emu_wrptr(sc, v->vnum, ATKHLDM, 0); 538 emu_wrptr(sc, v->vnum, DCYSUSM, DCYSUSM_DECAYTIME_MASK); 539 emu_wrptr(sc, v->vnum, LFOVAL2, 0x8000); 540 emu_wrptr(sc, v->vnum, IP, p); 541 emu_wrptr(sc, v->vnum, PEFE, 0x7f); 542 emu_wrptr(sc, v->vnum, FMMOD, 0); 543 emu_wrptr(sc, v->vnum, TREMFRQ, 0); 544 emu_wrptr(sc, v->vnum, FM2FRQ2, 0); 545 emu_wrptr(sc, v->vnum, ENVVAL, 0xbfff); 546 emu_wrptr(sc, v->vnum, ENVVOL, 0xbfff); 547 emu_wrptr(sc, v->vnum, IFATN, IFATN_FILTERCUTOFF_MASK); 548 549 if (v->slave != NULL) 550 emu_vwrite(sc, v->slave); 551 if (v->tracker != NULL) 552 emu_vwrite(sc, v->tracker); 553 } 554 555 #define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL)) 556 static void 557 emu_vtrigger(struct sc_info *sc, struct emu_voice *v, int go) 558 { 559 u_int32_t pitch_target; 560 if (go) { 561 pitch_target = IP_TO_CP((emu_rate_to_pitch(v->speed) >> 8)) >> 16; 562 emu_wrptr(sc, v->vnum, PTRX_PITCHTARGET, pitch_target); 563 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, pitch_target); 564 emu_wrptr(sc, v->vnum, VTFT, 0xffff); 565 emu_wrptr(sc, v->vnum, CVCF, 0xffff); 566 emu_enastop(sc, v->vnum, 0); 567 emu_enaint(sc, v->vnum, v->istracker); 568 emu_wrptr(sc, v->vnum, DCYSUSV, ENV_ON | 0x00007f7f); 569 } else { 570 emu_wrptr(sc, v->vnum, IFATN, 0xffff); 571 emu_wrptr(sc, v->vnum, IP, 0); 572 emu_wrptr(sc, v->vnum, VTFT, 0xffff); 573 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, 0); 574 emu_enaint(sc, v->vnum, 0); 575 } 576 if (v->slave != NULL) 577 emu_vtrigger(sc, v->slave, go); 578 if (v->tracker != NULL) 579 emu_vtrigger(sc, v->tracker, go); 580 } 581 582 static int 583 emu_vpos(struct sc_info *sc, struct emu_voice *v) 584 { 585 int s; 586 s = (v->b16? 1 : 0) + (v->stereo? 1 : 0); 587 return ((emu_rdptr(sc, v->vnum, CCCA_CURRADDR) >> s) - v->start); 588 } 589 590 #ifdef EMUDEBUG 591 static void 592 emu_vdump(struct sc_info *sc, struct emu_voice *v) 593 { 594 char *regname[] = { "cpf", "ptrx", "cvcf", "vtft", "z2", "z1", "psst", "dsl", 595 "ccca", "ccr", "clp", "fxrt", "mapa", "mapb", NULL, NULL, 596 "envvol", "atkhldv", "dcysusv", "lfoval1", 597 "envval", "atkhldm", "dcysusm", "lfoval2", 598 "ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2", 599 "tempenv" }; 600 int i, x; 601 602 printf("voice number %d\n", v->vnum); 603 for (i = 0, x = 0; i <= 0x1e; i++) { 604 if (regname[i] == NULL) 605 continue; 606 printf("%s\t[%08x]", regname[i], emu_rdptr(sc, v->vnum, i)); 607 printf("%s", (x == 2)? "\n" : "\t"); 608 x++; 609 if (x > 2) 610 x = 0; 611 } 612 printf("\n\n"); 613 } 614 #endif 615 616 /* channel interface */ 617 void * 618 emuchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 619 { 620 struct sc_info *sc = devinfo; 621 struct sc_chinfo *ch; 622 623 ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 624 ch->buffer = b; 625 ch->parent = sc; 626 ch->channel = c; 627 ch->master = emu_valloc(sc); 628 ch->slave = emu_valloc(sc); 629 ch->tracker = emu_valloc(sc); 630 if (emu_vinit(sc, ch->master, ch->slave, ch->tracker, EMU_BUFFSIZE, ch->channel)) 631 return NULL; 632 else 633 return ch; 634 } 635 636 static int 637 emuchan_setdir(void *data, int dir) 638 { 639 struct sc_chinfo *ch = data; 640 641 ch->dir = dir; 642 return 0; 643 } 644 645 static int 646 emuchan_setformat(void *data, u_int32_t format) 647 { 648 struct sc_chinfo *ch = data; 649 650 ch->fmt = format; 651 return 0; 652 } 653 654 static int 655 emuchan_setspeed(void *data, u_int32_t speed) 656 { 657 struct sc_chinfo *ch = data; 658 659 ch->spd = speed; 660 return ch->spd; 661 } 662 663 static int 664 emuchan_setblocksize(void *data, u_int32_t blocksize) 665 { 666 return blocksize; 667 } 668 669 static int 670 emuchan_trigger(void *data, int go) 671 { 672 struct sc_chinfo *ch = data; 673 struct sc_info *sc = ch->parent; 674 675 if (go == PCMTRIG_EMLDMAWR) return 0; 676 if (go == PCMTRIG_START) { 677 emu_vsetup(ch); 678 emu_vwrite(sc, ch->master); 679 #ifdef EMUDEBUG 680 printf("start [%d bit, %s, %d hz]\n", 681 ch->master->b16? 16 : 8, 682 ch->master->stereo? "stereo" : "mono", 683 ch->master->speed); 684 emu_vdump(sc, ch->master); 685 emu_vdump(sc, ch->slave); 686 #endif 687 } 688 emu_vtrigger(sc, ch->master, (go == PCMTRIG_START)? 1 : 0); 689 return 0; 690 } 691 692 static int 693 emuchan_getptr(void *data) 694 { 695 struct sc_chinfo *ch = data; 696 struct sc_info *sc = ch->parent; 697 698 return emu_vpos(sc, ch->master); 699 } 700 701 static pcmchan_caps * 702 emuchan_getcaps(void *data) 703 { 704 struct sc_chinfo *ch = data; 705 706 return (ch->dir == PCMDIR_PLAY)? &emu_playcaps : &emu_reccaps; 707 } 708 709 /* The interrupt handler */ 710 static void 711 emu_intr(void *p) 712 { 713 struct sc_info *sc = (struct sc_info *)p; 714 u_int32_t stat, i; 715 716 do { 717 stat = emu_rd(sc, IPR, 4); 718 719 /* process irq */ 720 for (i = 0; i < 64; i++) { 721 if (emu_testint(sc, i)) { 722 if (sc->voice[i].channel) 723 chn_intr(sc->voice[i].channel); 724 else 725 device_printf(sc->dev, "bad irq voice %d\n", i); 726 emu_clrint(sc, i); 727 } 728 } 729 730 emu_wr(sc, IPR, stat, 4); 731 } while (stat); 732 } 733 734 /* -------------------------------------------------------------------- */ 735 736 static void * 737 emu_malloc(struct sc_info *sc, u_int32_t sz) 738 { 739 void *buf; 740 bus_dmamap_t map; 741 742 if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map)) 743 return NULL; 744 return buf; 745 } 746 747 static void 748 emu_free(struct sc_info *sc, void *buf) 749 { 750 bus_dmamem_free(sc->parent_dmat, buf, NULL); 751 } 752 753 static void * 754 emu_memalloc(struct sc_info *sc, u_int32_t sz) 755 { 756 u_int32_t blksz, start, idx, ofs, tmp, found; 757 struct emu_mem *mem = &sc->mem; 758 struct emu_memblk *blk; 759 void *buf; 760 761 blksz = sz / EMUPAGESIZE; 762 if (sz > (blksz * EMUPAGESIZE)) 763 blksz++; 764 /* find a free block in the bitmap */ 765 found = 0; 766 start = 0; 767 while (!found && start + blksz < MAXPAGES) { 768 found = 1; 769 for (idx = start; idx < start + blksz; idx++) 770 if (mem->bmap[idx >> 3] & (1 << (idx & 7))) 771 found = 0; 772 if (!found) 773 start++; 774 } 775 if (!found) 776 return NULL; 777 blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT); 778 if (blk == NULL) 779 return NULL; 780 buf = emu_malloc(sc, sz); 781 if (buf == NULL) { 782 free(blk, M_DEVBUF); 783 return NULL; 784 } 785 blk->buf = buf; 786 blk->pte_start = start; 787 blk->pte_size = blksz; 788 /* printf("buf %p, pte_start %d, pte_size %d\n", blk->buf, blk->pte_start, blk->pte_size); */ 789 ofs = 0; 790 for (idx = start; idx < start + blksz; idx++) { 791 mem->bmap[idx >> 3] |= 1 << (idx & 7); 792 tmp = (u_int32_t)vtophys((u_int8_t *)buf + ofs); 793 /* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */ 794 mem->ptb_pages[idx] = (tmp << 1) | idx; 795 ofs += EMUPAGESIZE; 796 } 797 SLIST_INSERT_HEAD(&mem->blocks, blk, link); 798 return buf; 799 } 800 801 #ifdef notyet 802 static int 803 emu_memfree(struct sc_info *sc, void *buf) 804 { 805 u_int32_t idx, tmp; 806 struct emu_mem *mem = &sc->mem; 807 struct emu_memblk *blk, *i; 808 809 blk = NULL; 810 SLIST_FOREACH(i, &mem->blocks, link) { 811 if (i->buf == buf) 812 blk = i; 813 } 814 if (blk == NULL) 815 return EINVAL; 816 SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link); 817 emu_free(sc, buf); 818 tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1; 819 for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) { 820 mem->bmap[idx >> 3] &= ~(1 << (idx & 7)); 821 mem->ptb_pages[idx] = tmp | idx; 822 } 823 free(blk, M_DEVBUF); 824 return 0; 825 } 826 #endif 827 828 static int 829 emu_memstart(struct sc_info *sc, void *buf) 830 { 831 struct emu_mem *mem = &sc->mem; 832 struct emu_memblk *blk, *i; 833 834 blk = NULL; 835 SLIST_FOREACH(i, &mem->blocks, link) { 836 if (i->buf == buf) 837 blk = i; 838 } 839 if (blk == NULL) 840 return -EINVAL; 841 return blk->pte_start; 842 } 843 844 static void 845 emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y, u_int32_t *pc) 846 { 847 emu_wrefx(sc, (*pc) * 2, (x << 10) | y); 848 emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w); 849 (*pc)++; 850 } 851 852 static void 853 emu_initefx(struct sc_info *sc) 854 { 855 int i; 856 u_int32_t pc = 16; 857 858 for (i = 0; i < 512; i++) { 859 emu_wrefx(sc, i * 2, 0x10040); 860 emu_wrefx(sc, i * 2 + 1, 0x610040); 861 } 862 863 for (i = 0; i < 256; i++) 864 emu_wrptr(sc, 0, FXGPREGBASE + i, 0); 865 866 /* FX-8010 DSP Registers: 867 FX Bus 868 0x000-0x00f : 16 registers 869 Input 870 0x010/0x011 : AC97 Codec (l/r) 871 0x012/0x013 : ADC, S/PDIF (l/r) 872 0x014/0x015 : Mic(left), Zoom (l/r) 873 0x016/0x017 : APS S/PDIF?? (l/r) 874 Output 875 0x020/0x021 : AC97 Output (l/r) 876 0x022/0x023 : TOS link out (l/r) 877 0x024/0x025 : ??? (l/r) 878 0x026/0x027 : LiveDrive Headphone (l/r) 879 0x028/0x029 : Rear Channel (l/r) 880 0x02a/0x02b : ADC Recording Buffer (l/r) 881 Constants 882 0x040 - 0x044 = 0 - 4 883 0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20 884 0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000 885 0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000 886 0x04e = 0x80000000, 0x04f = 0x7fffffff 887 Temporary Values 888 0x056 : Accumulator 889 0x058 : Noise source? 890 0x059 : Noise source? 891 General Purpose Registers 892 0x100 - 0x1ff 893 Tank Memory Data Registers 894 0x200 - 0x2ff 895 Tank Memory Address Registers 896 0x300 - 0x3ff 897 */ 898 899 /* Operators: 900 0 : z := w + (x * y >> 31) 901 4 : z := w + x * y 902 6 : z := w + x + y 903 */ 904 905 /* Routing - this will be configurable in later version */ 906 907 /* GPR[0/1] = FX * 4 + SPDIF-in */ 908 emu_addefxop(sc, 4, 0x100, 0x12, 0, 0x44, &pc); 909 emu_addefxop(sc, 4, 0x101, 0x13, 1, 0x44, &pc); 910 /* GPR[0/1] += APS-input */ 911 emu_addefxop(sc, 6, 0x100, 0x100, 0x40, sc->APS ? 0x16 : 0x40, &pc); 912 emu_addefxop(sc, 6, 0x101, 0x101, 0x40, sc->APS ? 0x17 : 0x40, &pc); 913 /* FrontOut (AC97) = GPR[0/1] */ 914 emu_addefxop(sc, 6, 0x20, 0x40, 0x40, 0x100, &pc); 915 emu_addefxop(sc, 6, 0x21, 0x40, 0x41, 0x101, &pc); 916 /* RearOut = (GPR[0/1] * RearVolume) >> 31 */ 917 /* RearVolume = GRP[0x10/0x11] */ 918 emu_addefxop(sc, 0, 0x28, 0x40, 0x110, 0x100, &pc); 919 emu_addefxop(sc, 0, 0x29, 0x40, 0x111, 0x101, &pc); 920 /* TOS out = GPR[0/1] */ 921 emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc); 922 emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc); 923 /* Mute Out2 */ 924 emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc); 925 emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc); 926 /* Mute Out3 */ 927 emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc); 928 emu_addefxop(sc, 6, 0x27, 0x40, 0x40, 0x40, &pc); 929 /* Input0 (AC97) -> Record */ 930 emu_addefxop(sc, 6, 0x2a, 0x40, 0x40, 0x10, &pc); 931 emu_addefxop(sc, 6, 0x2b, 0x40, 0x40, 0x11, &pc); 932 933 emu_wrptr(sc, 0, DBG, 0); 934 } 935 936 /* Probe and attach the card */ 937 static int 938 emu_init(struct sc_info *sc) 939 { 940 u_int32_t spcs, ch, tmp, i; 941 942 /* disable audio and lock cache */ 943 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE, 4); 944 945 /* reset recording buffers */ 946 emu_wrptr(sc, 0, MICBS, 0); 947 emu_wrptr(sc, 0, MICBA, 0); 948 emu_wrptr(sc, 0, FXBS, 0); 949 emu_wrptr(sc, 0, FXBA, 0); 950 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE); 951 emu_wrptr(sc, 0, ADCBA, 0); 952 953 /* disable channel interrupt */ 954 emu_wr(sc, INTE, DISABLE, 4); 955 emu_wrptr(sc, 0, CLIEL, 0); 956 emu_wrptr(sc, 0, CLIEH, 0); 957 emu_wrptr(sc, 0, SOLEL, 0); 958 emu_wrptr(sc, 0, SOLEH, 0); 959 960 /* init envelope engine */ 961 for (ch = 0; ch < NUM_G; ch++) { 962 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF); 963 emu_wrptr(sc, ch, IP, 0); 964 emu_wrptr(sc, ch, VTFT, 0xffff); 965 emu_wrptr(sc, ch, CVCF, 0xffff); 966 emu_wrptr(sc, ch, PTRX, 0); 967 emu_wrptr(sc, ch, CPF, 0); 968 emu_wrptr(sc, ch, CCR, 0); 969 970 emu_wrptr(sc, ch, PSST, 0); 971 emu_wrptr(sc, ch, DSL, 0x10); 972 emu_wrptr(sc, ch, CCCA, 0); 973 emu_wrptr(sc, ch, Z1, 0); 974 emu_wrptr(sc, ch, Z2, 0); 975 emu_wrptr(sc, ch, FXRT, 0xd01c0000); 976 977 emu_wrptr(sc, ch, ATKHLDM, 0); 978 emu_wrptr(sc, ch, DCYSUSM, 0); 979 emu_wrptr(sc, ch, IFATN, 0xffff); 980 emu_wrptr(sc, ch, PEFE, 0); 981 emu_wrptr(sc, ch, FMMOD, 0); 982 emu_wrptr(sc, ch, TREMFRQ, 24); /* 1 Hz */ 983 emu_wrptr(sc, ch, FM2FRQ2, 24); /* 1 Hz */ 984 emu_wrptr(sc, ch, TEMPENV, 0); 985 986 /*** these are last so OFF prevents writing ***/ 987 emu_wrptr(sc, ch, LFOVAL2, 0); 988 emu_wrptr(sc, ch, LFOVAL1, 0); 989 emu_wrptr(sc, ch, ATKHLDV, 0); 990 emu_wrptr(sc, ch, ENVVOL, 0); 991 emu_wrptr(sc, ch, ENVVAL, 0); 992 993 sc->voice[ch].vnum = ch; 994 sc->voice[ch].slave = NULL; 995 sc->voice[ch].busy = 0; 996 sc->voice[ch].running = 0; 997 sc->voice[ch].b16 = 0; 998 sc->voice[ch].stereo = 0; 999 sc->voice[ch].speed = 0; 1000 sc->voice[ch].start = 0; 1001 sc->voice[ch].end = 0; 1002 sc->voice[ch].channel = NULL; 1003 } 1004 1005 /* 1006 * Init to 0x02109204 : 1007 * Clock accuracy = 0 (1000ppm) 1008 * Sample Rate = 2 (48kHz) 1009 * Audio Channel = 1 (Left of 2) 1010 * Source Number = 0 (Unspecified) 1011 * Generation Status = 1 (Original for Cat Code 12) 1012 * Cat Code = 12 (Digital Signal Mixer) 1013 * Mode = 0 (Mode 0) 1014 * Emphasis = 0 (None) 1015 * CP = 1 (Copyright unasserted) 1016 * AN = 0 (Audio data) 1017 * P = 0 (Consumer) 1018 */ 1019 spcs = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1020 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1021 SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 | 1022 SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT; 1023 emu_wrptr(sc, 0, SPCS0, spcs); 1024 emu_wrptr(sc, 0, SPCS1, spcs); 1025 emu_wrptr(sc, 0, SPCS2, spcs); 1026 1027 emu_initefx(sc); 1028 1029 SLIST_INIT(&sc->mem.blocks); 1030 sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t)); 1031 if (sc->mem.ptb_pages == NULL) 1032 return -1; 1033 1034 sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE); 1035 if (sc->mem.silent_page == NULL) { 1036 emu_free(sc, sc->mem.ptb_pages); 1037 return -1; 1038 } 1039 /* Clear page with silence & setup all pointers to this page */ 1040 bzero(sc->mem.silent_page, EMUPAGESIZE); 1041 tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1; 1042 for (i = 0; i < MAXPAGES; i++) 1043 sc->mem.ptb_pages[i] = tmp | i; 1044 1045 emu_wrptr(sc, 0, PTB, vtophys(sc->mem.ptb_pages)); 1046 emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */ 1047 emu_wrptr(sc, 0, TCBS, 4); /* taken from original driver */ 1048 1049 for (ch = 0; ch < NUM_G; ch++) { 1050 emu_wrptr(sc, ch, MAPA, tmp | MAP_PTI_MASK); 1051 emu_wrptr(sc, ch, MAPB, tmp | MAP_PTI_MASK); 1052 } 1053 1054 /* emu_memalloc(sc, EMUPAGESIZE); */ 1055 /* 1056 * Hokay, now enable the AUD bit 1057 * Enable Audio = 1 1058 * Mute Disable Audio = 0 1059 * Lock Tank Memory = 1 1060 * Lock Sound Memory = 0 1061 * Auto Mute = 1 1062 */ 1063 tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE; 1064 if (sc->rev >= 6) 1065 tmp |= HCFG_JOYENABLE; 1066 emu_wr(sc, HCFG, tmp, 4); 1067 1068 /* TOSLink detection */ 1069 sc->tos_link = 0; 1070 tmp = emu_rd(sc, HCFG, 4); 1071 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) { 1072 emu_wr(sc, HCFG, tmp | 0x800, 4); 1073 DELAY(50); 1074 if (tmp != (emu_rd(sc, HCFG, 4) & ~0x800)) { 1075 sc->tos_link = 1; 1076 emu_wr(sc, HCFG, tmp, 4); 1077 } 1078 } 1079 1080 return 0; 1081 } 1082 1083 static int 1084 emu_pci_probe(device_t dev) 1085 { 1086 char *s = NULL; 1087 1088 switch (pci_get_devid(dev)) { 1089 case EMU10K1_PCI_ID: 1090 s = "Creative EMU10K1"; 1091 break; 1092 } 1093 1094 if (s) device_set_desc(dev, s); 1095 return s? 0 : ENXIO; 1096 } 1097 1098 static int 1099 emu_pci_attach(device_t dev) 1100 { 1101 snddev_info *d; 1102 u_int32_t data; 1103 struct sc_info *sc; 1104 struct ac97_info *codec; 1105 int i, mapped; 1106 char status[SND_STATUSLEN]; 1107 1108 d = device_get_softc(dev); 1109 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 1110 device_printf(dev, "cannot allocate softc\n"); 1111 return ENXIO; 1112 } 1113 1114 bzero(sc, sizeof(*sc)); 1115 sc->type = pci_get_devid(dev); 1116 sc->rev = pci_get_revid(dev); 1117 1118 data = pci_read_config(dev, PCIR_COMMAND, 2); 1119 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 1120 pci_write_config(dev, PCIR_COMMAND, data, 2); 1121 data = pci_read_config(dev, PCIR_COMMAND, 2); 1122 1123 mapped = 0; 1124 /* Xemu dfr: is this strictly necessary? */ 1125 for (i = 0; (mapped == 0) && (i < PCI_MAXMAPS_0); i++) { 1126 sc->regid = PCIR_MAPS + i*4; 1127 sc->regtype = SYS_RES_MEMORY; 1128 sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid, 1129 0, ~0, 1, RF_ACTIVE); 1130 if (!sc->reg) { 1131 sc->regtype = SYS_RES_IOPORT; 1132 sc->reg = bus_alloc_resource(dev, sc->regtype, 1133 &sc->regid, 0, ~0, 1, 1134 RF_ACTIVE); 1135 } 1136 if (sc->reg) { 1137 sc->st = rman_get_bustag(sc->reg); 1138 sc->sh = rman_get_bushandle(sc->reg); 1139 mapped++; 1140 } 1141 } 1142 1143 if (mapped == 0) { 1144 device_printf(dev, "unable to map register space\n"); 1145 goto bad; 1146 } 1147 1148 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 1149 /*lowaddr*/1 << 31, /* can only access 0-2gb */ 1150 /*highaddr*/BUS_SPACE_MAXADDR, 1151 /*filter*/NULL, /*filterarg*/NULL, 1152 /*maxsize*/262144, /*nsegments*/1, /*maxsegz*/0x3ffff, 1153 /*flags*/0, &sc->parent_dmat) != 0) { 1154 device_printf(dev, "unable to create dma tag\n"); 1155 goto bad; 1156 } 1157 1158 if (emu_init(sc) == -1) { 1159 device_printf(dev, "unable to initialize the card\n"); 1160 goto bad; 1161 } 1162 1163 codec = ac97_create(dev, sc, NULL, emu_rdcd, emu_wrcd); 1164 if (codec == NULL) goto bad; 1165 if (mixer_init(d, &ac97_mixer, codec) == -1) goto bad; 1166 1167 sc->irqid = 0; 1168 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 1169 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 1170 if (!sc->irq || 1171 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, emu_intr, sc, &sc->ih)) { 1172 device_printf(dev, "unable to map interrupt\n"); 1173 goto bad; 1174 } 1175 1176 snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld", 1177 (sc->regtype == SYS_RES_IOPORT)? "io" : "memory", 1178 rman_get_start(sc->reg), rman_get_start(sc->irq)); 1179 1180 if (pcm_register(dev, sc, 1, 0)) goto bad; 1181 pcm_addchan(dev, PCMDIR_PLAY, &emu_chantemplate, sc); 1182 /* pcm_addchan(dev, PCMDIR_REC, &emu_chantemplate, sc); */ 1183 1184 pcm_setstatus(dev, status); 1185 1186 return 0; 1187 1188 bad: 1189 if (sc->reg) bus_release_resource(dev, sc->regtype, sc->regid, sc->reg); 1190 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 1191 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 1192 free(sc, M_DEVBUF); 1193 return ENXIO; 1194 } 1195 1196 static device_method_t emu_methods[] = { 1197 /* Device interface */ 1198 DEVMETHOD(device_probe, emu_pci_probe), 1199 DEVMETHOD(device_attach, emu_pci_attach), 1200 1201 { 0, 0 } 1202 }; 1203 1204 static driver_t emu_driver = { 1205 "pcm", 1206 emu_methods, 1207 sizeof(snddev_info), 1208 }; 1209 1210 static devclass_t pcm_devclass; 1211 1212 DRIVER_MODULE(emu, pci, emu_driver, pcm_devclass, 0, 0); 1213