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