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