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