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