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, ¶ms);
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, ¶ms));
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, ¶ms);
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, ¶ms));
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