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 { 374 spi_write(devc, codec_id, AK4396_LchATTCtl | 0x20, mix_scale(left, 8)); 375 spi_write(devc, codec_id, AK4396_RchATTCtl | 0x20, mix_scale(right, 8)); 376 } 377 378 static void 379 xonar_d1_set_play_volume(cmediahd_devc_t *devc, int codec_id, 380 int left, int right) 381 { 382 switch (codec_id) { 383 case 0: 384 i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLA, 385 CS4398_VOL(left)); 386 i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLB, 387 CS4398_VOL(right)); 388 break; 389 case 1: 390 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_1, 391 CS4362A_VOL(left)); 392 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_1, 393 CS4362A_VOL(right)); 394 break; 395 case 2: 396 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_2, 397 CS4362A_VOL(left)); 398 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_2, 399 CS4362A_VOL(right)); 400 break; 401 case 3: 402 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_3, 403 CS4362A_VOL(left)); 404 i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_3, 405 CS4362A_VOL(right)); 406 break; 407 } 408 } 409 410 static void 411 xonar_d2_set_play_volume(cmediahd_devc_t *devc, int codec_id, 412 int left, int right) 413 { 414 spi_write(devc, xd2_codec_map[codec_id], 16, mix_scale(left, 8)); 415 spi_write(devc, xd2_codec_map[codec_id], 17, mix_scale(right, 8)); 416 } 417 418 static void 419 xonar_stx_set_play_volume(cmediahd_devc_t *devc, int codec_id, 420 int left, int right) 421 { 422 if (codec_id == 0) { 423 i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(left, 8)); 424 i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(right, 8)); 425 } 426 } 427 428 static void 429 xonar_ds_set_play_volume(cmediahd_devc_t *devc, int codec_id, 430 int left, int right) 431 { 432 switch (codec_id) { 433 case 0: /* front */ 434 spi_write(devc, XONAR_DS_FRONTDAC, 0, 435 mix_scale(left, 7) | 0x180); 436 spi_write(devc, XONAR_DS_FRONTDAC, 1, 437 mix_scale(right, 7) | 0x180); 438 spi_write(devc, XONAR_DS_FRONTDAC, 3, 439 mix_scale(left, 7) |0x180); 440 spi_write(devc, XONAR_DS_FRONTDAC, 4, 441 mix_scale(right, 7) | 0x180); 442 break; 443 444 case 1: /* side */ 445 spi_write(devc, XONAR_DS_SURRDAC, 0, 446 mix_scale(left, 7) | 0x180); 447 spi_write(devc, XONAR_DS_SURRDAC, 1, 448 mix_scale(right, 7) | 0x180); 449 break; 450 case 2: /* rear */ 451 spi_write(devc, XONAR_DS_SURRDAC, 4, 452 mix_scale(left, 7) | 0x180); 453 spi_write(devc, XONAR_DS_SURRDAC, 5, 454 mix_scale(right, 7) | 0x180); 455 break; 456 case 3: /* center */ 457 spi_write(devc, XONAR_DS_SURRDAC, 6, 458 mix_scale(left, 7) | 0x180); 459 spi_write(devc, XONAR_DS_SURRDAC, 7, 460 mix_scale(right, 7) | 0x180); 461 break; 462 } 463 } 464 465 static void 466 cmediahd_set_rec_volume(cmediahd_devc_t *devc, int value) 467 { 468 unsigned char left, right; 469 470 left = (value >> 8) & 0xff; 471 right = value & 0xff; 472 473 if (left > 100) 474 left = 100; 475 if (right > 100) 476 right = 100; 477 478 spi_write(devc, XONAR_DS_FRONTDAC, 0xe, mix_scale(left, 8)); 479 spi_write(devc, XONAR_DS_FRONTDAC, 0xf, mix_scale(right, 8)); 480 } 481 482 static void 483 cmediahd_set_play_volume(cmediahd_devc_t *devc, int codec_id, int value) 484 { 485 int left, right; 486 487 left = (value >> 8) & 0xFF; 488 right = (value & 0xFF); 489 490 if (left > 100) 491 left = 100; 492 if (right > 100) 493 right = 100; 494 495 switch (devc->model) { 496 case SUBID_XONAR_D1: 497 case SUBID_XONAR_DX: 498 xonar_d1_set_play_volume(devc, codec_id, left, right); 499 break; 500 case SUBID_XONAR_D2: 501 case SUBID_XONAR_D2X: 502 xonar_d2_set_play_volume(devc, codec_id, left, right); 503 break; 504 case SUBID_XONAR_STX: 505 xonar_stx_set_play_volume(devc, codec_id, left, right); 506 break; 507 case SUBID_XONAR_DS: 508 xonar_ds_set_play_volume(devc, codec_id, left, right); 509 break; 510 default: 511 cmediahd_generic_set_play_volume(devc, codec_id, left, right); 512 break; 513 } 514 } 515 516 /* 517 * Audio routines 518 */ 519 520 int 521 cmediahd_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp) 522 { 523 cmediahd_portc_t *portc = arg; 524 525 _NOTE(ARGUNUSED(flag)); 526 527 portc->count = 0; 528 529 *nframesp = portc->nframes; 530 *bufp = portc->kaddr; 531 532 return (0); 533 } 534 535 void 536 cmediahd_close(void *arg) 537 { 538 _NOTE(ARGUNUSED(arg)); 539 } 540 541 int 542 cmediahd_start(void *arg) 543 { 544 cmediahd_portc_t *portc = arg; 545 cmediahd_devc_t *devc = portc->devc; 546 547 mutex_enter(&devc->mutex); 548 portc->offset = 0; 549 550 cmediahd_reset_port(portc); 551 552 switch (portc->direction) { 553 case CMEDIAHD_PLAY: 554 /* enable the dma */ 555 OUTW(devc, INW(devc, DMA_START) | 0x10, DMA_START); 556 break; 557 558 case CMEDIAHD_REC: 559 /* enable the channel */ 560 OUTW(devc, INW(devc, DMA_START) | (1<<devc->rec_eng.chan), 561 DMA_START); 562 break; 563 } 564 565 mutex_exit(&devc->mutex); 566 return (0); 567 } 568 569 void 570 cmediahd_stop(void *arg) 571 { 572 cmediahd_portc_t *portc = arg; 573 cmediahd_devc_t *devc = portc->devc; 574 575 mutex_enter(&devc->mutex); 576 switch (portc->direction) { 577 case CMEDIAHD_PLAY: 578 /* disable dma */ 579 OUTW(devc, INW(devc, DMA_START) & ~0x10, DMA_START); 580 break; 581 582 case CMEDIAHD_REC: 583 /* disable dma */ 584 OUTW(devc, INW(devc, DMA_START) & ~(1<<devc->rec_eng.chan), 585 DMA_START); 586 break; 587 } 588 mutex_exit(&devc->mutex); 589 } 590 591 int 592 cmediahd_format(void *arg) 593 { 594 _NOTE(ARGUNUSED(arg)); 595 596 return (AUDIO_FORMAT_S16_LE); 597 } 598 599 int 600 cmediahd_channels(void *arg) 601 { 602 cmediahd_portc_t *portc = arg; 603 604 return (portc->chans); 605 } 606 607 int 608 cmediahd_rate(void *arg) 609 { 610 _NOTE(ARGUNUSED(arg)); 611 612 return (48000); 613 } 614 615 void 616 cmediahd_sync(void *arg, unsigned nframes) 617 { 618 cmediahd_portc_t *portc = arg; 619 _NOTE(ARGUNUSED(nframes)); 620 621 (void) ddi_dma_sync(portc->buf_dmah, 0, 0, portc->syncdir); 622 } 623 624 static void 625 cmediahd_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 626 { 627 cmediahd_portc_t *portc = arg; 628 static const int map8ch[] = { 0, 1, 4, 5, 2, 3, 6, 7 }; 629 static const int map4ch[] = { 0, 1, 2, 3 }; 630 631 if (portc->chans <= 4) { 632 *offset = map4ch[chan]; 633 } else { 634 *offset = map8ch[chan]; 635 } 636 *incr = portc->chans; 637 } 638 639 uint64_t 640 cmediahd_count(void *arg) 641 { 642 cmediahd_portc_t *portc = arg; 643 cmediahd_devc_t *devc = portc->devc; 644 uint64_t count; 645 uint32_t offset; 646 647 mutex_enter(&devc->mutex); 648 649 if (portc->direction == CMEDIAHD_PLAY) 650 offset = portc->bufsz/4 - INL(devc, MULTICH_SIZE) + 1; 651 else 652 offset = portc->bufsz/4 - INW(devc, devc->rec_eng.size) + 1; 653 654 /* check for wrap */ 655 if (offset < portc->offset) { 656 count = ((portc->bufsz/4) - portc->offset) + offset; 657 } else { 658 count = offset - portc->offset; 659 } 660 portc->count += count; 661 portc->offset = offset; 662 663 /* convert from 16-bit stereo */ 664 count = portc->count / (portc->chans/2); 665 mutex_exit(&devc->mutex); 666 667 return (count); 668 } 669 670 /* private implementation bits */ 671 672 673 void 674 cmediahd_reset_port(cmediahd_portc_t *portc) 675 { 676 cmediahd_devc_t *devc = portc->devc; 677 int channels; 678 679 if (devc->suspended) 680 return; 681 682 portc->offset = 0; 683 684 switch (portc->direction) { 685 686 case CMEDIAHD_PLAY: 687 /* reset channel */ 688 OUTB(devc, INB(devc, CHAN_RESET)|0x10, CHAN_RESET); 689 drv_usecwait(10); 690 OUTB(devc, INB(devc, CHAN_RESET) & ~0x10, CHAN_RESET); 691 drv_usecwait(10); 692 693 OUTL(devc, portc->paddr, MULTICH_ADDR); 694 OUTL(devc, (portc->bufsz/4) - 1, MULTICH_SIZE); 695 OUTL(devc, (portc->bufsz/4) - 1, MULTICH_FRAG); 696 697 switch (portc->chans) { 698 case 2: 699 channels = 0; 700 break; 701 case 4: 702 channels = 1; 703 break; 704 case 6: 705 channels = 2; 706 break; 707 case 8: 708 channels = 3; 709 break; 710 } 711 OUTB(devc, (INB(devc, MULTICH_MODE) & ~0x3) | channels, 712 MULTICH_MODE); 713 714 /* set the format bits in play format register */ 715 OUTB(devc, (INB(devc, PLAY_FORMAT) & ~0xC) | 0x0, PLAY_FORMAT); 716 break; 717 718 case CMEDIAHD_REC: 719 OUTB(devc, INB(devc, CHAN_RESET) | (1 << devc->rec_eng.chan), 720 CHAN_RESET); 721 drv_usecwait(10); 722 OUTB(devc, INB(devc, CHAN_RESET) & ~(1 << devc->rec_eng.chan), 723 CHAN_RESET); 724 drv_usecwait(10); 725 726 OUTL(devc, portc->paddr, devc->rec_eng.addr); 727 OUTW(devc, (portc->bufsz/4) - 1, devc->rec_eng.size); 728 OUTW(devc, (portc->bufsz/4) - 1, devc->rec_eng.frag); 729 730 731 switch (portc->chans) { 732 case 2: 733 channels = 0x0; 734 break; 735 case 4: 736 channels = 0x1; 737 break; 738 case 6: 739 channels = 0x2; 740 break; 741 case 8: 742 channels = 0x4; 743 break; 744 default: 745 /* Stereo - boomer only supports stereo */ 746 channels = 0x0; 747 break; 748 } 749 750 OUTB(devc, (INB(devc, REC_MODE) & ~0x3) | channels, REC_MODE); 751 OUTB(devc, (INB(devc, REC_FORMAT) & ~0x3) | 0x0, REC_FORMAT); 752 753 } 754 } 755 756 int 757 cmediahd_alloc_port(cmediahd_devc_t *devc, int num) 758 { 759 cmediahd_portc_t *portc; 760 size_t len; 761 ddi_dma_cookie_t cookie; 762 uint_t count; 763 int dir; 764 unsigned caps; 765 audio_dev_t *adev; 766 767 adev = devc->adev; 768 portc = kmem_zalloc(sizeof (*portc), KM_SLEEP); 769 devc->portc[num] = portc; 770 portc->devc = devc; 771 portc->direction = num; 772 773 switch (num) { 774 case CMEDIAHD_REC: 775 portc->syncdir = DDI_DMA_SYNC_FORKERNEL; 776 portc->chans = 2; 777 caps = ENGINE_INPUT_CAP; 778 dir = DDI_DMA_READ; 779 break; 780 case CMEDIAHD_PLAY: 781 portc->syncdir = DDI_DMA_SYNC_FORDEV; 782 portc->chans = 8; 783 caps = ENGINE_OUTPUT_CAP; 784 dir = DDI_DMA_WRITE; 785 break; 786 default: 787 return (DDI_FAILURE); 788 } 789 790 /* 791 * Calculate buffer size and frames 792 */ 793 portc->nframes = 2048; 794 portc->bufsz = portc->nframes * portc->chans * 2; 795 796 /* Alloc buffers */ 797 if (ddi_dma_alloc_handle(devc->dip, &dma_attr_buf, DDI_DMA_SLEEP, NULL, 798 &portc->buf_dmah) != DDI_SUCCESS) { 799 audio_dev_warn(adev, "failed to allocate BUF handle"); 800 return (DDI_FAILURE); 801 } 802 803 if (ddi_dma_mem_alloc(portc->buf_dmah, CMEDIAHD_BUF_LEN, 804 &buf_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 805 &portc->kaddr, &len, &portc->buf_acch) != DDI_SUCCESS) { 806 audio_dev_warn(adev, "failed to allocate BUF memory"); 807 return (DDI_FAILURE); 808 } 809 810 bzero(portc->kaddr, len); 811 812 if (ddi_dma_addr_bind_handle(portc->buf_dmah, NULL, portc->kaddr, 813 len, DDI_DMA_CONSISTENT | dir, DDI_DMA_SLEEP, NULL, &cookie, 814 &count) != DDI_SUCCESS) { 815 audio_dev_warn(adev, "failed binding BUF DMA handle"); 816 return (DDI_FAILURE); 817 } 818 portc->paddr = cookie.dmac_address; 819 820 portc->engine = audio_engine_alloc(&cmediahd_engine_ops, caps); 821 if (portc->engine == NULL) { 822 audio_dev_warn(adev, "audio_engine_alloc failed"); 823 return (DDI_FAILURE); 824 } 825 826 audio_engine_set_private(portc->engine, portc); 827 audio_dev_add_engine(adev, portc->engine); 828 829 return (DDI_SUCCESS); 830 } 831 832 void 833 cmediahd_destroy(cmediahd_devc_t *devc) 834 { 835 mutex_destroy(&devc->mutex); 836 mutex_destroy(&devc->low_mutex); 837 838 for (int i = 0; i < CMEDIAHD_NUM_PORTC; i++) { 839 cmediahd_portc_t *portc = devc->portc[i]; 840 if (!portc) 841 continue; 842 if (portc->engine) { 843 audio_dev_remove_engine(devc->adev, portc->engine); 844 audio_engine_free(portc->engine); 845 } 846 if (portc->paddr) { 847 (void) ddi_dma_unbind_handle(portc->buf_dmah); 848 } 849 if (portc->buf_acch) { 850 ddi_dma_mem_free(&portc->buf_acch); 851 } 852 if (portc->buf_dmah) { 853 ddi_dma_free_handle(&portc->buf_dmah); 854 } 855 kmem_free(portc, sizeof (*portc)); 856 } 857 858 if (devc->ac97) { 859 ac97_free(devc->ac97); 860 } 861 862 cmediahd_del_controls(devc); 863 864 if (devc->adev != NULL) { 865 audio_dev_free(devc->adev); 866 } 867 if (devc->regsh != NULL) { 868 ddi_regs_map_free(&devc->regsh); 869 } 870 if (devc->pcih != NULL) { 871 pci_config_teardown(&devc->pcih); 872 } 873 kmem_free(devc, sizeof (*devc)); 874 } 875 876 void 877 cmediahd_ac97_hwinit(cmediahd_devc_t *devc) 878 { 879 /* GPIO #0 programmed as output, set CMI9780 Reg0x70 */ 880 cmediahd_write_ac97(devc, 0x70, 0x100); 881 882 /* LI2LI,MIC2MIC; let them always on, FOE on, ROE/BKOE/CBOE off */ 883 cmediahd_write_ac97(devc, 0x62, 0x180F); 884 885 /* unmute Master Volume */ 886 cmediahd_write_ac97(devc, 0x02, 0x0); 887 888 /* change PCBeep path, set Mix2FR on, option for quality issue */ 889 cmediahd_write_ac97(devc, 0x64, 0x8043); 890 891 /* mute PCBeep, option for quality issues */ 892 cmediahd_write_ac97(devc, 0x0A, 0x8000); 893 894 /* Record Select Control Register (Index 1Ah) */ 895 cmediahd_write_ac97(devc, 0x1A, 0x0000); 896 897 /* set Mic Volume Register 0x0Eh umute and enable micboost */ 898 cmediahd_write_ac97(devc, 0x0E, 0x0848); 899 900 /* set Line in Volume Register 0x10h mute */ 901 cmediahd_write_ac97(devc, 0x10, 0x8808); 902 903 /* set CD Volume Register 0x12h mute */ 904 cmediahd_write_ac97(devc, 0x12, 0x8808); 905 906 /* set AUX Volume Register 0x16h max */ 907 cmediahd_write_ac97(devc, 0x16, 0x0808); 908 909 /* set record gain Register 0x1Ch to max */ 910 cmediahd_write_ac97(devc, 0x1C, 0x0F0F); 911 912 /* GPIO status register enable GPO0 */ 913 cmediahd_write_ac97(devc, 0x72, 0x0001); 914 } 915 void 916 cmediahd_hwinit(cmediahd_devc_t *devc) 917 { 918 919 unsigned short sVal; 920 unsigned short i2s_fmt; 921 unsigned char bVal; 922 int i, count; 923 924 /* setup the default rec DMA engines to REC_A */ 925 devc->rec_eng.addr = RECA_ADDR; 926 devc->rec_eng.size = RECA_SIZE; 927 devc->rec_eng.frag = RECA_FRAG; 928 devc->rec_eng.i2s = I2S_ADC1; 929 devc->rec_eng.chan = REC_A; 930 931 /* setup GPIOs to 0 */ 932 devc->gpio_mic = 0; 933 devc->gpio_out = 0; 934 devc->gpio_codec = 0; 935 devc->gpio_alt = 0; 936 937 /* Init CMI Controller */ 938 sVal = INW(devc, CTRL_VERSION); 939 if (!(sVal & 0x0008)) { 940 bVal = INB(devc, MISC_REG); 941 bVal |= 0x20; 942 OUTB(devc, bVal, MISC_REG); 943 } 944 945 bVal = INB(devc, FUNCTION); 946 bVal |= 0x02; /* Reset codec */ 947 OUTB(devc, bVal, FUNCTION); 948 949 /* Cold reset onboard AC97 */ 950 OUTW(devc, 0x1, AC97_CTRL); 951 count = 100; 952 while ((INW(devc, AC97_CTRL) & 0x2) && (count--)) { 953 OUTW(devc, (INW(devc, AC97_CTRL) & ~0x2) | 0x2, AC97_CTRL); 954 drv_usecwait(100); 955 } 956 957 if (!count) 958 audio_dev_warn(devc->adev, "CMI8788 AC97 not ready"); 959 960 sVal = INW(devc, AC97_CTRL); 961 /* check if there's an onboard AC97 codec (CODEC 0) */ 962 if (sVal & 0x10) { 963 /* disable CODEC0 OUTPUT */ 964 OUTW(devc, INW(devc, AC97_OUT_CHAN_CONFIG) & ~0xFF00, 965 AC97_OUT_CHAN_CONFIG); 966 967 /* enable CODEC0 INPUT */ 968 OUTW(devc, INW(devc, AC97_IN_CHAN_CONFIG) | 0x0300, 969 AC97_IN_CHAN_CONFIG); 970 971 devc->has_ac97 = 1; 972 } 973 974 /* check if there's an front panel AC97 codec (CODEC1) */ 975 if (sVal & 0x20) { 976 /* enable CODEC1 OUTPUT */ 977 OUTW(devc, INW(devc, AC97_OUT_CHAN_CONFIG) | 0x0033, 978 AC97_OUT_CHAN_CONFIG); 979 /* enable CODEC1 INPUT */ 980 OUTW(devc, INW(devc, AC97_IN_CHAN_CONFIG) | 0x0033, 981 AC97_IN_CHAN_CONFIG); 982 983 devc->has_fp_ac97 = 1; 984 } 985 986 /* Disable AC97 interrupts and initialize AC97 */ 987 OUTB(devc, 0x0, AC97_INTR_MASK); 988 OUTW(devc, INW(devc, IRQ_MASK) & ~0x4000, IRQ_MASK); 989 990 /* I2S to 16bit/48Khz/Master, see below. */ 991 i2s_fmt = 0x011A; 992 993 /* Setup I2S to use 16bit instead of 24Bit */ 994 OUTW(devc, i2s_fmt, I2S_MULTICH_DAC); 995 OUTW(devc, i2s_fmt, I2S_ADC1); 996 OUTW(devc, i2s_fmt, I2S_ADC2); 997 OUTW(devc, i2s_fmt, I2S_ADC3); 998 999 /* setup Routing regs (default vals) */ 1000 OUTW(devc, 0xE400, PLAY_ROUTING); 1001 OUTB(devc, 0x00, REC_ROUTING); /* default routing set to I2S */ 1002 OUTB(devc, 0x00, REC_MONITOR); /* monitor through MULTICH_PLAY */ 1003 OUTB(devc, 0xE4, MONITOR_ROUTING); /* default monitor routing */ 1004 1005 1006 /* Enable Xonar output */ 1007 switch (devc->model) { 1008 case SUBID_XONAR_D1: 1009 case SUBID_XONAR_DX: 1010 /* GPIO8 = 0x100 controls mic/line-in */ 1011 /* GPIO0 = 0x001controls output */ 1012 /* GPIO2/3 = 0x00C codec output control */ 1013 1014 devc->rec_eng.addr = RECB_ADDR; 1015 devc->rec_eng.size = RECB_SIZE; 1016 devc->rec_eng.frag = RECB_FRAG; 1017 devc->rec_eng.i2s = I2S_ADC2; 1018 devc->rec_eng.chan = REC_B; 1019 1020 /* disable AC97 mixer - not used */ 1021 devc->has_ac97 = 0; 1022 1023 /* setup for 2wire communication mode */ 1024 OUTB(devc, INB(devc, FUNCTION) | 0x40, FUNCTION); 1025 1026 /* setup GPIO direction */ 1027 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x10D, GPIO_CONTROL); 1028 /* setup GPIO pins */ 1029 OUTW(devc, INW(devc, GPIO_DATA) | 0x101, GPIO_DATA); 1030 1031 /* init the front and rear dacs */ 1032 cs4398_init(devc, XONAR_DX_FRONTDAC); 1033 cs4362a_init(devc, XONAR_DX_SURRDAC); 1034 break; 1035 1036 case SUBID_XONAR_D2: 1037 case SUBID_XONAR_D2X: 1038 /* GPIO7 = 0x0080 controls mic/line-in */ 1039 /* GPIO8 = 0x0100 controls output */ 1040 /* GPIO2/3 = 0x000C codec output control */ 1041 1042 devc->rec_eng.addr = RECB_ADDR; 1043 devc->rec_eng.size = RECB_SIZE; 1044 devc->rec_eng.frag = RECB_FRAG; 1045 devc->rec_eng.i2s = I2S_ADC2; 1046 devc->rec_eng.chan = REC_B; 1047 1048 /* disable the AC97 mixer - it's not useful */ 1049 devc->has_ac97 = 0; 1050 1051 /* setup for spi communication mode */ 1052 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1053 /* setup the GPIO direction */ 1054 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x18c, GPIO_CONTROL); 1055 1056 /* setup GPIO Pins */ 1057 OUTW(devc, INW(devc, GPIO_DATA) | 0x100, GPIO_DATA); 1058 1059 /* for all 4 codecs: unmute, set to 24Bit SPI */ 1060 for (i = 0; i < 4; ++i) { 1061 /* left vol */ 1062 spi_write(devc, i, 16, mix_scale(75, 8)); 1063 /* right vol */ 1064 spi_write(devc, i, 17, mix_scale(75, 8)); 1065 /* unmute/24LSB/ATLD */ 1066 spi_write(devc, i, 18, 0x30 | 0x80); 1067 } 1068 break; 1069 1070 case SUBID_XONAR_STX: 1071 devc->rec_eng.addr = RECB_ADDR; 1072 devc->rec_eng.size = RECB_SIZE; 1073 devc->rec_eng.frag = RECB_FRAG; 1074 devc->rec_eng.i2s = I2S_ADC2; 1075 devc->rec_eng.chan = REC_B; 1076 1077 /* disable the AC97 mixer - it's not useful */ 1078 devc->has_ac97 = 0; 1079 1080 /* setup for spi communication mode */ 1081 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1082 /* setup the GPIO direction */ 1083 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x18F, GPIO_CONTROL); 1084 /* setup GPIO Pins */ 1085 OUTW(devc, INW(devc, GPIO_DATA) | 0x111, GPIO_DATA); 1086 1087 /* init front DAC */ 1088 /* left vol */ 1089 i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(75, 8)); 1090 /* right vol */ 1091 i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(75, 8)); 1092 /* unmute/24LSB/ATLD */ 1093 i2c_write(devc, XONAR_STX_FRONTDAC, 18, 0x30 | 0x80); 1094 i2c_write(devc, XONAR_STX_FRONTDAC, 19, 0); /* ATS1/FLT_SHARP */ 1095 i2c_write(devc, XONAR_STX_FRONTDAC, 20, 0); /* OS_64 */ 1096 i2c_write(devc, XONAR_STX_FRONTDAC, 21, 0); 1097 break; 1098 1099 case SUBID_XONAR_DS: 1100 /* GPIO 8 = 1 output enabled 0 mute */ 1101 /* GPIO 7 = 1 lineout enabled 0 mute */ 1102 /* GPIO 6 = 1 mic select 0 line-in select */ 1103 /* GPIO 4 = 1 FP Headphone plugged in */ 1104 /* GPIO 3 = 1 FP Mic plugged in */ 1105 1106 devc->rec_eng.addr = RECA_ADDR; 1107 devc->rec_eng.size = RECA_SIZE; 1108 devc->rec_eng.frag = RECA_FRAG; 1109 devc->rec_eng.i2s = I2S_ADC1; 1110 devc->rec_eng.chan = REC_A; 1111 1112 /* disable the AC97 mixer - it's not useful */ 1113 devc->has_ac97 = 0; 1114 1115 /* setup for spi communication mode */ 1116 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1117 /* setup the GPIO direction */ 1118 OUTW(devc, INW(devc, GPIO_CONTROL) | 0x1D0, GPIO_CONTROL); 1119 /* setup GPIO Pins */ 1120 OUTW(devc, INW(devc, GPIO_DATA) | 0x1D0, GPIO_DATA); 1121 spi_write(devc, XONAR_DS_FRONTDAC, 0x17, 0x1); /* reset */ 1122 spi_write(devc, XONAR_DS_FRONTDAC, 0x7, 0x90); /* dac control */ 1123 spi_write(devc, XONAR_DS_FRONTDAC, 0x8, 0); /* unmute */ 1124 /* powerdown hp */ 1125 spi_write(devc, XONAR_DS_FRONTDAC, 0xC, 0x22); 1126 spi_write(devc, XONAR_DS_FRONTDAC, 0xD, 0x8); /* powerdown hp */ 1127 spi_write(devc, XONAR_DS_FRONTDAC, 0xA, 0x1); /* LJust/16bit */ 1128 spi_write(devc, XONAR_DS_FRONTDAC, 0xB, 0x1); /* LJust/16bit */ 1129 spi_write(devc, XONAR_DS_SURRDAC, 0x1f, 1); /* reset */ 1130 /* LJust/24bit */ 1131 spi_write(devc, XONAR_DS_SURRDAC, 0x3, 0x1|0x20); 1132 break; 1133 1134 1135 default: 1136 /* SPI default for anything else, including the */ 1137 OUTB(devc, (INB(devc, FUNCTION) & ~0x40) | 0x80, FUNCTION); 1138 OUTB(devc, 0x18, REC_ROUTING); /* default routing set to I2S */ 1139 break; 1140 } 1141 1142 /* only initialize AC97 if not defined */ 1143 if (devc->has_ac97) 1144 cmediahd_ac97_hwinit(devc); 1145 } 1146 1147 static int 1148 cmediahd_set_control(void *arg, uint64_t val) 1149 { 1150 cmediahd_ctrl_t *pc = arg; 1151 cmediahd_devc_t *devc = pc->devc; 1152 1153 mutex_enter(&devc->mutex); 1154 1155 pc->val = val; 1156 1157 switch (pc->num) { 1158 1159 case CTL_VOLUME: 1160 case CTL_FRONT: 1161 cmediahd_set_play_volume(devc, 0, val); 1162 break; 1163 1164 case CTL_REAR: 1165 cmediahd_set_play_volume(devc, 1, val); 1166 break; 1167 1168 case CTL_CENTER: 1169 val &= 0xff; 1170 val |= ((devc->controls[CTL_LFE].val) << 8); 1171 cmediahd_set_play_volume(devc, 2, val); 1172 break; 1173 1174 case CTL_LFE: 1175 val &= 0xff; 1176 val <<= 8; 1177 val |= (devc->controls[CTL_CENTER].val); 1178 cmediahd_set_play_volume(devc, 2, val); 1179 break; 1180 1181 case CTL_SURROUND: 1182 cmediahd_set_play_volume(devc, 3, val); 1183 break; 1184 1185 case CTL_MONITOR: 1186 /* enable recording monitor rec 1 and rec2 */ 1187 if (val) 1188 OUTB(devc, INB(devc, REC_MONITOR) | 0xF, REC_MONITOR); 1189 else 1190 OUTB(devc, INB(devc, REC_MONITOR) & ~0xF, REC_MONITOR); 1191 break; 1192 1193 case CTL_RECSRC: 1194 switch (val) { 1195 case 1: /* Line */ 1196 if (devc->model == SUBID_XONAR_DS) 1197 OUTW(devc, INW(devc, GPIO_DATA) & ~0x40, 1198 GPIO_DATA); 1199 1200 if (devc->model == SUBID_XONAR_D1 || 1201 devc->model == SUBID_XONAR_DX) 1202 OUTW(devc, INW(devc, GPIO_DATA) & 1203 ~devc->gpio_mic, GPIO_DATA); 1204 cmediahd_write_ac97(devc, 0x72, 1205 cmediahd_read_ac97(devc, 0x72) & ~0x1); 1206 cmediahd_write_ac97(devc, 0x1A, 0x0404); 1207 break; 1208 1209 case 2: /* Mic */ 1210 if (devc->model == SUBID_XONAR_DS) 1211 OUTW(devc, INW(devc, GPIO_DATA) | 0x40, 1212 GPIO_DATA); 1213 1214 if (devc->model == SUBID_XONAR_D1 || 1215 devc->model == SUBID_XONAR_DX) 1216 OUTW(devc, INW(devc, GPIO_DATA) | 1217 devc->gpio_mic, GPIO_DATA); 1218 cmediahd_write_ac97(devc, 0x72, 1219 cmediahd_read_ac97(devc, 0x72) | 0x1); 1220 /* Unmute Mic */ 1221 cmediahd_write_ac97(devc, 0xE, 1222 cmediahd_read_ac97(devc, 0xE) & ~0x8000); 1223 /* Mute AUX and Video */ 1224 cmediahd_write_ac97(devc, 0x12, 1225 cmediahd_read_ac97(devc, 0x12) | 0x8000); 1226 cmediahd_write_ac97(devc, 0x16, 1227 cmediahd_read_ac97(devc, 0x16) | 0x8000); 1228 cmediahd_write_ac97(devc, 0x1A, 0x0000); 1229 break; 1230 1231 case 4: /* AUX */ 1232 if (devc->model == SUBID_XONAR_D1 || 1233 devc->model == SUBID_XONAR_DX) 1234 OUTW(devc, INW(devc, GPIO_DATA) | 1235 devc->gpio_mic, GPIO_DATA); 1236 cmediahd_write_ac97(devc, 0x72, 1237 cmediahd_read_ac97(devc, 0x72) | 0x1); 1238 /* Unmute AUX */ 1239 cmediahd_write_ac97(devc, 0x16, 1240 cmediahd_read_ac97(devc, 0x16) & ~0x8000); 1241 /* Mute CD and Mic */ 1242 cmediahd_write_ac97(devc, 0x14, 1243 cmediahd_read_ac97(devc, 0x14) | 0x8000); 1244 cmediahd_write_ac97(devc, 0x0E, 1245 cmediahd_read_ac97(devc, 0x0E) | 0x8000); 1246 cmediahd_write_ac97(devc, 0x1A, 0x0303); 1247 break; 1248 1249 case 8: /* Video (CD) */ 1250 if (devc->model == SUBID_XONAR_D1 || 1251 devc->model == SUBID_XONAR_DX) 1252 OUTW(devc, INW(devc, GPIO_DATA) | 1253 devc->gpio_mic, GPIO_DATA); 1254 cmediahd_write_ac97(devc, 0x72, 1255 cmediahd_read_ac97(devc, 0x72) | 0x1); 1256 /* Unmute Video (CD) */ 1257 cmediahd_write_ac97(devc, 0x14, 1258 cmediahd_read_ac97(devc, 0x14) & ~0x8000); 1259 /* Mute AUX and Mic */ 1260 cmediahd_write_ac97(devc, 0x16, 1261 cmediahd_read_ac97(devc, 0x16) | 0x8000); 1262 cmediahd_write_ac97(devc, 0x0E, 1263 cmediahd_read_ac97(devc, 0x0E) | 0x8000); 1264 /* set input to video */ 1265 cmediahd_write_ac97(devc, 0x1A, 0x0202); 1266 break; 1267 } 1268 break; 1269 1270 case CTL_LOOP: 1271 if (val) 1272 OUTW(devc, INW(devc, GPIO_DATA) | devc->gpio_alt, 1273 GPIO_DATA); 1274 else 1275 OUTW(devc, (INW(devc, GPIO_DATA) & ~devc->gpio_alt), 1276 GPIO_DATA); 1277 break; 1278 1279 case CTL_SPREAD: 1280 if (val) 1281 OUTW(devc, INW(devc, PLAY_ROUTING) & 0x00FF, 1282 PLAY_ROUTING); 1283 else 1284 OUTW(devc, (INW(devc, PLAY_ROUTING) & 0x00FF) | 1285 0xE400, PLAY_ROUTING); 1286 break; 1287 1288 case CTL_RECGAIN: 1289 cmediahd_set_rec_volume(devc, val); 1290 break; 1291 1292 case CTL_MICVOL: 1293 if (val) 1294 cmediahd_write_ac97(devc, 0x0E, 1295 (0x40 | mix_scale(val, -5)) & ~0x8000); 1296 else 1297 cmediahd_write_ac97(devc, 0x0E, 0x8000); 1298 break; 1299 1300 case CTL_AUXVOL: 1301 if (val) 1302 cmediahd_write_ac97(devc, 0x16, 1303 mix_scale(val, -5) & ~0x8000); 1304 else 1305 cmediahd_write_ac97(devc, 0x16, 0x8000); 1306 break; 1307 1308 1309 case CTL_CDVOL: 1310 if (val) 1311 cmediahd_write_ac97(devc, 0x14, 1312 mix_scale(val, -5) & ~0x8000); 1313 else 1314 cmediahd_write_ac97(devc, 0x14, 0x8000); 1315 break; 1316 } 1317 1318 mutex_exit(&devc->mutex); 1319 return (0); 1320 } 1321 1322 static int 1323 cmediahd_get_control(void *arg, uint64_t *val) 1324 { 1325 cmediahd_ctrl_t *pc = arg; 1326 cmediahd_devc_t *devc = pc->devc; 1327 1328 mutex_enter(&devc->mutex); 1329 *val = pc->val; 1330 mutex_exit(&devc->mutex); 1331 return (0); 1332 } 1333 1334 static void 1335 cmediahd_alloc_ctrl(cmediahd_devc_t *devc, uint32_t num, uint64_t val) 1336 { 1337 audio_ctrl_desc_t desc; 1338 cmediahd_ctrl_t *pc; 1339 1340 bzero(&desc, sizeof (desc)); 1341 1342 pc = &devc->controls[num]; 1343 pc->num = num; 1344 pc->devc = devc; 1345 1346 1347 switch (num) { 1348 1349 case CTL_VOLUME: 1350 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 1351 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1352 desc.acd_minvalue = 0; 1353 desc.acd_maxvalue = 100; 1354 desc.acd_flags = PCMVOL; 1355 break; 1356 1357 case CTL_FRONT: 1358 desc.acd_name = AUDIO_CTRL_ID_FRONT; 1359 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1360 desc.acd_minvalue = 0; 1361 desc.acd_maxvalue = 100; 1362 desc.acd_flags = PCMVOL; 1363 break; 1364 1365 case CTL_REAR: 1366 desc.acd_name = AUDIO_CTRL_ID_REAR; 1367 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1368 desc.acd_minvalue = 0; 1369 desc.acd_maxvalue = 100; 1370 desc.acd_flags = PCMVOL; 1371 break; 1372 1373 case CTL_SURROUND: 1374 desc.acd_name = AUDIO_CTRL_ID_SURROUND; 1375 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1376 desc.acd_minvalue = 0; 1377 desc.acd_maxvalue = 100; 1378 desc.acd_flags = PCMVOL; 1379 break; 1380 1381 case CTL_CENTER: 1382 desc.acd_name = AUDIO_CTRL_ID_CENTER; 1383 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1384 desc.acd_minvalue = 0; 1385 desc.acd_maxvalue = 100; 1386 desc.acd_flags = PCMVOL; 1387 break; 1388 1389 case CTL_LFE: 1390 desc.acd_name = AUDIO_CTRL_ID_LFE; 1391 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1392 desc.acd_minvalue = 0; 1393 desc.acd_maxvalue = 100; 1394 desc.acd_flags = PCMVOL; 1395 break; 1396 1397 case CTL_MONITOR: 1398 desc.acd_name = AUDIO_CTRL_ID_MONSRC; 1399 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1400 desc.acd_minvalue = 0; 1401 desc.acd_maxvalue = 1; 1402 desc.acd_flags = RECCTL; 1403 break; 1404 1405 case CTL_RECSRC: 1406 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 1407 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1408 desc.acd_flags = RECCTL; 1409 desc.acd_enum[0] = AUDIO_PORT_LINEIN; 1410 desc.acd_enum[1] = AUDIO_PORT_MIC; 1411 1412 if (devc->model == SUBID_XONAR_D2 || 1413 devc->model == SUBID_XONAR_D2X) { 1414 desc.acd_minvalue = 0xF; 1415 desc.acd_maxvalue = 0xF; 1416 desc.acd_enum[2] = AUDIO_PORT_AUX1IN; 1417 desc.acd_enum[3] = AUDIO_PORT_CD; 1418 } else { 1419 desc.acd_minvalue = 0x3; 1420 desc.acd_maxvalue = 0x3; 1421 } 1422 break; 1423 1424 case CTL_LOOP: 1425 desc.acd_name = AUDIO_CTRL_ID_LOOPBACK; 1426 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1427 desc.acd_minvalue = 0; 1428 desc.acd_maxvalue = 1; 1429 desc.acd_flags = RECCTL; 1430 break; 1431 1432 case CTL_SPREAD: 1433 desc.acd_name = AUDIO_CTRL_ID_SPREAD; 1434 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1435 desc.acd_minvalue = 0; 1436 desc.acd_maxvalue = 1; 1437 desc.acd_flags = PLAYCTL; 1438 break; 1439 1440 case CTL_RECGAIN: 1441 desc.acd_name = AUDIO_CTRL_ID_RECGAIN; 1442 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1443 desc.acd_minvalue = 0; 1444 desc.acd_maxvalue = 100; 1445 desc.acd_flags = RECVOL; 1446 break; 1447 1448 case CTL_MICVOL: 1449 desc.acd_name = AUDIO_CTRL_ID_MIC; 1450 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1451 desc.acd_minvalue = 0; 1452 desc.acd_maxvalue = 100; 1453 desc.acd_flags = RECVOL; 1454 break; 1455 1456 case CTL_AUXVOL: 1457 desc.acd_name = AUDIO_CTRL_ID_AUX1IN; 1458 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1459 desc.acd_minvalue = 0; 1460 desc.acd_maxvalue = 100; 1461 desc.acd_flags = RECVOL; 1462 break; 1463 case CTL_CDVOL: 1464 desc.acd_name = AUDIO_CTRL_ID_CD; 1465 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1466 desc.acd_minvalue = 0; 1467 desc.acd_maxvalue = 100; 1468 desc.acd_flags = RECVOL; 1469 break; 1470 1471 } 1472 1473 pc->val = val; 1474 pc->ctrl = audio_dev_add_control(devc->adev, &desc, 1475 cmediahd_get_control, cmediahd_set_control, pc); 1476 } 1477 1478 static void 1479 cmediahd_refresh_mixer(cmediahd_devc_t *devc) 1480 { 1481 int ctl; 1482 1483 for (ctl = 0; ctl < CTL_NUM; ctl++) { 1484 if (devc->controls[ctl].ctrl == NULL) 1485 continue; 1486 (void) cmediahd_set_control(&devc->controls[ctl], 1487 devc->controls[ctl].val); 1488 } 1489 } 1490 1491 static void 1492 cmediahd_add_controls(cmediahd_devc_t *devc) 1493 { 1494 cmediahd_alloc_ctrl(devc, CTL_VOLUME, 80 | (80 << 8)); 1495 cmediahd_alloc_ctrl(devc, CTL_FRONT, 80 | (80<<8)); 1496 cmediahd_alloc_ctrl(devc, CTL_REAR, 80 | (80<<8)); 1497 cmediahd_alloc_ctrl(devc, CTL_CENTER, 80); 1498 cmediahd_alloc_ctrl(devc, CTL_LFE, 80); 1499 cmediahd_alloc_ctrl(devc, CTL_SURROUND, 80 | (80<<8)); 1500 cmediahd_alloc_ctrl(devc, CTL_SPREAD, 0); 1501 cmediahd_alloc_ctrl(devc, CTL_MONITOR, 0); 1502 cmediahd_alloc_ctrl(devc, CTL_LOOP, 0); 1503 cmediahd_alloc_ctrl(devc, CTL_RECSRC, 2); 1504 1505 switch (devc->model) { 1506 case SUBID_XONAR_DS: 1507 cmediahd_alloc_ctrl(devc, CTL_RECGAIN, 80|80<<8); 1508 break; 1509 case SUBID_XONAR_D2: 1510 case SUBID_XONAR_D2X: 1511 cmediahd_alloc_ctrl(devc, CTL_MICVOL, 80|80<<8); 1512 cmediahd_alloc_ctrl(devc, CTL_AUXVOL, 80|80<<8); 1513 cmediahd_alloc_ctrl(devc, CTL_CDVOL, 80|80<<8); 1514 break; 1515 } 1516 1517 cmediahd_refresh_mixer(devc); 1518 } 1519 1520 void 1521 cmediahd_del_controls(cmediahd_devc_t *dev) 1522 { 1523 for (int i = 0; i < CTL_NUM; i++) { 1524 if (dev->controls[i].ctrl) { 1525 audio_dev_del_control(dev->controls[i].ctrl); 1526 dev->controls[i].ctrl = NULL; 1527 } 1528 } 1529 } 1530 1531 int 1532 cmediahd_attach(dev_info_t *dip) 1533 { 1534 uint16_t pci_command, vendor, device, subvendor, subdevice; 1535 cmediahd_devc_t *devc; 1536 ddi_acc_handle_t pcih; 1537 1538 devc = kmem_zalloc(sizeof (*devc), KM_SLEEP); 1539 devc->dip = dip; 1540 ddi_set_driver_private(dip, devc); 1541 1542 mutex_init(&devc->mutex, NULL, MUTEX_DRIVER, NULL); 1543 mutex_init(&devc->low_mutex, NULL, MUTEX_DRIVER, NULL); 1544 1545 if ((devc->adev = audio_dev_alloc(dip, 0)) == NULL) { 1546 cmn_err(CE_WARN, "audio_dev_alloc failed"); 1547 goto error; 1548 } 1549 1550 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1551 audio_dev_warn(devc->adev, "pci_config_setup failed"); 1552 goto error; 1553 } 1554 devc->pcih = pcih; 1555 1556 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1557 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1558 subvendor = pci_config_get16(pcih, PCI_CONF_SUBVENID); 1559 subdevice = pci_config_get16(pcih, PCI_CONF_SUBSYSID); 1560 if (vendor != PCI_VENDOR_ID_CMEDIA || 1561 device != PCI_DEVICE_ID_CMEDIAHD) { 1562 audio_dev_warn(devc->adev, "Hardware not recognized " 1563 "(vendor=%x, dev=%x)", vendor, device); 1564 goto error; 1565 } 1566 1567 1568 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1569 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1570 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1571 1572 if ((ddi_regs_map_setup(dip, 1, &devc->base, 0, 0, &dev_attr, 1573 &devc->regsh)) != DDI_SUCCESS) { 1574 audio_dev_warn(devc->adev, "failed to map registers"); 1575 goto error; 1576 } 1577 1578 audio_dev_set_description(devc->adev, "CMedia 8788"); 1579 1580 /* Detect Xonar device */ 1581 if (subvendor == ASUS_VENDOR_ID) { 1582 switch (subdevice) { 1583 case SUBID_XONAR_D1: 1584 audio_dev_set_description(devc->adev, 1585 "Asus Xonar D1 (AV100)"); 1586 break; 1587 case SUBID_XONAR_DX: 1588 audio_dev_set_description(devc->adev, 1589 "Asus Xonar DX (AV100)"); 1590 break; 1591 case SUBID_XONAR_D2: 1592 audio_dev_set_description(devc->adev, 1593 "Asus Xonar D2 (AV200)"); 1594 break; 1595 case SUBID_XONAR_D2X: 1596 audio_dev_set_description(devc->adev, 1597 "Asus Xonar D2X (AV200)"); 1598 break; 1599 case SUBID_XONAR_STX: 1600 audio_dev_set_description(devc->adev, 1601 "Asus Xonar STX (AV100)"); 1602 break; 1603 case SUBID_XONAR_DS: 1604 audio_dev_set_description(devc->adev, 1605 "Asus Xonar DS (AV66)"); 1606 break; 1607 default: 1608 audio_dev_set_description(devc->adev, 1609 "Asus Xonar Unknown Model"); 1610 subdevice = SUBID_GENERIC; 1611 break; 1612 } 1613 devc->model = subdevice; 1614 } 1615 1616 cmediahd_hwinit(devc); 1617 1618 if (cmediahd_alloc_port(devc, CMEDIAHD_PLAY) != DDI_SUCCESS) 1619 goto error; 1620 if (cmediahd_alloc_port(devc, CMEDIAHD_REC) != DDI_SUCCESS) 1621 goto error; 1622 1623 /* Add the AC97 Mixer if there is an onboard AC97 device */ 1624 if (devc->has_ac97) { 1625 devc->ac97 = ac97_alloc(dip, cmediahd_read_ac97, 1626 cmediahd_write_ac97, devc); 1627 if (ac97_init(devc->ac97, devc->adev) != DDI_SUCCESS) { 1628 audio_dev_warn(devc->adev, "failed to init ac97"); 1629 goto error; 1630 } 1631 } 1632 #if 0 1633 /* Add the front panel AC97 device if one exists */ 1634 if (devc->has_fp_ac97) { 1635 devc->fp_ac97 = ac97_alloc(dip, cmediahd_read_fp_ac97, 1636 cmediahd_write_fp_ac97, devc); 1637 if (ac97_init(devc->fp_ac97, devc->adev) != DDI_SUCCESS) { 1638 audio_dev_warn(devc->adev, "failed to init fp_ac97"); 1639 goto error; 1640 } 1641 } 1642 #endif 1643 /* Add the standard CMI8788 Mixer panel */ 1644 cmediahd_add_controls(devc); 1645 1646 if (audio_dev_register(devc->adev) != DDI_SUCCESS) { 1647 audio_dev_warn(devc->adev, "unable to register with framework"); 1648 goto error; 1649 } 1650 1651 ddi_report_dev(dip); 1652 1653 return (DDI_SUCCESS); 1654 1655 error: 1656 cmediahd_destroy(devc); 1657 return (DDI_FAILURE); 1658 } 1659 1660 int 1661 cmediahd_resume(dev_info_t *dip) 1662 { 1663 cmediahd_devc_t *devc; 1664 1665 devc = ddi_get_driver_private(dip); 1666 1667 cmediahd_hwinit(devc); 1668 1669 if (devc->ac97) 1670 ac97_reset(devc->ac97); 1671 1672 cmediahd_refresh_mixer(devc); 1673 1674 audio_dev_resume(devc->adev); 1675 1676 return (DDI_SUCCESS); 1677 } 1678 1679 int 1680 cmediahd_detach(cmediahd_devc_t *devc) 1681 { 1682 if (audio_dev_unregister(devc->adev) != DDI_SUCCESS) 1683 return (DDI_FAILURE); 1684 1685 cmediahd_destroy(devc); 1686 return (DDI_SUCCESS); 1687 } 1688 1689 int 1690 cmediahd_suspend(cmediahd_devc_t *devc) 1691 { 1692 audio_dev_suspend(devc->adev); 1693 return (DDI_SUCCESS); 1694 } 1695 1696 static int cmediahd_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 1697 static int cmediahd_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 1698 static int cmediahd_ddi_quiesce(dev_info_t *); 1699 1700 static struct dev_ops cmediahd_dev_ops = { 1701 DEVO_REV, /* rev */ 1702 0, /* refcnt */ 1703 NULL, /* getinfo */ 1704 nulldev, /* identify */ 1705 nulldev, /* probe */ 1706 cmediahd_ddi_attach, /* attach */ 1707 cmediahd_ddi_detach, /* detach */ 1708 nodev, /* reset */ 1709 NULL, /* cb_ops */ 1710 NULL, /* bus_ops */ 1711 NULL, /* power */ 1712 cmediahd_ddi_quiesce, /* quiesce */ 1713 }; 1714 1715 static struct modldrv cmediahd_modldrv = { 1716 &mod_driverops, /* drv_modops */ 1717 "CMedia 8788", /* linkinfo */ 1718 &cmediahd_dev_ops, /* dev_ops */ 1719 }; 1720 1721 static struct modlinkage modlinkage = { 1722 MODREV_1, 1723 { &cmediahd_modldrv, NULL } 1724 }; 1725 1726 int 1727 _init(void) 1728 { 1729 int rv; 1730 1731 audio_init_ops(&cmediahd_dev_ops, CMEDIAHD_NAME); 1732 if ((rv = mod_install(&modlinkage)) != 0) { 1733 audio_fini_ops(&cmediahd_dev_ops); 1734 } 1735 return (rv); 1736 } 1737 1738 int 1739 _fini(void) 1740 { 1741 int rv; 1742 1743 if ((rv = mod_remove(&modlinkage)) == 0) { 1744 audio_fini_ops(&cmediahd_dev_ops); 1745 } 1746 return (rv); 1747 } 1748 1749 int 1750 _info(struct modinfo *modinfop) 1751 { 1752 return (mod_info(&modlinkage, modinfop)); 1753 } 1754 1755 int 1756 cmediahd_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1757 { 1758 switch (cmd) { 1759 case DDI_ATTACH: 1760 return (cmediahd_attach(dip)); 1761 1762 case DDI_RESUME: 1763 return (cmediahd_resume(dip)); 1764 1765 default: 1766 return (DDI_FAILURE); 1767 } 1768 } 1769 1770 int 1771 cmediahd_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1772 { 1773 cmediahd_devc_t *devc; 1774 1775 devc = ddi_get_driver_private(dip); 1776 1777 switch (cmd) { 1778 case DDI_DETACH: 1779 return (cmediahd_detach(devc)); 1780 1781 case DDI_SUSPEND: 1782 return (cmediahd_suspend(devc)); 1783 1784 default: 1785 return (DDI_FAILURE); 1786 } 1787 } 1788 1789 int 1790 cmediahd_ddi_quiesce(dev_info_t *dip) 1791 { 1792 cmediahd_devc_t *devc; 1793 1794 devc = ddi_get_driver_private(dip); 1795 1796 OUTW(devc, 0x0, DMA_START); 1797 1798 /* 1799 * Turn off the hardware 1800 */ 1801 1802 1803 return (DDI_SUCCESS); 1804 } 1805