]>
Commit | Line | Data |
---|---|---|
7953793c BD |
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 <[email protected]> | |
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 | ||
2690e61e | 27 | #ifdef HDA_MIXER |
7953793c BD |
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 */ | |
2690e61e | 45 | static const desc_param glue(common_params_audio_dac_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 69 | static const desc_param glue(common_params_audio_adc_, PARAM)[] = { |
7953793c BD |
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) */ | |
2690e61e | 97 | static const desc_param glue(common_params_audio_lineout_, PARAM)[] = { |
7953793c BD |
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) */ | |
2690e61e | 119 | static const desc_param glue(common_params_audio_linein_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 137 | static const desc_param glue(output_params_root_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 154 | static const desc_param glue(output_params_audio_func_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 189 | static const desc_node glue(output_nodes_, PARAM)[] = { |
7953793c BD |
190 | { |
191 | .nid = AC_NODE_ROOT, | |
192 | .name = "root", | |
2690e61e BD |
193 | .params = glue(output_params_root_, PARAM), |
194 | .nparams = ARRAY_SIZE(glue(output_params_root_, PARAM)), | |
7953793c BD |
195 | },{ |
196 | .nid = 1, | |
197 | .name = "func", | |
2690e61e BD |
198 | .params = glue(output_params_audio_func_, PARAM), |
199 | .nparams = ARRAY_SIZE(glue(output_params_audio_func_, PARAM)), | |
7953793c BD |
200 | },{ |
201 | .nid = 2, | |
202 | .name = "dac", | |
2690e61e BD |
203 | .params = glue(common_params_audio_dac_, PARAM), |
204 | .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)), | |
7953793c BD |
205 | .stindex = 0, |
206 | },{ | |
207 | .nid = 3, | |
208 | .name = "out", | |
2690e61e BD |
209 | .params = glue(common_params_audio_lineout_, PARAM), |
210 | .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)), | |
7953793c BD |
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 */ | |
2690e61e | 222 | static const desc_codec glue(output_, PARAM) = { |
7953793c BD |
223 | .name = "output", |
224 | .iid = QEMU_HDA_ID_OUTPUT, | |
2690e61e BD |
225 | .nodes = glue(output_nodes_, PARAM), |
226 | .nnodes = ARRAY_SIZE(glue(output_nodes_, PARAM)), | |
7953793c BD |
227 | }; |
228 | ||
229 | /* duplex: root node */ | |
2690e61e | 230 | static const desc_param glue(duplex_params_root_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 247 | static const desc_param glue(duplex_params_audio_func_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 282 | static const desc_node glue(duplex_nodes_, PARAM)[] = { |
7953793c BD |
283 | { |
284 | .nid = AC_NODE_ROOT, | |
285 | .name = "root", | |
2690e61e BD |
286 | .params = glue(duplex_params_root_, PARAM), |
287 | .nparams = ARRAY_SIZE(glue(duplex_params_root_, PARAM)), | |
7953793c BD |
288 | },{ |
289 | .nid = 1, | |
290 | .name = "func", | |
2690e61e BD |
291 | .params = glue(duplex_params_audio_func_, PARAM), |
292 | .nparams = ARRAY_SIZE(glue(duplex_params_audio_func_, PARAM)), | |
7953793c BD |
293 | },{ |
294 | .nid = 2, | |
295 | .name = "dac", | |
2690e61e BD |
296 | .params = glue(common_params_audio_dac_, PARAM), |
297 | .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)), | |
7953793c BD |
298 | .stindex = 0, |
299 | },{ | |
300 | .nid = 3, | |
301 | .name = "out", | |
2690e61e BD |
302 | .params = glue(common_params_audio_lineout_, PARAM), |
303 | .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)), | |
7953793c BD |
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", | |
2690e61e BD |
314 | .params = glue(common_params_audio_adc_, PARAM), |
315 | .nparams = ARRAY_SIZE(glue(common_params_audio_adc_, PARAM)), | |
7953793c BD |
316 | .stindex = 1, |
317 | .conn = (uint32_t[]) { 5 }, | |
318 | },{ | |
319 | .nid = 5, | |
320 | .name = "in", | |
2690e61e BD |
321 | .params = glue(common_params_audio_linein_, PARAM), |
322 | .nparams = ARRAY_SIZE(glue(common_params_audio_linein_, PARAM)), | |
7953793c BD |
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 */ | |
2690e61e | 333 | static const desc_codec glue(duplex_, PARAM) = { |
7953793c BD |
334 | .name = "duplex", |
335 | .iid = QEMU_HDA_ID_DUPLEX, | |
2690e61e BD |
336 | .nodes = glue(duplex_nodes_, PARAM), |
337 | .nnodes = ARRAY_SIZE(glue(duplex_nodes_, PARAM)), | |
7953793c BD |
338 | }; |
339 | ||
340 | /* micro: root node */ | |
2690e61e | 341 | static const desc_param glue(micro_params_root_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 358 | static const desc_param glue(micro_params_audio_func_, PARAM)[] = { |
7953793c BD |
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 */ | |
2690e61e | 393 | static const desc_node glue(micro_nodes_, PARAM)[] = { |
7953793c BD |
394 | { |
395 | .nid = AC_NODE_ROOT, | |
396 | .name = "root", | |
2690e61e BD |
397 | .params = glue(micro_params_root_, PARAM), |
398 | .nparams = ARRAY_SIZE(glue(micro_params_root_, PARAM)), | |
7953793c BD |
399 | },{ |
400 | .nid = 1, | |
401 | .name = "func", | |
2690e61e BD |
402 | .params = glue(micro_params_audio_func_, PARAM), |
403 | .nparams = ARRAY_SIZE(glue(micro_params_audio_func_, PARAM)), | |
7953793c BD |
404 | },{ |
405 | .nid = 2, | |
406 | .name = "dac", | |
2690e61e BD |
407 | .params = glue(common_params_audio_dac_, PARAM), |
408 | .nparams = ARRAY_SIZE(glue(common_params_audio_dac_, PARAM)), | |
7953793c BD |
409 | .stindex = 0, |
410 | },{ | |
411 | .nid = 3, | |
412 | .name = "out", | |
2690e61e BD |
413 | .params = glue(common_params_audio_lineout_, PARAM), |
414 | .nparams = ARRAY_SIZE(glue(common_params_audio_lineout_, PARAM)), | |
7953793c BD |
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", | |
2690e61e BD |
425 | .params = glue(common_params_audio_adc_, PARAM), |
426 | .nparams = ARRAY_SIZE(glue(common_params_audio_adc_, PARAM)), | |
7953793c BD |
427 | .stindex = 1, |
428 | .conn = (uint32_t[]) { 5 }, | |
429 | },{ | |
430 | .nid = 5, | |
431 | .name = "in", | |
2690e61e BD |
432 | .params = glue(common_params_audio_linein_, PARAM), |
433 | .nparams = ARRAY_SIZE(glue(common_params_audio_linein_, PARAM)), | |
7953793c BD |
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 */ | |
2690e61e | 444 | static const desc_codec glue(micro_, PARAM) = { |
7953793c BD |
445 | .name = "micro", |
446 | .iid = QEMU_HDA_ID_MICRO, | |
2690e61e BD |
447 | .nodes = glue(micro_nodes_, PARAM), |
448 | .nnodes = ARRAY_SIZE(glue(micro_nodes_, PARAM)), | |
7953793c | 449 | }; |
2690e61e BD |
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 |