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