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