xref: /illumos-gate/usr/src/cmd/bhyve/hda_codec.c (revision 1e56f352c1c208679012bca47d552e127f5b1072)
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);
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)
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 	sc = calloc(1, sizeof(*sc));
404 	if (!sc)
405 		return (-1);
406 
407 	if (play && rec)
408 		sc->get_parameters = hda_codec_duplex_parameters;
409 	else {
410 		if (play)
411 			sc->get_parameters = hda_codec_output_parameters;
412 		else
413 			sc->get_parameters = hda_codec_input_parameters;
414 	}
415 	sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID;
416 	sc->no_nodes = HDA_CODEC_NODES_COUNT;
417 	sc->conn_list = hda_codec_conn_list;
418 	sc->conf_default = hda_codec_conf_default;
419 	sc->pin_ctrl_default = hda_codec_pin_ctrl_default;
420 	sc->verb_handlers = hda_codec_verb_handlers;
421 	DPRINTF("HDA Codec nodes: %d", sc->no_nodes);
422 
423 	/*
424 	 * Initialize the Audio Output stream
425 	 */
426 	if (play) {
427 		st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
428 
429 		err = hda_audio_ctxt_init(&st->actx, "hda-audio-output",
430 			hda_codec_audio_output_do_transfer,
431 			hda_codec_audio_output_do_setup, sc);
432 		assert(!err);
433 
434 		st->aud = audio_init(play, 1);
435 		if (!st->aud) {
436 			DPRINTF("Fail to init the output audio player");
437 			return (-1);
438 		}
439 	}
440 
441 	/*
442 	 * Initialize the Audio Input stream
443 	 */
444 	if (rec) {
445 		st = &sc->streams[HDA_CODEC_STREAM_INPUT];
446 
447 		err = hda_audio_ctxt_init(&st->actx, "hda-audio-input",
448 			hda_codec_audio_input_do_transfer,
449 			hda_codec_audio_input_do_setup, sc);
450 		assert(!err);
451 
452 		st->aud = audio_init(rec, 0);
453 		if (!st->aud) {
454 			DPRINTF("Fail to init the input audio player");
455 			return (-1);
456 		}
457 	}
458 
459 	sc->hci = hci;
460 	hci->priv = sc;
461 
462 	return (0);
463 }
464 
465 static int
466 hda_codec_reset(struct hda_codec_inst *hci)
467 {
468 	const struct hda_ops *hops = NULL;
469 	struct hda_codec_softc *sc = NULL;
470 	struct hda_codec_stream *st = NULL;
471 	int i;
472 
473 	assert(hci);
474 
475 	hops = hci->hops;
476 	assert(hops);
477 
478 	sc = (struct hda_codec_softc *)hci->priv;
479 	assert(sc);
480 
481 	for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) {
482 		st = &sc->streams[i];
483 		st->left_gain = HDA_CODEC_AMP_NUMSTEPS;
484 		st->right_gain = HDA_CODEC_AMP_NUMSTEPS;
485 		st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
486 		st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
487 	}
488 
489 	DPRINTF("cad: 0x%x", hci->cad);
490 
491 	if (!hops->signal) {
492 		DPRINTF("The controller ops does not implement \
493 			 the signal function");
494 		return (-1);
495 	}
496 
497 	return (hops->signal(hci));
498 }
499 
500 static int
501 hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
502 {
503 	const struct hda_ops *hops = NULL;
504 	struct hda_codec_softc *sc = NULL;
505 	uint8_t cad = 0, nid = 0;
506 	uint16_t verb = 0, payload = 0;
507 	uint32_t res = 0;
508 
509 	/* 4 bits */
510 	cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f;
511 	/* 8 bits */
512 	nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff;
513 
514 	if ((cmd_data & 0x70000) == 0x70000) {
515 		/* 12 bits */
516 		verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff;
517 		/* 8 bits */
518 		payload = cmd_data & 0xff;
519 	} else {
520 		/* 4 bits */
521 		verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f;
522 		/* 16 bits */
523 		payload = cmd_data & 0xffff;
524 	}
525 
526 	assert(cad == hci->cad);
527 	assert(hci);
528 
529 	hops = hci->hops;
530 	assert(hops);
531 
532 	sc = (struct hda_codec_softc *)hci->priv;
533 	assert(sc);
534 
535 	assert(nid < sc->no_nodes);
536 
537 	if (!hops->response) {
538 		DPRINTF("The controller ops does not implement \
539 			 the response function");
540 		return (-1);
541 	}
542 
543 	switch (verb) {
544 	case HDA_CMD_VERB_GET_PARAMETER:
545 		res = sc->get_parameters[nid][payload];
546 		break;
547 	case HDA_CMD_VERB_GET_CONN_LIST_ENTRY:
548 		res = sc->conn_list[nid][0];
549 		break;
550 	case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL:
551 		res = sc->pin_ctrl_default[nid];
552 		break;
553 	case HDA_CMD_VERB_GET_PIN_SENSE:
554 		res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED;
555 		break;
556 	case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT:
557 		res = sc->conf_default[nid];
558 		break;
559 	case HDA_CMD_VERB_GET_SUBSYSTEM_ID:
560 		res = sc->subsystem_id;
561 		break;
562 	default:
563 		assert(sc->verb_handlers);
564 		if (sc->verb_handlers[nid])
565 			res = sc->verb_handlers[nid](sc, verb, payload);
566 		else
567 			DPRINTF("Unknown VERB: 0x%x", verb);
568 		break;
569 	}
570 
571 	DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x",
572 	    cad, nid, verb, payload, res);
573 
574 	return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL));
575 }
576 
577 static int
578 hda_codec_notify(struct hda_codec_inst *hci, uint8_t run,
579     uint8_t stream, uint8_t dir)
580 {
581 	struct hda_codec_softc *sc = NULL;
582 	struct hda_codec_stream *st = NULL;
583 	struct hda_audio_ctxt *actx = NULL;
584 	int i;
585 	int err;
586 
587 	assert(hci);
588 	assert(stream);
589 
590 	sc = (struct hda_codec_softc *)hci->priv;
591 	assert(sc);
592 
593 	i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT;
594 	st = &sc->streams[i];
595 
596 	DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d",
597 	    run, stream, st->stream, dir);
598 
599 	if (stream != st->stream) {
600 		DPRINTF("Stream not found");
601 		return (0);
602 	}
603 
604 	actx = &st->actx;
605 
606 	if (run)
607 		err = hda_audio_ctxt_start(actx);
608 	else
609 		err = hda_audio_ctxt_stop(actx);
610 
611 	return (err);
612 }
613 
614 static int
615 hda_codec_parse_format(uint16_t fmt, struct audio_params *params)
616 {
617 	uint8_t div = 0;
618 
619 	assert(params);
620 
621 	/* Compute the Sample Rate */
622 	params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000;
623 
624 	switch (fmt & HDA_CODEC_FMT_MULT_MASK) {
625 	case HDA_CODEC_FMT_MULT_2:
626 		params->rate *= 2;
627 		break;
628 	case HDA_CODEC_FMT_MULT_3:
629 		params->rate *= 3;
630 		break;
631 	case HDA_CODEC_FMT_MULT_4:
632 		params->rate *= 4;
633 		break;
634 	}
635 
636 	div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK;
637 	params->rate /= (div + 1);
638 
639 	/* Compute the Bits per Sample */
640 	switch (fmt & HDA_CODEC_FMT_BITS_MASK) {
641 	case HDA_CODEC_FMT_BITS_8:
642 		params->format = AFMT_U8;
643 		break;
644 	case HDA_CODEC_FMT_BITS_16:
645 		params->format = AFMT_S16_LE;
646 		break;
647 	case HDA_CODEC_FMT_BITS_24:
648 		params->format = AFMT_S24_LE;
649 		break;
650 	case HDA_CODEC_FMT_BITS_32:
651 		params->format = AFMT_S32_LE;
652 		break;
653 	default:
654 		DPRINTF("Unknown format bits: 0x%x",
655 		    fmt & HDA_CODEC_FMT_BITS_MASK);
656 		return (-1);
657 	}
658 
659 	/* Compute the Number of Channels */
660 	params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1;
661 
662 	return (0);
663 }
664 
665 static uint32_t
666 hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb,
667     uint16_t payload)
668 {
669 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
670 	int res;
671 
672 	res = hda_codec_audio_inout_nid(st, verb, payload);
673 
674 	return (res);
675 }
676 
677 static void
678 hda_codec_audio_output_do_transfer(void *arg)
679 {
680 	const struct hda_ops *hops = NULL;
681 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
682 	struct hda_codec_inst *hci = NULL;
683 	struct hda_codec_stream *st = NULL;
684 	struct audio *aud = NULL;
685 	int err;
686 
687 	hci = sc->hci;
688 	assert(hci);
689 
690 	hops = hci->hops;
691 	assert(hops);
692 
693 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
694 	aud = st->aud;
695 
696 	err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf));
697 	if (err)
698 		return;
699 
700 	err = audio_playback(aud, st->buf, sizeof(st->buf));
701 	assert(!err);
702 }
703 
704 static int
705 hda_codec_audio_output_do_setup(void *arg)
706 {
707 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
708 	struct hda_codec_stream *st = NULL;
709 	struct audio *aud = NULL;
710 	struct audio_params params;
711 	int err;
712 
713 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
714 	aud = st->aud;
715 
716 	err = hda_codec_parse_format(st->fmt, &params);
717 	if (err)
718 		return (-1);
719 
720 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
721 	    params.rate, params.channels, params.format);
722 
723 	return (audio_set_params(aud, &params));
724 }
725 
726 static uint32_t
727 hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb,
728     uint16_t payload)
729 {
730 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT];
731 	int res;
732 
733 	res = hda_codec_audio_inout_nid(st, verb, payload);
734 
735 	return (res);
736 }
737 
738 static void
739 hda_codec_audio_input_do_transfer(void *arg)
740 {
741 	const struct hda_ops *hops = NULL;
742 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
743 	struct hda_codec_inst *hci = NULL;
744 	struct hda_codec_stream *st = NULL;
745 	struct audio *aud = NULL;
746 	int err;
747 
748 	hci = sc->hci;
749 	assert(hci);
750 
751 	hops = hci->hops;
752 	assert(hops);
753 
754 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
755 	aud = st->aud;
756 
757 	err = audio_record(aud, st->buf, sizeof(st->buf));
758 	assert(!err);
759 
760 	hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf));
761 }
762 
763 static int
764 hda_codec_audio_input_do_setup(void *arg)
765 {
766 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
767 	struct hda_codec_stream *st = NULL;
768 	struct audio *aud = NULL;
769 	struct audio_params params;
770 	int err;
771 
772 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
773 	aud = st->aud;
774 
775 	err = hda_codec_parse_format(st->fmt, &params);
776 	if (err)
777 		return (-1);
778 
779 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
780 	    params.rate, params.channels, params.format);
781 
782 	return (audio_set_params(aud, &params));
783 }
784 
785 static uint32_t
786 hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb,
787     uint16_t payload)
788 {
789 	uint32_t res = 0;
790 	uint8_t mute = 0;
791 	uint8_t gain = 0;
792 
793 	DPRINTF("%s verb: 0x%x, payload, 0x%x", st->actx.name, verb, payload);
794 
795 	switch (verb) {
796 	case HDA_CMD_VERB_GET_CONV_FMT:
797 		res = st->fmt;
798 		break;
799 	case HDA_CMD_VERB_SET_CONV_FMT:
800 		st->fmt = payload;
801 		break;
802 	case HDA_CMD_VERB_GET_AMP_GAIN_MUTE:
803 		if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) {
804 			res = st->left_gain | st->left_mute;
805 			DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x", res);
806 		} else {
807 			res = st->right_gain | st->right_mute;
808 			DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x", res);
809 		}
810 		break;
811 	case HDA_CMD_VERB_SET_AMP_GAIN_MUTE:
812 		mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
813 		gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK;
814 
815 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) {
816 			st->left_mute = mute;
817 			st->left_gain = gain;
818 			DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \
819 			    mute: 0x%x gain: 0x%x", mute, gain);
820 		}
821 
822 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) {
823 			st->right_mute = mute;
824 			st->right_gain = gain;
825 			DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \
826 			    mute: 0x%x gain: 0x%x", mute, gain);
827 		}
828 		break;
829 	case HDA_CMD_VERB_GET_CONV_STREAM_CHAN:
830 		res = (st->stream << 4) | st->channel;
831 		break;
832 	case HDA_CMD_VERB_SET_CONV_STREAM_CHAN:
833 		st->channel = payload & 0x0f;
834 		st->stream = (payload >> 4) & 0x0f;
835 		DPRINTF("st->channel: 0x%x st->stream: 0x%x",
836 		    st->channel, st->stream);
837 		if (!st->stream)
838 			hda_audio_ctxt_stop(&st->actx);
839 		break;
840 	default:
841 		DPRINTF("Unknown VERB: 0x%x", verb);
842 		break;
843 	}
844 
845 	return (res);
846 }
847 
848 static const struct hda_codec_class hda_codec = {
849 	.name		= "hda_codec",
850 	.init		= hda_codec_init,
851 	.reset		= hda_codec_reset,
852 	.command	= hda_codec_command,
853 	.notify		= hda_codec_notify,
854 };
855 HDA_EMUL_SET(hda_codec);
856 
857 /*
858  * HDA Audio Context module function definitions
859  */
860 
861 static void *
862 hda_audio_ctxt_thr(void *arg)
863 {
864 	struct hda_audio_ctxt *actx = arg;
865 
866 	DPRINTF("Start Thread: %s", actx->name);
867 
868 	pthread_mutex_lock(&actx->mtx);
869 	while (1) {
870 		while (!actx->run)
871 			pthread_cond_wait(&actx->cond, &actx->mtx);
872 
873 		actx->do_transfer(actx->priv);
874 	}
875 	pthread_mutex_unlock(&actx->mtx);
876 
877 	pthread_exit(NULL);
878 	return (NULL);
879 }
880 
881 static int
882 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
883     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
884 {
885 	int err;
886 
887 	assert(actx);
888 	assert(tname);
889 	assert(do_transfer);
890 	assert(do_setup);
891 	assert(priv);
892 
893 	memset(actx, 0, sizeof(*actx));
894 
895 	actx->run = 0;
896 	actx->do_transfer = do_transfer;
897 	actx->do_setup = do_setup;
898 	actx->priv = priv;
899 	if (strlen(tname) < sizeof(actx->name))
900 		memcpy(actx->name, tname, strlen(tname) + 1);
901 	else
902 		strcpy(actx->name, "unknown");
903 
904 	err = pthread_mutex_init(&actx->mtx, NULL);
905 	assert(!err);
906 
907 	err = pthread_cond_init(&actx->cond, NULL);
908 	assert(!err);
909 
910 	err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
911 	assert(!err);
912 
913 	pthread_set_name_np(actx->tid, tname);
914 
915 	actx->started = 1;
916 
917 	return (0);
918 }
919 
920 static int
921 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
922 {
923 	int err = 0;
924 
925 	assert(actx);
926 	assert(actx->started);
927 
928 	/* The stream is supposed to be stopped */
929 	if (actx->run)
930 		return (-1);
931 
932 	pthread_mutex_lock(&actx->mtx);
933 	err = (* actx->do_setup)(actx->priv);
934 	if (!err) {
935 		actx->run = 1;
936 		pthread_cond_signal(&actx->cond);
937 	}
938 	pthread_mutex_unlock(&actx->mtx);
939 
940 	return (err);
941 }
942 
943 static int
944 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
945 {
946 	actx->run = 0;
947 	return (0);
948 }
949