xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c (revision 7d1e83948cb684521e72cab96020be241508f449)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/audio/audio_driver.h>
27 #include <sys/note.h>
28 #include <sys/beep.h>
29 #include <sys/pci.h>
30 #include "audiohd.h"
31 
32 #define	DEFINTS			175
33 #define	DRVNAME			"audiohd"
34 /*
35  * Module linkage routines for the kernel
36  */
37 
38 static int audiohd_attach(dev_info_t *, ddi_attach_cmd_t);
39 static int audiohd_detach(dev_info_t *, ddi_detach_cmd_t);
40 static int audiohd_quiesce(dev_info_t *);
41 static int audiohd_resume(audiohd_state_t *);
42 static int audiohd_suspend(audiohd_state_t *);
43 
44 /* interrupt handler */
45 static uint_t audiohd_intr(caddr_t);
46 
47 /*
48  * Local routines
49  */
50 static int audiohd_init_state(audiohd_state_t *, dev_info_t *);
51 static int audiohd_init_pci(audiohd_state_t *, ddi_device_acc_attr_t *);
52 static void audiohd_fini_pci(audiohd_state_t *);
53 static int audiohd_reset_controller(audiohd_state_t *);
54 static int audiohd_init_controller(audiohd_state_t *);
55 static void audiohd_fini_controller(audiohd_state_t *);
56 static void audiohd_stop_dma(audiohd_state_t *);
57 static void audiohd_disable_intr(audiohd_state_t *);
58 static int audiohd_create_codec(audiohd_state_t *);
59 static void audiohd_build_path(audiohd_state_t *);
60 static void audiohd_destroy_codec(audiohd_state_t *);
61 static int audiohd_alloc_dma_mem(audiohd_state_t *, audiohd_dma_t *,
62     size_t, ddi_dma_attr_t *, uint_t);
63 static void audiohd_finish_output_path(hda_codec_t *codec);
64 static uint32_t audioha_codec_verb_get(void *, uint8_t,
65     uint8_t, uint16_t, uint8_t);
66 static uint32_t audioha_codec_4bit_verb_get(void *, uint8_t,
67     uint8_t, uint16_t, uint16_t);
68 static int audiohd_reinit_hda(audiohd_state_t *);
69 static int audiohd_response_from_codec(audiohd_state_t *statep,
70     uint32_t *resp, uint32_t *respex);
71 static void audiohd_restore_codec_gpio(audiohd_state_t *statep);
72 static void audiohd_change_speaker_state(audiohd_state_t *statep, int on);
73 static int audiohd_allocate_port(audiohd_state_t *statep);
74 static void audiohd_free_port(audiohd_state_t *statep);
75 static void audiohd_restore_path(audiohd_state_t *statep);
76 static int audiohd_add_controls(audiohd_state_t *statep);
77 static void audiohd_get_channels(audiohd_state_t *statep);
78 static void audiohd_init_path(audiohd_state_t *statep);
79 static void audiohd_del_controls(audiohd_state_t *statep);
80 static void audiohd_destroy(audiohd_state_t *statep);
81 static void audiohd_beep_on(void *arg);
82 static void audiohd_beep_off(void *arg);
83 static void audiohd_beep_freq(void *arg, int freq);
84 static wid_t audiohd_find_beep(hda_codec_t *codec, wid_t wid, int depth);
85 static void audiohd_build_beep_path(hda_codec_t *codec);
86 static void audiohd_build_beep_amp(hda_codec_t *codec);
87 static void  audiohd_finish_beep_path(hda_codec_t *codec);
88 static void audiohd_do_set_beep_volume(audiohd_state_t *statep,
89     audiohd_path_t *path, uint64_t val);
90 static void audiohd_set_beep_volume(audiohd_state_t *statep);
91 static int audiohd_set_beep(void *arg, uint64_t val);
92 
93 static	int	audiohd_beep;
94 static	int	audiohd_beep_divider;
95 static	int	audiohd_beep_vol = 1;
96 
97 static ddi_device_acc_attr_t hda_dev_accattr = {
98 	DDI_DEVICE_ATTR_V0,
99 	DDI_STRUCTURE_LE_ACC,
100 	DDI_STRICTORDER_ACC
101 };
102 
103 static const char *audiohd_dtypes[] = {
104 	AUDIO_PORT_LINEOUT,
105 	AUDIO_PORT_SPEAKER,
106 	AUDIO_PORT_HEADPHONES,
107 	AUDIO_PORT_CD,
108 	AUDIO_PORT_SPDIFOUT,
109 	AUDIO_PORT_DIGOUT,
110 	AUDIO_PORT_MODEM,
111 	AUDIO_PORT_HANDSET,
112 	AUDIO_PORT_LINEIN,
113 	AUDIO_PORT_AUX1IN,
114 	AUDIO_PORT_MIC,
115 	AUDIO_PORT_PHONE,
116 	AUDIO_PORT_SPDIFIN,
117 	AUDIO_PORT_DIGIN,
118 	AUDIO_PORT_NONE,	/* reserved port, don't use */
119 	AUDIO_PORT_OTHER,
120 	NULL,
121 };
122 
123 enum {
124 	CTL_VOLUME = 0,
125 	CTL_FRONT,
126 	CTL_SPEAKER,
127 	CTL_HEADPHONE,
128 	CTL_REAR,
129 	CTL_CENTER,
130 	CTL_SURROUND,
131 	CTL_LFE,
132 	CTL_IGAIN,
133 	CTL_LINEIN,
134 	CTL_MIC,
135 	CTL_CD,
136 	CTL_MONGAIN,
137 	CTL_MONSRC,
138 	CTL_RECSRC,
139 	CTL_BEEP
140 };
141 
142 static void
143 audiohd_set_chipset_info(audiohd_state_t *statep)
144 {
145 	uint32_t		devid;
146 	const char		*name;
147 	const char		*vers;
148 
149 	devid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID);
150 	devid <<= 16;
151 	devid |= pci_config_get16(statep->hda_pci_handle, PCI_CONF_DEVID);
152 
153 	name = AUDIOHD_DEV_CONFIG;
154 	vers = AUDIOHD_DEV_VERSION;
155 
156 	switch (devid) {
157 	case 0x80862668:
158 		name = "Intel HD Audio";
159 		vers = "ICH6";
160 		break;
161 	case 0x808627d8:
162 		name = "Intel HD Audio";
163 		vers = "ICH7";
164 		break;
165 	case 0x8086284b:
166 		name = "Intel HD Audio";
167 		vers = "ICH8";
168 		break;
169 	case 0x8086293e:
170 		name = "Intel HD Audio";
171 		vers = "ICH9";
172 		break;
173 	case 0x10de0371:
174 		name = "NVIDIA HD Audio";
175 		vers = "MCP55";
176 		break;
177 	case 0x10de03f0:
178 		name = "NVIDIA HD Audio";
179 		vers = "MCP61A";
180 		break;
181 	case 0x10de026c:
182 		name = "NVIDIA HD Audio";
183 		vers = "6151";
184 		break;
185 	case 0x10de03e4:
186 		name = "NVIDIA HD Audio";
187 		vers = "MCP61";
188 		break;
189 	case 0x10de044a:
190 		name = "NVIDIA HD Audio";
191 		vers = "MCP65";
192 		break;
193 	case 0x10de055c:
194 		name = "NVIDIA HD Audio";
195 		vers = "MCP67";
196 		break;
197 	case 0x1002437b:
198 		name = "ATI HD Audio";
199 		vers = "SB450";
200 		break;
201 	case 0x10024383:
202 		name = "ATI HD Audio";
203 		vers = "SB600";
204 		break;
205 	case 0x11063288:
206 		name = "VIA HD Audio";
207 		vers = "HDA";
208 		break;
209 	}
210 	/* set device information */
211 	audio_dev_set_description(statep->adev, name);
212 	audio_dev_set_version(statep->adev, vers);
213 }
214 
215 static int
216 audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
217 {
218 	audiohd_state_t		*statep;
219 	int			instance;
220 
221 	instance = ddi_get_instance(dip);
222 	switch (cmd) {
223 	case DDI_ATTACH:
224 		break;
225 
226 	case DDI_RESUME:
227 		statep = ddi_get_driver_private(dip);
228 		ASSERT(statep != NULL);
229 		return (audiohd_resume(statep));
230 
231 	default:
232 		return (DDI_FAILURE);
233 	}
234 
235 	/* High-level interrupt isn't supported by this driver */
236 	if (ddi_intr_hilevel(dip, 0) != 0) {
237 		cmn_err(CE_WARN,
238 		    "unsupported high level interrupt");
239 		return (DDI_FAILURE);
240 	}
241 
242 	/* allocate the soft state structure */
243 	statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
244 	ddi_set_driver_private(dip, statep);
245 
246 	/* interrupt cookie and initialize mutex */
247 	if (audiohd_init_state(statep, dip) != DDI_SUCCESS) {
248 		cmn_err(CE_NOTE,
249 		    "audiohd_init_state failed");
250 		goto error;
251 	}
252 
253 	/* Set PCI command register to enable bus master and memeory I/O */
254 	if (audiohd_init_pci(statep, &hda_dev_accattr) != DDI_SUCCESS) {
255 		audio_dev_warn(statep->adev,
256 		    "couldn't init pci regs");
257 		goto error;
258 	}
259 
260 	audiohd_set_chipset_info(statep);
261 
262 	if (audiohd_init_controller(statep) != DDI_SUCCESS) {
263 		audio_dev_warn(statep->adev,
264 		    "couldn't init controller");
265 		goto error;
266 	}
267 
268 	if (audiohd_create_codec(statep) != DDI_SUCCESS) {
269 		audio_dev_warn(statep->adev,
270 		    "couldn't create codec");
271 		goto error;
272 	}
273 
274 	audiohd_build_path(statep);
275 
276 	audiohd_get_channels(statep);
277 	if (audiohd_allocate_port(statep) != DDI_SUCCESS) {
278 		audio_dev_warn(statep->adev, "allocate port failure");
279 		goto error;
280 	}
281 	audiohd_init_path(statep);
282 	/* set up kernel statistics */
283 	if ((statep->hda_ksp = kstat_create(DRVNAME, instance,
284 	    DRVNAME, "controller", KSTAT_TYPE_INTR, 1,
285 	    KSTAT_FLAG_PERSISTENT)) != NULL) {
286 		kstat_install(statep->hda_ksp);
287 	}
288 
289 	/* disable interrupts and clear interrupt status */
290 	audiohd_disable_intr(statep);
291 
292 	/* set up the interrupt handler */
293 	if (ddi_add_intr(dip, 0, &statep->hda_intr_cookie,
294 	    (ddi_idevice_cookie_t *)NULL, audiohd_intr, (caddr_t)statep) !=
295 	    DDI_SUCCESS) {
296 		audio_dev_warn(statep->adev,
297 		    "bad interrupt specification ");
298 		goto error;
299 	}
300 	statep->intr_added = B_TRUE;
301 
302 	/*
303 	 * Register audio controls.
304 	 */
305 	if (audiohd_add_controls(statep) == DDI_FAILURE) {
306 		audio_dev_warn(statep->adev,
307 		    "unable to allocate controls");
308 		goto error;
309 	}
310 	if (audio_dev_register(statep->adev) != DDI_SUCCESS) {
311 		audio_dev_warn(statep->adev,
312 		    "unable to register with framework");
313 		goto error;
314 	}
315 	ddi_report_dev(dip);
316 
317 	/* enable interrupt */
318 	AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL,
319 	    AUDIOHD_INTCTL_BIT_GIE |
320 	    AUDIOHD_INTCTL_BIT_SIE);
321 	return (DDI_SUCCESS);
322 error:
323 	audiohd_destroy(statep);
324 	return (DDI_FAILURE);
325 }
326 
327 static int
328 audiohd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
329 {
330 	audiohd_state_t		*statep;
331 
332 	statep = ddi_get_driver_private(dip);
333 	ASSERT(statep != NULL);
334 
335 	switch (cmd) {
336 	case DDI_DETACH:
337 		break;
338 
339 	case DDI_SUSPEND:
340 		return (audiohd_suspend(statep));
341 
342 	default:
343 		return (DDI_FAILURE);
344 	}
345 	if (audio_dev_unregister(statep->adev) != DDI_SUCCESS)
346 		return (DDI_FAILURE);
347 
348 	if (audiohd_beep)
349 		(void) beep_fini();
350 	audiohd_destroy(statep);
351 	return (DDI_SUCCESS);
352 }
353 
354 static struct dev_ops audiohd_dev_ops = {
355 	DEVO_REV,		/* rev */
356 	0,			/* refcnt */
357 	NULL,			/* getinfo */
358 	nulldev,		/* identify */
359 	nulldev,		/* probe */
360 	audiohd_attach,		/* attach */
361 	audiohd_detach,		/* detach */
362 	nodev,			/* reset */
363 	NULL,			/* cb_ops */
364 	NULL,			/* bus_ops */
365 	NULL,			/* power */
366 	audiohd_quiesce,	/* quiesce */
367 };
368 
369 static struct modldrv audiohd_modldrv = {
370 	&mod_driverops,			/* drv_modops */
371 	"AudioHD",			/* linkinfo */
372 	&audiohd_dev_ops,		/* dev_ops */
373 };
374 
375 static struct modlinkage modlinkage = {
376 	MODREV_1,
377 	{ &audiohd_modldrv, NULL }
378 };
379 
380 int
381 _init(void)
382 {
383 	int	rv;
384 
385 	audio_init_ops(&audiohd_dev_ops, DRVNAME);
386 	if ((rv = mod_install(&modlinkage)) != 0) {
387 		audio_fini_ops(&audiohd_dev_ops);
388 	}
389 	return (rv);
390 }
391 
392 int
393 _fini(void)
394 {
395 	int	rv;
396 
397 	if ((rv = mod_remove(&modlinkage)) == 0) {
398 		audio_fini_ops(&audiohd_dev_ops);
399 	}
400 	return (rv);
401 }
402 
403 int
404 _info(struct modinfo *modinfop)
405 {
406 	return (mod_info(&modlinkage, modinfop));
407 }
408 
409 /*
410  * Audio routines
411  */
412 
413 static int
414 audiohd_engine_format(void *arg)
415 {
416 	_NOTE(ARGUNUSED(arg));
417 
418 	return (AUDIO_FORMAT_S16_LE);
419 }
420 
421 static int
422 audiohd_engine_channels(void *arg)
423 {
424 	audiohd_port_t *port = arg;
425 
426 	return (port->nchan);
427 }
428 
429 static int
430 audiohd_engine_rate(void *arg)
431 {
432 	_NOTE(ARGUNUSED(arg));
433 
434 	return (48000);
435 }
436 static void
437 audiohd_free_path(audiohd_state_t *statep)
438 {
439 	audiohd_path_t		*path;
440 	int			i;
441 
442 	for (i = 0; i < statep->pathnum; i++) {
443 		if (statep->path[i]) {
444 			path = statep->path[i];
445 			kmem_free(path, sizeof (audiohd_path_t));
446 		}
447 	}
448 }
449 static void
450 audiohd_destroy(audiohd_state_t *statep)
451 {
452 	dev_info_t		*dip = statep->hda_dip;
453 
454 	mutex_enter(&statep->hda_mutex);
455 	audiohd_stop_dma(statep);
456 	audiohd_disable_intr(statep);
457 	mutex_exit(&statep->hda_mutex);
458 	if (statep->intr_added) {
459 		ddi_remove_intr(dip, 0, statep->hda_intr_cookie);
460 	}
461 	if (statep->hda_ksp)
462 		kstat_delete(statep->hda_ksp);
463 	audiohd_free_port(statep);
464 	audiohd_free_path(statep);
465 	audiohd_destroy_codec(statep);
466 	audiohd_del_controls(statep);
467 	audiohd_fini_controller(statep);
468 	audiohd_fini_pci(statep);
469 	mutex_destroy(&statep->hda_mutex);
470 	if (statep->adev)
471 		audio_dev_free(statep->adev);
472 	kmem_free(statep, sizeof (*statep));
473 }
474 /*
475  * get the max channels the hardware supported
476  */
477 static void
478 audiohd_get_channels(audiohd_state_t *statep)
479 {
480 	int		i;
481 	uint8_t		maxp, assoc;
482 
483 	maxp = 2;
484 	for (i = 0; i < AUDIOHD_MAX_ASSOC; i++) {
485 		if (maxp < statep->chann[i]) {
486 			maxp = statep->chann[i];
487 			assoc = i;
488 		}
489 	}
490 	statep->pchan = maxp;
491 	statep->assoc = assoc;
492 	/* for record, support stereo so far */
493 	statep->rchan = 2;
494 }
495 static void
496 audiohd_init_play_path(audiohd_path_t *path)
497 {
498 	int				i;
499 	uint32_t			ctrl;
500 	uint8_t				ctrl8;
501 	uint8_t				nchann;
502 	audiohd_widget_t		*widget;
503 	audiohd_pin_t			*pin;
504 	wid_t				wid;
505 	audiohd_pin_color_t		color;
506 
507 	audiohd_state_t		*statep = path->statep;
508 	hda_codec_t		*codec = path->codec;
509 
510 	/* enable SPDIF output */
511 	for (i = 0; i < path->pin_nums; i++) {
512 		wid = path->pin_wid[i];
513 		widget = codec->widget[wid];
514 		pin = (audiohd_pin_t *)widget->priv;
515 		if (pin->device == DTYPE_SPDIF_OUT) {
516 			ctrl = audioha_codec_verb_get(
517 			    statep,
518 			    codec->index,
519 			    path->adda_wid,
520 			    AUDIOHDC_VERB_GET_SPDIF_CTL,
521 			    0);
522 			ctrl |= AUDIOHD_SPDIF_ON;
523 			ctrl8 = ctrl &
524 			    AUDIOHD_SPDIF_MASK;
525 			(void) audioha_codec_verb_get(
526 			    statep,
527 			    codec->index,
528 			    path->adda_wid,
529 			    AUDIOHDC_VERB_SET_SPDIF_LCL,
530 			    ctrl8);
531 			/*
532 			 * We find that on intel ICH10 chipset with codec
533 			 * ALC888, audio is scratchy if we set the tag on the
534 			 * SPDIF path. So we just return here without setting
535 			 * the tag for the path as a workaround.
536 			 */
537 			if (codec->vid == AUDIOHD_CODECID_ALC888) {
538 				return;
539 			}
540 		}
541 	}
542 	wid = path->pin_wid[0];
543 	widget = codec->widget[wid];
544 	pin = (audiohd_pin_t *)widget->priv;
545 
546 	/* two channels supported */
547 	if (pin->device == DTYPE_SPEAKER ||
548 	    pin->device == DTYPE_HP_OUT ||
549 	    pin->assoc != statep->assoc) {
550 		(void) audioha_codec_verb_get(
551 		    statep,
552 		    codec->index,
553 		    path->adda_wid,
554 		    AUDIOHDC_VERB_SET_STREAM_CHANN,
555 		    statep->port[PORT_DAC]->index <<
556 		    AUDIOHD_PLAY_TAG_OFF);
557 		(void) audioha_codec_4bit_verb_get(
558 		    statep,
559 		    codec->index,
560 		    path->adda_wid,
561 		    AUDIOHDC_VERB_SET_CONV_FMT,
562 		    AUDIOHD_FMT_PCM << 4 |
563 		    statep->pchan - 1);
564 	/* multichannel supported */
565 	} else {
566 		color = (pin->config >> AUDIOHD_PIN_CLR_OFF) &
567 		    AUDIOHD_PIN_CLR_MASK;
568 		switch (color) {
569 		case AUDIOHD_PIN_BLACK:
570 			nchann = statep->pchan - 2;
571 			break;
572 		case AUDIOHD_PIN_ORANGE:
573 			nchann = 2;
574 			break;
575 		case AUDIOHD_PIN_GREY:
576 			nchann = 4;
577 			break;
578 		case AUDIOHD_PIN_GREEN:
579 			nchann = 0;
580 			break;
581 		default:
582 			nchann = 0;
583 			break;
584 		}
585 		(void) audioha_codec_verb_get(statep,
586 		    codec->index,
587 		    path->adda_wid,
588 		    AUDIOHDC_VERB_SET_STREAM_CHANN,
589 		    statep->port[PORT_DAC]->index <<
590 		    AUDIOHD_PLAY_TAG_OFF |
591 		    nchann);
592 		(void) audioha_codec_4bit_verb_get(
593 		    statep,
594 		    codec->index,
595 		    path->adda_wid,
596 		    AUDIOHDC_VERB_SET_CONV_FMT,
597 		    AUDIOHD_FMT_PCM << 4 |
598 		    statep->pchan - 1);
599 	}
600 }
601 static void
602 audiohd_init_record_path(audiohd_path_t *path)
603 {
604 	audiohd_state_t		*statep = path->statep;
605 	hda_codec_t		*codec = path->codec;
606 	int			i;
607 	wid_t			wid;
608 	audiohd_pin_t		*pin;
609 	audiohd_widget_t	*widget;
610 
611 	for (i = 0; i < path->pin_nums; i++) {
612 		wid = path->pin_wid[i];
613 		widget = codec->widget[wid];
614 		pin = (audiohd_pin_t *)widget->priv;
615 	/*
616 	 * Since there is no SPDIF input device available for test,
617 	 * we will use this code in the future to support SPDIF input
618 	 */
619 #if 0
620 		if (pin->device == DTYPE_SPDIF_IN) {
621 			ctrl = audioha_codec_verb_get(
622 			    statep,
623 			    codec->index,
624 			    path->adda_wid,
625 			    AUDIOHDC_VERB_GET_SPDIF_CTL,
626 			    0);
627 			ctrl |= AUDIOHD_SPDIF_ON;
628 			ctrl8 = ctrl &
629 			    AUDIOHD_SPDIF_MASK;
630 			(void) audioha_codec_verb_get(
631 			    statep,
632 			    codec->index,
633 			    path->adda_wid,
634 			    AUDIOHDC_VERB_SET_SPDIF_LCL,
635 			    ctrl8);
636 			statep->inmask |= (1U << DTYPE_SPDIF_IN);
637 		}
638 #endif
639 		if (pin->device == DTYPE_MIC_IN) {
640 			if (((pin->config >>
641 			    AUDIOHD_PIN_CONTP_OFF) &
642 			    AUDIOHD_PIN_CONTP_MASK) ==
643 			    AUDIOHD_PIN_CON_FIXED)
644 				statep->port[PORT_ADC]->index = path->tag;
645 		}
646 		if ((pin->device == DTYPE_LINE_IN) ||
647 		    (pin->device == DTYPE_CD) ||
648 		    (pin->device == DTYPE_MIC_IN)) {
649 			statep->inmask |= (1U << pin->device);
650 		}
651 	}
652 	(void) audioha_codec_verb_get(statep,
653 	    codec->index,
654 	    path->adda_wid,
655 	    AUDIOHDC_VERB_SET_STREAM_CHANN,
656 	    path->tag <<
657 	    AUDIOHD_REC_TAG_OFF);
658 	(void) audioha_codec_4bit_verb_get(statep,
659 	    codec->index,
660 	    path->adda_wid,
661 	    AUDIOHDC_VERB_SET_CONV_FMT,
662 	    AUDIOHD_FMT_PCM << 4 | statep->rchan - 1);
663 
664 }
665 static void
666 audiohd_init_path(audiohd_state_t *statep)
667 {
668 	int				i;
669 	audiohd_path_t			*path;
670 
671 	for (i = 0; i < statep->pathnum; i++) {
672 		path = statep->path[i];
673 		if (!path)
674 			continue;
675 		switch (path->path_type) {
676 			case PLAY:
677 				audiohd_init_play_path(path);
678 				break;
679 			case RECORD:
680 				audiohd_init_record_path(path);
681 				break;
682 			default:
683 				break;
684 		}
685 	}
686 	statep->in_port = 0;
687 }
688 
689 static int
690 audiohd_reset_port(audiohd_port_t *port)
691 {
692 	uint16_t		regbase;
693 	audiohd_state_t		*statep;
694 	uint8_t			bTmp;
695 	int			i;
696 
697 	regbase = port->regoff;
698 	statep = port->statep;
699 
700 	bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL);
701 	/* stop stream */
702 	bTmp &= ~AUDIOHD_REG_RIRBSIZE;
703 	AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp);
704 
705 	/* wait 40us for stream to stop as HD spec */
706 	drv_usecwait(40);
707 
708 	/* reset stream */
709 	bTmp |= AUDIOHDR_SD_CTL_SRST;
710 	AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp);
711 
712 	for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) {
713 		/* Empirical testing time, which works well */
714 		drv_usecwait(50);
715 		bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL);
716 		bTmp &= AUDIOHDR_SD_CTL_SRST;
717 		if (bTmp)
718 			break;
719 	}
720 
721 	if (!bTmp) {
722 		audio_dev_warn(statep->adev, "Failed to reset stream %d",
723 		    port->index);
724 		return (DDI_FAILURE);
725 	}
726 
727 	/* Empirical testing time, which works well */
728 	drv_usecwait(300);
729 
730 	/* exit reset stream */
731 	bTmp &= ~AUDIOHDR_SD_CTL_SRST;
732 	AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp);
733 
734 	for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) {
735 		/* Empircal testing time */
736 		drv_usecwait(50);
737 		bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL);
738 		bTmp &= AUDIOHDR_SD_CTL_SRST;
739 		if (!bTmp)
740 			break;
741 	}
742 
743 	if (bTmp) {
744 		audio_dev_warn(statep->adev,
745 		    "Failed to exit reset state for"
746 		    " stream %d, bTmp=0x%02x", port->index, bTmp);
747 		return (DDI_FAILURE);
748 	}
749 
750 	AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_BDLPL,
751 	    (uint32_t)port->bdl_paddr);
752 	AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_BDLPU,
753 	    (uint32_t)(port->bdl_paddr >> 32));
754 	AUDIOHD_REG_SET16(regbase + AUDIOHD_SDREG_OFFSET_LVI,
755 	    AUDIOHD_BDLE_NUMS - 1);
756 	AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_CBL,
757 	    port->samp_size * AUDIOHD_BDLE_NUMS);
758 
759 	AUDIOHD_REG_SET16(regbase + AUDIOHD_SDREG_OFFSET_FORMAT,
760 	    port->format << 4 | port->nchan - 1);
761 
762 	/* clear status */
763 	AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_STS,
764 	    AUDIOHDR_SD_STS_BCIS | AUDIOHDR_SD_STS_FIFOE |
765 	    AUDIOHDR_SD_STS_DESE);
766 
767 	/* set stream tag */
768 	AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL +
769 	    AUDIOHD_PLAY_CTL_OFF,
770 	    (port->index) << AUDIOHD_PLAY_TAG_OFF);
771 
772 	return (DDI_SUCCESS);
773 }
774 static int
775 audiohd_engine_open(void *arg, int flag,
776     unsigned *fragfrp, unsigned *nfragsp, caddr_t *bufp)
777 {
778 	audiohd_port_t	*port = arg;
779 	audiohd_state_t	*statep = port->statep;
780 
781 	_NOTE(ARGUNUSED(flag));
782 
783 	mutex_enter(&statep->hda_mutex);
784 	(void) audiohd_reset_port(port);
785 	mutex_exit(&statep->hda_mutex);
786 
787 	port->started = B_FALSE;
788 	port->count = 0;
789 	port->curpos = 0;
790 	*fragfrp = port->fragfr;
791 	*nfragsp = AUDIOHD_BDLE_NUMS;
792 	*bufp = port->samp_kaddr;
793 
794 	return (0);
795 }
796 
797 static void
798 audiohd_start_port(audiohd_port_t *port)
799 {
800 	audiohd_state_t	*statep = port->statep;
801 
802 	ASSERT(mutex_owned(&statep->hda_mutex));
803 
804 	/* if suspended, then do nothing else */
805 	if (statep->suspended) {
806 		return;
807 	}
808 
809 	/* Enable interrupt and start DMA */
810 	AUDIOHD_REG_SET8(port->regoff + AUDIOHD_SDREG_OFFSET_CTL,
811 	    AUDIOHDR_SD_CTL_INTS | AUDIOHDR_SD_CTL_SRUN);
812 }
813 
814 static void
815 audiohd_stop_port(audiohd_port_t *port)
816 {
817 	audiohd_state_t	*statep = port->statep;
818 
819 	ASSERT(mutex_owned(&statep->hda_mutex));
820 	/* if suspended, then do nothing else */
821 	if (statep->suspended) {
822 		return;
823 	}
824 	AUDIOHD_REG_SET8(port->regoff + AUDIOHD_SDREG_OFFSET_CTL, 0);
825 }
826 
827 static int
828 audiohd_engine_start(void *arg)
829 {
830 	audiohd_port_t		*port = arg;
831 	audiohd_state_t		*statep = port->statep;
832 
833 	mutex_enter(&statep->hda_mutex);
834 	if (!port->started) {
835 		audiohd_start_port(port);
836 		port->started = B_TRUE;
837 		port->triggered = B_TRUE;
838 	}
839 	mutex_exit(&statep->hda_mutex);
840 	return (0);
841 }
842 
843 static void
844 audiohd_engine_stop(void *arg)
845 {
846 	audiohd_port_t		*port = arg;
847 	audiohd_state_t		*statep = port->statep;
848 
849 	mutex_enter(&statep->hda_mutex);
850 	if (port->started) {
851 		audiohd_stop_port(port);
852 	}
853 	port->started = B_FALSE;
854 	mutex_exit(&statep->hda_mutex);
855 }
856 
857 static void
858 audiohd_update_port(audiohd_port_t *port)
859 {
860 	int			pos;
861 	uint32_t		len;
862 	audiohd_state_t		*statep = port->statep;
863 
864 	pos = AUDIOHD_REG_GET32(port->regoff + AUDIOHD_SDREG_OFFSET_LPIB);
865 	pos &= AUDIOHD_POS_MASK;
866 	if (pos > port->curpos)
867 		len = (pos - port->curpos) & AUDIOHD_POS_MASK;
868 	else {
869 		len = pos + port->samp_size * AUDIOHD_BDLE_NUMS - port->curpos;
870 		len &= AUDIOHD_POS_MASK;
871 	}
872 	port->curpos += len;
873 	if (port->curpos >= port->samp_size * AUDIOHD_BDLE_NUMS)
874 		port->curpos -= port->samp_size * AUDIOHD_BDLE_NUMS;
875 
876 	port->len = len;
877 	port->count += len / (port->nchan * 2);
878 
879 
880 }
881 
882 static uint64_t
883 audiohd_engine_count(void *arg)
884 {
885 	audiohd_port_t	*port = arg;
886 	audiohd_state_t	*statep = port->statep;
887 	uint64_t	val;
888 
889 	mutex_enter(&statep->hda_mutex);
890 	audiohd_update_port(port);
891 	val = port->count;
892 	mutex_exit(&statep->hda_mutex);
893 	return (val);
894 }
895 
896 static void
897 audiohd_engine_close(void *arg)
898 {
899 	audiohd_port_t		*port = arg;
900 	audiohd_state_t		*statep = port->statep;
901 
902 	mutex_enter(&statep->hda_mutex);
903 	audiohd_stop_port(port);
904 	port->started = B_FALSE;
905 	port->triggered = B_FALSE;
906 	mutex_exit(&statep->hda_mutex);
907 }
908 
909 static void
910 audiohd_engine_sync(void *arg, unsigned nframes)
911 {
912 	audiohd_port_t *port = arg;
913 
914 	_NOTE(ARGUNUSED(nframes));
915 
916 	(void) ddi_dma_sync(port->samp_dmah, port->curpos,
917 	    port->len, port->sync_dir);
918 
919 }
920 
921 static size_t
922 audiohd_engine_qlen(void *arg)
923 {
924 	audiohd_port_t *port = arg;
925 
926 	return (port->fragfr);
927 }
928 
929 audio_engine_ops_t audiohd_engine_ops = {
930 	AUDIO_ENGINE_VERSION,		/* version number */
931 	audiohd_engine_open,
932 	audiohd_engine_close,
933 	audiohd_engine_start,
934 	audiohd_engine_stop,
935 	audiohd_engine_count,
936 	audiohd_engine_format,
937 	audiohd_engine_channels,
938 	audiohd_engine_rate,
939 	audiohd_engine_sync,
940 	audiohd_engine_qlen,
941 };
942 
943 static int
944 audiohd_get_value(void *arg, uint64_t *val)
945 {
946 	audiohd_ctrl_t	*pc = arg;
947 	audiohd_state_t	*statep = pc->statep;
948 
949 	mutex_enter(&statep->hda_mutex);
950 	*val = pc->val;
951 	mutex_exit(&statep->hda_mutex);
952 	return (0);
953 }
954 
955 static void
956 audiohd_set_output_gain(audiohd_state_t *statep)
957 {
958 	int			i;
959 	audiohd_path_t		*path;
960 	uint_t			tmp;
961 	wid_t			wid;
962 	audiohd_widget_t	*w;
963 	uint8_t			gain;
964 	uint32_t		maxgain;
965 
966 	if (statep->soft_volume)
967 		return;
968 	gain = (uint8_t)statep->controls[CTL_VOLUME]->val;
969 	for (i = 0; i < statep->pathnum; i++) {
970 		path = statep->path[i];
971 		if (!path || path->path_type != PLAY)
972 			continue;
973 		/* use the DACs to adjust the volume */
974 		wid = path->adda_wid;
975 		w = path->codec->widget[wid];
976 		maxgain = w->outamp_cap &
977 		    AUDIOHDC_AMP_CAP_STEP_NUMS;
978 		maxgain >>= AUDIOHD_GAIN_OFF;
979 		if (w->outamp_cap) {
980 			tmp = gain * maxgain / 100;
981 			(void) audioha_codec_4bit_verb_get(statep,
982 			    path->codec->index,
983 			    wid,
984 			    AUDIOHDC_VERB_SET_AMP_MUTE,
985 			    AUDIOHDC_AMP_SET_LEFT |
986 			    AUDIOHDC_AMP_SET_OUTPUT | tmp);
987 			(void) audioha_codec_4bit_verb_get(statep,
988 			    path->codec->index,
989 			    wid,
990 			    AUDIOHDC_VERB_SET_AMP_MUTE,
991 			    AUDIOHDC_AMP_SET_RIGHT |
992 			    AUDIOHDC_AMP_SET_OUTPUT | tmp);
993 		}
994 	}
995 }
996 
997 static void
998 audiohd_do_set_pin_volume(audiohd_state_t *statep, audiohd_path_t *path,
999     uint64_t val)
1000 {
1001 	uint8_t				l, r;
1002 	uint_t				tmp;
1003 	int				gain;
1004 
1005 	if (path->mute_wid && val == 0) {
1006 		(void) audioha_codec_4bit_verb_get(
1007 		    statep,
1008 		    path->codec->index,
1009 		    path->mute_wid,
1010 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1011 		    path->mute_dir |
1012 		    AUDIOHDC_AMP_SET_LNR |
1013 		    AUDIOHDC_AMP_SET_MUTE);
1014 		return;
1015 	}
1016 
1017 	l = (val & 0xff00) >> 8;
1018 	r = (val & 0xff);
1019 
1020 	tmp = l * path->gain_bits / 100;
1021 	(void) audioha_codec_4bit_verb_get(statep,
1022 	    path->codec->index,
1023 	    path->gain_wid,
1024 	    AUDIOHDC_VERB_SET_AMP_MUTE,
1025 	    AUDIOHDC_AMP_SET_LEFT | path->gain_dir |
1026 	    tmp);
1027 	tmp = r * path->gain_bits / 100;
1028 	(void) audioha_codec_4bit_verb_get(statep,
1029 	    path->codec->index,
1030 	    path->gain_wid,
1031 	    AUDIOHDC_VERB_SET_AMP_MUTE,
1032 	    AUDIOHDC_AMP_SET_RIGHT | path->gain_dir |
1033 	    tmp);
1034 	if (path->mute_wid && path->mute_wid != path->gain_wid) {
1035 		gain = AUDIOHDC_GAIN_MAX;
1036 		(void) audioha_codec_4bit_verb_get(
1037 		    statep,
1038 		    path->codec->index,
1039 		    path->mute_wid,
1040 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1041 		    path->mute_dir |
1042 		    AUDIOHDC_AMP_SET_LEFT |
1043 		    gain);
1044 		(void) audioha_codec_4bit_verb_get(
1045 		    statep,
1046 		    path->codec->index,
1047 		    path->mute_wid,
1048 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1049 		    path->mute_dir |
1050 		    AUDIOHDC_AMP_SET_RIGHT |
1051 		    gain);
1052 	}
1053 }
1054 
1055 static void
1056 audiohd_set_pin_volume(audiohd_state_t *statep, audiohda_device_type_t type)
1057 {
1058 	int				i, j;
1059 	audiohd_path_t			*path;
1060 	audiohd_widget_t		*widget;
1061 	wid_t				wid;
1062 	audiohd_pin_t			*pin;
1063 	hda_codec_t			*codec;
1064 	uint64_t			val;
1065 	audiohd_ctrl_t			*control;
1066 
1067 	switch (type) {
1068 		case DTYPE_SPEAKER:
1069 			control = statep->controls[CTL_SPEAKER];
1070 			if (control == NULL)
1071 				return;
1072 			val = control->val;
1073 			break;
1074 		case DTYPE_HP_OUT:
1075 			control = statep->controls[CTL_HEADPHONE];
1076 			if (control == NULL)
1077 				return;
1078 			val = control->val;
1079 			break;
1080 		case DTYPE_LINEOUT:
1081 			control = statep->controls[CTL_FRONT];
1082 			if (control == NULL)
1083 				return;
1084 			val = control->val;
1085 			break;
1086 
1087 		case DTYPE_CD:
1088 			control = statep->controls[CTL_CD];
1089 			if (control == NULL)
1090 				return;
1091 			val = control->val;
1092 			break;
1093 		case DTYPE_LINE_IN:
1094 			control = statep->controls[CTL_LINEIN];
1095 			if (control == NULL)
1096 				return;
1097 			val = control->val;
1098 			break;
1099 		case DTYPE_MIC_IN:
1100 			control = statep->controls[CTL_MIC];
1101 			if (control == NULL)
1102 				return;
1103 			val = control->val;
1104 			break;
1105 	}
1106 
1107 	for (i = 0; i < statep->pathnum; i++) {
1108 		path = statep->path[i];
1109 		if (!path)
1110 			continue;
1111 		codec = path->codec;
1112 		for (j = 0; j < path->pin_nums; j++) {
1113 			wid = path->pin_wid[j];
1114 			widget = codec->widget[wid];
1115 			pin = (audiohd_pin_t *)widget->priv;
1116 			if ((pin->device == type) && path->gain_wid) {
1117 				audiohd_do_set_pin_volume(statep, path, val);
1118 			}
1119 		}
1120 	}
1121 }
1122 
1123 
1124 static void
1125 audiohd_set_pin_volume_by_color(audiohd_state_t *statep,
1126     audiohd_pin_color_t color)
1127 {
1128 	int			i, j;
1129 	audiohd_path_t		*path;
1130 	audiohd_widget_t	*widget;
1131 	wid_t			wid;
1132 	audiohd_pin_t		*pin;
1133 	hda_codec_t		*codec;
1134 	uint8_t			l, r;
1135 	uint64_t		val;
1136 	audiohd_pin_color_t	clr;
1137 	audiohd_ctrl_t		*control;
1138 
1139 	switch (color) {
1140 		case AUDIOHD_PIN_GREEN:
1141 			control = statep->controls[CTL_FRONT];
1142 			if (control == NULL)
1143 				return;
1144 			val = control->val;
1145 			break;
1146 		case AUDIOHD_PIN_BLACK:
1147 			control = statep->controls[CTL_REAR];
1148 			if (control == NULL)
1149 				return;
1150 			val = control->val;
1151 			break;
1152 		case AUDIOHD_PIN_ORANGE:
1153 			control = statep->controls[CTL_CENTER];
1154 			if (control == NULL)
1155 				return;
1156 			l = control->val;
1157 			control = statep->controls[CTL_LFE];
1158 			if (control == NULL)
1159 				return;
1160 			r = control->val;
1161 			val = (l << 8) | r;
1162 			break;
1163 		case AUDIOHD_PIN_GREY:
1164 			control = statep->controls[CTL_SURROUND];
1165 			if (control == NULL)
1166 				return;
1167 			val = control->val;
1168 			break;
1169 	}
1170 
1171 	for (i = 0; i < statep->pathnum; i++) {
1172 		path = statep->path[i];
1173 		if (!path)
1174 			continue;
1175 		codec = path->codec;
1176 		for (j = 0; j < path->pin_nums; j++) {
1177 			wid = path->pin_wid[j];
1178 			widget = codec->widget[wid];
1179 			pin = (audiohd_pin_t *)widget->priv;
1180 			clr = (pin->config >> AUDIOHD_PIN_CLR_OFF) &
1181 			    AUDIOHD_PIN_CLR_MASK;
1182 			if ((clr == color) && path->gain_wid) {
1183 				audiohd_do_set_pin_volume(statep, path, val);
1184 			}
1185 		}
1186 	}
1187 }
1188 
1189 static int
1190 audiohd_set_input_pin(audiohd_state_t *statep)
1191 {
1192 	uint64_t		val;
1193 	hda_codec_t		*codec;
1194 	audiohd_pin_t		*pin;
1195 	audiohd_path_t		*path;
1196 	audiohd_widget_t	*widget, *w;
1197 	int			i, j;
1198 	wid_t			wid, pin_wid = 0;
1199 
1200 	val = statep->controls[CTL_RECSRC]->val;
1201 	for (i = 0; i < statep->pathnum; i++) {
1202 		path = statep->path[i];
1203 		if (!path || path->path_type != RECORD)
1204 			continue;
1205 		switch ((ddi_ffs(val & 0xffff)) - 1) {
1206 		case DTYPE_LINE_IN:
1207 		case DTYPE_MIC_IN:
1208 		case DTYPE_CD:
1209 			for (j = 0; j < path->pin_nums; j++) {
1210 				wid = path->pin_wid[j];
1211 				widget = path->codec->widget[wid];
1212 				pin = (audiohd_pin_t *)widget->priv;
1213 				if ((1U << pin->device) == val) {
1214 					AUDIOHD_ENABLE_PIN_IN(statep,
1215 					    path->codec->index,
1216 					    pin->wid);
1217 					pin_wid = pin->wid;
1218 					codec = path->codec;
1219 					statep->in_port = pin->device;
1220 				} else if (statep->in_port == pin->device) {
1221 					AUDIOHD_DISABLE_PIN_IN(statep,
1222 					    path->codec->index,
1223 					    pin->wid);
1224 				}
1225 			}
1226 			break;
1227 		default:
1228 			break;
1229 		}
1230 		break;
1231 	}
1232 	if (pin_wid == 0)
1233 		return (DDI_SUCCESS);
1234 	w = codec->widget[pin_wid];
1235 	pin = (audiohd_pin_t *)w->priv;
1236 	w = codec->widget[pin->adc_dac_wid];
1237 	path = (audiohd_path_t *)w->priv;
1238 	/*
1239 	 * If there is a real selector in this input path,
1240 	 * we select the right one input for the selector.
1241 	 */
1242 	if (path->sum_wid) {
1243 		w = codec->widget[path->sum_wid];
1244 		if (w->type == WTYPE_AUDIO_SEL) {
1245 			for (i = 0; i < path->pin_nums; i++)
1246 				if (path->pin_wid[i] == pin_wid)
1247 					break;
1248 			(void) audioha_codec_verb_get(
1249 			    statep, codec->index, path->sum_wid,
1250 			    AUDIOHDC_VERB_SET_CONN_SEL,
1251 			    path->sum_selconn[i]);
1252 		}
1253 	}
1254 	return (DDI_SUCCESS);
1255 }
1256 
1257 static void
1258 audiohd_set_pin_monitor_gain(hda_codec_t *codec, audiohd_state_t *statep,
1259     uint_t caddr, audiohd_pin_t *pin, uint64_t gain)
1260 {
1261 	int 			i, k;
1262 	uint_t			ltmp, rtmp;
1263 	audiohd_widget_t	*widget;
1264 	uint8_t		l, r;
1265 
1266 	l = (gain & 0xff00) >> 8;
1267 	r = (gain & 0xff);
1268 
1269 	for (k = 0; k < pin->num; k++) {
1270 		ltmp = l * pin->mg_gain[k] / 100;
1271 		rtmp = r * pin->mg_gain[k] / 100;
1272 		widget = codec->widget[pin->mg_wid[k]];
1273 		if (pin->mg_dir[k] == AUDIOHDC_AMP_SET_OUTPUT) {
1274 			(void) audioha_codec_4bit_verb_get(
1275 			    statep,
1276 			    caddr,
1277 			    pin->mg_wid[k],
1278 			    AUDIOHDC_VERB_SET_AMP_MUTE,
1279 			    AUDIOHDC_AMP_SET_LEFT|
1280 			    pin->mg_dir[k] | ltmp);
1281 			(void) audioha_codec_4bit_verb_get(
1282 			    statep,
1283 			    caddr,
1284 			    pin->mg_wid[k],
1285 			    AUDIOHDC_VERB_SET_AMP_MUTE,
1286 			    AUDIOHDC_AMP_SET_RIGHT|
1287 			    pin->mg_dir[k] | rtmp);
1288 		} else if (pin->mg_dir[k] == AUDIOHDC_AMP_SET_INPUT) {
1289 			for (i = 0; i < widget->used; i++) {
1290 				(void) audioha_codec_4bit_verb_get(
1291 				    statep,
1292 				    caddr,
1293 				    pin->mg_wid[k],
1294 				    AUDIOHDC_VERB_SET_AMP_MUTE,
1295 				    AUDIOHDC_AMP_SET_RIGHT|
1296 				    widget->selmon[i]<<
1297 				    AUDIOHDC_AMP_SET_INDEX_OFFSET |
1298 				    pin->mg_dir[k] | rtmp);
1299 				(void) audioha_codec_4bit_verb_get(
1300 				    statep,
1301 				    caddr,
1302 				    pin->mg_wid[k],
1303 				    AUDIOHDC_VERB_SET_AMP_MUTE,
1304 				    AUDIOHDC_AMP_SET_LEFT|
1305 				    widget->selmon[i]<<
1306 				    AUDIOHDC_AMP_SET_INDEX_OFFSET |
1307 				    pin->mg_dir[k] | ltmp);
1308 			}
1309 		}
1310 	}
1311 }
1312 
1313 static void
1314 audiohd_set_monitor_gain(audiohd_state_t *statep)
1315 {
1316 	int			i, j;
1317 	audiohd_path_t		*path;
1318 	uint_t			caddr;
1319 	audiohd_widget_t	*w;
1320 	wid_t			wid;
1321 	audiohd_pin_t		*pin;
1322 	audiohd_ctrl_t		*ctrl;
1323 	uint64_t		val;
1324 
1325 	ctrl = statep->controls[CTL_MONGAIN];
1326 	if (ctrl == NULL)
1327 		return;
1328 	val = ctrl->val;
1329 
1330 	for (i = 0; i < statep->pathnum; i++) {
1331 		path = statep->path[i];
1332 		if (path == NULL || path->path_type != PLAY)
1333 			continue;
1334 		caddr = path->codec->index;
1335 		for (j = 0; j < path->pin_nums; j++) {
1336 			wid = path->pin_wid[j];
1337 			w = path->codec->widget[wid];
1338 			pin = (audiohd_pin_t *)w->priv;
1339 			audiohd_set_pin_monitor_gain(path->codec, statep,
1340 			    caddr, pin, val);
1341 		}
1342 	}
1343 
1344 }
1345 
1346 static void
1347 audiohd_set_beep_volume(audiohd_state_t *statep)
1348 {
1349 	int			i;
1350 	audiohd_path_t		*path;
1351 	hda_codec_t		*codec;
1352 	uint64_t		val;
1353 	uint_t			tmp;
1354 	audiohd_ctrl_t		*control;
1355 	uint32_t		vid;
1356 
1357 	control = statep->controls[CTL_BEEP];
1358 	if (control == NULL)
1359 		return;
1360 	val = control->val;
1361 	for (i = 0; i < statep->pathnum; i++) {
1362 		path = statep->path[i];
1363 		if (!path || path->path_type != BEEP)
1364 			continue;
1365 		codec = path->codec;
1366 		vid = codec->vid;
1367 		vid = vid >> 16;
1368 
1369 		switch (vid) {
1370 		case  AUDIOHD_VID_SIGMATEL:
1371 			/*
1372 			 * Sigmatel HD codec specific operation.
1373 			 * There is a workaround,
1374 			 * Due to Sigmatel HD codec hardware problem,
1375 			 * which it can't mute beep when volume is 0.
1376 			 * So add global value audiohd_beep_vol,
1377 			 * Set freq to 0 when volume is 0.
1378 			 */
1379 			tmp = val * path->gain_bits / 100;
1380 			if (tmp == 0) {
1381 				audiohd_beep_vol = 0;
1382 			} else {
1383 				audiohd_beep_vol = tmp;
1384 				(void) audioha_codec_verb_get(
1385 				    statep,
1386 				    codec->index,
1387 				    path->beep_wid,
1388 				    AUDIOHDC_VERB_SET_BEEP_VOL,
1389 				    tmp);
1390 			}
1391 			break;
1392 
1393 		default:
1394 			/* Common operation based on audiohd spec */
1395 			audiohd_do_set_beep_volume(statep, path, val);
1396 			break;
1397 		}
1398 	}
1399 }
1400 
1401 static void
1402 audiohd_do_set_beep_volume(audiohd_state_t *statep, audiohd_path_t *path,
1403     uint64_t val)
1404 {
1405 	uint8_t		l, r;
1406 	uint_t		tmp;
1407 	int		gain;
1408 
1409 	if (val == 0) {
1410 		(void) audioha_codec_4bit_verb_get(
1411 		    statep,
1412 		    path->codec->index,
1413 		    path->mute_wid,
1414 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1415 		    path->mute_dir |
1416 		    AUDIOHDC_AMP_SET_LNR |
1417 		    AUDIOHDC_AMP_SET_MUTE);
1418 		return;
1419 	}
1420 
1421 	r = (val & 0xff);
1422 	l = r;
1423 
1424 	tmp = l * path->gain_bits / 100;
1425 	(void) audioha_codec_4bit_verb_get(statep,
1426 	    path->codec->index,
1427 	    path->gain_wid,
1428 	    AUDIOHDC_VERB_SET_AMP_MUTE,
1429 	    AUDIOHDC_AMP_SET_LEFT | path->gain_dir |
1430 	    tmp);
1431 	tmp = r * path->gain_bits / 100;
1432 	(void) audioha_codec_4bit_verb_get(statep,
1433 	    path->codec->index,
1434 	    path->gain_wid,
1435 	    AUDIOHDC_VERB_SET_AMP_MUTE,
1436 	    AUDIOHDC_AMP_SET_RIGHT | path->gain_dir |
1437 	    tmp);
1438 	if (path->mute_wid != path->gain_wid) {
1439 		gain = AUDIOHDC_GAIN_MAX;
1440 		(void) audioha_codec_4bit_verb_get(
1441 		    statep,
1442 		    path->codec->index,
1443 		    path->mute_wid,
1444 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1445 		    path->mute_dir |
1446 		    AUDIOHDC_AMP_SET_LEFT |
1447 		    gain);
1448 		(void) audioha_codec_4bit_verb_get(
1449 		    statep,
1450 		    path->codec->index,
1451 		    path->mute_wid,
1452 		    AUDIOHDC_VERB_SET_AMP_MUTE,
1453 		    path->mute_dir |
1454 		    AUDIOHDC_AMP_SET_RIGHT |
1455 		    gain);
1456 	}
1457 }
1458 
1459 static void
1460 audiohd_configure_output(audiohd_state_t *statep)
1461 {
1462 	audiohd_set_pin_volume(statep, DTYPE_LINEOUT);
1463 	audiohd_set_pin_volume(statep, DTYPE_SPEAKER);
1464 	audiohd_set_pin_volume(statep, DTYPE_HP_OUT);
1465 
1466 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREEN);
1467 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_BLACK);
1468 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREY);
1469 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE);
1470 
1471 	audiohd_set_output_gain(statep);
1472 }
1473 static void
1474 audiohd_configure_input(audiohd_state_t *statep)
1475 {
1476 	(void) audiohd_set_input_pin(statep);
1477 	audiohd_set_monitor_gain(statep);
1478 	audiohd_set_pin_volume(statep, DTYPE_LINE_IN);
1479 	audiohd_set_pin_volume(statep, DTYPE_CD);
1480 	audiohd_set_pin_volume(statep, DTYPE_MIC_IN);
1481 }
1482 static int
1483 audiohd_set_volume(void *arg, uint64_t val)
1484 {
1485 	audiohd_ctrl_t	*pc = arg;
1486 	audiohd_state_t	*statep = pc->statep;
1487 
1488 	val &= 0xff;
1489 	if (val > 100)
1490 		return (EINVAL);
1491 
1492 	mutex_enter(&statep->hda_mutex);
1493 	pc->val = val;
1494 	audiohd_configure_output(statep);
1495 	mutex_exit(&statep->hda_mutex);
1496 
1497 	return (0);
1498 }
1499 
1500 static int
1501 audiohd_set_recsrc(void *arg, uint64_t val)
1502 {
1503 	audiohd_ctrl_t	*pc = arg;
1504 	audiohd_state_t *statep = pc->statep;
1505 
1506 	if (val & ~(statep->inmask))
1507 		return (EINVAL);
1508 
1509 	mutex_enter(&statep->hda_mutex);
1510 	pc->val = val;
1511 	audiohd_configure_input(statep);
1512 	mutex_exit(&statep->hda_mutex);
1513 	return (0);
1514 }
1515 
1516 static int
1517 audiohd_set_rear(void *arg, uint64_t val)
1518 {
1519 	audiohd_ctrl_t	*pc = arg;
1520 	audiohd_state_t	*statep = pc->statep;
1521 	uint8_t		l, r;
1522 
1523 	if (val & ~0xffff)
1524 		return (EINVAL);
1525 
1526 	l = (val & 0xff00) >> 8;
1527 	r = (val & 0xff);
1528 	if ((l > 100) || (r > 100))
1529 		return (EINVAL);
1530 
1531 	mutex_enter(&statep->hda_mutex);
1532 	pc->val = val;
1533 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_BLACK);
1534 	mutex_exit(&statep->hda_mutex);
1535 
1536 	return (0);
1537 }
1538 
1539 static int
1540 audiohd_set_center(void *arg, uint64_t val)
1541 {
1542 	audiohd_ctrl_t	*pc = arg;
1543 	audiohd_state_t	*statep = pc->statep;
1544 
1545 	val &= 0xff;
1546 
1547 	if (val > 100)
1548 		return (EINVAL);
1549 
1550 	mutex_enter(&statep->hda_mutex);
1551 	pc->val = val;
1552 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE);
1553 	mutex_exit(&statep->hda_mutex);
1554 
1555 	return (0);
1556 }
1557 
1558 static int
1559 audiohd_set_surround(void *arg, uint64_t val)
1560 {
1561 	audiohd_ctrl_t	*pc = arg;
1562 	audiohd_state_t	*statep = pc->statep;
1563 	uint8_t		l, r;
1564 
1565 	if (val & ~0xffff)
1566 		return (EINVAL);
1567 
1568 	l = (val & 0xff00) >> 8;
1569 	r = (val & 0xff);
1570 	if ((l > 100) || (r > 100))
1571 		return (EINVAL);
1572 
1573 	mutex_enter(&statep->hda_mutex);
1574 	pc->val = val;
1575 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREY);
1576 	mutex_exit(&statep->hda_mutex);
1577 
1578 	return (0);
1579 }
1580 
1581 static int
1582 audiohd_set_lfe(void *arg, uint64_t val)
1583 {
1584 	audiohd_ctrl_t	*pc = arg;
1585 	audiohd_state_t	*statep = pc->statep;
1586 
1587 	val &= 0xff;
1588 
1589 	if (val > 100)
1590 		return (EINVAL);
1591 
1592 	mutex_enter(&statep->hda_mutex);
1593 	pc->val = val;
1594 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE);
1595 	mutex_exit(&statep->hda_mutex);
1596 
1597 	return (0);
1598 }
1599 static int
1600 audiohd_set_speaker(void *arg, uint64_t val)
1601 {
1602 	audiohd_ctrl_t	*pc = arg;
1603 	audiohd_state_t	*statep = pc->statep;
1604 	uint8_t		l, r;
1605 
1606 	if (val & ~0xffff)
1607 		return (EINVAL);
1608 
1609 	l = (val & 0xff00) >> 8;
1610 	r = (val & 0xff);
1611 	if ((l > 100) || (r > 100))
1612 		return (EINVAL);
1613 
1614 	mutex_enter(&statep->hda_mutex);
1615 	pc->val = val;
1616 	audiohd_set_pin_volume(statep, DTYPE_SPEAKER);
1617 	mutex_exit(&statep->hda_mutex);
1618 
1619 	return (0);
1620 }
1621 static int
1622 audiohd_set_front(void *arg, uint64_t val)
1623 {
1624 	audiohd_ctrl_t	*pc = arg;
1625 	audiohd_state_t	*statep = pc->statep;
1626 	uint8_t		l, r;
1627 
1628 	if (val & ~0xffff)
1629 		return (EINVAL);
1630 
1631 	l = (val & 0xff00) >> 8;
1632 	r = (val & 0xff);
1633 	if ((l > 100) || (r > 100))
1634 		return (EINVAL);
1635 
1636 	mutex_enter(&statep->hda_mutex);
1637 	pc->val = val;
1638 	audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREEN);
1639 	mutex_exit(&statep->hda_mutex);
1640 
1641 	return (0);
1642 }
1643 static int
1644 audiohd_set_headphone(void *arg, uint64_t val)
1645 {
1646 	audiohd_ctrl_t	*pc = arg;
1647 	audiohd_state_t	*statep = pc->statep;
1648 	uint8_t		l, r;
1649 
1650 	if (val & ~0xffff)
1651 		return (EINVAL);
1652 
1653 	l = (val & 0xff00) >> 8;
1654 	r = (val & 0xff);
1655 	if ((l > 100) || (r > 100))
1656 		return (EINVAL);
1657 
1658 	mutex_enter(&statep->hda_mutex);
1659 	pc->val = val;
1660 	audiohd_set_pin_volume(statep, DTYPE_HP_OUT);
1661 	mutex_exit(&statep->hda_mutex);
1662 
1663 	return (0);
1664 }
1665 static int
1666 audiohd_set_linein(void *arg, uint64_t val)
1667 {
1668 	audiohd_ctrl_t	*pc = arg;
1669 	audiohd_state_t	*statep = pc->statep;
1670 	uint8_t		l, r;
1671 
1672 	if (val & ~0xffff)
1673 		return (EINVAL);
1674 
1675 	l = (val & 0xff00) >> 8;
1676 	r = (val & 0xff);
1677 	if ((l > 100) || (r > 100))
1678 		return (EINVAL);
1679 
1680 	mutex_enter(&statep->hda_mutex);
1681 	pc->val = val;
1682 	audiohd_set_pin_volume(statep, DTYPE_LINE_IN);
1683 	mutex_exit(&statep->hda_mutex);
1684 
1685 	return (0);
1686 }
1687 
1688 static int
1689 audiohd_set_mic(void *arg, uint64_t val)
1690 {
1691 	audiohd_ctrl_t	*pc = arg;
1692 	audiohd_state_t	*statep = pc->statep;
1693 	uint8_t		l, r;
1694 
1695 	if (val & ~0xffff)
1696 		return (EINVAL);
1697 
1698 	l = (val & 0xff00) >> 8;
1699 	r = (val & 0xff);
1700 	if ((l > 100) || (r > 100))
1701 		return (EINVAL);
1702 
1703 	mutex_enter(&statep->hda_mutex);
1704 	pc->val = val;
1705 	audiohd_set_pin_volume(statep, DTYPE_MIC_IN);
1706 	mutex_exit(&statep->hda_mutex);
1707 
1708 	return (0);
1709 }
1710 
1711 static int
1712 audiohd_set_cd(void *arg, uint64_t val)
1713 {
1714 	audiohd_ctrl_t	*pc = arg;
1715 	audiohd_state_t	*statep = pc->statep;
1716 	uint8_t		l, r;
1717 
1718 	if (val & ~0xffff)
1719 		return (EINVAL);
1720 
1721 	l = (val & 0xff00) >> 8;
1722 	r = (val & 0xff);
1723 	if ((l > 100) || (r > 100))
1724 		return (EINVAL);
1725 
1726 	mutex_enter(&statep->hda_mutex);
1727 	pc->val = val;
1728 	audiohd_set_pin_volume(statep, DTYPE_CD);
1729 	mutex_exit(&statep->hda_mutex);
1730 
1731 	return (0);
1732 }
1733 
1734 static int
1735 audiohd_set_mongain(void *arg, uint64_t val)
1736 {
1737 	audiohd_ctrl_t	*pc = arg;
1738 	audiohd_state_t	*statep = pc->statep;
1739 	uint8_t		l, r;
1740 
1741 	if (val & ~0xffff)
1742 		return (EINVAL);
1743 
1744 	l = (val & 0xff00) >> 8;
1745 	r = (val & 0xff);
1746 	if ((l > 100) || (r > 100))
1747 		return (EINVAL);
1748 
1749 	mutex_enter(&statep->hda_mutex);
1750 	pc->val = val;
1751 	audiohd_configure_input(statep);
1752 	mutex_exit(&statep->hda_mutex);
1753 
1754 	return (0);
1755 }
1756 
1757 static int
1758 audiohd_set_beep(void *arg, uint64_t val)
1759 {
1760 	audiohd_ctrl_t  *pc = arg;
1761 	audiohd_state_t *statep = pc->statep;
1762 
1763 	val &= 0xff;
1764 
1765 	if (val > 100)
1766 		return (EINVAL);
1767 
1768 	mutex_enter(&statep->hda_mutex);
1769 	pc->val = val;
1770 	audiohd_set_beep_volume(statep);
1771 	mutex_exit(&statep->hda_mutex);
1772 
1773 	return (0);
1774 }
1775 
1776 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
1777 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
1778 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
1779 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
1780 #define	MONVOL	(MONCTL | AUDIO_CTRL_FLAG_MONVOL)
1781 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
1782 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
1783 #define	RWCTL	AUDIO_CTRL_FLAG_RW
1784 
1785 static audiohd_ctrl_t *
1786 audiohd_alloc_ctrl(audiohd_state_t *statep, uint32_t num, uint64_t val)
1787 {
1788 	audio_ctrl_desc_t	desc;
1789 	audio_ctrl_wr_t		fn;
1790 	audiohd_ctrl_t		*pc;
1791 
1792 	pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
1793 	pc->statep = statep;
1794 	pc->num = num;
1795 
1796 	bzero(&desc, sizeof (desc));
1797 
1798 	switch (num) {
1799 	case CTL_VOLUME:
1800 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
1801 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1802 		desc.acd_minvalue = 0;
1803 		desc.acd_maxvalue = 100;
1804 		desc.acd_flags = PCMVOL;
1805 		fn = audiohd_set_volume;
1806 		break;
1807 
1808 	case CTL_FRONT:
1809 		desc.acd_name = AUDIO_CTRL_ID_FRONT;
1810 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1811 		desc.acd_minvalue = 0;
1812 		desc.acd_maxvalue = 100;
1813 		desc.acd_flags = MAINVOL;
1814 		fn = audiohd_set_front;
1815 		break;
1816 
1817 	case CTL_SPEAKER:
1818 		desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
1819 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1820 		desc.acd_minvalue = 0;
1821 		desc.acd_maxvalue = 100;
1822 		desc.acd_flags = MAINVOL;
1823 		fn = audiohd_set_speaker;
1824 		break;
1825 
1826 	case CTL_HEADPHONE:
1827 		desc.acd_name = AUDIO_CTRL_ID_HEADPHONE;
1828 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1829 		desc.acd_minvalue = 0;
1830 		desc.acd_maxvalue = 100;
1831 		desc.acd_flags = MAINVOL;
1832 		fn = audiohd_set_headphone;
1833 		break;
1834 
1835 	case CTL_REAR:
1836 		desc.acd_name = AUDIO_CTRL_ID_REAR;
1837 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1838 		desc.acd_minvalue = 0;
1839 		desc.acd_maxvalue = 100;
1840 		desc.acd_flags = MAINVOL;
1841 		fn = audiohd_set_rear;
1842 		break;
1843 
1844 	case CTL_CENTER:
1845 		desc.acd_name = AUDIO_CTRL_ID_CENTER;
1846 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1847 		desc.acd_minvalue = 0;
1848 		desc.acd_maxvalue = 100;
1849 		desc.acd_flags = MAINVOL;
1850 		fn = audiohd_set_center;
1851 		break;
1852 
1853 	case CTL_SURROUND:
1854 		desc.acd_name = AUDIO_CTRL_ID_SURROUND;
1855 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1856 		desc.acd_minvalue = 0;
1857 		desc.acd_maxvalue = 100;
1858 		desc.acd_flags = MAINVOL;
1859 		fn = audiohd_set_surround;
1860 		break;
1861 
1862 	case CTL_LFE:
1863 		desc.acd_name = AUDIO_CTRL_ID_LFE;
1864 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1865 		desc.acd_minvalue = 0;
1866 		desc.acd_maxvalue = 100;
1867 		desc.acd_flags = MAINVOL;
1868 		fn = audiohd_set_lfe;
1869 		break;
1870 
1871 	case CTL_LINEIN:
1872 		desc.acd_name = AUDIO_CTRL_ID_LINEIN;
1873 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1874 		desc.acd_minvalue = 0;
1875 		desc.acd_maxvalue = 100;
1876 		desc.acd_flags = RECVOL;
1877 		fn = audiohd_set_linein;
1878 		break;
1879 
1880 	case CTL_MIC:
1881 		desc.acd_name = AUDIO_CTRL_ID_MIC;
1882 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1883 		desc.acd_minvalue = 0;
1884 		desc.acd_maxvalue = 100;
1885 		desc.acd_flags = RECVOL;
1886 		fn = audiohd_set_mic;
1887 		break;
1888 
1889 	case CTL_CD:
1890 		desc.acd_name = AUDIO_CTRL_ID_CD;
1891 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1892 		desc.acd_minvalue = 0;
1893 		desc.acd_maxvalue = 100;
1894 		desc.acd_flags = RECVOL;
1895 		fn = audiohd_set_cd;
1896 		break;
1897 
1898 	case CTL_MONGAIN:
1899 		desc.acd_name = AUDIO_CTRL_ID_MONGAIN;
1900 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1901 		desc.acd_minvalue = 0;
1902 		desc.acd_maxvalue = 100;
1903 		desc.acd_flags = MONVOL;
1904 		fn = audiohd_set_mongain;
1905 		break;
1906 
1907 	case CTL_RECSRC:
1908 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
1909 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1910 		desc.acd_minvalue = statep->inmask;
1911 		desc.acd_maxvalue = statep->inmask;
1912 		desc.acd_flags = RECCTL;
1913 		for (int i = 0; audiohd_dtypes[i]; i++) {
1914 			desc.acd_enum[i] = audiohd_dtypes[i];
1915 		}
1916 		fn = audiohd_set_recsrc;
1917 		break;
1918 
1919 	case CTL_BEEP:
1920 		desc.acd_name = AUDIO_CTRL_ID_BEEP;
1921 		desc.acd_type =	AUDIO_CTRL_TYPE_MONO;
1922 		desc.acd_minvalue = 0;
1923 		desc.acd_maxvalue = 100;
1924 		desc.acd_flags = RWCTL;
1925 		fn = audiohd_set_beep;
1926 		break;
1927 	}
1928 
1929 	pc->val = val;
1930 	pc->ctrl = audio_dev_add_control(statep->adev, &desc,
1931 	    audiohd_get_value, fn, pc);
1932 
1933 	return (pc);
1934 }
1935 
1936 static void
1937 audiohd_free_ctrl(audiohd_ctrl_t *pc)
1938 {
1939 	if (pc == NULL)
1940 		return;
1941 	if (pc->ctrl)
1942 		audio_dev_del_control(pc->ctrl);
1943 	kmem_free(pc, sizeof (*pc));
1944 }
1945 
1946 static void
1947 audiohd_del_controls(audiohd_state_t *statep)
1948 {
1949 	int		i;
1950 	for (i = 0; i < CTRL_NUM; i++) {
1951 		if (statep->controls[i])
1952 			audiohd_free_ctrl(statep->controls[i]);
1953 	}
1954 }
1955 
1956 static int
1957 audiohd_add_controls(audiohd_state_t *statep)
1958 {
1959 	int			i, j;
1960 	audiohd_path_t		*path;
1961 	wid_t			wid;
1962 	audiohd_pin_t		*pin;
1963 	audiohd_widget_t	*widget, *w;
1964 	hda_codec_t		*codec;
1965 	audiohd_pin_color_t	clr;
1966 
1967 #define	ADD_CTRL(ID, VAL)	\
1968 	if (statep->controls[ID] == NULL) \
1969 		statep->controls[ID] = audiohd_alloc_ctrl(statep, ID, VAL);\
1970 	if (statep->controls[ID] == NULL) {				\
1971 		audio_dev_warn(statep->adev,				\
1972 		    "Unable to allocate %s control", #ID);		\
1973 		return (DDI_FAILURE);					\
1974 	}
1975 
1976 	for (i = 0; i < statep->pathnum; i++) {
1977 		path = statep->path[i];
1978 		if (!path || path->path_type != PLAY)
1979 			continue;
1980 		/*
1981 		 * Firstly we check if all the DACs on the play paths
1982 		 * have amplifiers. If any of them doesn't have, we just use
1983 		 * the soft volume control to adjust the PCM volume.
1984 		 */
1985 		wid = path->adda_wid;
1986 		w = path->codec->widget[wid];
1987 		if (!w->outamp_cap) {
1988 			(void) audio_dev_add_soft_volume(statep->adev);
1989 			statep->soft_volume = B_TRUE;
1990 			break;
1991 		}
1992 	}
1993 	/*
1994 	 * if all the DACs on the play paths have the amplifiers, we use DACs'
1995 	 * amplifiers to adjust volume.
1996 	 */
1997 	if (!statep->soft_volume) {
1998 		ADD_CTRL(CTL_VOLUME, 0x4b);
1999 	}
2000 	/* allocate other controls */
2001 	for (i = 0; i < statep->pathnum; i++) {
2002 		path = statep->path[i];
2003 		if (!path)
2004 			continue;
2005 		codec = path->codec;
2006 		if (path->path_type == BEEP) {
2007 			widget = codec->widget[path->beep_wid];
2008 			if (widget->type == WTYPE_BEEP &&
2009 			    path->gain_wid != 0) {
2010 				ADD_CTRL(CTL_BEEP, 0x4b4b);
2011 				break;
2012 			}
2013 		}
2014 
2015 		for (j = 0; j < path->pin_nums; j++) {
2016 			wid = path->pin_wid[j];
2017 			widget = codec->widget[wid];
2018 			pin = (audiohd_pin_t *)widget->priv;
2019 			if (pin->device == DTYPE_SPEAKER) {
2020 				ADD_CTRL(CTL_SPEAKER, 0x4b4b);
2021 			} else if (pin->device == DTYPE_HP_OUT) {
2022 				ADD_CTRL(CTL_HEADPHONE, 0x4b4b);
2023 			} else if (pin->device == DTYPE_LINE_IN) {
2024 				ADD_CTRL(CTL_LINEIN, 0x3232);
2025 			} else if (pin->device == DTYPE_MIC_IN) {
2026 				ADD_CTRL(CTL_MIC, 0x3232);
2027 			} else if (pin->device == DTYPE_CD) {
2028 				ADD_CTRL(CTL_CD, 0x3232);
2029 			}
2030 			clr = (pin->config >> AUDIOHD_PIN_CLR_OFF) &
2031 			    AUDIOHD_PIN_CLR_MASK;
2032 			if (clr == AUDIOHD_PIN_GREEN) {
2033 				ADD_CTRL(CTL_FRONT, 0x4b4b);
2034 			} else if (clr == AUDIOHD_PIN_BLACK &&
2035 			    pin->device != DTYPE_HP_OUT &&
2036 			    pin->device != DTYPE_MIC_IN) {
2037 				ADD_CTRL(CTL_REAR, 0x4b4b);
2038 			} else if (clr == AUDIOHD_PIN_ORANGE) {
2039 				ADD_CTRL(CTL_CENTER, 0x4b);
2040 				ADD_CTRL(CTL_LFE, 0x4b);
2041 			} else if (clr == AUDIOHD_PIN_GREY) {
2042 				ADD_CTRL(CTL_SURROUND, 0x4b4b);
2043 			}
2044 		}
2045 	}
2046 
2047 	if (!statep->monitor_unsupported) {
2048 		ADD_CTRL(CTL_MONGAIN, 0);
2049 	}
2050 
2051 	ADD_CTRL(CTL_RECSRC, (1U << DTYPE_MIC_IN));
2052 
2053 	audiohd_configure_output(statep);
2054 	audiohd_configure_input(statep);
2055 
2056 	return (DDI_SUCCESS);
2057 }
2058 
2059 /*
2060  * quiesce(9E) entry point.
2061  *
2062  * This function is called when the system is single-threaded at high
2063  * PIL with preemption disabled. Therefore, this function must not be
2064  * blocked.
2065  *
2066  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
2067  * DDI_FAILURE indicates an error condition and should almost never happen.
2068  */
2069 static int
2070 audiohd_quiesce(dev_info_t *dip)
2071 {
2072 	audiohd_state_t		*statep;
2073 
2074 	statep = ddi_get_driver_private(dip);
2075 
2076 	audiohd_stop_dma(statep);
2077 	audiohd_disable_intr(statep);
2078 
2079 	return (DDI_SUCCESS);
2080 }
2081 
2082 static void
2083 audiohd_beep_on(void *arg)
2084 {
2085 	hda_codec_t *codec = ((audiohd_widget_t *)arg)->codec;
2086 	audiohd_state_t *statep = codec->soft_statep;
2087 	int caddr = codec->index;
2088 	wid_t wid = ((audiohd_widget_t *)arg)->wid_wid;
2089 
2090 	(void) audioha_codec_verb_get(statep, caddr, wid,
2091 	    AUDIOHDC_VERB_SET_BEEP_GEN, audiohd_beep_divider);
2092 }
2093 
2094 static void
2095 audiohd_beep_off(void *arg)
2096 {
2097 	hda_codec_t *codec = ((audiohd_widget_t *)arg)->codec;
2098 	audiohd_state_t *statep = codec->soft_statep;
2099 	int caddr = codec->index;
2100 	wid_t wid = ((audiohd_widget_t *)arg)->wid_wid;
2101 
2102 	(void) audioha_codec_verb_get(statep, caddr, wid,
2103 	    AUDIOHDC_VERB_SET_BEEP_GEN, AUDIOHDC_MUTE_BEEP_GEN);
2104 }
2105 
2106 static void
2107 audiohd_beep_freq(void *arg, int freq)
2108 {
2109 	_NOTE(ARGUNUSED(arg));
2110 	if (freq == 0) {
2111 		audiohd_beep_divider = 0;
2112 	} else {
2113 		if (freq > AUDIOHDC_MAX_BEEP_GEN)
2114 			freq = AUDIOHDC_MAX_BEEP_GEN;
2115 		else if (freq < AUDIOHDC_MIX_BEEP_GEN)
2116 			freq = AUDIOHDC_MIX_BEEP_GEN;
2117 		audiohd_beep_divider = AUDIOHDC_SAMPR48000 / freq;
2118 	}
2119 
2120 	if (audiohd_beep_vol == 0)
2121 		audiohd_beep_divider = 0;
2122 }
2123 
2124 /*
2125  * audiohd_init_state()
2126  *
2127  * Description
2128  *	This routine initailizes soft state of driver instance,
2129  *	also, it requests an interrupt cookie and initializes
2130  *	mutex for soft state.
2131  */
2132 /*ARGSUSED*/
2133 static int
2134 audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip)
2135 {
2136 	audio_dev_t			*adev;
2137 
2138 	statep->hda_dip = dip;
2139 
2140 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
2141 		cmn_err(CE_WARN, "unable to allocate audio dev");
2142 		return (DDI_FAILURE);
2143 	}
2144 	statep->adev = adev;
2145 	statep->intr_added = B_FALSE;
2146 
2147 	/* set device information */
2148 	audio_dev_set_description(adev, AUDIOHD_DEV_CONFIG);
2149 	audio_dev_set_version(adev, AUDIOHD_DEV_VERSION);
2150 
2151 	if (ddi_get_iblock_cookie(dip, (uint_t)0, &statep->hda_intr_cookie) !=
2152 	    DDI_SUCCESS) {
2153 		audio_dev_warn(statep->adev,
2154 		    "cannot get iblock cookie");
2155 		return (DDI_FAILURE);
2156 	}
2157 	mutex_init(&statep->hda_mutex, NULL,
2158 	    MUTEX_DRIVER, statep->hda_intr_cookie);
2159 
2160 	statep->hda_rirb_rp = 0;
2161 
2162 	return (DDI_SUCCESS);
2163 }	/* audiohd_init_state() */
2164 
2165 /*
2166  * audiohd_init_pci()
2167  *
2168  * Description
2169  *	enable driver to access PCI configure space and memory
2170  *	I/O space.
2171  */
2172 static int
2173 audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr)
2174 {
2175 	uint16_t	cmdreg;
2176 	uint16_t	vid;
2177 	uint8_t		cTmp;
2178 	dev_info_t	*dip = statep->hda_dip;
2179 	audio_dev_t	*ahandle = statep->adev;
2180 
2181 	if (pci_config_setup(dip, &statep->hda_pci_handle) == DDI_FAILURE) {
2182 		audio_dev_warn(ahandle,
2183 		    "pci config mapping failed");
2184 		return (DDI_FAILURE);
2185 	}
2186 
2187 	if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0,
2188 	    0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) {
2189 		audio_dev_warn(ahandle,
2190 		    "memory I/O mapping failed");
2191 		return (DDI_FAILURE);
2192 	}
2193 
2194 	/*
2195 	 * HD audio control uses memory I/O only, enable it here.
2196 	 */
2197 	cmdreg = pci_config_get16(statep->hda_pci_handle, PCI_CONF_COMM);
2198 	pci_config_put16(statep->hda_pci_handle, PCI_CONF_COMM,
2199 	    cmdreg | PCI_COMM_MAE | PCI_COMM_ME);
2200 
2201 	vid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID);
2202 	switch (vid) {
2203 
2204 	case AUDIOHD_VID_INTEL:
2205 		/*
2206 		 * Currently, Intel (G)MCH and ICHx chipsets support PCI
2207 		 * Express QoS. It implemenets two VCs(virtual channels)
2208 		 * and allows OS software to map 8 traffic classes to the
2209 		 * two VCs. Some BIOSes initialize HD audio hardware to
2210 		 * use TC7 (traffic class 7) and to map TC7 to VC1 as Intel
2211 		 * recommended. However, solaris doesn't support PCI express
2212 		 * QoS yet. As a result, this driver can not work for those
2213 		 * hardware without touching PCI express control registers.
2214 		 * Here, we set TCSEL to 0 so as to use TC0/VC0 (VC0 is
2215 		 * always enabled and TC0 is always mapped to VC0) for all
2216 		 * Intel HD audio controllers.
2217 		 */
2218 		cTmp = pci_config_get8(statep->hda_pci_handle,
2219 		    AUDIOHD_INTEL_PCI_TCSEL);
2220 		pci_config_put8(statep->hda_pci_handle,
2221 		    AUDIOHD_INTEL_PCI_TCSEL, (cTmp & AUDIOHD_INTEL_TCS_MASK));
2222 		break;
2223 
2224 	case AUDIOHD_VID_ATI:
2225 		/*
2226 		 * Refer to ATI SB450 datesheet. We set snoop for SB450
2227 		 * like hardware.
2228 		 */
2229 		cTmp = pci_config_get8(statep->hda_pci_handle,
2230 		    AUDIOHD_ATI_PCI_MISC2);
2231 		pci_config_put8(statep->hda_pci_handle, AUDIOHD_ATI_PCI_MISC2,
2232 		    (cTmp & AUDIOHD_ATI_MISC2_MASK) | AUDIOHD_ATI_MISC2_SNOOP);
2233 		break;
2234 		/*
2235 		 * Refer to the datasheet, we set snoop for NVIDIA
2236 		 * like hardware
2237 		 */
2238 	case AUDIOHD_VID_NVIDIA:
2239 		cTmp = pci_config_get8(statep->hda_pci_handle,
2240 		    AUDIOHD_CORB_SIZE_OFF);
2241 		pci_config_put8(statep->hda_pci_handle, AUDIOHD_CORB_SIZE_OFF,
2242 		    cTmp | AUDIOHD_NVIDIA_SNOOP);
2243 		break;
2244 
2245 	default:
2246 		break;
2247 	}
2248 
2249 	return (DDI_SUCCESS);
2250 }	/* audiohd_init_pci() */
2251 
2252 
2253 /*
2254  * audiohd_fini_pci()
2255  *
2256  * Description
2257  *	Release mapping for PCI configure space.
2258  */
2259 static void
2260 audiohd_fini_pci(audiohd_state_t *statep)
2261 {
2262 	if (statep->hda_reg_handle != NULL) {
2263 		ddi_regs_map_free(&statep->hda_reg_handle);
2264 		statep->hda_reg_handle = NULL;
2265 	}
2266 
2267 	if (statep->hda_pci_handle != NULL) {
2268 		pci_config_teardown(&statep->hda_pci_handle);
2269 		statep->hda_pci_handle = NULL;
2270 	}
2271 
2272 }	/* audiohd_fini_pci() */
2273 
2274 /*
2275  * audiohd_stop_dma()
2276  *
2277  * Description
2278  *	Stop all DMA behaviors of controllers, for command I/O
2279  *	and each audio stream.
2280  */
2281 static void
2282 audiohd_stop_dma(audiohd_state_t *statep)
2283 {
2284 	int	i;
2285 	uint_t	base;
2286 	uint8_t	bTmp;
2287 
2288 	AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, 0);
2289 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, 0);
2290 
2291 	base = AUDIOHD_REG_SD_BASE;
2292 	for (i = 0; i < statep->hda_streams_nums; i++) {
2293 		bTmp = AUDIOHD_REG_GET8(base + AUDIOHD_SDREG_OFFSET_CTL);
2294 
2295 		/* for input/output stream, it is the same */
2296 		bTmp &= ~AUDIOHDR_RIRBCTL_DMARUN;
2297 
2298 		AUDIOHD_REG_SET8(base + AUDIOHD_SDREG_OFFSET_CTL, bTmp);
2299 		base += AUDIOHD_REG_SD_LEN;
2300 	}
2301 
2302 	/* wait 40us for stream DMA to stop */
2303 	drv_usecwait(40);
2304 
2305 }	/* audiohd_stop_dma() */
2306 
2307 /*
2308  * audiohd_reset_controller()
2309  *
2310  * Description:
2311  *	This routine is just used to reset controller and
2312  *	CODEC as well by HW reset bit in global control
2313  *	register of HD controller.
2314  */
2315 static int
2316 audiohd_reset_controller(audiohd_state_t *statep)
2317 {
2318 	int		i;
2319 	uint16_t	sTmp;
2320 	uint32_t	gctl;
2321 
2322 	/* Reset Status register but preserve the first bit */
2323 	sTmp = AUDIOHD_REG_GET16(AUDIOHD_REG_STATESTS);
2324 	AUDIOHD_REG_SET16(AUDIOHD_REG_STATESTS, sTmp & 0x8000);
2325 
2326 	/* reset controller */
2327 	gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL);
2328 	gctl &= ~AUDIOHDR_GCTL_CRST;
2329 	AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, gctl);  /* entering reset state */
2330 	for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) {
2331 		/* Empirical testing time: 150 */
2332 		drv_usecwait(150);
2333 		gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL);
2334 		if ((gctl & AUDIOHDR_GCTL_CRST) == 0)
2335 			break;
2336 	}
2337 
2338 	if ((gctl & AUDIOHDR_GCTL_CRST) != 0) {
2339 		audio_dev_warn(statep->adev,
2340 		    "failed to enter reset state");
2341 		return (DDI_FAILURE);
2342 	}
2343 
2344 	/* Empirical testing time:300 */
2345 	drv_usecwait(300);
2346 
2347 	/* exit reset state */
2348 	AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, gctl | AUDIOHDR_GCTL_CRST);
2349 
2350 	for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) {
2351 		/* Empirical testing time: 150, which works well */
2352 		drv_usecwait(150);
2353 		gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL);
2354 		if (gctl & AUDIOHDR_GCTL_CRST)
2355 			break;
2356 	}
2357 
2358 	if ((gctl & AUDIOHDR_GCTL_CRST) == 0) {
2359 		audio_dev_warn(statep->adev,
2360 		    "failed to exit reset state");
2361 		return (DDI_FAILURE);
2362 	}
2363 
2364 	/* HD spec requires to wait 250us at least. we use 500us */
2365 	drv_usecwait(500);
2366 
2367 	/* enable unsolicited response */
2368 	AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL,
2369 	    gctl |  AUDIOHDR_GCTL_URESPE);
2370 
2371 	return (DDI_SUCCESS);
2372 
2373 }	/* audiohd_reset_controller() */
2374 
2375 /*
2376  * audiohd_alloc_dma_mem()
2377  *
2378  * Description:
2379  *	This is an utility routine. It is used to allocate DMA
2380  *	memory.
2381  */
2382 static int
2383 audiohd_alloc_dma_mem(audiohd_state_t *statep, audiohd_dma_t *pdma,
2384     size_t memsize, ddi_dma_attr_t *dma_attr_p, uint_t dma_flags)
2385 {
2386 	ddi_dma_cookie_t	cookie;
2387 	uint_t			count;
2388 	dev_info_t		*dip = statep->hda_dip;
2389 	audio_dev_t		*ahandle = statep->adev;
2390 
2391 	if (ddi_dma_alloc_handle(dip, dma_attr_p, DDI_DMA_SLEEP,
2392 	    NULL, &pdma->ad_dmahdl) != DDI_SUCCESS) {
2393 		audio_dev_warn(ahandle,
2394 		    "ddi_dma_alloc_handle failed");
2395 		return (DDI_FAILURE);
2396 	}
2397 
2398 	if (ddi_dma_mem_alloc(pdma->ad_dmahdl, memsize, &hda_dev_accattr,
2399 	    dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING),
2400 	    DDI_DMA_SLEEP, NULL,
2401 	    (caddr_t *)&pdma->ad_vaddr, &pdma->ad_real_sz,
2402 	    &pdma->ad_acchdl) != DDI_SUCCESS) {
2403 		audio_dev_warn(ahandle,
2404 		    "ddi_dma_mem_alloc failed");
2405 		return (DDI_FAILURE);
2406 	}
2407 
2408 	if (ddi_dma_addr_bind_handle(pdma->ad_dmahdl, NULL,
2409 	    (caddr_t)pdma->ad_vaddr, pdma->ad_real_sz, dma_flags,
2410 	    DDI_DMA_SLEEP, NULL, &cookie, &count) != DDI_DMA_MAPPED) {
2411 		audio_dev_warn(ahandle,
2412 		    "ddi_dma_addr_bind_handle failed");
2413 		return (DDI_FAILURE);
2414 	}
2415 
2416 	pdma->ad_paddr = (uint64_t)(cookie.dmac_laddress);
2417 	pdma->ad_req_sz = memsize;
2418 
2419 	return (DDI_SUCCESS);
2420 }	/* audiohd_alloc_dma_mem() */
2421 
2422 /*
2423  * audiohd_release_dma_mem()
2424  *
2425  * Description:
2426  *	Release DMA memory.
2427  */
2428 
2429 static void
2430 audiohd_release_dma_mem(audiohd_dma_t *pdma)
2431 {
2432 	if (pdma->ad_dmahdl != NULL) {
2433 		(void) ddi_dma_unbind_handle(pdma->ad_dmahdl);
2434 	}
2435 
2436 	if (pdma->ad_acchdl != NULL) {
2437 		ddi_dma_mem_free(&pdma->ad_acchdl);
2438 		pdma->ad_acchdl = NULL;
2439 	}
2440 
2441 	if (pdma->ad_dmahdl != NULL) {
2442 		ddi_dma_free_handle(&pdma->ad_dmahdl);
2443 		pdma->ad_dmahdl = NULL;
2444 	}
2445 
2446 }	/* audiohd_release_dma_mem() */
2447 
2448 /*
2449  * audiohd_reinit_hda()
2450  *
2451  * Description:
2452  *	This routine is used to re-initialize HD controller and codec.
2453  */
2454 static int
2455 audiohd_reinit_hda(audiohd_state_t *statep)
2456 {
2457 	uint64_t	addr;
2458 
2459 	/* set PCI configure space in case it's not restored OK */
2460 	(void) audiohd_init_pci(statep, &hda_dev_accattr);
2461 
2462 	/* reset controller */
2463 	if (audiohd_reset_controller(statep) != DDI_SUCCESS)
2464 		return (DDI_FAILURE);
2465 	AUDIOHD_REG_SET32(AUDIOHD_REG_SYNC, 0); /* needn't sync stream */
2466 
2467 	/* Initialize controller RIRB */
2468 	addr = statep->hda_dma_rirb.ad_paddr;
2469 	AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBLBASE, (uint32_t)addr);
2470 	AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE,
2471 	    (uint32_t)(addr >> 32));
2472 	AUDIOHD_REG_SET16(AUDIOHD_REG_RIRBWP, AUDIOHDR_RIRBWP_RESET);
2473 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSIZE, AUDIOHDR_RIRBSZ_256);
2474 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, AUDIOHDR_RIRBCTL_DMARUN |
2475 	    AUDIOHDR_RIRBCTL_RINTCTL);
2476 
2477 	/* Initialize controller CORB */
2478 	addr = statep->hda_dma_corb.ad_paddr;
2479 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, AUDIOHDR_CORBRP_RESET);
2480 	AUDIOHD_REG_SET32(AUDIOHD_REG_CORBLBASE, (uint32_t)addr);
2481 	AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE,
2482 	    (uint32_t)(addr >> 32));
2483 	AUDIOHD_REG_SET8(AUDIOHD_REG_CORBSIZE, AUDIOHDR_CORBSZ_256);
2484 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, 0);
2485 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0);
2486 	AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, AUDIOHDR_CORBCTL_DMARUN);
2487 
2488 	audiohd_restore_codec_gpio(statep);
2489 	audiohd_restore_path(statep);
2490 	audiohd_init_path(statep);
2491 
2492 	return (DDI_SUCCESS);
2493 }	/* audiohd_reinit_hda */
2494 
2495 /*
2496  * audiohd_init_controller()
2497  *
2498  * Description:
2499  *	This routine is used to initialize HD controller. It
2500  *	allocates DMA memory for CORB/RIRB, buffer descriptor
2501  *	list and cylic data buffer for both play and record
2502  *	stream.
2503  */
2504 static int
2505 audiohd_init_controller(audiohd_state_t *statep)
2506 {
2507 	uint64_t	addr;
2508 	uint16_t	gcap;
2509 	int		retval;
2510 
2511 	ddi_dma_attr_t	dma_attr = {
2512 		DMA_ATTR_V0,		/* version */
2513 		0,			/* addr_lo */
2514 		0xffffffffffffffffULL,	/* addr_hi */
2515 		0x00000000ffffffffULL,	/* count_max */
2516 		128,			/* 128-byte alignment as HD spec */
2517 		0xfff,			/* burstsize */
2518 		1,			/* minxfer */
2519 		0xffffffff,		/* maxxfer */
2520 		0xffffffff,		/* seg */
2521 		1,			/* sgllen */
2522 		1,			/* granular */
2523 		0			/* flags */
2524 	};
2525 
2526 	gcap = AUDIOHD_REG_GET16(AUDIOHD_REG_GCAP);
2527 
2528 	/*
2529 	 * If the device doesn't support 64-bit DMA, we should not
2530 	 * allocate DMA memory from 4G above
2531 	 */
2532 	if ((gcap & AUDIOHDR_GCAP_64OK) == 0)
2533 		dma_attr.dma_attr_addr_hi = 0xffffffffUL;
2534 
2535 	statep->hda_input_streams = (gcap & AUDIOHDR_GCAP_INSTREAMS) >>
2536 	    AUDIOHD_INSTR_NUM_OFF;
2537 	statep->hda_output_streams = (gcap & AUDIOHDR_GCAP_OUTSTREAMS) >>
2538 	    AUDIOHD_OUTSTR_NUM_OFF;
2539 	statep->hda_streams_nums = statep->hda_input_streams +
2540 	    statep->hda_output_streams;
2541 
2542 
2543 	statep->hda_record_regbase = AUDIOHD_REG_SD_BASE;
2544 	statep->hda_play_regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN *
2545 	    statep->hda_input_streams;
2546 
2547 
2548 	/* stop all dma before starting to reset controller */
2549 	audiohd_stop_dma(statep);
2550 
2551 	if (audiohd_reset_controller(statep) != DDI_SUCCESS)
2552 		return (DDI_FAILURE);
2553 
2554 	/* check codec */
2555 	statep->hda_codec_mask = AUDIOHD_REG_GET16(AUDIOHD_REG_STATESTS);
2556 	if (!statep->hda_codec_mask) {
2557 		audio_dev_warn(statep->adev,
2558 		    "no codec exists");
2559 		return (DDI_FAILURE);
2560 	}
2561 
2562 	/* allocate DMA for CORB */
2563 	retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_corb,
2564 	    AUDIOHD_CDBIO_CORB_LEN, &dma_attr,
2565 	    DDI_DMA_WRITE | DDI_DMA_STREAMING);
2566 	if (retval != DDI_SUCCESS) {
2567 		audio_dev_warn(statep->adev,
2568 		    "failed to alloc DMA for CORB");
2569 		return (DDI_FAILURE);
2570 	}
2571 
2572 	/* allocate DMA for RIRB */
2573 	retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_rirb,
2574 	    AUDIOHD_CDBIO_RIRB_LEN, &dma_attr,
2575 	    DDI_DMA_READ | DDI_DMA_STREAMING);
2576 	if (retval != DDI_SUCCESS) {
2577 		audio_dev_warn(statep->adev,
2578 		    "failed to alloc DMA for RIRB");
2579 		return (DDI_FAILURE);
2580 	}
2581 
2582 
2583 	AUDIOHD_REG_SET32(AUDIOHD_REG_SYNC, 0); /* needn't sync stream */
2584 
2585 	/* Initialize RIRB */
2586 	addr = statep->hda_dma_rirb.ad_paddr;
2587 	AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBLBASE, (uint32_t)addr);
2588 	AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE,
2589 	    (uint32_t)(addr >> 32));
2590 	AUDIOHD_REG_SET16(AUDIOHD_REG_RIRBWP, AUDIOHDR_RIRBWP_RESET);
2591 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSIZE, AUDIOHDR_RIRBSZ_256);
2592 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, AUDIOHDR_RIRBCTL_DMARUN |
2593 	    AUDIOHDR_RIRBCTL_RINTCTL);
2594 
2595 	/* initialize CORB */
2596 	addr = statep->hda_dma_corb.ad_paddr;
2597 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, AUDIOHDR_CORBRP_RESET);
2598 	AUDIOHD_REG_SET32(AUDIOHD_REG_CORBLBASE, (uint32_t)addr);
2599 	AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE,
2600 	    (uint32_t)(addr >> 32));
2601 	AUDIOHD_REG_SET8(AUDIOHD_REG_CORBSIZE, AUDIOHDR_CORBSZ_256);
2602 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, 0);
2603 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0);
2604 	AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, AUDIOHDR_CORBCTL_DMARUN);
2605 
2606 	return (DDI_SUCCESS);
2607 }	/* audiohd_init_controller() */
2608 
2609 /*
2610  * audiohd_fini_controller()
2611  *
2612  * Description:
2613  *	Releases DMA memory allocated in audiohd_init_controller()
2614  */
2615 static void
2616 audiohd_fini_controller(audiohd_state_t *statep)
2617 {
2618 	audiohd_stop_dma(statep);
2619 	audiohd_release_dma_mem(&statep->hda_dma_rirb);
2620 	audiohd_release_dma_mem(&statep->hda_dma_corb);
2621 
2622 }	/* audiohd_fini_controller() */
2623 
2624 /*
2625  * audiohd_get_conns_from_entry()
2626  *
2627  * Description:
2628  *	Get connection list from every entry for a widget
2629  */
2630 static void
2631 audiohd_get_conns_from_entry(hda_codec_t *codec, audiohd_widget_t *widget,
2632     uint32_t entry, audiohd_entry_prop_t *prop)
2633 {
2634 	int	i, k, num;
2635 	wid_t	input_wid;
2636 
2637 	for (i = 0; i < prop->conns_per_entry &&
2638 	    widget->nconns < prop->conn_len;
2639 	    i++, entry >>= prop->bits_per_conn) {
2640 		ASSERT(widget->nconns < AUDIOHD_MAX_CONN);
2641 		input_wid = entry & prop->mask_wid;
2642 		if (entry & prop->mask_range) {
2643 			if (widget->nconns == 0) {
2644 				if (input_wid < codec->first_wid ||
2645 				    (input_wid > codec->last_wid)) {
2646 					break;
2647 				}
2648 				widget->avail_conn[widget->nconns++] =
2649 				    input_wid;
2650 			} else {
2651 				for (k = widget->avail_conn[widget->nconns-1] +
2652 				    1; k <= input_wid; k++) {
2653 					ASSERT(widget->nconns <
2654 					    AUDIOHD_MAX_CONN);
2655 					if (k < codec->first_wid ||
2656 					    (k > codec->last_wid)) {
2657 						break;
2658 					} else {
2659 						num = widget->nconns;
2660 						widget->avail_conn[num] = k;
2661 						widget->nconns++;
2662 					}
2663 				}
2664 			}
2665 		} else {
2666 			if ((codec->first_wid <= input_wid) && (input_wid <=
2667 			    codec->last_wid))
2668 				widget->avail_conn[widget->nconns++] =
2669 				    input_wid;
2670 		}
2671 	}
2672 }
2673 
2674 /*
2675  * audiohd_get_conns()
2676  *
2677  * Description:
2678  *	Get all connection list for a widget. The connection list is used for
2679  *	build output path, input path, and monitor path
2680  */
2681 static void
2682 audiohd_get_conns(hda_codec_t *codec, wid_t wid)
2683 {
2684 	audiohd_state_t		*statep = codec->soft_statep;
2685 	audiohd_widget_t	*widget = codec->widget[wid];
2686 	uint8_t	caddr = codec->index;
2687 	uint32_t	entry;
2688 	audiohd_entry_prop_t	prop;
2689 	wid_t	input_wid;
2690 	int	i;
2691 
2692 	prop.conn_len = audioha_codec_verb_get(statep, caddr, wid,
2693 	    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_CONNLIST_LEN);
2694 
2695 	if (prop.conn_len & AUDIOHD_FORM_MASK) {
2696 		prop.conns_per_entry = 2;
2697 		prop.bits_per_conn = 16;
2698 		prop.mask_range = 0x00008000;
2699 		prop.mask_wid = 0x00007fff;
2700 	} else {
2701 		prop.conns_per_entry = 4;
2702 		prop.bits_per_conn = 8;
2703 		prop.mask_range = 0x00000080;
2704 		prop.mask_wid = 0x0000007f;
2705 	}
2706 	prop.conn_len &= AUDIOHD_LEN_MASK;
2707 
2708 	/*
2709 	 * This should not happen since the ConnectionList bit of
2710 	 * widget capabilities already told us that this widget
2711 	 * has a connection list
2712 	 */
2713 	if (prop.conn_len == 0) {
2714 		widget->nconns = 0;
2715 		cmn_err(CE_WARN, "node %d has 0 connections\n", wid);
2716 		return;
2717 	}
2718 
2719 	if (prop.conn_len == 1) {
2720 		entry = audioha_codec_verb_get(statep, caddr,
2721 		    wid, AUDIOHDC_VERB_GET_CONN_LIST_ENT, 0);
2722 		input_wid = entry & prop.mask_wid;
2723 		if ((input_wid < codec->first_wid) ||
2724 		    (input_wid > codec->last_wid)) {
2725 			return;
2726 		}
2727 		widget->avail_conn[0] = input_wid;
2728 		widget->nconns = 1;
2729 		return;
2730 	}
2731 	widget->nconns = 0;
2732 	for (i = 0; i < prop.conn_len; i += prop.conns_per_entry) {
2733 		entry = audioha_codec_verb_get(statep, caddr, wid,
2734 		    AUDIOHDC_VERB_GET_CONN_LIST_ENT, i);
2735 		audiohd_get_conns_from_entry(codec, widget, entry, &prop);
2736 	}
2737 }
2738 
2739 /*
2740  * Read PinCapabilities & default configuration
2741  */
2742 static void
2743 audiohd_get_pin_config(audiohd_widget_t *widget)
2744 {
2745 	hda_codec_t		*codec = widget->codec;
2746 	audiohd_state_t		*statep = codec->soft_statep;
2747 	audiohd_pin_t		*pin, *prev, *p;
2748 
2749 	int		caddr = codec->index;
2750 	wid_t		wid = widget->wid_wid;
2751 	uint32_t	cap, config, pinctrl;
2752 	uint8_t		urctrl, vrefbits;
2753 
2754 	cap = audioha_codec_verb_get(statep, caddr, wid,
2755 	    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PIN_CAP);
2756 	config = audioha_codec_verb_get(statep, caddr,
2757 	    wid, AUDIOHDC_VERB_GET_DEFAULT_CONF, 0);
2758 	pinctrl = audioha_codec_verb_get(statep, caddr,
2759 	    wid, AUDIOHDC_VERB_GET_PIN_CTRL, 0);
2760 
2761 	pin = (audiohd_pin_t *)kmem_zalloc(sizeof (audiohd_pin_t), KM_SLEEP);
2762 	widget->priv = pin;
2763 
2764 	/*
2765 	 * If the pin has no physical connection for port,
2766 	 * we won't link it to pin linkage list ???
2767 	 */
2768 	if (((config >> AUDIOHD_PIN_CON_STEP) & AUDIOHD_PIN_CON_MASK) == 0x1) {
2769 		pin->no_phys_conn = 1;
2770 	}
2771 
2772 	/* bit 4:3 are reserved, read-modify-write is needed */
2773 	pin->ctrl = pinctrl & AUDIOHD_PIN_IO_MASK;
2774 	pin->wid = wid;
2775 	pin->cap = cap;
2776 	pin->config = config;
2777 	pin->num = 0;
2778 	pin->finish = 0;
2779 
2780 	vrefbits = (cap >> AUDIOHD_PIN_VREF_OFF) & AUDIOHD_PIN_VREF_MASK;
2781 	if (vrefbits & AUDIOHD_PIN_VREF_L1)
2782 		pin->vrefvalue = 0x5;
2783 	else if (vrefbits & AUDIOHD_PIN_VREF_L2)
2784 		pin->vrefvalue = 0x4;
2785 	else if (vrefbits & AUDIOHD_PIN_VREF_L3)
2786 		pin->vrefvalue = 0x2;
2787 	else
2788 		pin->vrefvalue = 0x1;
2789 
2790 	pin->seq = config & AUDIOHD_PIN_SEQ_MASK;
2791 	pin->assoc = (config & AUDIOHD_PIN_ASO_MASK) >> AUDIOHD_PIN_ASO_OFF;
2792 	pin->device = (config & AUDIOHD_PIN_DEV_MASK) >> AUDIOHD_PIN_DEV_OFF;
2793 
2794 	/* enable the unsolicited response of the pin */
2795 	if ((widget->widget_cap & AUDIOHD_URCAP_MASK) &&
2796 	    (pin->cap & AUDIOHD_DTCCAP_MASK) &&
2797 	    ((pin->device == DTYPE_LINEOUT) ||
2798 	    (pin->device == DTYPE_SPDIF_OUT) ||
2799 	    (pin->device == DTYPE_HP_OUT) ||
2800 	    (pin->device == DTYPE_MIC_IN))) {
2801 			urctrl = (uint8_t)(1 << (AUDIOHD_UR_ENABLE_OFF - 1));
2802 			urctrl |= (wid & AUDIOHD_UR_TAG_MASK);
2803 			(void) audioha_codec_verb_get(statep, caddr,
2804 			    wid, AUDIOHDC_VERB_SET_URCTRL, urctrl);
2805 	}
2806 	/* accommodate all the pins in a link list sorted by assoc and seq */
2807 	if (codec->first_pin == NULL) {
2808 		codec->first_pin = pin;
2809 	} else {
2810 		prev = NULL;
2811 		p = codec->first_pin;
2812 		while (p) {
2813 			if (p->assoc > pin->assoc)
2814 				break;
2815 			if ((p->assoc == pin->assoc) &&
2816 			    (p->seq > pin->seq))
2817 				break;
2818 			prev = p;
2819 			p = p->next;
2820 		}
2821 		if (prev) {
2822 			pin->next = prev->next;
2823 			prev->next = pin;
2824 		} else {
2825 			pin->next = codec->first_pin;
2826 			codec->first_pin = pin;
2827 		}
2828 	}
2829 
2830 }	/* audiohd_get_pin_config() */
2831 
2832 /*
2833  * audiohd_create_widgets()
2834  *
2835  * Description:
2836  *	All widgets are created and stored in an array of codec
2837  */
2838 static int
2839 audiohd_create_widgets(hda_codec_t *codec)
2840 {
2841 	audiohd_widget_t	*widget;
2842 	audiohd_state_t		*statep = codec->soft_statep;
2843 	wid_t	wid;
2844 	uint32_t	type, widcap;
2845 	int		caddr = codec->index;
2846 
2847 	for (wid = codec->first_wid;
2848 	    wid <= codec->last_wid; wid++) {
2849 		widget = (audiohd_widget_t *)
2850 		    kmem_zalloc(sizeof (audiohd_widget_t), KM_SLEEP);
2851 		codec->widget[wid] = widget;
2852 		widget->codec = codec;
2853 		widget->selconn = AUDIOHD_NULL_CONN;
2854 
2855 		widcap = audioha_codec_verb_get(statep, caddr, wid,
2856 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_AUDIO_WID_CAP);
2857 		type = AUDIOHD_WIDCAP_TO_WIDTYPE(widcap);
2858 		widget->wid_wid = wid;
2859 		widget->type = type;
2860 		widget->widget_cap = widcap;
2861 		widget->finish = 0;
2862 		widget->used = 0;
2863 
2864 		/* if there's connection list */
2865 		if (widcap & AUDIOHD_WIDCAP_CONNLIST) {
2866 			audiohd_get_conns(codec, wid);
2867 		}
2868 
2869 		/* if power control, power it up to D0 state */
2870 		if (widcap & AUDIOHD_WIDCAP_PWRCTRL) {
2871 			(void) audioha_codec_verb_get(statep, caddr, wid,
2872 			    AUDIOHDC_VERB_SET_POWER_STATE, 0);
2873 		}
2874 
2875 		/*
2876 		 * if this widget has format override, we read it.
2877 		 * Otherwise, it uses the format of audio function.
2878 		 */
2879 		if (widcap & AUDIOHD_WIDCAP_FMT_OVRIDE) {
2880 			widget->pcm_format =
2881 			    audioha_codec_verb_get(statep, caddr, wid,
2882 			    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PCM);
2883 		} else {
2884 			widget->pcm_format = codec->pcm_format;
2885 		}
2886 
2887 		/*
2888 		 * Input amplifier. Has the widget input amplifier ?
2889 		 */
2890 		if (widcap & AUDIOHD_WIDCAP_INAMP) {
2891 			/*
2892 			 * if overrided bit is 0, use the default
2893 			 * amplifier of audio function as HD spec.
2894 			 * Otherwise, we read it.
2895 			 */
2896 			if ((widcap & AUDIOHD_WIDCAP_AMP_OVRIDE) == 0)
2897 				widget->inamp_cap = codec->inamp_cap;
2898 			else
2899 				widget->inamp_cap =
2900 				    audioha_codec_verb_get(statep, caddr, wid,
2901 				    AUDIOHDC_VERB_GET_PARAM,
2902 				    AUDIOHDC_PAR_INAMP_CAP);
2903 		} else {
2904 			widget->inamp_cap = 0;
2905 		}
2906 
2907 		/*
2908 		 * output amplifier. Has this widget output amplifier ?
2909 		 */
2910 		if (widcap & AUDIOHD_WIDCAP_OUTAMP) {
2911 			if ((widcap & AUDIOHD_WIDCAP_AMP_OVRIDE) == 0)
2912 				widget->outamp_cap = codec->outamp_cap;
2913 			else
2914 				widget->outamp_cap =
2915 				    audioha_codec_verb_get(statep, caddr, wid,
2916 				    AUDIOHDC_VERB_GET_PARAM,
2917 				    AUDIOHDC_PAR_OUTAMP_CAP);
2918 		} else {
2919 			widget->outamp_cap = 0;
2920 		}
2921 
2922 		switch (type) {
2923 		case WTYPE_AUDIO_OUT:
2924 		case WTYPE_AUDIO_IN:
2925 		case WTYPE_AUDIO_MIX:
2926 		case WTYPE_AUDIO_SEL:
2927 		case WTYPE_VENDOR:
2928 		case WTYPE_POWER:
2929 		case WTYPE_VOL_KNOB:
2930 			break;
2931 		case WTYPE_PIN:
2932 			audiohd_get_pin_config(widget);
2933 			break;
2934 		case WTYPE_BEEP:
2935 			/*
2936 			 * Get the audiohd_beep_switch value from audiohd.conf,
2937 			 * which is for turning on/off widget beep.
2938 			 */
2939 			audiohd_beep = ddi_prop_get_int(DDI_DEV_T_ANY,
2940 			    statep->hda_dip,
2941 			    DDI_PROP_DONTPASS, "audiohd_beep", 1);
2942 
2943 			if (audiohd_beep) {
2944 				(void) beep_fini();
2945 				(void) beep_init((void *) widget,
2946 				    audiohd_beep_on,
2947 				    audiohd_beep_off,
2948 				    audiohd_beep_freq);
2949 			}
2950 			break;
2951 		default:
2952 			break;
2953 		}
2954 	}
2955 
2956 	return (DDI_SUCCESS);
2957 
2958 }	/* audiohd_create_widgets() */
2959 
2960 /*
2961  * audiohd_destroy_widgets()
2962  */
2963 static void
2964 audiohd_destroy_widgets(hda_codec_t *codec)
2965 {
2966 	for (int i = 0; i < AUDIOHD_MAX_WIDGET; i++) {
2967 		if (codec->widget[i]) {
2968 			kmem_free(codec->widget[i], sizeof (audiohd_widget_t));
2969 			codec->widget[i] = NULL;
2970 		}
2971 	}
2972 
2973 }	/* audiohd_destroy_widgets() */
2974 
2975 static void
2976 audiohd_set_codec_info(hda_codec_t *codec)
2977 {
2978 	char buf[256];
2979 
2980 	switch (codec->vid) {
2981 	case 0x10ec0260:
2982 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC260");
2983 		break;
2984 	case 0x10ec0262:
2985 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC262");
2986 		break;
2987 	case 0x10ec0268:
2988 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC268");
2989 		break;
2990 	case 0x10ec0662:
2991 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC662");
2992 		break;
2993 	case 0x10ec861:
2994 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC861");
2995 		break;
2996 	case 0x10ec0862:
2997 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC862");
2998 		break;
2999 	case 0x10ec0880:
3000 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC880");
3001 		break;
3002 	case 0x10ec0882:
3003 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC882");
3004 		break;
3005 	case 0x10ec0883:
3006 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC883");
3007 		break;
3008 	case 0x10ec0885:
3009 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC885");
3010 		break;
3011 	case 0x10ec0888:
3012 		(void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC888");
3013 		break;
3014 	case 0x13f69880:
3015 		(void) snprintf(buf, sizeof (buf), "CMedia HD codec: CMI19880");
3016 		break;
3017 	case 0x434d4980:
3018 		(void) snprintf(buf, sizeof (buf), "CMedia HD codec: CMI19880");
3019 		break;
3020 	case 0x11d41981:
3021 		(void) snprintf(buf, sizeof (buf),
3022 		    "Analog Devices HD codec: AD1981");
3023 		break;
3024 	case 0x11d41983:
3025 		(void) snprintf(buf, sizeof (buf),
3026 		    "Analog Devices HD codec: AD1983");
3027 		break;
3028 	case 0x11d41984:
3029 		(void) snprintf(buf, sizeof (buf),
3030 		    "Analog Devices HD codec: AD1984");
3031 		break;
3032 	case 0x11d41986:
3033 		(void) snprintf(buf, sizeof (buf),
3034 		    "Analog Devices HD codec: AD1986A");
3035 		break;
3036 	case 0x11d41988:
3037 		(void) snprintf(buf, sizeof (buf),
3038 		    "Analog Devices HD codec: AD1988A");
3039 		break;
3040 	case 0x11d4198b:
3041 		(void) snprintf(buf, sizeof (buf),
3042 		    "Analog Devices HD codec: AD1988B");
3043 		break;
3044 	case 0x83847690:
3045 		(void) snprintf(buf, sizeof (buf),
3046 		    "Sigmatel HD codec: STAC9200");
3047 		break;
3048 	case 0x838476a0:
3049 		(void) snprintf(buf, sizeof (buf),
3050 		    "Sigmatel HD codec: STAC9205");
3051 		break;
3052 	case 0x838476a1:
3053 		(void) snprintf(buf, sizeof (buf),
3054 		    "Sigmatel HD codec: STAC9205D");
3055 		break;
3056 	case 0x838476a2:
3057 		(void) snprintf(buf, sizeof (buf),
3058 		    "Sigmatel HD codec: STAC9204");
3059 		break;
3060 	case 0x838476a3:
3061 		(void) snprintf(buf, sizeof (buf),
3062 		    "Sigmatel HD codec: STAC9204D");
3063 		break;
3064 	case 0x83847880:
3065 		(void) snprintf(buf, sizeof (buf),
3066 		    "Sigmatel HD codec: STAC9220 A1");
3067 		break;
3068 	case 0x83847882:
3069 		(void) snprintf(buf, sizeof (buf),
3070 		    "Sigmatel HD codec: STAC9220 A2");
3071 		break;
3072 	case 0x83847680:
3073 		(void) snprintf(buf, sizeof (buf),
3074 		    "Sigmatel HD codec: STAC9221 A1");
3075 		break;
3076 	case 0x83847681:
3077 		(void) snprintf(buf, sizeof (buf),
3078 		    "Sigmatel HD codec: STAC9220 D");
3079 		break;
3080 	case 0x83847682:
3081 		(void) snprintf(buf, sizeof (buf),
3082 		    "Sigmatel HD codec: STAC9221");
3083 		break;
3084 	case 0x83847683:
3085 		(void) snprintf(buf, sizeof (buf),
3086 		    "Sigmatel HD codec: STAC9221D");
3087 		break;
3088 	case 0x83847610:
3089 		(void) snprintf(buf, sizeof (buf),
3090 		    "Sigmatel HD codec: STAC9230XN");
3091 		break;
3092 	case 0x83847611:
3093 		(void) snprintf(buf, sizeof (buf),
3094 		    "Sigmatel HD codec: STAC9230DN");
3095 		break;
3096 	case 0x83847612:
3097 		(void) snprintf(buf, sizeof (buf),
3098 		    "Sigmatel HD codec: STAC9230XT");
3099 		break;
3100 	case 0x83847613:
3101 		(void) snprintf(buf, sizeof (buf),
3102 		    "Sigmatel HD codec: STAC9230DT");
3103 		break;
3104 	case 0x83847614:
3105 		(void) snprintf(buf, sizeof (buf),
3106 		    "Sigmatel HD codec: STAC9229X");
3107 		break;
3108 	case 0x83847615:
3109 		(void) snprintf(buf, sizeof (buf),
3110 		    "Sigmatel HD codec: STAC9229D");
3111 		break;
3112 	case 0x83847616:
3113 		(void) snprintf(buf, sizeof (buf),
3114 		    "Sigmatel HD codec: STAC9228X");
3115 		break;
3116 	case 0x83847617:
3117 		(void) snprintf(buf, sizeof (buf),
3118 		    "Sigmatel HD codec: STAC9228D");
3119 		break;
3120 	case 0x83847618:
3121 		(void) snprintf(buf, sizeof (buf),
3122 		    "Sigmatel HD codec: STAC9227X");
3123 		break;
3124 	case 0x83847619:
3125 		(void) snprintf(buf, sizeof (buf),
3126 		    "Sigmatel HD codec: STAC9227D");
3127 		break;
3128 	case 0x838476a4:
3129 		(void) snprintf(buf, sizeof (buf),
3130 		    "Sigmatel HD codec: STAC9255");
3131 		break;
3132 	case 0x838476a5:
3133 		(void) snprintf(buf, sizeof (buf),
3134 		    "Sigmatel HD codec: STAC9255D");
3135 		break;
3136 	case 0x838476a6:
3137 		(void) snprintf(buf, sizeof (buf),
3138 		    "Sigmatel HD codec: STAC9254");
3139 		break;
3140 	case 0x838476a7:
3141 		(void) snprintf(buf, sizeof (buf),
3142 		    "Sigmatel HD codec: STAC9254D");
3143 		break;
3144 	case 0x83847620:
3145 		(void) snprintf(buf, sizeof (buf),
3146 		    "Sigmatel HD codec: STAC9274");
3147 		break;
3148 	case 0x83847621:
3149 		(void) snprintf(buf, sizeof (buf),
3150 		    "Sigmatel HD codec: STAC9274D");
3151 		break;
3152 	case 0x83847622:
3153 		(void) snprintf(buf, sizeof (buf),
3154 		    "Sigmatel HD codec: STAC9273X");
3155 		break;
3156 	case 0x83847623:
3157 		(void) snprintf(buf, sizeof (buf),
3158 		    "Sigmatel HD codec: STAC9273D");
3159 		break;
3160 	case 0x83847624:
3161 		(void) snprintf(buf, sizeof (buf),
3162 		    "Sigmatel HD codec: STAC9272X");
3163 		break;
3164 	case 0x83847625:
3165 		(void) snprintf(buf, sizeof (buf),
3166 		    "Sigmatel HD codec: STAC9272D");
3167 		break;
3168 	case 0x83847626:
3169 		(void) snprintf(buf, sizeof (buf),
3170 		    "Sigmatel HD codec: STAC9271X");
3171 		break;
3172 	case 0x83847627:
3173 		(void) snprintf(buf, sizeof (buf),
3174 		    "Sigmatel HD codec: STAC9271D");
3175 		break;
3176 	case 0x83847628:
3177 		(void) snprintf(buf, sizeof (buf),
3178 		    "Sigmatel HD codec: STAC9274X5NH");
3179 		break;
3180 	case 0x83847629:
3181 		(void) snprintf(buf, sizeof (buf),
3182 		    "Sigmatel HD codec: STAC9274D5NH");
3183 		break;
3184 	case 0x83847662:
3185 		(void) snprintf(buf, sizeof (buf),
3186 		    "Sigmatel HD codec: STAC9872AK");
3187 		break;
3188 	case 0x83847664:
3189 		(void) snprintf(buf, sizeof (buf),
3190 		    "Sigmatel HD codec: STAC9872K");
3191 		break;
3192 	default:
3193 		(void) snprintf(buf, sizeof (buf),
3194 		    "Unkown HD codec");
3195 		break;
3196 
3197 	}
3198 	audio_dev_add_info(codec->soft_statep->adev, buf);
3199 }
3200 /*
3201  * audiohd_create_codec()
3202  *
3203  * Description:
3204  *	Searching for supported CODEC. If find, allocate memory
3205  *	to hold codec structure.
3206  */
3207 static int
3208 audiohd_create_codec(audiohd_state_t *statep)
3209 {
3210 	hda_codec_t	*codec;
3211 	uint32_t	mask, type;
3212 	uint32_t	nums;
3213 	uint32_t	i, j;
3214 	wid_t		wid;
3215 
3216 	mask = statep->hda_codec_mask;
3217 	ASSERT(mask != 0);
3218 
3219 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
3220 		if ((mask & (1 << i)) == 0)
3221 			continue;
3222 		codec = (hda_codec_t *)kmem_zalloc(
3223 		    sizeof (hda_codec_t), KM_SLEEP);
3224 		codec->index = i;
3225 		codec->vid = audioha_codec_verb_get(statep, i,
3226 		    AUDIOHDC_NODE_ROOT, AUDIOHDC_VERB_GET_PARAM,
3227 		    AUDIOHDC_PAR_VENDOR_ID);
3228 		codec->revid =
3229 		    audioha_codec_verb_get(statep, i,
3230 		    AUDIOHDC_NODE_ROOT, AUDIOHDC_VERB_GET_PARAM,
3231 		    AUDIOHDC_PAR_REV_ID);
3232 
3233 		nums = audioha_codec_verb_get(statep,
3234 		    i, AUDIOHDC_NODE_ROOT,
3235 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_NODE_COUNT);
3236 		if (nums == (uint32_t)(-1)) {
3237 			kmem_free(codec, sizeof (hda_codec_t));
3238 			continue;
3239 		}
3240 		wid = (nums >> AUDIOHD_CODEC_STR_OFF) & AUDIOHD_CODEC_STR_MASK;
3241 		nums = nums & AUDIOHD_CODEC_NUM_MASK;
3242 
3243 		/*
3244 		 * Assume that each codec has just one audio function group
3245 		 */
3246 		for (j = 0; j < nums; j++, wid++) {
3247 			type = audioha_codec_verb_get(statep, i, wid,
3248 			    AUDIOHDC_VERB_GET_PARAM,
3249 			    AUDIOHDC_PAR_FUNCTION_TYPE);
3250 			if ((type & AUDIOHD_CODEC_TYPE_MASK) ==
3251 			    AUDIOHDC_AUDIO_FUNC_GROUP) {
3252 				codec->wid_afg = wid;
3253 				break;
3254 			}
3255 		}
3256 
3257 		if (codec->wid_afg == 0) {
3258 			kmem_free(codec, sizeof (hda_codec_t));
3259 			continue;
3260 		}
3261 
3262 		ASSERT(codec->wid_afg == wid);
3263 
3264 		/* work around for Sony VAIO laptop with specific codec */
3265 		if ((codec->vid != AUDIOHD_CODECID_SONY1) &&
3266 		    (codec->vid != AUDIOHD_CODECID_SONY2)) {
3267 			/*
3268 			 * GPIO controls which are laptop specific workarounds
3269 			 * and might be changed. Some laptops use GPIO,
3270 			 * so we need to enable and set the GPIO correctly.
3271 			 */
3272 			(void) audioha_codec_verb_get(statep, i, wid,
3273 			    AUDIOHDC_VERB_SET_GPIO_MASK, AUDIOHDC_GPIO_ENABLE);
3274 			(void) audioha_codec_verb_get(statep, i, wid,
3275 			    AUDIOHDC_VERB_SET_GPIO_DIREC, AUDIOHDC_GPIO_DIRECT);
3276 			(void) audioha_codec_verb_get(statep, i, wid,
3277 			    AUDIOHDC_VERB_SET_GPIO_STCK,
3278 			    AUDIOHDC_GPIO_DATA_CTRL);
3279 			(void) audioha_codec_verb_get(statep, i, wid,
3280 			    AUDIOHDC_VERB_SET_GPIO_DATA,
3281 			    AUDIOHDC_GPIO_STCK_CTRL);
3282 		}
3283 
3284 		/* power-up audio function group */
3285 		(void) audioha_codec_verb_get(statep, i, wid,
3286 		    AUDIOHDC_VERB_SET_POWER_STATE, 0);
3287 
3288 		/* subsystem id is attached to funtion group */
3289 		codec->outamp_cap = audioha_codec_verb_get(statep, i, wid,
3290 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_OUTAMP_CAP);
3291 		codec->inamp_cap = audioha_codec_verb_get(statep, i, wid,
3292 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_INAMP_CAP);
3293 		codec->stream_format = audioha_codec_verb_get(statep, i, wid,
3294 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_STREAM);
3295 		codec->pcm_format = audioha_codec_verb_get(statep, i, wid,
3296 		    AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PCM);
3297 
3298 		nums = audioha_codec_verb_get(statep, i, wid,
3299 		    AUDIOHDC_VERB_GET_PARAM,
3300 		    AUDIOHDC_PAR_NODE_COUNT);
3301 		wid = (nums >> AUDIOHD_CODEC_STR_OFF) & AUDIOHD_CODEC_STR_MASK;
3302 		nums = nums & AUDIOHD_CODEC_NUM_MASK;
3303 		codec->first_wid = wid;
3304 		codec->last_wid = wid + nums;
3305 		codec->nnodes = nums;
3306 
3307 		/*
3308 		 * We output the codec information to syslog
3309 		 */
3310 		statep->codec[i] = codec;
3311 		codec->soft_statep = statep;
3312 		audiohd_set_codec_info(codec);
3313 		(void) audiohd_create_widgets(codec);
3314 	}
3315 
3316 	return (DDI_SUCCESS);
3317 
3318 }	/* audiohd_create_codec() */
3319 
3320 /*
3321  * audiohd_destroy_codec()
3322  *
3323  * Description:
3324  *	destroy codec structure, and release its memory
3325  */
3326 static void
3327 audiohd_destroy_codec(audiohd_state_t *statep)
3328 {
3329 	int			i;
3330 	audiohd_pin_t		*pin, *npin;
3331 
3332 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
3333 		if (statep->codec[i]) {
3334 			audiohd_destroy_widgets(statep->codec[i]);
3335 			/*
3336 			 * free pins
3337 			 */
3338 			pin = statep->codec[i]->first_pin;
3339 			while (pin) {
3340 				npin = pin;
3341 				pin = pin->next;
3342 				kmem_free(npin, sizeof (audiohd_pin_t));
3343 			}
3344 
3345 			kmem_free(statep->codec[i], sizeof (hda_codec_t));
3346 			statep->codec[i] = NULL;
3347 		}
3348 	}
3349 }	/* audiohd_destroy_codec() */
3350 
3351 /*
3352  * audiohd_find_dac()
3353  * Description:
3354  *	Find a dac for a output path. Then the play data can be sent to the out
3355  *	put pin through the output path.
3356  *
3357  * Arguments:
3358  *	hda_codec_t	*codec		where the dac widget exists
3359  *	wid_t		wid		the no. of a widget
3360  *	int		mixer		whether the path need mixer or not
3361  *	int		*mixernum	the total of mixer in the output path
3362  *	int		exclusive	an exclusive path or share path
3363  *	int		depth		the depth of search
3364  *
3365  * Return:
3366  *	1) wid of the first shared widget in the path from
3367  *	   pin to DAC if exclusive is 0;
3368  *	2) wid of DAC widget;
3369  *	3) 0 if no path
3370  */
3371 static wid_t
3372 audiohd_find_dac(hda_codec_t *codec, wid_t wid,
3373     int mixer, int *mixernum,
3374     int exclusive, int depth)
3375 {
3376 	audiohd_widget_t	*widget = codec->widget[wid];
3377 	wid_t	wdac = (uint32_t)(DDI_FAILURE);
3378 	wid_t	retval;
3379 
3380 	if (depth > AUDIOHD_MAX_DEPTH)
3381 		return (uint32_t)(DDI_FAILURE);
3382 
3383 	if (widget == NULL)
3384 		return (uint32_t)(DDI_FAILURE);
3385 
3386 	/*
3387 	 * If exclusive is true, we try to find a path which doesn't
3388 	 * share any widget with other paths.
3389 	 */
3390 	if (exclusive) {
3391 		if (widget->path_flags & AUDIOHD_PATH_DAC)
3392 			return (uint32_t)(DDI_FAILURE);
3393 	} else {
3394 		if (widget->path_flags & AUDIOHD_PATH_DAC)
3395 			return (wid);
3396 	}
3397 
3398 	switch (widget->type) {
3399 	case WTYPE_AUDIO_OUT:
3400 		/* We need mixer widget, but the the mixer num is 0, failed  */
3401 		if (mixer && !*mixernum)
3402 			return (uint32_t)(DDI_FAILURE);
3403 		widget->path_flags |= AUDIOHD_PATH_DAC;
3404 		widget->out_weight++;
3405 		wdac = widget->wid_wid;
3406 		break;
3407 
3408 	case WTYPE_AUDIO_MIX:
3409 	case WTYPE_AUDIO_SEL:
3410 		if (widget->type == WTYPE_AUDIO_MIX)
3411 			(*mixernum)++;
3412 		for (int i = 0; i < widget->nconns; i++) {
3413 			retval = audiohd_find_dac(codec,
3414 			    widget->avail_conn[i],
3415 			    mixer, mixernum,
3416 			    exclusive, depth + 1);
3417 			if (retval != (uint32_t)DDI_FAILURE) {
3418 				if (widget->selconn == AUDIOHD_NULL_CONN) {
3419 					widget->selconn = i;
3420 					wdac = retval;
3421 				}
3422 				widget->path_flags |= AUDIOHD_PATH_DAC;
3423 				widget->out_weight++;
3424 
3425 				/* return when found a path */
3426 				return (wdac);
3427 			}
3428 		}
3429 	default:
3430 		break;
3431 	}
3432 
3433 	return (wdac);
3434 }	/* audiohd_find_dac() */
3435 
3436 /*
3437  * audiohd_do_build_output_path()
3438  *
3439  * Description:
3440  *	Search an output path for each pin in the codec.
3441  * Arguments:
3442  *	hda_codec_t	*codec		where the output path exists
3443  *	int		mixer		wheter the path needs mixer widget
3444  *	int		*mnum		total of mixer widget in the path
3445  *	int		exclusive	an exclusive path or shared path
3446  *	int		depth		search depth
3447  */
3448 static void
3449 audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum,
3450     int exclusive, int depth)
3451 {
3452 	audiohd_pin_t		*pin;
3453 	audiohd_widget_t	*widget, *wdac;
3454 	audiohd_path_t	*path;
3455 	wid_t			wid;
3456 	audiohd_state_t	*statep;
3457 	int			i;
3458 
3459 	statep = codec->soft_statep;
3460 
3461 	for (pin = codec->first_pin; pin; pin = pin->next) {
3462 		if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
3463 			continue;
3464 		if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
3465 		    AUDIOHD_PIN_NO_CONN)
3466 			continue;
3467 		if ((pin->device != DTYPE_LINEOUT) &&
3468 		    (pin->device != DTYPE_SPEAKER) &&
3469 		    (pin->device != DTYPE_SPDIF_OUT) &&
3470 		    (pin->device != DTYPE_HP_OUT))
3471 			continue;
3472 		if (pin->finish)
3473 			continue;
3474 		widget = codec->widget[pin->wid];
3475 
3476 		widget->inamp_cap = 0;
3477 		for (i = 0; i < widget->nconns; i++) {
3478 			/*
3479 			 * If a dac found, the return value is the wid of the
3480 			 * widget on the path, or the return value is
3481 			 * DDI_FAILURE
3482 			 */
3483 			wid = audiohd_find_dac(codec,
3484 			    widget->avail_conn[i], mixer, mnum, exclusive,
3485 			    depth);
3486 			/*
3487 			 * A dac was not found
3488 			 */
3489 			if (wid == (wid_t)DDI_FAILURE)
3490 				continue;
3491 			if (pin->device != DTYPE_SPEAKER &&
3492 			    pin->device != DTYPE_HP_OUT)
3493 				statep->chann[pin->assoc] += 2;
3494 			path = (audiohd_path_t *)
3495 			    kmem_zalloc(sizeof (audiohd_path_t),
3496 			    KM_SLEEP);
3497 			path->adda_wid = wid;
3498 			path->pin_wid[0] = widget->wid_wid;
3499 			path->pin_nums = 1;
3500 			path->path_type = PLAY;
3501 			path->codec = codec;
3502 			path->statep = statep;
3503 			wdac = codec->widget[wid];
3504 			wdac->priv = path;
3505 			pin->adc_dac_wid = wid;
3506 			pin->finish = 1;
3507 			widget->path_flags |= AUDIOHD_PATH_DAC;
3508 			widget->out_weight++;
3509 			widget->selconn = i;
3510 			statep->path[statep->pathnum++] = path;
3511 			break;
3512 		}
3513 	}
3514 
3515 }	/* audiohd_do_build_output_path() */
3516 
3517 /*
3518  * audiohd_build_output_path()
3519  *
3520  * Description:
3521  *	Build the output path in the codec for every pin.
3522  *	First we try to search output path with mixer widget exclusively
3523  *	Then we try to search shared output path with mixer widget.
3524  *	Then we try to search output path without mixer widget exclusively.
3525  *	At last we try to search shared ouput path for the remained pins
3526  */
3527 static void
3528 audiohd_build_output_path(hda_codec_t *codec)
3529 {
3530 	int 			mnum = 0;
3531 	uint8_t			mixer_allow = 1;
3532 
3533 	/* work around for hp mini 1000 laptop */
3534 	if (codec->vid == AUDIOHD_CODECID_HP)
3535 		mixer_allow = 0;
3536 	/* search an exclusive mixer widget path. This is preferred */
3537 	audiohd_do_build_output_path(codec, mixer_allow, &mnum, 1, 0);
3538 
3539 	/* search a shared mixer widget path for the remained pins */
3540 	audiohd_do_build_output_path(codec, mixer_allow, &mnum, 0, 0);
3541 
3542 	/* search an exclusive widget path without mixer for the remained pin */
3543 	audiohd_do_build_output_path(codec, 0, &mnum, 1, 0);
3544 
3545 	/* search a shared widget path without mixer for the remained pin */
3546 	audiohd_do_build_output_path(codec, 0, &mnum, 0, 0);
3547 
3548 }	/* audiohd_build_output_path */
3549 
3550 /*
3551  * audiohd_build_output_amp
3552  *
3553  * Description:
3554  *	Find the gain control and mute control widget
3555  */
3556 static void
3557 audiohd_build_output_amp(hda_codec_t *codec)
3558 {
3559 	audiohd_path_t		*path;
3560 	audiohd_widget_t	*w, *widget, *wpin, *wdac;
3561 	audiohd_pin_t		*pin;
3562 	wid_t		wid;
3563 	int		weight;
3564 	int		i, j;
3565 	uint32_t	gain;
3566 
3567 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
3568 		path = codec->soft_statep->path[i];
3569 		if (path == NULL || path->path_type == RECORD ||
3570 		    path->codec != codec)
3571 			continue;
3572 		for (j = 0; j < path->pin_nums; j++) {
3573 			wid = path->pin_wid[j];
3574 			wpin = codec->widget[wid];
3575 			pin = (audiohd_pin_t *)wpin->priv;
3576 			weight = wpin->out_weight;
3577 
3578 			/*
3579 			 * search a node which can mute this pin while
3580 			 * the mute functionality doesn't effect other
3581 			 * pins.
3582 			 */
3583 			widget = wpin;
3584 			while (widget) {
3585 				if (widget->outamp_cap &
3586 				    AUDIOHDC_AMP_CAP_MUTE_CAP) {
3587 					pin->mute_wid = widget->wid_wid;
3588 					pin->mute_dir = AUDIOHDC_AMP_SET_OUTPUT;
3589 					break;
3590 				}
3591 				if (widget->inamp_cap &
3592 				    AUDIOHDC_AMP_CAP_MUTE_CAP) {
3593 					pin->mute_wid = widget->wid_wid;
3594 					pin->mute_dir = AUDIOHDC_AMP_SET_INPUT;
3595 					break;
3596 				}
3597 				if (widget->selconn == AUDIOHD_NULL_CONN)
3598 					break;
3599 				wid = widget->avail_conn[widget->selconn];
3600 				widget = codec->widget[wid];
3601 				if (widget && widget->out_weight != weight)
3602 					break;
3603 			}
3604 
3605 			/*
3606 			 * We select the wid which has maxium gain range in
3607 			 * the output path. Meanwhile, the gain controlling
3608 			 * of this node doesn't effect other pins if this
3609 			 * output stream has multiple pins.
3610 			 */
3611 			gain = 0;
3612 			widget = wpin;
3613 			while (widget) {
3614 				gain = (widget->outamp_cap &
3615 				    AUDIOHDC_AMP_CAP_STEP_NUMS);
3616 				if (gain && gain > pin->gain_bits) {
3617 					pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT;
3618 					pin->gain_bits = gain;
3619 					pin->gain_wid = widget->wid_wid;
3620 				}
3621 				gain = widget->inamp_cap &
3622 				    AUDIOHDC_AMP_CAP_STEP_NUMS;
3623 				if (gain && gain > pin->gain_bits) {
3624 					pin->gain_dir = AUDIOHDC_AMP_SET_INPUT;
3625 					pin->gain_bits = gain;
3626 					pin->gain_wid = widget->wid_wid;
3627 				}
3628 				if (widget->selconn == AUDIOHD_NULL_CONN)
3629 					break;
3630 				wid = widget->avail_conn[widget->selconn];
3631 				widget = codec->widget[wid];
3632 				if (widget && widget->out_weight != weight)
3633 					break;
3634 			}
3635 			pin->gain_bits >>= AUDIOHD_GAIN_OFF;
3636 		}
3637 
3638 		/*
3639 		 * if this stream has multiple pins, we try to find
3640 		 * a mute & gain-controlling nodes which can effect
3641 		 * all output pins of this stream to be used for the
3642 		 * whole stream
3643 		 */
3644 		if (path->pin_nums == 1) {
3645 			path->mute_wid = pin->mute_wid;
3646 			path->mute_dir = pin->mute_dir;
3647 			path->gain_wid = pin->gain_wid;
3648 			path->gain_dir = pin->gain_dir;
3649 			path->gain_bits = pin->gain_bits;
3650 		} else {
3651 			wdac = codec->widget[path->adda_wid];
3652 			weight = wdac->out_weight;
3653 			wid = path->pin_wid[0];
3654 			w = codec->widget[wid];
3655 			while (w && w->out_weight != weight) {
3656 				wid = w->avail_conn[w->selconn];
3657 				w = codec->widget[wid];
3658 			}
3659 
3660 			/* find mute controlling node for this stream */
3661 			widget = w;
3662 			while (widget) {
3663 				if (widget->outamp_cap &
3664 				    AUDIOHDC_AMP_CAP_MUTE_CAP) {
3665 					path->mute_wid = widget->wid_wid;
3666 					path->mute_dir =
3667 					    AUDIOHDC_AMP_SET_OUTPUT;
3668 					break;
3669 				}
3670 				if (widget->inamp_cap &
3671 				    AUDIOHDC_AMP_CAP_MUTE_CAP) {
3672 					path->mute_wid = widget->wid_wid;
3673 					path->mute_dir =
3674 					    AUDIOHDC_AMP_SET_INPUT;
3675 					break;
3676 				}
3677 				if (widget->selconn == AUDIOHD_NULL_CONN)
3678 					break;
3679 				wid = widget->avail_conn[widget->selconn];
3680 				widget = codec->widget[wid];
3681 			}
3682 
3683 			/* find volume controlling node for this stream */
3684 			gain = 0;
3685 			widget = w;
3686 			while (widget) {
3687 				gain = (widget->outamp_cap &
3688 				    AUDIOHDC_AMP_CAP_STEP_NUMS);
3689 				if (gain && gain > pin->gain_bits) {
3690 					path->gain_dir =
3691 					    AUDIOHDC_AMP_SET_OUTPUT;
3692 					path->gain_bits = gain;
3693 					path->gain_wid = widget->wid_wid;
3694 				}
3695 				gain = widget->inamp_cap &
3696 				    AUDIOHDC_AMP_CAP_STEP_NUMS;
3697 				if (gain && (gain > pin->gain_bits) &&
3698 				    (widget->type != WTYPE_AUDIO_MIX)) {
3699 					path->gain_dir =
3700 					    AUDIOHDC_AMP_SET_INPUT;
3701 					path->gain_bits = gain;
3702 					path->gain_wid = widget->wid_wid;
3703 				}
3704 				if (widget->selconn == AUDIOHD_NULL_CONN)
3705 					break;
3706 				wid = widget->avail_conn[widget->selconn];
3707 				widget = codec->widget[wid];
3708 			}
3709 			path->gain_bits >>= AUDIOHD_GAIN_OFF;
3710 		}
3711 
3712 	}
3713 
3714 }	/* audiohd_build_output_amp */
3715 
3716 /*
3717  * audiohd_finish_output_path()
3718  *
3719  * Description:
3720  *	Enable the widgets on the output path
3721  */
3722 static void
3723 audiohd_finish_output_path(hda_codec_t *codec)
3724 {
3725 	audiohd_state_t		*statep = codec->soft_statep;
3726 	audiohd_path_t		*path;
3727 	audiohd_widget_t	*widget;
3728 	audiohd_pin_t		*pin;
3729 	uint_t			caddr = codec->index;
3730 	wid_t			wid;
3731 	int			i, j;
3732 
3733 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
3734 		path = codec->soft_statep->path[i];
3735 		if (!path || path->path_type != PLAY || path->codec != codec)
3736 			continue;
3737 		for (j = 0; j < path->pin_nums; j++) {
3738 			wid = path->pin_wid[j];
3739 			widget = codec->widget[wid];
3740 			pin = (audiohd_pin_t *)widget->priv;
3741 			{
3742 			uint32_t    lTmp;
3743 
3744 			lTmp = audioha_codec_verb_get(statep, caddr, wid,
3745 			    AUDIOHDC_VERB_GET_PIN_CTRL, 0);
3746 			(void) audioha_codec_verb_get(statep, caddr, wid,
3747 			    AUDIOHDC_VERB_SET_PIN_CTRL, (lTmp |
3748 			    pin->vrefvalue |
3749 			    AUDIOHDC_PIN_CONTROL_OUT_ENABLE |
3750 			    AUDIOHDC_PIN_CONTROL_HP_ENABLE) &
3751 			    ~ AUDIOHDC_PIN_CONTROL_IN_ENABLE);
3752 			}
3753 			/* If this pin has external amplifier, enable it */
3754 			if (pin->cap & AUDIOHD_EXT_AMP_MASK)
3755 				(void) audioha_codec_verb_get(statep, caddr,
3756 				    wid, AUDIOHDC_VERB_SET_EAPD,
3757 				    AUDIOHD_EXT_AMP_ENABLE);
3758 
3759 			if (widget->outamp_cap) {
3760 				(void) audioha_codec_4bit_verb_get(statep,
3761 				    caddr, wid, AUDIOHDC_VERB_SET_AMP_MUTE,
3762 				    AUDIOHDC_AMP_SET_LR_OUTPUT |
3763 				    AUDIOHDC_GAIN_MAX);
3764 			}
3765 
3766 			(void) audioha_codec_verb_get(statep, caddr, wid,
3767 			    AUDIOHDC_VERB_SET_CONN_SEL, widget->selconn);
3768 
3769 			wid = widget->avail_conn[widget->selconn];
3770 			widget = codec->widget[wid];
3771 
3772 			while (widget) {
3773 				/*
3774 				 * Set all amplifiers in this path to
3775 				 * the maximum
3776 				 * volume and unmute them.
3777 				 */
3778 				if (widget->outamp_cap) {
3779 					(void) audioha_codec_4bit_verb_get(
3780 					    statep,
3781 					    caddr,
3782 					    wid, AUDIOHDC_VERB_SET_AMP_MUTE,
3783 					    AUDIOHDC_AMP_SET_LR_OUTPUT |
3784 					    AUDIOHDC_GAIN_MAX);
3785 				}
3786 				if (widget->inamp_cap) {
3787 					(void) audioha_codec_4bit_verb_get(
3788 					    statep,
3789 					    caddr,
3790 					    wid, AUDIOHDC_VERB_SET_AMP_MUTE,
3791 					    AUDIOHDC_AMP_SET_LR_INPUT |
3792 					    AUDIOHDC_GAIN_MAX |
3793 					    (widget->selconn <<
3794 					    AUDIOHDC_AMP_SET_INDEX_OFFSET));
3795 				}
3796 
3797 				if (widget->selconn == AUDIOHD_NULL_CONN)
3798 					break;
3799 				/*
3800 				 * Accoding to HD spec, mixer doesn't support
3801 				 * "select connection"
3802 				 */
3803 				if ((widget->type != WTYPE_AUDIO_MIX) &&
3804 				    (widget->nconns > 1))
3805 					(void) audioha_codec_verb_get(statep,
3806 					    caddr,
3807 					    wid,
3808 					    AUDIOHDC_VERB_SET_CONN_SEL,
3809 					    widget->selconn);
3810 
3811 				wid = widget->avail_conn[widget->selconn];
3812 				widget = codec->widget[wid];
3813 			}
3814 		}
3815 	}
3816 }	/* audiohd_finish_output_path() */
3817 
3818 /*
3819  * audiohd_find_input_pins()
3820  *
3821  * Description:
3822  * 	Here we consider a mixer/selector with multi-input as a real sum
3823  * 	widget. Only the first real mixer/selector widget is permitted in
3824  * 	an input path(recording path). If there are more mixers/selectors
3825  * 	execept the first one, only the first input/connection of those
3826  * 	widgets will be used by our driver, that means, we ignore other
3827  * 	inputs of those mixers/selectors.
3828  */
3829 static int
3830 audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer,
3831     int depth, audiohd_path_t *path)
3832 {
3833 	audiohd_widget_t	*widget = codec->widget[wid];
3834 	audiohd_pin_t		*pin;
3835 	audiohd_state_t		*statep = codec->soft_statep;
3836 	uint_t			caddr = codec->index;
3837 	int			retval = -1;
3838 	int			num, i;
3839 	uint32_t		pinctrl;
3840 
3841 	if (depth > AUDIOHD_MAX_DEPTH)
3842 		return (uint32_t)(DDI_FAILURE);
3843 	if (widget == NULL)
3844 		return (uint32_t)(DDI_FAILURE);
3845 
3846 	/* we don't share widgets */
3847 	if (widget->path_flags & AUDIOHD_PATH_ADC ||
3848 	    widget->path_flags & AUDIOHD_PATH_DAC)
3849 		return (uint32_t)(DDI_FAILURE);
3850 
3851 	switch (widget->type) {
3852 	case WTYPE_PIN:
3853 		pin = (audiohd_pin_t *)widget->priv;
3854 		if (pin->no_phys_conn)
3855 			return (uint32_t)(DDI_FAILURE);
3856 		/* enable the pins' input capability */
3857 		pinctrl = audioha_codec_verb_get(statep, caddr, wid,
3858 		    AUDIOHDC_VERB_GET_PIN_CTRL, 0);
3859 		(void) audioha_codec_verb_get(statep, caddr, wid,
3860 		    AUDIOHDC_VERB_SET_PIN_CTRL,
3861 		    pinctrl | AUDIOHD_PIN_IN_ENABLE);
3862 		if (pin->cap & AUDIOHD_EXT_AMP_MASK) {
3863 			(void) audioha_codec_verb_get(statep, caddr,
3864 			    wid, AUDIOHDC_VERB_SET_EAPD,
3865 			    AUDIOHD_EXT_AMP_ENABLE);
3866 		}
3867 		switch (pin->device) {
3868 		case DTYPE_CD:
3869 		case DTYPE_LINE_IN:
3870 		case DTYPE_MIC_IN:
3871 		case DTYPE_AUX:
3872 			widget->path_flags |= AUDIOHD_PATH_ADC;
3873 			widget->in_weight++;
3874 			path->pin_wid[path->pin_nums++] = wid;
3875 			pin->adc_dac_wid = path->adda_wid;
3876 			return (DDI_SUCCESS);
3877 		}
3878 		break;
3879 	case WTYPE_AUDIO_MIX:
3880 	case WTYPE_AUDIO_SEL:
3881 		/*
3882 		 * If the sum widget has only one input, we don't
3883 		 * consider it as a real sum widget.
3884 		 */
3885 		if (widget->nconns == 1) {
3886 			widget->selconn = 0;
3887 			retval = audiohd_find_input_pins(codec,
3888 			    widget->avail_conn[0],
3889 			    allowmixer, depth + 1, path);
3890 			if (retval != DDI_FAILURE) {
3891 				widget->path_flags |= AUDIOHD_PATH_ADC;
3892 				widget->in_weight++;
3893 			}
3894 			break;
3895 		}
3896 
3897 		if (allowmixer) {
3898 			/*
3899 			 * This is a real sum widget, we will reject
3900 			 * other real sum widget when we find more in
3901 			 * the following path-searching.
3902 			 */
3903 			for (int i = 0; i < widget->nconns; i++) {
3904 				retval = audiohd_find_input_pins(codec,
3905 				    widget->avail_conn[i], 0, depth + 1,
3906 				    path);
3907 				if (retval != DDI_FAILURE) {
3908 					widget->in_weight++;
3909 					num = path->pin_nums - 1;
3910 					path->sum_selconn[num] = i;
3911 					path->sum_wid = wid;
3912 					widget->path_flags |=
3913 					    AUDIOHD_PATH_ADC;
3914 					if (widget->selconn ==
3915 					    AUDIOHD_NULL_CONN) {
3916 						widget->selconn = i;
3917 					}
3918 				}
3919 			}
3920 
3921 			/* return SUCCESS if we found at least one input path */
3922 			if (path->pin_nums > 0)
3923 				retval = DDI_SUCCESS;
3924 		} else {
3925 			/*
3926 			 * We had already found a real sum before this one since
3927 			 * allowmixer is 0.
3928 			 */
3929 			for (i = 0; i < widget->nconns; i++) {
3930 				retval = audiohd_find_input_pins(codec,
3931 				    widget->avail_conn[i], 0, depth + 1,
3932 				    path);
3933 				if (retval != DDI_FAILURE) {
3934 					widget->selconn = i;
3935 					widget->path_flags |= AUDIOHD_PATH_ADC;
3936 					widget->in_weight++;
3937 					break;
3938 				}
3939 			}
3940 		}
3941 		break;
3942 	default:
3943 		break;
3944 	}
3945 
3946 	return (retval);
3947 }	/* audiohd_find_input_pins */
3948 
3949 /*
3950  * audiohd_build_input_path()
3951  *
3952  * Description:
3953  *	Find input path for the codec
3954  */
3955 static void
3956 audiohd_build_input_path(hda_codec_t *codec)
3957 {
3958 	audiohd_widget_t	*widget;
3959 	audiohd_path_t		*path = NULL;
3960 	wid_t			wid;
3961 	int			i;
3962 	int			retval;
3963 	uint8_t			rtag = 0;
3964 	audiohd_state_t		*statep = codec->soft_statep;
3965 
3966 	for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
3967 
3968 		widget = codec->widget[wid];
3969 
3970 		/* check if it is an ADC widget */
3971 		if (!widget || widget->type != WTYPE_AUDIO_IN)
3972 			continue;
3973 
3974 		if (path == NULL)
3975 			path = kmem_zalloc(sizeof (audiohd_path_t),
3976 			    KM_SLEEP);
3977 		else
3978 			bzero(path, sizeof (audiohd_port_t));
3979 
3980 		path->adda_wid = wid;
3981 
3982 		/*
3983 		 * Is there any ADC widget which has more than one input ??
3984 		 * I don't believe. Anyway, we carefully deal with this. But
3985 		 * if hardware vendors embed a selector in a ADC, we just use
3986 		 * the first available input, which has connection to input pin
3987 		 * widget. Because selector cannot perform mixer functionality,
3988 		 * and we just permit one selector or mixer in a recording path,
3989 		 * if we use the selector embedded in ADC,we cannot use possible
3990 		 * mixer during path searching.
3991 		 */
3992 		for (i = 0; i < widget->nconns; i++) {
3993 			retval = audiohd_find_input_pins(codec,
3994 			    widget->avail_conn[i], 1, 0, path);
3995 			if (retval == DDI_SUCCESS) {
3996 				path->codec = codec;
3997 				path->statep = statep;
3998 				path->path_type = RECORD;
3999 				path->tag = ++rtag;
4000 				codec->nistream++;
4001 				statep->path[statep->pathnum++] = path;
4002 				widget->selconn = i;
4003 				widget->priv = path;
4004 				path = NULL;
4005 				break;
4006 			}
4007 		}
4008 	}
4009 	if (path)
4010 		kmem_free(path, sizeof (audiohd_path_t));
4011 }	/* audiohd_build_input_path */
4012 
4013 /*
4014  * audiohd_build_input_amp()
4015  *
4016  * Description:
4017  *	Find gain and mute control widgets on the input path
4018  */
4019 static void
4020 audiohd_build_input_amp(hda_codec_t *codec)
4021 {
4022 	audiohd_path_t		*path;
4023 	audiohd_widget_t	*wsum, *wadc, *w;
4024 	audiohd_pin_t		*pin;
4025 	uint_t			gain;
4026 	wid_t			wid;
4027 	int			i, j;
4028 	int			weight;
4029 
4030 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
4031 		path = codec->soft_statep->path[i];
4032 		if (path == NULL || path->path_type != RECORD ||
4033 		    path->codec != codec)
4034 			continue;
4035 
4036 		wid = path->adda_wid;
4037 		wadc = path->codec->widget[wid];
4038 		weight = wadc->in_weight;
4039 
4040 		/*
4041 		 * Search node which has mute functionality for
4042 		 * the whole input path
4043 		 */
4044 		w = wadc;
4045 		while (w) {
4046 			if (w->outamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) {
4047 				path->mute_wid = w->wid_wid;
4048 				path->mute_dir = AUDIOHDC_AMP_SET_OUTPUT;
4049 				break;
4050 			}
4051 			if ((w->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) &&
4052 			    (w->wid_wid != path->sum_wid)) {
4053 				path->mute_wid = w->wid_wid;
4054 				path->mute_dir = AUDIOHDC_AMP_SET_INPUT;
4055 				break;
4056 			}
4057 
4058 			if (w->selconn == AUDIOHD_NULL_CONN)
4059 				break;
4060 			wid = w->avail_conn[w->selconn];
4061 			w = path->codec->widget[wid];
4062 			if (w && w->in_weight != weight)
4063 				break;
4064 		}
4065 
4066 		/*
4067 		 * Search a node for amplifier adjusting for the whole
4068 		 * input path
4069 		 */
4070 		w = wadc;
4071 		gain = 0;
4072 		while (w) {
4073 			gain = (w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS);
4074 			if (gain && gain > path->gain_bits) {
4075 				path->gain_dir = AUDIOHDC_AMP_SET_OUTPUT;
4076 				path->gain_bits = gain;
4077 				path->gain_wid = w->wid_wid;
4078 			}
4079 			gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS;
4080 			if (gain && (gain > path->gain_bits) &&
4081 			    (w->wid_wid != path->sum_wid)) {
4082 				path->gain_dir = AUDIOHDC_AMP_SET_INPUT;
4083 				path->gain_bits = gain;
4084 				path->gain_wid = w->wid_wid;
4085 			}
4086 			if (w->selconn == AUDIOHD_NULL_CONN)
4087 				break;
4088 			wid = w->avail_conn[w->selconn];
4089 			w = path->codec->widget[wid];
4090 		}
4091 		path->gain_bits >>= AUDIOHD_GAIN_OFF;
4092 
4093 		/*
4094 		 * If the input path has one pin only, the mute/amp
4095 		 * controlling is shared by the whole path and pin
4096 		 */
4097 		if (path->pin_nums == 1) {
4098 			wid = path->pin_wid[0];
4099 			w = path->codec->widget[wid];
4100 			pin = (audiohd_pin_t *)w->priv;
4101 			pin->gain_dir = path->gain_dir;
4102 			pin->gain_bits = path->gain_bits;
4103 			pin->gain_wid = path->gain_wid;
4104 			pin->mute_wid = path->mute_wid;
4105 			pin->mute_dir = path->mute_dir;
4106 			continue;
4107 		}
4108 
4109 		/*
4110 		 * For multi-pin device, there must be a selector
4111 		 * or mixer along the input path, and the sum_wid
4112 		 * is the widget's node id.
4113 		 */
4114 		wid = path->sum_wid;
4115 		wsum = path->codec->widget[wid]; /* sum widget */
4116 
4117 		for (j = 0; j < path->pin_nums; j++) {
4118 			wid = path->pin_wid[j];
4119 			w = path->codec->widget[wid];
4120 			pin = (audiohd_pin_t *)w->priv;
4121 
4122 			/* find node for mute */
4123 			if (wsum->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) {
4124 				pin->mute_wid = wsum->wid_wid;
4125 				pin->mute_dir = AUDIOHDC_AMP_SET_INPUT;
4126 			} else {
4127 				wid = wsum->avail_conn[path->sum_selconn[i]];
4128 				w = path->codec->widget[wid];
4129 				while (w) {
4130 					if (w->outamp_cap &
4131 					    AUDIOHDC_AMP_CAP_MUTE_CAP) {
4132 						pin->mute_wid = w->wid_wid;
4133 						pin->mute_dir =
4134 						    AUDIOHDC_AMP_SET_OUTPUT;
4135 						break;
4136 					}
4137 					if (w->inamp_cap &
4138 					    AUDIOHDC_AMP_CAP_MUTE_CAP) {
4139 						pin->mute_wid = w->wid_wid;
4140 						pin->mute_dir =
4141 						    AUDIOHDC_AMP_SET_INPUT;
4142 						break;
4143 					}
4144 
4145 					if (w->selconn == AUDIOHD_NULL_CONN)
4146 						break;
4147 					wid = w->avail_conn[w->selconn];
4148 					w = path->codec->widget[wid];
4149 				}
4150 			}
4151 
4152 			/* find node for amp controlling */
4153 			gain = (wsum->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS);
4154 			wid = wsum->avail_conn[path->sum_selconn[i]];
4155 			w = path->codec->widget[wid];
4156 			while (w) {
4157 				gain = (w->outamp_cap &
4158 				    AUDIOHDC_AMP_CAP_STEP_NUMS);
4159 				if (gain && gain > pin->gain_bits) {
4160 					pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT;
4161 					pin->gain_bits = gain;
4162 					pin->gain_wid = w->wid_wid;
4163 				}
4164 				gain = w->inamp_cap &
4165 				    AUDIOHDC_AMP_CAP_STEP_NUMS;
4166 				if (gain && (gain > pin->gain_bits)) {
4167 					pin->gain_dir = AUDIOHDC_AMP_SET_INPUT;
4168 					pin->gain_bits = gain;
4169 					pin->gain_wid = w->wid_wid;
4170 				}
4171 				if (w->selconn == AUDIOHD_NULL_CONN)
4172 					break;
4173 				wid = w->avail_conn[w->selconn];
4174 				w = path->codec->widget[wid];
4175 			}
4176 			pin->gain_bits >>= AUDIOHD_GAIN_OFF;
4177 		}
4178 	}
4179 }	/* audiohd_build_input_amp() */
4180 
4181 /*
4182  * audiohd_finish_input_path()
4183  *
4184  * Description:
4185  *	Enable the widgets on the input path
4186  */
4187 static void
4188 audiohd_finish_input_path(hda_codec_t *codec)
4189 {
4190 	audiohd_state_t		*statep = codec->soft_statep;
4191 	audiohd_path_t		*path;
4192 	audiohd_widget_t	*w, *wsum;
4193 	uint_t			caddr = codec->index;
4194 	wid_t			wid;
4195 	int			i, j;
4196 
4197 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
4198 		path = codec->soft_statep->path[i];
4199 		if (path == NULL || path->path_type != RECORD ||
4200 		    path->codec != codec)
4201 			continue;
4202 		wid = path->adda_wid;
4203 		w = path->codec->widget[wid];
4204 		while (w && (w->wid_wid != path->sum_wid) &&
4205 		    (w->type != WTYPE_PIN)) {
4206 			if ((w->type == WTYPE_AUDIO_SEL) && (w->nconns > 1))
4207 				(void) audioha_codec_verb_get(statep, caddr,
4208 				    w->wid_wid,
4209 				    AUDIOHDC_VERB_SET_CONN_SEL, w->selconn);
4210 
4211 			if (w->outamp_cap) {
4212 				(void) audioha_codec_4bit_verb_get(statep,
4213 				    caddr,
4214 				    w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4215 				    AUDIOHDC_AMP_SET_LR_OUTPUT |
4216 				    AUDIOHDC_GAIN_MAX);
4217 			}
4218 
4219 			if (w->inamp_cap) {
4220 				(void) audioha_codec_4bit_verb_get(statep,
4221 				    caddr,
4222 				    w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4223 				    AUDIOHDC_AMP_SET_LR_INPUT |
4224 				    AUDIOHDC_GAIN_MAX |
4225 				    (w->selconn <<
4226 				    AUDIOHDC_AMP_SET_INDEX_OFFSET));
4227 			}
4228 
4229 			wid = w->avail_conn[w->selconn];
4230 			w = path->codec->widget[wid];
4231 		}
4232 
4233 		/*
4234 		 * After exiting from the above loop, the widget pointed
4235 		 * by w can be a pin widget or select/mixer widget. If it
4236 		 * is a pin widget, we already finish "select connection"
4237 		 * operation for the whole path.
4238 		 */
4239 		if (w && w->type == WTYPE_PIN)
4240 			continue;
4241 
4242 		/*
4243 		 * deal with multi-pin input devices.
4244 		 */
4245 		wid = path->sum_wid;
4246 		wsum = path->codec->widget[wid];
4247 		if (wsum == NULL)
4248 			continue;
4249 		if (wsum->outamp_cap) {
4250 			(void) audioha_codec_4bit_verb_get(statep,
4251 			    caddr,
4252 			    wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4253 			    AUDIOHDC_AMP_SET_LR_OUTPUT |
4254 			    AUDIOHDC_GAIN_MAX);
4255 		}
4256 
4257 		for (j = 0; j < path->pin_nums; j++) {
4258 			if (wsum->inamp_cap) {
4259 				(void) audioha_codec_4bit_verb_get(statep,
4260 				    caddr,
4261 				    wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4262 				    AUDIOHDC_AMP_SET_LR_INPUT |
4263 				    AUDIOHDC_GAIN_MAX |
4264 				    (path->sum_selconn[j] <<
4265 				    AUDIOHDC_AMP_SET_INDEX_OFFSET));
4266 			}
4267 			if (wsum->type == WTYPE_AUDIO_SEL) {
4268 				(void) audioha_codec_verb_get(statep, caddr,
4269 				    wsum->wid_wid,
4270 				    AUDIOHDC_VERB_SET_CONN_SEL,
4271 				    path->sum_selconn[j]);
4272 			}
4273 
4274 			wid = wsum->avail_conn[path->sum_selconn[j]];
4275 			w = path->codec->widget[wid];
4276 			while (w && w->type != WTYPE_PIN) {
4277 				if ((w->type != WTYPE_AUDIO_MIX) &&
4278 				    (w->nconns > 1))
4279 					(void) audioha_codec_verb_get(statep,
4280 					    caddr, w->wid_wid,
4281 					    AUDIOHDC_VERB_SET_CONN_SEL,
4282 					    w->selconn);
4283 
4284 				if (w->outamp_cap) {
4285 					(void) audioha_codec_4bit_verb_get(
4286 					    statep,
4287 					    caddr,
4288 					    w->wid_wid,
4289 					    AUDIOHDC_VERB_SET_AMP_MUTE,
4290 					    AUDIOHDC_AMP_SET_LR_OUTPUT |
4291 					    AUDIOHDC_GAIN_MAX);
4292 				}
4293 
4294 				if (w->inamp_cap) {
4295 					(void) audioha_codec_4bit_verb_get(
4296 					    statep,
4297 					    caddr,
4298 					    w->wid_wid,
4299 					    AUDIOHDC_VERB_SET_AMP_MUTE,
4300 					    AUDIOHDC_AMP_SET_LR_INPUT |
4301 					    AUDIOHDC_GAIN_MAX |
4302 					    (w->selconn <<
4303 					    AUDIOHDC_AMP_SET_INDEX_OFFSET));
4304 				}
4305 				wid = w->avail_conn[w->selconn];
4306 				w = path->codec->widget[wid];
4307 			}
4308 		}
4309 	}	/* end of istream loop */
4310 }	/* audiohd_finish_input_path */
4311 
4312 /*
4313  * audiohd_find_inpin_for_monitor()
4314  *
4315  * Description:
4316  *	Find input pin for monitor path.
4317  *
4318  * Arguments:
4319  *	hda_codec_t		*codec		where the monitor path exists
4320  *	audiohd_ostream_t	*ostream	output ostream
4321  *	wid_t			id		no. of widget being searched
4322  *	int			mixer		share or not
4323  */
4324 static int
4325 audiohd_find_inpin_for_monitor(hda_codec_t *codec,
4326     audiohd_path_t *path, wid_t id, int mixer)
4327 {
4328 	wid_t 			wid;
4329 	audiohd_widget_t	*widget;
4330 	audiohd_pin_t		*pin;
4331 	int 			i, find = 0;
4332 
4333 	wid = id;
4334 	widget = codec->widget[wid];
4335 	if (widget == NULL)
4336 		return (uint32_t)(DDI_FAILURE);
4337 
4338 	if (widget->type == WTYPE_PIN) {
4339 		pin = (audiohd_pin_t *)widget->priv;
4340 		if (pin->no_phys_conn)
4341 			return (uint32_t)(DDI_FAILURE);
4342 		switch (pin->device) {
4343 			case DTYPE_SPDIF_IN:
4344 				widget->path_flags |= AUDIOHD_PATH_MON;
4345 				return (DDI_SUCCESS);
4346 			case DTYPE_CD:
4347 				widget->path_flags |= AUDIOHD_PATH_MON;
4348 				return (DDI_SUCCESS);
4349 			case DTYPE_LINE_IN:
4350 				widget->path_flags |= AUDIOHD_PATH_MON;
4351 				return (DDI_SUCCESS);
4352 			case DTYPE_MIC_IN:
4353 				widget->path_flags |= AUDIOHD_PATH_MON;
4354 				return (DDI_SUCCESS);
4355 			case DTYPE_AUX:
4356 				widget->path_flags |= AUDIOHD_PATH_MON;
4357 				return (DDI_SUCCESS);
4358 			default:
4359 				return (uint32_t)(DDI_FAILURE);
4360 		}
4361 	}
4362 	/* the widget has been visited and can't be directed to input pin */
4363 	if (widget->path_flags & AUDIOHD_PATH_NOMON) {
4364 		return (uint32_t)(DDI_FAILURE);
4365 	}
4366 	/* the widget has been used by the monitor path, and we can share it */
4367 	if (widget->path_flags & AUDIOHD_PATH_MON) {
4368 		if (mixer)
4369 			return (DDI_SUCCESS);
4370 		else
4371 			return (uint32_t)(DDI_FAILURE);
4372 	}
4373 	switch (widget->type) {
4374 		case WTYPE_AUDIO_MIX:
4375 			for (i = 0; i < widget->nconns; i++) {
4376 				if (widget->selconn == i && widget->path_flags &
4377 				    AUDIOHD_PATH_DAC)
4378 					continue;
4379 				if (audiohd_find_inpin_for_monitor(codec,
4380 				    path,
4381 				    widget->avail_conn[i], mixer) ==
4382 				    DDI_SUCCESS) {
4383 					widget->selmon[widget->used++] = i;
4384 					widget->path_flags |= AUDIOHD_PATH_MON;
4385 					find = 1;
4386 				}
4387 			}
4388 			break;
4389 		case WTYPE_AUDIO_SEL:
4390 			for (i = 0; i < widget->nconns; i++) {
4391 				if (widget->selconn == i && widget->path_flags &
4392 				    AUDIOHD_PATH_DAC)
4393 					continue;
4394 				if (audiohd_find_inpin_for_monitor(codec,
4395 				    path,
4396 				    widget->avail_conn[i],
4397 				    mixer) ==
4398 				    DDI_SUCCESS) {
4399 					widget->selmon[0] = i;
4400 					widget->path_flags |= AUDIOHD_PATH_MON;
4401 					return (DDI_SUCCESS);
4402 				}
4403 			}
4404 		default:
4405 			break;
4406 	}
4407 	if (!find) {
4408 		widget->path_flags |= AUDIOHD_PATH_NOMON;
4409 		return (uint32_t)(DDI_FAILURE);
4410 	}
4411 	else
4412 		return (DDI_SUCCESS);
4413 }	/* audiohd_find_inpin_for_monitor */
4414 
4415 /*
4416  * audiohd_build_monitor_path()
4417  *
4418  * Description:
4419  * 	The functionality of mixer is to mix inputs, such as CD-IN, MIC,
4420  * 	Line-in, etc, with DAC outputs, so as to minitor what is being
4421  * 	recorded and implement "What you hear is what you get". However,
4422  * 	this functionality are really hardware-dependent: the inputs
4423  * 	must be directed to MIXER if they can be directed to ADC as
4424  * 	recording sources.
4425  */
4426 static void
4427 audiohd_build_monitor_path(hda_codec_t *codec)
4428 {
4429 	audiohd_path_t		*path;
4430 	audiohd_widget_t	*widget;
4431 	audiohd_state_t		*statep = codec->soft_statep;
4432 	wid_t			wid;
4433 	int			i, j, k, l, find;
4434 	int			mixernum = 0;
4435 
4436 	for (i = 0; i < statep->pathnum; i++) {
4437 		path = statep->path[i];
4438 		if (!path || path->codec != codec ||path->path_type != PLAY)
4439 			continue;
4440 		for (j = 0; j < path->pin_nums; j++) {
4441 			wid = path->pin_wid[j];
4442 			widget = codec->widget[wid];
4443 			l = 0;
4444 			while (widget) {
4445 				while (widget &&
4446 				    ((widget->type != WTYPE_AUDIO_MIX) ||
4447 				    (widget->nconns < 2))) {
4448 					if (widget->selconn ==
4449 					    AUDIOHD_NULL_CONN)
4450 						break;
4451 					wid =
4452 					    widget->avail_conn[widget->selconn];
4453 					widget = codec->widget[wid];
4454 				}
4455 
4456 				/*
4457 				 * No mixer in this output path, we cannot build
4458 				 * mixer path for this path, skip it,
4459 				 * and continue
4460 				 * for next output path.
4461 				 */
4462 				if (widget == NULL || widget->selconn ==
4463 				    AUDIOHD_NULL_CONN) {
4464 					break;
4465 				}
4466 				mixernum++;
4467 				for (k = 0; k < widget->nconns; k++) {
4468 
4469 					/*
4470 					 * this connection must be routined
4471 					 * to DAC instead of an input pin
4472 					 * widget, we needn't waste time for
4473 					 * it
4474 					 */
4475 					if (widget->selconn == k)
4476 						continue;
4477 					find = 0;
4478 					if (audiohd_find_inpin_for_monitor(
4479 					    codec,
4480 					    path,
4481 					    widget->avail_conn[k], 0) ==
4482 					    DDI_SUCCESS) {
4483 						path->mon_wid[j][l] = wid;
4484 						widget->selmon[widget->used++] =
4485 						    k;
4486 						widget->path_flags |=
4487 						    AUDIOHD_PATH_MON;
4488 						find = 1;
4489 					} else if (
4490 					    audiohd_find_inpin_for_monitor(
4491 					    codec,
4492 					    path,
4493 					    widget->avail_conn[k], 1) ==
4494 					    DDI_SUCCESS) {
4495 						path->mon_wid[j][l] = wid;
4496 						widget->selmon[widget->used++] =
4497 						    k;
4498 						widget->path_flags |=
4499 						    AUDIOHD_PATH_MON;
4500 						find = 1;
4501 
4502 					}
4503 
4504 				}
4505 
4506 				/*
4507 				 * we needn't check widget->selconn here
4508 				 * since this
4509 				 * widget is a selector or mixer, it cannot
4510 				 * be NULL connection.
4511 				 */
4512 				if (!find) {
4513 					path->mon_wid[i][l] = 0;
4514 					widget->path_flags |=
4515 					    AUDIOHD_PATH_NOMON;
4516 				}
4517 				wid = widget->avail_conn[widget->selconn];
4518 				widget = codec->widget[wid];
4519 				l++;
4520 			}
4521 			path->maxmixer[j] = l;
4522 		}
4523 
4524 	}
4525 	if (mixernum == 0)
4526 		statep->monitor_unsupported = B_TRUE;
4527 	else
4528 		statep->monitor_unsupported = B_FALSE;
4529 }	/* audiohd_build_monitor_path */
4530 
4531 /*
4532  * audiohd_do_finish_monitor_path
4533  *
4534  * Description:
4535  *	Enable the widgets on the monitor path
4536  */
4537 static void
4538 audiohd_do_finish_monitor_path(hda_codec_t *codec, audiohd_widget_t *wgt)
4539 {
4540 	uint_t			caddr = codec->index;
4541 	audiohd_widget_t 	*widget = wgt;
4542 	audiohd_widget_t	*w;
4543 	audiohd_state_t		*statep = codec->soft_statep;
4544 	wid_t			wid;
4545 	int			i;
4546 	int			share = 0;
4547 
4548 	if (!widget || widget->finish)
4549 		return;
4550 	if (widget->path_flags & AUDIOHD_PATH_ADC)
4551 		share = 1;
4552 	if ((widget->outamp_cap)&&!share)
4553 			(void) audioha_codec_4bit_verb_get(statep, caddr,
4554 			    widget->wid_wid,
4555 			    AUDIOHDC_VERB_SET_AMP_MUTE,
4556 			    AUDIOHDC_AMP_SET_LR_OUTPUT
4557 			    | AUDIOHDC_GAIN_MAX);
4558 	if ((widget->inamp_cap)&&!share) {
4559 		for (i = 0; i < widget->used; i++) {
4560 		(void) audioha_codec_4bit_verb_get(statep, caddr,
4561 		    widget->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4562 		    AUDIOHDC_AMP_SET_LR_INPUT |
4563 		    AUDIOHDC_GAIN_MAX |
4564 		    (widget->selmon[i] <<
4565 		    AUDIOHDC_AMP_SET_INDEX_OFFSET));
4566 		}
4567 	}
4568 	if ((widget->type == WTYPE_AUDIO_SEL) && (widget->nconns > 1) &&
4569 	    !share) {
4570 		(void) audioha_codec_verb_get(statep, caddr,
4571 		    widget->wid_wid,
4572 		    AUDIOHDC_VERB_SET_CONN_SEL, widget->selmon[0]);
4573 	}
4574 	widget->finish = 1;
4575 	if (widget->used == 0)
4576 		return;
4577 	if (widget->used > 0) {
4578 		for (i = 0; i < widget->used; i++) {
4579 			wid = widget->avail_conn[widget->selmon[i]];
4580 			w = codec->widget[wid];
4581 			audiohd_do_finish_monitor_path(codec, w);
4582 		}
4583 	}
4584 }	/* audiohd_do_finish_monitor_path */
4585 
4586 /*
4587  * audiohd_finish_monitor_path
4588  *
4589  * Description:
4590  *	Enable the monitor path for every ostream path
4591  */
4592 static void
4593 audiohd_finish_monitor_path(hda_codec_t *codec)
4594 {
4595 	audiohd_path_t		*path;
4596 	audiohd_widget_t	*widget;
4597 	audiohd_state_t		*statep = codec->soft_statep;
4598 	wid_t			wid;
4599 	int 			i, j, k;
4600 
4601 	for (i = 0; i < statep->pathnum; i++) {
4602 		path = statep->path[i];
4603 		if (!path || path->codec != codec || path->path_type != PLAY)
4604 			continue;
4605 		for (j = 0; j < path->pin_nums; j++) {
4606 			for (k = 0; k < path->maxmixer[j]; k++) {
4607 				wid = path->mon_wid[j][k];
4608 				if (wid == 0) {
4609 					continue;
4610 				}
4611 				widget = codec->widget[wid];
4612 				audiohd_do_finish_monitor_path(codec, widget);
4613 			}
4614 		}
4615 	}
4616 }	/* audiohd_finish_monitor_path */
4617 
4618 /*
4619  * audiohd_do_build_monit_amp()
4620  *
4621  * Description:
4622  *	Search for the gain control widget for the monitor path
4623  */
4624 static void
4625 audiohd_do_build_monitor_amp(hda_codec_t *codec, audiohd_pin_t *pin,
4626     audiohd_widget_t *widget)
4627 {
4628 	audiohd_widget_t	*w = widget;
4629 	uint32_t		gain;
4630 	int			i;
4631 	wid_t			wid;
4632 
4633 	if (!w ||
4634 	    (w->type == WTYPE_PIN) ||
4635 	    !w->used ||
4636 	    (pin->num == AUDIOHD_MAX_CONN) ||
4637 	    (w->path_flags & AUDIOHD_PATH_ADC))
4638 		return;
4639 	if (!(w->path_flags & AUDIOHD_PATH_DAC)) {
4640 		gain = w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS;
4641 		if (gain) {
4642 			pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_OUTPUT;
4643 			pin->mg_gain[pin->num] = gain;
4644 			pin->mg_wid[pin->num] = w->wid_wid;
4645 			pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF;
4646 			pin->num++;
4647 			return;
4648 		}
4649 		gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS;
4650 		if (gain) {
4651 			pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_INPUT;
4652 			pin->mg_gain[pin->num] = gain;
4653 			pin->mg_wid[pin->num] = w->wid_wid;
4654 			pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF;
4655 			pin->num++;
4656 			return;
4657 		}
4658 	}
4659 	for (i = 0; i < w->used; i++) {
4660 		wid = w->avail_conn[w->selmon[i]];
4661 		audiohd_do_build_monitor_amp(codec, pin, codec->widget[wid]);
4662 	}
4663 
4664 
4665 }	/* audiohd_do_build_monitor_amp() */
4666 
4667 /*
4668  * audiohd_build_monitor_amp()
4669  *
4670  * Description:
4671  *	Search gain control widget for every ostream monitor
4672  */
4673 static void
4674 audiohd_build_monitor_amp(hda_codec_t *codec)
4675 {
4676 	audiohd_path_t		*path;
4677 	audiohd_widget_t	*widget, *w;
4678 	audiohd_state_t		*statep = codec->soft_statep;
4679 	audiohd_pin_t		*pin;
4680 	wid_t			wid, id;
4681 	int			i, j, k;
4682 
4683 	for (i = 0; i < statep->pathnum; i++) {
4684 		path = statep->path[i];
4685 		if (!path || path->codec != codec || path->path_type != PLAY)
4686 			continue;
4687 		for (j = 0; j < path->pin_nums; j++) {
4688 			id = path->pin_wid[j];
4689 			w = codec->widget[id];
4690 			pin = (audiohd_pin_t *)(w->priv);
4691 			for (k = 0; k < path->maxmixer[j]; k++) {
4692 				wid = path->mon_wid[j][k];
4693 				if (!wid)
4694 					continue;
4695 				widget = codec->widget[wid];
4696 				audiohd_do_build_monitor_amp(codec, pin,
4697 				    widget);
4698 			}
4699 		}
4700 	}
4701 }
4702 
4703 /*
4704  * audiohd_find_beep()
4705  * Description:
4706  *      Find a beep for a beep path. Then the play data can be sent to the out
4707  *      put pin through the beep path.
4708  *
4709  * Arguments:
4710  *      hda_codec_t     *codec          where the beep widget exists
4711  *      wid_t           wid             the no. of a widget
4712  *      int             depth           the depth of search
4713  *
4714  * Return:
4715  *      1) wid of Beep widget;
4716  *      2) 0 if no path
4717  */
4718 static wid_t
4719 audiohd_find_beep(hda_codec_t *codec, wid_t wid, int depth)
4720 {
4721 	audiohd_widget_t	*widget = codec->widget[wid];
4722 	wid_t   		wbeep = (uint32_t)(DDI_FAILURE);
4723 	wid_t   		retval;
4724 
4725 	if (depth > AUDIOHD_MAX_DEPTH)
4726 		return (uint32_t)(DDI_FAILURE);
4727 
4728 	if (widget == NULL)
4729 		return (uint32_t)(DDI_FAILURE);
4730 
4731 	switch (widget->type) {
4732 	case WTYPE_BEEP:
4733 		widget->path_flags |= AUDIOHD_PATH_BEEP;
4734 		wbeep = widget->wid_wid;
4735 		break;
4736 
4737 	case WTYPE_AUDIO_MIX:
4738 	case WTYPE_AUDIO_SEL:
4739 		for (int i = 0; i < widget->nconns; i++) {
4740 			retval = audiohd_find_beep(codec,
4741 			    widget->avail_conn[i], depth + 1);
4742 			if (retval != (uint32_t)DDI_FAILURE) {
4743 				if (widget->selconn != AUDIOHD_NULL_CONN)
4744 					continue;
4745 				widget->selconn = i;
4746 				wbeep = retval;
4747 				widget->path_flags |= AUDIOHD_PATH_BEEP;
4748 				return (wbeep);
4749 			}
4750 		}
4751 	default:
4752 		break;
4753 	}
4754 
4755 	return (wbeep);
4756 }       /* audiohd_find_beep() */
4757 
4758 /*
4759  * audiohd_build_beep_path()
4760  *
4761  * Description:
4762  *      Search an beep path for each pin in the codec.
4763  * Arguments:
4764  *      hda_codec_t     *codec          where the beep path exists
4765  */
4766 static void
4767 audiohd_build_beep_path(hda_codec_t *codec)
4768 {
4769 	audiohd_pin_t		*pin;
4770 	audiohd_widget_t	*widget;
4771 	audiohd_path_t		*path;
4772 	wid_t			wid;
4773 	audiohd_state_t		*statep;
4774 	int			i;
4775 	boolean_t		beeppath = B_FALSE;
4776 
4777 	statep = codec->soft_statep;
4778 
4779 	for (pin = codec->first_pin; pin; pin = pin->next) {
4780 		if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
4781 			continue;
4782 		if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
4783 		    AUDIOHD_PIN_NO_CONN)
4784 			continue;
4785 		if ((pin->device != DTYPE_LINEOUT) &&
4786 		    (pin->device != DTYPE_SPEAKER) &&
4787 		    (pin->device != DTYPE_SPDIF_OUT) &&
4788 		    (pin->device != DTYPE_HP_OUT))
4789 			continue;
4790 		widget = codec->widget[pin->wid];
4791 
4792 		widget->inamp_cap = 0;
4793 		for (i = 0; i < widget->nconns; i++) {
4794 			/*
4795 			 * If a beep found, the return value is the wid of the
4796 			 * widget on the path, or the return value is
4797 			 * DDI_FAILURE
4798 			 */
4799 			wid = audiohd_find_beep(codec,
4800 			    widget->avail_conn[i], 0);
4801 			/*
4802 			 * A beep was not found
4803 			 */
4804 			if (wid == (wid_t)DDI_FAILURE)
4805 				continue;
4806 			if (widget->selconn != AUDIOHD_NULL_CONN)
4807 				continue;
4808 			path = (audiohd_path_t *)
4809 			    kmem_zalloc(sizeof (audiohd_path_t),
4810 			    KM_SLEEP);
4811 			path->beep_wid = wid;
4812 			path->pin_wid[0] = widget->wid_wid;
4813 			path->pin_nums = 1;
4814 			path->path_type = BEEP;
4815 			beeppath = 1;
4816 			path->codec = codec;
4817 			path->statep = statep;
4818 			widget->path_flags |= AUDIOHD_PATH_BEEP;
4819 			widget->selconn = i;
4820 			statep->path[statep->pathnum++] = path;
4821 
4822 			break;
4823 		}
4824 	}
4825 
4826 	if (!beeppath) {
4827 		for (int i = 0; i < AUDIOHD_CODEC_MAX; i++) {
4828 			codec = statep->codec[i];
4829 			if (!codec)
4830 				continue;
4831 			for (wid = codec->first_wid; wid <= codec->last_wid;
4832 			    wid++) {
4833 				widget = codec->widget[wid];
4834 				if (widget->type == WTYPE_BEEP) {
4835 					path = (audiohd_path_t *)
4836 					    kmem_zalloc(sizeof (audiohd_path_t),
4837 					    KM_SLEEP);
4838 					path->beep_wid = wid;
4839 					path->pin_nums = 0;
4840 					path->path_type = BEEP;
4841 					beeppath = 1;
4842 					path->codec = codec;
4843 					path->statep = statep;
4844 					widget->path_flags |= AUDIOHD_PATH_BEEP;
4845 					statep->path[statep->pathnum++] = path;
4846 					break;
4847 				}
4848 			}
4849 		}
4850 	}
4851 }       /* audiohd_build_beep_path() */
4852 
4853 /*
4854  * audiohd_build_beep_amp
4855  *
4856  * Description:
4857  *      Find the gain control and mute control widget
4858  */
4859 static void
4860 audiohd_build_beep_amp(hda_codec_t *codec)
4861 {
4862 	audiohd_path_t		*path;
4863 	audiohd_widget_t	*widget, *wpin, *wbeep;
4864 	wid_t			wid;
4865 	int			i, j;
4866 	uint32_t		gain;
4867 
4868 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
4869 		path = codec->soft_statep->path[i];
4870 		if (path == NULL || path->path_type != BEEP ||
4871 		    path->codec != codec)
4872 			continue;
4873 		if (path->pin_nums == 0) {
4874 			path->mute_wid = path->beep_wid;
4875 			path->mute_dir = AUDIOHDC_AMP_SET_OUTPUT;
4876 			wbeep = codec->widget[path->beep_wid];
4877 			gain = (wbeep->outamp_cap &
4878 			    AUDIOHDC_AMP_CAP_STEP_NUMS);
4879 			if (gain) {
4880 				path->gain_dir = AUDIOHDC_AMP_SET_OUTPUT;
4881 				path->gain_bits = gain;
4882 				path->gain_wid = path->beep_wid;
4883 			}
4884 			path->gain_bits >>= AUDIOHD_GAIN_OFF;
4885 			break;
4886 		}
4887 		for (j = 0; j < path->pin_nums; j++) {
4888 			wid = path->pin_wid[j];
4889 			wpin = codec->widget[wid];
4890 			wbeep = codec->widget[path->beep_wid];
4891 
4892 			widget = wpin;
4893 			while (widget) {
4894 				if (widget->out_weight == 0 &&
4895 				    widget->outamp_cap &
4896 				    AUDIOHDC_AMP_CAP_MUTE_CAP) {
4897 					path->mute_wid = widget->wid_wid;
4898 					path->mute_dir =
4899 					    AUDIOHDC_AMP_SET_OUTPUT;
4900 					break;
4901 				}
4902 				if (widget->selconn == AUDIOHD_NULL_CONN)
4903 					break;
4904 				wid = widget->avail_conn[widget->selconn];
4905 				widget = codec->widget[wid];
4906 			}
4907 
4908 			gain = 0;
4909 			widget = wpin;
4910 			while (widget) {
4911 				if (widget->out_weight == 0 &&
4912 				    widget->outamp_cap &
4913 				    AUDIOHDC_AMP_CAP_STEP_NUMS) {
4914 					gain = (widget->outamp_cap &
4915 					    AUDIOHDC_AMP_CAP_STEP_NUMS);
4916 					if (gain && gain > path->gain_bits) {
4917 						path->gain_dir =
4918 						    AUDIOHDC_AMP_SET_OUTPUT;
4919 						path->gain_bits = gain;
4920 						path->gain_wid =
4921 						    widget->wid_wid;
4922 					}
4923 				}
4924 				if (widget->selconn == AUDIOHD_NULL_CONN)
4925 					break;
4926 				wid = widget->avail_conn[widget->selconn];
4927 				widget = codec->widget[wid];
4928 			}
4929 			path->gain_bits >>= AUDIOHD_GAIN_OFF;
4930 		}
4931 	}
4932 }       /* audiohd_build_beep_amp */
4933 
4934 /*
4935  * audiohd_finish_beep_path()
4936  *
4937  * Description:
4938  *      Enable the widgets on the beep path
4939  */
4940 static void
4941 audiohd_finish_beep_path(hda_codec_t *codec)
4942 {
4943 	audiohd_state_t		*statep = codec->soft_statep;
4944 	audiohd_path_t		*path;
4945 	audiohd_widget_t	*widget;
4946 	uint_t			caddr = codec->index;
4947 	wid_t			wid;
4948 	int			i, j;
4949 
4950 	for (i = 0; i < codec->soft_statep->pathnum; i++) {
4951 		path = codec->soft_statep->path[i];
4952 		if (!path || path->path_type != BEEP || path->codec != codec)
4953 			continue;
4954 		for (j = 0; j < path->pin_nums; j++) {
4955 			wid = path->pin_wid[j];
4956 			widget = codec->widget[wid];
4957 
4958 			(void) audioha_codec_verb_get(statep, caddr, wid,
4959 			    AUDIOHDC_VERB_SET_CONN_SEL, widget->selconn);
4960 
4961 			wid = widget->avail_conn[widget->selconn];
4962 			widget = codec->widget[wid];
4963 
4964 			while (widget) {
4965 				/*
4966 				 * Set all amplifiers in this path to
4967 				 * the maximum
4968 				 * volume and unmute them.
4969 				 */
4970 				if (widget->out_weight != 0)
4971 					continue;
4972 				if (widget->outamp_cap) {
4973 					(void) audioha_codec_4bit_verb_get(
4974 					    statep,
4975 					    caddr,
4976 					    wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4977 					    AUDIOHDC_AMP_SET_LR_OUTPUT |
4978 					    AUDIOHDC_GAIN_MAX);
4979 					}
4980 				if (widget->inamp_cap) {
4981 					(void) audioha_codec_4bit_verb_get(
4982 					    statep,
4983 					    caddr,
4984 					    wid, AUDIOHDC_VERB_SET_AMP_MUTE,
4985 					    AUDIOHDC_AMP_SET_LR_INPUT |
4986 					    AUDIOHDC_GAIN_MAX |
4987 					    (widget->selconn <<
4988 					    AUDIOHDC_AMP_SET_INDEX_OFFSET));
4989 				}
4990 
4991 				if (widget->selconn == AUDIOHD_NULL_CONN)
4992 					break;
4993 				/*
4994 				 * Accoding to HD spec, mixer doesn't support
4995 				 * "select connection"
4996 				 */
4997 				if ((widget->type != WTYPE_AUDIO_MIX) &&
4998 				    (widget->nconns > 1))
4999 					(void) audioha_codec_verb_get(statep,
5000 					    caddr,
5001 					    wid,
5002 					    AUDIOHDC_VERB_SET_CONN_SEL,
5003 					    widget->selconn);
5004 
5005 				wid = widget->avail_conn[widget->selconn];
5006 				widget = codec->widget[wid];
5007 			}
5008 		}
5009 	}
5010 }       /* audiohd_finish_beep_path */
5011 
5012 /*
5013  * audiohd_build_path()
5014  *
5015  * Description:
5016  *	Here we build the output, input, monitor path.
5017  *	And also enable the path in default.
5018  *	Search for the gain and mute control for the path
5019  */
5020 static void
5021 audiohd_build_path(audiohd_state_t *statep)
5022 {
5023 	int		i;
5024 
5025 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5026 		if (statep->codec[i]) {
5027 			audiohd_build_output_path(statep->codec[i]);
5028 			audiohd_build_output_amp(statep->codec[i]);
5029 			audiohd_finish_output_path(statep->codec[i]);
5030 
5031 			audiohd_build_input_path(statep->codec[i]);
5032 			audiohd_build_input_amp(statep->codec[i]);
5033 			audiohd_finish_input_path(statep->codec[i]);
5034 
5035 			audiohd_build_monitor_path(statep->codec[i]);
5036 			audiohd_build_monitor_amp(statep->codec[i]);
5037 			audiohd_finish_monitor_path(statep->codec[i]);
5038 
5039 			audiohd_build_beep_path(statep->codec[i]);
5040 			audiohd_build_beep_amp(statep->codec[i]);
5041 			audiohd_finish_beep_path(statep->codec[i]);
5042 		}
5043 	}
5044 }	/* audiohd_build_path */
5045 
5046 /*
5047  * audiohd_allocate_port()
5048  */
5049 static int
5050 audiohd_allocate_port(audiohd_state_t *statep)
5051 {
5052 	int			i, j;
5053 	audiohd_port_t		*port;
5054 	int			dir;
5055 	unsigned		caps;
5056 	char			*prop;
5057 	int			rc;
5058 	audio_dev_t		*adev;
5059 	dev_info_t		*dip;
5060 	ddi_dma_cookie_t	cookie;
5061 	uint_t			count;
5062 	uint64_t		buf_phys_addr;
5063 	sd_bdle_t		*entry;
5064 	uint16_t		gcap;
5065 	size_t			real_size;
5066 
5067 	adev = statep->adev;
5068 	dip = statep->hda_dip;
5069 
5070 	ddi_dma_attr_t	dma_attr = {
5071 		DMA_ATTR_V0,		/* version */
5072 		0,			/* addr_lo */
5073 		0xffffffffffffffffULL,	/* addr_hi */
5074 		0x00000000ffffffffULL,	/* count_max */
5075 		128,			/* 128-byte alignment as HD spec */
5076 		0xfff,			/* burstsize */
5077 		1,			/* minxfer */
5078 		0xffffffff,		/* maxxfer */
5079 		0xffffffff,		/* seg */
5080 		1,			/* sgllen */
5081 		1,			/* granular */
5082 		0			/* flags */
5083 	};
5084 
5085 	gcap = AUDIOHD_REG_GET16(AUDIOHD_REG_GCAP);
5086 	if ((gcap & AUDIOHDR_GCAP_64OK) == 0)
5087 		dma_attr.dma_attr_addr_hi = 0xffffffffUL;
5088 
5089 	for (i = 0; i < PORT_MAX; i++) {
5090 		port = kmem_zalloc(sizeof (*port), KM_SLEEP);
5091 		port->started = B_FALSE;
5092 		port->triggered = B_FALSE;
5093 		statep->port[i] = port;
5094 		port->statep = statep;
5095 		switch (i) {
5096 		case PORT_ADC:
5097 			prop = "record-interrupts";
5098 			dir = DDI_DMA_READ | DDI_DMA_CONSISTENT;
5099 			caps = ENGINE_INPUT_CAP;
5100 			port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
5101 			port->nchan = statep->rchan;
5102 			port->index = 1;
5103 			port->regoff = AUDIOHD_REG_SD_BASE;
5104 			break;
5105 		case PORT_DAC:
5106 			prop = "play-interrupts";
5107 			dir = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
5108 			caps = ENGINE_OUTPUT_CAP;
5109 			port->sync_dir = DDI_DMA_SYNC_FORDEV;
5110 			port->nchan = statep->pchan;
5111 			port->index = statep->hda_input_streams + 1;
5112 			port->regoff = AUDIOHD_REG_SD_BASE +
5113 			    AUDIOHD_REG_SD_LEN *
5114 			    statep->hda_input_streams;
5115 			break;
5116 		default:
5117 			return (DDI_FAILURE);
5118 		}
5119 
5120 		port->intrs = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
5121 		    DDI_PROP_DONTPASS, prop, AUDIOHD_INTS);
5122 
5123 		/* make sure the values are good */
5124 		if (port->intrs < AUDIOHD_MIN_INTS) {
5125 			audio_dev_warn(adev, "%s too low, %d, resetting to %d",
5126 			    prop, port->intrs, AUDIOHD_INTS);
5127 			port->intrs = AUDIOHD_INTS;
5128 		} else if (port->intrs > AUDIOHD_MAX_INTS) {
5129 			audio_dev_warn(adev, "%s too high, %d, resetting to %d",
5130 			    prop, port->intrs, AUDIOHD_INTS);
5131 			port->intrs = AUDIOHD_INTS;
5132 		}
5133 
5134 		port->format = AUDIOHD_FMT_PCM;
5135 		port->fragfr = 48000 / port->intrs;
5136 		port->fragfr = (port->fragfr + AUDIOHD_FRAGFR_ALIGN - 1) & ~
5137 		    (AUDIOHD_FRAGFR_ALIGN - 1);
5138 		port->samp_size = port->fragfr * port->nchan * 2;
5139 		port->samp_size = (port->samp_size +
5140 		    AUDIOHD_BDLE_BUF_ALIGN - 1) & ~
5141 		    (AUDIOHD_BDLE_BUF_ALIGN - 1);
5142 
5143 		/* allocate dma handle */
5144 		rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP,
5145 		    NULL, &port->samp_dmah);
5146 		if (rc != DDI_SUCCESS) {
5147 			audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d",
5148 			    rc);
5149 			return (DDI_FAILURE);
5150 		}
5151 		/* allocate DMA buffer */
5152 		rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size *
5153 		    AUDIOHD_BDLE_NUMS,
5154 		    &hda_dev_accattr,
5155 		    DDI_DMA_CONSISTENT,
5156 		    DDI_DMA_SLEEP, NULL, &port->samp_kaddr,
5157 		    &real_size, &port->samp_acch);
5158 		if (rc == DDI_FAILURE) {
5159 			audio_dev_warn(adev, "dma_mem_alloc failed");
5160 			return (DDI_FAILURE);
5161 		}
5162 
5163 		/* bind DMA buffer */
5164 		rc = ddi_dma_addr_bind_handle(port->samp_dmah, NULL,
5165 		    port->samp_kaddr, real_size, dir,
5166 		    DDI_DMA_SLEEP, NULL, &cookie, &count);
5167 		if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
5168 			audio_dev_warn(adev,
5169 			    "ddi_dma_addr_bind_handle failed: %d", rc);
5170 			return (DDI_FAILURE);
5171 		}
5172 		port->samp_paddr = (uint64_t)cookie.dmac_laddress;
5173 
5174 		/*
5175 		 * now, from here we allocate DMA
5176 		 * memory for buffer descriptor list.
5177 		 * we allocate adjacent DMA memory for all DMA engines.
5178 		 */
5179 		rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP,
5180 		    NULL, &port->bdl_dmah);
5181 		if (rc != DDI_SUCCESS) {
5182 			audio_dev_warn(adev,
5183 			    "ddi_dma_alloc_handle(bdlist) failed");
5184 			return (DDI_FAILURE);
5185 		}
5186 
5187 		/*
5188 		 * we allocate all buffer descriptors lists in continuous
5189 		 * dma memory.
5190 		 */
5191 		port->bdl_size = sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS;
5192 		rc = ddi_dma_mem_alloc(port->bdl_dmah, port->bdl_size,
5193 		    &hda_dev_accattr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
5194 		    &port->bdl_kaddr, &real_size, &port->bdl_acch);
5195 		if (rc != DDI_SUCCESS) {
5196 			audio_dev_warn(adev,
5197 			    "ddi_dma_mem_alloc(bdlist) failed");
5198 			return (DDI_FAILURE);
5199 		}
5200 
5201 		rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL,
5202 		    port->bdl_kaddr,
5203 		    real_size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT,
5204 		    DDI_DMA_SLEEP,
5205 		    NULL, &cookie, &count);
5206 		if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
5207 			audio_dev_warn(adev, "addr_bind_handle failed");
5208 			return (DDI_FAILURE);
5209 		}
5210 		port->bdl_paddr = (uint64_t)cookie.dmac_laddress;
5211 
5212 		entry = (sd_bdle_t *)port->bdl_kaddr;
5213 		buf_phys_addr = port->samp_paddr;
5214 
5215 		for (j = 0; j < AUDIOHD_BDLE_NUMS; j++) {
5216 			entry->sbde_addr = buf_phys_addr;
5217 			entry->sbde_len = port->samp_size;
5218 			entry->sbde_ioc = 1;
5219 			buf_phys_addr += port->samp_size;
5220 			entry++;
5221 		}
5222 		(void) ddi_dma_sync(port->bdl_dmah, 0, sizeof (sd_bdle_t) *
5223 		    AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV);
5224 		port->curpos = 0;
5225 
5226 		port->engine = audio_engine_alloc(&audiohd_engine_ops, caps);
5227 		if (port->engine == NULL) {
5228 			return (DDI_FAILURE);
5229 		}
5230 
5231 		audio_engine_set_private(port->engine, port);
5232 		audio_dev_add_engine(adev, port->engine);
5233 	}
5234 
5235 	return (DDI_SUCCESS);
5236 }
5237 
5238 static void
5239 audiohd_free_port(audiohd_state_t *statep)
5240 {
5241 	int			i;
5242 	audiohd_port_t		*port;
5243 
5244 	if (statep == NULL) {
5245 		return;
5246 	}
5247 	for (i = 0; i < PORT_MAX; i++) {
5248 		port = statep->port[i];
5249 		if (port == NULL)
5250 			continue;
5251 		if (port->engine) {
5252 			audio_dev_remove_engine(statep->adev,
5253 			    port->engine);
5254 			audio_engine_free(port->engine);
5255 		}
5256 		if (port->samp_dmah) {
5257 			(void) ddi_dma_unbind_handle(port->samp_dmah);
5258 		}
5259 		if (port->samp_acch) {
5260 			ddi_dma_mem_free(&port->samp_acch);
5261 		}
5262 		if (port->samp_dmah) {
5263 			ddi_dma_free_handle(&port->samp_dmah);
5264 		}
5265 		if (port->bdl_dmah) {
5266 			(void) ddi_dma_unbind_handle(port->bdl_dmah);
5267 		}
5268 		if (port->bdl_acch) {
5269 			ddi_dma_mem_free(&port->bdl_acch);
5270 		}
5271 		if (port->bdl_dmah) {
5272 			ddi_dma_free_handle(&port->bdl_dmah);
5273 		}
5274 
5275 		kmem_free(port, sizeof (audiohd_port_t));
5276 	}
5277 }
5278 
5279 /*
5280  * audiohd_change_widget_power_state(audiohd_state_t *statep, int off)
5281  * Description:
5282  * 	This routine is used to change the widget power betwen D0 and D2.
5283  * 	D0 is fully on; D2 allows the lowest possible power consuming state
5284  * 	from which it can return to the fully on state: D0.
5285  */
5286 static void
5287 audiohd_change_widget_power_state(audiohd_state_t *statep, int off)
5288 {
5289 	int			i;
5290 	wid_t			wid;
5291 	hda_codec_t		*codec;
5292 	audiohd_widget_t	*widget;
5293 
5294 	/* Change power to D2 */
5295 	if (off) {
5296 		for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5297 			codec = statep->codec[i];
5298 			if (!codec)
5299 				continue;
5300 			for (wid = codec->first_wid; wid <= codec->last_wid;
5301 			    wid++) {
5302 				widget = codec->widget[wid];
5303 				if (widget->widget_cap &
5304 				    AUDIOHD_WIDCAP_PWRCTRL) {
5305 					(void) audioha_codec_verb_get(statep,
5306 					    codec->index, wid,
5307 					    AUDIOHDC_VERB_SET_POWER_STATE,
5308 					    AUDIOHD_PW_D2);
5309 				}
5310 			}
5311 		}
5312 	/* Change power to D0 */
5313 	} else {
5314 		for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5315 			codec = statep->codec[i];
5316 			if (!codec)
5317 				continue;
5318 			for (wid = codec->first_wid; wid <= codec->last_wid;
5319 			    wid++) {
5320 				widget = codec->widget[wid];
5321 				if (widget->widget_cap &
5322 				    AUDIOHD_WIDCAP_PWRCTRL) {
5323 					(void) audioha_codec_verb_get(statep,
5324 					    codec->index, wid,
5325 					    AUDIOHDC_VERB_SET_POWER_STATE,
5326 					    AUDIOHD_PW_D0);
5327 				}
5328 			}
5329 		}
5330 	}
5331 }
5332 /*
5333  * audiohd_restore_path()
5334  * Description:
5335  * 	This routine is used to restore the path on the codec.
5336  */
5337 static void
5338 audiohd_restore_path(audiohd_state_t *statep)
5339 {
5340 	int			i;
5341 	hda_codec_t		*codec;
5342 
5343 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5344 		codec = statep->codec[i];
5345 		if (!codec)
5346 			continue;
5347 		audiohd_finish_output_path(statep->codec[i]);
5348 		audiohd_finish_input_path(statep->codec[i]);
5349 		audiohd_finish_monitor_path(statep->codec[i]);
5350 	}
5351 }
5352 
5353 /*
5354  * restore_play_and_record()
5355  */
5356 static void
5357 audiohd_restore_play_and_record(audiohd_state_t *statep)
5358 {
5359 	int		i;
5360 	audiohd_port_t	*port;
5361 
5362 	mutex_enter(&statep->hda_mutex);
5363 	for (i = 0; i < PORT_MAX; i++) {
5364 		port = statep->port[i];
5365 		if (port == NULL)
5366 			continue;
5367 		if (port != NULL)
5368 			audio_engine_reset(port->engine);
5369 		if (port->triggered) {
5370 			(void) audiohd_reset_port(port);
5371 			audiohd_start_port(port);
5372 		} else {
5373 			audiohd_stop_port(port);
5374 
5375 		}
5376 	}
5377 	mutex_exit(&statep->hda_mutex);
5378 }
5379 /*
5380  * audiohd_reset_pins_ur_cap()
5381  * Description:
5382  * 	Enable the unsolicited response of the pins which have the unsolicited
5383  * 	response capability
5384  */
5385 static void
5386 audiohd_reset_pins_ur_cap(audiohd_state_t *statep)
5387 {
5388 	hda_codec_t		*codec;
5389 	audiohd_pin_t		*pin;
5390 	audiohd_widget_t	*widget;
5391 	uint32_t		urctrl;
5392 	int			i;
5393 
5394 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5395 		codec = statep->codec[i];
5396 		if (!codec)
5397 			continue;
5398 		pin = codec->first_pin;
5399 		while (pin) {
5400 			/* enable the unsolicited response of the pin */
5401 			widget = codec->widget[pin->wid];
5402 			if ((widget->widget_cap &
5403 			    (AUDIOHD_URCAP_MASK) &&
5404 			    (pin->cap & AUDIOHD_DTCCAP_MASK)) &&
5405 			    ((pin->device == DTYPE_LINEOUT) ||
5406 			    (pin->device == DTYPE_SPDIF_OUT) ||
5407 			    (pin->device == DTYPE_HP_OUT) ||
5408 			    (pin->device == DTYPE_MIC_IN))) {
5409 				urctrl = (uint8_t)(1 <<
5410 				    (AUDIOHD_UR_ENABLE_OFF - 1));
5411 				urctrl |= (pin->wid & AUDIOHD_UR_TAG_MASK);
5412 				(void) audioha_codec_verb_get(statep,
5413 				    codec->index,
5414 				    pin->wid,
5415 				    AUDIOHDC_VERB_SET_URCTRL, urctrl);
5416 			}
5417 			pin = pin->next;
5418 		}
5419 	}
5420 }
5421 static void
5422 audiohd_restore_codec_gpio(audiohd_state_t *statep)
5423 {
5424 	int		i;
5425 	wid_t		wid;
5426 	hda_codec_t	*codec;
5427 
5428 	for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5429 		codec = statep->codec[i];
5430 		if (codec == NULL)
5431 			continue;
5432 		wid = codec->wid_afg;
5433 
5434 		/* power-up audio function group */
5435 		(void) audioha_codec_verb_get(statep, i, wid,
5436 		    AUDIOHDC_VERB_SET_POWER_STATE, 0);
5437 		/* work around for Sony VAIO laptop with specific codec */
5438 		if ((codec->vid != AUDIOHD_CODECID_SONY1) &&
5439 		    (codec->vid != AUDIOHD_CODECID_SONY2)) {
5440 			/*
5441 			 * GPIO controls which are laptop specific workarounds
5442 			 * and might be changed. Some laptops use GPIO,
5443 			 * so we need to enable and set the GPIO correctly.
5444 			 */
5445 			(void) audioha_codec_verb_get(statep, i, wid,
5446 			    AUDIOHDC_VERB_SET_GPIO_MASK, AUDIOHDC_GPIO_ENABLE);
5447 			(void) audioha_codec_verb_get(statep, i, wid,
5448 			    AUDIOHDC_VERB_SET_GPIO_DIREC, AUDIOHDC_GPIO_DIRECT);
5449 			(void) audioha_codec_verb_get(statep, i, wid,
5450 			    AUDIOHDC_VERB_SET_GPIO_STCK,
5451 			    AUDIOHDC_GPIO_DATA_CTRL);
5452 			(void) audioha_codec_verb_get(statep, i, wid,
5453 			    AUDIOHDC_VERB_SET_GPIO_DATA,
5454 			    AUDIOHDC_GPIO_STCK_CTRL);
5455 		}
5456 	}
5457 }
5458 /*
5459  * audiohd_resume()
5460  */
5461 static int
5462 audiohd_resume(audiohd_state_t *statep)
5463 {
5464 	uint8_t		rirbsts;
5465 
5466 	mutex_enter(&statep->hda_mutex);
5467 	statep->suspended = B_FALSE;
5468 	/* Restore the hda state */
5469 	if (audiohd_reinit_hda(statep) == DDI_FAILURE) {
5470 		audio_dev_warn(statep->adev,
5471 		    "hda reinit failed");
5472 		mutex_exit(&statep->hda_mutex);
5473 		return (DDI_SUCCESS);
5474 	}
5475 	/* reset to enable the capability of unsolicited response for pin */
5476 	audiohd_reset_pins_ur_cap(statep);
5477 	/* Enable interrupt */
5478 	AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL,
5479 	    AUDIOHD_INTCTL_BIT_GIE |
5480 	    AUDIOHD_INTCTL_BIT_SIE);
5481 	/* clear the unsolicited response interrupt */
5482 	rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS);
5483 	AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts);
5484 	mutex_exit(&statep->hda_mutex);
5485 
5486 	audiohd_restore_play_and_record(statep);
5487 	audiohd_configure_output(statep);
5488 	audiohd_configure_input(statep);
5489 
5490 	/* set widget power to D0 */
5491 	audiohd_change_widget_power_state(statep, AUDIOHD_PW_ON);
5492 
5493 	return (DDI_SUCCESS);
5494 }	/* audiohd_resume */
5495 
5496 /*
5497  * audiohd_suspend()
5498  */
5499 static int
5500 audiohd_suspend(audiohd_state_t *statep)
5501 {
5502 	mutex_enter(&statep->hda_mutex);
5503 	statep->suspended = B_TRUE;
5504 
5505 	/* set widget power to D2 */
5506 	audiohd_change_widget_power_state(statep, AUDIOHD_PW_OFF);
5507 	/* Disable h/w */
5508 	audiohd_disable_intr(statep);
5509 	audiohd_stop_dma(statep);
5510 	mutex_exit(&statep->hda_mutex);
5511 
5512 	return (DDI_SUCCESS);
5513 }	/* audiohd_suspend */
5514 
5515 /*
5516  * audiohd_disable_pin()
5517  */
5518 static int
5519 audiohd_disable_pin(audiohd_state_t *statep, int caddr, wid_t wid)
5520 {
5521 	AUDIOHD_DISABLE_PIN_OUT(statep, caddr, wid);
5522 	return (DDI_SUCCESS);
5523 }
5524 
5525 /*
5526  * audiohd_enable_pin()
5527  */
5528 static int
5529 audiohd_enable_pin(audiohd_state_t *statep, int caddr, wid_t wid)
5530 {
5531 	AUDIOHD_ENABLE_PIN_OUT(statep, caddr, wid);
5532 	return (DDI_SUCCESS);
5533 }
5534 /*
5535  * audiohd_change_speaker_state()
5536  */
5537 static void
5538 audiohd_change_speaker_state(audiohd_state_t *statep, int on)
5539 {
5540 	audiohd_path_t		*path;
5541 	audiohd_widget_t	*widget;
5542 	audiohd_pin_t		*pin;
5543 	int			i, j;
5544 	wid_t			wid;
5545 
5546 	for (i = 0; i < statep->pathnum; i++) {
5547 		path = statep->path[i];
5548 		if (!path || path->path_type != PLAY)
5549 			continue;
5550 		if (on) {
5551 			for (j = 0; j < path->pin_nums; j++) {
5552 				wid = path->pin_wid[j];
5553 				widget = path->codec->widget[wid];
5554 				pin = (audiohd_pin_t *)widget->priv;
5555 				if (pin->device == DTYPE_SPEAKER) {
5556 					(void) audiohd_enable_pin(
5557 					    statep,
5558 					    path->codec->index,
5559 					    pin->wid);
5560 				}
5561 			}
5562 
5563 		} else {
5564 			for (j = 0; j < path->pin_nums; j++) {
5565 				wid = path->pin_wid[j];
5566 				widget = path->codec->widget[wid];
5567 				pin = (audiohd_pin_t *)widget->priv;
5568 				if (pin->device == DTYPE_SPEAKER) {
5569 					(void) audiohd_disable_pin(
5570 					    statep,
5571 					    path->codec->index,
5572 					    pin->wid);
5573 				}
5574 			}
5575 		}
5576 	}
5577 }
5578 /*
5579  * audiohd_select_mic()
5580  *
5581  * Description:
5582  *	This function is used for the recording path which has a selector
5583  *	as the sumwidget. We select the external MIC if it is plugged into the
5584  *	MIC jack, otherwise the internal integrated MIC is selected.
5585  */
5586 static void
5587 audiohd_select_mic(audiohd_state_t *statep, uint8_t index,
5588 uint8_t id, int select)
5589 {
5590 	hda_codec_t		*codec;
5591 	audiohd_path_t		*path;
5592 	audiohd_widget_t	*widget, *sumwgt;
5593 	audiohd_pin_t		*pin;
5594 	int			i, j;
5595 	wid_t			wid;
5596 
5597 	codec = statep->codec[index];
5598 	if (codec == NULL)
5599 		return;
5600 	for (i = 0; i < statep->pathnum; i++) {
5601 		path = statep->path[i];
5602 		if (path->codec != codec || path->path_type != RECORD)
5603 			continue;
5604 		sumwgt = codec->widget[path->sum_wid];
5605 		if (path && sumwgt &&
5606 		    (sumwgt->type == WTYPE_AUDIO_SEL)) {
5607 			for (j = 0; j < path->pin_nums; j++) {
5608 				wid = path->pin_wid[j];
5609 				widget = codec->widget[wid];
5610 				if (widget == NULL)
5611 					return;
5612 				pin = (audiohd_pin_t *)widget->priv;
5613 				if (select &&
5614 				    pin->device == DTYPE_MIC_IN &&
5615 				    pin->wid == id &&
5616 				    (((pin->config >>
5617 				    AUDIOHD_PIN_CONTP_OFF) &
5618 				    AUDIOHD_PIN_CONTP_MASK) ==
5619 				    AUDIOHD_PIN_CON_JACK)) {
5620 					(void) audioha_codec_verb_get(
5621 					    statep,
5622 					    index,
5623 					    path->sum_wid,
5624 					    AUDIOHDC_VERB_SET_CONN_SEL,
5625 					    path->sum_selconn[j]);
5626 					statep->port[PORT_ADC]->index =
5627 					    path->tag;
5628 					return;
5629 				} else if (!select &&
5630 				    pin->device == DTYPE_MIC_IN &&
5631 				    pin->wid == id &&
5632 				    (((pin->config >>
5633 				    AUDIOHD_PIN_CONTP_OFF) &
5634 				    AUDIOHD_PIN_CONTP_MASK) ==
5635 				    AUDIOHD_PIN_CON_JACK)) {
5636 					(void) audioha_codec_verb_get(
5637 					    statep,
5638 					    index,
5639 					    path->sum_wid,
5640 					    AUDIOHDC_VERB_SET_CONN_SEL,
5641 					    path->sum_selconn[j]);
5642 					statep->port[PORT_ADC]->index =
5643 					    path->tag;
5644 					return;
5645 				}
5646 			}
5647 			if (path == NULL)
5648 				break;
5649 			sumwgt = codec->widget[path->sum_wid];
5650 		}
5651 	}
5652 	/*
5653 	 * If the input istream > 1, we should set the record stream tag
5654 	 * respectively. All the input streams sharing one tag may make the
5655 	 * record sound distorted.
5656 	 */
5657 	if (codec->nistream > 1) {
5658 		for (i = 0; i < statep->pathnum; i++) {
5659 			path = statep->path[i];
5660 			if (!path || path->path_type != RECORD)
5661 				continue;
5662 			for (j = 0; j < path->pin_nums; j++) {
5663 				wid = path->pin_wid[j];
5664 				widget = codec->widget[wid];
5665 				if (widget == NULL)
5666 					return;
5667 				pin = (audiohd_pin_t *)widget->priv;
5668 				if (select &&
5669 				    pin->device == DTYPE_MIC_IN &&
5670 				    pin->wid == id &&
5671 				    (((pin->config >>
5672 				    AUDIOHD_PIN_CONTP_OFF) &
5673 				    AUDIOHD_PIN_CONTP_MASK) ==
5674 				    AUDIOHD_PIN_CON_JACK)) {
5675 					statep->port[PORT_ADC]->index =
5676 					    path->tag;
5677 					return;
5678 				} else if (!select &&
5679 				    pin->device == DTYPE_MIC_IN &&
5680 				    (((pin->config >>
5681 				    AUDIOHD_PIN_CONTP_OFF) &
5682 				    AUDIOHD_PIN_CONTP_MASK) ==
5683 				    AUDIOHD_PIN_CON_FIXED)) {
5684 					statep->port[PORT_ADC]->index =
5685 					    path->tag;
5686 					return;
5687 				}
5688 			}
5689 		}
5690 	}
5691 }
5692 /*
5693  * audiohd_pin_sense()
5694  *
5695  * Description
5696  *
5697  * 	When the earphone is plugged into the jack associtated with the pin
5698  * 	complex, we disable the built in speaker. When the earphone is plugged
5699  * 	out of the jack, we enable the built in speaker.
5700  */
5701 static void
5702 audiohd_pin_sense(audiohd_state_t *statep, uint32_t resp, uint32_t respex)
5703 {
5704 	uint8_t			index;
5705 	uint8_t			id;
5706 	uint32_t		rs;
5707 	audiohd_widget_t	*widget;
5708 	audiohd_pin_t		*pin;
5709 	hda_codec_t		*codec;
5710 
5711 	index = respex & AUDIOHD_RIRB_CODEC_MASK;
5712 	id = resp >> (AUDIOHD_RIRB_WID_OFF - 1);
5713 
5714 	codec = statep->codec[index];
5715 	if (codec == NULL)
5716 		return;
5717 	widget = codec->widget[id];
5718 	if (widget == NULL)
5719 		return;
5720 
5721 	rs = audioha_codec_verb_get(statep, index, id,
5722 	    AUDIOHDC_VERB_GET_PIN_SENSE, 0);
5723 	if (rs >> (AUDIOHD_PIN_PRES_OFF - 1) & 1) {
5724 		/* A MIC is plugged in, we select the MIC as input */
5725 		if ((widget->type == WTYPE_PIN) &&
5726 		    (pin = (audiohd_pin_t *)widget->priv) &&
5727 		    (pin->device == DTYPE_MIC_IN)) {
5728 			audiohd_select_mic(statep, index, id, 1);
5729 			return;
5730 		}
5731 		/* output pin is plugged */
5732 		audiohd_change_speaker_state(statep, AUDIOHD_SP_OFF);
5733 	} else {
5734 		/*
5735 		 * A MIC is unplugged, we select the built in MIC
5736 		 * as input.
5737 		 */
5738 		if ((widget->type == WTYPE_PIN) &&
5739 		    (pin = (audiohd_pin_t *)widget->priv) &&
5740 		    (pin->device == DTYPE_MIC_IN)) {
5741 			audiohd_select_mic(statep, index, id, 0);
5742 			return;
5743 		}
5744 		/* output pin is unplugged */
5745 		audiohd_change_speaker_state(statep, AUDIOHD_SP_ON);
5746 	}
5747 
5748 }
5749 /*
5750  * audiohd_intr()
5751  *
5752  * Description
5753  *
5754  *
5755  * Arguments:
5756  *	caddr_t     arg Pointer to the interrupting device's state
5757  *	            structure
5758  *
5759  * Returns:
5760  *	DDI_INTR_CLAIMED    Interrupt claimed and processed
5761  *	DDI_INTR_UNCLAIMED  Interrupt not claimed, and thus ignored
5762  */
5763 static uint_t
5764 audiohd_intr(caddr_t arg)
5765 {
5766 	audiohd_state_t	*statep = (audiohd_state_t *)arg;
5767 	uint32_t	status;
5768 	uint32_t	regbase;
5769 	uint32_t	resp, respex;
5770 	uint8_t		sdstatus, rirbsts;
5771 	int		i, ret;
5772 	audio_engine_t	*do_adc = NULL;
5773 	audio_engine_t	*do_dac = NULL;
5774 
5775 
5776 	mutex_enter(&statep->hda_mutex);
5777 	if (statep->suspended) {
5778 		mutex_exit(&statep->hda_mutex);
5779 		return (DDI_INTR_UNCLAIMED);
5780 	}
5781 
5782 	status = AUDIOHD_REG_GET32(AUDIOHD_REG_INTSTS);
5783 	if (status == 0) {
5784 		mutex_exit(&statep->hda_mutex);
5785 		return (DDI_INTR_UNCLAIMED);
5786 	}
5787 	AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, status);
5788 
5789 	/*
5790 	 * unsolicited response from pins, maybe something plugged in or out
5791 	 * of the jack.
5792 	 */
5793 	if (status & AUDIOHD_CIS_MASK) {
5794 		/* clear the unsolicited response interrupt */
5795 		rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS);
5796 		AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts);
5797 		/*
5798 		 * We have to wait and try several times to make sure the
5799 		 * unsolicited response is generated by our pins.
5800 		 * we need to make it work for audiohd spec 0.9, which is
5801 		 * just a draft version and requires more time to wait.
5802 		 */
5803 		for (i = 0; i < AUDIOHD_TEST_TIMES; i++) {
5804 			ret = audiohd_response_from_codec(statep, &resp,
5805 			    &respex);
5806 			if ((ret == DDI_SUCCESS) &&
5807 			    (respex & AUDIOHD_RIRB_UR_MASK)) {
5808 				/*
5809 				 * A pin may generate more than one ur rirb,
5810 				 * we only need handle one of them, and clear
5811 				 * the other ones
5812 				 */
5813 				statep->hda_rirb_rp =
5814 				    AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) &
5815 				    AUDIOHD_RIRB_WPMASK;
5816 				break;
5817 			}
5818 		}
5819 		if ((ret == DDI_SUCCESS) &&
5820 		    (respex & AUDIOHD_RIRB_UR_MASK)) {
5821 			audiohd_pin_sense(statep, resp, respex);
5822 		}
5823 	}
5824 
5825 	/* stream intr */
5826 	for (i = 0; i < statep->hda_streams_nums; i++) {
5827 		if ((status & (1<<i)) == 0)
5828 			continue;
5829 
5830 		regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN * i;
5831 		sdstatus = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_STS);
5832 
5833 		/* clear intrs */
5834 		AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_STS, sdstatus);
5835 		if (i < statep->hda_input_streams)
5836 			do_adc = statep->port[PORT_ADC]->engine;
5837 		else
5838 			do_dac = statep->port[PORT_DAC]->engine;
5839 	}
5840 
5841 	/* update the kernel interrupt statistics */
5842 	if (statep->hda_ksp) {
5843 		((kstat_intr_t *)
5844 		    (statep->hda_ksp->ks_data))->intrs[KSTAT_INTR_HARD]++;
5845 	}
5846 
5847 	mutex_exit(&statep->hda_mutex);
5848 
5849 	if (do_adc)
5850 		audio_engine_produce(do_adc);
5851 	if (do_dac)
5852 		audio_engine_consume(do_dac);
5853 	return (DDI_INTR_CLAIMED);
5854 }	/* audiohd_intr() */
5855 
5856 /*
5857  * audiohd_disable_intr()
5858  *
5859  * Description:
5860  *	Disable all possible interrupts.
5861  */
5862 static void
5863 audiohd_disable_intr(audiohd_state_t *statep)
5864 {
5865 	int		i;
5866 	uint32_t	base;
5867 
5868 	AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 0);
5869 	base = AUDIOHD_REG_SD_BASE;
5870 	for (i = 0; i < statep->hda_streams_nums; i++) {
5871 		AUDIOHD_REG_SET8(base + AUDIOHD_SDREG_OFFSET_STS,
5872 		    AUDIOHDR_SD_STS_INTRS);
5873 		base += AUDIOHD_REG_SD_LEN;
5874 	}
5875 	AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, (uint32_t)(-1));
5876 
5877 }	/* audiohd_disable_intr() */
5878 
5879 
5880 /*
5881  * audiohd_12bit_verb_to_codec()
5882  *
5883  * Description:
5884  *
5885  */
5886 static int
5887 audiohd_12bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr,
5888     uint8_t wid,
5889     uint16_t cmd, uint8_t param)
5890 {
5891 	uint32_t	verb;
5892 	uint16_t	wptr;
5893 	uint16_t	rptr;
5894 
5895 	ASSERT((cmd & AUDIOHDC_12BIT_VERB_MASK) == 0);
5896 
5897 	wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK;
5898 	rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK;
5899 
5900 	wptr++;
5901 	wptr &= AUDIOHD_CMDIO_ENT_MASK;
5902 
5903 	/* overflow */
5904 	if (wptr == rptr) {
5905 		return (DDI_FAILURE);
5906 	}
5907 
5908 	verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF;
5909 	verb |= wid << AUDIOHD_VERB_NID_OFF;
5910 	verb |= cmd << AUDIOHD_VERB_CMD_OFF;
5911 	verb |= param;
5912 
5913 	*((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb;
5914 	(void) ddi_dma_sync(statep->hda_dma_corb.ad_dmahdl, 0,
5915 	    sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV);
5916 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr);
5917 
5918 	return (DDI_SUCCESS);
5919 
5920 }	/* audiohd_12bit_verb_to_codec() */
5921 
5922 /*
5923  * audiohd_4bit_verb_to_codec()
5924  *
5925  * Description:
5926  *
5927  */
5928 static int
5929 audiohd_4bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr,
5930     uint8_t wid,
5931     uint32_t cmd, uint16_t param)
5932 {
5933 	uint32_t	verb;
5934 	uint16_t	wptr;
5935 	uint16_t	rptr;
5936 
5937 	ASSERT((cmd & AUDIOHDC_4BIT_VERB_MASK) == 0);
5938 
5939 	wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK;
5940 	rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK;
5941 
5942 	wptr++;
5943 	wptr &= AUDIOHD_CMDIO_ENT_MASK;
5944 
5945 	/* overflow */
5946 	if (wptr == rptr) {
5947 		return (DDI_FAILURE);
5948 	}
5949 
5950 	verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF;
5951 	verb |= wid << AUDIOHD_VERB_NID_OFF;
5952 	verb |= cmd << AUDIOHD_VERB_CMD16_OFF;
5953 	verb |= param;
5954 
5955 	*((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb;
5956 	AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr);
5957 
5958 	return (DDI_SUCCESS);
5959 
5960 }	/* audiohd_4bit_verb_to_codec() */
5961 
5962 /*
5963  * audiohd_response_from_codec()
5964  *
5965  * Description:
5966  *
5967  */
5968 static int
5969 audiohd_response_from_codec(audiohd_state_t *statep, uint32_t *resp,
5970     uint32_t *respex)
5971 {
5972 	uint16_t	wptr;
5973 	uint16_t	rptr;
5974 	uint32_t	*lp;
5975 
5976 	wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) & 0x00ff;
5977 	rptr = statep->hda_rirb_rp;
5978 
5979 	if (rptr == wptr) {
5980 		return (DDI_FAILURE);
5981 	}
5982 
5983 	rptr++;
5984 	rptr &= AUDIOHD_RING_MAX_SIZE;
5985 
5986 	lp = (uint32_t *)(statep->hda_dma_rirb.ad_vaddr) + (rptr << 1);
5987 	*resp = *(lp);
5988 	*respex = *(lp + 1);
5989 
5990 	statep->hda_rirb_rp = rptr;
5991 
5992 	return (DDI_SUCCESS);
5993 
5994 }	/* audiohd_response_from_codec() */
5995 
5996 
5997 /*
5998  * audioha_codec_verb_get()
5999  */
6000 static uint32_t
6001 audioha_codec_verb_get(void *arg, uint8_t caddr, uint8_t wid,
6002     uint16_t verb,
6003     uint8_t param)
6004 {
6005 	audiohd_state_t	*statep = (audiohd_state_t *)arg;
6006 	uint32_t	resp;
6007 	uint32_t	respex;
6008 	int		ret;
6009 	int		i;
6010 
6011 	ret = audiohd_12bit_verb_to_codec(statep, caddr, wid, verb, param);
6012 	if (ret != DDI_SUCCESS) {
6013 		return (uint32_t)(-1);
6014 	}
6015 
6016 	/*
6017 	 * Empirical testing times. 50 times is enough for audiohd spec 1.0.
6018 	 * But we need to make it work for audiohd spec 0.9, which is just a
6019 	 * draft version and requires more time to wait.
6020 	 */
6021 	for (i = 0; i < 500; i++) {
6022 		ret = audiohd_response_from_codec(statep, &resp, &respex);
6023 		if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) &&
6024 		    ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) &&
6025 		    (ret == DDI_SUCCESS))
6026 			break;
6027 		/* Empirical testing time, which works well */
6028 		drv_usecwait(30);
6029 	}
6030 
6031 	if (ret == DDI_SUCCESS) {
6032 		return (resp);
6033 	}
6034 
6035 	audio_dev_warn(statep->adev, "timeout when get "
6036 	    " response from codec: wid=%d, verb=0x%04x, param=0x%04x",
6037 	    wid, verb, param);
6038 
6039 	return ((uint32_t)(-1));
6040 
6041 }	/* audioha_codec_verb_get() */
6042 
6043 
6044 /*
6045  * audioha_codec_4bit_verb_get()
6046  */
6047 static uint32_t
6048 audioha_codec_4bit_verb_get(void *arg, uint8_t caddr, uint8_t wid,
6049     uint16_t verb, uint16_t param)
6050 {
6051 	audiohd_state_t	*statep = (audiohd_state_t *)arg;
6052 	uint32_t	resp;
6053 	uint32_t	respex;
6054 	int		ret;
6055 	int		i;
6056 
6057 	ret = audiohd_4bit_verb_to_codec(statep, caddr, wid, verb, param);
6058 	if (ret != DDI_SUCCESS) {
6059 		return (uint32_t)(-1);
6060 	}
6061 
6062 	for (i = 0; i < 500; i++) {
6063 		ret = audiohd_response_from_codec(statep, &resp, &respex);
6064 		if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) &&
6065 		    ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) &&
6066 		    (ret == DDI_SUCCESS))
6067 			break;
6068 		/* Empirical testing time, which works well */
6069 		drv_usecwait(30);
6070 	}
6071 
6072 	if (ret == DDI_SUCCESS) {
6073 		return (resp);
6074 	}
6075 
6076 	audio_dev_warn(statep->adev,  "timeout when get "
6077 	    " response from codec: wid=%d, verb=0x%04x, param=0x%04x",
6078 	    wid, verb, param);
6079 
6080 	return ((uint32_t)(-1));
6081 
6082 }	/* audioha_codec_4bit_verb_get() */
6083