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]
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Purpose: Driver for CMEDIA CM8738 PCI audio controller.
28 * This file is part of Open Sound System
30 * Copyright (C) 4Front Technologies 1996-2008.
33 #include <sys/audio/audio_driver.h>
36 #include <sys/sysmacros.h>
40 * Note: The original 4Front driver had support SPDIF and dual dac
41 * options. Dual dac support is probably not terribly useful. SPDIF
42 * on the other hand might be quite useful, we just don't have a card
43 * that supports it at present. Some variants of the chip are also
44 * capable of jack retasking, but we're electing to punt on supporting
45 * that as well, for now (we don't have any cards that would benefit
48 * Note that surround support requires the use of the second DMA
49 * engine, and that the same second DMA engine is the only way one can
50 * capture from SPDIF. Rather than support a lot more complexity in
51 * the driver, we we will probably just punt on ever supporting
52 * capture of SPDIF. (SPDIF playback should be doable, however.)
54 * Adding back support for the advanced features would be an
55 * interesting project for someone with access to suitable hardware.
57 * Note that each variant (CMI 8338, 8738-033, -037, -055, and 8768)
58 * seems to have significant differences in some of the registers.
59 * While programming these parts for basic stereo is pretty much the
60 * same on all parts, doing anything more than that can be
61 * sigificantly different for each part.
64 static ddi_device_acc_attr_t acc_attr
= {
70 static ddi_device_acc_attr_t buf_attr
= {
76 static ddi_dma_attr_t dma_attr
= {
77 DMA_ATTR_VERSION
, /* dma_attr_version */
78 0x0, /* dma_attr_addr_lo */
79 0xffffffffU
, /* dma_attr_addr_hi */
80 0x3ffff, /* dma_attr_count_max */
81 0x8, /* dma_attr_align */
82 0x7f, /* dma_attr_burstsizes */
83 0x1, /* dma_attr_minxfer */
84 0x3ffff, /* dma_attr_maxxfer */
85 0x3ffff, /* dma_attr_seg */
86 0x1, /* dma_attr_sgllen */
87 0x1, /* dma_attr_granular */
88 0 /* dma_attr_flags */
93 cmpci_open(void *arg
, int flag
, uint_t
*nframesp
, caddr_t
*bufp
)
95 cmpci_port_t
*port
= arg
;
96 cmpci_dev_t
*dev
= port
->dev
;
98 _NOTE(ARGUNUSED(flag
));
100 mutex_enter(&dev
->mutex
);
102 *nframesp
= port
->nframes
;
106 mutex_exit(&dev
->mutex
);
112 cmpci_close(void *arg
)
114 _NOTE(ARGUNUSED(arg
));
118 cmpci_start(void *arg
)
120 cmpci_port_t
*port
= arg
;
121 cmpci_dev_t
*dev
= port
->dev
;
123 mutex_enter(&dev
->mutex
);
128 SET32(dev
, REG_FUNCTRL0
, port
->fc0_rst_bit
);
130 CLR32(dev
, REG_FUNCTRL0
, port
->fc0_rst_bit
);
133 /* Set 48k 16-bit stereo -- these are just with all bits set. */
134 SET32(dev
, REG_FUNCTRL1
, port
->fc1_rate_mask
);
135 SET32(dev
, REG_CHFORMAT
, port
->chformat_mask
);
137 if ((port
->num
== 1) && (dev
->maxch
> 2)) {
138 CLR32(dev
, REG_LEGACY
, LEGACY_NXCHG
);
140 if (port
->nchan
> 2) {
141 SET32(dev
, REG_MISC
, MISC_XCHGDAC
);
142 CLR32(dev
, REG_MISC
, MISC_N4SPK3D
);
144 CLR32(dev
, REG_MISC
, MISC_XCHGDAC
);
145 SET32(dev
, REG_MISC
, MISC_N4SPK3D
);
148 switch (port
->nchan
) {
150 if (dev
->maxch
>= 8) {
151 CLR8(dev
, REG_MISC2
, MISC2_CHB3D8C
);
153 if (dev
->maxch
>= 6) {
154 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D5C
);
155 CLR32(dev
, REG_LEGACY
, LEGACY_CHB3D6C
);
157 if (dev
->maxch
>= 4) {
158 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D
);
162 if (dev
->maxch
>= 8) {
163 CLR8(dev
, REG_MISC2
, MISC2_CHB3D8C
);
165 if (dev
->maxch
>= 6) {
166 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D5C
);
167 CLR32(dev
, REG_LEGACY
, LEGACY_CHB3D6C
);
168 CLR32(dev
, REG_MISC
, MISC_ENCENTER
);
169 CLR32(dev
, REG_LEGACY
, LEGACY_EXBASSEN
);
171 SET32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D
);
174 if (dev
->maxch
>= 8) {
175 CLR8(dev
, REG_MISC2
, MISC2_CHB3D8C
);
177 SET32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D5C
);
178 SET32(dev
, REG_LEGACY
, LEGACY_CHB3D6C
);
179 CLR32(dev
, REG_MISC
, MISC_ENCENTER
);
180 CLR32(dev
, REG_LEGACY
, LEGACY_EXBASSEN
);
181 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D
);
185 SET8(dev
, REG_MISC2
, MISC2_CHB3D8C
);
186 CLR32(dev
, REG_MISC
, MISC_ENCENTER
);
187 CLR32(dev
, REG_LEGACY
, LEGACY_EXBASSEN
);
188 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D5C
);
189 CLR32(dev
, REG_LEGACY
, LEGACY_CHB3D6C
);
190 CLR32(dev
, REG_CHFORMAT
, CHFORMAT_CHB3D
);
195 PUT32(dev
, port
->reg_paddr
, port
->paddr
);
196 PUT16(dev
, port
->reg_bufsz
, (port
->bufsz
/ 4) - 1);
197 PUT16(dev
, port
->reg_fragsz
, (port
->bufsz
/ 4) - 1);
202 SET32(dev
, REG_FUNCTRL0
, port
->fc0_rec_bit
);
204 CLR32(dev
, REG_FUNCTRL0
, port
->fc0_rec_bit
);
207 SET32(dev
, REG_FUNCTRL0
, port
->fc0_en_bit
);
208 mutex_exit(&dev
->mutex
);
214 cmpci_stop(void *arg
)
216 cmpci_port_t
*port
= arg
;
217 cmpci_dev_t
*dev
= port
->dev
;
219 mutex_enter(&dev
->mutex
);
220 CLR32(dev
, REG_FUNCTRL0
, port
->fc0_en_bit
);
221 mutex_exit(&dev
->mutex
);
225 cmpci_count(void *arg
)
227 cmpci_port_t
*port
= arg
;
228 cmpci_dev_t
*dev
= port
->dev
;
232 mutex_enter(&dev
->mutex
);
234 /* this gives us the offset in dwords */
235 offset
= (port
->bufsz
/ 4) - (GET16(dev
, port
->reg_bufsz
) + 1);
237 /* check for wrap - note that the count is given in dwords */
238 if (offset
< port
->offset
) {
239 count
= ((port
->bufsz
/ 4) - port
->offset
) + offset
;
241 count
= offset
- port
->offset
;
243 port
->count
+= count
;
244 port
->offset
= offset
;
247 mutex_exit(&dev
->mutex
);
250 * convert dwords to frames - unfortunately this requires a
253 return (count
/ (port
->nchan
/ 2));
256 #define MASK(nbits) ((1 << (nbits)) - 1)
257 #define SCALE(val, nbits) \
258 ((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
260 #define LEFT(dev, ctl) min(((dev->controls[ctl].value) >> 8), 100)
261 #define RIGHT(dev, ctl) min(((dev->controls[ctl].value) & 0xff), 100)
262 #define MONO(dev, ctl) min(dev->controls[ctl].value, 100)
265 cmpci_setmixer(cmpci_dev_t
*dev
, uint8_t idx
, uint8_t val
)
267 PUT8(dev
, REG_IDXADDR
, idx
);
268 PUT8(dev
, REG_IDXDATA
, val
);
272 cmpci_getmixer(cmpci_dev_t
*dev
, uint8_t idx
)
274 PUT8(dev
, REG_IDXADDR
, idx
);
275 return (GET8(dev
, REG_IDXDATA
));
280 cmpci_configure_mixer(cmpci_dev_t
*dev
)
282 uint64_t left
, right
;
288 /* reset all mix values */
289 outmix
= inmix
[0] = inmix
[1] = 0;
291 outmix
= OUTMIX_MIC
|
292 OUTMIX_CD_R
| OUTMIX_CD_L
| OUTMIX_LINE_R
| OUTMIX_LINE_L
;
294 inmix
[0] = INMIX_LINE_L
| INMIX_CD_L
| INMIX_MIC
;
295 inmix
[1] = INMIX_LINE_R
| INMIX_CD_R
| INMIX_MIC
;
297 recsrcs
= dev
->controls
[CTL_RECSRCS
].value
;
298 monsrcs
= dev
->controls
[CTL_MONSRCS
].value
;
300 /* program PCM volume */
301 left
= MONO(dev
, CTL_VOLUME
);
303 /* left and right are the same */
304 cmpci_setmixer(dev
, IDX_VOICE_LEFT
, SCALE(left
, 5));
305 cmpci_setmixer(dev
, IDX_VOICE_RIGHT
, SCALE(left
, 5));
306 CLR8(dev
, REG_MIX2
, MIX2_WSMUTE
);
308 cmpci_setmixer(dev
, IDX_VOICE_LEFT
, 0);
309 cmpci_setmixer(dev
, IDX_VOICE_RIGHT
, 0);
310 SET8(dev
, REG_MIX2
, MIX2_WSMUTE
);
313 left
= LEFT(dev
, CTL_LINEOUT
);
314 right
= RIGHT(dev
, CTL_LINEOUT
);
316 /* lineout/master volume - no separate mute */
317 cmpci_setmixer(dev
, IDX_MASTER_LEFT
, SCALE(left
, 5));
318 cmpci_setmixer(dev
, IDX_MASTER_RIGHT
, SCALE(right
, 5));
320 /* speaker volume - mute in extension register, but we don't use */
321 left
= MONO(dev
, CTL_SPEAKER
);
322 cmpci_setmixer(dev
, IDX_SPEAKER
, SCALE(left
, 2));
325 left
= MONO(dev
, CTL_MIC
);
327 cmpci_setmixer(dev
, IDX_MIC
, SCALE(left
, 5));
328 /* set record mic gain */
329 uint8_t v
= GET8(dev
, REG_MIX3
);
331 v
|= ((left
* 7) / 100) << 1;
332 PUT8(dev
, REG_MIX3
, v
);
333 cmpci_setmixer(dev
, 0x3f, SCALE(100, 2));
334 cmpci_setmixer(dev
, 0x40, SCALE(100, 2));
336 cmpci_setmixer(dev
, IDX_MIC
, 0);
337 outmix
&= ~OUTMIX_MIC
;
338 inmix
[0] &= ~INMIX_MIC
;
339 inmix
[1] &= ~INMIX_MIC
;
343 left
= LEFT(dev
, CTL_LINEOUT
);
344 right
= RIGHT(dev
, CTL_LINEOUT
);
346 cmpci_setmixer(dev
, IDX_LINEIN_LEFT
, SCALE(left
, 5));
348 cmpci_setmixer(dev
, IDX_LINEIN_LEFT
, 0);
349 inmix
[0] &= ~INMIX_LINE_L
;
350 outmix
&= ~OUTMIX_LINE_L
;
353 cmpci_setmixer(dev
, IDX_LINEIN_RIGHT
, SCALE(left
, 5));
355 cmpci_setmixer(dev
, IDX_LINEIN_RIGHT
, 0);
356 inmix
[1] &= ~INMIX_LINE_R
;
357 outmix
&= ~OUTMIX_LINE_R
;
361 left
= LEFT(dev
, CTL_CD
);
362 right
= RIGHT(dev
, CTL_CD
);
364 cmpci_setmixer(dev
, IDX_CDDA_LEFT
, SCALE(left
, 5));
366 cmpci_setmixer(dev
, IDX_CDDA_LEFT
, 0);
367 inmix
[0] &= ~INMIX_CD_L
;
368 outmix
&= ~OUTMIX_CD_L
;
371 cmpci_setmixer(dev
, IDX_CDDA_RIGHT
, SCALE(left
, 5));
373 cmpci_setmixer(dev
, IDX_CDDA_RIGHT
, 0);
374 inmix
[1] &= ~INMIX_CD_R
;
375 outmix
&= ~OUTMIX_CD_R
;
378 /* aux - trickier because it doesn't use regular sbpro mixer */
379 left
= LEFT(dev
, CTL_AUX
);
380 right
= RIGHT(dev
, CTL_AUX
);
381 PUT8(dev
, REG_VAUX
, (((left
* 15) / 100) << 4) | ((right
* 15) / 100));
382 /* maybe enable recording */
383 if ((left
|| right
) && (recsrcs
& (1 << SRC_LINE
))) {
384 SET8(dev
, REG_MIX3
, MIX3_RAUXREN
| MIX3_RAUXLEN
);
386 CLR8(dev
, REG_MIX3
, MIX3_RAUXREN
| MIX3_RAUXLEN
);
388 /* maybe enable monitoring */
389 if ((left
|| right
) && (monsrcs
& (1 << SRC_AUX
))) {
390 CLR8(dev
, REG_MIX3
, MIX3_VAUXRM
| MIX3_VAUXLM
);
392 SET8(dev
, REG_MIX3
, MIX3_VAUXRM
| MIX3_VAUXLM
);
395 /* now do the recsrcs */
396 if ((recsrcs
& (1 << SRC_MIC
)) == 0) {
397 inmix
[0] &= ~INMIX_MIC
;
398 inmix
[1] &= ~INMIX_MIC
;
400 if ((recsrcs
& (1 << SRC_LINE
)) == 0) {
401 inmix
[0] &= ~INMIX_LINE_L
;
402 inmix
[1] &= ~INMIX_LINE_R
;
404 if ((recsrcs
& (1 << SRC_CD
)) == 0) {
405 inmix
[0] &= ~INMIX_CD_L
;
406 inmix
[1] &= ~INMIX_CD_R
;
408 if (recsrcs
& (1 << SRC_MIX
)) {
409 SET8(dev
, REG_MIX2
, MIX2_WAVEIN_L
| MIX2_WAVEIN_R
);
411 CLR8(dev
, REG_MIX2
, MIX2_WAVEIN_L
| MIX2_WAVEIN_R
);
413 cmpci_setmixer(dev
, IDX_INMIX_L
, inmix
[0]);
414 cmpci_setmixer(dev
, IDX_INMIX_R
, inmix
[1]);
416 /* now the monsrcs */
417 if ((monsrcs
& (1 << SRC_MIC
)) == 0) {
418 outmix
&= ~OUTMIX_MIC
;
420 if ((monsrcs
& (1 << SRC_LINE
)) == 0) {
421 outmix
&= ~(OUTMIX_LINE_L
| OUTMIX_LINE_R
);
423 if ((monsrcs
& (1 << SRC_CD
)) == 0) {
424 outmix
&= ~(OUTMIX_CD_L
| OUTMIX_CD_R
);
426 cmpci_setmixer(dev
, IDX_OUTMIX
, outmix
);
429 if (dev
->controls
[CTL_MICBOOST
].value
!= 0) {
430 CLR8(dev
, REG_MIX3
, MIX3_MICGAINZ
);
431 cmpci_setmixer(dev
, IDX_EXTENSION
,
432 cmpci_getmixer(dev
, IDX_EXTENSION
) & ~0x1);
434 SET8(dev
, REG_MIX3
, MIX3_MICGAINZ
);
435 cmpci_setmixer(dev
, IDX_EXTENSION
,
436 cmpci_getmixer(dev
, IDX_EXTENSION
) | 0x1);
441 cmpci_set_ctrl(void *arg
, uint64_t val
)
443 cmpci_ctrl_t
*cc
= arg
;
444 cmpci_dev_t
*dev
= cc
->dev
;
447 * We don't bother to check for valid values - a bogus value
448 * will give incorrect volumes, but is otherwise harmless.
450 mutex_enter(&dev
->mutex
);
452 cmpci_configure_mixer(dev
);
453 mutex_exit(&dev
->mutex
);
459 cmpci_get_ctrl(void *arg
, uint64_t *val
)
461 cmpci_ctrl_t
*cc
= arg
;
462 cmpci_dev_t
*dev
= cc
->dev
;
464 mutex_enter(&dev
->mutex
);
466 mutex_exit(&dev
->mutex
);
470 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
471 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
472 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
473 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
474 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
475 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL)
478 cmpci_alloc_ctrl(cmpci_dev_t
*dev
, uint32_t num
, uint64_t val
)
480 audio_ctrl_desc_t desc
;
483 cc
= &dev
->controls
[num
];
484 bzero(&desc
, sizeof (desc
));
489 desc
.acd_name
= AUDIO_CTRL_ID_VOLUME
;
490 desc
.acd_type
= AUDIO_CTRL_TYPE_MONO
;
491 desc
.acd_minvalue
= 0;
492 desc
.acd_maxvalue
= 100;
493 desc
.acd_flags
= PCMVOL
;
497 desc
.acd_name
= AUDIO_CTRL_ID_LINEOUT
;
498 desc
.acd_type
= AUDIO_CTRL_TYPE_STEREO
;
499 desc
.acd_minvalue
= 0;
500 desc
.acd_maxvalue
= 100;
501 desc
.acd_flags
= MAINVOL
;
505 desc
.acd_name
= AUDIO_CTRL_ID_SPEAKER
;
506 desc
.acd_type
= AUDIO_CTRL_TYPE_MONO
;
507 desc
.acd_minvalue
= 0;
508 desc
.acd_maxvalue
= 100;
509 desc
.acd_flags
= MAINVOL
;
513 desc
.acd_name
= AUDIO_CTRL_ID_MIC
;
514 desc
.acd_type
= AUDIO_CTRL_TYPE_MONO
;
515 desc
.acd_minvalue
= 0;
516 desc
.acd_maxvalue
= 100;
517 desc
.acd_flags
= RECVOL
;
521 desc
.acd_name
= AUDIO_CTRL_ID_LINEIN
;
522 desc
.acd_type
= AUDIO_CTRL_TYPE_STEREO
;
523 desc
.acd_minvalue
= 0;
524 desc
.acd_maxvalue
= 100;
525 desc
.acd_flags
= RECVOL
;
529 desc
.acd_name
= AUDIO_CTRL_ID_CD
;
530 desc
.acd_type
= AUDIO_CTRL_TYPE_STEREO
;
531 desc
.acd_minvalue
= 0;
532 desc
.acd_maxvalue
= 100;
533 desc
.acd_flags
= RECVOL
;
537 desc
.acd_name
= AUDIO_CTRL_ID_AUX1IN
;
538 desc
.acd_type
= AUDIO_CTRL_TYPE_STEREO
;
539 desc
.acd_minvalue
= 0;
540 desc
.acd_maxvalue
= 100;
541 desc
.acd_flags
= RECVOL
;
545 desc
.acd_name
= AUDIO_CTRL_ID_RECSRC
;
546 desc
.acd_type
= AUDIO_CTRL_TYPE_ENUM
;
547 desc
.acd_enum
[SRC_MIC
] = AUDIO_PORT_MIC
;
548 desc
.acd_enum
[SRC_LINE
] = AUDIO_PORT_LINEIN
;
549 desc
.acd_enum
[SRC_CD
] = AUDIO_PORT_CD
;
550 desc
.acd_enum
[SRC_AUX
] = AUDIO_PORT_AUX1IN
;
551 desc
.acd_enum
[SRC_MIX
] = AUDIO_PORT_STEREOMIX
;
552 desc
.acd_minvalue
= (1 << (SRC_MIX
+ 1)) - 1;
553 desc
.acd_maxvalue
= desc
.acd_minvalue
;
554 desc
.acd_flags
= RECCTL
| AUDIO_CTRL_FLAG_MULTI
;
558 desc
.acd_name
= AUDIO_CTRL_ID_MONSRC
;
559 desc
.acd_type
= AUDIO_CTRL_TYPE_ENUM
;
560 desc
.acd_enum
[SRC_MIC
] = AUDIO_PORT_MIC
;
561 desc
.acd_enum
[SRC_LINE
] = AUDIO_PORT_LINEIN
;
562 desc
.acd_enum
[SRC_CD
] = AUDIO_PORT_CD
;
563 desc
.acd_enum
[SRC_AUX
] = AUDIO_PORT_AUX1IN
;
564 desc
.acd_minvalue
= ((1 << (SRC_AUX
+ 1)) - 1);
565 desc
.acd_maxvalue
= desc
.acd_minvalue
;
566 desc
.acd_flags
= MONCTL
| AUDIO_CTRL_FLAG_MULTI
;
570 desc
.acd_name
= AUDIO_CTRL_ID_MICBOOST
;
571 desc
.acd_type
= AUDIO_CTRL_TYPE_BOOLEAN
;
572 desc
.acd_minvalue
= 0;
573 desc
.acd_maxvalue
= 1;
574 desc
.acd_flags
= RECCTL
;
579 cc
->ctrl
= audio_dev_add_control(dev
->adev
, &desc
,
580 cmpci_get_ctrl
, cmpci_set_ctrl
, cc
);
584 cmpci_add_controls(cmpci_dev_t
*dev
)
587 audio_dev_add_soft_volume(dev
->adev
);
589 cmpci_alloc_ctrl(dev
, CTL_VOLUME
, 75);
591 cmpci_alloc_ctrl(dev
, CTL_LINEOUT
, 90 | (90 << 8));
592 cmpci_alloc_ctrl(dev
, CTL_SPEAKER
, 75);
593 cmpci_alloc_ctrl(dev
, CTL_MIC
, 32);
594 cmpci_alloc_ctrl(dev
, CTL_LINEIN
, 64 | (64 << 8));
595 cmpci_alloc_ctrl(dev
, CTL_CD
, 75 | (75 << 8));
596 cmpci_alloc_ctrl(dev
, CTL_AUX
, 75 | (75 << 8));
597 cmpci_alloc_ctrl(dev
, CTL_RECSRCS
, (1 << SRC_MIC
));
598 cmpci_alloc_ctrl(dev
, CTL_MONSRCS
, 0);
599 cmpci_alloc_ctrl(dev
, CTL_MICBOOST
, 0);
603 cmpci_del_controls(cmpci_dev_t
*dev
)
605 for (int i
= 0; i
< CTL_NUM
; i
++) {
606 if (dev
->controls
[i
].ctrl
) {
607 audio_dev_del_control(dev
->controls
[i
].ctrl
);
608 dev
->controls
[i
].ctrl
= NULL
;
614 cmpci_reset(cmpci_dev_t
*dev
)
617 SET32(dev
, REG_MISC
, MISC_RESET
);
618 (void) GET32(dev
, REG_MISC
);
620 CLR32(dev
, REG_MISC
, MISC_RESET
);
622 /* reset all channels */
623 PUT32(dev
, REG_FUNCTRL0
, 0);
625 /* disable interrupts and such */
626 CLR32(dev
, REG_FUNCTRL0
, FUNCTRL0_CH0_EN
| FUNCTRL0_CH1_EN
);
627 CLR32(dev
, REG_INTCTRL
, INTCTRL_CH0_EN
| INTCTRL_CH1_EN
);
629 /* disable uart, joystick in Function Control Reg1 */
630 CLR32(dev
, REG_FUNCTRL1
, FUNCTRL1_UART_EN
| FUNCTRL1_JYSTK_EN
);
633 * Set DAC and ADC rates to 48 kHz - note that both rates have
634 * all bits set in them, so we can do this with a simple "set".
636 SET32(dev
, REG_FUNCTRL1
,
637 FUNCTRL1_DAC_RATE_48K
| FUNCTRL1_ADC_RATE_48K
);
639 /* Set 16-bit stereo -- also these are just with all bits set. */
640 SET32(dev
, REG_CHFORMAT
, CHFORMAT_CH0_16ST
| CHFORMAT_CH1_16ST
);
644 cmpci_format(void *unused
)
646 _NOTE(ARGUNUSED(unused
));
647 return (AUDIO_FORMAT_S16_LE
);
651 cmpci_channels(void *arg
)
653 cmpci_port_t
*port
= arg
;
655 return (port
->nchan
);
659 cmpci_chinfo(void *arg
, int chan
, unsigned *offset
, unsigned *incr
)
661 cmpci_port_t
*port
= arg
;
662 static const int map8ch
[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
663 static const int map4ch
[] = { 0, 1, 2, 3 };
665 if (port
->nchan
<= 4) {
666 *offset
= map4ch
[chan
];
668 *offset
= map8ch
[chan
];
674 cmpci_rate(void *unused
)
676 _NOTE(ARGUNUSED(unused
));
681 cmpci_sync(void *arg
, unsigned nframes
)
683 cmpci_port_t
*port
= arg
;
685 _NOTE(ARGUNUSED(nframes
));
687 (void) ddi_dma_sync(port
->dmah
, 0, 0, port
->sync_dir
);
690 audio_engine_ops_t cmpci_engine_ops
= {
691 AUDIO_ENGINE_VERSION
, /* version number */
703 NULL
, /* playahead */
707 cmpci_init(cmpci_dev_t
*dev
)
709 audio_dev_t
*adev
= dev
->adev
;
712 playch
= ddi_prop_get_int(DDI_DEV_T_ANY
, dev
->dip
,
713 DDI_PROP_DONTPASS
, "channels", dev
->maxch
);
715 if ((playch
% 2) || (playch
< 2) || (playch
> dev
->maxch
)) {
717 "Invalid channels property (%d), resetting to %d",
722 for (int i
= 0; i
< PORT_MAX
; i
++) {
731 port
= &dev
->port
[i
];
736 * Channel 0 is recording channel, unless we are in
737 * dual DAC mode. The reason for this is simple --
738 * only channel "B" (which I presume to mean channel
739 * 1) supports multichannel configuration.
741 * However, if we're going to use SPDIF recording,
742 * then recording *must* occur on channel 1. Yes, the
743 * hardware is "strange".
748 caps
= ENGINE_INPUT_CAP
;
749 dmaflags
= DDI_DMA_READ
| DDI_DMA_CONSISTENT
;
750 port
->reg_paddr
= REG_CH0_PADDR
;
751 port
->reg_bufsz
= REG_CH0_BUFSZ
;
752 port
->reg_fragsz
= REG_CH0_FRAGSZ
;
753 port
->fc0_rst_bit
= FUNCTRL0_CH0_RST
;
754 port
->fc0_rec_bit
= FUNCTRL0_CH0_REC
;
755 port
->fc0_en_bit
= FUNCTRL0_CH0_EN
;
756 port
->sync_dir
= DDI_DMA_SYNC_FORKERNEL
;
757 port
->capture
= B_TRUE
;
758 port
->fc1_rate_mask
= FUNCTRL1_ADC_RATE_48K
;
759 port
->chformat_mask
= CHFORMAT_CH0_16ST
;
764 caps
= ENGINE_OUTPUT_CAP
;
765 dmaflags
= DDI_DMA_WRITE
| DDI_DMA_CONSISTENT
;
766 port
->reg_paddr
= REG_CH1_PADDR
;
767 port
->reg_bufsz
= REG_CH1_BUFSZ
;
768 port
->reg_fragsz
= REG_CH1_FRAGSZ
;
769 port
->fc0_rst_bit
= FUNCTRL0_CH1_RST
;
770 port
->fc0_rec_bit
= FUNCTRL0_CH1_REC
;
771 port
->fc0_en_bit
= FUNCTRL0_CH1_EN
;
772 port
->sync_dir
= DDI_DMA_SYNC_FORDEV
;
773 port
->capture
= B_FALSE
;
774 port
->fc1_rate_mask
= FUNCTRL1_DAC_RATE_48K
;
775 port
->chformat_mask
= CHFORMAT_CH1_16ST
;
776 port
->nchan
= playch
;
781 * For efficiency, we'd like to have the fragments
782 * evenly divisble by 64 bytes. Since frames are
783 * already evenly divisble by 4 (16-bit stereo), this
784 * is adequate. For a typical configuration (175 Hz
785 * requested) this will translate to 166 Hz.
787 port
->nframes
= 2048;
788 port
->bufsz
= port
->nframes
* port
->nchan
* 2;
790 if (ddi_dma_alloc_handle(dev
->dip
, &dma_attr
, DDI_DMA_DONTWAIT
,
791 NULL
, &port
->dmah
) != DDI_SUCCESS
) {
792 audio_dev_warn(adev
, "ch%d: dma hdl alloc failed", i
);
793 return (DDI_FAILURE
);
795 if (ddi_dma_mem_alloc(port
->dmah
, port
->bufsz
, &buf_attr
,
796 DDI_DMA_CONSISTENT
, DDI_DMA_DONTWAIT
, NULL
, &port
->kaddr
,
797 &rlen
, &port
->acch
) != DDI_SUCCESS
) {
798 audio_dev_warn(adev
, "ch%d: dma mem allcoc failed", i
);
799 return (DDI_FAILURE
);
801 bzero(port
->kaddr
, rlen
);
803 if (ddi_dma_addr_bind_handle(port
->dmah
, NULL
, port
->kaddr
,
804 rlen
, dmaflags
, DDI_DMA_DONTWAIT
, NULL
, &c
, &ccnt
) !=
806 audio_dev_warn(adev
, "ch%d: dma bind failed", i
);
807 return (DDI_FAILURE
);
809 port
->paddr
= c
.dmac_address
;
811 port
->engine
= audio_engine_alloc(&cmpci_engine_ops
, caps
);
812 if (port
->engine
== NULL
) {
813 audio_dev_warn(adev
, "ch%d: alloc engine failed", i
);
814 return (DDI_FAILURE
);
816 audio_engine_set_private(port
->engine
, port
);
817 audio_dev_add_engine(adev
, port
->engine
);
820 cmpci_add_controls(dev
);
823 cmpci_configure_mixer(dev
);
825 if (audio_dev_register(adev
) != DDI_SUCCESS
) {
826 audio_dev_warn(adev
, "audio_dev_register failed");
827 return (DDI_FAILURE
);
830 return (DDI_SUCCESS
);
834 cmpci_destroy(cmpci_dev_t
*dev
)
836 mutex_destroy(&dev
->mutex
);
838 /* free up ports, including DMA resources for ports */
839 for (int i
= 0; i
< PORT_MAX
; i
++) {
840 cmpci_port_t
*port
= &dev
->port
[i
];
842 if (port
->paddr
!= 0)
843 (void) ddi_dma_unbind_handle(port
->dmah
);
844 if (port
->acch
!= NULL
)
845 ddi_dma_mem_free(&port
->acch
);
846 if (port
->dmah
!= NULL
)
847 ddi_dma_free_handle(&port
->dmah
);
849 if (port
->engine
!= NULL
) {
850 audio_dev_remove_engine(dev
->adev
, port
->engine
);
851 audio_engine_free(port
->engine
);
855 if (dev
->acch
!= NULL
) {
856 ddi_regs_map_free(&dev
->acch
);
859 cmpci_del_controls(dev
);
861 if (dev
->adev
!= NULL
) {
862 audio_dev_free(dev
->adev
);
865 kmem_free(dev
, sizeof (*dev
));
869 cmpci_attach(dev_info_t
*dip
)
871 uint16_t vendor
, device
;
873 ddi_acc_handle_t pcih
;
877 if (pci_config_setup(dip
, &pcih
) != DDI_SUCCESS
) {
878 audio_dev_warn(NULL
, "pci_config_setup failed");
879 return (DDI_FAILURE
);
882 vendor
= pci_config_get16(pcih
, PCI_CONF_VENID
);
883 device
= pci_config_get16(pcih
, PCI_CONF_DEVID
);
885 if (vendor
!= CMEDIA_VENDOR_ID
||
886 ((device
!= CMEDIA_CM8738
) && (device
!= CMEDIA_CM8338A
) &&
887 (device
!= CMEDIA_CM8338B
))) {
888 pci_config_teardown(&pcih
);
889 audio_dev_warn(NULL
, "device not recognized");
890 return (DDI_FAILURE
);
893 /* enable IO and Master accesses */
894 pci_config_put16(pcih
, PCI_CONF_COMM
,
895 pci_config_get16(pcih
, PCI_CONF_COMM
) |
896 PCI_COMM_MAE
| PCI_COMM_IO
);
898 pci_config_teardown(&pcih
);
900 dev
= kmem_zalloc(sizeof (*dev
), KM_SLEEP
);
902 mutex_init(&dev
->mutex
, NULL
, MUTEX_DRIVER
, NULL
);
904 ddi_set_driver_private(dip
, dev
);
906 if ((adev
= audio_dev_alloc(dip
, 0)) == NULL
) {
911 if (ddi_regs_map_setup(dip
, 1, &dev
->regs
, 0, 0, &acc_attr
,
912 &dev
->acch
) != DDI_SUCCESS
) {
913 audio_dev_warn(adev
, "can't map registers");
917 /* setup some initial values */
919 audio_dev_set_description(adev
, "C-Media PCI Audio");
923 * Crazy 8738 detection scheme. Reviewing multiple
924 * different open sources gives multiple different
925 * answers here. Its unclear how accurate this is.
926 * The approach taken here is a bit conservative in
927 * assigning multiple channel support, but for users
928 * with newer 8768 cards should offer the best
931 val
= GET32(dev
, REG_INTCTRL
) & INTCTRL_MDL_MASK
;
934 if (GET32(dev
, REG_CHFORMAT
& CHFORMAT_VER_MASK
)) {
935 audio_dev_set_version(adev
, "CMI-8738-037");
938 audio_dev_set_version(adev
, "CMI-8738-033");
940 } else if ((val
& INTCTRL_MDL_068
) == INTCTRL_MDL_068
) {
941 audio_dev_set_version(adev
, "CMI-8768");
943 dev
->softvol
= B_TRUE
; /* No hardware PCM volume */
944 } else if ((val
& INTCTRL_MDL_055
) == INTCTRL_MDL_055
) {
945 audio_dev_set_version(adev
, "CMI-8738-055");
947 } else if ((val
& INTCTRL_MDL_039
) == INTCTRL_MDL_039
) {
948 audio_dev_set_version(adev
, "CMI-8738-039");
951 audio_dev_set_version(adev
, "CMI-8738");
956 audio_dev_set_version(dev
->adev
, "CMI-8338");
960 audio_dev_set_version(dev
->adev
, "CMI-8338B");
964 if (cmpci_init(dev
) != DDI_SUCCESS
) {
965 audio_dev_warn(dev
->adev
, "can't init device");
969 return (DDI_SUCCESS
);
973 return (DDI_FAILURE
);
977 cmpci_resume(cmpci_dev_t
*dev
)
979 mutex_enter(&dev
->mutex
);
981 /* wait one millisecond, to give reset a chance to get up */
983 mutex_exit(&dev
->mutex
);
985 audio_dev_resume(dev
->adev
);
987 return (DDI_SUCCESS
);
991 cmpci_detach(cmpci_dev_t
*dev
)
993 if (audio_dev_unregister(dev
->adev
) != DDI_SUCCESS
)
994 return (DDI_FAILURE
);
996 mutex_enter(&dev
->mutex
);
998 /* disable channels */
999 PUT32(dev
, REG_FUNCTRL0
, 0);
1001 mutex_exit(&dev
->mutex
);
1005 return (DDI_SUCCESS
);
1009 cmpci_quiesce(dev_info_t
*dip
)
1013 if ((dev
= ddi_get_driver_private(dip
)) == NULL
) {
1014 return (DDI_FAILURE
);
1017 /* disable channels */
1018 PUT32(dev
, REG_FUNCTRL0
, 0);
1020 return (DDI_SUCCESS
);
1024 cmpci_ddi_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
1030 return (cmpci_attach(dip
));
1033 if ((dev
= ddi_get_driver_private(dip
)) == NULL
) {
1034 return (DDI_FAILURE
);
1036 return (cmpci_resume(dev
));
1039 return (DDI_FAILURE
);
1044 cmpci_ddi_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
1048 if ((dev
= ddi_get_driver_private(dip
)) == NULL
) {
1049 return (DDI_FAILURE
);
1054 return (cmpci_detach(dev
));
1057 audio_dev_suspend(dev
->adev
);
1058 return (DDI_SUCCESS
);
1061 return (DDI_FAILURE
);
1065 static struct dev_ops cmpci_dev_ops
= {
1069 nulldev
, /* identify */
1070 nulldev
, /* probe */
1071 cmpci_ddi_attach
, /* attach */
1072 cmpci_ddi_detach
, /* detach */
1077 cmpci_quiesce
, /* quiesce */
1080 static struct modldrv cmpci_modldrv
= {
1081 &mod_driverops
, /* drv_modops */
1082 "C-Media PCI Audio", /* linkinfo */
1083 &cmpci_dev_ops
, /* dev_ops */
1086 static struct modlinkage modlinkage
= {
1088 { &cmpci_modldrv
, NULL
}
1096 audio_init_ops(&cmpci_dev_ops
, "audiocmi");
1097 if ((rv
= mod_install(&modlinkage
)) != 0) {
1098 audio_fini_ops(&cmpci_dev_ops
);
1107 if ((rv
= mod_remove(&modlinkage
)) == 0) {
1108 audio_fini_ops(&cmpci_dev_ops
);
1114 _info(struct modinfo
*modinfop
)
1116 return (mod_info(&modlinkage
, modinfop
));