xref: /freebsd/usr.sbin/bhyve/hda_codec.c (revision e94a1d6a7f2eb932850e1db418bf34d5c6991ce8)
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 #include <sys/cdefs.h>
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(hci);
525 
526 	hops = hci->hops;
527 	assert(hops);
528 
529 	sc = (struct hda_codec_softc *)hci->priv;
530 	assert(sc);
531 
532 	if (cad != hci->cad || nid >= sc->no_nodes) {
533 		DPRINTF("Invalid command data");
534 		return (-1);
535 	}
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 		if (payload < HDA_CODEC_PARAMS_COUNT)
546 			res = sc->get_parameters[nid][payload];
547 		break;
548 	case HDA_CMD_VERB_GET_CONN_LIST_ENTRY:
549 		res = sc->conn_list[nid][0];
550 		break;
551 	case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL:
552 		res = sc->pin_ctrl_default[nid];
553 		break;
554 	case HDA_CMD_VERB_GET_PIN_SENSE:
555 		res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED;
556 		break;
557 	case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT:
558 		res = sc->conf_default[nid];
559 		break;
560 	case HDA_CMD_VERB_GET_SUBSYSTEM_ID:
561 		res = sc->subsystem_id;
562 		break;
563 	default:
564 		assert(sc->verb_handlers);
565 		if (sc->verb_handlers[nid])
566 			res = sc->verb_handlers[nid](sc, verb, payload);
567 		else
568 			DPRINTF("Unknown VERB: 0x%x", verb);
569 		break;
570 	}
571 
572 	DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x",
573 	    cad, nid, verb, payload, res);
574 
575 	return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL));
576 }
577 
578 static int
hda_codec_notify(struct hda_codec_inst * hci,uint8_t run,uint8_t stream,uint8_t dir)579 hda_codec_notify(struct hda_codec_inst *hci, uint8_t run,
580     uint8_t stream, uint8_t dir)
581 {
582 	struct hda_codec_softc *sc = NULL;
583 	struct hda_codec_stream *st = NULL;
584 	struct hda_audio_ctxt *actx = NULL;
585 	int i;
586 	int err;
587 
588 	assert(hci);
589 	assert(stream);
590 
591 	sc = (struct hda_codec_softc *)hci->priv;
592 	assert(sc);
593 
594 	i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT;
595 	st = &sc->streams[i];
596 
597 	DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d",
598 	    run, stream, st->stream, dir);
599 
600 	if (stream != st->stream) {
601 		DPRINTF("Stream not found");
602 		return (0);
603 	}
604 
605 	actx = &st->actx;
606 
607 	if (run)
608 		err = hda_audio_ctxt_start(actx);
609 	else
610 		err = hda_audio_ctxt_stop(actx);
611 
612 	return (err);
613 }
614 
615 static int
hda_codec_parse_format(uint16_t fmt,struct audio_params * params)616 hda_codec_parse_format(uint16_t fmt, struct audio_params *params)
617 {
618 	uint8_t div = 0;
619 
620 	assert(params);
621 
622 	/* Compute the Sample Rate */
623 	params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000;
624 
625 	switch (fmt & HDA_CODEC_FMT_MULT_MASK) {
626 	case HDA_CODEC_FMT_MULT_2:
627 		params->rate *= 2;
628 		break;
629 	case HDA_CODEC_FMT_MULT_3:
630 		params->rate *= 3;
631 		break;
632 	case HDA_CODEC_FMT_MULT_4:
633 		params->rate *= 4;
634 		break;
635 	}
636 
637 	div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK;
638 	params->rate /= (div + 1);
639 
640 	/* Compute the Bits per Sample */
641 	switch (fmt & HDA_CODEC_FMT_BITS_MASK) {
642 	case HDA_CODEC_FMT_BITS_8:
643 		params->format = AFMT_U8;
644 		break;
645 	case HDA_CODEC_FMT_BITS_16:
646 		params->format = AFMT_S16_LE;
647 		break;
648 	case HDA_CODEC_FMT_BITS_24:
649 		params->format = AFMT_S24_LE;
650 		break;
651 	case HDA_CODEC_FMT_BITS_32:
652 		params->format = AFMT_S32_LE;
653 		break;
654 	default:
655 		DPRINTF("Unknown format bits: 0x%x",
656 		    fmt & HDA_CODEC_FMT_BITS_MASK);
657 		return (-1);
658 	}
659 
660 	/* Compute the Number of Channels */
661 	params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1;
662 
663 	return (0);
664 }
665 
666 static uint32_t
hda_codec_audio_output_nid(struct hda_codec_softc * sc,uint16_t verb,uint16_t payload)667 hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb,
668     uint16_t payload)
669 {
670 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
671 	int res;
672 
673 	res = hda_codec_audio_inout_nid(st, verb, payload);
674 
675 	return (res);
676 }
677 
678 static void
hda_codec_audio_output_do_transfer(void * arg)679 hda_codec_audio_output_do_transfer(void *arg)
680 {
681 	const struct hda_ops *hops = NULL;
682 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
683 	struct hda_codec_inst *hci = NULL;
684 	struct hda_codec_stream *st = NULL;
685 	struct audio *aud = NULL;
686 	int err;
687 
688 	hci = sc->hci;
689 	assert(hci);
690 
691 	hops = hci->hops;
692 	assert(hops);
693 
694 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
695 	aud = st->aud;
696 
697 	err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf));
698 	if (err)
699 		return;
700 
701 	err = audio_playback(aud, st->buf, sizeof(st->buf));
702 	assert(!err);
703 }
704 
705 static int
hda_codec_audio_output_do_setup(void * arg)706 hda_codec_audio_output_do_setup(void *arg)
707 {
708 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
709 	struct hda_codec_stream *st = NULL;
710 	struct audio *aud = NULL;
711 	struct audio_params params;
712 	int err;
713 
714 	st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
715 	aud = st->aud;
716 
717 	err = hda_codec_parse_format(st->fmt, &params);
718 	if (err)
719 		return (-1);
720 
721 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
722 	    params.rate, params.channels, params.format);
723 
724 	return (audio_set_params(aud, &params));
725 }
726 
727 static uint32_t
hda_codec_audio_input_nid(struct hda_codec_softc * sc,uint16_t verb,uint16_t payload)728 hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb,
729     uint16_t payload)
730 {
731 	struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT];
732 	int res;
733 
734 	res = hda_codec_audio_inout_nid(st, verb, payload);
735 
736 	return (res);
737 }
738 
739 static void
hda_codec_audio_input_do_transfer(void * arg)740 hda_codec_audio_input_do_transfer(void *arg)
741 {
742 	const struct hda_ops *hops = NULL;
743 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
744 	struct hda_codec_inst *hci = NULL;
745 	struct hda_codec_stream *st = NULL;
746 	struct audio *aud = NULL;
747 	int err;
748 
749 	hci = sc->hci;
750 	assert(hci);
751 
752 	hops = hci->hops;
753 	assert(hops);
754 
755 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
756 	aud = st->aud;
757 
758 	err = audio_record(aud, st->buf, sizeof(st->buf));
759 	assert(!err);
760 
761 	hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf));
762 }
763 
764 static int
hda_codec_audio_input_do_setup(void * arg)765 hda_codec_audio_input_do_setup(void *arg)
766 {
767 	struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
768 	struct hda_codec_stream *st = NULL;
769 	struct audio *aud = NULL;
770 	struct audio_params params;
771 	int err;
772 
773 	st = &sc->streams[HDA_CODEC_STREAM_INPUT];
774 	aud = st->aud;
775 
776 	err = hda_codec_parse_format(st->fmt, &params);
777 	if (err)
778 		return (-1);
779 
780 	DPRINTF("rate: %d, channels: %d, format: 0x%x",
781 	    params.rate, params.channels, params.format);
782 
783 	return (audio_set_params(aud, &params));
784 }
785 
786 static uint32_t
hda_codec_audio_inout_nid(struct hda_codec_stream * st,uint16_t verb,uint16_t payload)787 hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb,
788     uint16_t payload)
789 {
790 	uint32_t res = 0;
791 	uint8_t mute = 0;
792 	uint8_t gain = 0;
793 
794 	DPRINTF("%s verb: 0x%x, payload, 0x%x", st->actx.name, verb, payload);
795 
796 	switch (verb) {
797 	case HDA_CMD_VERB_GET_CONV_FMT:
798 		res = st->fmt;
799 		break;
800 	case HDA_CMD_VERB_SET_CONV_FMT:
801 		st->fmt = payload;
802 		break;
803 	case HDA_CMD_VERB_GET_AMP_GAIN_MUTE:
804 		if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) {
805 			res = st->left_gain | st->left_mute;
806 			DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x", res);
807 		} else {
808 			res = st->right_gain | st->right_mute;
809 			DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x", res);
810 		}
811 		break;
812 	case HDA_CMD_VERB_SET_AMP_GAIN_MUTE:
813 		mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
814 		gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK;
815 
816 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) {
817 			st->left_mute = mute;
818 			st->left_gain = gain;
819 			DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \
820 			    mute: 0x%x gain: 0x%x", mute, gain);
821 		}
822 
823 		if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) {
824 			st->right_mute = mute;
825 			st->right_gain = gain;
826 			DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \
827 			    mute: 0x%x gain: 0x%x", mute, gain);
828 		}
829 		break;
830 	case HDA_CMD_VERB_GET_CONV_STREAM_CHAN:
831 		res = (st->stream << 4) | st->channel;
832 		break;
833 	case HDA_CMD_VERB_SET_CONV_STREAM_CHAN:
834 		st->channel = payload & 0x0f;
835 		st->stream = (payload >> 4) & 0x0f;
836 		DPRINTF("st->channel: 0x%x st->stream: 0x%x",
837 		    st->channel, st->stream);
838 		if (!st->stream)
839 			hda_audio_ctxt_stop(&st->actx);
840 		break;
841 	default:
842 		DPRINTF("Unknown VERB: 0x%x", verb);
843 		break;
844 	}
845 
846 	return (res);
847 }
848 
849 static const struct hda_codec_class hda_codec = {
850 	.name		= "hda_codec",
851 	.init		= hda_codec_init,
852 	.reset		= hda_codec_reset,
853 	.command	= hda_codec_command,
854 	.notify		= hda_codec_notify,
855 };
856 HDA_EMUL_SET(hda_codec);
857 
858 /*
859  * HDA Audio Context module function definitions
860  */
861 
862 static void *
hda_audio_ctxt_thr(void * arg)863 hda_audio_ctxt_thr(void *arg)
864 {
865 	struct hda_audio_ctxt *actx = arg;
866 
867 	DPRINTF("Start Thread: %s", actx->name);
868 
869 	pthread_mutex_lock(&actx->mtx);
870 	while (1) {
871 		while (!actx->run)
872 			pthread_cond_wait(&actx->cond, &actx->mtx);
873 
874 		actx->do_transfer(actx->priv);
875 	}
876 	pthread_mutex_unlock(&actx->mtx);
877 
878 	pthread_exit(NULL);
879 	return (NULL);
880 }
881 
882 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)883 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
884     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
885 {
886 	int err;
887 
888 	assert(actx);
889 	assert(tname);
890 	assert(do_transfer);
891 	assert(do_setup);
892 	assert(priv);
893 
894 	memset(actx, 0, sizeof(*actx));
895 
896 	actx->run = 0;
897 	actx->do_transfer = do_transfer;
898 	actx->do_setup = do_setup;
899 	actx->priv = priv;
900 	if (strlen(tname) < sizeof(actx->name))
901 		memcpy(actx->name, tname, strlen(tname) + 1);
902 	else
903 		strcpy(actx->name, "unknown");
904 
905 	err = pthread_mutex_init(&actx->mtx, NULL);
906 	assert(!err);
907 
908 	err = pthread_cond_init(&actx->cond, NULL);
909 	assert(!err);
910 
911 	err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
912 	assert(!err);
913 
914 	pthread_set_name_np(actx->tid, tname);
915 
916 	actx->started = 1;
917 
918 	return (0);
919 }
920 
921 static int
hda_audio_ctxt_start(struct hda_audio_ctxt * actx)922 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
923 {
924 	int err = 0;
925 
926 	assert(actx);
927 	assert(actx->started);
928 
929 	/* The stream is supposed to be stopped */
930 	if (actx->run)
931 		return (-1);
932 
933 	pthread_mutex_lock(&actx->mtx);
934 	err = (* actx->do_setup)(actx->priv);
935 	if (!err) {
936 		actx->run = 1;
937 		pthread_cond_signal(&actx->cond);
938 	}
939 	pthread_mutex_unlock(&actx->mtx);
940 
941 	return (err);
942 }
943 
944 static int
hda_audio_ctxt_stop(struct hda_audio_ctxt * actx)945 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
946 {
947 	actx->run = 0;
948 	return (0);
949 }
950