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