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