6939934 boomer needs engine scheduling overhaul
[unleashed.git] / usr / src / uts / common / io / audio / drv / audiols / audiols.c
blobad5bd088c43bf5aff229fbf553d105591e34ed77
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Purpose: Driver for the Creative Audigy LS sound card
30 * Copyright (C) 4Front Technologies 1996-2009.
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>
44 #include "audiols.h"
46 static struct ddi_device_acc_attr dev_attr = {
47 DDI_DEVICE_ATTR_V0,
48 DDI_STRUCTURE_LE_ACC,
49 DDI_STRICTORDER_ACC
52 static struct ddi_device_acc_attr buf_attr = {
53 DDI_DEVICE_ATTR_V0,
54 DDI_NEVERSWAP_ACC,
55 DDI_STRICTORDER_ACC
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 */
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 *);
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 *);
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);
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
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.
119 * Furthermore, even then the AC'97 codec offers inputs that we just
120 * aren't interested in.
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,
138 * AC'97 sources we don't want to expose.
140 const char *audigyls_badsrcs[] = {
141 AUDIO_PORT_VIDEO,
142 AUDIO_PORT_CD,
143 AUDIO_PORT_STEREOMIX,
144 AUDIO_PORT_MONOMIX,
145 NULL,
148 static unsigned int
149 read_chan(audigyls_dev_t *dev, int reg, int chn)
151 uint32_t val;
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);
160 return (val);
163 static void
164 write_chan(audigyls_dev_t *dev, int reg, int chn, uint32_t value)
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);
174 static unsigned int
175 read_reg(audigyls_dev_t *dev, int reg)
177 return (read_chan(dev, reg, 0));
180 static void
181 write_reg(audigyls_dev_t *dev, int reg, uint32_t value)
183 write_chan(dev, reg, 0, value);
187 static uint16_t
188 audigyls_read_ac97(void *arg, uint8_t index)
190 audigyls_dev_t *dev = arg;
191 uint16_t dtemp = 0;
192 int i;
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;
200 if (i == 10000) { /* Timeout */
201 mutex_exit(&dev->low_mutex);
202 return (0xffff);
204 dtemp = INW(dev, AC97D);
205 mutex_exit(&dev->low_mutex);
207 return (dtemp);
210 static void
211 audigyls_write_ac97(void *arg, uint8_t index, uint16_t data)
213 audigyls_dev_t *dev = arg;
214 int i;
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;
222 if (i == 50000) {
223 mutex_exit(&dev->low_mutex);
224 return;
226 OUTW(dev, AC97D, data);
227 mutex_exit(&dev->low_mutex);
230 static void
231 select_digital_enable(audigyls_dev_t *dev, int mode)
234 * Set the out3/spdif combo jack format.
235 * mode0=analog rear/center, 1=spdif
238 if (mode == 0) {
239 write_reg(dev, SPC, 0x00000f00);
240 } else {
241 write_reg(dev, SPC, 0x0000000f);
245 /* only for SBLive 7.1 */
246 void
247 audigyls_i2c_write(audigyls_dev_t *dev, int reg, int data)
249 int i, timeout, tmp;
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;
266 if (timeout > 100)
267 break;
269 timeout++;
272 /* transaction aborted */
273 if (tmp & 0x200)
274 break;
279 audigyls_spi_write(audigyls_dev_t *dev, int data)
281 unsigned int orig;
282 unsigned int tmp;
283 int i, valid;
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;
298 if (!valid) /* Timed out */
299 return (0);
301 return (1);
305 * Audio routines
309 audigyls_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp)
311 audigyls_port_t *port = arg;
312 audigyls_dev_t *dev = port->dev;
314 _NOTE(ARGUNUSED(flag));
316 mutex_enter(&dev->mutex);
318 port->count = 0;
319 *nframesp = port->buf_frames;
320 *bufp = port->buf_kaddr;
321 mutex_exit(&dev->mutex);
323 return (0);
326 void
327 audigyls_close(void *arg)
329 _NOTE(ARGUNUSED(arg));
333 audigyls_start(void *arg)
335 audigyls_port_t *port = arg;
336 audigyls_dev_t *dev = port->dev;
337 uint32_t tmp;
339 mutex_enter(&dev->mutex);
341 port->offset = 0;
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);
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;
362 case AUDIGYLS_REC_PORT:
363 write_chan(dev, CRFA, 2, 0);
364 write_chan(dev, CRCAV, 2, 0);
366 tmp = read_reg(dev, SA);
367 tmp |= SA_SRA(2);
368 write_reg(dev, SA, tmp);
369 break;
372 mutex_exit(&dev->mutex);
373 return (0);
376 void
377 audigyls_stop(void *arg)
379 audigyls_port_t *port = arg;
380 audigyls_dev_t *dev = port->dev;
381 uint32_t tmp;
383 mutex_enter(&dev->mutex);
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;
394 case AUDIGYLS_REC_PORT:
395 tmp = read_reg(dev, SA);
396 tmp &= ~SA_SRA(2);
397 write_reg(dev, SA, tmp);
398 break;
401 mutex_exit(&dev->mutex);
405 audigyls_format(void *arg)
407 _NOTE(ARGUNUSED(arg));
409 return (AUDIO_FORMAT_S16_LE);
413 audigyls_channels(void *arg)
415 audigyls_port_t *port = arg;
417 return (port->nchan);
421 audigyls_rate(void *arg)
423 _NOTE(ARGUNUSED(arg));
425 return (48000);
428 void
429 audigyls_sync(void *arg, unsigned nframes)
431 audigyls_port_t *port = arg;
432 _NOTE(ARGUNUSED(nframes));
434 (void) ddi_dma_sync(port->buf_dmah, 0, 0, port->syncdir);
437 uint64_t
438 audigyls_count(void *arg)
440 audigyls_port_t *port = arg;
441 audigyls_dev_t *dev = port->dev;
442 uint64_t count;
443 uint32_t offset, n;
445 mutex_enter(&dev->mutex);
447 if (port->direction == AUDIGYLS_PLAY_PORT) {
448 offset = read_chan(dev, CPFA, 0);
449 } else {
450 offset = read_chan(dev, CRFA, 2);
453 /* get the offset, and switch to frames */
454 offset /= (2 * sizeof (uint16_t));
456 if (offset >= port->offset) {
457 n = offset - port->offset;
458 } else {
459 n = offset + (port->buf_frames - port->offset);
461 port->offset = offset;
462 port->count += n;
464 count = port->count;
465 mutex_exit(&dev->mutex);
466 return (count);
469 static void
470 audigyls_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr)
472 audigyls_port_t *port = arg;
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;
483 /* private implementation bits */
486 audigyls_alloc_port(audigyls_dev_t *dev, int num)
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;
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;
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);
519 port->buf_frames = 2048;
520 port->buf_size = port->buf_frames * port->nchan * sizeof (int16_t);
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);
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);
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);
542 port->buf_paddr = cookie.dmac_address;
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);
550 audio_engine_set_private(port->engine, port);
551 audio_dev_add_engine(adev, port->engine);
553 return (DDI_SUCCESS);
556 void
557 audigyls_del_controls(audigyls_dev_t *dev)
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;
567 void
568 audigyls_destroy(audigyls_dev_t *dev)
570 mutex_destroy(&dev->mutex);
571 mutex_destroy(&dev->low_mutex);
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);
581 if (port->buf_paddr) {
582 (void) ddi_dma_unbind_handle(port->buf_dmah);
584 if (port->buf_acch) {
585 ddi_dma_mem_free(&port->buf_acch);
587 if (port->buf_dmah) {
588 ddi_dma_free_handle(&port->buf_dmah);
590 kmem_free(port, sizeof (*port));
593 if (dev->ac97 != NULL) {
594 ac97_free(dev->ac97);
597 audigyls_del_controls(dev);
599 if (dev->adev != NULL) {
600 audio_dev_free(dev->adev);
602 if (dev->regsh != NULL) {
603 ddi_regs_map_free(&dev->regsh);
605 if (dev->pcih != NULL) {
606 pci_config_teardown(&dev->pcih);
608 kmem_free(dev, sizeof (*dev));
611 void
612 audigyls_hwinit(audigyls_dev_t *dev)
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,
620 uint32_t tmp;
621 int i, tries;
622 uint32_t paddr;
623 uint32_t chunksz;
624 audigyls_port_t *port;
627 /* Set the orange jack to be analog out or S/PDIF */
628 select_digital_enable(dev, dev->digital_enable);
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.
637 * in SB570, pin 0-4 and 6 is used as GPO and pin 5 and 7 is
638 * used as GPI.
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
662 if (dev->ac97)
663 OUTL(dev, GPIO, 0x005f03a3);
664 else {
665 /* for SBLive 7.1 */
666 OUTL(dev, GPIO, 0x005f4301);
668 audigyls_i2c_write(dev, 0x15, 0x2);
669 tries = 0;
670 again:
671 for (i = 0; i < sizeof (spi_dac); i++) {
672 if (!audigyls_spi_write(dev, spi_dac[i]) &&
673 tries < 100) {
674 tries++;
675 goto again;
680 OUTL(dev, IER, 0);
681 OUTL(dev, HC, 0x00000009); /* Enable audio, use 48 kHz */
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);
691 write_reg(dev, HMIXMAP_I2S, 0x76543210); /* Default out route */
692 write_reg(dev, AUDCTL, 0x0f0f003f); /* Enable all outputs */
694 /* All audio stopped! */
695 write_reg(dev, SA, 0);
697 for (i = 0; i < 4; i++) {
699 * Reset DMA pointers and counters. Note that we do
700 * not use scatter/gather.
702 write_chan(dev, PTBA, i, 0);
703 write_chan(dev, PTBS, i, 0);
704 write_chan(dev, PTCA, i, 0);
706 write_chan(dev, CPFA, i, 0);
707 write_chan(dev, PFEA, i, 0);
708 write_chan(dev, CPCAV, i, 0);
710 write_chan(dev, CRFA, i, 0);
711 write_chan(dev, CRCAV, i, 0);
715 * The 5.1 play port made up channels 0, 1, and 3. The record
716 * port is channel 2.
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);
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);
737 /* Set sample rates to 48 kHz. */
738 tmp = read_chan(dev, SRCTL, 0) & ~0x0303c00f;
739 write_chan(dev, SRCTL, 0, tmp);
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 */
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)
755 #define MASK(nbits) ((1 << (nbits)) - 1)
756 #define SCALE(val, nbits) \
757 ((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
759 static uint32_t
760 audigyls_stereo_scale(uint32_t value, uint8_t bits)
762 uint8_t left, right;
763 uint32_t val;
765 left = (value >> 8) & 0xff;
766 right = value & 0xff;
768 val = (((left * ((1 << bits) - 1) / 100) << 8) |
769 (right * ((1 << bits) - 1) / 100));
770 return (val);
773 static void
774 audigyls_configure_mixer(audigyls_dev_t *dev)
776 unsigned int r, v1, v2;
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);
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);
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);
796 /* spread */
797 r = dev->controls[CTL_SPREAD].val ? 0x10101010 : 0x76543210;
798 write_reg(dev, HMIXMAP_I2S, r);
800 /* input items */
802 /* recgain */
803 v1 = dev->controls[CTL_RECORDVOL].val;
804 if (dev->ac97_recgain && !dev->controls[CTL_LOOP].val) {
806 * For AC'97, we use the AC'97 record gain, unless we are
807 * in loopback.
809 (void) ac97_control_set(dev->ac97_recgain, v1);
810 write_reg(dev, P17RECVOLL, 0x30303030);
811 write_reg(dev, P17RECVOLH, 0x30303030);
812 } else {
814 * Otherwise we set the P17 gain.
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);
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);
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;
850 case 2:
851 audigyls_i2c_write(dev, 0x15, 0x4); /* Line */
852 OUTL(dev, GPIO, INL(dev, GPIO) & ~0x400);
853 break;
855 v1 = RECSEL_I2SIN; /* SB 7.1 value */
858 /* If loopback, record what you hear instead */
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 {
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.
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) |
883 write_reg(dev, P17RECSEL, r);
886 static int
887 audigyls_set_control(void *arg, uint64_t val)
889 audigyls_ctrl_t *pc = arg;
890 audigyls_dev_t *dev = pc->dev;
892 switch (pc->num) {
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);
902 break;
904 case CTL_CENTER:
905 case CTL_LFE:
906 case CTL_MONGAIN:
907 if (val > 100) {
908 return (EINVAL);
910 break;
912 case CTL_RECSRC:
913 if (((1U << val) & (dev->recmask)) == 0) {
914 return (EINVAL);
916 break;
918 case CTL_SPREAD:
919 case CTL_LOOP:
920 switch (val) {
921 case 0:
922 case 1:
923 break;
924 default:
925 return (EINVAL);
929 mutex_enter(&dev->mutex);
930 pc->val = val;
931 audigyls_configure_mixer(dev);
933 mutex_exit(&dev->mutex);
935 return (0);
938 static int
939 audigyls_get_control(void *arg, uint64_t *val)
941 audigyls_ctrl_t *pc = arg;
942 audigyls_dev_t *dev = pc->dev;
944 mutex_enter(&dev->mutex);
945 *val = pc->val;
946 mutex_exit(&dev->mutex);
947 return (0);
950 static void
951 audigyls_alloc_ctrl(audigyls_dev_t *dev, uint32_t num, uint64_t val)
953 audio_ctrl_desc_t desc;
954 audigyls_ctrl_t *pc;
956 bzero(&desc, sizeof (desc));
958 pc = &dev->controls[num];
959 pc->num = num;
960 pc->dev = dev;
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;
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;
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;
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;
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;
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;
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.
1014 if (dev->ac97_recsrc) {
1015 int i, j;
1016 const char *n;
1017 const audio_ctrl_desc_t *adp;
1019 adp = ac97_control_desc(dev->ac97_recsrc);
1020 for (i = 0; i < 64; i++) {
1021 n = adp->acd_enum[i];
1023 if (((adp->acd_minvalue & (1 << i)) == 0) ||
1024 (n == NULL)) {
1025 continue;
1027 for (j = 0; audigyls_badsrcs[j]; j++) {
1028 if (strcmp(n, audigyls_badsrcs[j])
1029 == 0) {
1030 n = NULL;
1031 break;
1034 if (n) {
1035 desc.acd_enum[i] = n;
1036 dev->recmask |= (1 << i);
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;
1047 break;
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;
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;
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;
1075 pc->val = val;
1076 pc->ctrl = audio_dev_add_control(dev->adev, &desc,
1077 audigyls_get_control, audigyls_set_control, pc);
1080 static void
1081 audigyls_add_controls(audigyls_dev_t *dev)
1083 audio_dev_add_soft_volume(dev->adev);
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);
1099 audigyls_attach(dev_info_t *dip)
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;
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);
1114 if ((dev->adev = audio_dev_alloc(dip, 0)) == NULL) {
1115 cmn_err(CE_WARN, "audio_dev_alloc failed");
1116 goto error;
1119 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
1120 audio_dev_warn(dev->adev, "pci_config_setup failed");
1121 goto error;
1123 dev->pcih = pcih;
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;
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);
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;
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);
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;
1197 audio_dev_set_description(dev->adev, name);
1198 if (version)
1199 audio_dev_set_version(dev->adev, version);
1201 if (ac97) {
1202 ac97_ctrl_t *ctrl;
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;
1213 ac97_probe_controls(dev->ac97);
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);
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);
1230 audigyls_add_controls(dev);
1232 if (dev->ac97) {
1233 ac97_register_controls(dev->ac97);
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;
1241 audigyls_hwinit(dev);
1243 audigyls_configure_mixer(dev);
1245 if (audio_dev_register(dev->adev) != DDI_SUCCESS) {
1246 audio_dev_warn(dev->adev, "unable to register with framework");
1247 goto error;
1250 ddi_report_dev(dip);
1252 return (DDI_SUCCESS);
1254 error:
1255 audigyls_destroy(dev);
1256 return (DDI_FAILURE);
1260 audigyls_resume(dev_info_t *dip)
1262 audigyls_dev_t *dev;
1264 dev = ddi_get_driver_private(dip);
1266 audigyls_hwinit(dev);
1268 /* allow ac97 operations again */
1269 if (dev->ac97)
1270 ac97_reset(dev->ac97);
1272 audio_dev_resume(dev->adev);
1274 return (DDI_SUCCESS);
1278 audigyls_detach(audigyls_dev_t *dev)
1280 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1281 return (DDI_FAILURE);
1283 audigyls_destroy(dev);
1284 return (DDI_SUCCESS);
1288 audigyls_suspend(audigyls_dev_t *dev)
1290 audio_dev_suspend(dev->adev);
1292 return (DDI_SUCCESS);
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 *);
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 */
1314 static struct modldrv audigyls_modldrv = {
1315 &mod_driverops, /* drv_modops */
1316 "Creative Audigy LS Audio", /* linkinfo */
1317 &audigyls_dev_ops, /* dev_ops */
1320 static struct modlinkage modlinkage = {
1321 MODREV_1,
1322 { &audigyls_modldrv, NULL }
1326 _init(void)
1328 int rv;
1330 audio_init_ops(&audigyls_dev_ops, AUDIGYLS_NAME);
1331 if ((rv = mod_install(&modlinkage)) != 0) {
1332 audio_fini_ops(&audigyls_dev_ops);
1334 return (rv);
1338 _fini(void)
1340 int rv;
1342 if ((rv = mod_remove(&modlinkage)) == 0) {
1343 audio_fini_ops(&audigyls_dev_ops);
1345 return (rv);
1349 _info(struct modinfo *modinfop)
1351 return (mod_info(&modlinkage, modinfop));
1355 audigyls_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1357 switch (cmd) {
1358 case DDI_ATTACH:
1359 return (audigyls_attach(dip));
1361 case DDI_RESUME:
1362 return (audigyls_resume(dip));
1364 default:
1365 return (DDI_FAILURE);
1370 audigyls_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1372 audigyls_dev_t *dev;
1374 dev = ddi_get_driver_private(dip);
1376 switch (cmd) {
1377 case DDI_DETACH:
1378 return (audigyls_detach(dev));
1380 case DDI_SUSPEND:
1381 return (audigyls_suspend(dev));
1383 default:
1384 return (DDI_FAILURE);
1389 audigyls_ddi_quiesce(dev_info_t *dip)
1391 audigyls_dev_t *dev;
1392 uint32_t status;
1395 * Turn off the hardware
1397 dev = ddi_get_driver_private(dip);
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);