qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/3] hda: add hda-micro codec


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 2/3] hda: add hda-micro codec
Date: Thu, 26 Apr 2012 09:15:03 +0200

It's identical to the hda-duplex codec, except that it advertises the
input as microphone instead of line-in and the output as speaker instead
of line-out.  Some guest apps (microsoft netmeeting being one) are picky
when it comes to selecting the recording source and don't accept
line-in, so give them what they expect.

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 hw/hda-audio.c |  143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 411be08..4e69c3c 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -115,6 +115,7 @@ static void hda_codec_parse_fmt(uint32_t format, struct 
audsettings *as)
 #define QEMU_HDA_ID_VENDOR  0x1af4
 #define QEMU_HDA_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x10)
 #define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x20)
+#define QEMU_HDA_ID_MICRO   ((QEMU_HDA_ID_VENDOR << 16) | 0x30)
 
 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 |       \
                               0x1fc /* 16 -> 96 kHz */)
@@ -427,6 +428,117 @@ static const desc_codec duplex = {
     .nnodes = ARRAY_SIZE(duplex_nodes),
 };
 
+/* micro: root node */
+static const desc_param micro_params_root[] = {
+    {
+        .id  = AC_PAR_VENDOR_ID,
+        .val = QEMU_HDA_ID_MICRO,
+    },{
+        .id  = AC_PAR_SUBSYSTEM_ID,
+        .val = QEMU_HDA_ID_MICRO,
+    },{
+        .id  = AC_PAR_REV_ID,
+        .val = 0x00100101,
+    },{
+        .id  = AC_PAR_NODE_COUNT,
+        .val = 0x00010001,
+    },
+};
+
+/* micro: audio function */
+static const desc_param micro_params_audio_func[] = {
+    {
+        .id  = AC_PAR_FUNCTION_TYPE,
+        .val = AC_GRP_AUDIO_FUNCTION,
+    },{
+        .id  = AC_PAR_SUBSYSTEM_ID,
+        .val = QEMU_HDA_ID_MICRO,
+    },{
+        .id  = AC_PAR_NODE_COUNT,
+        .val = 0x00020004,
+    },{
+        .id  = AC_PAR_PCM,
+        .val = QEMU_HDA_PCM_FORMATS,
+    },{
+        .id  = AC_PAR_STREAM,
+        .val = AC_SUPFMT_PCM,
+    },{
+        .id  = AC_PAR_AMP_IN_CAP,
+        .val = QEMU_HDA_AMP_NONE,
+    },{
+        .id  = AC_PAR_AMP_OUT_CAP,
+        .val = QEMU_HDA_AMP_NONE,
+    },{
+        .id  = AC_PAR_GPIO_CAP,
+        .val = 0,
+    },{
+        .id  = AC_PAR_AUDIO_FG_CAP,
+        .val = 0x00000808,
+    },{
+        .id  = AC_PAR_POWER_STATE,
+        .val = 0,
+    },
+};
+
+/* micro: nodes */
+static const desc_node micro_nodes[] = {
+    {
+        .nid     = AC_NODE_ROOT,
+        .name    = "root",
+        .params  = micro_params_root,
+        .nparams = ARRAY_SIZE(micro_params_root),
+    },{
+        .nid     = 1,
+        .name    = "func",
+        .params  = micro_params_audio_func,
+        .nparams = ARRAY_SIZE(micro_params_audio_func),
+    },{
+        .nid     = 2,
+        .name    = "dac",
+        .params  = common_params_audio_dac,
+        .nparams = ARRAY_SIZE(common_params_audio_dac),
+        .stindex = 0,
+    },{
+        .nid     = 3,
+        .name    = "out",
+        .params  = common_params_audio_lineout,
+        .nparams = ARRAY_SIZE(common_params_audio_lineout),
+        .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
+                    (AC_JACK_SPEAKER      << AC_DEFCFG_DEVICE_SHIFT)    |
+                    (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
+                    (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
+                    0x10),
+        .pinctl  = AC_PINCTL_OUT_EN,
+        .conn    = (uint32_t[]) { 2 },
+    },{
+        .nid     = 4,
+        .name    = "adc",
+        .params  = common_params_audio_adc,
+        .nparams = ARRAY_SIZE(common_params_audio_adc),
+        .stindex = 1,
+        .conn    = (uint32_t[]) { 5 },
+    },{
+        .nid     = 5,
+        .name    = "in",
+        .params  = common_params_audio_linein,
+        .nparams = ARRAY_SIZE(common_params_audio_linein),
+        .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
+                    (AC_JACK_MIC_IN       << AC_DEFCFG_DEVICE_SHIFT)    |
+                    (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
+                    (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
+                    0x20),
+        .pinctl  = AC_PINCTL_IN_EN,
+    }
+};
+
+/* micro: codec */
+static const desc_codec micro = {
+    .name   = "micro",
+    .iid    = QEMU_HDA_ID_MICRO,
+    .nodes  = micro_nodes,
+    .nnodes = ARRAY_SIZE(micro_nodes),
+};
+
 /* -------------------------------------------------------------------------- 
*/
 
 static const char *fmt2name[] = {
@@ -906,6 +1018,11 @@ static int hda_audio_init_duplex(HDACodecDevice *hda)
     return hda_audio_init(hda, &duplex);
 }
 
+static int hda_audio_init_micro(HDACodecDevice *hda)
+{
+    return hda_audio_init(hda, &micro);
+}
+
 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -915,7 +1032,7 @@ static void hda_audio_output_class_init(ObjectClass 
*klass, void *data)
     k->exit = hda_audio_exit;
     k->command = hda_audio_command;
     k->stream = hda_audio_stream;
-    dc->desc = "HDA Audio Codec, output-only";
+    dc->desc = "HDA Audio Codec, output-only (line-out)";
     dc->vmsd = &vmstate_hda_audio;
     dc->props = hda_audio_properties;
 }
@@ -936,7 +1053,7 @@ static void hda_audio_duplex_class_init(ObjectClass 
*klass, void *data)
     k->exit = hda_audio_exit;
     k->command = hda_audio_command;
     k->stream = hda_audio_stream;
-    dc->desc = "HDA Audio Codec, duplex";
+    dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
     dc->vmsd = &vmstate_hda_audio;
     dc->props = hda_audio_properties;
 }
@@ -948,10 +1065,32 @@ static TypeInfo hda_audio_duplex_info = {
     .class_init    = hda_audio_duplex_class_init,
 };
 
+static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+    k->init = hda_audio_init_micro;
+    k->exit = hda_audio_exit;
+    k->command = hda_audio_command;
+    k->stream = hda_audio_stream;
+    dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
+    dc->vmsd = &vmstate_hda_audio;
+    dc->props = hda_audio_properties;
+}
+
+static TypeInfo hda_audio_micro_info = {
+    .name          = "hda-micro",
+    .parent        = TYPE_HDA_CODEC_DEVICE,
+    .instance_size = sizeof(HDAAudioState),
+    .class_init    = hda_audio_micro_class_init,
+};
+
 static void hda_audio_register_types(void)
 {
     type_register_static(&hda_audio_output_info);
     type_register_static(&hda_audio_duplex_info);
+    type_register_static(&hda_audio_micro_info);
 }
 
 type_init(hda_audio_register_types)
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]