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