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