1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Purpose: Driver for the CMedia 8788 sound card 29 */ 30 /* 31 * 32 * Copyright (C) 4Front Technologies 1996-2011. 33 * 34 * This software is released under CDDL 1.0 source license. 35 * See the COPYING file included in the main directory of this source 36 * distribution for the license terms and conditions. 37 */ 38 39 #include <sys/types.h> 40 #include <sys/modctl.h> 41 #include <sys/kmem.h> 42 #include <sys/conf.h> 43 #include <sys/ddi.h> 44 #include <sys/sunddi.h> 45 #include <sys/pci.h> 46 #include <sys/sysmacros.h> 47 #include <sys/note.h> 48 #include <sys/audio/audio_driver.h> 49 #include <sys/audio/ac97.h> 50 51 #include "audiocmihd.h" 52 53 static struct ddi_device_acc_attr dev_attr = { 54 DDI_DEVICE_ATTR_V0, 55 DDI_STRUCTURE_LE_ACC, 56 DDI_STRICTORDER_ACC 57 }; 58 59 static struct ddi_device_acc_attr buf_attr = { 60 DDI_DEVICE_ATTR_V0, 61 DDI_NEVERSWAP_ACC, 62 DDI_STRICTORDER_ACC 63 }; 64 65 static ddi_dma_attr_t dma_attr_buf = { 66 DMA_ATTR_V0, /* version number */ 67 0x0, /* dma_attr_addr_lo */ 68 0xffffffffU, /* dma_attr_addr_hi */ 69 0x3ffff, /* dma_attr_count_max */ 70 0x8, /* dma_attr_align */ 71 0x7f, /* dma_attr_burstsizes */ 72 0x1, /* dma_attr_minxfer */ 73 0x3ffff, /* dma_attr_maxxfer */ 74 0x3ffff, /* dma_attr_seg */ 75 0x1, /* dma_attr_sgllen */ 76 0x1, /* dma_attr_granular */ 77 0 /* dma_attr_flags */ 78 }; 79 80 81 static int cmediahd_attach(dev_info_t *); 82 static int cmediahd_resume(dev_info_t *); 83 static int cmediahd_detach(cmediahd_devc_t *); 84 static int cmediahd_suspend(cmediahd_devc_t *); 85 86 static int cmediahd_open(void *, int, unsigned *, caddr_t *); 87 static void cmediahd_close(void *); 88 static int cmediahd_start(void *); 89 static void cmediahd_stop(void *); 90 static int cmediahd_format(void *); 91 static int cmediahd_channels(void *); 92 static int cmediahd_rate(void *); 93 static uint64_t cmediahd_count(void *); 94 static void cmediahd_sync(void *, unsigned); 95 static void cmediahd_chinfo(void *, int, unsigned *, unsigned *); 96 97 98 static uint16_t cmediahd_read_ac97(void *, uint8_t); 99 static void cmediahd_write_ac97(void *, uint8_t, uint16_t); 100 static int cmediahd_alloc_port(cmediahd_devc_t *, int); 101 static void cmediahd_reset_port(cmediahd_portc_t *); 102 static void cmediahd_destroy(cmediahd_devc_t *); 103 static void cmediahd_hwinit(cmediahd_devc_t *); 104 static void cmediahd_refresh_mixer(cmediahd_devc_t *devc); 105 static uint32_t mix_scale(uint32_t, int8_t); 106 static void cmediahd_ac97_hwinit(cmediahd_devc_t *); 107 static void cmediahd_del_controls(cmediahd_devc_t *); 108 109 110 static audio_engine_ops_t cmediahd_engine_ops = { 111 AUDIO_ENGINE_VERSION, 112 cmediahd_open, 113 cmediahd_close, 114 cmediahd_start, 115 cmediahd_stop, 116 cmediahd_count, 117 cmediahd_format, 118 cmediahd_channels, 119 cmediahd_rate, 120 cmediahd_sync, 121 NULL, /* qlen */ 122 cmediahd_chinfo, 123 NULL /* playahead */ 124 }; 125 126 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 127 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 128 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 129 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 130 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 131 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 132 133 static const char mix_cvt[101] = { 134 0, 0, 3, 7, 10, 13, 16, 19, 135 21, 23, 26, 28, 30, 32, 34, 35, 136 37, 39, 40, 42, 43, 45, 46, 47, 137 49, 50, 51, 52, 53, 55, 56, 57, 138 58, 59, 60, 61, 62, 63, 64, 65, 139 65, 66, 67, 68, 69, 70, 70, 71, 140 72, 73, 73, 74, 75, 75, 76, 77, 141 77, 78, 79, 79, 80, 81, 81, 82, 142 82, 83, 84, 84, 85, 85, 86, 86, 143 87, 87, 88, 88, 89, 89, 90, 90, 144 91, 91, 92, 92, 93, 93, 94, 94, 145 95, 95, 96, 96, 96, 97, 97, 98, 146 98, 98, 99, 99, 100 147 }; 148 149 static uint32_t 150 mix_scale(uint32_t vol, int8_t bits) 151 { 152 vol = mix_cvt[vol]; 153 vol = (vol * ((1 << bits) - 1)) / 100; 154 return (vol); 155 } 156 157 static uint16_t 158 cmediahd_read_ac97(void *arg, uint8_t reg) 159 { 160 cmediahd_devc_t *devc = arg; 161 uint32_t val; 162 uint16_t data; 163 164 mutex_enter(&devc->low_mutex); 165 val = 0L; 166 val |= reg << 16; 167 val |= 0 << 24; /* codec 0 or codec 1 */ 168 val |= 1 << 23; /* ac97 read the reg address */ 169 OUTL(devc, val, AC97_CMD_DATA); 170 drv_usecwait(100); 171 data = INL(devc, AC97_CMD_DATA) & 0xFFFF; 172 mutex_exit(&devc->low_mutex); 173 return (data); 174 } 175 176 static void 177 cmediahd_write_ac97(void *arg, uint8_t reg, uint16_t data) 178 { 179 cmediahd_devc_t *devc = arg; 180 uint32_t val; 181 182 mutex_enter(&devc->low_mutex); 183 val = 0L; 184 val |= reg << 16; 185 val |= data & 0xFFFF; 186 val |= 0 << 24; /* on board codec or frontpanel */ 187 val |= 0 << 23; /* ac97 write operation */ 188 OUTL(devc, val, AC97_CMD_DATA); 189 drv_usecwait(100); 190 mutex_exit(&devc->low_mutex); 191 } 192 193 #if 0 /* Front Panel AC'97 not supported yet */ 194 static uint16_t 195 cmediahd_read_fp_ac97(void *arg, uint8_t reg) 196 { 197 cmediahd_devc_t *devc = arg; 198 uint32_t val; 199 uint16_t data; 200 201 mutex_enter(&devc->low_mutex); 202 val = 0L; 203 val |= 1 << 24; /* front panel */ 204 val |= 1 << 23; /* ac97 read the reg address */ 205 val |= reg << 16; 206 OUTL(devc, val, AC97_CMD_DATA); 207 drv_usecwait(100); 208 data = INL(devc, AC97_CMD_DATA) & 0xFFFF; 209 mutex_exit(&devc->low_mutex); 210 211 return (data); 212 } 213 214 static void 215 cmediahd_write_fp_ac97(void *arg, uint8_t reg, uint16_t data) 216 { 217 cmediahd_devc_t *devc = arg; 218 uint32_t val; 219 220 mutex_enter(&devc->low_mutex); 221 val = 0L; 222 val |= 1 << 24; /* frontpanel */ 223 val |= 0 << 23; /* ac97 write operation */ 224 val |= reg << 16; 225 val |= data & 0xFFFF; 226 OUTL(devc, val, AC97_CMD_DATA); 227 drv_usecwait(100); 228 mutex_exit(&devc->low_mutex); 229 } 230 #endif 231 232 static void 233 spi_write(void *arg, int codec_num, unsigned char reg, int val) 234 { 235 cmediahd_devc_t *devc = arg; 236 unsigned int tmp; 237 int latch, shift, count; 238 239 mutex_enter(&devc->low_mutex); 240 241 /* check if SPI is busy */ 242 count = 10; 243 while ((INB(devc, SPI_CONTROL) & 0x1) && count-- > 0) { 244 drv_usecwait(10); 245 } 246 247 if (devc->model == SUBID_XONAR_DS) { 248 shift = 9; 249 latch = 0; 250 } else { 251 shift = 8; 252 latch = 0x80; 253 } 254 255 /* 2 byte data/reg info to be written */ 256 tmp = val; 257 tmp |= (reg << shift); 258 259 /* write 2-byte data values */ 260 OUTB(devc, tmp & 0xff, SPI_DATA + 0); 261 OUTB(devc, (tmp >> 8) & 0xff, SPI_DATA + 1); 262 263 /* Latch high, clock=160, Len=2byte, mode=write */ 264 tmp = (INB(devc, SPI_CONTROL) & ~0x7E) | latch | 0x1; 265 266 /* now address which codec you want to send the data to */ 267 tmp |= (codec_num << 4); 268 269 /* send the command to write the data */ 270 OUTB(devc, tmp, SPI_CONTROL); 271 272 mutex_exit(&devc->low_mutex); 273 } 274 275 static void 276 i2c_write(void *arg, unsigned char codec_num, unsigned char reg, 277 unsigned char data) 278 { 279 cmediahd_devc_t *devc = arg; 280 int count = 50; 281 282 /* Wait for it to stop being busy */ 283 mutex_enter(&devc->low_mutex); 284 while ((INW(devc, TWO_WIRE_CTRL) & 0x1) && (count > 0)) { 285 drv_usecwait(10); 286 count--; 287 } 288 289 if (count == 0) { 290 audio_dev_warn(devc->adev, "Time out on Two-Wire interface"); 291 mutex_exit(&devc->low_mutex); 292 return; 293 } 294 295 /* first write the Register Address into the MAP register */ 296 OUTB(devc, reg, TWO_WIRE_MAP); 297 298 /* now write the data */ 299 OUTB(devc, data, TWO_WIRE_DATA); 300 301 /* select the codec number to address */ 302 OUTB(devc, codec_num, TWO_WIRE_ADDR); 303 304 mutex_exit(&devc->low_mutex); 305 } 306 307 static void 308 cs4398_init(void *arg, int codec) 309 { 310 cmediahd_devc_t *devc = arg; 311 312 /* Fast Two-Wire. Reduces the wire ready time. */ 313 OUTW(devc, 0x0100, TWO_WIRE_CTRL); 314 315 /* Power down, enable control mode. */ 316 i2c_write(devc, codec, CS4398_MISC_CTRL, 317 CS4398_CPEN | CS4398_POWER_DOWN); 318 /* 319 * Left justified PCM (DAC and 8788 support I2S, but doesn't work. 320 * Setting it introduces clipping like hell). 321 */ 322 i2c_write(devc, codec, CS4398_MODE_CTRL, 0x00); 323 i2c_write(devc, codec, 3, 0x09); 324 i2c_write(devc, codec, 4, 0x82); /* PCM Automute */ 325 i2c_write(devc, codec, 5, 0x80); /* Vol A+B to -64dB */ 326 i2c_write(devc, codec, 6, 0x80); 327 i2c_write(devc, codec, 7, 0xf0); /* soft ramping on */ 328 329 /* remove the powerdown flag */ 330 i2c_write(devc, codec, CS4398_MISC_CTRL, CS4398_CPEN); 331 } 332 333 334 static void 335 cs4362a_init(void *arg, int codec) 336 { 337 338 cmediahd_devc_t *devc = arg; 339 340 OUTW(devc, 0x0100, TWO_WIRE_CTRL); 341 342 /* Power down and enable control port. */ 343 i2c_write(devc, codec, CS4362A_MODE1_CTRL, 344 CS4362A_CPEN | CS4362A_POWER_DOWN); 345 /* Left-justified PCM */ 346 i2c_write(devc, codec, CS4362A_MODE2_CTRL, CS4362A_DIF_LJUST); 347 /* Ramp & Automute, re-set DAC defaults. */ 348 i2c_write(devc, codec, CS4362A_MODE3_CTRL, 0x84); 349 /* Filter control, DAC defs. */ 350 i2c_write(devc, codec, CS4362A_FILTER_CTRL, 0); 351 /* Invert control, DAC defs. */ 352 i2c_write(devc, codec, CS4362A_INVERT_CTRL, 0); 353 /* Mixing control, DAC defs. */ 354 i2c_write(devc, codec, CS4362A_MIX1_CTRL, 0x24); 355 i2c_write(devc, codec, CS4362A_MIX2_CTRL, 0x24); 356 i2c_write(devc, codec, CS4362A_MIX3_CTRL, 0x24); 357 /* Volume to -64dB. */ 358 i2c_write(devc, codec, CS4362A_VOLA_1, 0x40); 359 i2c_write(devc, codec, CS4362A_VOLB_1, 0x40); 360 i2c_write(devc, codec, CS4362A_VOLA_2, 0x40); 361 i2c_write(devc, codec, CS4362A_VOLB_2, 0x40); 362 i2c_write(devc, codec, CS4362A_VOLA_3, 0x40); 363 i2c_write(devc, codec, CS4362A_VOLB_3, 0x40); 364 /* Power up. */ 365 i2c_write(devc, codec, CS4362A_MODE1_CTRL, CS4362A_CPEN); 366 } 367 368 369 static void 370 cmediahd_generic_set_play_volume(cmediahd_devc_t *devc, int codec_id, 371 int left, int right) 372 { 373 spi_write(devc, codec_id, AK4396_LchATTCtl | 0x20, mix_scale(left, 8)); 374 spi_write(devc, codec_id, AK4396_RchATTCtl | 0x20, mix_scale(right, 8)); 375 } 376 377 static void 378 xonar_d1_set_play_volume(cmediahd_devc_t *devc, int codec_id, 379 int left, int right) 380 { 381 switch (codec_id) { 382 case 0: 383 i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLA, 384 CS4398_VOL(left)); 385 i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLB, 386 CS4398_VOL(right)); 387 break; 388 case 1: 389 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_1, 390 CS4362A_VOL(left)); 391 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_1, 392 CS4362A_VOL(right)); 393 break; 394 case 2: 395 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_2, 396 CS4362A_VOL(left)); 397 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_2, 398 CS4362A_VOL(right)); 399 break; 400 case 3: 401 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_3, 402 CS4362A_VOL(left)); 403 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_3, 404 CS4362A_VOL(right)); 405 break; 406 } 407 } 408 409 static void 410 xonar_d2_set_play_volume(cmediahd_devc_t *devc, int codec_id, 411 int left, int right) 412 { 413 spi_write(devc, xd2_codec_map[codec_id], 16, mix_scale(left, 8)); 414 spi_write(devc, xd2_codec_map[codec_id], 17, mix_scale(right, 8)); 415 } 416 417 static void 418 xonar_stx_set_play_volume(cmediahd_devc_t *devc, int codec_id, 419 int left, int right) 420 { 421 if (codec_id == 0) { 422 i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(left, 8)); 423 i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(right, 8)); 424 } 425 } 426 427 static void 428 xonar_ds_set_play_volume(cmediahd_devc_t *devc, int codec_id, 429 int left, int right) 430 { 431 switch (codec_id) { 432 case 0: /* front */ 433 spi_write(devc, XONAR_DS_FRONTDAC, 0, 434 mix_scale(left, 7) | 0x180); 435 spi_write(devc, XONAR_DS_FRONTDAC, 1, 436 mix_scale(right, 7) | 0x180); 437 spi_write(devc, XONAR_DS_FRONTDAC, 3, 438 mix_scale(left, 7) |0x180); 439 spi_write(devc, XONAR_DS_FRONTDAC, 4, 440 mix_scale(right, 7) | 0x180); 441 break; 442 443 case 1: /* side */ 444 spi_write(devc, XONAR_DS_SURRDAC, 0, 445 mix_scale(left, 7) | 0x180); 446 spi_write(devc, XONAR_DS_SURRDAC, 1, 447 mix_scale(right, 7) | 0x180); 448 break; 449 case 2: /* rear */ 450 spi_write(devc, XONAR_DS_SURRDAC, 4, 451 mix_scale(left, 7) | 0x180); 452 spi_write(devc, XONAR_DS_SURRDAC, 5, 453 mix_scale(right, 7) | 0x180); 454 break; 455 case 3: /* center */ 456 spi_write(devc, XONAR_DS_SURRDAC, 6, 457 mix_scale(left, 7) | 0x180); 458 spi_write(devc, XONAR_DS_SURRDAC, 7, 459 mix_scale(right, 7) | 0x180); 460 break; 461 } 462 } 463 464 static void 465 cmediahd_set_rec_volume(cmediahd_devc_t *devc, int value) 466 { 467 unsigned char left, right; 468 469 left = (value >> 8) & 0xff; 470 right = value & 0xff; 471 472 if (left > 100) 473 left = 100; 474 if (right > 100) 475 right = 100; 476 477 spi_write(devc, XONAR_DS_FRONTDAC, 0xe, mix_scale(left, 8)); 478 spi_write(devc, XONAR_DS_FRONTDAC, 0xf, mix_scale(right, 8)); 479 } 480 481 static void 482 cmediahd_set_play_volume(cmediahd_devc_t *devc, int codec_id, int value) 483 { 484 int left, right; 485 486 left = (value >> 8) & 0xFF; 487 right = (value & 0xFF); 488 489 if (left > 100) 490 left = 100; 491 if (right > 100) 492 right = 100; 493 494 switch (devc->model) { 495 case SUBID_XONAR_D1: 496 case SUBID_XONAR_DX: 497 xonar_d1_set_play_volume(devc, codec_id, left, right); 498 break; 499 case SUBID_XONAR_D2: 500 case SUBID_XONAR_D2X: 501 xonar_d2_set_play_volume(devc, codec_id, left, right); 502 break; 503 case SUBID_XONAR_STX: 504 xonar_stx_set_play_volume(devc, codec_id, left, right); 505 break; 506 case SUBID_XONAR_DS: 507 xonar_ds_set_play_volume(devc, codec_id, left, right); 508 break; 509 default: 510 cmediahd_generic_set_play_volume(devc, codec_id, left, right); 511 break; 512 } 513 } 514 515 /* 516 * Audio routines 517 */ 518 519 int 520 cmediahd_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp) 521 { 522 cmediahd_portc_t *portc = arg; 523 524 _NOTE(ARGUNUSED(flag)); 525 526 portc->count = 0; 527 528 *nframesp = portc->nframes; 529 *bufp = portc->kaddr; 530 531 return (0); 532 } 533 534 void 535 cmediahd_close(void *arg) 536 { 537 _NOTE(ARGUNUSED(arg)); 538 } 539 540 int 541 cmediahd_start(void *arg) 542 { 543 cmediahd_portc_t *portc = arg; 544 cmediahd_devc_t *devc = portc->devc; 545 546 mutex_enter(&devc->mutex); 547 portc->offset = 0; 548 549 cmediahd_reset_port(portc); 550 551 switch (portc->direction) { 552 case CMEDIAHD_PLAY: 553 /* enable the dma */ 554 OUTW(devc, INW(devc, DMA_START) | 0x10, DMA_START); 555 break; 556 557 case CMEDIAHD_REC: 558 /* enable the channel */ 559 OUTW(devc, INW(devc, DMA_START) | (1<<devc->rec_eng.chan), 560 DMA_START); 561 break; 562 } 563 564 mutex_exit(&devc->mutex); 565 return (0); 566 } 567 568 void 569 cmediahd_stop(void *arg) 570 { 571 cmediahd_portc_t *portc = arg; 572 cmediahd_devc_t *devc = portc->devc; 573 574 mutex_enter(&devc->mutex); 575 switch (portc->direction) { 576 case CMEDIAHD_PLAY: 577 /* disable dma */ 578 OUTW(devc, INW(devc, DMA_START) & ~0x10, DMA_START); 579 break; 580 581 case CMEDIAHD_REC: 582 /* disable dma */ 583 OUTW(devc, INW(devc, DMA_START) & ~(1<<devc->rec_eng.chan), 584 DMA_START); 585 break; 586 } 587 mutex_exit(&devc->mutex); 588 } 589 590 int 591 cmediahd_format(void *arg) 592 { 593 _NOTE(ARGUNUSED(arg)); 594 595 return (AUDIO_FORMAT_S16_LE); 596 } 597 598 int 599 cmediahd_channels(void *arg) 600 { 601 cmediahd_portc_t *portc = arg; 602 603 return (portc->chans); 604 } 605 606 int 607 cmediahd_rate(void *arg) 608 { 609 _NOTE(ARGUNUSED(arg)); 610 611 return (48000); 612 } 613 614 void 615 cmediahd_sync(void *arg, unsigned nframes) 616 { 617 cmediahd_portc_t *portc = arg; 618 _NOTE(ARGUNUSED(nframes)); 619 620 (void) ddi_dma_sync(portc->buf_dmah, 0, 0, portc->syncdir); 621 } 622 623 static void 624 cmediahd_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 625 { 626 cmediahd_portc_t *portc = arg; 627 static const int map8ch[] = { 0, 1, 4, 5, 2, 3, 6, 7 }; 628 static const int map4ch[] = { 0, 1, 2, 3 }; 629 630 if (portc->chans <= 4) { 631 *offset = map4ch[chan]; 632 } else { 633 *offset = map8ch[chan]; 634 } 635 *incr = portc->chans; 636 } 637 638 uint64_t 639 cmediahd_count(void *arg) 640 { 641 cmediahd_portc_t *portc = arg; 642 cmediahd_devc_t *devc = portc->devc; 643 uint64_t count; 644 uint32_t offset; 645 646 mutex_enter(&devc->mutex); 647 648 if (portc->direction == CMEDIAHD_PLAY) 649 offset = portc->bufsz/4 - INL(devc, MULTICH_SIZE) + 1; 650 else 651 offset = portc->bufsz/4 - INW(devc, devc->rec_eng.size) + 1; 652 653 /* check for wrap */ 654 if (offset < portc->offset) { 655 count = ((portc->bufsz/4) - portc->offset) + offset; 656 } else { 657 count = offset - portc->offset; 658 } 659 portc->count += count; 660 portc->offset = offset; 661 662 /* convert from 16-bit stereo */ 663 count = portc->count / (portc->chans/2); 664 mutex_exit(&devc->mutex); 665 666 return (count); 667 } 668 669 /* private implementation bits */ 670 671 672 void 673 cmediahd_reset_port(cmediahd_portc_t *portc) 674 { 675 cmediahd_devc_t *devc = portc->devc; 676 int channels; 677 678 if (devc->suspended) 679 return; 680 681 portc->offset = 0; 682 683 switch (portc->direction) { 684 685 case CMEDIAHD_PLAY: 686 /* reset channel */ 687 OUTB(devc, INB(devc, CHAN_RESET)|0x10, CHAN_RESET); 688 drv_usecwait(10); 689 OUTB(devc, INB(devc, CHAN_RESET) & ~0x10, CHAN_RESET); 690 drv_usecwait(10); 691 692 OUTL(devc, portc->paddr, MULTICH_ADDR); 693 OUTL(devc, (portc->bufsz/4) - 1, MULTICH_SIZE); 694 OUTL(devc, (portc->bufsz/4) - 1, MULTICH_FRAG); 695 696 switch (portc->chans) { 697 case 2: 698 channels = 0; 699 break; 700 case 4: 701 channels = 1; 702 break; 703 case 6: 704 channels = 2; 705 break; 706 case 8: 707 channels = 3; 708 break; 709 default: 710 channels = 0x0; 711 break; 712 } 713 OUTB(devc, (INB(devc, MULTICH_MODE) & ~0x3) | channels, 714 MULTICH_MODE); 715 716 /* set the format bits in play format register */ 717 OUTB(devc, (INB(devc, PLAY_FORMAT) & ~0xC) | 0x0, PLAY_FORMAT); 718 break; 719 720 case CMEDIAHD_REC: 721 OUTB(devc, INB(devc, CHAN_RESET) | (1 << devc->rec_eng.chan), 722 CHAN_RESET); 723 drv_usecwait(10); 724 OUTB(devc, INB(devc, CHAN_RESET) & ~(1 << devc->rec_eng.chan), 725 CHAN_RESET); 726 drv_usecwait(10); 727 728 OUTL(devc, portc->paddr, devc->rec_eng.addr); 729 OUTW(devc, (portc->bufsz/4) - 1, devc->rec_eng.size); 730 OUTW(devc, (portc->bufsz/4) - 1, devc->rec_eng.frag); 731 732 733 switch (portc->chans) { 734 case 2: 735 channels = 0x0; 736 break; 737 case 4: 738 channels = 0x1; 739 break; 740 case 6: 741 channels = 0x2; 742 break; 743 case 8: 744 channels = 0x4; 745 break; 746 default: 747 /* Stereo - boomer only supports stereo */ 748 channels = 0x0; 749 break; 750 } 751 752 OUTB(devc, (INB(devc, REC_MODE) & ~0x3) | channels, REC_MODE); 753 OUTB(devc, (INB(devc, REC_FORMAT) & ~0x3) | 0x0, REC_FORMAT); 754 755 } 756 } 757 758 int 759 cmediahd_alloc_port(cmediahd_devc_t *devc, int num) 760 { 761 cmediahd_portc_t *portc; 762 size_t len; 763 ddi_dma_cookie_t cookie; 764 uint_t count; 765 int dir; 766 unsigned caps; 767 audio_dev_t *adev; 768 769 adev = devc->adev; 770 portc = kmem_zalloc(sizeof (*portc), KM_SLEEP); 771 devc->portc[num] = portc; 772 portc->devc = devc; 773 portc->direction = num; 774 775 switch (num) { 776 case CMEDIAHD_REC: 777 portc->syncdir = DDI_DMA_SYNC_FORKERNEL; 778 portc->chans = 2; 779 caps = ENGINE_INPUT_CAP; 780 dir = DDI_DMA_READ; 781 break; 782 case CMEDIAHD_PLAY: 783 portc->syncdir = DDI_DMA_SYNC_FORDEV; 784 portc->chans = 8; 785 caps = ENGINE_OUTPUT_CAP; 786 dir = DDI_DMA_WRITE; 787 break; 788 default: 789 return (DDI_FAILURE); 790 } 791 792 /* 793 * Calculate buffer size and frames 794 */ 795 portc->nframes = 2048; 796 portc->bufsz = portc->nframes * portc->chans * 2; 797 798 /* Alloc buffers */ 799 if (ddi_dma_alloc_handle(devc->dip, &dma_attr_buf, DDI_DMA_SLEEP, NULL, 800 &portc->buf_dmah) != DDI_SUCCESS) { 801 audio_dev_warn(adev, "failed to allocate BUF handle"); 802 return (DDI_FAILURE); 803 } 804 805 if (ddi_dma_mem_alloc(portc->buf_dmah, CMEDIAHD_BUF_LEN, 806 &buf_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 807 &portc->kaddr, &len, &portc->buf_acch) != DDI_SUCCESS) { 808 audio_dev_warn(adev, "failed to allocate BUF memory"); 809 return (DDI_FAILURE); 810 } 811 812 bzero(portc->kaddr, len); 813 814 if (ddi_dma_addr_bind_handle(portc->buf_dmah, NULL, portc->kaddr, 815 len, DDI_DMA_CONSISTENT | dir, DDI_DMA_SLEEP, NULL, &cookie, 816 &count) != DDI_SUCCESS) { 817 audio_dev_warn(adev, "failed binding BUF DMA handle"); 818 return (DDI_FAILURE); 819 } 820 portc->paddr = cookie.dmac_address; 821 822 portc->engine = audio_engine_alloc(&cmediahd_engine_ops, caps); 823 if (portc->engine == NULL) { 824 audio_dev_warn(adev, "audio_engine_alloc failed"); 825 return (DDI_FAILURE); 826 } 827 828 audio_engine_set_private(portc->engine, portc); 829 audio_dev_add_engine(adev, portc->engine); 830 831 return (DDI_SUCCESS); 832 } 833 834 void 835 cmediahd_destroy(cmediahd_devc_t *devc) 836 { 837 mutex_destroy(&devc->mutex); 838 mutex_destroy(&devc->low_mutex); 839 840 for (int i = 0; i < CMEDIAHD_NUM_PORTC; i++) { 841 cmediahd_portc_t *portc = devc->portc[i]; 842 if (!portc) 843 continue; 844 if (portc->engine) { 845 audio_dev_remove_engine(devc->adev, portc->engine); 846 audio_engine_free(portc->engine); 847 } 848 if (portc->paddr) { 849 (void) ddi_dma_unbind_handle(portc->buf_dmah); 850 } 851 if (portc->buf_acch) { 852 ddi_dma_mem_free(&portc->buf_acch); 853 } 854 if (portc->buf_dmah) { 855 ddi_dma_free_handle(&portc->buf_dmah); 856 } 857 kmem_free(portc, sizeof (*portc)); 858 } 859 860 if (devc->ac97) { 861 ac97_free(devc->ac97); 862 } 863 864 cmediahd_del_controls(devc); 865 866 if (devc->adev != NULL) { 867 audio_dev_free(devc->adev); 868 } 869 if (devc->regsh != NULL) { 870 ddi_regs_map_free(&devc->regsh); 871 } 872 if (devc->pcih != NULL) { 873 pci_config_teardown(&devc->pcih); 874 } 875 kmem_free(devc, sizeof (*devc)); 876 } 877 878 void 879 cmediahd_ac97_hwinit(cmediahd_devc_t *devc) 880 { 881 /* GPIO #0 programmed as output, set CMI9780 Reg0x70 */ 882 cmediahd_write_ac97(devc, 0x70, 0x100); 883 884 /* LI2LI,MIC2MIC; let them always on, FOE on, ROE/BKOE/CBOE off */ 885 cmediahd_write_ac97(devc, 0x62, 0x180F); 886 887 /* unmute Master Volume */ 888 cmediahd_write_ac97(devc, 0x02, 0x0); 889 890 /* change PCBeep path, set Mix2FR on, option for quality issue */ 891 cmediahd_write_ac97(devc, 0x64, 0x8043); 892 893 /* mute PCBeep, option for quality issues */ 894 cmediahd_write_ac97(devc, 0x0A, 0x8000); 895 896 /* Record Select Control Register (Index 1Ah) */ 897 cmediahd_write_ac97(devc, 0x1A, 0x0000); 898 899 /* set Mic Volume Register 0x0Eh umute and enable micboost */ 900 cmediahd_write_ac97(devc, 0x0E, 0x0848); 901 902 /* set Line in Volume Register 0x10h mute */ 903 cmediahd_write_ac97(devc, 0x10, 0x8808); 904 905 /* set CD Volume Register 0x12h mute */ 906 cmediahd_write_ac97(devc, 0x12, 0x8808); 907 908 /* set AUX Volume Register 0x16h max */ 909 cmediahd_write_ac97(devc, 0x16, 0x0808); 910 911 /* set record gain Register 0x1Ch to max */ 912 cmediahd_write_ac97(devc, 0x1C, 0x0F0F); 913 914 /* GPIO status register enable GPO0 */ 915 cmediahd_write_ac97(devc, 0x72, 0x0001); 916 } 917 void 918 cmediahd_hwinit(cmediahd_devc_t *devc) 919 { 920 921 unsigned short sVal; 922 unsigned short i2s_fmt; 923 unsigned char bVal; 924 int i, count; 925 926 /* setup the default rec DMA engines to REC_A */ 927 devc->rec_eng.addr = RECA_ADDR; 928 devc->rec_eng.size = RECA_SIZE; 929 devc->rec_eng.frag = RECA_FRAG; 930 devc->rec_eng.i2s = I2S_ADC1; 931 devc->rec_eng.chan = REC_A; 932 933 /* setup GPIOs to 0 */ 934 devc->gpio_mic = 0; 935 devc->gpio_out = 0; 936 devc->gpio_codec = 0; 937 devc->gpio_alt = 0; 938 939 /* Init CMI Controller */ 940 sVal = INW(devc, CTRL_VERSION); 941 if (!(sVal & 0x0008)) { 942 bVal = INB(devc, MISC_REG); 943 bVal |= 0x20; 944 OUTB(devc, bVal, MISC_REG); 945 } 946 947 bVal = INB(devc, FUNCTION); 948 bVal |= 0x02; /* Reset codec */ 949 OUTB(devc, bVal, FUNCTION); 950 951 /* Cold reset onboard AC97 */ 952 OUTW(devc, 0x1, AC97_CTRL); 953 count = 100; 954 while ((INW(devc, AC97_CTRL) & 0x2) && (count--)) { 955 OUTW(devc, (INW(devc, AC97_CTRL) & ~0x2) | 0x2, AC97_CTRL); 956 drv_usecwait(100); 957 } 958 959 if (!count) 960 audio_dev_warn(devc->adev, "CMI8788 AC97 not ready"); 961 962 sVal = INW(devc, AC97_CTRL); 963 /* check if there's an onboard AC97 codec (CODEC 0) */ 964 if (sVal & 0x10) { 965 /* disable CODEC0 OUTPUT */ 966 OUTW(devc, INW(devc, AC97_OUT_CHAN_CONFIG) & ~0xFF00, 967 AC97_OUT_CHAN_CONFIG); 968 969 /* enable CODEC0 INPUT */ 970 OUTW(devc, INW(devc, AC97_IN_CHAN_CONFIG) | 0x0300, 971 AC97_IN_CHAN_CONFIG); 972 973 devc->has_ac97 = 1; 974 } 975 976 /* check if there's an front panel AC97 codec (CODEC1) */ 977 if (sVal & 0x20) { 978 /* enable CODEC1 OUTPUT */ 979 OUTW(devc, INW(devc, AC97_OUT_CHAN_CONFIG) | 0x0033, 980 AC97_OUT_CHAN_CONFIG); 981 /* enable CODEC1 INPUT */ 982 OUTW(devc, INW(devc, AC97_IN_CHAN_CONFIG) | 0x0033, 983 AC97_IN_CHAN_CONFIG); 984 985 devc->has_fp_ac97 = 1; 986 } 987 988 /* Disable AC97 interrupts and initialize AC97 */ 989 OUTB(devc, 0x0, AC97_INTR_MASK); 990 OUTW(devc, INW(devc, IRQ_MASK) & ~0x4000, IRQ_MASK); 991 992 /* I2S to 16bit/48Khz/Master, see below. */ 993 i2s_fmt = 0x011A; 994 995 /* Setup I2S to use 16bit instead of 24Bit */ 996 OUTW(devc, i2s_fmt, I2S_MULTICH_DAC); 997 OUTW(devc, i2s_fmt, I2S_ADC1); 998 OUTW(devc, i2s_fmt, I2S_ADC2); 999 OUTW(devc, i2s_fmt, I2S_ADC3); 1000 1001 /* setup Routing regs (default vals) */ 1002 OUTW(devc, 0xE400, PLAY_ROUTING); 1003 OUTB(devc, 0x00, REC_ROUTING); /* default routing set to I2S */ 1004 OUTB(devc, 0x00, REC_MONITOR); /* monitor through MULTICH_PLAY */ 1005 OUTB(devc, 0xE4, MONITOR_ROUTING); /* default monitor routing */ 1006 1007 1008 /* Enable Xonar output */ 1009 switch (devc->model) { 1010 case SUBID_XONAR_D1: 1011 case SUBID_XONAR_DX: 1012 /* GPIO8 = 0x100 controls mic/line-in */ 1013 /* GPIO0 = 0x001controls output */ 1014 /* GPIO2/3 = 0x00C codec output control */ 1015 1016 devc->rec_eng.addr = RECB_ADDR; 1017 devc->rec_eng.size = RECB_SIZE; 1018 devc->rec_eng.frag = RECB_FRAG; 1019 devc->rec_eng.i2s = I2S_ADC2; 1020 devc->rec_eng.chan = REC_B; 1021 1022 /* disable AC97 mixer - not used */ 1023 devc->has_ac97 = 0; 1024 1025 /* setup for 2wire communication mode */ 1026 OUTB(devc, INB(devc, FUNCTION) | 0x40, FUNCTION); 1027 1028 /* setup GPIO direction */ 1029 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x10D, GPIO_CONTROL); 1030 /* setup GPIO pins */ 1031 OUTW(devc, INW(devc, GPIO_DATA) | 0x101, GPIO_DATA); 1032 1033 /* init the front and rear dacs */ 1034 cs4398_init(devc, XONAR_DX_FRONTDAC); 1035 cs4362a_init(devc, XONAR_DX_SURRDAC); 1036 break; 1037 1038 case SUBID_XONAR_D2: 1039 case SUBID_XONAR_D2X: 1040 /* GPIO7 = 0x0080 controls mic/line-in */ 1041 /* GPIO8 = 0x0100 controls output */ 1042 /* GPIO2/3 = 0x000C codec output control */ 1043 1044 devc->rec_eng.addr = RECB_ADDR; 1045 devc->rec_eng.size = RECB_SIZE; 1046 devc->rec_eng.frag = RECB_FRAG; 1047 devc->rec_eng.i2s = I2S_ADC2; 1048 devc->rec_eng.chan = REC_B; 1049 1050 /* disable the AC97 mixer - it's not useful */ 1051 devc->has_ac97 = 0; 1052 1053 /* setup for spi communication mode */ 1054 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1055 /* setup the GPIO direction */ 1056 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x18c, GPIO_CONTROL); 1057 1058 /* setup GPIO Pins */ 1059 OUTW(devc, INW(devc, GPIO_DATA) | 0x100, GPIO_DATA); 1060 1061 /* for all 4 codecs: unmute, set to 24Bit SPI */ 1062 for (i = 0; i < 4; ++i) { 1063 /* left vol */ 1064 spi_write(devc, i, 16, mix_scale(75, 8)); 1065 /* right vol */ 1066 spi_write(devc, i, 17, mix_scale(75, 8)); 1067 /* unmute/24LSB/ATLD */ 1068 spi_write(devc, i, 18, 0x30 | 0x80); 1069 } 1070 break; 1071 1072 case SUBID_XONAR_STX: 1073 devc->rec_eng.addr = RECB_ADDR; 1074 devc->rec_eng.size = RECB_SIZE; 1075 devc->rec_eng.frag = RECB_FRAG; 1076 devc->rec_eng.i2s = I2S_ADC2; 1077 devc->rec_eng.chan = REC_B; 1078 1079 /* disable the AC97 mixer - it's not useful */ 1080 devc->has_ac97 = 0; 1081 1082 /* setup for spi communication mode */ 1083 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1084 /* setup the GPIO direction */ 1085 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x18F, GPIO_CONTROL); 1086 /* setup GPIO Pins */ 1087 OUTW(devc, INW(devc, GPIO_DATA) | 0x111, GPIO_DATA); 1088 1089 /* init front DAC */ 1090 /* left vol */ 1091 i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(75, 8)); 1092 /* right vol */ 1093 i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(75, 8)); 1094 /* unmute/24LSB/ATLD */ 1095 i2c_write(devc, XONAR_STX_FRONTDAC, 18, 0x30 | 0x80); 1096 i2c_write(devc, XONAR_STX_FRONTDAC, 19, 0); /* ATS1/FLT_SHARP */ 1097 i2c_write(devc, XONAR_STX_FRONTDAC, 20, 0); /* OS_64 */ 1098 i2c_write(devc, XONAR_STX_FRONTDAC, 21, 0); 1099 break; 1100 1101 case SUBID_XONAR_DS: 1102 /* GPIO 8 = 1 output enabled 0 mute */ 1103 /* GPIO 7 = 1 lineout enabled 0 mute */ 1104 /* GPIO 6 = 1 mic select 0 line-in select */ 1105 /* GPIO 4 = 1 FP Headphone plugged in */ 1106 /* GPIO 3 = 1 FP Mic plugged in */ 1107 1108 devc->rec_eng.addr = RECA_ADDR; 1109 devc->rec_eng.size = RECA_SIZE; 1110 devc->rec_eng.frag = RECA_FRAG; 1111 devc->rec_eng.i2s = I2S_ADC1; 1112 devc->rec_eng.chan = REC_A; 1113 1114 /* disable the AC97 mixer - it's not useful */ 1115 devc->has_ac97 = 0; 1116 1117 /* setup for spi communication mode */ 1118 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1119 /* setup the GPIO direction */ 1120 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x1D0, GPIO_CONTROL); 1121 /* setup GPIO Pins */ 1122 OUTW(devc, INW(devc, GPIO_DATA) | 0x1D0, GPIO_DATA); 1123 spi_write(devc, XONAR_DS_FRONTDAC, 0x17, 0x1); /* reset */ 1124 spi_write(devc, XONAR_DS_FRONTDAC, 0x7, 0x90); /* dac control */ 1125 spi_write(devc, XONAR_DS_FRONTDAC, 0x8, 0); /* unmute */ 1126 /* powerdown hp */ 1127 spi_write(devc, XONAR_DS_FRONTDAC, 0xC, 0x22); 1128 spi_write(devc, XONAR_DS_FRONTDAC, 0xD, 0x8); /* powerdown hp */ 1129 spi_write(devc, XONAR_DS_FRONTDAC, 0xA, 0x1); /* LJust/16bit */ 1130 spi_write(devc, XONAR_DS_FRONTDAC, 0xB, 0x1); /* LJust/16bit */ 1131 spi_write(devc, XONAR_DS_SURRDAC, 0x1f, 1); /* reset */ 1132 /* LJust/24bit */ 1133 spi_write(devc, XONAR_DS_SURRDAC, 0x3, 0x1|0x20); 1134 break; 1135 1136 1137 default: 1138 /* SPI default for anything else, including the */ 1139 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1140 OUTB(devc, 0x18, REC_ROUTING); /* default routing set to I2S */ 1141 break; 1142 } 1143 1144 /* only initialize AC97 if not defined */ 1145 if (devc->has_ac97) 1146 cmediahd_ac97_hwinit(devc); 1147 } 1148 1149 static int 1150 cmediahd_set_control(void *arg, uint64_t val) 1151 { 1152 cmediahd_ctrl_t *pc = arg; 1153 cmediahd_devc_t *devc = pc->devc; 1154 1155 mutex_enter(&devc->mutex); 1156 1157 pc->val = val; 1158 1159 switch (pc->num) { 1160 1161 case CTL_VOLUME: 1162 case CTL_FRONT: 1163 cmediahd_set_play_volume(devc, 0, val); 1164 break; 1165 1166 case CTL_REAR: 1167 cmediahd_set_play_volume(devc, 1, val); 1168 break; 1169 1170 case CTL_CENTER: 1171 val &= 0xff; 1172 val |= ((devc->controls[CTL_LFE].val) << 8); 1173 cmediahd_set_play_volume(devc, 2, val); 1174 break; 1175 1176 case CTL_LFE: 1177 val &= 0xff; 1178 val <<= 8; 1179 val |= (devc->controls[CTL_CENTER].val); 1180 cmediahd_set_play_volume(devc, 2, val); 1181 break; 1182 1183 case CTL_SURROUND: 1184 cmediahd_set_play_volume(devc, 3, val); 1185 break; 1186 1187 case CTL_MONITOR: 1188 /* enable recording monitor rec 1 and rec2 */ 1189 if (val) 1190 OUTB(devc, INB(devc, REC_MONITOR) | 0xF, REC_MONITOR); 1191 else 1192 OUTB(devc, INB(devc, REC_MONITOR) & ~0xF, REC_MONITOR); 1193 break; 1194 1195 case CTL_RECSRC: 1196 switch (val) { 1197 case 1: /* Line */ 1198 if (devc->model == SUBID_XONAR_DS) 1199 OUTW(devc, INW(devc, GPIO_DATA) & ~0x40, 1200 GPIO_DATA); 1201 1202 if (devc->model == SUBID_XONAR_D1 || 1203 devc->model == SUBID_XONAR_DX) 1204 OUTW(devc, INW(devc, GPIO_DATA) & 1205 ~devc->gpio_mic, GPIO_DATA); 1206 cmediahd_write_ac97(devc, 0x72, 1207 cmediahd_read_ac97(devc, 0x72) & ~0x1); 1208 cmediahd_write_ac97(devc, 0x1A, 0x0404); 1209 break; 1210 1211 case 2: /* Mic */ 1212 if (devc->model == SUBID_XONAR_DS) 1213 OUTW(devc, INW(devc, GPIO_DATA) | 0x40, 1214 GPIO_DATA); 1215 1216 if (devc->model == SUBID_XONAR_D1 || 1217 devc->model == SUBID_XONAR_DX) 1218 OUTW(devc, INW(devc, GPIO_DATA) | 1219 devc->gpio_mic, GPIO_DATA); 1220 cmediahd_write_ac97(devc, 0x72, 1221 cmediahd_read_ac97(devc, 0x72) | 0x1); 1222 /* Unmute Mic */ 1223 cmediahd_write_ac97(devc, 0xE, 1224 cmediahd_read_ac97(devc, 0xE) & ~0x8000); 1225 /* Mute AUX and Video */ 1226 cmediahd_write_ac97(devc, 0x12, 1227 cmediahd_read_ac97(devc, 0x12) | 0x8000); 1228 cmediahd_write_ac97(devc, 0x16, 1229 cmediahd_read_ac97(devc, 0x16) | 0x8000); 1230 cmediahd_write_ac97(devc, 0x1A, 0x0000); 1231 break; 1232 1233 case 4: /* AUX */ 1234 if (devc->model == SUBID_XONAR_D1 || 1235 devc->model == SUBID_XONAR_DX) 1236 OUTW(devc, INW(devc, GPIO_DATA) | 1237 devc->gpio_mic, GPIO_DATA); 1238 cmediahd_write_ac97(devc, 0x72, 1239 cmediahd_read_ac97(devc, 0x72) | 0x1); 1240 /* Unmute AUX */ 1241 cmediahd_write_ac97(devc, 0x16, 1242 cmediahd_read_ac97(devc, 0x16) & ~0x8000); 1243 /* Mute CD and Mic */ 1244 cmediahd_write_ac97(devc, 0x14, 1245 cmediahd_read_ac97(devc, 0x14) | 0x8000); 1246 cmediahd_write_ac97(devc, 0x0E, 1247 cmediahd_read_ac97(devc, 0x0E) | 0x8000); 1248 cmediahd_write_ac97(devc, 0x1A, 0x0303); 1249 break; 1250 1251 case 8: /* Video (CD) */ 1252 if (devc->model == SUBID_XONAR_D1 || 1253 devc->model == SUBID_XONAR_DX) 1254 OUTW(devc, INW(devc, GPIO_DATA) | 1255 devc->gpio_mic, GPIO_DATA); 1256 cmediahd_write_ac97(devc, 0x72, 1257 cmediahd_read_ac97(devc, 0x72) | 0x1); 1258 /* Unmute Video (CD) */ 1259 cmediahd_write_ac97(devc, 0x14, 1260 cmediahd_read_ac97(devc, 0x14) & ~0x8000); 1261 /* Mute AUX and Mic */ 1262 cmediahd_write_ac97(devc, 0x16, 1263 cmediahd_read_ac97(devc, 0x16) | 0x8000); 1264 cmediahd_write_ac97(devc, 0x0E, 1265 cmediahd_read_ac97(devc, 0x0E) | 0x8000); 1266 /* set input to video */ 1267 cmediahd_write_ac97(devc, 0x1A, 0x0202); 1268 break; 1269 } 1270 break; 1271 1272 case CTL_LOOP: 1273 if (val) 1274 OUTW(devc, INW(devc, GPIO_DATA) | devc->gpio_alt, 1275 GPIO_DATA); 1276 else 1277 OUTW(devc, (INW(devc, GPIO_DATA) & ~devc->gpio_alt), 1278 GPIO_DATA); 1279 break; 1280 1281 case CTL_SPREAD: 1282 if (val) 1283 OUTW(devc, INW(devc, PLAY_ROUTING) & 0x00FF, 1284 PLAY_ROUTING); 1285 else 1286 OUTW(devc, (INW(devc, PLAY_ROUTING) & 0x00FF) | 1287 0xE400, PLAY_ROUTING); 1288 break; 1289 1290 case CTL_RECGAIN: 1291 cmediahd_set_rec_volume(devc, val); 1292 break; 1293 1294 case CTL_MICVOL: 1295 if (val) 1296 cmediahd_write_ac97(devc, 0x0E, 1297 (0x40 | mix_scale(val, -5)) & ~0x8000); 1298 else 1299 cmediahd_write_ac97(devc, 0x0E, 0x8000); 1300 break; 1301 1302 case CTL_AUXVOL: 1303 if (val) 1304 cmediahd_write_ac97(devc, 0x16, 1305 mix_scale(val, -5) & ~0x8000); 1306 else 1307 cmediahd_write_ac97(devc, 0x16, 0x8000); 1308 break; 1309 1310 1311 case CTL_CDVOL: 1312 if (val) 1313 cmediahd_write_ac97(devc, 0x14, 1314 mix_scale(val, -5) & ~0x8000); 1315 else 1316 cmediahd_write_ac97(devc, 0x14, 0x8000); 1317 break; 1318 } 1319 1320 mutex_exit(&devc->mutex); 1321 return (0); 1322 } 1323 1324 static int 1325 cmediahd_get_control(void *arg, uint64_t *val) 1326 { 1327 cmediahd_ctrl_t *pc = arg; 1328 cmediahd_devc_t *devc = pc->devc; 1329 1330 mutex_enter(&devc->mutex); 1331 *val = pc->val; 1332 mutex_exit(&devc->mutex); 1333 return (0); 1334 } 1335 1336 static void 1337 cmediahd_alloc_ctrl(cmediahd_devc_t *devc, uint32_t num, uint64_t val) 1338 { 1339 audio_ctrl_desc_t desc; 1340 cmediahd_ctrl_t *pc; 1341 1342 bzero(&desc, sizeof (desc)); 1343 1344 pc = &devc->controls[num]; 1345 pc->num = num; 1346 pc->devc = devc; 1347 1348 1349 switch (num) { 1350 1351 case CTL_VOLUME: 1352 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 1353 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1354 desc.acd_minvalue = 0; 1355 desc.acd_maxvalue = 100; 1356 desc.acd_flags = PCMVOL; 1357 break; 1358 1359 case CTL_FRONT: 1360 desc.acd_name = AUDIO_CTRL_ID_FRONT; 1361 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1362 desc.acd_minvalue = 0; 1363 desc.acd_maxvalue = 100; 1364 desc.acd_flags = PCMVOL; 1365 break; 1366 1367 case CTL_REAR: 1368 desc.acd_name = AUDIO_CTRL_ID_REAR; 1369 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1370 desc.acd_minvalue = 0; 1371 desc.acd_maxvalue = 100; 1372 desc.acd_flags = PCMVOL; 1373 break; 1374 1375 case CTL_SURROUND: 1376 desc.acd_name = AUDIO_CTRL_ID_SURROUND; 1377 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1378 desc.acd_minvalue = 0; 1379 desc.acd_maxvalue = 100; 1380 desc.acd_flags = PCMVOL; 1381 break; 1382 1383 case CTL_CENTER: 1384 desc.acd_name = AUDIO_CTRL_ID_CENTER; 1385 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1386 desc.acd_minvalue = 0; 1387 desc.acd_maxvalue = 100; 1388 desc.acd_flags = PCMVOL; 1389 break; 1390 1391 case CTL_LFE: 1392 desc.acd_name = AUDIO_CTRL_ID_LFE; 1393 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1394 desc.acd_minvalue = 0; 1395 desc.acd_maxvalue = 100; 1396 desc.acd_flags = PCMVOL; 1397 break; 1398 1399 case CTL_MONITOR: 1400 desc.acd_name = AUDIO_CTRL_ID_MONSRC; 1401 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1402 desc.acd_minvalue = 0; 1403 desc.acd_maxvalue = 1; 1404 desc.acd_flags = RECCTL; 1405 break; 1406 1407 case CTL_RECSRC: 1408 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 1409 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1410 desc.acd_flags = RECCTL; 1411 desc.acd_enum[0] = AUDIO_PORT_LINEIN; 1412 desc.acd_enum[1] = AUDIO_PORT_MIC; 1413 1414 if (devc->model == SUBID_XONAR_D2 || 1415 devc->model == SUBID_XONAR_D2X) { 1416 desc.acd_minvalue = 0xF; 1417 desc.acd_maxvalue = 0xF; 1418 desc.acd_enum[2] = AUDIO_PORT_AUX1IN; 1419 desc.acd_enum[3] = AUDIO_PORT_CD; 1420 } else { 1421 desc.acd_minvalue = 0x3; 1422 desc.acd_maxvalue = 0x3; 1423 } 1424 break; 1425 1426 case CTL_LOOP: 1427 desc.acd_name = AUDIO_CTRL_ID_LOOPBACK; 1428 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1429 desc.acd_minvalue = 0; 1430 desc.acd_maxvalue = 1; 1431 desc.acd_flags = RECCTL; 1432 break; 1433 1434 case CTL_SPREAD: 1435 desc.acd_name = AUDIO_CTRL_ID_SPREAD; 1436 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1437 desc.acd_minvalue = 0; 1438 desc.acd_maxvalue = 1; 1439 desc.acd_flags = PLAYCTL; 1440 break; 1441 1442 case CTL_RECGAIN: 1443 desc.acd_name = AUDIO_CTRL_ID_RECGAIN; 1444 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1445 desc.acd_minvalue = 0; 1446 desc.acd_maxvalue = 100; 1447 desc.acd_flags = RECVOL; 1448 break; 1449 1450 case CTL_MICVOL: 1451 desc.acd_name = AUDIO_CTRL_ID_MIC; 1452 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1453 desc.acd_minvalue = 0; 1454 desc.acd_maxvalue = 100; 1455 desc.acd_flags = RECVOL; 1456 break; 1457 1458 case CTL_AUXVOL: 1459 desc.acd_name = AUDIO_CTRL_ID_AUX1IN; 1460 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1461 desc.acd_minvalue = 0; 1462 desc.acd_maxvalue = 100; 1463 desc.acd_flags = RECVOL; 1464 break; 1465 case CTL_CDVOL: 1466 desc.acd_name = AUDIO_CTRL_ID_CD; 1467 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1468 desc.acd_minvalue = 0; 1469 desc.acd_maxvalue = 100; 1470 desc.acd_flags = RECVOL; 1471 break; 1472 1473 } 1474 1475 pc->val = val; 1476 pc->ctrl = audio_dev_add_control(devc->adev, &desc, 1477 cmediahd_get_control, cmediahd_set_control, pc); 1478 } 1479 1480 static void 1481 cmediahd_refresh_mixer(cmediahd_devc_t *devc) 1482 { 1483 int ctl; 1484 1485 for (ctl = 0; ctl < CTL_NUM; ctl++) { 1486 if (devc->controls[ctl].ctrl == NULL) 1487 continue; 1488 (void) cmediahd_set_control(&devc->controls[ctl], 1489 devc->controls[ctl].val); 1490 } 1491 } 1492 1493 static void 1494 cmediahd_add_controls(cmediahd_devc_t *devc) 1495 { 1496 cmediahd_alloc_ctrl(devc, CTL_VOLUME, 80 | (80 << 8)); 1497 cmediahd_alloc_ctrl(devc, CTL_FRONT, 80 | (80<<8)); 1498 cmediahd_alloc_ctrl(devc, CTL_REAR, 80 | (80<<8)); 1499 cmediahd_alloc_ctrl(devc, CTL_CENTER, 80); 1500 cmediahd_alloc_ctrl(devc, CTL_LFE, 80); 1501 cmediahd_alloc_ctrl(devc, CTL_SURROUND, 80 | (80<<8)); 1502 cmediahd_alloc_ctrl(devc, CTL_SPREAD, 0); 1503 cmediahd_alloc_ctrl(devc, CTL_MONITOR, 0); 1504 cmediahd_alloc_ctrl(devc, CTL_LOOP, 0); 1505 cmediahd_alloc_ctrl(devc, CTL_RECSRC, 2); 1506 1507 switch (devc->model) { 1508 case SUBID_XONAR_DS: 1509 cmediahd_alloc_ctrl(devc, CTL_RECGAIN, 80|80<<8); 1510 break; 1511 case SUBID_XONAR_D2: 1512 case SUBID_XONAR_D2X: 1513 cmediahd_alloc_ctrl(devc, CTL_MICVOL, 80|80<<8); 1514 cmediahd_alloc_ctrl(devc, CTL_AUXVOL, 80|80<<8); 1515 cmediahd_alloc_ctrl(devc, CTL_CDVOL, 80|80<<8); 1516 break; 1517 } 1518 1519 cmediahd_refresh_mixer(devc); 1520 } 1521 1522 void 1523 cmediahd_del_controls(cmediahd_devc_t *dev) 1524 { 1525 for (int i = 0; i < CTL_NUM; i++) { 1526 if (dev->controls[i].ctrl) { 1527 audio_dev_del_control(dev->controls[i].ctrl); 1528 dev->controls[i].ctrl = NULL; 1529 } 1530 } 1531 } 1532 1533 int 1534 cmediahd_attach(dev_info_t *dip) 1535 { 1536 uint16_t pci_command, vendor, device, subvendor, subdevice; 1537 cmediahd_devc_t *devc; 1538 ddi_acc_handle_t pcih; 1539 1540 devc = kmem_zalloc(sizeof (*devc), KM_SLEEP); 1541 devc->dip = dip; 1542 ddi_set_driver_private(dip, devc); 1543 1544 mutex_init(&devc->mutex, NULL, MUTEX_DRIVER, NULL); 1545 mutex_init(&devc->low_mutex, NULL, MUTEX_DRIVER, NULL); 1546 1547 if ((devc->adev = audio_dev_alloc(dip, 0)) == NULL) { 1548 cmn_err(CE_WARN, "audio_dev_alloc failed"); 1549 goto error; 1550 } 1551 1552 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1553 audio_dev_warn(devc->adev, "pci_config_setup failed"); 1554 goto error; 1555 } 1556 devc->pcih = pcih; 1557 1558 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1559 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1560 subvendor = pci_config_get16(pcih, PCI_CONF_SUBVENID); 1561 subdevice = pci_config_get16(pcih, PCI_CONF_SUBSYSID); 1562 if (vendor != PCI_VENDOR_ID_CMEDIA || 1563 device != PCI_DEVICE_ID_CMEDIAHD) { 1564 audio_dev_warn(devc->adev, "Hardware not recognized " 1565 "(vendor=%x, dev=%x)", vendor, device); 1566 goto error; 1567 } 1568 1569 1570 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1571 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1572 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1573 1574 if ((ddi_regs_map_setup(dip, 1, &devc->base, 0, 0, &dev_attr, 1575 &devc->regsh)) != DDI_SUCCESS) { 1576 audio_dev_warn(devc->adev, "failed to map registers"); 1577 goto error; 1578 } 1579 1580 audio_dev_set_description(devc->adev, "CMedia 8788"); 1581 1582 /* Detect Xonar device */ 1583 if (subvendor == ASUS_VENDOR_ID) { 1584 switch (subdevice) { 1585 case SUBID_XONAR_D1: 1586 audio_dev_set_description(devc->adev, 1587 "Asus Xonar D1 (AV100)"); 1588 break; 1589 case SUBID_XONAR_DX: 1590 audio_dev_set_description(devc->adev, 1591 "Asus Xonar DX (AV100)"); 1592 break; 1593 case SUBID_XONAR_D2: 1594 audio_dev_set_description(devc->adev, 1595 "Asus Xonar D2 (AV200)"); 1596 break; 1597 case SUBID_XONAR_D2X: 1598 audio_dev_set_description(devc->adev, 1599 "Asus Xonar D2X (AV200)"); 1600 break; 1601 case SUBID_XONAR_STX: 1602 audio_dev_set_description(devc->adev, 1603 "Asus Xonar STX (AV100)"); 1604 break; 1605 case SUBID_XONAR_DS: 1606 audio_dev_set_description(devc->adev, 1607 "Asus Xonar DS (AV66)"); 1608 break; 1609 default: 1610 audio_dev_set_description(devc->adev, 1611 "Asus Xonar Unknown Model"); 1612 subdevice = SUBID_GENERIC; 1613 break; 1614 } 1615 devc->model = subdevice; 1616 } 1617 1618 cmediahd_hwinit(devc); 1619 1620 if (cmediahd_alloc_port(devc, CMEDIAHD_PLAY) != DDI_SUCCESS) 1621 goto error; 1622 if (cmediahd_alloc_port(devc, CMEDIAHD_REC) != DDI_SUCCESS) 1623 goto error; 1624 1625 /* Add the AC97 Mixer if there is an onboard AC97 device */ 1626 if (devc->has_ac97) { 1627 devc->ac97 = ac97_alloc(dip, cmediahd_read_ac97, 1628 cmediahd_write_ac97, devc); 1629 if (ac97_init(devc->ac97, devc->adev) != DDI_SUCCESS) { 1630 audio_dev_warn(devc->adev, "failed to init ac97"); 1631 goto error; 1632 } 1633 } 1634 #if 0 1635 /* Add the front panel AC97 device if one exists */ 1636 if (devc->has_fp_ac97) { 1637 devc->fp_ac97 = ac97_alloc(dip, cmediahd_read_fp_ac97, 1638 cmediahd_write_fp_ac97, devc); 1639 if (ac97_init(devc->fp_ac97, devc->adev) != DDI_SUCCESS) { 1640 audio_dev_warn(devc->adev, "failed to init fp_ac97"); 1641 goto error; 1642 } 1643 } 1644 #endif 1645 /* Add the standard CMI8788 Mixer panel */ 1646 cmediahd_add_controls(devc); 1647 1648 if (audio_dev_register(devc->adev) != DDI_SUCCESS) { 1649 audio_dev_warn(devc->adev, "unable to register with framework"); 1650 goto error; 1651 } 1652 1653 ddi_report_dev(dip); 1654 1655 return (DDI_SUCCESS); 1656 1657 error: 1658 cmediahd_destroy(devc); 1659 return (DDI_FAILURE); 1660 } 1661 1662 int 1663 cmediahd_resume(dev_info_t *dip) 1664 { 1665 cmediahd_devc_t *devc; 1666 1667 devc = ddi_get_driver_private(dip); 1668 1669 cmediahd_hwinit(devc); 1670 1671 if (devc->ac97) 1672 ac97_reset(devc->ac97); 1673 1674 cmediahd_refresh_mixer(devc); 1675 1676 audio_dev_resume(devc->adev); 1677 1678 return (DDI_SUCCESS); 1679 } 1680 1681 int 1682 cmediahd_detach(cmediahd_devc_t *devc) 1683 { 1684 if (audio_dev_unregister(devc->adev) != DDI_SUCCESS) 1685 return (DDI_FAILURE); 1686 1687 cmediahd_destroy(devc); 1688 return (DDI_SUCCESS); 1689 } 1690 1691 int 1692 cmediahd_suspend(cmediahd_devc_t *devc) 1693 { 1694 audio_dev_suspend(devc->adev); 1695 return (DDI_SUCCESS); 1696 } 1697 1698 static int cmediahd_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 1699 static int cmediahd_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 1700 static int cmediahd_ddi_quiesce(dev_info_t *); 1701 1702 static struct dev_ops cmediahd_dev_ops = { 1703 DEVO_REV, /* rev */ 1704 0, /* refcnt */ 1705 NULL, /* getinfo */ 1706 nulldev, /* identify */ 1707 nulldev, /* probe */ 1708 cmediahd_ddi_attach, /* attach */ 1709 cmediahd_ddi_detach, /* detach */ 1710 nodev, /* reset */ 1711 NULL, /* cb_ops */ 1712 NULL, /* bus_ops */ 1713 NULL, /* power */ 1714 cmediahd_ddi_quiesce, /* quiesce */ 1715 }; 1716 1717 static struct modldrv cmediahd_modldrv = { 1718 &mod_driverops, /* drv_modops */ 1719 "CMedia 8788", /* linkinfo */ 1720 &cmediahd_dev_ops, /* dev_ops */ 1721 }; 1722 1723 static struct modlinkage modlinkage = { 1724 MODREV_1, 1725 { &cmediahd_modldrv, NULL } 1726 }; 1727 1728 int 1729 _init(void) 1730 { 1731 int rv; 1732 1733 audio_init_ops(&cmediahd_dev_ops, CMEDIAHD_NAME); 1734 if ((rv = mod_install(&modlinkage)) != 0) { 1735 audio_fini_ops(&cmediahd_dev_ops); 1736 } 1737 return (rv); 1738 } 1739 1740 int 1741 _fini(void) 1742 { 1743 int rv; 1744 1745 if ((rv = mod_remove(&modlinkage)) == 0) { 1746 audio_fini_ops(&cmediahd_dev_ops); 1747 } 1748 return (rv); 1749 } 1750 1751 int 1752 _info(struct modinfo *modinfop) 1753 { 1754 return (mod_info(&modlinkage, modinfop)); 1755 } 1756 1757 int 1758 cmediahd_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1759 { 1760 switch (cmd) { 1761 case DDI_ATTACH: 1762 return (cmediahd_attach(dip)); 1763 1764 case DDI_RESUME: 1765 return (cmediahd_resume(dip)); 1766 1767 default: 1768 return (DDI_FAILURE); 1769 } 1770 } 1771 1772 int 1773 cmediahd_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1774 { 1775 cmediahd_devc_t *devc; 1776 1777 devc = ddi_get_driver_private(dip); 1778 1779 switch (cmd) { 1780 case DDI_DETACH: 1781 return (cmediahd_detach(devc)); 1782 1783 case DDI_SUSPEND: 1784 return (cmediahd_suspend(devc)); 1785 1786 default: 1787 return (DDI_FAILURE); 1788 } 1789 } 1790 1791 int 1792 cmediahd_ddi_quiesce(dev_info_t *dip) 1793 { 1794 cmediahd_devc_t *devc; 1795 1796 devc = ddi_get_driver_private(dip); 1797 1798 OUTW(devc, 0x0, DMA_START); 1799 1800 /* 1801 * Turn off the hardware 1802 */ 1803 1804 1805 return (DDI_SUCCESS); 1806 } 1807