qemu/hw/audio/hda-codec-common.h
<<
>>
Prefs
   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 */
  45static 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 */
  69static 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) */
  97static 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) */
 119static 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 */
 137static 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 */
 154static 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 */
 189static 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 */
 222static 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 */
 230static 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 */
 247static 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 */
 282static 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 */
 333static 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 */
 341static 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 */
 358static 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 */
 393static 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 */
 444static 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