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