]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/hda_codec.c
powerpc: Transition to Secure-PLT, like most other OSs (Toolchain part)
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / hda_codec.c
1 /*-
2  * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
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, const char *opts);
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, const char *opts)
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         DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts);
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\n", 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\n");
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\n");
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         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\n", hci->cad);
490
491         if (!hops->signal) {
492                 DPRINTF("The controller ops does not implement \
493                          the signal function\n");
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         struct hda_codec_softc *sc = NULL;
504         struct hda_ops *hops = NULL;
505         uint8_t cad = 0, nid = 0;
506         uint16_t verb = 0, payload = 0;
507         uint32_t res = 0;
508
509         /* 4 bits */
510         cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f;
511         /* 8 bits */
512         nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff;
513
514         if ((cmd_data & 0x70000) == 0x70000) {
515                 /* 12 bits */
516                 verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff;
517                 /* 8 bits */
518                 payload = cmd_data & 0xff;
519         } else {
520                 /* 4 bits */
521                 verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f;
522                 /* 16 bits */
523                 payload = cmd_data & 0xffff;
524         }
525
526         assert(cad == hci->cad);
527         assert(hci);
528
529         hops = hci->hops;
530         assert(hops);
531
532         sc = (struct hda_codec_softc *)hci->priv;
533         assert(sc);
534
535         assert(nid < sc->no_nodes);
536
537         if (!hops->response) {
538                 DPRINTF("The controller ops does not implement \
539                          the response function\n");
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\n", verb);
568                 break;
569         }
570
571         DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x\n",
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\n",
597             run, stream, st->stream, dir);
598
599         if (stream != st->stream) {
600                 DPRINTF("Stream not found\n");
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\n",
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         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
681         struct hda_codec_inst *hci = NULL;
682         struct hda_ops *hops = NULL;
683         struct hda_codec_stream *st = NULL;
684         struct audio *aud = NULL;
685         int err;
686
687         hci = sc->hci;
688         assert(hci);
689
690         hops = hci->hops;
691         assert(hops);
692
693         st = &sc->streams[HDA_CODEC_STREAM_OUTPUT];
694         aud = st->aud;
695
696         err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf));
697         if (err)
698                 return;
699
700         err = audio_playback(aud, st->buf, sizeof(st->buf));
701         assert(!err);
702 }
703
704 static int
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\n",
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         struct hda_codec_softc *sc = (struct hda_codec_softc *)arg;
742         struct hda_codec_inst *hci = NULL;
743         struct hda_ops *hops = NULL;
744         struct hda_codec_stream *st = NULL;
745         struct audio *aud = NULL;
746         int err;
747
748         hci = sc->hci;
749         assert(hci);
750
751         hops = hci->hops;
752         assert(hops);
753
754         st = &sc->streams[HDA_CODEC_STREAM_INPUT];
755         aud = st->aud;
756
757         err = audio_record(aud, st->buf, sizeof(st->buf));
758         assert(!err);
759
760         hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf));
761 }
762
763 static int
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\n",
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\n", 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\n", res);
806                 } else {
807                         res = st->right_gain | st->right_mute;
808                         DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x\n", 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\n", 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\n", 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\n",
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\n", verb);
842                 break;
843         }
844
845         return (res);
846 }
847
848 struct hda_codec_class hda_codec  = {
849         .name           = "hda_codec",
850         .init           = hda_codec_init,
851         .reset          = hda_codec_reset,
852         .command        = hda_codec_command,
853         .notify         = hda_codec_notify,
854 };
855
856 HDA_EMUL_SET(hda_codec);
857
858
859 /*
860  * HDA Audio Context module function definitions
861  */
862
863 static void *
864 hda_audio_ctxt_thr(void *arg)
865 {
866         struct hda_audio_ctxt *actx = arg;
867
868         DPRINTF("Start Thread: %s\n", actx->name);
869
870         pthread_mutex_lock(&actx->mtx);
871         while (1) {
872                 while (!actx->run)
873                         pthread_cond_wait(&actx->cond, &actx->mtx);
874
875                 actx->do_transfer(actx->priv);
876         }
877         pthread_mutex_unlock(&actx->mtx);
878
879         pthread_exit(NULL);
880         return (NULL);
881 }
882
883 static int
884 hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname,
885     transfer_func_t do_transfer, setup_func_t do_setup, void *priv)
886 {
887         int err;
888
889         assert(actx);
890         assert(tname);
891         assert(do_transfer);
892         assert(do_setup);
893         assert(priv);
894
895         memset(actx, 0, sizeof(*actx));
896
897         actx->run = 0;
898         actx->do_transfer = do_transfer;
899         actx->do_setup = do_setup;
900         actx->priv = priv;
901         if (strlen(tname) < sizeof(actx->name))
902                 memcpy(actx->name, tname, strlen(tname) + 1);
903         else
904                 strcpy(actx->name, "unknown");
905
906         err = pthread_mutex_init(&actx->mtx, NULL);
907         assert(!err);
908
909         err = pthread_cond_init(&actx->cond, NULL);
910         assert(!err);
911
912         err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx);
913         assert(!err);
914
915         pthread_set_name_np(actx->tid, tname);
916
917         actx->started = 1;
918
919         return (0);
920 }
921
922 static int
923 hda_audio_ctxt_start(struct hda_audio_ctxt *actx)
924 {
925         int err = 0;
926
927         assert(actx);
928         assert(actx->started);
929
930         /* The stream is supposed to be stopped */
931         if (actx->run)
932                 return (-1);
933
934         pthread_mutex_lock(&actx->mtx);
935         err = (* actx->do_setup)(actx->priv);
936         if (!err) {
937                 actx->run = 1;
938                 pthread_cond_signal(&actx->cond);
939         }
940         pthread_mutex_unlock(&actx->mtx);
941
942         return (err);
943 }
944
945 static int
946 hda_audio_ctxt_stop(struct hda_audio_ctxt *actx)
947 {
948         actx->run = 0;
949         return (0);
950 }