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