]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/hda_codec.c
Add SPDX tags to bhyve(8) HD Audio device.
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / hda_codec.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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, const char *opts);
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, const char *opts)
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         DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts);
404
405         sc = calloc(1, sizeof(*sc));
406         if (!sc)
407                 return (-1);
408
409         if (play && rec)
410                 sc->get_parameters = hda_codec_duplex_parameters;
411         else {
412                 if (play)
413                         sc->get_parameters = hda_codec_output_parameters;
414                 else
415                         sc->get_parameters = hda_codec_input_parameters;
416         }
417         sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID;
418         sc->no_nodes = HDA_CODEC_NODES_COUNT;
419         sc->conn_list = hda_codec_conn_list;
420         sc->conf_default = hda_codec_conf_default;
421         sc->pin_ctrl_default = hda_codec_pin_ctrl_default;
422         sc->verb_handlers = hda_codec_verb_handlers;
423         DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes);
424
425         /*
426          * Initialize the Audio Output stream
427          */
428         if (play) {
429                 st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
430
431                 err = hda_audio_ctxt_init(&st->actx, "hda-audio-output",
432                         hda_codec_audio_output_do_transfer,
433                         hda_codec_audio_output_do_setup, sc);
434                 assert(!err);
435
436                 st->aud = audio_init(play, 1);
437                 if (!st->aud) {
438                         DPRINTF("Fail to init the output audio player\n");
439                         return (-1);
440                 }
441         }
442
443         /*
444          * Initialize the Audio Input stream
445          */
446         if (rec) {
447                 st = &sc->streams[HDA_CODEC_STREAM_INPUT];
448
449                 err = hda_audio_ctxt_init(&st->actx, "hda-audio-input",
450                         hda_codec_audio_input_do_transfer,
451                         hda_codec_audio_input_do_setup, sc);
452                 assert(!err);
453
454                 st->aud = audio_init(rec, 0);
455                 if (!st->aud) {
456                         DPRINTF("Fail to init the input audio player\n");
457                         return (-1);
458                 }
459         }
460
461         sc->hci = hci;
462         hci->priv = sc;
463
464         return (0);
465 }
466
467 static int
468 hda_codec_reset(struct hda_codec_inst *hci)
469 {
470         struct hda_ops *hops = NULL;
471         struct hda_codec_softc *sc = NULL;
472         struct hda_codec_stream *st = NULL;
473         int i;
474
475         assert(hci);
476
477         hops = hci->hops;
478         assert(hops);
479
480         sc = (struct hda_codec_softc *)hci->priv;
481         assert(sc);
482
483         for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) {
484                 st = &sc->streams[i];
485                 st->left_gain = HDA_CODEC_AMP_NUMSTEPS;
486                 st->right_gain = HDA_CODEC_AMP_NUMSTEPS;
487                 st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
488                 st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
489         }
490
491         DPRINTF("cad: 0x%x\n", hci->cad);
492
493         if (!hops->signal) {
494                 DPRINTF("The controller ops does not implement \
495                          the signal function\n");
496                 return (-1);
497         }
498
499         return (hops->signal(hci));
500 }
501
502 static int
503 hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
504 {
505         struct hda_codec_softc *sc = NULL;
506         struct hda_ops *hops = NULL;
507         uint8_t cad = 0, nid = 0;
508         uint16_t verb = 0, payload = 0;
509         uint32_t res = 0;
510
511         /* 4 bits */
512         cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f;
513         /* 8 bits */
514         nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff;
515
516         if ((cmd_data & 0x70000) == 0x70000) {
517                 /* 12 bits */
518                 verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff;
519                 /* 8 bits */
520                 payload = cmd_data & 0xff;
521         } else {
522                 /* 4 bits */
523                 verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f;
524                 /* 16 bits */
525                 payload = cmd_data & 0xffff;
526         }
527
528         assert(cad == hci->cad);
529         assert(hci);
530
531         hops = hci->hops;
532         assert(hops);
533
534         sc = (struct hda_codec_softc *)hci->priv;
535         assert(sc);
536
537         assert(nid < sc->no_nodes);
538
539         if (!hops->response) {
540                 DPRINTF("The controller ops does not implement \
541                          the response function\n");
542                 return (-1);
543         }
544
545         switch (verb) {
546         case HDA_CMD_VERB_GET_PARAMETER:
547                 res = sc->get_parameters[nid][payload];
548                 break;
549         case HDA_CMD_VERB_GET_CONN_LIST_ENTRY:
550                 res = sc->conn_list[nid][0];
551                 break;
552         case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL:
553                 res = sc->pin_ctrl_default[nid];
554                 break;
555         case HDA_CMD_VERB_GET_PIN_SENSE:
556                 res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED;
557                 break;
558         case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT:
559                 res = sc->conf_default[nid];
560                 break;
561         case HDA_CMD_VERB_GET_SUBSYSTEM_ID:
562                 res = sc->subsystem_id;
563                 break;
564         default:
565                 assert(sc->verb_handlers);
566                 if (sc->verb_handlers[nid])
567                         res = sc->verb_handlers[nid](sc, verb, payload);
568                 else
569                         DPRINTF("Unknown VERB: 0x%x\n", verb);
570                 break;
571         }
572
573         DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x\n",
574             cad, nid, verb, payload, res);
575
576         return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL));
577 }
578
579 static int
580 hda_codec_notify(struct hda_codec_inst *hci, uint8_t run,
581     uint8_t stream, uint8_t dir)
582 {
583         struct hda_codec_softc *sc = NULL;
584         struct hda_codec_stream *st = NULL;
585         struct hda_audio_ctxt *actx = NULL;
586         int i;
587         int err;
588
589         assert(hci);
590         assert(stream);
591
592         sc = (struct hda_codec_softc *)hci->priv;
593         assert(sc);
594
595         i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT;
596         st = &sc->streams[i];
597
598         DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d\n",
599             run, stream, st->stream, dir);
600
601         if (stream != st->stream) {
602                 DPRINTF("Stream not found\n");
603                 return (0);
604         }
605
606         actx = &st->actx;
607
608         if (run)
609                 err = hda_audio_ctxt_start(actx);
610         else
611                 err = hda_audio_ctxt_stop(actx);
612
613         return (err);
614 }
615
616 static int
617 hda_codec_parse_format(uint16_t fmt, struct audio_params *params)
618 {
619         uint8_t div = 0;
620
621         assert(params);
622
623         /* Compute the Sample Rate */
624         params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000;
625
626         switch (fmt & HDA_CODEC_FMT_MULT_MASK) {
627         case HDA_CODEC_FMT_MULT_2:
628                 params->rate *= 2;
629                 break;
630         case HDA_CODEC_FMT_MULT_3:
631                 params->rate *= 3;
632                 break;
633         case HDA_CODEC_FMT_MULT_4:
634                 params->rate *= 4;
635                 break;
636         }
637
638         div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK;
639         params->rate /= (div + 1);
640
641         /* Compute the Bits per Sample */
642         switch (fmt & HDA_CODEC_FMT_BITS_MASK) {
643         case HDA_CODEC_FMT_BITS_8:
644                 params->format = AFMT_U8;
645                 break;
646         case HDA_CODEC_FMT_BITS_16:
647                 params->format = AFMT_S16_LE;
648                 break;
649         case HDA_CODEC_FMT_BITS_24:
650                 params->format = AFMT_S24_LE;
651                 break;
652         case HDA_CODEC_FMT_BITS_32:
653                 params->format = AFMT_S32_LE;
654                 break;
655         default:
656                 DPRINTF("Unknown format bits: 0x%x\n",
657                     fmt & HDA_CODEC_FMT_BITS_MASK);
658                 return (-1);
659         }
660
661         /* Compute the Number of Channels */
662         params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1;
663
664         return (0);
665 }
666
667 static uint32_t
668 hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb,
669     uint16_t payload)
670 {
671         struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
672         int res;
673
674         res = hda_codec_audio_inout_nid(st, verb, payload);
675
676         return (res);
677 }
678
679 static void
680 hda_codec_audio_output_do_transfer(void *arg)
681 {
682         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
683         struct hda_codec_inst *hci = NULL;
684         struct hda_ops *hops = NULL;
685         struct hda_codec_stream *st = NULL;
686         struct audio *aud = NULL;
687         int err;
688
689         hci = sc->hci;
690         assert(hci);
691
692         hops = hci->hops;
693         assert(hops);
694
695         st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
696         aud = st->aud;
697
698         err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf));
699         if (err)
700                 return;
701
702         err = audio_playback(aud, st->buf, sizeof(st->buf));
703         assert(!err);
704 }
705
706 static int
707 hda_codec_audio_output_do_setup(void *arg)
708 {
709         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
710         struct hda_codec_stream *st = NULL;
711         struct audio *aud = NULL;
712         struct audio_params params;
713         int err;
714
715         st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
716         aud = st->aud;
717
718         err = hda_codec_parse_format(st->fmt, &params);
719         if (err)
720                 return (-1);
721
722         DPRINTF("rate: %d, channels: %d, format: 0x%x\n",
723             params.rate, params.channels, params.format);
724
725         return (audio_set_params(aud, &params));
726 }
727
728 static uint32_t
729 hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb,
730     uint16_t payload)
731 {
732         struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT];
733         int res;
734
735         res = hda_codec_audio_inout_nid(st, verb, payload);
736
737         return (res);
738 }
739
740 static void
741 hda_codec_audio_input_do_transfer(void *arg)
742 {
743         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
744         struct hda_codec_inst *hci = NULL;
745         struct hda_ops *hops = NULL;
746         struct hda_codec_stream *st = NULL;
747         struct audio *aud = NULL;
748         int err;
749
750         hci = sc->hci;
751         assert(hci);
752
753         hops = hci->hops;
754         assert(hops);
755
756         st = &sc->streams[HDA_CODEC_STREAM_INPUT];
757         aud = st->aud;
758
759         err = audio_record(aud, st->buf, sizeof(st->buf));
760         assert(!err);
761
762         hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf));
763 }
764
765 static int
766 hda_codec_audio_input_do_setup(void *arg)
767 {
768         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
769         struct hda_codec_stream *st = NULL;
770         struct audio *aud = NULL;
771         struct audio_params params;
772         int err;
773
774         st = &sc->streams[HDA_CODEC_STREAM_INPUT];
775         aud = st->aud;
776
777         err = hda_codec_parse_format(st->fmt, &params);
778         if (err)
779                 return (-1);
780
781         DPRINTF("rate: %d, channels: %d, format: 0x%x\n",
782             params.rate, params.channels, params.format);
783
784         return (audio_set_params(aud, &params));
785 }
786
787 static uint32_t
788 hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb,
789     uint16_t payload)
790 {
791         uint32_t res = 0;
792         uint8_t mute = 0;
793         uint8_t gain = 0;
794
795         DPRINTF("%s verb: 0x%x, payload, 0x%x\n", st->actx.name, verb, payload);
796
797         switch (verb) {
798         case HDA_CMD_VERB_GET_CONV_FMT:
799                 res = st->fmt;
800                 break;
801         case HDA_CMD_VERB_SET_CONV_FMT:
802                 st->fmt = payload;
803                 break;
804         case HDA_CMD_VERB_GET_AMP_GAIN_MUTE:
805                 if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) {
806                         res = st->left_gain | st->left_mute;
807                         DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x\n", res);
808                 } else {
809                         res = st->right_gain | st->right_mute;
810                         DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x\n", res);
811                 }
812                 break;
813         case HDA_CMD_VERB_SET_AMP_GAIN_MUTE:
814                 mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE;
815                 gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK;
816
817                 if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) {
818                         st->left_mute = mute;
819                         st->left_gain = gain;
820                         DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \
821                             mute: 0x%x gain: 0x%x\n", mute, gain);
822                 }
823
824                 if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) {
825                         st->right_mute = mute;
826                         st->right_gain = gain;
827                         DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \
828                             mute: 0x%x gain: 0x%x\n", mute, gain);
829                 }
830                 break;
831         case HDA_CMD_VERB_GET_CONV_STREAM_CHAN:
832                 res = (st->stream << 4) | st->channel;
833                 break;
834         case HDA_CMD_VERB_SET_CONV_STREAM_CHAN:
835                 st->channel = payload & 0x0f;
836                 st->stream = (payload >> 4) & 0x0f;
837                 DPRINTF("st->channel: 0x%x st->stream: 0x%x\n",
838                     st->channel, st->stream);
839                 if (!st->stream)
840                         hda_audio_ctxt_stop(&st->actx);
841                 break;
842         default:
843                 DPRINTF("Unknown VERB: 0x%x\n", verb);
844                 break;
845         }
846
847         return (res);
848 }
849
850 struct hda_codec_class hda_codec  = {
851         .name           = "hda_codec",
852         .init           = hda_codec_init,
853         .reset          = hda_codec_reset,
854         .command        = hda_codec_command,
855         .notify         = hda_codec_notify,
856 };
857
858 HDA_EMUL_SET(hda_codec);
859
860
861 /*
862  * HDA Audio Context module function definitions
863  */
864
865 static void *
866 hda_audio_ctxt_thr(void *arg)
867 {
868         struct hda_audio_ctxt *actx = arg;
869
870         DPRINTF("Start Thread: %s\n", actx->name);
871
872         pthread_mutex_lock(&actx->mtx);
873         while (1) {
874                 while (!actx->run)
875                         pthread_cond_wait(&actx->cond, &actx->mtx);
876
877                 actx->do_transfer(actx->priv);
878         }
879         pthread_mutex_unlock(&actx->mtx);
880
881         pthread_exit(NULL);
882         return (NULL);
883 }
884
885 static int
886 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
887     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
888 {
889         int err;
890
891         assert(actx);
892         assert(tname);
893         assert(do_transfer);
894         assert(do_setup);
895         assert(priv);
896
897         memset(actx, 0, sizeof(*actx));
898
899         actx->run = 0;
900         actx->do_transfer = do_transfer;
901         actx->do_setup = do_setup;
902         actx->priv = priv;
903         if (strlen(tname) < sizeof(actx->name))
904                 memcpy(actx->name, tname, strlen(tname) + 1);
905         else
906                 strcpy(actx->name, "unknown");
907
908         err = pthread_mutex_init(&actx->mtx, NULL);
909         assert(!err);
910
911         err = pthread_cond_init(&actx->cond, NULL);
912         assert(!err);
913
914         err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
915         assert(!err);
916
917         pthread_set_name_np(actx->tid, tname);
918
919         actx->started = 1;
920
921         return (0);
922 }
923
924 static int
925 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
926 {
927         int err = 0;
928
929         assert(actx);
930         assert(actx->started);
931
932         /* The stream is supposed to be stopped */
933         if (actx->run)
934                 return (-1);
935
936         pthread_mutex_lock(&actx->mtx);
937         err = (* actx->do_setup)(actx->priv);
938         if (!err) {
939                 actx->run = 1;
940                 pthread_cond_signal(&actx->cond);
941         }
942         pthread_mutex_unlock(&actx->mtx);
943
944         return (err);
945 }
946
947 static int
948 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
949 {
950         actx->run = 0;
951         return (0);
952 }