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