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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * Purpose: Driver for the Creative Audigy LS sound card 28 */ 29 /* 30 * Copyright (C) 4Front Technologies 1996-2009. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/modctl.h> 35 #include <sys/kmem.h> 36 #include <sys/conf.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 #include <sys/pci.h> 40 #include <sys/note.h> 41 #include <sys/audio/audio_driver.h> 42 #include <sys/audio/ac97.h> 43 44 #include "audiols.h" 45 46 static struct ddi_device_acc_attr dev_attr = { 47 DDI_DEVICE_ATTR_V0, 48 DDI_STRUCTURE_LE_ACC, 49 DDI_STRICTORDER_ACC 50 }; 51 52 static struct ddi_device_acc_attr buf_attr = { 53 DDI_DEVICE_ATTR_V0, 54 DDI_NEVERSWAP_ACC, 55 DDI_STRICTORDER_ACC 56 }; 57 58 static ddi_dma_attr_t dma_attr_buf = { 59 DMA_ATTR_V0, /* version number */ 60 0x00000000, /* low DMA address range */ 61 0xffffffff, /* high DMA address range */ 62 0x000fffff, /* DMA counter (16 bits only in Audigy LS) */ 63 4, /* DMA address alignment */ 64 0x3c, /* DMA burstsizes */ 65 4, /* min effective DMA size */ 66 0xffffffff, /* max DMA xfer size */ 67 0xffffffff, /* segment boundary */ 68 1, /* s/g length */ 69 4, /* granularity of device */ 70 0 /* Bus specific DMA flags */ 71 }; 72 73 static int audigyls_attach(dev_info_t *); 74 static int audigyls_resume(dev_info_t *); 75 static int audigyls_detach(audigyls_dev_t *); 76 static int audigyls_suspend(audigyls_dev_t *); 77 78 static int audigyls_open(void *, int, unsigned *, caddr_t *); 79 static void audigyls_close(void *); 80 static int audigyls_start(void *); 81 static void audigyls_stop(void *); 82 static int audigyls_format(void *); 83 static int audigyls_channels(void *); 84 static int audigyls_rate(void *); 85 static uint64_t audigyls_count(void *); 86 static void audigyls_sync(void *, unsigned); 87 static void audigyls_chinfo(void *, int, unsigned *, unsigned *); 88 89 90 static uint16_t audigyls_read_ac97(void *, uint8_t); 91 static void audigyls_write_ac97(void *, uint8_t, uint16_t); 92 static int audigyls_alloc_port(audigyls_dev_t *, int); 93 static void audigyls_destroy(audigyls_dev_t *); 94 static void audigyls_hwinit(audigyls_dev_t *); 95 static void audigyls_configure_mixer(audigyls_dev_t *dev); 96 97 static audio_engine_ops_t audigyls_engine_ops = { 98 AUDIO_ENGINE_VERSION, 99 audigyls_open, 100 audigyls_close, 101 audigyls_start, 102 audigyls_stop, 103 audigyls_count, 104 audigyls_format, 105 audigyls_channels, 106 audigyls_rate, 107 audigyls_sync, 108 NULL, 109 audigyls_chinfo, 110 NULL 111 }; 112 113 /* 114 * Audigy LS uses AC'97 strictly for the recording side of things. 115 * While the chip can supposedly route output to AC'97 for playback, 116 * the PCI devices use a separate I2S DAC instead. As a result we 117 * need to suppress controls that the AC'97 codec registers. 118 * 119 * Furthermore, even then the AC'97 codec offers inputs that we just 120 * aren't interested in. 121 */ 122 const char *audigyls_remove_ac97[] = { 123 AUDIO_CTRL_ID_VOLUME, 124 AUDIO_CTRL_ID_LINEOUT, 125 AUDIO_CTRL_ID_HEADPHONE, 126 AUDIO_CTRL_ID_CD, 127 AUDIO_CTRL_ID_VIDEO, 128 AUDIO_CTRL_ID_3DDEPTH, 129 AUDIO_CTRL_ID_3DENHANCE, 130 AUDIO_CTRL_ID_BEEP, 131 AUDIO_CTRL_ID_RECGAIN, 132 AUDIO_CTRL_ID_RECSRC, 133 AUDIO_CTRL_ID_LOOPBACK, 134 NULL, 135 }; 136 137 /* 138 * AC'97 sources we don't want to expose. 139 */ 140 const char *audigyls_badsrcs[] = { 141 AUDIO_PORT_VIDEO, 142 AUDIO_PORT_CD, 143 AUDIO_PORT_STEREOMIX, 144 AUDIO_PORT_MONOMIX, 145 NULL, 146 }; 147 148 static unsigned int 149 read_chan(audigyls_dev_t *dev, int reg, int chn) 150 { 151 uint32_t val; 152 153 mutex_enter(&dev->low_mutex); 154 /* Pointer */ 155 OUTL(dev, PR, (reg << 16) | (chn & 0xffff)); 156 /* Data */ 157 val = INL(dev, DR); 158 mutex_exit(&dev->low_mutex); 159 160 return (val); 161 } 162 163 static void 164 write_chan(audigyls_dev_t *dev, int reg, int chn, uint32_t value) 165 { 166 mutex_enter(&dev->low_mutex); 167 /* Pointer */ 168 OUTL(dev, PR, (reg << 16) | (chn & 0x7)); 169 /* Data */ 170 OUTL(dev, DR, value); 171 mutex_exit(&dev->low_mutex); 172 } 173 174 static unsigned int 175 read_reg(audigyls_dev_t *dev, int reg) 176 { 177 return (read_chan(dev, reg, 0)); 178 } 179 180 static void 181 write_reg(audigyls_dev_t *dev, int reg, uint32_t value) 182 { 183 write_chan(dev, reg, 0, value); 184 } 185 186 187 static uint16_t 188 audigyls_read_ac97(void *arg, uint8_t index) 189 { 190 audigyls_dev_t *dev = arg; 191 uint16_t dtemp = 0; 192 int i; 193 194 mutex_enter(&dev->low_mutex); 195 OUTB(dev, AC97A, index); 196 for (i = 0; i < 10000; i++) { 197 if (INB(dev, AC97A) & 0x80) 198 break; 199 } 200 if (i == 10000) { /* Timeout */ 201 mutex_exit(&dev->low_mutex); 202 return (0xffff); 203 } 204 dtemp = INW(dev, AC97D); 205 mutex_exit(&dev->low_mutex); 206 207 return (dtemp); 208 } 209 210 static void 211 audigyls_write_ac97(void *arg, uint8_t index, uint16_t data) 212 { 213 audigyls_dev_t *dev = arg; 214 int i; 215 216 mutex_enter(&dev->low_mutex); 217 OUTB(dev, AC97A, index); 218 for (i = 0; i < 50000; i++) { 219 if (INB(dev, AC97A) & 0x80) 220 break; 221 } 222 if (i == 50000) { 223 mutex_exit(&dev->low_mutex); 224 return; 225 } 226 OUTW(dev, AC97D, data); 227 mutex_exit(&dev->low_mutex); 228 } 229 230 static void 231 select_digital_enable(audigyls_dev_t *dev, int mode) 232 { 233 /* 234 * Set the out3/spdif combo jack format. 235 * mode0=analog rear/center, 1=spdif 236 */ 237 238 if (mode == 0) { 239 write_reg(dev, SPC, 0x00000f00); 240 } else { 241 write_reg(dev, SPC, 0x0000000f); 242 } 243 } 244 245 /* only for SBLive 7.1 */ 246 void 247 audigyls_i2c_write(audigyls_dev_t *dev, int reg, int data) 248 { 249 int i, timeout, tmp; 250 251 tmp = (reg << 9 | data) << 16; /* set the upper 16 bits */ 252 /* first write the command to the data reg */ 253 write_reg(dev, I2C_1, tmp); 254 for (i = 0; i < 20; i++) { 255 tmp = read_reg(dev, I2C_A) & ~0x6fe; 256 /* see audigyls.pdf for bits */ 257 tmp |= 0x400 | 0x100 | 0x34; 258 write_reg(dev, I2C_A, tmp); 259 /* now wait till controller sets valid bit (0x100) to 0 */ 260 timeout = 0; 261 for (;;) { 262 tmp = read_reg(dev, I2C_A); 263 if ((tmp & 0x100) == 0) 264 break; 265 266 if (timeout > 100) 267 break; 268 269 timeout++; 270 } 271 272 /* transaction aborted */ 273 if (tmp & 0x200) 274 break; 275 } 276 } 277 278 int 279 audigyls_spi_write(audigyls_dev_t *dev, int data) 280 { 281 unsigned int orig; 282 unsigned int tmp; 283 int i, valid; 284 285 tmp = read_reg(dev, SPI); 286 orig = (tmp & ~0x3ffff) | 0x30000; 287 write_reg(dev, SPI, orig | data); 288 valid = 0; 289 /* Wait for status bit to return to 0 */ 290 for (i = 0; i < 1000; i++) { 291 drv_usecwait(100); 292 tmp = read_reg(dev, SPI); 293 if (!(tmp & 0x10000)) { 294 valid = 1; 295 break; 296 } 297 } 298 if (!valid) /* Timed out */ 299 return (0); 300 301 return (1); 302 } 303 304 /* 305 * Audio routines 306 */ 307 308 int 309 audigyls_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp) 310 { 311 audigyls_port_t *port = arg; 312 audigyls_dev_t *dev = port->dev; 313 314 _NOTE(ARGUNUSED(flag)); 315 316 mutex_enter(&dev->mutex); 317 318 port->count = 0; 319 *nframesp = port->buf_frames; 320 *bufp = port->buf_kaddr; 321 mutex_exit(&dev->mutex); 322 323 return (0); 324 } 325 326 void 327 audigyls_close(void *arg) 328 { 329 _NOTE(ARGUNUSED(arg)); 330 } 331 332 int 333 audigyls_start(void *arg) 334 { 335 audigyls_port_t *port = arg; 336 audigyls_dev_t *dev = port->dev; 337 uint32_t tmp; 338 339 mutex_enter(&dev->mutex); 340 341 port->offset = 0; 342 343 switch (port->direction) { 344 case AUDIGYLS_PLAY_PORT: 345 write_chan(dev, PTCA, 0, 0); 346 write_chan(dev, CPFA, 0, 0); 347 write_chan(dev, CPCAV, 0, 0); 348 write_chan(dev, PTCA, 1, 0); 349 write_chan(dev, CPFA, 1, 0); 350 write_chan(dev, CPCAV, 1, 0); 351 write_chan(dev, PTCA, 3, 0); 352 write_chan(dev, CPFA, 3, 0); 353 write_chan(dev, CPCAV, 3, 0); 354 355 tmp = read_reg(dev, SA); 356 tmp |= SA_SPA(0); 357 tmp |= SA_SPA(1); 358 tmp |= SA_SPA(3); 359 write_reg(dev, SA, tmp); 360 break; 361 362 case AUDIGYLS_REC_PORT: 363 write_chan(dev, CRFA, 2, 0); 364 write_chan(dev, CRCAV, 2, 0); 365 366 tmp = read_reg(dev, SA); 367 tmp |= SA_SRA(2); 368 write_reg(dev, SA, tmp); 369 break; 370 } 371 372 mutex_exit(&dev->mutex); 373 return (0); 374 } 375 376 void 377 audigyls_stop(void *arg) 378 { 379 audigyls_port_t *port = arg; 380 audigyls_dev_t *dev = port->dev; 381 uint32_t tmp; 382 383 mutex_enter(&dev->mutex); 384 385 switch (port->direction) { 386 case AUDIGYLS_PLAY_PORT: 387 tmp = read_reg(dev, SA); 388 tmp &= ~SA_SPA(0); 389 tmp &= ~SA_SPA(1); 390 tmp &= ~SA_SPA(3); 391 write_reg(dev, SA, tmp); 392 break; 393 394 case AUDIGYLS_REC_PORT: 395 tmp = read_reg(dev, SA); 396 tmp &= ~SA_SRA(2); 397 write_reg(dev, SA, tmp); 398 break; 399 } 400 401 mutex_exit(&dev->mutex); 402 } 403 404 int 405 audigyls_format(void *arg) 406 { 407 _NOTE(ARGUNUSED(arg)); 408 409 return (AUDIO_FORMAT_S16_LE); 410 } 411 412 int 413 audigyls_channels(void *arg) 414 { 415 audigyls_port_t *port = arg; 416 417 return (port->nchan); 418 } 419 420 int 421 audigyls_rate(void *arg) 422 { 423 _NOTE(ARGUNUSED(arg)); 424 425 return (48000); 426 } 427 428 void 429 audigyls_sync(void *arg, unsigned nframes) 430 { 431 audigyls_port_t *port = arg; 432 _NOTE(ARGUNUSED(nframes)); 433 434 (void) ddi_dma_sync(port->buf_dmah, 0, 0, port->syncdir); 435 } 436 437 uint64_t 438 audigyls_count(void *arg) 439 { 440 audigyls_port_t *port = arg; 441 audigyls_dev_t *dev = port->dev; 442 uint64_t count; 443 uint32_t offset, n; 444 445 mutex_enter(&dev->mutex); 446 447 if (port->direction == AUDIGYLS_PLAY_PORT) { 448 offset = read_chan(dev, CPFA, 0); 449 } else { 450 offset = read_chan(dev, CRFA, 2); 451 } 452 453 /* get the offset, and switch to frames */ 454 offset /= (2 * sizeof (uint16_t)); 455 456 if (offset >= port->offset) { 457 n = offset - port->offset; 458 } else { 459 n = offset + (port->buf_frames - port->offset); 460 } 461 port->offset = offset; 462 port->count += n; 463 464 count = port->count; 465 mutex_exit(&dev->mutex); 466 return (count); 467 } 468 469 static void 470 audigyls_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 471 { 472 audigyls_port_t *port = arg; 473 474 if (port->direction == AUDIGYLS_PLAY_PORT) { 475 *offset = (port->buf_frames * 2 * (chan / 2)) + (chan % 2); 476 *incr = 2; 477 } else { 478 *offset = chan; 479 *incr = 2; 480 } 481 } 482 483 /* private implementation bits */ 484 485 int 486 audigyls_alloc_port(audigyls_dev_t *dev, int num) 487 { 488 audigyls_port_t *port; 489 size_t len; 490 ddi_dma_cookie_t cookie; 491 uint_t count; 492 int dir; 493 unsigned caps; 494 audio_dev_t *adev; 495 496 adev = dev->adev; 497 port = kmem_zalloc(sizeof (*port), KM_SLEEP); 498 dev->port[num] = port; 499 port->dev = dev; 500 port->direction = num; 501 502 switch (num) { 503 case AUDIGYLS_REC_PORT: 504 port->syncdir = DDI_DMA_SYNC_FORKERNEL; 505 caps = ENGINE_INPUT_CAP; 506 dir = DDI_DMA_READ; 507 port->nchan = 2; 508 break; 509 case AUDIGYLS_PLAY_PORT: 510 port->syncdir = DDI_DMA_SYNC_FORDEV; 511 caps = ENGINE_OUTPUT_CAP; 512 dir = DDI_DMA_WRITE; 513 port->nchan = 6; 514 break; 515 default: 516 return (DDI_FAILURE); 517 } 518 519 port->buf_frames = 2048; 520 port->buf_size = port->buf_frames * port->nchan * sizeof (int16_t); 521 522 /* Alloc buffers */ 523 if (ddi_dma_alloc_handle(dev->dip, &dma_attr_buf, DDI_DMA_SLEEP, NULL, 524 &port->buf_dmah) != DDI_SUCCESS) { 525 audio_dev_warn(adev, "failed to allocate BUF handle"); 526 return (DDI_FAILURE); 527 } 528 529 if (ddi_dma_mem_alloc(port->buf_dmah, port->buf_size, 530 &buf_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 531 &port->buf_kaddr, &len, &port->buf_acch) != DDI_SUCCESS) { 532 audio_dev_warn(adev, "failed to allocate BUF memory"); 533 return (DDI_FAILURE); 534 } 535 536 if (ddi_dma_addr_bind_handle(port->buf_dmah, NULL, port->buf_kaddr, 537 len, DDI_DMA_CONSISTENT | dir, DDI_DMA_SLEEP, NULL, &cookie, 538 &count) != DDI_SUCCESS) { 539 audio_dev_warn(adev, "failed binding BUF DMA handle"); 540 return (DDI_FAILURE); 541 } 542 port->buf_paddr = cookie.dmac_address; 543 544 port->engine = audio_engine_alloc(&audigyls_engine_ops, caps); 545 if (port->engine == NULL) { 546 audio_dev_warn(adev, "audio_engine_alloc failed"); 547 return (DDI_FAILURE); 548 } 549 550 audio_engine_set_private(port->engine, port); 551 audio_dev_add_engine(adev, port->engine); 552 553 return (DDI_SUCCESS); 554 } 555 556 void 557 audigyls_del_controls(audigyls_dev_t *dev) 558 { 559 for (int i = 0; i < CTL_NUM; i++) { 560 if (dev->controls[i].ctrl) { 561 audio_dev_del_control(dev->controls[i].ctrl); 562 dev->controls[i].ctrl = NULL; 563 } 564 } 565 } 566 567 void 568 audigyls_destroy(audigyls_dev_t *dev) 569 { 570 mutex_destroy(&dev->mutex); 571 mutex_destroy(&dev->low_mutex); 572 573 for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) { 574 audigyls_port_t *port = dev->port[i]; 575 if (!port) 576 continue; 577 if (port->engine) { 578 audio_dev_remove_engine(dev->adev, port->engine); 579 audio_engine_free(port->engine); 580 } 581 if (port->buf_paddr) { 582 (void) ddi_dma_unbind_handle(port->buf_dmah); 583 } 584 if (port->buf_acch) { 585 ddi_dma_mem_free(&port->buf_acch); 586 } 587 if (port->buf_dmah) { 588 ddi_dma_free_handle(&port->buf_dmah); 589 } 590 kmem_free(port, sizeof (*port)); 591 } 592 593 if (dev->ac97 != NULL) { 594 ac97_free(dev->ac97); 595 } 596 597 audigyls_del_controls(dev); 598 599 if (dev->adev != NULL) { 600 audio_dev_free(dev->adev); 601 } 602 if (dev->regsh != NULL) { 603 ddi_regs_map_free(&dev->regsh); 604 } 605 if (dev->pcih != NULL) { 606 pci_config_teardown(&dev->pcih); 607 } 608 kmem_free(dev, sizeof (*dev)); 609 } 610 611 void 612 audigyls_hwinit(audigyls_dev_t *dev) 613 { 614 static unsigned int spi_dac[] = { 615 0x00ff, 0x02ff, 0x0400, 0x520, 0x0620, 0x08ff, 0x0aff, 0x0cff, 616 0x0eff, 0x10ff, 0x1200, 0x1400, 0x1800, 0x1aff, 0x1cff, 617 0x1e00, 0x0530, 0x0602, 0x0622, 0x1400, 618 }; 619 620 uint32_t tmp; 621 int i, tries; 622 uint32_t paddr; 623 uint32_t chunksz; 624 audigyls_port_t *port; 625 626 627 /* Set the orange jack to be analog out or S/PDIF */ 628 select_digital_enable(dev, dev->digital_enable); 629 630 /* 631 * In P17, there's 8 GPIO pins. 632 * GPIO register: 0x00XXYYZZ 633 * XX: Configure GPIO to be either GPI (0) or GPO (1). 634 * YY: GPO values, applicable if the pin is configure to be GPO. 635 * ZZ: GPI values, applicable if the pin is configure to be GPI. 636 * 637 * in SB570, pin 0-4 and 6 is used as GPO and pin 5 and 7 is 638 * used as GPI. 639 * 640 * GPO0: 641 * 1 ==> Analog output 642 * 0 ==> Digital output 643 * GPO1: 644 * 1 ==> Enable output on card 645 * 0 ==> Disable output on card 646 * GPO2: 647 * 1 ==> Enable Mic Bias and Mic Path 648 * 0 ==> Disable Mic Bias and Mic Path 649 * GPO3: 650 * 1 ==> Disable SPDIF-IO output 651 * 0 ==> Enable SPDIF-IO output 652 * GPO4 and GPO6: 653 * DAC sampling rate selection: 654 * Not applicable to SB570 since DAC is controlled through SPI 655 * GPI5: 656 * 1 ==> Front Panel is not connected 657 * 0 ==> Front Panel is connected 658 * GPI7: 659 * 1 ==> Front Panel Headphone is not connected 660 * 0 ==> Front Panel Headphone is connected 661 */ 662 if (dev->ac97) 663 OUTL(dev, GPIO, 0x005f03a3); 664 else { 665 /* for SBLive 7.1 */ 666 OUTL(dev, GPIO, 0x005f4301); 667 668 audigyls_i2c_write(dev, 0x15, 0x2); 669 tries = 0; 670 again: 671 for (i = 0; i < (sizeof (spi_dac) / sizeof (spi_dac[0])); i++) { 672 if (!audigyls_spi_write(dev, spi_dac[i]) && 673 tries < 100) { 674 tries++; 675 goto again; 676 } 677 } 678 } 679 680 OUTL(dev, IER, 0); 681 OUTL(dev, HC, 0x00000009); /* Enable audio, use 48 kHz */ 682 683 tmp = read_chan(dev, SRCTL, 0); 684 if (dev->ac97) 685 tmp |= 0xf0c81000; /* Record src0/src1 from ac97 */ 686 else 687 tmp |= 0x50c81000; /* Record src0/src1 from I2SIN */ 688 tmp &= ~0x0303c00f; /* Set sample rates to 48 kHz */ 689 write_chan(dev, SRCTL, 0, tmp); 690 691 write_reg(dev, HMIXMAP_I2S, 0x76543210); /* Default out route */ 692 write_reg(dev, AUDCTL, 0x0f0f003f); /* Enable all outputs */ 693 694 /* All audio stopped! */ 695 write_reg(dev, SA, 0); 696 697 for (i = 0; i < 4; i++) { 698 /* 699 * Reset DMA pointers and counters. Note that we do 700 * not use scatter/gather. 701 */ 702 write_chan(dev, PTBA, i, 0); 703 write_chan(dev, PTBS, i, 0); 704 write_chan(dev, PTCA, i, 0); 705 706 write_chan(dev, CPFA, i, 0); 707 write_chan(dev, PFEA, i, 0); 708 write_chan(dev, CPCAV, i, 0); 709 710 write_chan(dev, CRFA, i, 0); 711 write_chan(dev, CRCAV, i, 0); 712 } 713 714 /* 715 * The 5.1 play port made up channels 0, 1, and 3. The record 716 * port is channel 2. 717 */ 718 port = dev->port[AUDIGYLS_PLAY_PORT]; 719 paddr = port->buf_paddr; 720 chunksz = port->buf_frames * 4; 721 write_chan(dev, PFBA, 0, paddr); 722 write_chan(dev, PFBS, 0, chunksz << 16); 723 paddr += chunksz; 724 write_chan(dev, PFBA, 1, paddr); 725 write_chan(dev, PFBS, 1, chunksz << 16); 726 paddr += chunksz; 727 write_chan(dev, PFBA, 3, paddr); 728 write_chan(dev, PFBS, 3, chunksz << 16); 729 730 /* Record */ 731 port = dev->port[AUDIGYLS_REC_PORT]; 732 paddr = port->buf_paddr; 733 chunksz = port->buf_frames * 4; 734 write_chan(dev, RFBA, 2, paddr); 735 write_chan(dev, RFBS, 2, chunksz << 16); 736 737 /* Set sample rates to 48 kHz. */ 738 tmp = read_chan(dev, SRCTL, 0) & ~0x0303c00f; 739 write_chan(dev, SRCTL, 0, tmp); 740 741 write_reg(dev, SCS0, 0x02108004); /* Audio */ 742 write_reg(dev, SCS1, 0x02108004); /* Audio */ 743 write_reg(dev, SCS2, 0x02108004); /* Audio */ 744 write_reg(dev, SCS3, 0x02108004); /* Audio */ 745 } 746 747 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 748 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 749 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 750 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 751 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 752 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 753 #define MONVOL (MONCTL | AUDIO_CTRL_FLAG_MONVOL) 754 755 #define MASK(nbits) ((1 << (nbits)) - 1) 756 #define SCALE(val, nbits) \ 757 ((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits))) 758 759 static uint32_t 760 audigyls_stereo_scale(uint32_t value, uint8_t bits) 761 { 762 uint8_t left, right; 763 uint32_t val; 764 765 left = (value >> 8) & 0xff; 766 right = value & 0xff; 767 768 val = (((left * ((1 << bits) - 1) / 100) << 8) | 769 (right * ((1 << bits) - 1) / 100)); 770 return (val); 771 } 772 773 static void 774 audigyls_configure_mixer(audigyls_dev_t *dev) 775 { 776 unsigned int r, v1, v2; 777 778 /* output items */ 779 /* front */ 780 r = 0xffff - audigyls_stereo_scale(dev->controls[CTL_FRONT].val, 8); 781 r = (r << 16) | r; 782 write_chan(dev, MIXVOL_I2S, 0, r); 783 784 /* surround */ 785 r = 0xffff - audigyls_stereo_scale(dev->controls[CTL_SURROUND].val, 8); 786 r = (r << 16) | r; 787 write_chan(dev, MIXVOL_I2S, 3, r); 788 789 /* center/lfe */ 790 v1 = 255 - SCALE(dev->controls[CTL_CENTER].val, 8); 791 v2 = 255 - SCALE(dev->controls[CTL_LFE].val, 8); 792 r = (v1 << 8) | v2; 793 r = (r << 16) | r; 794 write_chan(dev, MIXVOL_I2S, 1, r); 795 796 /* spread */ 797 r = dev->controls[CTL_SPREAD].val ? 0x10101010 : 0x76543210; 798 write_reg(dev, HMIXMAP_I2S, r); 799 800 /* input items */ 801 802 /* recgain */ 803 v1 = dev->controls[CTL_RECORDVOL].val; 804 if (dev->ac97_recgain && !dev->controls[CTL_LOOP].val) { 805 /* 806 * For AC'97, we use the AC'97 record gain, unless we are 807 * in loopback. 808 */ 809 (void) ac97_control_set(dev->ac97_recgain, v1); 810 write_reg(dev, P17RECVOLL, 0x30303030); 811 write_reg(dev, P17RECVOLH, 0x30303030); 812 } else { 813 /* 814 * Otherwise we set the P17 gain. 815 */ 816 r = 0xffff - audigyls_stereo_scale(v1, 8); 817 r = r << 16 | r; 818 write_reg(dev, P17RECVOLL, r); 819 write_reg(dev, P17RECVOLH, r); 820 } 821 822 /* monitor gain */ 823 if (dev->ac97) { 824 /* AC'97 monitor gain is done by the AC'97 codec */ 825 write_chan(dev, SRCTL, 1, 0x30303030); 826 write_reg(dev, SMIXMAP_I2S, 0x10101076); 827 } else { 828 /* For non-AC'97 devices, just a single master monitor gain */ 829 r = 255 - SCALE(dev->controls[CTL_MONGAIN].val, 8); 830 write_chan(dev, SRCTL, 1, 0xffff0000 | r << 8 | r); 831 if (r != 0xff) { 832 write_reg(dev, SMIXMAP_I2S, 0x10101076); 833 } else { 834 write_reg(dev, SMIXMAP_I2S, 0x10101010); 835 } 836 } 837 838 /* record source */ 839 if (dev->ac97_recsrc != NULL) { 840 (void) ac97_control_set(dev->ac97_recsrc, 841 dev->controls[CTL_RECSRC].val); 842 v1 = RECSEL_AC97; /* Audigy LS */ 843 } else { 844 switch (dev->controls[CTL_RECSRC].val) { 845 case 1: 846 audigyls_i2c_write(dev, 0x15, 0x2); /* Mic */ 847 OUTL(dev, GPIO, INL(dev, GPIO) | 0x400); 848 break; 849 850 case 2: 851 audigyls_i2c_write(dev, 0x15, 0x4); /* Line */ 852 OUTL(dev, GPIO, INL(dev, GPIO) & ~0x400); 853 break; 854 } 855 v1 = RECSEL_I2SIN; /* SB 7.1 value */ 856 } 857 858 /* If loopback, record what you hear instead */ 859 860 if (dev->controls[CTL_LOOP].val) { 861 r = 0; 862 v1 = RECSEL_I2SOUT; 863 r |= (v1 << 28) | (v1 << 24) | (v1 << 20) | (v1 << 16) | v1; 864 } else { 865 /* 866 * You'd think this would be the same as the logic 867 * above, but experience shows that what you need for 868 * loopback is different. This whole thing looks 869 * particularly fishy to me. I suspect someone has 870 * made a mistake somewhere. But I can't seem to 871 * figure out where it lies. 872 */ 873 if (dev->ac97_recsrc != NULL) { 874 r = 0xe4; 875 for (int i = 0; i < 4; i++) 876 r |= v1 << (16 + i * 3); /* Select input */ 877 } else { 878 r = (v1 << 28) | (v1 << 24) | (v1 << 20) | (v1 << 16) | 879 v1; 880 } 881 } 882 883 write_reg(dev, P17RECSEL, r); 884 } 885 886 static int 887 audigyls_set_control(void *arg, uint64_t val) 888 { 889 audigyls_ctrl_t *pc = arg; 890 audigyls_dev_t *dev = pc->dev; 891 892 switch (pc->num) { 893 894 case CTL_FRONT: 895 case CTL_SURROUND: 896 case CTL_RECORDVOL: 897 if (((val & 0xff) > 100) || 898 (((val & 0xff00) >> 8) > 100) || 899 ((val & ~0xffff) != 0)) { 900 return (EINVAL); 901 } 902 break; 903 904 case CTL_CENTER: 905 case CTL_LFE: 906 case CTL_MONGAIN: 907 if (val > 100) { 908 return (EINVAL); 909 } 910 break; 911 912 case CTL_RECSRC: 913 if (((1U << val) & (dev->recmask)) == 0) { 914 return (EINVAL); 915 } 916 break; 917 918 case CTL_SPREAD: 919 case CTL_LOOP: 920 switch (val) { 921 case 0: 922 case 1: 923 break; 924 default: 925 return (EINVAL); 926 } 927 } 928 929 mutex_enter(&dev->mutex); 930 pc->val = val; 931 audigyls_configure_mixer(dev); 932 933 mutex_exit(&dev->mutex); 934 935 return (0); 936 } 937 938 static int 939 audigyls_get_control(void *arg, uint64_t *val) 940 { 941 audigyls_ctrl_t *pc = arg; 942 audigyls_dev_t *dev = pc->dev; 943 944 mutex_enter(&dev->mutex); 945 *val = pc->val; 946 mutex_exit(&dev->mutex); 947 return (0); 948 } 949 950 static void 951 audigyls_alloc_ctrl(audigyls_dev_t *dev, uint32_t num, uint64_t val) 952 { 953 audio_ctrl_desc_t desc; 954 audigyls_ctrl_t *pc; 955 956 bzero(&desc, sizeof (desc)); 957 958 pc = &dev->controls[num]; 959 pc->num = num; 960 pc->dev = dev; 961 962 963 switch (num) { 964 case CTL_FRONT: 965 desc.acd_name = AUDIO_CTRL_ID_FRONT; 966 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 967 desc.acd_minvalue = 0; 968 desc.acd_maxvalue = 100; 969 desc.acd_flags = MAINVOL; 970 break; 971 972 case CTL_SURROUND: 973 desc.acd_name = AUDIO_CTRL_ID_SURROUND; 974 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 975 desc.acd_minvalue = 0; 976 desc.acd_maxvalue = 100; 977 desc.acd_flags = MAINVOL; 978 break; 979 980 case CTL_CENTER: 981 desc.acd_name = AUDIO_CTRL_ID_CENTER; 982 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 983 desc.acd_minvalue = 0; 984 desc.acd_maxvalue = 100; 985 desc.acd_flags = MAINVOL; 986 break; 987 988 case CTL_LFE: 989 desc.acd_name = AUDIO_CTRL_ID_LFE; 990 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 991 desc.acd_minvalue = 0; 992 desc.acd_maxvalue = 100; 993 desc.acd_flags = MAINVOL; 994 break; 995 996 case CTL_RECORDVOL: 997 desc.acd_name = AUDIO_CTRL_ID_RECGAIN; 998 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 999 desc.acd_minvalue = 0; 1000 desc.acd_maxvalue = 100; 1001 desc.acd_flags = RECVOL; 1002 break; 1003 1004 case CTL_RECSRC: 1005 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 1006 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1007 desc.acd_flags = RECCTL; 1008 1009 /* 1010 * For AC'97 devices, we want to expose the reasonable 1011 * AC'97 input sources, but suppress the stereomix, 1012 * because we use loopback instead. 1013 */ 1014 if (dev->ac97_recsrc) { 1015 int i, j; 1016 const char *n; 1017 const audio_ctrl_desc_t *adp; 1018 1019 adp = ac97_control_desc(dev->ac97_recsrc); 1020 for (i = 0; i < 64; i++) { 1021 n = adp->acd_enum[i]; 1022 1023 if (((adp->acd_minvalue & (1 << i)) == 0) || 1024 (n == NULL)) { 1025 continue; 1026 } 1027 for (j = 0; audigyls_badsrcs[j]; j++) { 1028 if (strcmp(n, audigyls_badsrcs[j]) 1029 == 0) { 1030 n = NULL; 1031 break; 1032 } 1033 } 1034 if (n) { 1035 desc.acd_enum[i] = n; 1036 dev->recmask |= (1 << i); 1037 } 1038 } 1039 desc.acd_minvalue = desc.acd_maxvalue = dev->recmask; 1040 } else { 1041 dev->recmask = 3; 1042 desc.acd_minvalue = 3; 1043 desc.acd_maxvalue = 3; 1044 desc.acd_enum[0] = AUDIO_PORT_MIC; 1045 desc.acd_enum[1] = AUDIO_PORT_LINEIN; 1046 } 1047 break; 1048 1049 case CTL_MONGAIN: 1050 ASSERT(!dev->ac97); 1051 desc.acd_name = AUDIO_CTRL_ID_MONGAIN; 1052 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1053 desc.acd_minvalue = 0; 1054 desc.acd_maxvalue = 100; 1055 desc.acd_flags = MONVOL; 1056 break; 1057 1058 case CTL_SPREAD: 1059 desc.acd_name = AUDIO_CTRL_ID_SPREAD; 1060 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1061 desc.acd_minvalue = 0; 1062 desc.acd_maxvalue = 1; 1063 desc.acd_flags = PLAYCTL; 1064 break; 1065 1066 case CTL_LOOP: 1067 desc.acd_name = AUDIO_CTRL_ID_LOOPBACK; 1068 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1069 desc.acd_minvalue = 0; 1070 desc.acd_maxvalue = 1; 1071 desc.acd_flags = RECCTL; 1072 break; 1073 } 1074 1075 pc->val = val; 1076 pc->ctrl = audio_dev_add_control(dev->adev, &desc, 1077 audigyls_get_control, audigyls_set_control, pc); 1078 } 1079 1080 static void 1081 audigyls_add_controls(audigyls_dev_t *dev) 1082 { 1083 audio_dev_add_soft_volume(dev->adev); 1084 1085 audigyls_alloc_ctrl(dev, CTL_FRONT, 75 | (75 << 8)); 1086 audigyls_alloc_ctrl(dev, CTL_SURROUND, 75 | (75 << 8)); 1087 audigyls_alloc_ctrl(dev, CTL_CENTER, 75); 1088 audigyls_alloc_ctrl(dev, CTL_LFE, 75); 1089 audigyls_alloc_ctrl(dev, CTL_RECORDVOL, 75 | (75 << 8)); 1090 audigyls_alloc_ctrl(dev, CTL_RECSRC, 1); 1091 audigyls_alloc_ctrl(dev, CTL_SPREAD, 0); 1092 audigyls_alloc_ctrl(dev, CTL_LOOP, 0); 1093 if (!dev->ac97) { 1094 audigyls_alloc_ctrl(dev, CTL_MONGAIN, 0); 1095 } 1096 } 1097 1098 int 1099 audigyls_attach(dev_info_t *dip) 1100 { 1101 uint16_t pci_command, vendor, device; 1102 uint32_t subdevice; 1103 audigyls_dev_t *dev; 1104 ddi_acc_handle_t pcih; 1105 const char *name, *version; 1106 boolean_t ac97 = B_FALSE; 1107 1108 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1109 dev->dip = dip; 1110 ddi_set_driver_private(dip, dev); 1111 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL); 1112 mutex_init(&dev->low_mutex, NULL, MUTEX_DRIVER, NULL); 1113 1114 if ((dev->adev = audio_dev_alloc(dip, 0)) == NULL) { 1115 cmn_err(CE_WARN, "audio_dev_alloc failed"); 1116 goto error; 1117 } 1118 1119 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1120 audio_dev_warn(dev->adev, "pci_config_setup failed"); 1121 goto error; 1122 } 1123 dev->pcih = pcih; 1124 1125 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1126 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1127 subdevice = pci_config_get16(pcih, PCI_CONF_SUBVENID); 1128 subdevice <<= 16; 1129 subdevice |= pci_config_get16(pcih, PCI_CONF_SUBSYSID); 1130 if (vendor != PCI_VENDOR_ID_CREATIVE || 1131 device != PCI_DEVICE_ID_CREATIVE_AUDIGYLS) { 1132 audio_dev_warn(dev->adev, "Hardware not recognized " 1133 "(vendor=%x, dev=%x)", vendor, device); 1134 goto error; 1135 } 1136 1137 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1138 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1139 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1140 1141 if ((ddi_regs_map_setup(dip, 1, &dev->base, 0, 0, &dev_attr, 1142 &dev->regsh)) != DDI_SUCCESS) { 1143 audio_dev_warn(dev->adev, "failed to map registers"); 1144 goto error; 1145 } 1146 1147 /* Function of the orange jack: 0=analog, 1=digital */ 1148 dev->digital_enable = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 1149 DDI_PROP_DONTPASS, "digital-enable", 0); 1150 1151 switch (subdevice) { 1152 case 0x11021001: /* SB0310 */ 1153 case 0x11021002: /* SB0310 */ 1154 case 0x11021005: /* SB0310b */ 1155 name = "Creative Audigy LS"; 1156 version = "SB0310"; /* could also be SB0312 */ 1157 ac97 = B_TRUE; 1158 break; 1159 case 0x11021006: 1160 name = "Creative Sound Blaster Live! 24 bit"; 1161 version = "SB0410"; 1162 break; 1163 case 0x11021007: /* Dell OEM version */ 1164 name = "Creative Sound Blaster Live! 24 bit"; 1165 version = "SB0413"; 1166 break; 1167 case 0x1102100a: 1168 name = "Creative Audigy SE"; 1169 version = "SB0570"; 1170 break; 1171 case 0x11021011: 1172 name = "Creative Audigy SE OEM"; 1173 version = "SB0570a"; 1174 break; 1175 case 0x11021012: 1176 name = "Creative X-Fi Extreme Audio"; 1177 version = "SB0790"; 1178 break; 1179 case 0x14621009: 1180 name = "MSI K8N Diamond MB"; 1181 version = "SB0438"; 1182 break; 1183 case 0x12973038: 1184 name = "Shuttle XPC SD31P"; 1185 version = "SD31P"; 1186 break; 1187 case 0x12973041: 1188 name = "Shuttle XPC SD11G5"; 1189 version = "SD11G5"; 1190 break; 1191 default: 1192 name = "Creative Audigy LS"; 1193 version = NULL; 1194 break; 1195 } 1196 1197 audio_dev_set_description(dev->adev, name); 1198 if (version) 1199 audio_dev_set_version(dev->adev, version); 1200 1201 if (ac97) { 1202 ac97_ctrl_t *ctrl; 1203 1204 /* Original Audigy LS revision (AC97 based) */ 1205 dev->ac97 = ac97_allocate(dev->adev, dip, 1206 audigyls_read_ac97, audigyls_write_ac97, dev); 1207 if (dev->ac97 == NULL) { 1208 audio_dev_warn(dev->adev, 1209 "failed to allocate ac97 handle"); 1210 goto error; 1211 } 1212 1213 ac97_probe_controls(dev->ac97); 1214 1215 /* remove the AC'97 controls we don't want to expose */ 1216 for (int i = 0; audigyls_remove_ac97[i]; i++) { 1217 ctrl = ac97_control_find(dev->ac97, 1218 audigyls_remove_ac97[i]); 1219 if (ctrl != NULL) { 1220 ac97_control_unregister(ctrl); 1221 } 1222 } 1223 1224 dev->ac97_recgain = ac97_control_find(dev->ac97, 1225 AUDIO_CTRL_ID_RECGAIN); 1226 dev->ac97_recsrc = ac97_control_find(dev->ac97, 1227 AUDIO_CTRL_ID_RECSRC); 1228 } 1229 1230 audigyls_add_controls(dev); 1231 1232 if (dev->ac97) { 1233 ac97_register_controls(dev->ac97); 1234 } 1235 1236 if (audigyls_alloc_port(dev, AUDIGYLS_PLAY_PORT) != DDI_SUCCESS) 1237 goto error; 1238 if (audigyls_alloc_port(dev, AUDIGYLS_REC_PORT) != DDI_SUCCESS) 1239 goto error; 1240 1241 audigyls_hwinit(dev); 1242 1243 audigyls_configure_mixer(dev); 1244 1245 if (audio_dev_register(dev->adev) != DDI_SUCCESS) { 1246 audio_dev_warn(dev->adev, "unable to register with framework"); 1247 goto error; 1248 } 1249 1250 ddi_report_dev(dip); 1251 1252 return (DDI_SUCCESS); 1253 1254 error: 1255 audigyls_destroy(dev); 1256 return (DDI_FAILURE); 1257 } 1258 1259 int 1260 audigyls_resume(dev_info_t *dip) 1261 { 1262 audigyls_dev_t *dev; 1263 1264 dev = ddi_get_driver_private(dip); 1265 1266 audigyls_hwinit(dev); 1267 1268 /* allow ac97 operations again */ 1269 if (dev->ac97) 1270 ac97_reset(dev->ac97); 1271 1272 audio_dev_resume(dev->adev); 1273 1274 return (DDI_SUCCESS); 1275 } 1276 1277 int 1278 audigyls_detach(audigyls_dev_t *dev) 1279 { 1280 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS) 1281 return (DDI_FAILURE); 1282 1283 audigyls_destroy(dev); 1284 return (DDI_SUCCESS); 1285 } 1286 1287 int 1288 audigyls_suspend(audigyls_dev_t *dev) 1289 { 1290 audio_dev_suspend(dev->adev); 1291 1292 return (DDI_SUCCESS); 1293 } 1294 1295 static int audigyls_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 1296 static int audigyls_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 1297 static int audigyls_ddi_quiesce(dev_info_t *); 1298 1299 static struct dev_ops audigyls_dev_ops = { 1300 DEVO_REV, /* rev */ 1301 0, /* refcnt */ 1302 NULL, /* getinfo */ 1303 nulldev, /* identify */ 1304 nulldev, /* probe */ 1305 audigyls_ddi_attach, /* attach */ 1306 audigyls_ddi_detach, /* detach */ 1307 nodev, /* reset */ 1308 NULL, /* cb_ops */ 1309 NULL, /* bus_ops */ 1310 NULL, /* power */ 1311 audigyls_ddi_quiesce, /* quiesce */ 1312 }; 1313 1314 static struct modldrv audigyls_modldrv = { 1315 &mod_driverops, /* drv_modops */ 1316 "Creative Audigy LS Audio", /* linkinfo */ 1317 &audigyls_dev_ops, /* dev_ops */ 1318 }; 1319 1320 static struct modlinkage modlinkage = { 1321 MODREV_1, 1322 { &audigyls_modldrv, NULL } 1323 }; 1324 1325 int 1326 _init(void) 1327 { 1328 int rv; 1329 1330 audio_init_ops(&audigyls_dev_ops, AUDIGYLS_NAME); 1331 if ((rv = mod_install(&modlinkage)) != 0) { 1332 audio_fini_ops(&audigyls_dev_ops); 1333 } 1334 return (rv); 1335 } 1336 1337 int 1338 _fini(void) 1339 { 1340 int rv; 1341 1342 if ((rv = mod_remove(&modlinkage)) == 0) { 1343 audio_fini_ops(&audigyls_dev_ops); 1344 } 1345 return (rv); 1346 } 1347 1348 int 1349 _info(struct modinfo *modinfop) 1350 { 1351 return (mod_info(&modlinkage, modinfop)); 1352 } 1353 1354 int 1355 audigyls_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1356 { 1357 switch (cmd) { 1358 case DDI_ATTACH: 1359 return (audigyls_attach(dip)); 1360 1361 case DDI_RESUME: 1362 return (audigyls_resume(dip)); 1363 1364 default: 1365 return (DDI_FAILURE); 1366 } 1367 } 1368 1369 int 1370 audigyls_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1371 { 1372 audigyls_dev_t *dev; 1373 1374 dev = ddi_get_driver_private(dip); 1375 1376 switch (cmd) { 1377 case DDI_DETACH: 1378 return (audigyls_detach(dev)); 1379 1380 case DDI_SUSPEND: 1381 return (audigyls_suspend(dev)); 1382 1383 default: 1384 return (DDI_FAILURE); 1385 } 1386 } 1387 1388 int 1389 audigyls_ddi_quiesce(dev_info_t *dip) 1390 { 1391 audigyls_dev_t *dev; 1392 uint32_t status; 1393 1394 /* 1395 * Turn off the hardware 1396 */ 1397 dev = ddi_get_driver_private(dip); 1398 1399 write_reg(dev, SA, 0); 1400 OUTL(dev, IER, 0); /* Interrupt disable */ 1401 write_reg(dev, AIE, 0); /* Disable audio interrupts */ 1402 status = INL(dev, IPR); 1403 OUTL(dev, IPR, status); /* Acknowledge */ 1404 return (DDI_SUCCESS); 1405 } 1406