xref: /qemu/hw/audio/hda-codec-common.h (revision 72ac97cd)
1 /*
2  * Common code to disable/enable mixer emulation at run time
3  *
4  * Copyright (C) 2013 Red Hat, Inc.
5  *
6  * Written by Bandan Das <bsd@redhat.com>
7  * with important bits picked up from hda-codec.c
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /*
24  * HDA codec descriptions
25  */
26 
27 #ifdef HDA_MIXER
28 #define QEMU_HDA_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x12)
29 #define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x22)
30 #define QEMU_HDA_ID_MICRO   ((QEMU_HDA_ID_VENDOR << 16) | 0x32)
31 #define QEMU_HDA_AMP_CAPS                                               \
32     (AC_AMPCAP_MUTE |                                                   \
33      (QEMU_HDA_AMP_STEPS << AC_AMPCAP_OFFSET_SHIFT)    |                \
34      (QEMU_HDA_AMP_STEPS << AC_AMPCAP_NUM_STEPS_SHIFT) |                \
35      (3                  << AC_AMPCAP_STEP_SIZE_SHIFT))
36 #else
37 #define QEMU_HDA_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x11)
38 #define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x21)
39 #define QEMU_HDA_ID_MICRO   ((QEMU_HDA_ID_VENDOR << 16) | 0x31)
40 #define QEMU_HDA_AMP_CAPS   QEMU_HDA_AMP_NONE
41 #endif
42 
43 
44 /* common: audio output widget */
45 static const desc_param glue(common_params_audio_dac_, PARAM)[] = {
46     {
47         .id  = AC_PAR_AUDIO_WIDGET_CAP,
48         .val = ((AC_WID_AUD_OUT << AC_WCAP_TYPE_SHIFT) |
49                 AC_WCAP_FORMAT_OVRD |
50                 AC_WCAP_AMP_OVRD |
51                 AC_WCAP_OUT_AMP |
52                 AC_WCAP_STEREO),
53     },{
54         .id  = AC_PAR_PCM,
55         .val = QEMU_HDA_PCM_FORMATS,
56     },{
57         .id  = AC_PAR_STREAM,
58         .val = AC_SUPFMT_PCM,
59     },{
60         .id  = AC_PAR_AMP_IN_CAP,
61         .val = QEMU_HDA_AMP_NONE,
62     },{
63         .id  = AC_PAR_AMP_OUT_CAP,
64         .val = QEMU_HDA_AMP_CAPS,
65     },
66 };
67 
68 /* common: audio input widget */
69 static const desc_param glue(common_params_audio_adc_, PARAM)[] = {
70     {
71         .id  = AC_PAR_AUDIO_WIDGET_CAP,
72         .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) |
73                 AC_WCAP_CONN_LIST |
74                 AC_WCAP_FORMAT_OVRD |
75                 AC_WCAP_AMP_OVRD |
76                 AC_WCAP_IN_AMP |
77                 AC_WCAP_STEREO),
78     },{
79         .id  = AC_PAR_CONNLIST_LEN,
80         .val = 1,
81     },{
82         .id  = AC_PAR_PCM,
83         .val = QEMU_HDA_PCM_FORMATS,
84     },{
85         .id  = AC_PAR_STREAM,
86         .val = AC_SUPFMT_PCM,
87     },{
88         .id  = AC_PAR_AMP_IN_CAP,
89         .val = QEMU_HDA_AMP_CAPS,
90     },{
91         .id  = AC_PAR_AMP_OUT_CAP,
92         .val = QEMU_HDA_AMP_NONE,
93     },
94 };
95 
96 /* common: pin widget (line-out) */
97 static const desc_param glue(common_params_audio_lineout_, PARAM)[] = {
98     {
99         .id  = AC_PAR_AUDIO_WIDGET_CAP,
100         .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
101                 AC_WCAP_CONN_LIST |
102                 AC_WCAP_STEREO),
103     },{
104         .id  = AC_PAR_PIN_CAP,
105         .val = AC_PINCAP_OUT,
106     },{
107         .id  = AC_PAR_CONNLIST_LEN,
108         .val = 1,
109     },{
110         .id  = AC_PAR_AMP_IN_CAP,
111         .val = QEMU_HDA_AMP_NONE,
112     },{
113         .id  = AC_PAR_AMP_OUT_CAP,
114         .val = QEMU_HDA_AMP_NONE,
115     },
116 };
117 
118 /* common: pin widget (line-in) */
119 static const desc_param glue(common_params_audio_linein_, PARAM)[] = {
120     {
121         .id  = AC_PAR_AUDIO_WIDGET_CAP,
122         .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
123                 AC_WCAP_STEREO),
124     },{
125         .id  = AC_PAR_PIN_CAP,
126         .val = AC_PINCAP_IN,
127     },{
128         .id  = AC_PAR_AMP_IN_CAP,
129         .val = QEMU_HDA_AMP_NONE,
130     },{
131         .id  = AC_PAR_AMP_OUT_CAP,
132         .val = QEMU_HDA_AMP_NONE,
133     },
134 };
135 
136 /* output: root node */
137 static const desc_param glue(output_params_root_, PARAM)[] = {
138     {
139         .id  = AC_PAR_VENDOR_ID,
140         .val = QEMU_HDA_ID_OUTPUT,
141     },{
142         .id  = AC_PAR_SUBSYSTEM_ID,
143         .val = QEMU_HDA_ID_OUTPUT,
144     },{
145         .id  = AC_PAR_REV_ID,
146         .val = 0x00100101,
147     },{
148         .id  = AC_PAR_NODE_COUNT,
149         .val = 0x00010001,
150     },
151 };
152 
153 /* output: audio function */
154 static const desc_param glue(output_params_audio_func_, PARAM)[] = {
155     {
156         .id  = AC_PAR_FUNCTION_TYPE,
157         .val = AC_GRP_AUDIO_FUNCTION,
158     },{
159         .id  = AC_PAR_SUBSYSTEM_ID,
160         .val = QEMU_HDA_ID_OUTPUT,
161     },{
162         .id  = AC_PAR_NODE_COUNT,
163         .val = 0x00020002,
164     },{
165         .id  = AC_PAR_PCM,
166         .val = QEMU_HDA_PCM_FORMATS,
167     },{
168         .id  = AC_PAR_STREAM,
169         .val = AC_SUPFMT_PCM,
170     },{
171         .id  = AC_PAR_AMP_IN_CAP,
172         .val = QEMU_HDA_AMP_NONE,
173     },{
174         .id  = AC_PAR_AMP_OUT_CAP,
175         .val = QEMU_HDA_AMP_NONE,
176     },{
177         .id  = AC_PAR_GPIO_CAP,
178         .val = 0,
179     },{
180         .id  = AC_PAR_AUDIO_FG_CAP,
181         .val = 0x00000808,
182     },{
183         .id  = AC_PAR_POWER_STATE,
184         .val = 0,
185     },
186 };
187 
188 /* output: nodes */
189 static const desc_node glue(output_nodes_, PARAM)[] = {
190     {
191         .nid     = AC_NODE_ROOT,
192         .name    = "root",
193         .params  = glue(output_params_root_, PARAM),
194         .nparams = ARRAY_SIZE(glue(output_params_root_, PARAM)),
195     },{
196         .nid     = 1,
197         .name    = "func",
198         .params  = glue(output_params_audio_func_, PARAM),
199         .nparams = ARRAY_SIZE(glue(output_params_audio_func_, PARAM)),
200     },{
201         .nid     = 2,
202         .name    = "dac",
203         .params  = glue(common_params_audio_dac_, PARAM),
204         .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)),
205         .stindex = 0,
206     },{
207         .nid     = 3,
208         .name    = "out",
209         .params  = glue(common_params_audio_lineout_, PARAM),
210         .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)),
211         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
212                     (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
213                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
214                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
215                     0x10),
216         .pinctl  = AC_PINCTL_OUT_EN,
217         .conn    = (uint32_t[]) { 2 },
218     }
219 };
220 
221 /* output: codec */
222 static const desc_codec glue(output_, PARAM) = {
223     .name   = "output",
224     .iid    = QEMU_HDA_ID_OUTPUT,
225     .nodes  = glue(output_nodes_, PARAM),
226     .nnodes = ARRAY_SIZE(glue(output_nodes_, PARAM)),
227 };
228 
229 /* duplex: root node */
230 static const desc_param glue(duplex_params_root_, PARAM)[] = {
231     {
232         .id  = AC_PAR_VENDOR_ID,
233         .val = QEMU_HDA_ID_DUPLEX,
234     },{
235         .id  = AC_PAR_SUBSYSTEM_ID,
236         .val = QEMU_HDA_ID_DUPLEX,
237     },{
238         .id  = AC_PAR_REV_ID,
239         .val = 0x00100101,
240     },{
241         .id  = AC_PAR_NODE_COUNT,
242         .val = 0x00010001,
243     },
244 };
245 
246 /* duplex: audio function */
247 static const desc_param glue(duplex_params_audio_func_, PARAM)[] = {
248     {
249         .id  = AC_PAR_FUNCTION_TYPE,
250         .val = AC_GRP_AUDIO_FUNCTION,
251     },{
252         .id  = AC_PAR_SUBSYSTEM_ID,
253         .val = QEMU_HDA_ID_DUPLEX,
254     },{
255         .id  = AC_PAR_NODE_COUNT,
256         .val = 0x00020004,
257     },{
258         .id  = AC_PAR_PCM,
259         .val = QEMU_HDA_PCM_FORMATS,
260     },{
261         .id  = AC_PAR_STREAM,
262         .val = AC_SUPFMT_PCM,
263     },{
264         .id  = AC_PAR_AMP_IN_CAP,
265         .val = QEMU_HDA_AMP_NONE,
266     },{
267         .id  = AC_PAR_AMP_OUT_CAP,
268         .val = QEMU_HDA_AMP_NONE,
269     },{
270         .id  = AC_PAR_GPIO_CAP,
271         .val = 0,
272     },{
273         .id  = AC_PAR_AUDIO_FG_CAP,
274         .val = 0x00000808,
275     },{
276         .id  = AC_PAR_POWER_STATE,
277         .val = 0,
278     },
279 };
280 
281 /* duplex: nodes */
282 static const desc_node glue(duplex_nodes_, PARAM)[] = {
283     {
284         .nid     = AC_NODE_ROOT,
285         .name    = "root",
286         .params  = glue(duplex_params_root_, PARAM),
287         .nparams = ARRAY_SIZE(glue(duplex_params_root_, PARAM)),
288     },{
289         .nid     = 1,
290         .name    = "func",
291         .params  = glue(duplex_params_audio_func_, PARAM),
292         .nparams = ARRAY_SIZE(glue(duplex_params_audio_func_, PARAM)),
293     },{
294         .nid     = 2,
295         .name    = "dac",
296         .params  = glue(common_params_audio_dac_, PARAM),
297         .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)),
298         .stindex = 0,
299     },{
300         .nid     = 3,
301         .name    = "out",
302         .params  = glue(common_params_audio_lineout_, PARAM),
303         .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)),
304         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
305                     (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
306                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
307                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
308                     0x10),
309         .pinctl  = AC_PINCTL_OUT_EN,
310         .conn    = (uint32_t[]) { 2 },
311     },{
312         .nid     = 4,
313         .name    = "adc",
314         .params  = glue(common_params_audio_adc_, PARAM),
315         .nparams = ARRAY_SIZE(glue(common_params_audio_adc_, PARAM)),
316         .stindex = 1,
317         .conn    = (uint32_t[]) { 5 },
318     },{
319         .nid     = 5,
320         .name    = "in",
321         .params  = glue(common_params_audio_linein_, PARAM),
322         .nparams = ARRAY_SIZE(glue(common_params_audio_linein_, PARAM)),
323         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
324                     (AC_JACK_LINE_IN      << AC_DEFCFG_DEVICE_SHIFT)    |
325                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
326                     (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
327                     0x20),
328         .pinctl  = AC_PINCTL_IN_EN,
329     }
330 };
331 
332 /* duplex: codec */
333 static const desc_codec glue(duplex_, PARAM) = {
334     .name   = "duplex",
335     .iid    = QEMU_HDA_ID_DUPLEX,
336     .nodes  = glue(duplex_nodes_, PARAM),
337     .nnodes = ARRAY_SIZE(glue(duplex_nodes_, PARAM)),
338 };
339 
340 /* micro: root node */
341 static const desc_param glue(micro_params_root_, PARAM)[] = {
342     {
343         .id  = AC_PAR_VENDOR_ID,
344         .val = QEMU_HDA_ID_MICRO,
345     },{
346         .id  = AC_PAR_SUBSYSTEM_ID,
347         .val = QEMU_HDA_ID_MICRO,
348     },{
349         .id  = AC_PAR_REV_ID,
350         .val = 0x00100101,
351     },{
352         .id  = AC_PAR_NODE_COUNT,
353         .val = 0x00010001,
354     },
355 };
356 
357 /* micro: audio function */
358 static const desc_param glue(micro_params_audio_func_, PARAM)[] = {
359     {
360         .id  = AC_PAR_FUNCTION_TYPE,
361         .val = AC_GRP_AUDIO_FUNCTION,
362     },{
363         .id  = AC_PAR_SUBSYSTEM_ID,
364         .val = QEMU_HDA_ID_MICRO,
365     },{
366         .id  = AC_PAR_NODE_COUNT,
367         .val = 0x00020004,
368     },{
369         .id  = AC_PAR_PCM,
370         .val = QEMU_HDA_PCM_FORMATS,
371     },{
372         .id  = AC_PAR_STREAM,
373         .val = AC_SUPFMT_PCM,
374     },{
375         .id  = AC_PAR_AMP_IN_CAP,
376         .val = QEMU_HDA_AMP_NONE,
377     },{
378         .id  = AC_PAR_AMP_OUT_CAP,
379         .val = QEMU_HDA_AMP_NONE,
380     },{
381         .id  = AC_PAR_GPIO_CAP,
382         .val = 0,
383     },{
384         .id  = AC_PAR_AUDIO_FG_CAP,
385         .val = 0x00000808,
386     },{
387         .id  = AC_PAR_POWER_STATE,
388         .val = 0,
389     },
390 };
391 
392 /* micro: nodes */
393 static const desc_node glue(micro_nodes_, PARAM)[] = {
394     {
395         .nid     = AC_NODE_ROOT,
396         .name    = "root",
397         .params  = glue(micro_params_root_, PARAM),
398         .nparams = ARRAY_SIZE(glue(micro_params_root_, PARAM)),
399     },{
400         .nid     = 1,
401         .name    = "func",
402         .params  = glue(micro_params_audio_func_, PARAM),
403         .nparams = ARRAY_SIZE(glue(micro_params_audio_func_, PARAM)),
404     },{
405         .nid     = 2,
406         .name    = "dac",
407         .params  = glue(common_params_audio_dac_, PARAM),
408         .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)),
409         .stindex = 0,
410     },{
411         .nid     = 3,
412         .name    = "out",
413         .params  = glue(common_params_audio_lineout_, PARAM),
414         .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)),
415         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
416                     (AC_JACK_SPEAKER      << AC_DEFCFG_DEVICE_SHIFT)    |
417                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
418                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
419                     0x10),
420         .pinctl  = AC_PINCTL_OUT_EN,
421         .conn    = (uint32_t[]) { 2 },
422     },{
423         .nid     = 4,
424         .name    = "adc",
425         .params  = glue(common_params_audio_adc_, PARAM),
426         .nparams = ARRAY_SIZE(glue(common_params_audio_adc_, PARAM)),
427         .stindex = 1,
428         .conn    = (uint32_t[]) { 5 },
429     },{
430         .nid     = 5,
431         .name    = "in",
432         .params  = glue(common_params_audio_linein_, PARAM),
433         .nparams = ARRAY_SIZE(glue(common_params_audio_linein_, PARAM)),
434         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
435                     (AC_JACK_MIC_IN       << AC_DEFCFG_DEVICE_SHIFT)    |
436                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
437                     (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
438                     0x20),
439         .pinctl  = AC_PINCTL_IN_EN,
440     }
441 };
442 
443 /* micro: codec */
444 static const desc_codec glue(micro_, PARAM) = {
445     .name   = "micro",
446     .iid    = QEMU_HDA_ID_MICRO,
447     .nodes  = glue(micro_nodes_, PARAM),
448     .nnodes = ARRAY_SIZE(glue(micro_nodes_, PARAM)),
449 };
450 
451 #undef PARAM
452 #undef HDA_MIXER
453 #undef QEMU_HDA_ID_OUTPUT
454 #undef QEMU_HDA_ID_DUPLEX
455 #undef QEMU_HDA_ID_MICRO
456 #undef QEMU_HDA_AMP_CAPS
457