diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ac97.c | 67 | ||||
-rw-r--r-- | hw/pc_sysfw.c | 3 | ||||
-rw-r--r-- | hw/qdev-properties.c | 1 |
3 files changed, 53 insertions, 18 deletions
@@ -54,6 +54,8 @@ enum { AC97_6Ch_Vol_C_LFE_Mute = 0x36, AC97_6Ch_Vol_L_R_Surround_Mute = 0x38, AC97_Vendor_Reserved = 0x58, + AC97_Sigmatel_Analog = 0x6c, /* We emulate a Sigmatel codec */ + AC97_Sigmatel_Dac2Invert = 0x6e, /* We emulate a Sigmatel codec */ AC97_Vendor_ID1 = 0x7c, AC97_Vendor_ID2 = 0x7e }; @@ -342,7 +344,7 @@ static uint16_t mixer_load (AC97LinkState *s, uint32_t i) uint16_t val = 0xffff; if (i + 2 > sizeof (s->mixer_data)) { - dolog ("mixer_store: index %d out of bounds %zd\n", + dolog ("mixer_load: index %d out of bounds %zd\n", i, sizeof (s->mixer_data)); } else { @@ -456,8 +458,7 @@ static void update_combined_volume_out (AC97LinkState *s) get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1, &mute, &lvol, &rvol); - /* FIXME: should be 1f according to spec */ - get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x3f, 1, + get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x1f, 1, &pmute, &plvol, &prvol); mute = mute | pmute; @@ -480,11 +481,22 @@ static void update_volume_in (AC97LinkState *s) static void set_volume (AC97LinkState *s, int index, uint32_t val) { - mixer_store (s, index, val); - if (index == AC97_Master_Volume_Mute || index == AC97_PCM_Out_Volume_Mute) { + switch (index) { + case AC97_Master_Volume_Mute: + val &= 0xbf3f; + mixer_store (s, index, val); + update_combined_volume_out (s); + break; + case AC97_PCM_Out_Volume_Mute: + val &= 0x9f1f; + mixer_store (s, index, val); update_combined_volume_out (s); - } else if (index == AC97_Record_Gain_Mute) { + break; + case AC97_Record_Gain_Mute: + val &= 0x8f0f; + mixer_store (s, index, val); update_volume_in (s); + break; } } @@ -503,14 +515,17 @@ static void mixer_reset (AC97LinkState *s) memset (s->mixer_data, 0, sizeof (s->mixer_data)); memset (active, 0, sizeof (active)); mixer_store (s, AC97_Reset , 0x0000); /* 6940 */ - mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000); + mixer_store (s, AC97_Headphone_Volume_Mute , 0x0000); + mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x0000); + mixer_store (s, AC97_Master_Tone_RL, 0x0000); mixer_store (s, AC97_PC_BEEP_Volume_Mute , 0x0000); - - mixer_store (s, AC97_Phone_Volume_Mute , 0x8008); - mixer_store (s, AC97_Mic_Volume_Mute , 0x8008); - mixer_store (s, AC97_CD_Volume_Mute , 0x8808); - mixer_store (s, AC97_Aux_Volume_Mute , 0x8808); - mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x8000); + mixer_store (s, AC97_Phone_Volume_Mute , 0x0000); + mixer_store (s, AC97_Mic_Volume_Mute , 0x0000); + mixer_store (s, AC97_Line_In_Volume_Mute , 0x0000); + mixer_store (s, AC97_CD_Volume_Mute , 0x0000); + mixer_store (s, AC97_Video_Volume_Mute , 0x0000); + mixer_store (s, AC97_Aux_Volume_Mute , 0x0000); + mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x0000); mixer_store (s, AC97_General_Purpose , 0x0000); mixer_store (s, AC97_3D_Control , 0x0000); mixer_store (s, AC97_Powerdown_Ctrl_Stat , 0x000f); @@ -532,7 +547,7 @@ static void mixer_reset (AC97LinkState *s) record_select (s, 0); set_volume (s, AC97_Master_Volume_Mute, 0x8000); set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808); - set_volume (s, AC97_Line_In_Volume_Mute, 0x8808); + set_volume (s, AC97_Record_Gain_Mute, 0x8808); reset_voices (s, active); } @@ -588,14 +603,13 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val) mixer_reset (s); break; case AC97_Powerdown_Ctrl_Stat: - val &= ~0xf; + val &= ~0x800f; val |= mixer_load (s, index) & 0xf; mixer_store (s, index, val); break; case AC97_PCM_Out_Volume_Mute: case AC97_Master_Volume_Mute: case AC97_Record_Gain_Mute: - case AC97_Line_In_Volume_Mute: set_volume (s, index, val); break; case AC97_Record_Select: @@ -657,6 +671,23 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val) val); } break; + case AC97_Headphone_Volume_Mute: + case AC97_Master_Volume_Mono_Mute: + case AC97_Master_Tone_RL: + case AC97_PC_BEEP_Volume_Mute: + case AC97_Phone_Volume_Mute: + case AC97_Mic_Volume_Mute: + case AC97_Line_In_Volume_Mute: + case AC97_CD_Volume_Mute: + case AC97_Video_Volume_Mute: + case AC97_Aux_Volume_Mute: + case AC97_Record_Gain_Mic_Mute: + case AC97_General_Purpose: + case AC97_3D_Control: + case AC97_Sigmatel_Analog: + case AC97_Sigmatel_Dac2Invert: + /* None of the features in these regs are emulated, so they are RO */ + break; default: dolog ("U nam writew %#x <- %#x\n", addr, val); mixer_store (s, index, val); @@ -1158,8 +1189,8 @@ static int ac97_post_load (void *opaque, int version_id) mixer_load (s, AC97_Master_Volume_Mute)); set_volume (s, AC97_PCM_Out_Volume_Mute, mixer_load (s, AC97_PCM_Out_Volume_Mute)); - set_volume (s, AC97_Line_In_Volume_Mute, - mixer_load (s, AC97_Line_In_Volume_Mute)); + set_volume (s, AC97_Record_Gain_Mute, + mixer_load (s, AC97_Record_Gain_Mute)); active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM); active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM); diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c index fafdf9b1c1..f0d7c21b5c 100644 --- a/hw/pc_sysfw.c +++ b/hw/pc_sysfw.c @@ -85,6 +85,9 @@ static void pc_fw_add_pflash_drv(void) filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); opts = drive_add(IF_PFLASH, -1, filename, "readonly=on"); + + g_free(filename); + if (opts == NULL) { return; } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 98dd06aeba..c5545dcd37 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -834,6 +834,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, visit_type_str(v, &str, name, &local_err); if (local_err) { + error_free(local_err); return set_int32(obj, v, opaque, name, errp); } |