xref: /illumos-gate/usr/src/cmd/bhyve/hda_codec.c (revision c94be9439c4f0773ef60e2cec21d548359cfea20)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <pthread.h>
34 #include <pthread_np.h>
35 #include <unistd.h>
36 
37 #include "pci_hda.h"
38 #include "audio.h"
39 
40 /*
41  * HDA Codec defines
42  */
43 #define INTEL_VENDORID				0x8086
44 
45 #define HDA_CODEC_SUBSYSTEM_ID			((INTEL_VENDORID << 16) | 0x01)
46 #define HDA_CODEC_ROOT_NID			0x00
47 #define HDA_CODEC_FG_NID			0x01
48 #define HDA_CODEC_AUDIO_OUTPUT_NID		0x02
49 #define HDA_CODEC_PIN_OUTPUT_NID		0x03
50 #define HDA_CODEC_AUDIO_INPUT_NID		0x04
51 #define HDA_CODEC_PIN_INPUT_NID			0x05
52 
53 #define HDA_CODEC_STREAMS_COUNT			0x02
54 #define HDA_CODEC_STREAM_OUTPUT			0x00
55 #define HDA_CODEC_STREAM_INPUT			0x01
56 
57 #define HDA_CODEC_PARAMS_COUNT			0x14
58 #define HDA_CODEC_CONN_LIST_COUNT		0x01
59 #define HDA_CODEC_RESPONSE_EX_UNSOL		0x10
60 #define HDA_CODEC_RESPONSE_EX_SOL		0x00
61 #define HDA_CODEC_AMP_NUMSTEPS			0x4a
62 
63 #define HDA_CODEC_SUPP_STREAM_FORMATS_PCM				\
64 	(1 << HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT)
65 
66 #define HDA_CODEC_FMT_BASE_MASK			(0x01 << 14)
67 
68 #define HDA_CODEC_FMT_MULT_MASK			(0x07 << 11)
69 #define HDA_CODEC_FMT_MULT_2			(0x01 << 11)
70 #define HDA_CODEC_FMT_MULT_3			(0x02 << 11)
71 #define HDA_CODEC_FMT_MULT_4			(0x03 << 11)
72 
73 #define HDA_CODEC_FMT_DIV_MASK			0x07
74 #define HDA_CODEC_FMT_DIV_SHIFT			8
75 
76 #define HDA_CODEC_FMT_BITS_MASK			(0x07 << 4)
77 #define HDA_CODEC_FMT_BITS_8			(0x00 << 4)
78 #define HDA_CODEC_FMT_BITS_16			(0x01 << 4)
79 #define HDA_CODEC_FMT_BITS_24			(0x03 << 4)
80 #define HDA_CODEC_FMT_BITS_32			(0x04 << 4)
81 
82 #define HDA_CODEC_FMT_CHAN_MASK			(0x0f << 0)
83 
84 #define HDA_CODEC_AUDIO_WCAP_OUTPUT					\
85 	(0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT)
86 #define HDA_CODEC_AUDIO_WCAP_INPUT					\
87 	(0x01 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT)
88 #define HDA_CODEC_AUDIO_WCAP_PIN					\
89 	(0x04 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT)
90 #define HDA_CODEC_AUDIO_WCAP_CONN_LIST					\
91 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT)
92 #define HDA_CODEC_AUDIO_WCAP_FORMAT_OVR					\
93 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT)
94 #define HDA_CODEC_AUDIO_WCAP_AMP_OVR					\
95 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT)
96 #define HDA_CODEC_AUDIO_WCAP_OUT_AMP					\
97 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT)
98 #define HDA_CODEC_AUDIO_WCAP_IN_AMP					\
99 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT)
100 #define HDA_CODEC_AUDIO_WCAP_STEREO					\
101 	(1 << HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT)
102 
103 #define HDA_CODEC_PIN_CAP_OUTPUT					\
104 	(1 << HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT)
105 #define HDA_CODEC_PIN_CAP_INPUT						\
106 	(1 << HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT)
107 #define HDA_CODEC_PIN_CAP_PRESENCE_DETECT				\
108 	(1 << HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT)
109 
110 #define HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP				\
111 	(1 << HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT)
112 #define HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE				\
113 	(0x03 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT)
114 #define HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS				\
115 	(HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT)
116 #define HDA_CODEC_OUTPUT_AMP_CAP_OFFSET					\
117 	(HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT)
118 
119 #define HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE	0x80
120 #define HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK	0x7f
121 
122 #define HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED	(1 << 31)
123 #define HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE				\
124 	(1 << HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT)
125 #define HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE				\
126 	(1 << HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT)
127 
128 #define HDA_CONFIG_DEFAULTCONF_COLOR_BLACK				\
129 	(0x01 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT)
130 #define HDA_CONFIG_DEFAULTCONF_COLOR_RED				\
131 	(0x05 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT)
132 
133 #define HDA_CODEC_BUF_SIZE			HDA_FIFO_SIZE
134 
135 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
136 
137 
138 /*
139  * HDA Audio Context data structures
140  */
141 
142 typedef void (*transfer_func_t)(void *arg);
143 typedef int (*setup_func_t)(void *arg);
144 
145 struct hda_audio_ctxt {
146 	char name[64];
147 	uint8_t run;
148 	uint8_t started;
149 	void *priv;
150 	pthread_t tid;
151 	pthread_mutex_t mtx;
152 	pthread_cond_t cond;
153 	setup_func_t do_setup;
154 	transfer_func_t do_transfer;
155 };
156 
157 /*
158  * HDA Audio Context module function declarations
159  */
160 
161 static void *hda_audio_ctxt_thr(void *arg);
162 static int hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
163     transfer_func_t do_transfer, setup_func_t do_setup, void *priv);
164 static int hda_audio_ctxt_start(struct hda_audio_ctxt *actx);
165 static int hda_audio_ctxt_stop(struct hda_audio_ctxt *actx);
166 
167 /*
168  * HDA Codec data structures
169  */
170 
171 struct hda_codec_softc;
172 
173 typedef uint32_t (*verb_func_t)(struct hda_codec_softc *sc, uint16_t verb,
174 				    uint16_t payload);
175 
176 struct hda_codec_stream {
177 	uint8_t buf[HDA_CODEC_BUF_SIZE];
178 	uint8_t channel;
179 	uint16_t fmt;
180 	uint8_t stream;
181 
182 	uint8_t left_gain;
183 	uint8_t right_gain;
184 	uint8_t left_mute;
185 	uint8_t right_mute;
186 
187 	struct audio *aud;
188 	struct hda_audio_ctxt actx;
189 };
190 
191 struct hda_codec_softc {
192 	uint32_t no_nodes;
193 	uint32_t subsystem_id;
194 	const uint32_t (*get_parameters)[HDA_CODEC_PARAMS_COUNT];
195 	const uint8_t (*conn_list)[HDA_CODEC_CONN_LIST_COUNT];
196 	const uint32_t *conf_default;
197 	const uint8_t *pin_ctrl_default;
198 	const verb_func_t *verb_handlers;
199 
200 	struct hda_codec_inst *hci;
201 	struct hda_codec_stream streams[HDA_CODEC_STREAMS_COUNT];
202 };
203 
204 /*
205  * HDA Codec module function declarations
206  */
207 static int hda_codec_init(struct hda_codec_inst *hci, const char *play,
208     const char *rec, const char *opts);
209 static int hda_codec_reset(struct hda_codec_inst *hci);
210 static int hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data);
211 static int hda_codec_notify(struct hda_codec_inst *hci, uint8_t run,
212     uint8_t stream, uint8_t dir);
213 
214 static int hda_codec_parse_format(uint16_t fmt, struct audio_params *params);
215 
216 static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc,
217     uint16_t verb, uint16_t payload);
218 static void hda_codec_audio_output_do_transfer(void *arg);
219 static int hda_codec_audio_output_do_setup(void *arg);
220 static uint32_t hda_codec_audio_input_nid(struct hda_codec_softc *sc,
221     uint16_t verb, uint16_t payload);
222 static void hda_codec_audio_input_do_transfer(void *arg);
223 static int hda_codec_audio_input_do_setup(void *arg);
224 
225 static uint32_t hda_codec_audio_inout_nid(struct hda_codec_stream *st,
226     uint16_t verb, uint16_t payload);
227 
228 /*
229  * HDA Codec global data
230  */
231 
232 #define HDA_CODEC_ROOT_DESC						\
233 	[HDA_CODEC_ROOT_NID] = {					\
234 		[HDA_PARAM_VENDOR_ID] = INTEL_VENDORID,			\
235 		[HDA_PARAM_REVISION_ID] = 0xffff,			\
236 		/* 1 Subnode, StartNid = 1 */				\
237 		[HDA_PARAM_SUB_NODE_COUNT] = 0x00010001,		\
238 	},								\
239 
240 #define HDA_CODEC_FG_COMMON_DESC					\
241 	[HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO,\
242 	/* B8 - B32, 8.0 - 192.0kHz */					\
243 	[HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff,		\
244 	[HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM,\
245 	[HDA_PARAM_INPUT_AMP_CAP] = 0x00,	/* None */		\
246 	[HDA_PARAM_OUTPUT_AMP_CAP] = 0x00,	/* None */		\
247 	[HDA_PARAM_GPIO_COUNT] = 0x00,					\
248 
249 #define HDA_CODEC_FG_OUTPUT_DESC					\
250 	[HDA_CODEC_FG_NID] = {						\
251 		/* 2 Subnodes, StartNid = 2 */				\
252 		[HDA_PARAM_SUB_NODE_COUNT] = 0x00020002,		\
253 		HDA_CODEC_FG_COMMON_DESC				\
254 	},								\
255 
256 #define HDA_CODEC_FG_INPUT_DESC						\
257 	[HDA_CODEC_FG_NID] = {						\
258 		/* 2 Subnodes, StartNid = 4 */				\
259 		[HDA_PARAM_SUB_NODE_COUNT] = 0x00040002,		\
260 		HDA_CODEC_FG_COMMON_DESC				\
261 	},								\
262 
263 #define HDA_CODEC_FG_DUPLEX_DESC					\
264 	[HDA_CODEC_FG_NID] = {						\
265 		/* 4 Subnodes, StartNid = 2 */				\
266 		[HDA_PARAM_SUB_NODE_COUNT] = 0x00020004,		\
267 		HDA_CODEC_FG_COMMON_DESC				\
268 	},								\
269 
270 #define HDA_CODEC_OUTPUT_DESC						\
271 	[HDA_CODEC_AUDIO_OUTPUT_NID] = {				\
272 		[HDA_PARAM_AUDIO_WIDGET_CAP] = 				\
273 				HDA_CODEC_AUDIO_WCAP_OUTPUT |		\
274 				HDA_CODEC_AUDIO_WCAP_FORMAT_OVR |	\
275 				HDA_CODEC_AUDIO_WCAP_AMP_OVR |		\
276 				HDA_CODEC_AUDIO_WCAP_OUT_AMP |		\
277 				HDA_CODEC_AUDIO_WCAP_STEREO,		\
278 		/* B16, 16.0 - 192.0kHz */				\
279 		[HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc,	\
280 		[HDA_PARAM_SUPP_STREAM_FORMATS] =			\
281 				HDA_CODEC_SUPP_STREAM_FORMATS_PCM,	\
282 		[HDA_PARAM_INPUT_AMP_CAP] = 0x00,	/* None */	\
283 		[HDA_PARAM_CONN_LIST_LENGTH] = 0x00,			\
284 		[HDA_PARAM_OUTPUT_AMP_CAP] =				\
285 				HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP |	\
286 				HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE |	\
287 				HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS |	\
288 				HDA_CODEC_OUTPUT_AMP_CAP_OFFSET,	\
289 	},								\
290 	[HDA_CODEC_PIN_OUTPUT_NID] = {					\
291 		[HDA_PARAM_AUDIO_WIDGET_CAP] =				\
292 				HDA_CODEC_AUDIO_WCAP_PIN |		\
293 				HDA_CODEC_AUDIO_WCAP_CONN_LIST |	\
294 				HDA_CODEC_AUDIO_WCAP_STEREO,		\
295 		[HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_OUTPUT |	\
296 				      HDA_CODEC_PIN_CAP_PRESENCE_DETECT,\
297 		[HDA_PARAM_INPUT_AMP_CAP] = 0x00,	/* None */	\
298 		[HDA_PARAM_CONN_LIST_LENGTH] = 0x01,			\
299 		[HDA_PARAM_OUTPUT_AMP_CAP] = 0x00,	/* None */	\
300 	},								\
301 
302 #define HDA_CODEC_INPUT_DESC						\
303 	[HDA_CODEC_AUDIO_INPUT_NID] = {					\
304 		[HDA_PARAM_AUDIO_WIDGET_CAP] =				\
305 				HDA_CODEC_AUDIO_WCAP_INPUT |		\
306 				HDA_CODEC_AUDIO_WCAP_CONN_LIST |	\
307 				HDA_CODEC_AUDIO_WCAP_FORMAT_OVR |	\
308 				HDA_CODEC_AUDIO_WCAP_AMP_OVR |		\
309 				HDA_CODEC_AUDIO_WCAP_IN_AMP |		\
310 				HDA_CODEC_AUDIO_WCAP_STEREO,		\
311 		/* B16, 16.0 - 192.0kHz */				\
312 		[HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc,	\
313 		[HDA_PARAM_SUPP_STREAM_FORMATS] =			\
314 				HDA_CODEC_SUPP_STREAM_FORMATS_PCM,	\
315 		[HDA_PARAM_OUTPUT_AMP_CAP] = 0x00,	/* None */	\
316 		[HDA_PARAM_CONN_LIST_LENGTH] = 0x01,			\
317 		[HDA_PARAM_INPUT_AMP_CAP] =				\
318 				HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP |	\
319 				HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE |	\
320 				HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS |	\
321 				HDA_CODEC_OUTPUT_AMP_CAP_OFFSET,	\
322 	},								\
323 	[HDA_CODEC_PIN_INPUT_NID] = {					\
324 		[HDA_PARAM_AUDIO_WIDGET_CAP] =				\
325 				HDA_CODEC_AUDIO_WCAP_PIN |		\
326 				HDA_CODEC_AUDIO_WCAP_STEREO,		\
327 		[HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT |		\
328 				HDA_CODEC_PIN_CAP_PRESENCE_DETECT,	\
329 		[HDA_PARAM_INPUT_AMP_CAP] = 0x00,	/* None */	\
330 		[HDA_PARAM_OUTPUT_AMP_CAP] = 0x00,	/* None */	\
331 	},								\
332 
333 static const uint32_t
334 hda_codec_output_parameters[][HDA_CODEC_PARAMS_COUNT] = {
335 	HDA_CODEC_ROOT_DESC
336 	HDA_CODEC_FG_OUTPUT_DESC
337 	HDA_CODEC_OUTPUT_DESC
338 };
339 
340 static const uint32_t
341 hda_codec_input_parameters[][HDA_CODEC_PARAMS_COUNT] = {
342 	HDA_CODEC_ROOT_DESC
343 	HDA_CODEC_FG_INPUT_DESC
344 	HDA_CODEC_INPUT_DESC
345 };
346 
347 static const uint32_t
348 hda_codec_duplex_parameters[][HDA_CODEC_PARAMS_COUNT] = {
349 	HDA_CODEC_ROOT_DESC
350 	HDA_CODEC_FG_DUPLEX_DESC
351 	HDA_CODEC_OUTPUT_DESC
352 	HDA_CODEC_INPUT_DESC
353 };
354 
355 #define HDA_CODEC_NODES_COUNT	(ARRAY_SIZE(hda_codec_duplex_parameters))
356 
357 static const uint8_t
358 hda_codec_conn_list[HDA_CODEC_NODES_COUNT][HDA_CODEC_CONN_LIST_COUNT] = {
359 	[HDA_CODEC_PIN_OUTPUT_NID] = {HDA_CODEC_AUDIO_OUTPUT_NID},
360 	[HDA_CODEC_AUDIO_INPUT_NID] = {HDA_CODEC_PIN_INPUT_NID},
361 };
362 
363 static const uint32_t
364 hda_codec_conf_default[HDA_CODEC_NODES_COUNT] = {
365 	[HDA_CODEC_PIN_OUTPUT_NID] =					\
366 		HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK |
367 		HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
368 		HDA_CONFIG_DEFAULTCONF_COLOR_BLACK |
369 		(0x01 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT),
370 	[HDA_CODEC_PIN_INPUT_NID] = HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK |
371 				    HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN |
372 				    HDA_CONFIG_DEFAULTCONF_COLOR_RED |
373 			(0x02 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT),
374 };
375 
376 static const uint8_t
377 hda_codec_pin_ctrl_default[HDA_CODEC_NODES_COUNT] = {
378 	[HDA_CODEC_PIN_OUTPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE,
379 	[HDA_CODEC_PIN_INPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE,
380 };
381 
382 static const
383 verb_func_t hda_codec_verb_handlers[HDA_CODEC_NODES_COUNT] = {
384 	[HDA_CODEC_AUDIO_OUTPUT_NID] = hda_codec_audio_output_nid,
385 	[HDA_CODEC_AUDIO_INPUT_NID] = hda_codec_audio_input_nid,
386 };
387 
388 /*
389  * HDA Codec module function definitions
390  */
391 
392 static int
393 hda_codec_init(struct hda_codec_inst *hci, const char *play,
394     const char *rec, const char *opts)
395 {
396 	struct hda_codec_softc *sc = NULL;
397 	struct hda_codec_stream *st = NULL;
398 	int err;
399 
400 	if (!(play || rec))
401 		return (-1);
402 
403 	DPRINTF("cad: 0x%x opts: %s", hci->cad, opts);
404 
405 	sc = calloc(1, sizeof(*sc));
406 	if (!sc)
407 		return (-1);
408 
409 	if (play && rec)
410 		sc->get_parameters = hda_codec_duplex_parameters;
411 	else {
412 		if (play)
413 			sc->get_parameters = hda_codec_output_parameters;
414 		else
415 			sc->get_parameters = hda_codec_input_parameters;
416 	}
417 	sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID;
418 	sc->no_nodes = HDA_CODEC_NODES_COUNT;
419 	sc->conn_list = hda_codec_conn_list;
420 	sc->conf_default = hda_codec_conf_default;
421 	sc->pin_ctrl_default = hda_codec_pin_ctrl_default;
422 	sc->verb_handlers = hda_codec_verb_handlers;
423 	DPRINTF("HDA Codec nodes: %d", sc->no_nodes);
424 
425 	/*
426 	 * Initialize the Audio Output stream
427 	 */
428 	if (play) {
429 		st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
430 
431 		err = hda_audio_ctxt_init(&st->actx, "hda-audio-output",
432 			hda_codec_audio_output_do_transfer,
433 			hda_codec_audio_output_do_setup, sc);
434 		assert(!err);
435 
436 		st->aud = audio_init(play, 1);
437 		if (!st->aud) {
438 			DPRINTF("Fail to init the output audio player");
439 			return (-1);
440 		}
441 	}
442 
443 	/*
444 	 * Initialize the Audio Input stream
445 	 */
446 	if (rec) {
447 		st = &sc->streams[HDA_CODEC_STREAM_INPUT];
448 
449 		err = hda_audio_ctxt_init(&st->actx, "hda-audio-input",
450 			hda_codec_audio_input_do_transfer,
451 			hda_codec_audio_input_do_setup, sc);
452 		assert(!err);
453 
454 		st->aud = audio_init(rec, 0);
455 		if (!st->aud) {
456 			DPRINTF("Fail to init the input audio player");
457 			return (-1);
458 		}
459 	}
460 
461 	sc->hci = hci;
462 	hci->priv = sc;
463 
464 	return (0);
465 }
466 
467 static int
468 hda_codec_reset(struct hda_codec_inst *hci)
469 {
470 	struct hda_ops *hops = NULL;
471 	struct hda_codec_softc *sc = NULL;
472 	struct hda_codec_stream *st = NULL;
473 	int i;
474 
475 	assert(hci);
476 
477 	hops = hci->hops;
478 	assert(hops);
479 
480 	sc = (struct hda_codec_softc *)hci->priv;
481 	assert(sc);
482 
483 	for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) {
484 		st = &sc->streams[i];
485 		st->left_gain = HDA_CODEC_AMP_NUMSTEPS;
486 		st->right_gain = HDA_CODEC_AMP_NUMSTEPS;
487 		st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
488 		st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
489 	}
490 
491 	DPRINTF("cad: 0x%x", hci->cad);
492 
493 	if (!hops->signal) {
494 		DPRINTF("The controller ops does not implement \
495 			 the signal function");
496 		return (-1);
497 	}
498 
499 	return (hops->signal(hci));
500 }
501 
502 static int
503 hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
504 {
505 	struct hda_codec_softc *sc = NULL;
506 	struct hda_ops *hops = NULL;
507 	uint8_t cad = 0, nid = 0;
508 	uint16_t verb = 0, payload = 0;
509 	uint32_t res = 0;
510 
511 	/* 4 bits */
512 	cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f;
513 	/* 8 bits */
514 	nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff;
515 
516 	if ((cmd_data & 0x70000) == 0x70000) {
517 		/* 12 bits */
518 		verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff;
519 		/* 8 bits */
520 		payload = cmd_data & 0xff;
521 	} else {
522 		/* 4 bits */
523 		verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f;
524 		/* 16 bits */
525 		payload = cmd_data & 0xffff;
526 	}
527 
528 	assert(cad == hci->cad);
529 	assert(hci);
530 
531 	hops = hci->hops;
532 	assert(hops);
533 
534 	sc = (struct hda_codec_softc *)hci->priv;
535 	assert(sc);
536 
537 	assert(nid < sc->no_nodes);
538 
539 	if (!hops->response) {
540 		DPRINTF("The controller ops does not implement \
541 			 the response function");
542 		return (-1);
543 	}
544 
545 	switch (verb) {
546 	case HDA_CMD_VERB_GET_PARAMETER:
547 		res = sc->get_parameters[nid][payload];
548 		break;
549 	case HDA_CMD_VERB_GET_CONN_LIST_ENTRY:
550 		res = sc->conn_list[nid][0];
551 		break;
552 	case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL:
553 		res = sc->pin_ctrl_default[nid];
554 		break;
555 	case HDA_CMD_VERB_GET_PIN_SENSE:
556 		res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED;
557 		break;
558 	case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT:
559 		res = sc->conf_default[nid];
560 		break;
561 	case HDA_CMD_VERB_GET_SUBSYSTEM_ID:
562 		res = sc->subsystem_id;
563 		break;
564 	default:
565 		assert(sc->verb_handlers);
566 		if (sc->verb_handlers[nid])
567 			res = sc->verb_handlers[nid](sc, verb, payload);
568 		else
569 			DPRINTF("Unknown VERB: 0x%x", verb);
570 		break;
571 	}
572 
573 	DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x",
574 	    cad, nid, verb, payload, res);
575 
576 	return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL));
577 }
578 
579 static int
580 hda_codec_notify(struct hda_codec_inst *hci, uint8_t run,
581     uint8_t stream, uint8_t dir)
582 {
583 	struct hda_codec_softc *sc = NULL;
584 	struct hda_codec_stream *st = NULL;
585 	struct hda_audio_ctxt *actx = NULL;
586 	int i;
587 	int err;
588 
589 	assert(hci);
590 	assert(stream);
591 
592 	sc = (struct hda_codec_softc *)hci->priv;
593 	assert(sc);
594 
595 	i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT;
596 	st = &sc->streams[i];
597 
598 	DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d",
599 	    run, stream, st->stream, dir);
600 
601 	if (stream != st->stream) {
602 		DPRINTF("Stream not found");
603 		return (0);
604 	}
605 
606 	actx = &st->actx;
607 
608 	if (run)
609 		err = hda_audio_ctxt_start(actx);
610 	else
611 		err = hda_audio_ctxt_stop(actx);
612 
613 	return (err);
614 }
615 
616 static int
617 hda_codec_parse_format(uint16_t fmt, struct audio_params *params)
618 {
619 	uint8_t div = 0;
620 
621 	assert(params);
622 
623 	/* Compute the Sample Rate */
624 	params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000;
625 
626 	switch (fmt & HDA_CODEC_FMT_MULT_MASK) {
627 	case HDA_CODEC_FMT_MULT_2:
628 		params->rate *= 2;
629 		break;
630 	case HDA_CODEC_FMT_MULT_3:
631 		params->rate *= 3;
632 		break;
633 	case HDA_CODEC_FMT_MULT_4:
634 		params->rate *= 4;
635 		break;
636 	}
637 
638 	div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK;
639 	params->rate /= (div + 1);
640 
641 	/* Compute the Bits per Sample */
642 	switch (fmt & HDA_CODEC_FMT_BITS_MASK) {
643 	case HDA_CODEC_FMT_BITS_8:
644 		params->format = AFMT_U8;
645 		break;
646 	case HDA_CODEC_FMT_BITS_16:
647 		params->format = AFMT_S16_LE;
648 		break;
649 	case HDA_CODEC_FMT_BITS_24:
650 		params->format = AFMT_S24_LE;
651 		break;
652 	case HDA_CODEC_FMT_BITS_32:
653 		params->format = AFMT_S32_LE;
654 		break;
655 	default:
656 		DPRINTF("Unknown format bits: 0x%x",
657 		    fmt & HDA_CODEC_FMT_BITS_MASK);
658 		return (-1);
659 	}
660 
661 	/* Compute the Number of Channels */
662 	params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1;
663 
664 	return (0);
665 }
666 
667 static uint32_t
668 hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb,
669     uint16_t payload)
670 {
671 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
672 	int res;
673 
674 	res = hda_codec_audio_inout_nid(st, verb, payload);
675 
676 	return (res);
677 }
678 
679 static void
680 hda_codec_audio_output_do_transfer(void *arg)
681 {
682 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
683 	struct hda_codec_inst *hci = NULL;
684 	struct hda_ops *hops = NULL;
685 	struct hda_codec_stream *st = NULL;
686 	struct audio *aud = NULL;
687 	int err;
688 
689 	hci = sc->hci;
690 	assert(hci);
691 
692 	hops = hci->hops;
693 	assert(hops);
694 
695 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
696 	aud = st->aud;
697 
698 	err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf));
699 	if (err)
700 		return;
701 
702 	err = audio_playback(aud, st->buf, sizeof(st->buf));
703 	assert(!err);
704 }
705 
706 static int
707 hda_codec_audio_output_do_setup(void *arg)
708 {
709 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
710 	struct hda_codec_stream *st = NULL;
711 	struct audio *aud = NULL;
712 	struct audio_params params;
713 	int err;
714 
715 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
716 	aud = st->aud;
717 
718 	err = hda_codec_parse_format(st->fmt, &params);
719 	if (err)
720 		return (-1);
721 
722 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
723 	    params.rate, params.channels, params.format);
724 
725 	return (audio_set_params(aud, &params));
726 }
727 
728 static uint32_t
729 hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb,
730     uint16_t payload)
731 {
732 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT];
733 	int res;
734 
735 	res = hda_codec_audio_inout_nid(st, verb, payload);
736 
737 	return (res);
738 }
739 
740 static void
741 hda_codec_audio_input_do_transfer(void *arg)
742 {
743 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
744 	struct hda_codec_inst *hci = NULL;
745 	struct hda_ops *hops = NULL;
746 	struct hda_codec_stream *st = NULL;
747 	struct audio *aud = NULL;
748 	int err;
749 
750 	hci = sc->hci;
751 	assert(hci);
752 
753 	hops = hci->hops;
754 	assert(hops);
755 
756 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
757 	aud = st->aud;
758 
759 	err = audio_record(aud, st->buf, sizeof(st->buf));
760 	assert(!err);
761 
762 	hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf));
763 }
764 
765 static int
766 hda_codec_audio_input_do_setup(void *arg)
767 {
768 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
769 	struct hda_codec_stream *st = NULL;
770 	struct audio *aud = NULL;
771 	struct audio_params params;
772 	int err;
773 
774 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
775 	aud = st->aud;
776 
777 	err = hda_codec_parse_format(st->fmt, &params);
778 	if (err)
779 		return (-1);
780 
781 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
782 	    params.rate, params.channels, params.format);
783 
784 	return (audio_set_params(aud, &params));
785 }
786 
787 static uint32_t
788 hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb,
789     uint16_t payload)
790 {
791 	uint32_t res = 0;
792 	uint8_t mute = 0;
793 	uint8_t gain = 0;
794 
795 	DPRINTF("%s verb: 0x%x, payload, 0x%x", st->actx.name, verb, payload);
796 
797 	switch (verb) {
798 	case HDA_CMD_VERB_GET_CONV_FMT:
799 		res = st->fmt;
800 		break;
801 	case HDA_CMD_VERB_SET_CONV_FMT:
802 		st->fmt = payload;
803 		break;
804 	case HDA_CMD_VERB_GET_AMP_GAIN_MUTE:
805 		if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) {
806 			res = st->left_gain | st->left_mute;
807 			DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x", res);
808 		} else {
809 			res = st->right_gain | st->right_mute;
810 			DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x", res);
811 		}
812 		break;
813 	case HDA_CMD_VERB_SET_AMP_GAIN_MUTE:
814 		mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
815 		gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK;
816 
817 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) {
818 			st->left_mute = mute;
819 			st->left_gain = gain;
820 			DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \
821 			    mute: 0x%x gain: 0x%x", mute, gain);
822 		}
823 
824 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) {
825 			st->right_mute = mute;
826 			st->right_gain = gain;
827 			DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \
828 			    mute: 0x%x gain: 0x%x", mute, gain);
829 		}
830 		break;
831 	case HDA_CMD_VERB_GET_CONV_STREAM_CHAN:
832 		res = (st->stream << 4) | st->channel;
833 		break;
834 	case HDA_CMD_VERB_SET_CONV_STREAM_CHAN:
835 		st->channel = payload & 0x0f;
836 		st->stream = (payload >> 4) & 0x0f;
837 		DPRINTF("st->channel: 0x%x st->stream: 0x%x",
838 		    st->channel, st->stream);
839 		if (!st->stream)
840 			hda_audio_ctxt_stop(&st->actx);
841 		break;
842 	default:
843 		DPRINTF("Unknown VERB: 0x%x", verb);
844 		break;
845 	}
846 
847 	return (res);
848 }
849 
850 struct hda_codec_class hda_codec  = {
851 	.name		= "hda_codec",
852 	.init		= hda_codec_init,
853 	.reset		= hda_codec_reset,
854 	.command	= hda_codec_command,
855 	.notify		= hda_codec_notify,
856 };
857 
858 HDA_EMUL_SET(hda_codec);
859 
860 
861 /*
862  * HDA Audio Context module function definitions
863  */
864 
865 static void *
866 hda_audio_ctxt_thr(void *arg)
867 {
868 	struct hda_audio_ctxt *actx = arg;
869 
870 	DPRINTF("Start Thread: %s", actx->name);
871 
872 	pthread_mutex_lock(&actx->mtx);
873 	while (1) {
874 		while (!actx->run)
875 			pthread_cond_wait(&actx->cond, &actx->mtx);
876 
877 		actx->do_transfer(actx->priv);
878 	}
879 	pthread_mutex_unlock(&actx->mtx);
880 
881 	pthread_exit(NULL);
882 	return (NULL);
883 }
884 
885 static int
886 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
887     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
888 {
889 	int err;
890 
891 	assert(actx);
892 	assert(tname);
893 	assert(do_transfer);
894 	assert(do_setup);
895 	assert(priv);
896 
897 	memset(actx, 0, sizeof(*actx));
898 
899 	actx->run = 0;
900 	actx->do_transfer = do_transfer;
901 	actx->do_setup = do_setup;
902 	actx->priv = priv;
903 	if (strlen(tname) < sizeof(actx->name))
904 		memcpy(actx->name, tname, strlen(tname) + 1);
905 	else
906 		strcpy(actx->name, "unknown");
907 
908 	err = pthread_mutex_init(&actx->mtx, NULL);
909 	assert(!err);
910 
911 	err = pthread_cond_init(&actx->cond, NULL);
912 	assert(!err);
913 
914 	err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
915 	assert(!err);
916 
917 	pthread_set_name_np(actx->tid, tname);
918 
919 	actx->started = 1;
920 
921 	return (0);
922 }
923 
924 static int
925 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
926 {
927 	int err = 0;
928 
929 	assert(actx);
930 	assert(actx->started);
931 
932 	/* The stream is supposed to be stopped */
933 	if (actx->run)
934 		return (-1);
935 
936 	pthread_mutex_lock(&actx->mtx);
937 	err = (* actx->do_setup)(actx->priv);
938 	if (!err) {
939 		actx->run = 1;
940 		pthread_cond_signal(&actx->cond);
941 	}
942 	pthread_mutex_unlock(&actx->mtx);
943 
944 	return (err);
945 }
946 
947 static int
948 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
949 {
950 	actx->run = 0;
951 	return (0);
952 }
953