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