]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/hda_codec.c
libarchive: merge from vendor branch
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / hda_codec.c
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 __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
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
466 hda_codec_reset(struct hda_codec_inst *hci)
467 {
468         const 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
501 hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
502 {
503         const struct hda_ops *hops = NULL;
504         struct hda_codec_softc *sc = 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
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
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
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
678 hda_codec_audio_output_do_transfer(void *arg)
679 {
680         const struct hda_ops *hops = NULL;
681         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
682         struct hda_codec_inst *hci = 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
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, &params);
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, &params));
724 }
725
726 static uint32_t
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
739 hda_codec_audio_input_do_transfer(void *arg)
740 {
741         const struct hda_ops *hops = NULL;
742         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
743         struct hda_codec_inst *hci = 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
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, &params);
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, &params));
783 }
784
785 static uint32_t
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 static const 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 HDA_EMUL_SET(hda_codec);
856
857 /*
858  * HDA Audio Context module function definitions
859  */
860
861 static void *
862 hda_audio_ctxt_thr(void *arg)
863 {
864         struct hda_audio_ctxt *actx = arg;
865
866         DPRINTF("Start Thread: %s", actx->name);
867
868         pthread_mutex_lock(&actx->mtx);
869         while (1) {
870                 while (!actx->run)
871                         pthread_cond_wait(&actx->cond, &actx->mtx);
872
873                 actx->do_transfer(actx->priv);
874         }
875         pthread_mutex_unlock(&actx->mtx);
876
877         pthread_exit(NULL);
878         return (NULL);
879 }
880
881 static int
882 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
883     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
884 {
885         int err;
886
887         assert(actx);
888         assert(tname);
889         assert(do_transfer);
890         assert(do_setup);
891         assert(priv);
892
893         memset(actx, 0, sizeof(*actx));
894
895         actx->run = 0;
896         actx->do_transfer = do_transfer;
897         actx->do_setup = do_setup;
898         actx->priv = priv;
899         if (strlen(tname) < sizeof(actx->name))
900                 memcpy(actx->name, tname, strlen(tname) + 1);
901         else
902                 strcpy(actx->name, "unknown");
903
904         err = pthread_mutex_init(&actx->mtx, NULL);
905         assert(!err);
906
907         err = pthread_cond_init(&actx->cond, NULL);
908         assert(!err);
909
910         err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
911         assert(!err);
912
913         pthread_set_name_np(actx->tid, tname);
914
915         actx->started = 1;
916
917         return (0);
918 }
919
920 static int
921 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
922 {
923         int err = 0;
924
925         assert(actx);
926         assert(actx->started);
927
928         /* The stream is supposed to be stopped */
929         if (actx->run)
930                 return (-1);
931
932         pthread_mutex_lock(&actx->mtx);
933         err = (* actx->do_setup)(actx->priv);
934         if (!err) {
935                 actx->run = 1;
936                 pthread_cond_signal(&actx->cond);
937         }
938         pthread_mutex_unlock(&actx->mtx);
939
940         return (err);
941 }
942
943 static int
944 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
945 {
946         actx->run = 0;
947         return (0);
948 }