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