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