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