1 /* $OpenBSD: envy.c,v 1.56 2013/05/24 07:58:46 ratchov Exp $ */ 2 /* 3 * Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * TODO: 20 * 21 * - add nspdin, nspdout, to struct envy_card 22 * 23 * - use eeprom version rather isht flag 24 * 25 * - implement HT mixer, midi uart, spdif, init ADC/DACs for >48kHz modes 26 * 27 */ 28 29 #include "midi.h" 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/device.h> 33 #include <sys/ioctl.h> 34 #include <sys/audioio.h> 35 #include <sys/malloc.h> 36 #include <sys/kernel.h> 37 #include <dev/audio_if.h> 38 #include <dev/midi_if.h> 39 #include <dev/ic/ac97.h> 40 #include <dev/pci/pcivar.h> 41 #include <dev/pci/pcidevs.h> 42 #include <dev/pci/envyvar.h> 43 #include <dev/pci/envyreg.h> 44 #include <machine/bus.h> 45 #include <uvm/uvm.h> 46 47 #ifdef ENVY_DEBUG 48 #define DPRINTF(...) do { if (envydebug) printf(__VA_ARGS__); } while(0) 49 #define DPRINTFN(n, ...) do { if (envydebug > (n)) printf(__VA_ARGS__); } while(0) 50 int envydebug = 1; 51 #else 52 #define DPRINTF(...) do {} while(0) 53 #define DPRINTFN(n, ...) do {} while(0) 54 #endif 55 #define DEVNAME(sc) ((sc)->dev.dv_xname) 56 57 int envymatch(struct device *, void *, void *); 58 void envyattach(struct device *, struct device *, void *); 59 int envydetach(struct device *, int); 60 61 int envy_ccs_read(struct envy_softc *, int); 62 void envy_ccs_write(struct envy_softc *, int, int); 63 int envy_mt_read_1(struct envy_softc *, int); 64 void envy_mt_write_1(struct envy_softc *, int, int); 65 int envy_mt_read_2(struct envy_softc *, int); 66 void envy_mt_write_2(struct envy_softc *, int, int); 67 int envy_mt_read_4(struct envy_softc *, int); 68 void envy_mt_write_4(struct envy_softc *, int, int); 69 int envy_cci_read(struct envy_softc *, int); 70 void envy_cci_write(struct envy_softc *, int, int); 71 void envy_i2c_wait(struct envy_softc *); 72 int envy_i2c_read(struct envy_softc *, int, int); 73 void envy_i2c_write(struct envy_softc *, int, int, int); 74 int envy_gpio_getstate(struct envy_softc *); 75 void envy_gpio_setstate(struct envy_softc *, int); 76 int envy_gpio_getmask(struct envy_softc *); 77 void envy_gpio_setmask(struct envy_softc *, int); 78 int envy_gpio_getdir(struct envy_softc *); 79 void envy_gpio_setdir(struct envy_softc *, int); 80 void envy_gpio_i2c_start_bit(struct envy_softc *, int, int); 81 void envy_gpio_i2c_stop_bit(struct envy_softc *, int, int); 82 void envy_gpio_i2c_byte_out(struct envy_softc *, int, int, int); 83 int envy_eeprom_gpioxxx(struct envy_softc *, int); 84 void envy_midi_wait(struct envy_softc *); 85 void envy_reset(struct envy_softc *); 86 int envy_codec_read(struct envy_softc *, int, int); 87 void envy_codec_write(struct envy_softc *, int, int, int); 88 void envy_pintr(struct envy_softc *); 89 int envy_intr(void *); 90 91 int envy_lineout_getsrc(struct envy_softc *, int); 92 void envy_lineout_setsrc(struct envy_softc *, int, int); 93 int envy_spdout_getsrc(struct envy_softc *, int); 94 void envy_spdout_setsrc(struct envy_softc *, int, int); 95 void envy_mon_getvol(struct envy_softc *, int, int, int *); 96 void envy_mon_setvol(struct envy_softc *, int, int, int); 97 98 int envy_open(void *, int); 99 void envy_close(void *); 100 void *envy_allocm(void *, int, size_t, int, int); 101 void envy_freem(void *, void *, int); 102 int envy_query_encoding(void *, struct audio_encoding *); 103 int envy_set_params(void *, int, int, struct audio_params *, 104 struct audio_params *); 105 int envy_round_blocksize(void *, int); 106 size_t envy_round_buffersize(void *, int, size_t); 107 int envy_trigger_output(void *, void *, void *, int, 108 void (*)(void *), void *, struct audio_params *); 109 int envy_trigger_input(void *, void *, void *, int, 110 void (*)(void *), void *, struct audio_params *); 111 int envy_halt_output(void *); 112 int envy_halt_input(void *); 113 int envy_getdev(void *, struct audio_device *); 114 int envy_query_devinfo(void *, struct mixer_devinfo *); 115 int envy_get_port(void *, struct mixer_ctrl *); 116 int envy_set_port(void *, struct mixer_ctrl *); 117 int envy_get_props(void *); 118 #if NMIDI > 0 119 int envy_midi_open(void *, int, void (*)(void *, int), 120 void (*)(void *), void *); 121 void envy_midi_close(void *); 122 int envy_midi_output(void *, int); 123 void envy_midi_getinfo(void *, struct midi_info *); 124 #endif 125 126 int envy_ac97_wait(struct envy_softc *); 127 int envy_ac97_attach_codec(void *, struct ac97_codec_if *); 128 int envy_ac97_read_codec(void *, u_int8_t, u_int16_t *); 129 int envy_ac97_write_codec(void *, u_int8_t, u_int16_t); 130 void envy_ac97_reset_codec(void *); 131 enum ac97_host_flags envy_ac97_flags_codec(void *); 132 133 void delta_init(struct envy_softc *); 134 void delta_codec_write(struct envy_softc *, int, int, int); 135 136 void ap192k_init(struct envy_softc *); 137 void ap192k_codec_write(struct envy_softc *, int, int, int); 138 139 void ewx_codec_write(struct envy_softc *, int, int, int); 140 141 void revo51_init(struct envy_softc *); 142 void revo51_codec_write(struct envy_softc *, int, int, int); 143 144 void envy_ac97_init(struct envy_softc *); 145 void dynex_sc51_init(struct envy_softc *); 146 147 void julia_init(struct envy_softc *); 148 void julia_codec_write(struct envy_softc *, int, int, int); 149 150 void unkenvy_init(struct envy_softc *); 151 void unkenvy_codec_write(struct envy_softc *, int, int, int); 152 int unkenvy_codec_ndev(struct envy_softc *); 153 154 int ak4524_dac_ndev(struct envy_softc *); 155 void ak4524_dac_devinfo(struct envy_softc *, struct mixer_devinfo *, int); 156 void ak4524_dac_get(struct envy_softc *, struct mixer_ctrl *, int); 157 int ak4524_dac_set(struct envy_softc *, struct mixer_ctrl *, int); 158 int ak4524_adc_ndev(struct envy_softc *); 159 void ak4524_adc_devinfo(struct envy_softc *, struct mixer_devinfo *, int); 160 void ak4524_adc_get(struct envy_softc *, struct mixer_ctrl *, int); 161 int ak4524_adc_set(struct envy_softc *, struct mixer_ctrl *, int); 162 163 int ak4358_dac_ndev(struct envy_softc *); 164 void ak4358_dac_devinfo(struct envy_softc *, struct mixer_devinfo *, int); 165 void ak4358_dac_get(struct envy_softc *, struct mixer_ctrl *, int); 166 int ak4358_dac_set(struct envy_softc *, struct mixer_ctrl *, int); 167 168 int ak5365_adc_ndev(struct envy_softc *); 169 void ak5365_adc_devinfo(struct envy_softc *, struct mixer_devinfo *, int); 170 void ak5365_adc_get(struct envy_softc *, struct mixer_ctrl *, int); 171 int ak5365_adc_set(struct envy_softc *, struct mixer_ctrl *, int); 172 173 struct cfattach envy_ca = { 174 sizeof(struct envy_softc), envymatch, envyattach, envydetach 175 }; 176 177 struct cfdriver envy_cd = { 178 NULL, "envy", DV_DULL 179 }; 180 181 struct audio_hw_if envy_hw_if = { 182 envy_open, /* open */ 183 envy_close, /* close */ 184 NULL, /* drain */ 185 envy_query_encoding, /* query_encoding */ 186 envy_set_params, /* set_params */ 187 envy_round_blocksize, /* round_blocksize */ 188 NULL, /* commit_settings */ 189 NULL, /* init_output */ 190 NULL, /* init_input */ 191 NULL, /* start_output */ 192 NULL, /* start_input */ 193 envy_halt_output, /* halt_output */ 194 envy_halt_input, /* halt_input */ 195 NULL, /* speaker_ctl */ 196 envy_getdev, /* getdev */ 197 NULL, /* setfd */ 198 envy_set_port, /* set_port */ 199 envy_get_port, /* get_port */ 200 envy_query_devinfo, /* query_devinfo */ 201 envy_allocm, /* malloc */ 202 envy_freem, /* free */ 203 envy_round_buffersize, /* round_buffersize */ 204 NULL, /* mappage */ 205 envy_get_props, /* get_props */ 206 envy_trigger_output, /* trigger_output */ 207 envy_trigger_input, /* trigger_input */ 208 NULL 209 }; 210 211 #if NMIDI > 0 212 struct midi_hw_if envy_midi_hw_if = { 213 envy_midi_open, 214 envy_midi_close, 215 envy_midi_output, 216 NULL, /* flush */ 217 envy_midi_getinfo, 218 NULL /* ioctl */ 219 }; 220 #endif 221 222 struct pci_matchid envy_matchids[] = { 223 { PCI_VENDOR_ICENSEMBLE, PCI_PRODUCT_ICENSEMBLE_ICE1712 }, 224 { PCI_VENDOR_ICENSEMBLE, PCI_PRODUCT_ICENSEMBLE_VT172x } 225 }; 226 227 /* 228 * correspondence between rates (in frames per second) 229 * and values of rate register 230 */ 231 struct { 232 int rate, reg; 233 } envy_rates[] = { 234 { 8000, 0x6}, { 9600, 0x3}, {11025, 0xa}, {12000, 2}, {16000, 5}, 235 {22050, 0x9}, {24000, 0x1}, {32000, 0x4}, {44100, 8}, {48000, 0}, 236 {64000, 0xf}, {88200, 0xb}, {96000, 0x7}, {-1, -1} 237 }; 238 239 /* 240 * ESI Julia cards don't have EEPROM, use this copy 241 */ 242 static unsigned char julia_eeprom[ENVY_EEPROM_MAXSZ] = { 243 /* gpio mask/dir/state is from linux */ 244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 0x20, 0x80, 0xf8, 0xc3, 246 0x9f, 0xff, 0x7f, 247 0x90, 0xff, 0x7f, 248 0x66, 0x00, 0x00 249 }; 250 251 struct envy_codec ak4524_dac = { 252 "ak4524 dac", ak4524_dac_ndev, ak4524_dac_devinfo, ak4524_dac_get, ak4524_dac_set 253 }, ak4524_adc = { 254 "ak4524 adc", ak4524_adc_ndev, ak4524_adc_devinfo, ak4524_adc_get, ak4524_adc_set 255 }, ak4358_dac = { 256 "ak4358 dac", ak4358_dac_ndev, ak4358_dac_devinfo, ak4358_dac_get, ak4358_dac_set 257 }, ak5365_adc = { 258 "ak5365 adc", ak5365_adc_ndev, ak5365_adc_devinfo, ak5365_adc_get, ak5365_adc_set 259 }, unkenvy_codec = { 260 "unknown codec", unkenvy_codec_ndev, NULL, NULL, NULL 261 }; 262 263 /* 264 * array with vendor/product sub-IDs to card info 265 */ 266 struct envy_card envy_cards[] = { 267 { 268 PCI_ID_CODE(0x1412, 0xd630), 269 "M-Audio Delta 1010", 270 8, &ak4524_adc, 8, &ak4524_dac, 271 delta_init, 272 delta_codec_write, 273 NULL 274 }, { 275 PCI_ID_CODE(0x1412, 0xd632), 276 "M-Audio Delta 66", 277 4, &ak4524_adc, 4, &ak4524_dac, 278 delta_init, 279 delta_codec_write, 280 NULL 281 }, { 282 PCI_ID_CODE(0x1412, 0xd633), 283 "M-Audio Delta 44", 284 4, &ak4524_adc, 4, &ak4524_dac, 285 delta_init, 286 delta_codec_write, 287 NULL 288 }, { 289 PCI_ID_CODE(0x1412, 0xd63b), 290 "M-Audio Delta 1010LT", 291 8, &ak4524_adc, 8, &ak4524_dac, 292 delta_init, 293 delta_codec_write, 294 NULL 295 }, { 296 PCI_ID_CODE(0x1412, 0xd634), 297 "M-Audio Audiophile 2496", 298 2, &ak4524_adc, 2, &ak4524_dac, 299 delta_init, 300 delta_codec_write, 301 NULL 302 }, { 303 PCI_ID_CODE(0x153b, 0x1130), 304 "Terratec EWX 24/96", 305 2, &ak4524_adc, 2, &ak4524_dac, 306 delta_init, 307 ewx_codec_write, 308 NULL 309 }, { 310 0, 311 "unknown 1712-based card", 312 8, &unkenvy_codec, 8, &unkenvy_codec, 313 unkenvy_init, 314 unkenvy_codec_write 315 } 316 }, envy_cards_ht[] = { 317 { 318 PCI_ID_CODE(0x3031, 0x4553), 319 "ESI Julia", 320 2, &unkenvy_codec, 2, &ak4358_dac, 321 julia_init, 322 julia_codec_write, 323 julia_eeprom 324 }, { 325 PCI_ID_CODE(0x1412, 0x3632), 326 "M-Audio Audiophile 192k", 327 2, &unkenvy_codec, 2, &ak4358_dac, 328 ap192k_init, 329 ap192k_codec_write 330 }, { 331 PCI_ID_CODE(0x1412, 0x3631), 332 "M-Audio Revolution 5.1", 333 2, &ak5365_adc, 6, &ak4358_dac, 334 revo51_init, 335 revo51_codec_write 336 }, { 337 PCI_ID_CODE(0x1412, 0x2403), 338 "VIA Tremor 5.1", 339 2, &unkenvy_codec, 6, &unkenvy_codec, 340 envy_ac97_init, 341 unkenvy_codec_write 342 }, { 343 PCI_ID_CODE(0x14c3, 0x1705), 344 "Dynex DX-SC51", 345 2, &unkenvy_codec, 6, &unkenvy_codec, 346 dynex_sc51_init, 347 unkenvy_codec_write 348 }, { 349 0, 350 "unknown 1724-based card", 351 2, &unkenvy_codec, 8, &unkenvy_codec, 352 unkenvy_init, 353 unkenvy_codec_write 354 } 355 }; 356 357 358 /* 359 * M-Audio Delta specific code 360 */ 361 362 /* 363 * GPIO pin numbers 364 */ 365 #define DELTA_GPIO_CLK 0x2 366 #define DELTA_GPIO_DOUT 0x8 367 #define DELTA_GPIO_CSMASK 0x70 368 #define DELTA_GPIO_CS(dev) ((dev) << 4) 369 370 void 371 delta_init(struct envy_softc *sc) 372 { 373 int dev; 374 375 for (dev = 0; dev < sc->card->noch / 2; dev++) { 376 envy_codec_write(sc, dev, AK4524_RST, 0x0); 377 delay(300); 378 envy_codec_write(sc, dev, AK4524_RST, 379 AK4524_RST_AD | AK4524_RST_DA); 380 envy_codec_write(sc, dev, AK4524_FMT, 381 AK4524_FMT_IIS24); 382 sc->shadow[dev][AK4524_DEEMVOL] = AK4524_DEEM_OFF; 383 sc->shadow[dev][AK4524_ADC_GAIN0] = 0x7f; 384 sc->shadow[dev][AK4524_ADC_GAIN1] = 0x7f; 385 sc->shadow[dev][AK4524_DAC_GAIN0] = 0x7f; 386 sc->shadow[dev][AK4524_DAC_GAIN1] = 0x7f; 387 } 388 } 389 390 void 391 delta_codec_write(struct envy_softc *sc, int dev, int addr, int data) 392 { 393 int bits, i, reg; 394 395 reg = envy_gpio_getstate(sc); 396 reg &= ~DELTA_GPIO_CSMASK; 397 reg |= DELTA_GPIO_CS(dev); 398 envy_gpio_setstate(sc, reg); 399 delay(1); 400 401 bits = 0xa000 | (addr << 8) | data; 402 for (i = 0; i < 16; i++) { 403 reg &= ~(DELTA_GPIO_CLK | DELTA_GPIO_DOUT); 404 reg |= (bits & 0x8000) ? DELTA_GPIO_DOUT : 0; 405 envy_gpio_setstate(sc, reg); 406 delay(1); 407 408 reg |= DELTA_GPIO_CLK; 409 envy_gpio_setstate(sc, reg); 410 delay(1); 411 bits <<= 1; 412 } 413 414 reg |= DELTA_GPIO_CSMASK; 415 envy_gpio_setstate(sc, reg); 416 delay(1); 417 } 418 419 /* 420 * M-Audio Audiophile 192 specific code 421 */ 422 423 /* 424 * GPIO pin numbers 425 */ 426 #define AP192K_GPIO_CLK 0x2 427 #define AP192K_GPIO_DOUT 0x8 428 #define AP192K_GPIO_CSMASK 0x30 429 #define AP192K_GPIO_CS(dev) ((dev) << 4) 430 #define AP192K_GPIO_ADC_PWR 0x800 431 #define AP192K_GPIO_ADC_DFSMASK (3 << 9) 432 #define AP192K_GPIO_ADC_DFS(v) ((v) << 9) 433 #define AP192K_GPIO_MUTE 0x400000 434 435 void 436 ap192k_init(struct envy_softc *sc) 437 { 438 int i, reg; 439 440 /* AK4358 */ 441 envy_codec_write(sc, 0, 0, 0); /* reset */ 442 delay(300); 443 envy_codec_write(sc, 0, 0, 0x87); /* i2s mode */ 444 delay(1); 445 for (i = 0; i < sc->card->noch; i++) { 446 sc->shadow[0][AK4358_ATT(i)] = 0xff; 447 } 448 449 /* AK5385 */ 450 delay(1); 451 reg = envy_gpio_getstate(sc); 452 reg &= ~(AP192K_GPIO_ADC_PWR | AP192K_GPIO_ADC_DFSMASK); 453 reg |= AP192K_GPIO_ADC_DFS(0); 454 envy_gpio_setstate(sc, reg); 455 reg |= AP192K_GPIO_ADC_PWR; 456 envy_gpio_setstate(sc, reg); 457 } 458 459 void 460 ap192k_codec_write(struct envy_softc *sc, int dev, int addr, int data) 461 { 462 int bits, i, reg; 463 464 reg = envy_gpio_getstate(sc); 465 reg &= ~AP192K_GPIO_CSMASK; 466 reg |= AP192K_GPIO_CS(dev); 467 envy_gpio_setstate(sc, reg); 468 delay(1); 469 470 bits = 0xa000 | (addr << 8) | data; 471 for (i = 0; i < 16; i++) { 472 reg &= ~(AP192K_GPIO_CLK | AP192K_GPIO_DOUT); 473 reg |= (bits & 0x8000) ? AP192K_GPIO_DOUT : 0; 474 envy_gpio_setstate(sc, reg); 475 delay(1); 476 477 reg |= AP192K_GPIO_CLK; 478 envy_gpio_setstate(sc, reg); 479 delay(1); 480 bits <<= 1; 481 } 482 483 reg |= AP192K_GPIO_CSMASK; 484 envy_gpio_setstate(sc, reg); 485 delay(1); 486 } 487 488 /* 489 * Terratec EWX specific code 490 */ 491 492 /* 493 * GPIO pin numbers 494 */ 495 #define EWX_GPIO_CSMASK 0x01 496 #define EWX_GPIO_DOUT 0x10 497 #define EWX_GPIO_CLK 0x20 498 499 void 500 ewx_codec_write(struct envy_softc *sc, int dev, int addr, int data) 501 { 502 int bits, i, reg; 503 504 reg = envy_gpio_getstate(sc); 505 reg |= (EWX_GPIO_CSMASK | EWX_GPIO_CLK); 506 envy_gpio_setstate(sc, reg); 507 delay(1); 508 509 bits = 0xa000 | (addr << 8) | data; 510 for (i = 0; i < 16; i++) { 511 reg &= ~(EWX_GPIO_CLK | EWX_GPIO_DOUT); 512 reg |= (bits & 0x8000) ? EWX_GPIO_DOUT : 0; 513 envy_gpio_setstate(sc, reg); 514 delay(1); 515 516 reg |= EWX_GPIO_CLK; 517 envy_gpio_setstate(sc, reg); 518 delay(1); 519 bits <<= 1; 520 } 521 522 reg &= ~EWX_GPIO_CSMASK; 523 envy_gpio_setstate(sc, reg); 524 delay(1); 525 526 reg |= EWX_GPIO_CSMASK; 527 envy_gpio_setstate(sc, reg); 528 delay(1); 529 } 530 531 532 /* 533 * M-Audio Revolution 5.1 specific code 534 */ 535 536 #define REVO51_GPIO_CLK 0x2 537 #define REVO51_GPIO_DOUT 0x8 538 #define REVO51_GPIO_CSMASK 0x30 539 #define REVO51_GPIO_CS(dev) ((dev) ? 0x10 : 0x20) 540 #define REVO51_MUTE 0x400000 541 #define REVO51_PT2258S_SDA 0x40 542 #define REVO51_PT2258S_SCL 0x80 543 #define REVO51_PT2258S_ADDR 0x80 544 #define REVO51_PT2258S_MUTE 6 545 546 void 547 revo51_init(struct envy_softc *sc) 548 { 549 int i, reg; 550 551 /* AK4358 */ 552 envy_codec_write(sc, 0, 0, 0); /* reset */ 553 delay(300); 554 envy_codec_write(sc, 0, 0, 0x87); /* i2s mode */ 555 for (i = 0; i < sc->card->noch; i++) { 556 sc->shadow[0][AK4358_ATT(i)] = 0xff; 557 } 558 559 /* AK5365 */ 560 envy_codec_write(sc, 1, AK5365_RST, 0); /* reset */ 561 delay(300); 562 envy_codec_write(sc, 1, AK5365_CTRL, AK5365_CTRL_I2S); /* i2s mode */ 563 envy_codec_write(sc, 1, AK5365_RST , AK5365_RST_NORM); 564 sc->shadow[1][AK5365_ATT(0)] = 0x7f; 565 sc->shadow[1][AK5365_ATT(1)] = 0x7f; 566 567 /* PT2258S */ 568 envy_codec_write(sc, 2, REVO51_PT2258S_MUTE, 0xc0); /* reset */ 569 envy_codec_write(sc, 2, REVO51_PT2258S_MUTE, 0xf9); /* mute */ 570 571 reg = envy_gpio_getstate(sc); 572 reg |= REVO51_MUTE; 573 envy_gpio_setstate(sc, reg); 574 } 575 576 void 577 revo51_codec_write(struct envy_softc *sc, int dev, int addr, int data) 578 { 579 int attn, bits, mask, reg; 580 int xlat[6] = {0x90, 0x50, 0x10, 0x30, 0x70, 0xb0}; 581 582 /* AK4358 & AK5365 */ 583 if (dev < 2) { 584 reg = envy_gpio_getstate(sc); 585 reg &= ~REVO51_GPIO_CSMASK; 586 reg |= REVO51_GPIO_CS(dev); 587 envy_gpio_setstate(sc, reg); 588 delay(1); 589 590 bits = 0xa000 | (addr << 8) | data; 591 for (mask = 0x8000; mask != 0; mask >>= 1) { 592 reg &= ~(REVO51_GPIO_CLK | REVO51_GPIO_DOUT); 593 reg |= (bits & mask) ? REVO51_GPIO_DOUT : 0; 594 envy_gpio_setstate(sc, reg); 595 delay(1); 596 597 reg |= REVO51_GPIO_CLK; 598 envy_gpio_setstate(sc, reg); 599 delay(1); 600 } 601 602 reg |= REVO51_GPIO_CSMASK; 603 envy_gpio_setstate(sc, reg); 604 delay(1); 605 return; 606 } 607 608 /* PT2258S */ 609 envy_gpio_i2c_start_bit(sc, REVO51_PT2258S_SDA, REVO51_PT2258S_SCL); 610 envy_gpio_i2c_byte_out(sc, REVO51_PT2258S_SDA, REVO51_PT2258S_SCL, 611 REVO51_PT2258S_ADDR); 612 613 if (addr == REVO51_PT2258S_MUTE) { 614 envy_gpio_i2c_byte_out(sc, REVO51_PT2258S_SDA, 615 REVO51_PT2258S_SCL, data); 616 } else { 617 /* 1's digit */ 618 attn = data % 10; 619 attn += xlat[addr]; 620 envy_gpio_i2c_byte_out(sc, REVO51_PT2258S_SDA, 621 REVO51_PT2258S_SCL, attn); 622 623 /* 10's digit */ 624 attn = data / 10; 625 attn += xlat[addr] - 0x10; 626 envy_gpio_i2c_byte_out(sc, REVO51_PT2258S_SDA, 627 REVO51_PT2258S_SCL, attn); 628 } 629 630 envy_gpio_i2c_stop_bit(sc, REVO51_PT2258S_SDA, REVO51_PT2258S_SCL); 631 } 632 633 /* 634 * Generic AC'97 initialization 635 */ 636 637 void 638 envy_ac97_init(struct envy_softc *sc) 639 { 640 sc->isac97 = 1; 641 sc->host_if.arg = sc; 642 sc->host_if.attach = envy_ac97_attach_codec; 643 sc->host_if.read = envy_ac97_read_codec; 644 sc->host_if.write = envy_ac97_write_codec; 645 sc->host_if.reset = envy_ac97_reset_codec; 646 sc->host_if.flags = envy_ac97_flags_codec; 647 648 if (ac97_attach(&sc->host_if) != 0) 649 printf("%s: can't attach ac97\n", DEVNAME(sc)); 650 } 651 652 /* 653 * Dynex 654 */ 655 656 void 657 dynex_sc51_init(struct envy_softc *sc) 658 { 659 sc->codec_flags |= AC97_HOST_VT1616_DYNEX; 660 envy_ac97_init(sc); 661 } 662 663 /* 664 * ESI Julia specific code 665 */ 666 667 void 668 julia_init(struct envy_softc *sc) 669 { 670 int i; 671 672 envy_codec_write(sc, 0, 0, 0); /* reset */ 673 delay(300); 674 envy_codec_write(sc, 0, 0, 0x87); /* i2s mode */ 675 for (i = 0; i < sc->card->noch; i++) { 676 sc->shadow[0][AK4358_ATT(i)] = 0xff; 677 } 678 } 679 680 void 681 julia_codec_write(struct envy_softc *sc, int dev, int addr, int data) 682 { 683 #define JULIA_AK4358_ADDR 0x11 684 envy_i2c_write(sc, JULIA_AK4358_ADDR, addr, data); 685 } 686 687 /* 688 * unknown card, ignore codecs setup and hope it works with the power on 689 * settings 690 */ 691 692 void 693 unkenvy_init(struct envy_softc *sc) 694 { 695 } 696 697 void 698 unkenvy_codec_write(struct envy_softc *sc, int dev, int addr, int data) 699 { 700 } 701 702 int 703 unkenvy_codec_ndev(struct envy_softc *sc) 704 { 705 return 0; 706 } 707 708 /* 709 * AK 4358 DAC specific code 710 */ 711 int 712 ak4358_dac_ndev(struct envy_softc *sc) 713 { 714 /* 1 volume knob per channel */ 715 return sc->card->noch; 716 } 717 718 void 719 ak4358_dac_devinfo(struct envy_softc *sc, struct mixer_devinfo *dev, int idx) 720 { 721 dev->type = AUDIO_MIXER_VALUE; 722 dev->mixer_class = ENVY_MIX_CLASSOUT; 723 dev->un.v.delta = 2; 724 dev->un.v.num_channels = 1; 725 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 726 AudioNline "%d", idx); 727 strlcpy(dev->un.v.units.name, AudioNvolume, 728 MAX_AUDIO_DEV_LEN); 729 } 730 731 void 732 ak4358_dac_get(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 733 { 734 int val; 735 736 val = envy_codec_read(sc, 0, AK4358_ATT(idx)) & ~AK4358_ATT_EN; 737 ctl->un.value.num_channels = 1; 738 ctl->un.value.level[0] = 2 * val; 739 } 740 741 int 742 ak4358_dac_set(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 743 { 744 int val; 745 746 if (ctl->un.value.num_channels != 1) 747 return EINVAL; 748 val = ctl->un.value.level[0] / 2; 749 envy_codec_write(sc, 0, AK4358_ATT(idx), val | AK4358_ATT_EN); 750 return 0; 751 } 752 753 /* 754 * AK 4524 DAC specific code 755 */ 756 int 757 ak4524_dac_ndev(struct envy_softc *sc) 758 { 759 /* 1 mute + 2 volume knobs per channel pair */ 760 return 3 * (sc->card->noch / 2); 761 } 762 763 void 764 ak4524_dac_devinfo(struct envy_softc *sc, struct mixer_devinfo *dev, int idx) 765 { 766 int ndev; 767 768 ndev = sc->card->noch; 769 if (idx < ndev) { 770 dev->type = AUDIO_MIXER_VALUE; 771 dev->mixer_class = ENVY_MIX_CLASSOUT; 772 dev->un.v.delta = 2; 773 dev->un.v.num_channels = 1; 774 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 775 AudioNline "%d", idx); 776 strlcpy(dev->un.v.units.name, AudioNvolume, 777 MAX_AUDIO_DEV_LEN); 778 } else { 779 idx -= ndev; 780 dev->type = AUDIO_MIXER_ENUM; 781 dev->mixer_class = ENVY_MIX_CLASSOUT; 782 dev->un.e.member[0].ord = 0; 783 strlcpy(dev->un.e.member[0].label.name, AudioNoff, 784 MAX_AUDIO_DEV_LEN); 785 dev->un.e.member[1].ord = 1; 786 strlcpy(dev->un.e.member[1].label.name, AudioNon, 787 MAX_AUDIO_DEV_LEN); 788 dev->un.e.num_mem = 2; 789 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 790 AudioNmute "%d-%d", 2 * idx, 2 * idx + 1); 791 } 792 } 793 794 void 795 ak4524_dac_get(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 796 { 797 int val, ndev; 798 799 ndev = sc->card->noch; 800 if (idx < ndev) { 801 val = envy_codec_read(sc, idx / 2, 802 (idx % 2) + AK4524_DAC_GAIN0); 803 ctl->un.value.num_channels = 1; 804 ctl->un.value.level[0] = 2 * val; 805 } else { 806 idx -= ndev; 807 val = envy_codec_read(sc, idx, AK4524_DEEMVOL); 808 ctl->un.ord = (val & AK4524_MUTE) ? 1 : 0; 809 } 810 } 811 812 int 813 ak4524_dac_set(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 814 { 815 int val, ndev; 816 817 ndev = sc->card->noch; 818 if (idx < ndev) { 819 if (ctl->un.value.num_channels != 1) 820 return EINVAL; 821 val = ctl->un.value.level[0] / 2; 822 envy_codec_write(sc, idx / 2, 823 (idx % 2) + AK4524_DAC_GAIN0, val); 824 } else { 825 idx -= ndev; 826 if (ctl->un.ord >= 2) 827 return EINVAL; 828 val = AK4524_DEEM_OFF | (ctl->un.ord ? AK4524_MUTE : 0); 829 envy_codec_write(sc, idx, AK4524_DEEMVOL, val); 830 } 831 return 0; 832 } 833 834 /* 835 * AK 4524 ADC specific code 836 */ 837 int 838 ak4524_adc_ndev(struct envy_softc *sc) 839 { 840 /* one volume per channel */ 841 return sc->card->nich; 842 } 843 844 void 845 ak4524_adc_devinfo(struct envy_softc *sc, struct mixer_devinfo *dev, int idx) 846 { 847 dev->type = AUDIO_MIXER_VALUE; 848 dev->mixer_class = ENVY_MIX_CLASSIN; 849 dev->un.v.delta = 2; 850 dev->un.v.num_channels = 1; 851 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, AudioNline "%d", idx); 852 strlcpy(dev->un.v.units.name, AudioNvolume, MAX_AUDIO_DEV_LEN); 853 } 854 855 void 856 ak4524_adc_get(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 857 { 858 int val; 859 860 val = envy_codec_read(sc, idx / 2, (idx % 2) + AK4524_ADC_GAIN0); 861 ctl->un.value.num_channels = 1; 862 ctl->un.value.level[0] = 2 * val; 863 } 864 865 int 866 ak4524_adc_set(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 867 { 868 int val; 869 870 if (ctl->un.value.num_channels != 1) 871 return EINVAL; 872 val = ctl->un.value.level[0] / 2; 873 envy_codec_write(sc, idx / 2, (idx % 2) + AK4524_ADC_GAIN0, val); 874 return 0; 875 } 876 877 /* 878 * AK 5365 ADC specific code 879 */ 880 int 881 ak5365_adc_ndev(struct envy_softc *sc) 882 { 883 /* 1 source + 2 volume knobs per channel pair */ 884 return (sc->card->nich + 1); 885 } 886 887 void 888 ak5365_adc_devinfo(struct envy_softc *sc, struct mixer_devinfo *dev, int idx) 889 { 890 int ndev, i; 891 892 ndev = sc->card->nich; 893 if (idx < ndev) { 894 dev->type = AUDIO_MIXER_VALUE; 895 dev->mixer_class = ENVY_MIX_CLASSIN; 896 dev->un.v.delta = 2; 897 dev->un.v.num_channels = 1; 898 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 899 AudioNline "%d", idx); 900 strlcpy(dev->un.v.units.name, AudioNvolume, 901 MAX_AUDIO_DEV_LEN); 902 } else { 903 dev->type = AUDIO_MIXER_ENUM; 904 dev->mixer_class = ENVY_MIX_CLASSIN; 905 for (i = 0; i < 5; i++) { 906 dev->un.e.member[i].ord = i; 907 snprintf(dev->un.e.member[i].label.name, 908 MAX_AUDIO_DEV_LEN, AudioNline "%d", i); 909 } 910 dev->un.e.num_mem = 5; 911 strlcpy(dev->label.name, AudioNsource, 912 MAX_AUDIO_DEV_LEN); 913 } 914 } 915 916 void 917 ak5365_adc_get(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 918 { 919 int val, ndev; 920 921 ndev = sc->card->nich; 922 if (idx < ndev) { 923 val = envy_codec_read(sc, 1, AK5365_ATT(idx)); 924 ctl->un.value.num_channels = 1; 925 ctl->un.value.level[0] = 2 * val; 926 } else { 927 ctl->un.ord = envy_codec_read(sc, 1, AK5365_SRC); 928 } 929 } 930 931 int 932 ak5365_adc_set(struct envy_softc *sc, struct mixer_ctrl *ctl, int idx) 933 { 934 int val, ndev; 935 936 ndev = sc->card->nich; 937 if (idx < ndev) { 938 if (ctl->un.value.num_channels != 1) 939 return EINVAL; 940 val = ctl->un.value.level[0] / 2; 941 envy_codec_write(sc, 1, AK5365_ATT(idx), val); 942 } else { 943 if (ctl->un.ord >= 5) 944 return EINVAL; 945 val = ctl->un.ord & AK5365_SRC_MASK; 946 envy_codec_write(sc, 1, AK5365_SRC, val); 947 } 948 return 0; 949 } 950 951 /* 952 * generic Envy24 and Envy24HT code, common to all cards 953 */ 954 955 int 956 envy_ccs_read(struct envy_softc *sc, int reg) 957 { 958 int val; 959 960 val = bus_space_read_1(sc->ccs_iot, sc->ccs_ioh, reg); 961 bus_space_barrier(sc->ccs_iot, sc->ccs_ioh, 0, sc->ccs_iosz, 962 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 963 return val; 964 } 965 966 void 967 envy_ccs_write(struct envy_softc *sc, int reg, int val) 968 { 969 bus_space_write_1(sc->ccs_iot, sc->ccs_ioh, reg, val); 970 bus_space_barrier(sc->ccs_iot, sc->ccs_ioh, 0, sc->ccs_iosz, 971 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 972 } 973 974 int 975 envy_mt_read_1(struct envy_softc *sc, int reg) 976 { 977 int val; 978 979 val = bus_space_read_1(sc->mt_iot, sc->mt_ioh, reg); 980 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 981 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 982 return val; 983 } 984 985 void 986 envy_mt_write_1(struct envy_softc *sc, int reg, int val) 987 { 988 bus_space_write_1(sc->mt_iot, sc->mt_ioh, reg, val); 989 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 990 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 991 } 992 993 int 994 envy_mt_read_2(struct envy_softc *sc, int reg) 995 { 996 int val; 997 998 val = bus_space_read_2(sc->mt_iot, sc->mt_ioh, reg); 999 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 1000 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1001 return val; 1002 } 1003 1004 void 1005 envy_mt_write_2(struct envy_softc *sc, int reg, int val) 1006 { 1007 bus_space_write_2(sc->mt_iot, sc->mt_ioh, reg, val); 1008 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 1009 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1010 } 1011 1012 int 1013 envy_mt_read_4(struct envy_softc *sc, int reg) 1014 { 1015 int val; 1016 1017 val = bus_space_read_4(sc->mt_iot, sc->mt_ioh, reg); 1018 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 1019 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1020 return val; 1021 } 1022 1023 void 1024 envy_mt_write_4(struct envy_softc *sc, int reg, int val) 1025 { 1026 bus_space_write_4(sc->mt_iot, sc->mt_ioh, reg, val); 1027 bus_space_barrier(sc->mt_iot, sc->mt_ioh, 0, sc->mt_iosz, 1028 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1029 } 1030 1031 int 1032 envy_cci_read(struct envy_softc *sc, int index) 1033 { 1034 int val; 1035 1036 envy_ccs_write(sc, ENVY_CCI_INDEX, index); 1037 val = envy_ccs_read(sc, ENVY_CCI_DATA); 1038 return val; 1039 } 1040 1041 void 1042 envy_cci_write(struct envy_softc *sc, int index, int data) 1043 { 1044 envy_ccs_write(sc, ENVY_CCI_INDEX, index); 1045 envy_ccs_write(sc, ENVY_CCI_DATA, data); 1046 } 1047 1048 int 1049 envy_gpio_getstate(struct envy_softc *sc) 1050 { 1051 if (sc->isht) { 1052 return envy_ccs_read(sc, ENVY_CCS_GPIODATA0) | 1053 (envy_ccs_read(sc, ENVY_CCS_GPIODATA1) << 8) | 1054 (envy_ccs_read(sc, ENVY_CCS_GPIODATA2) << 16); 1055 } else 1056 return envy_cci_read(sc, ENVY_CCI_GPIODATA); 1057 } 1058 1059 void 1060 envy_gpio_setstate(struct envy_softc *sc, int reg) 1061 { 1062 if (sc->isht) { 1063 envy_ccs_write(sc, ENVY_CCS_GPIODATA0, reg & 0xff); 1064 envy_ccs_write(sc, ENVY_CCS_GPIODATA1, (reg >> 8) & 0xff); 1065 envy_ccs_write(sc, ENVY_CCS_GPIODATA2, (reg >> 16) & 0xff); 1066 } else 1067 envy_cci_write(sc, ENVY_CCI_GPIODATA, reg); 1068 } 1069 1070 int 1071 envy_gpio_getmask(struct envy_softc *sc) 1072 { 1073 if (sc->isht) { 1074 return envy_ccs_read(sc, ENVY_CCS_GPIOMASK0) | 1075 (envy_ccs_read(sc, ENVY_CCS_GPIOMASK1) << 8) | 1076 (envy_ccs_read(sc, ENVY_CCS_GPIOMASK2) << 16); 1077 } else 1078 return envy_cci_read(sc, ENVY_CCI_GPIOMASK); 1079 } 1080 1081 void 1082 envy_gpio_setmask(struct envy_softc *sc, int mask) 1083 { 1084 if (sc->isht) { 1085 envy_ccs_write(sc, ENVY_CCS_GPIOMASK0, mask & 0xff); 1086 envy_ccs_write(sc, ENVY_CCS_GPIOMASK1, (mask >> 8) & 0xff); 1087 envy_ccs_write(sc, ENVY_CCS_GPIOMASK2, (mask >> 16) & 0xff); 1088 } else 1089 envy_cci_write(sc, ENVY_CCI_GPIOMASK, mask); 1090 } 1091 1092 int 1093 envy_gpio_getdir(struct envy_softc *sc) 1094 { 1095 if (sc->isht) { 1096 return envy_ccs_read(sc, ENVY_CCS_GPIODIR0) | 1097 (envy_ccs_read(sc, ENVY_CCS_GPIODIR1) << 8) | 1098 (envy_ccs_read(sc, ENVY_CCS_GPIODIR2) << 16); 1099 } else 1100 return envy_cci_read(sc, ENVY_CCI_GPIODIR); 1101 } 1102 1103 void 1104 envy_gpio_setdir(struct envy_softc *sc, int dir) 1105 { 1106 if (sc->isht) { 1107 envy_ccs_write(sc, ENVY_CCS_GPIODIR0, dir & 0xff); 1108 envy_ccs_write(sc, ENVY_CCS_GPIODIR1, (dir >> 8) & 0xff); 1109 envy_ccs_write(sc, ENVY_CCS_GPIODIR2, (dir >> 16) & 0xff); 1110 } else 1111 envy_cci_write(sc, ENVY_CCI_GPIODIR, dir); 1112 } 1113 1114 void 1115 envy_gpio_i2c_start_bit(struct envy_softc *sc, int sda, int scl) 1116 { 1117 int reg; 1118 1119 reg = envy_gpio_getstate(sc); 1120 reg |= (sda | scl); 1121 envy_gpio_setstate(sc, reg); 1122 delay(5); 1123 reg &= ~sda; 1124 envy_gpio_setstate(sc, reg); 1125 delay(4); 1126 reg &= ~scl; 1127 envy_gpio_setstate(sc, reg); 1128 delay(5); 1129 } 1130 1131 void 1132 envy_gpio_i2c_stop_bit(struct envy_softc *sc, int sda, int scl) 1133 { 1134 int reg; 1135 1136 reg = envy_gpio_getstate(sc); 1137 reg &= ~sda; 1138 reg |= scl; 1139 envy_gpio_setstate(sc, reg); 1140 delay(4); 1141 reg |= sda; 1142 envy_gpio_setstate(sc, reg); 1143 } 1144 1145 void 1146 envy_gpio_i2c_byte_out(struct envy_softc *sc, int sda, int scl, int val) 1147 { 1148 int mask, reg; 1149 1150 reg = envy_gpio_getstate(sc); 1151 1152 for (mask = 0x80; mask != 0; mask >>= 1) { 1153 reg &= ~sda; 1154 reg |= (val & mask) ? sda : 0; 1155 envy_gpio_setstate(sc, reg); 1156 delay(1); 1157 reg |= scl; 1158 envy_gpio_setstate(sc, reg); 1159 delay(4); 1160 reg &= ~scl; 1161 envy_gpio_setstate(sc, reg); 1162 delay(5); 1163 } 1164 1165 reg |= scl; 1166 envy_gpio_setstate(sc, reg); 1167 delay(4); 1168 reg &= ~scl; 1169 envy_gpio_setstate(sc, reg); 1170 delay(5); 1171 } 1172 1173 void 1174 envy_i2c_wait(struct envy_softc *sc) 1175 { 1176 int timeout = 50, st; 1177 1178 for (;;) { 1179 st = envy_ccs_read(sc, ENVY_I2C_CTL); 1180 if (!(st & ENVY_I2C_CTL_BUSY)) 1181 break; 1182 if (timeout == 0) { 1183 printf("%s: i2c busy timeout\n", DEVNAME(sc)); 1184 break; 1185 } 1186 delay(50); 1187 timeout--; 1188 } 1189 } 1190 1191 int 1192 envy_i2c_read(struct envy_softc *sc, int dev, int addr) 1193 { 1194 envy_i2c_wait(sc); 1195 envy_ccs_write(sc, ENVY_I2C_ADDR, addr); 1196 envy_i2c_wait(sc); 1197 envy_ccs_write(sc, ENVY_I2C_DEV, dev << 1); 1198 envy_i2c_wait(sc); 1199 return envy_ccs_read(sc, ENVY_I2C_DATA); 1200 } 1201 1202 void 1203 envy_i2c_write(struct envy_softc *sc, int dev, int addr, int data) 1204 { 1205 if (dev == 0x50) { 1206 printf("%s: writing on eeprom is evil...\n", DEVNAME(sc)); 1207 return; 1208 } 1209 envy_i2c_wait(sc); 1210 envy_ccs_write(sc, ENVY_I2C_ADDR, addr); 1211 envy_i2c_wait(sc); 1212 envy_ccs_write(sc, ENVY_I2C_DATA, data); 1213 envy_i2c_wait(sc); 1214 envy_ccs_write(sc, ENVY_I2C_DEV, (dev << 1) | 1); 1215 } 1216 1217 int 1218 envy_codec_read(struct envy_softc *sc, int dev, int addr) { 1219 return sc->shadow[dev][addr]; 1220 } 1221 1222 void 1223 envy_codec_write(struct envy_softc *sc, int dev, int addr, int data) 1224 { 1225 DPRINTFN(2, "envy_codec_write: %d, %d, 0x%x\n", dev, addr, data); 1226 sc->shadow[dev][addr] = data; 1227 sc->card->codec_write(sc, dev, addr, data); 1228 } 1229 1230 int 1231 envy_eeprom_gpioxxx(struct envy_softc *sc, int addr) 1232 { 1233 int val; 1234 1235 val = sc->eeprom[addr]; 1236 if (sc->isht) { 1237 val |= sc->eeprom[++addr] << 8; 1238 val |= sc->eeprom[++addr] << 16; 1239 } 1240 return val; 1241 } 1242 1243 int 1244 envy_ac97_wait(struct envy_softc *sc) 1245 { 1246 int timeout = 50, st; 1247 1248 for (;;) { 1249 st = envy_mt_read_1(sc, ENVY_MT_AC97_CMD); 1250 if ((st & ENVY_MT_AC97_READY) && !(st & ENVY_MT_AC97_CMD_MASK)) { 1251 st = 0; 1252 break; 1253 } 1254 if (timeout == 0) { 1255 st = -1; 1256 break; 1257 } 1258 delay(50); 1259 timeout--; 1260 } 1261 1262 return (st); 1263 } 1264 1265 int 1266 envy_ac97_attach_codec(void *hdl, struct ac97_codec_if *codec_if) 1267 { 1268 struct envy_softc *sc = hdl; 1269 1270 sc->codec_if = codec_if; 1271 1272 return (0); 1273 } 1274 1275 int 1276 envy_ac97_read_codec(void *hdl, u_int8_t reg, u_int16_t *result) 1277 { 1278 struct envy_softc *sc = hdl; 1279 1280 if (envy_ac97_wait(sc)) { 1281 printf("%s: envy_ac97_read_codec: timed out\n", DEVNAME(sc)); 1282 return (-1); 1283 } 1284 1285 envy_mt_write_1(sc, ENVY_MT_AC97_IDX, reg & 0x7f); 1286 envy_mt_write_1(sc, ENVY_MT_AC97_CMD, 1287 ENVY_MT_AC97_CMD_RD); 1288 delay(50); 1289 1290 if (envy_ac97_wait(sc)) { 1291 printf("%s: envy_ac97_read_codec: timed out\n", DEVNAME(sc)); 1292 return (-1); 1293 } 1294 1295 *result = envy_mt_read_2(sc, ENVY_MT_AC97_DATA); 1296 1297 return (0); 1298 } 1299 1300 int 1301 envy_ac97_write_codec(void *hdl, u_int8_t reg, u_int16_t data) 1302 { 1303 struct envy_softc *sc = hdl; 1304 1305 if (envy_ac97_wait(sc)) { 1306 printf("%s: envy_ac97_write_codec: timed out\n", DEVNAME(sc)); 1307 return (-1); 1308 } 1309 1310 envy_mt_write_1(sc, ENVY_MT_AC97_IDX, reg & 0x7f); 1311 envy_mt_write_2(sc, ENVY_MT_AC97_DATA, data); 1312 envy_mt_write_1(sc, ENVY_MT_AC97_CMD, 1313 ENVY_MT_AC97_CMD_WR); 1314 delay(50); 1315 1316 return (0); 1317 } 1318 1319 void 1320 envy_ac97_reset_codec(void *hdl) 1321 { 1322 struct envy_softc *sc = hdl; 1323 1324 envy_mt_write_1(sc, ENVY_MT_AC97_CMD, ENVY_MT_AC97_CMD_RST); 1325 delay(50); 1326 envy_mt_write_1(sc, ENVY_MT_AC97_CMD, 0); 1327 delay(50); 1328 1329 if (envy_ac97_wait(sc)) { 1330 printf("%s: envy_ac97_reset_codec: timed out\n", DEVNAME(sc)); 1331 } 1332 1333 return; 1334 } 1335 1336 enum ac97_host_flags 1337 envy_ac97_flags_codec(void *hdl) 1338 { 1339 struct envy_softc *sc = hdl; 1340 1341 return (sc->codec_flags); 1342 } 1343 1344 void 1345 envy_midi_wait(struct envy_softc *sc) 1346 { 1347 int i, st; 1348 1349 for (i = 100;; i--) { 1350 st = envy_ccs_read(sc, ENVY_CCS_MIDISTAT0); 1351 if (!(st & ENVY_MIDISTAT_OBUSY(sc))) 1352 break; 1353 if (i == 0) { 1354 printf("%s: midi wait timeout\n", DEVNAME(sc)); 1355 break; 1356 } 1357 delay(10); 1358 } 1359 } 1360 1361 void 1362 envy_reset(struct envy_softc *sc) 1363 { 1364 int i; 1365 1366 /* 1367 * full reset 1368 */ 1369 envy_ccs_write(sc, ENVY_CTL, ENVY_CTL_RESET | ENVY_CTL_NATIVE); 1370 delay(200); 1371 envy_ccs_write(sc, ENVY_CTL, ENVY_CTL_NATIVE); 1372 delay(200); 1373 1374 /* 1375 * read EEPROM using i2c device or from a static array 1376 */ 1377 if (sc->card->eeprom == NULL) { 1378 for (i = 0; i < ENVY_EEPROM_MAXSZ; i++) { 1379 sc->eeprom[i] = envy_i2c_read(sc, ENVY_I2C_DEV_EEPROM, i); 1380 } 1381 #ifdef ENVY_DEBUG 1382 printf("%s: eeprom: ", DEVNAME(sc)); 1383 for (i = 0; i < ENVY_EEPROM_MAXSZ; i++) { 1384 printf(" %02x", (unsigned)sc->eeprom[i]); 1385 } 1386 printf("\n"); 1387 #endif 1388 } else 1389 memcpy(sc->eeprom, sc->card->eeprom, ENVY_EEPROM_MAXSZ); 1390 1391 /* 1392 * write EEPROM values to corresponding registers 1393 */ 1394 if (sc->isht) { 1395 envy_ccs_write(sc, ENVY_CCS_CONF, 1396 sc->eeprom[ENVY_EEPROM_CONF]); 1397 envy_ccs_write(sc, ENVY_CCS_ACLINK, 1398 sc->eeprom[ENVY_EEPROM_ACLINK]); 1399 envy_ccs_write(sc, ENVY_CCS_I2S, 1400 sc->eeprom[ENVY_EEPROM_I2S]); 1401 envy_ccs_write(sc, ENVY_CCS_SPDIF, 1402 sc->eeprom[ENVY_EEPROM_SPDIF]); 1403 } else { 1404 pci_conf_write(sc->pci_pc, sc->pci_tag, ENVY_CONF, 1405 sc->eeprom[ENVY_EEPROM_CONF] | 1406 (sc->eeprom[ENVY_EEPROM_ACLINK] << 8) | 1407 (sc->eeprom[ENVY_EEPROM_I2S] << 16) | 1408 (sc->eeprom[ENVY_EEPROM_SPDIF] << 24)); 1409 } 1410 1411 envy_gpio_setmask(sc, envy_eeprom_gpioxxx(sc, ENVY_EEPROM_GPIOMASK(sc))); 1412 envy_gpio_setdir(sc, envy_eeprom_gpioxxx(sc, ENVY_EEPROM_GPIODIR(sc))); 1413 envy_gpio_setstate(sc, envy_eeprom_gpioxxx(sc, ENVY_EEPROM_GPIOST(sc))); 1414 1415 DPRINTF("%s: gpio_mask = %02x\n", DEVNAME(sc), 1416 envy_gpio_getmask(sc)); 1417 DPRINTF("%s: gpio_dir = %02x\n", DEVNAME(sc), 1418 envy_gpio_getdir(sc)); 1419 DPRINTF("%s: gpio_state = %02x\n", DEVNAME(sc), 1420 envy_gpio_getstate(sc)); 1421 1422 if (sc->isht) { 1423 /* 1424 * set water marks so we get an interrupt for each byte 1425 */ 1426 envy_ccs_write(sc, ENVY_CCS_MIDIWAT, 1); 1427 envy_ccs_write(sc, ENVY_CCS_MIDIWAT, 1 | ENVY_CCS_MIDIWAT_RX); 1428 } 1429 1430 /* 1431 * switch to UART mode 1432 */ 1433 envy_ccs_write(sc, ENVY_CCS_MIDISTAT0, 0xff); 1434 envy_midi_wait(sc); 1435 envy_ccs_write(sc, ENVY_CCS_MIDISTAT0, ENVY_MIDISTAT_UART); 1436 envy_midi_wait(sc); 1437 if (!sc->isht) 1438 (void)envy_ccs_read(sc, ENVY_CCS_MIDIDATA0); 1439 1440 /* 1441 * clear all interrupts and unmask used ones 1442 */ 1443 envy_ccs_write(sc, ENVY_CCS_INTSTAT, 0xff); 1444 envy_ccs_write(sc, ENVY_CCS_INTMASK, 1445 ~(ENVY_CCS_INT_MT | ENVY_CCS_INT_MIDI0)); 1446 if (sc->isht) { 1447 envy_mt_write_1(sc, ENVY_MT_NSTREAM, 4 - sc->card->noch / 2); 1448 envy_mt_write_1(sc, ENVY_MT_IMASK, ~(ENVY_MT_IMASK_PDMA0 | 1449 ENVY_MT_IMASK_RDMA0 | ENVY_MT_IMASK_ERR)); 1450 } 1451 sc->iactive = 0; 1452 sc->oactive = 0; 1453 sc->card->init(sc); 1454 } 1455 1456 int 1457 envy_lineout_getsrc(struct envy_softc *sc, int out) 1458 { 1459 int reg, shift, src; 1460 1461 if (sc->isht) { 1462 reg = envy_mt_read_4(sc, ENVY_MT_HTSRC); 1463 DPRINTF("%s: outsrc=%x\n", DEVNAME(sc), reg); 1464 shift = 3 * (out / 2) + ((out & 1) ? 20 : 8); 1465 src = (reg >> shift) & ENVY_MT_HTSRC_MASK; 1466 if (src == ENVY_MT_HTSRC_DMA) { 1467 return ENVY_MIX_OUTSRC_DMA; 1468 } else { 1469 src -= ENVY_MT_HTSRC_LINE; 1470 return ENVY_MIX_OUTSRC_LINEIN + src; 1471 } 1472 } 1473 1474 reg = envy_mt_read_2(sc, ENVY_MT_OUTSRC); 1475 DPRINTF("%s: outsrc=%x\n", DEVNAME(sc), reg); 1476 shift = (out & 1) ? (out & ~1) + 8 : out; 1477 src = (reg >> shift) & 3; 1478 if (src == ENVY_MT_OUTSRC_DMA) { 1479 return ENVY_MIX_OUTSRC_DMA; 1480 } else if (src == ENVY_MT_OUTSRC_MON) { 1481 return ENVY_MIX_OUTSRC_MON; 1482 } 1483 reg = envy_mt_read_4(sc, ENVY_MT_INSEL); 1484 DPRINTF("%s: insel=%x\n", DEVNAME(sc), reg); 1485 reg = (reg >> (out * 4)) & 0xf; 1486 if (src == ENVY_MT_OUTSRC_LINE) 1487 return ENVY_MIX_OUTSRC_LINEIN + (reg & 7); 1488 else 1489 return ENVY_MIX_OUTSRC_SPDIN + (reg >> 3); 1490 } 1491 1492 void 1493 envy_lineout_setsrc(struct envy_softc *sc, int out, int src) 1494 { 1495 int reg, shift, mask, sel; 1496 1497 if (sc->isht) { 1498 if (src < ENVY_MIX_OUTSRC_SPDIN) { 1499 sel = ENVY_MT_HTSRC_LINE; 1500 sel += src; 1501 } else if (src < ENVY_MIX_OUTSRC_DMA) { 1502 sel = ENVY_MT_HTSRC_SPD; 1503 sel += src - ENVY_MIX_OUTSRC_SPDIN; 1504 } else { 1505 sel = ENVY_MT_HTSRC_DMA; 1506 } 1507 shift = 3 * (out / 2) + ((out & 1) ? 20 : 8); 1508 mask = ENVY_MT_HTSRC_MASK << shift; 1509 reg = envy_mt_read_4(sc, ENVY_MT_HTSRC); 1510 reg = (reg & ~mask) | (sel << shift); 1511 envy_mt_write_4(sc, ENVY_MT_HTSRC, reg); 1512 DPRINTF("%s: outsrc <- %x\n", DEVNAME(sc), reg); 1513 return; 1514 } 1515 1516 if (src < ENVY_MIX_OUTSRC_DMA) { 1517 /* 1518 * linein and spdin are used as output source so we 1519 * must select the input source channel number 1520 */ 1521 if (src < ENVY_MIX_OUTSRC_SPDIN) 1522 sel = src - ENVY_MIX_OUTSRC_LINEIN; 1523 else 1524 sel = (src - ENVY_MIX_OUTSRC_SPDIN) << 3; 1525 1526 shift = out * ENVY_MT_INSEL_BITS; 1527 mask = ENVY_MT_INSEL_MASK << shift; 1528 reg = envy_mt_read_4(sc, ENVY_MT_INSEL); 1529 reg = (reg & ~mask) | (sel << shift); 1530 envy_mt_write_4(sc, ENVY_MT_INSEL, reg); 1531 DPRINTF("%s: insel <- %x\n", DEVNAME(sc), reg); 1532 } 1533 1534 /* 1535 * set the lineout route register 1536 */ 1537 if (src < ENVY_MIX_OUTSRC_SPDIN) { 1538 sel = ENVY_MT_OUTSRC_LINE; 1539 } else if (src < ENVY_MIX_OUTSRC_DMA) { 1540 sel = ENVY_MT_OUTSRC_SPD; 1541 } else if (src == ENVY_MIX_OUTSRC_DMA) { 1542 sel = ENVY_MT_OUTSRC_DMA; 1543 } else { 1544 sel = ENVY_MT_OUTSRC_MON; 1545 } 1546 shift = (out & 1) ? (out & ~1) + 8 : out; 1547 mask = ENVY_MT_OUTSRC_MASK << shift; 1548 reg = envy_mt_read_2(sc, ENVY_MT_OUTSRC); 1549 reg = (reg & ~mask) | (sel << shift); 1550 envy_mt_write_2(sc, ENVY_MT_OUTSRC, reg); 1551 DPRINTF("%s: outsrc <- %x\n", DEVNAME(sc), reg); 1552 } 1553 1554 1555 int 1556 envy_spdout_getsrc(struct envy_softc *sc, int out) 1557 { 1558 int reg, src, sel; 1559 1560 reg = envy_mt_read_2(sc, ENVY_MT_SPDROUTE); 1561 DPRINTF("%s: spdroute=%x\n", DEVNAME(sc), reg); 1562 src = (out == 0) ? reg : reg >> 2; 1563 src &= ENVY_MT_SPDSRC_MASK; 1564 if (src == ENVY_MT_SPDSRC_DMA) { 1565 return ENVY_MIX_OUTSRC_DMA; 1566 } else if (src == ENVY_MT_SPDSRC_MON) { 1567 return ENVY_MIX_OUTSRC_MON; 1568 } 1569 1570 sel = (out == 0) ? reg >> 8 : reg >> 12; 1571 sel &= ENVY_MT_SPDSEL_MASK; 1572 if (src == ENVY_MT_SPDSRC_LINE) 1573 return ENVY_MIX_OUTSRC_LINEIN + (sel & 7); 1574 else 1575 return ENVY_MIX_OUTSRC_SPDIN + (sel >> 3); 1576 } 1577 1578 void 1579 envy_spdout_setsrc(struct envy_softc *sc, int out, int src) 1580 { 1581 int reg, shift, mask, sel; 1582 1583 reg = envy_mt_read_2(sc, ENVY_MT_SPDROUTE); 1584 if (src < ENVY_MIX_OUTSRC_DMA) { 1585 /* 1586 * linein and spdin are used as output source so we 1587 * must select the input source channel number 1588 */ 1589 if (src < ENVY_MIX_OUTSRC_SPDIN) 1590 sel = src - ENVY_MIX_OUTSRC_LINEIN; 1591 else 1592 sel = (src - ENVY_MIX_OUTSRC_SPDIN) << 3; 1593 1594 shift = 8 + out * ENVY_MT_SPDSEL_BITS; 1595 mask = ENVY_MT_SPDSEL_MASK << shift; 1596 reg = (reg & ~mask) | (sel << shift); 1597 } 1598 1599 /* 1600 * set the lineout route register 1601 */ 1602 if (src < ENVY_MIX_OUTSRC_SPDIN) { 1603 sel = ENVY_MT_OUTSRC_LINE; 1604 } else if (src < ENVY_MIX_OUTSRC_DMA) { 1605 sel = ENVY_MT_OUTSRC_SPD; 1606 } else if (src == ENVY_MIX_OUTSRC_DMA) { 1607 sel = ENVY_MT_OUTSRC_DMA; 1608 } else { 1609 sel = ENVY_MT_OUTSRC_MON; 1610 } 1611 shift = out * 2; 1612 mask = ENVY_MT_SPDSRC_MASK << shift; 1613 reg = (reg & ~mask) | (sel << shift); 1614 envy_mt_write_2(sc, ENVY_MT_SPDROUTE, reg); 1615 DPRINTF("%s: spdroute <- %x\n", DEVNAME(sc), reg); 1616 } 1617 1618 void 1619 envy_mon_getvol(struct envy_softc *sc, int idx, int ch, int *val) 1620 { 1621 int reg; 1622 1623 envy_mt_write_2(sc, ENVY_MT_MONIDX, idx); 1624 reg = envy_mt_read_1(sc, ENVY_MT_MONDATA + ch); 1625 *val = 0x7f - (reg & 0x7f); 1626 } 1627 1628 void 1629 envy_mon_setvol(struct envy_softc *sc, int idx, int ch, int val) 1630 { 1631 int reg; 1632 1633 envy_mt_write_2(sc, ENVY_MT_MONIDX, idx); 1634 reg = 0x7f - val; 1635 DPRINTF("%s: mon=%d/%d <- %d\n", DEVNAME(sc), reg, ch, val); 1636 envy_mt_write_1(sc, ENVY_MT_MONDATA + ch, reg); 1637 } 1638 1639 int 1640 envymatch(struct device *parent, void *match, void *aux) 1641 { 1642 return pci_matchbyid((struct pci_attach_args *)aux, envy_matchids, 1643 sizeof(envy_matchids) / sizeof(envy_matchids[0])); 1644 } 1645 1646 void 1647 envyattach(struct device *parent, struct device *self, void *aux) 1648 { 1649 struct envy_softc *sc = (struct envy_softc *)self; 1650 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 1651 pci_intr_handle_t ih; 1652 const char *intrstr; 1653 int subid; 1654 1655 sc->pci_tag = pa->pa_tag; 1656 sc->pci_pc = pa->pa_pc; 1657 sc->pci_dmat = pa->pa_dmat; 1658 sc->pci_ih = NULL; 1659 sc->ibuf.addr = sc->obuf.addr = NULL; 1660 sc->ccs_iosz = 0; 1661 sc->mt_iosz = 0; 1662 sc->isht = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ICENSEMBLE_VT172x); 1663 1664 if (pci_mapreg_map(pa, ENVY_CTL_BAR, PCI_MAPREG_TYPE_IO, 0, 1665 &sc->ccs_iot, &sc->ccs_ioh, NULL, &sc->ccs_iosz, 0)) { 1666 printf(": can't map ctl i/o space\n"); 1667 sc->ccs_iosz = 0; 1668 return; 1669 } 1670 if (pci_mapreg_map(pa, ENVY_MT_BAR(sc->isht), PCI_MAPREG_TYPE_IO, 0, 1671 &sc->mt_iot, &sc->mt_ioh, NULL, &sc->mt_iosz, 0)) { 1672 printf(": can't map mt i/o space\n"); 1673 sc->mt_iosz = 0; 1674 return; 1675 } 1676 if (pci_intr_map(pa, &ih)) { 1677 printf(": can't map interrupt\n"); 1678 } 1679 intrstr = pci_intr_string(sc->pci_pc, ih); 1680 sc->pci_ih = pci_intr_establish(sc->pci_pc, ih, IPL_AUDIO | IPL_MPSAFE, 1681 envy_intr, sc, sc->dev.dv_xname); 1682 if (sc->pci_ih == NULL) { 1683 printf(": can't establish interrupt"); 1684 if (intrstr) 1685 printf(" at %s", intrstr); 1686 printf("\n"); 1687 return; 1688 } 1689 printf(": %s\n", intrstr); 1690 subid = pci_conf_read(sc->pci_pc, sc->pci_tag, PCI_SUBVEND_0); 1691 sc->card = sc->isht ? envy_cards_ht : envy_cards; 1692 while (sc->card->subid != subid) { 1693 if (sc->card->subid == 0) 1694 break; 1695 sc->card++; 1696 } 1697 printf("%s: %s, %u inputs, %u outputs\n", DEVNAME(sc), 1698 sc->card->name, sc->card->nich, sc->card->noch); 1699 envy_reset(sc); 1700 sc->audio = audio_attach_mi(&envy_hw_if, sc, &sc->dev); 1701 #if NMIDI > 0 1702 if (!sc->isht || sc->eeprom[ENVY_EEPROM_CONF] & ENVY_CONF_MIDI) 1703 sc->midi = midi_attach_mi(&envy_midi_hw_if, sc, &sc->dev); 1704 #endif 1705 1706 } 1707 1708 int 1709 envydetach(struct device *self, int flags) 1710 { 1711 struct envy_softc *sc = (struct envy_softc *)self; 1712 1713 if (sc->pci_ih != NULL) { 1714 pci_intr_disestablish(sc->pci_pc, sc->pci_ih); 1715 sc->pci_ih = NULL; 1716 } 1717 if (sc->ccs_iosz) { 1718 bus_space_unmap(sc->ccs_iot, sc->ccs_ioh, sc->ccs_iosz); 1719 } 1720 if (sc->mt_iosz) { 1721 bus_space_unmap(sc->mt_iot, sc->mt_ioh, sc->mt_iosz); 1722 } 1723 return 0; 1724 } 1725 1726 int 1727 envy_open(void *self, int flags) 1728 { 1729 return 0; 1730 } 1731 1732 void 1733 envy_close(void *self) 1734 { 1735 } 1736 1737 void * 1738 envy_allocm(void *self, int dir, size_t size, int type, int flags) 1739 { 1740 struct envy_softc *sc = (struct envy_softc *)self; 1741 int err, basereg, wait; 1742 struct envy_buf *buf; 1743 bus_addr_t dma_addr; 1744 1745 if (dir == AUMODE_RECORD) { 1746 buf = &sc->ibuf; 1747 basereg = ENVY_MT_RADDR; 1748 } else { 1749 buf = &sc->obuf; 1750 basereg = ENVY_MT_PADDR; 1751 } 1752 if (buf->addr != NULL) { 1753 DPRINTF("%s: multiple alloc, dir = %d\n", DEVNAME(sc), dir); 1754 return NULL; 1755 } 1756 buf->size = size; 1757 wait = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1758 1759 #define ENVY_ALIGN 4 1760 #define ENVY_MAXADDR ((1 << 28) - 1) 1761 1762 buf->addr = (caddr_t)uvm_km_kmemalloc_pla(kernel_map, 1763 uvm.kernel_object, buf->size, 0, UVM_KMF_NOWAIT, 0, 1764 (paddr_t)ENVY_MAXADDR, 0, 0, 1); 1765 if (buf->addr == NULL) { 1766 DPRINTF("%s: unable to alloc dma segment\n", DEVNAME(sc)); 1767 goto err_ret; 1768 } 1769 err = bus_dmamap_create(sc->pci_dmat, buf->size, 1, buf->size, 0, 1770 wait, &buf->map); 1771 if (err) { 1772 DPRINTF("%s: dmamap_create: failed %d\n", DEVNAME(sc), err); 1773 goto err_unmap; 1774 } 1775 err = bus_dmamap_load(sc->pci_dmat, buf->map, buf->addr, 1776 buf->size, NULL, wait); 1777 if (err) { 1778 DPRINTF("%s: dmamap_load: failed %d\n", DEVNAME(sc), err); 1779 goto err_destroy; 1780 } 1781 dma_addr = buf->map->dm_segs[0].ds_addr; 1782 DPRINTF("%s: allocated %zd bytes dir=%d, ka=%p, da=%p\n", DEVNAME(sc), 1783 buf->size, dir, buf->addr, dma_addr); 1784 if (!sc->isht && (dma_addr & ~ENVY_MAXADDR)) { 1785 printf("%s: DMA address beyond 0x10000000\n", DEVNAME(sc)); 1786 goto err_unload; 1787 } 1788 envy_mt_write_4(sc, basereg, dma_addr); 1789 return buf->addr; 1790 err_unload: 1791 bus_dmamap_unload(sc->pci_dmat, buf->map); 1792 err_destroy: 1793 bus_dmamap_destroy(sc->pci_dmat, buf->map); 1794 err_unmap: 1795 uvm_km_free(kernel_map, (vaddr_t)buf->addr, buf->size); 1796 err_ret: 1797 return NULL; 1798 } 1799 1800 void 1801 envy_freem(void *self, void *addr, int type) 1802 { 1803 struct envy_buf *buf; 1804 struct envy_softc *sc = (struct envy_softc *)self; 1805 int dir; 1806 1807 if (sc->ibuf.addr == addr) { 1808 buf = &sc->ibuf; 1809 dir = AUMODE_RECORD; 1810 } else if (sc->obuf.addr == addr) { 1811 buf = &sc->obuf; 1812 dir = AUMODE_PLAY; 1813 } else { 1814 DPRINTF("%s: no buf to free\n", DEVNAME(sc)); 1815 return; 1816 } 1817 bus_dmamap_unload(sc->pci_dmat, buf->map); 1818 bus_dmamap_destroy(sc->pci_dmat, buf->map); 1819 uvm_km_free(kernel_map, (vaddr_t)&buf->addr, buf->size); 1820 buf->addr = NULL; 1821 DPRINTF("%s: freed buffer (mode=%d)\n", DEVNAME(sc), dir); 1822 } 1823 1824 int 1825 envy_query_encoding(void *self, struct audio_encoding *enc) 1826 { 1827 if (enc->index == 0) { 1828 strlcpy(enc->name, AudioEslinear_le, sizeof(enc->name)); 1829 enc->encoding = AUDIO_ENCODING_SLINEAR_LE; 1830 enc->precision = 24; 1831 enc->bps = 4; 1832 enc->msb = 1; 1833 enc->flags = 0; 1834 return 0; 1835 } 1836 return EINVAL; 1837 } 1838 1839 int 1840 envy_set_params(void *self, int setmode, int usemode, 1841 struct audio_params *p, struct audio_params *r) 1842 { 1843 struct envy_softc *sc = (struct envy_softc *)self; 1844 int i, rate, reg; 1845 1846 if (setmode == 0) 1847 return 0; 1848 if (setmode == (AUMODE_PLAY | AUMODE_RECORD) && 1849 p->sample_rate != r->sample_rate) { 1850 DPRINTF("%s: play/rec rates mismatch\n", DEVNAME(sc)); 1851 r->sample_rate = p->sample_rate; 1852 } 1853 rate = (setmode & AUMODE_PLAY) ? p->sample_rate : r->sample_rate; 1854 for (i = 0; envy_rates[i].rate < rate; i++) { 1855 if (envy_rates[i].rate == -1) { 1856 i--; 1857 DPRINTF("%s: rate: %d -> %d\n", DEVNAME(sc), rate, i); 1858 break; 1859 } 1860 } 1861 reg = envy_mt_read_1(sc, ENVY_MT_RATE); 1862 reg &= ~ENVY_MT_RATEMASK; 1863 reg |= envy_rates[i].reg; 1864 envy_mt_write_1(sc, ENVY_MT_RATE, reg); 1865 if (setmode & AUMODE_PLAY) { 1866 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 1867 p->precision = 24; 1868 p->bps = 4; 1869 p->msb = 1; 1870 p->channels = sc->isht ? sc->card->noch : ENVY_PCHANS; 1871 } 1872 if (setmode & AUMODE_RECORD) { 1873 r->encoding = AUDIO_ENCODING_SLINEAR_LE; 1874 r->precision = 24; 1875 r->bps = 4; 1876 r->msb = 1; 1877 r->channels = sc->isht ? sc->card->nich : ENVY_RCHANS; 1878 } 1879 return 0; 1880 } 1881 1882 int 1883 envy_round_blocksize(void *self, int blksz) 1884 { 1885 struct envy_softc *sc = (struct envy_softc *)self; 1886 int mul, pmult, rmult; 1887 1888 /* 1889 * XXX: audio(4) layer doesn't round to the sample size 1890 * until it's fixed, roll our own rounding 1891 */ 1892 1893 pmult = (sc->isht ? sc->card->noch : ENVY_PCHANS); 1894 if (pmult == 0) 1895 pmult = 1; 1896 rmult = (sc->isht ? sc->card->nich : ENVY_RCHANS); 1897 if (rmult == 0) 1898 rmult = 1; 1899 mul = pmult * rmult; 1900 while ((mul & 0x1f) != 0) 1901 mul <<= 1; 1902 blksz -= blksz % mul; 1903 if (blksz == 0) 1904 blksz = mul; 1905 return blksz; 1906 } 1907 1908 size_t 1909 envy_round_buffersize(void *self, int dir, size_t bufsz) 1910 { 1911 return bufsz; 1912 } 1913 1914 #ifdef ENVY_DEBUG 1915 void 1916 envy_pintr(struct envy_softc *sc) 1917 { 1918 int i; 1919 1920 if (sc->spurious > 0 || envydebug >= 2) { 1921 printf("%s: spurious = %u, start = %lld.%ld\n", 1922 DEVNAME(sc), sc->spurious, 1923 (long long)sc->start_ts.tv_sec, sc->start_ts.tv_nsec); 1924 for (i = 0; i < sc->nintr; i++) { 1925 printf("%lld.%09ld: " 1926 "active=%d/%d pos=%d/%d st=%x/%x, ctl=%x\n", 1927 (long long)sc->intrs[i].ts.tv_sec, 1928 sc->intrs[i].ts.tv_nsec, 1929 sc->intrs[i].iactive, 1930 sc->intrs[i].oactive, 1931 sc->intrs[i].ipos, 1932 sc->intrs[i].opos, 1933 sc->intrs[i].st, 1934 sc->intrs[i].mask, 1935 sc->intrs[i].ctl); 1936 } 1937 } 1938 } 1939 #endif 1940 1941 int 1942 envy_intr(void *self) 1943 { 1944 struct envy_softc *sc = (struct envy_softc *)self; 1945 int mintr, mstat, mdata; 1946 int st, err, ctl; 1947 int max; 1948 1949 mtx_enter(&audio_lock); 1950 st = envy_mt_read_1(sc, ENVY_MT_INTR); 1951 mintr = envy_ccs_read(sc, ENVY_CCS_INTSTAT); 1952 if (!(st & ENVY_MT_INTR_ALL) && !(mintr & ENVY_CCS_INT_MIDI0)) { 1953 mtx_leave(&audio_lock); 1954 return 0; 1955 } 1956 if (st & ENVY_MT_INTR_ERR) { 1957 err = envy_mt_read_1(sc, ENVY_MT_ERR); 1958 envy_mt_write_1(sc, ENVY_MT_ERR, err); 1959 } 1960 envy_mt_write_1(sc, ENVY_MT_INTR, st); 1961 envy_ccs_write(sc, ENVY_CCS_INTSTAT, mintr); 1962 1963 #ifdef ENVY_DEBUG 1964 if (sc->nintr < ENVY_NINTR) { 1965 sc->intrs[sc->nintr].iactive = sc->iactive; 1966 sc->intrs[sc->nintr].oactive = sc->oactive; 1967 sc->intrs[sc->nintr].st = st; 1968 sc->intrs[sc->nintr].ipos = envy_mt_read_2(sc, ENVY_MT_RBUFSZ); 1969 sc->intrs[sc->nintr].opos = envy_mt_read_2(sc, ENVY_MT_PBUFSZ); 1970 sc->intrs[sc->nintr].ctl = envy_mt_read_1(sc, ENVY_MT_CTL); 1971 sc->intrs[sc->nintr].mask = envy_mt_read_1(sc, ENVY_MT_IMASK); 1972 nanouptime(&sc->intrs[sc->nintr].ts); 1973 sc->nintr++; 1974 } 1975 #endif 1976 if (mintr & ENVY_CCS_INT_MIDI0) { 1977 for (max = 128; max > 0; max--) { 1978 mstat = envy_ccs_read(sc, ENVY_CCS_MIDISTAT0); 1979 if (mstat & ENVY_MIDISTAT_IEMPTY(sc)) 1980 break; 1981 mdata = envy_ccs_read(sc, ENVY_CCS_MIDIDATA0); 1982 #if NMIDI > 0 1983 if (sc->midi_in) 1984 sc->midi_in(sc->midi_arg, mdata); 1985 #endif 1986 } 1987 } 1988 if (st & ENVY_MT_INTR_PACK) { 1989 if (sc->oactive) 1990 sc->ointr(sc->oarg); 1991 else { 1992 ctl = envy_mt_read_1(sc, ENVY_MT_CTL); 1993 if (ctl & ENVY_MT_CTL_PSTART) { 1994 envy_mt_write_1(sc, 1995 ENVY_MT_CTL, ctl & ~ENVY_MT_CTL_PSTART); 1996 st &= ~ENVY_MT_INTR_PACK; 1997 sc->obusy = 0; 1998 wakeup(&sc->obusy); 1999 } 2000 #ifdef ENVY_DEBUG 2001 else 2002 sc->spurious++; 2003 #endif 2004 } 2005 } 2006 if (st & ENVY_MT_INTR_RACK) { 2007 if (sc->iactive) 2008 sc->iintr(sc->iarg); 2009 else { 2010 ctl = envy_mt_read_1(sc, ENVY_MT_CTL); 2011 if (ctl & ENVY_MT_CTL_RSTART(sc)) { 2012 envy_mt_write_1(sc, 2013 ENVY_MT_CTL, ctl & ~ENVY_MT_CTL_RSTART(sc)); 2014 st &= ~ENVY_MT_INTR_RACK; 2015 sc->ibusy = 0; 2016 wakeup(&sc->ibusy); 2017 } 2018 #ifdef ENVY_DEBUG 2019 else 2020 sc->spurious++; 2021 #endif 2022 } 2023 } 2024 mtx_leave(&audio_lock); 2025 return 1; 2026 } 2027 2028 int 2029 envy_trigger_output(void *self, void *start, void *end, int blksz, 2030 void (*intr)(void *), void *arg, struct audio_params *param) 2031 { 2032 struct envy_softc *sc = (struct envy_softc *)self; 2033 size_t bufsz; 2034 int st; 2035 2036 bufsz = (char *)end - (char *)start; 2037 #ifdef ENVY_DEBUG 2038 if (blksz % (sc->isht ? sc->card->noch * 4 : ENVY_PFRAME_SIZE) != 0) { 2039 printf("%s: %d: bad output blksz\n", DEVNAME(sc), blksz); 2040 return EINVAL; 2041 } 2042 if (bufsz % blksz) { 2043 printf("%s: %ld: bad output bufsz\n", DEVNAME(sc), bufsz); 2044 return EINVAL; 2045 } 2046 #endif 2047 mtx_enter(&audio_lock); 2048 envy_mt_write_2(sc, ENVY_MT_PBUFSZ, bufsz / 4 - 1); 2049 envy_mt_write_2(sc, ENVY_MT_PBLKSZ(sc), blksz / 4 - 1); 2050 2051 #ifdef ENVY_DEBUG 2052 if (!sc->iactive) { 2053 sc->nintr = 0; 2054 sc->spurious = 0; 2055 nanouptime(&sc->start_ts); 2056 } 2057 #endif 2058 sc->ointr = intr; 2059 sc->oarg = arg; 2060 sc->oactive = 1; 2061 sc->obusy = 1; 2062 st = ENVY_MT_INTR_PACK; 2063 envy_mt_write_1(sc, ENVY_MT_INTR, st); 2064 st = envy_mt_read_1(sc, ENVY_MT_CTL); 2065 st |= ENVY_MT_CTL_PSTART; 2066 envy_mt_write_1(sc, ENVY_MT_CTL, st); 2067 mtx_leave(&audio_lock); 2068 return 0; 2069 } 2070 2071 int 2072 envy_trigger_input(void *self, void *start, void *end, int blksz, 2073 void (*intr)(void *), void *arg, struct audio_params *param) 2074 { 2075 struct envy_softc *sc = (struct envy_softc *)self; 2076 size_t bufsz; 2077 int st; 2078 2079 bufsz = (char *)end - (char *)start; 2080 #ifdef ENVY_DEBUG 2081 if (blksz % (sc->isht ? sc->card->nich * 4 : ENVY_RFRAME_SIZE) != 0) { 2082 printf("%s: %d: bad input blksz\n", DEVNAME(sc), blksz); 2083 return EINVAL; 2084 } 2085 if (bufsz % blksz != 0) { 2086 printf("%s: %ld: bad input bufsz\n", DEVNAME(sc), bufsz); 2087 return EINVAL; 2088 } 2089 #endif 2090 mtx_enter(&audio_lock); 2091 envy_mt_write_2(sc, ENVY_MT_RBUFSZ, bufsz / 4 - 1); 2092 envy_mt_write_2(sc, ENVY_MT_RBLKSZ, blksz / 4 - 1); 2093 2094 #ifdef ENVY_DEBUG 2095 if (!sc->oactive) { 2096 sc->nintr = 0; 2097 sc->spurious = 0; 2098 nanouptime(&sc->start_ts); 2099 } 2100 #endif 2101 sc->iintr = intr; 2102 sc->iarg = arg; 2103 sc->iactive = 1; 2104 sc->ibusy = 1; 2105 st = ENVY_MT_INTR_RACK; 2106 envy_mt_write_1(sc, ENVY_MT_INTR, st); 2107 st = envy_mt_read_1(sc, ENVY_MT_CTL); 2108 st |= ENVY_MT_CTL_RSTART(sc); 2109 envy_mt_write_1(sc, ENVY_MT_CTL, st); 2110 mtx_leave(&audio_lock); 2111 return 0; 2112 } 2113 2114 int 2115 envy_halt_output(void *self) 2116 { 2117 struct envy_softc *sc = (struct envy_softc *)self; 2118 int err; 2119 2120 mtx_enter(&audio_lock); 2121 sc->oactive = 0; 2122 if (sc->obusy) { 2123 err = msleep(&sc->obusy, &audio_lock, PWAIT, "envyobus", 4 * hz); 2124 if (err) 2125 printf("%s: output DMA halt timeout\n", DEVNAME(sc)); 2126 } 2127 #ifdef ENVY_DEBUG 2128 if (!sc->iactive) 2129 envy_pintr(sc); 2130 #endif 2131 mtx_leave(&audio_lock); 2132 return 0; 2133 } 2134 2135 int 2136 envy_halt_input(void *self) 2137 { 2138 struct envy_softc *sc = (struct envy_softc *)self; 2139 int err; 2140 2141 mtx_enter(&audio_lock); 2142 sc->iactive = 0; 2143 if (sc->ibusy) { 2144 err = msleep(&sc->ibusy, &audio_lock, PWAIT, "envyibus", 4 * hz); 2145 if (err) 2146 printf("%s: input DMA halt timeout\n", DEVNAME(sc)); 2147 } 2148 #ifdef ENVY_DEBUG 2149 if (!sc->oactive) 2150 envy_pintr(sc); 2151 #endif 2152 mtx_leave(&audio_lock); 2153 return 0; 2154 } 2155 2156 int 2157 envy_getdev(void *self, struct audio_device *dev) 2158 { 2159 struct envy_softc *sc = (struct envy_softc *)self; 2160 2161 strlcpy(dev->name, sc->isht ? "Envy24HT" : "Envy24", MAX_AUDIO_DEV_LEN); 2162 strlcpy(dev->version, "-", MAX_AUDIO_DEV_LEN); 2163 strlcpy(dev->config, sc->card->name, MAX_AUDIO_DEV_LEN); 2164 return 0; 2165 } 2166 2167 int 2168 envy_query_devinfo(void *self, struct mixer_devinfo *dev) 2169 { 2170 struct envy_softc *sc = (struct envy_softc *)self; 2171 int i, n, idx, ndev; 2172 char *classes[] = { 2173 AudioCinputs, AudioCoutputs, AudioCmonitor 2174 }; 2175 2176 if (sc->isac97) 2177 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dev)); 2178 2179 if (dev->index < 0) 2180 return ENXIO; 2181 2182 idx = dev->index; 2183 ndev = ENVY_MIX_NCLASS; 2184 dev->prev = dev->next = AUDIO_MIXER_LAST; 2185 2186 /* 2187 * classes 2188 */ 2189 if (idx < ndev) { 2190 dev->type = AUDIO_MIXER_CLASS; 2191 dev->mixer_class = idx; 2192 strlcpy(dev->label.name, classes[idx], MAX_AUDIO_DEV_LEN); 2193 return 0; 2194 } 2195 idx -= ndev; 2196 2197 /* 2198 * output.lineX_source 2199 */ 2200 ndev = sc->card->noch; 2201 if (idx < ndev) { 2202 n = 0; 2203 dev->type = AUDIO_MIXER_ENUM; 2204 dev->mixer_class = ENVY_MIX_CLASSOUT; 2205 for (i = 0; i < sc->card->nich; i++) { 2206 dev->un.e.member[n].ord = n; 2207 snprintf(dev->un.e.member[n++].label.name, 2208 MAX_AUDIO_DEV_LEN, AudioNline "%d", i); 2209 } 2210 dev->un.e.member[n].ord = n; 2211 snprintf(dev->un.e.member[n++].label.name, 2212 MAX_AUDIO_DEV_LEN, "play%d", idx); 2213 if (!sc->isht && idx < 2) { 2214 dev->un.e.member[n].ord = n; 2215 snprintf(dev->un.e.member[n++].label.name, 2216 MAX_AUDIO_DEV_LEN, "mon%d", idx); 2217 } 2218 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 2219 "line%u_" AudioNsource, idx); 2220 dev->un.s.num_mem = n; 2221 return 0; 2222 } 2223 idx -= ndev; 2224 2225 /* 2226 * envy monitor level 2227 */ 2228 ndev = sc->isht ? 0 : ENVY_MIX_NMONITOR; 2229 if (idx < ndev) { 2230 dev->type = AUDIO_MIXER_VALUE; 2231 dev->mixer_class = ENVY_MIX_CLASSMON; 2232 dev->un.v.delta = 2; 2233 dev->un.v.num_channels = 1; 2234 snprintf(dev->label.name, MAX_AUDIO_DEV_LEN, 2235 "%s%d", idx < 10 ? "play" : "rec", idx % 10); 2236 strlcpy(dev->un.v.units.name, AudioNvolume, MAX_AUDIO_DEV_LEN); 2237 return 0; 2238 } 2239 idx -= ndev; 2240 2241 /* 2242 * inputs.xxx 2243 */ 2244 ndev = sc->card->adc->ndev(sc); 2245 if (idx < ndev) { 2246 sc->card->adc->devinfo(sc, dev, idx); 2247 return 0; 2248 } 2249 idx -= ndev; 2250 2251 /* 2252 * outputs.xxx 2253 */ 2254 ndev = sc->card->dac->ndev(sc); 2255 if (idx < ndev) { 2256 sc->card->dac->devinfo(sc, dev, idx); 2257 return 0; 2258 } 2259 return ENXIO; 2260 } 2261 2262 int 2263 envy_get_port(void *self, struct mixer_ctrl *ctl) 2264 { 2265 struct envy_softc *sc = (struct envy_softc *)self; 2266 int val, idx, ndev; 2267 2268 if (sc->isac97) 2269 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, ctl)); 2270 2271 if (ctl->dev < ENVY_MIX_NCLASS) { 2272 return EINVAL; 2273 } 2274 2275 idx = ctl->dev - ENVY_MIX_NCLASS; 2276 ndev = sc->card->noch; 2277 if (idx < ndev) { 2278 ctl->un.ord = envy_lineout_getsrc(sc, idx); 2279 if (ctl->un.ord >= ENVY_MIX_NOUTSRC) 2280 ctl->un.ord -= ENVY_MIX_NOUTSRC - sc->card->nich; 2281 return 0; 2282 } 2283 idx -= ndev; 2284 ndev = sc->isht ? 0 : ENVY_MIX_NMONITOR; 2285 if (idx < ndev) { 2286 envy_mon_getvol(sc, idx / 2, idx % 2, &val); 2287 ctl->un.value.num_channels = 1; 2288 ctl->un.value.level[0] = 2 * val; 2289 return 0; 2290 } 2291 idx -= ndev; 2292 ndev = sc->card->adc->ndev(sc); 2293 if (idx < ndev) { 2294 sc->card->adc->get(sc, ctl, idx); 2295 return 0; 2296 } 2297 idx -= ndev; 2298 ndev = sc->card->dac->ndev(sc); 2299 if (idx < ndev) { 2300 sc->card->dac->get(sc, ctl, idx); 2301 return 0; 2302 } 2303 return ENXIO; 2304 } 2305 2306 int 2307 envy_set_port(void *self, struct mixer_ctrl *ctl) 2308 { 2309 struct envy_softc *sc = (struct envy_softc *)self; 2310 int maxsrc, val, idx, ndev; 2311 2312 if (sc->isac97) 2313 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, ctl)); 2314 2315 if (ctl->dev < ENVY_MIX_NCLASS) { 2316 return EINVAL; 2317 } 2318 2319 idx = ctl->dev - ENVY_MIX_NCLASS; 2320 ndev = sc->card->noch; 2321 if (idx < ndev) { 2322 maxsrc = sc->card->nich + 1; 2323 if (idx < 2) 2324 maxsrc++; 2325 if (ctl->un.ord < 0 || ctl->un.ord >= maxsrc) 2326 return EINVAL; 2327 if (ctl->un.ord >= sc->card->nich) 2328 ctl->un.ord += ENVY_MIX_NOUTSRC - sc->card->nich; 2329 envy_lineout_setsrc(sc, idx, ctl->un.ord); 2330 return 0; 2331 } 2332 idx -= ndev; 2333 ndev = sc->isht ? 0 : ENVY_MIX_NMONITOR; 2334 if (idx < ndev) { 2335 if (ctl->un.value.num_channels != 1) { 2336 return EINVAL; 2337 } 2338 val = ctl->un.value.level[0] / 2; 2339 envy_mon_setvol(sc, idx / 2, idx % 2, val); 2340 return 0; 2341 } 2342 idx -= ndev; 2343 ndev = sc->card->adc->ndev(sc); 2344 if (idx < ndev) 2345 return sc->card->adc->set(sc, ctl, idx); 2346 idx -= ndev; 2347 ndev = sc->card->dac->ndev(sc); 2348 if (idx < ndev) 2349 return sc->card->dac->set(sc, ctl, idx); 2350 return ENXIO; 2351 } 2352 2353 int 2354 envy_get_props(void *self) 2355 { 2356 return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT; 2357 } 2358 2359 #if NMIDI > 0 2360 int 2361 envy_midi_open(void *self, int flags, 2362 void (*in)(void *, int), 2363 void (*out)(void *), 2364 void *arg) 2365 { 2366 struct envy_softc *sc = (struct envy_softc *)self; 2367 2368 mtx_enter(&audio_lock); 2369 sc->midi_in = in; 2370 sc->midi_out = out; 2371 sc->midi_arg = arg; 2372 mtx_leave(&audio_lock); 2373 return 0; 2374 } 2375 2376 void 2377 envy_midi_close(void *self) 2378 { 2379 struct envy_softc *sc = (struct envy_softc *)self; 2380 2381 tsleep(sc, PWAIT, "envymid", hz / 10); 2382 mtx_enter(&audio_lock); 2383 sc->midi_in = NULL; 2384 sc->midi_out = NULL; 2385 mtx_leave(&audio_lock); 2386 } 2387 2388 int 2389 envy_midi_output(void *self, int data) 2390 { 2391 struct envy_softc *sc = (struct envy_softc *)self; 2392 int st; 2393 2394 st = envy_ccs_read(sc, ENVY_CCS_MIDISTAT0); 2395 if (st & ENVY_MIDISTAT_OBUSY(sc)) 2396 return 0; 2397 envy_ccs_write(sc, ENVY_CCS_MIDIDATA0, data); 2398 return 1; 2399 } 2400 2401 void 2402 envy_midi_getinfo(void *self, struct midi_info *mi) 2403 { 2404 mi->props = MIDI_PROP_CAN_INPUT; 2405 mi->name = "Envy24 MIDI UART"; 2406 } 2407 #endif 2408