diff --git a/[refs] b/[refs] index 0118f6a52d3a..3b3f99418894 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7d489c460ee798be16ca135276fe23262baf038c +refs/heads/master: 14744d7da2e6ab5c6d8e82c84dc280e3c0dd8552 diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index 939a3dd58148..0d8d23581c44 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -240,7 +240,6 @@ AD1986A laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC) samsung 2-channel with EAPD (Samsung R65) - samsung-p50 2-channel with HP-automute (Samsung P50) AD1988/AD1988B/AD1989A/AD1989B ============================== diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 3ba68dc9fe48..fa2a16def17a 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5668,13 +5668,6 @@ F: drivers/misc/tifm* F: drivers/mmc/host/tifm_sd.c F: include/linux/tifm.h -TI TWL4030 SERIES SOC CODEC DRIVER -P: Peter Ujfalusi -M: peter.ujfalusi@nokia.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: sound/soc/codecs/twl4030* - TIPC NETWORK LAYER P: Per Liden M: per.liden@ericsson.com diff --git a/trunk/sound/isa/cmi8330.c b/trunk/sound/isa/cmi8330.c index 3ee0269e5bd0..de83608719ea 100644 --- a/trunk/sound/isa/cmi8330.c +++ b/trunk/sound/isa/cmi8330.c @@ -338,7 +338,7 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, return -EBUSY; acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL); - if (acard->mpu == NULL) + if (acard->play == NULL) return -EBUSY; pdev = acard->cap; diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 1988582d1ab8..84cc49ca9148 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -72,7 +72,6 @@ struct ad198x_spec { hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; unsigned int jack_present :1; - unsigned int inv_jack_detect:1; #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; @@ -670,15 +669,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = { }, }; -static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { +static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), - { } /* end */ -}; - -static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), @@ -702,9 +699,31 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), +static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), + HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "External Amplifier", + .info = ad198x_eapd_info, + .get = ad198x_eapd_get, + .put = ad198x_eapd_put, + .private_value = 0x1b | (1 << 8), /* port-D, inversed */ + }, { } /* end */ }; @@ -757,9 +776,8 @@ static void ad1986a_hp_automute(struct hda_codec *codec) unsigned int present; present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = !!(present & 0x80000000); - if (spec->inv_jack_detect) - spec->jack_present = !spec->jack_present; + /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ + spec->jack_present = !(present & 0x80000000); ad1986a_update_hp(codec); } @@ -798,7 +816,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { +static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -808,10 +826,33 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { .put = ad1986a_hp_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), }, + HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "External Amplifier", + .info = ad198x_eapd_info, + .get = ad198x_eapd_get, + .put = ad198x_eapd_put, + .private_value = 0x1b | (1 << 8), /* port-D, inversed */ + }, { } /* end */ }; - /* * initialization verbs */ @@ -940,27 +981,6 @@ static struct hda_verb ad1986a_hp_init_verbs[] = { {} }; -static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case AD1986A_HP_EVENT: - ad1986a_hp_automute(codec); - break; - case AD1986A_MIC_EVENT: - ad1986a_automic(codec); - break; - } -} - -static int ad1986a_samsung_p50_init(struct hda_codec *codec) -{ - ad198x_init(codec); - ad1986a_hp_automute(codec); - ad1986a_automic(codec); - return 0; -} - /* models */ enum { @@ -971,7 +991,6 @@ enum { AD1986A_LAPTOP_AUTOMUTE, AD1986A_ULTRA, AD1986A_SAMSUNG, - AD1986A_SAMSUNG_P50, AD1986A_MODELS }; @@ -983,7 +1002,6 @@ static const char *ad1986a_models[AD1986A_MODELS] = { [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", [AD1986A_ULTRA] = "ultra", [AD1986A_SAMSUNG] = "samsung", - [AD1986A_SAMSUNG_P50] = "samsung-p50", }; static struct snd_pci_quirk ad1986a_cfg_tbl[] = { @@ -1006,7 +1024,6 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), - SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), @@ -1094,10 +1111,7 @@ static int patch_ad1986a(struct hda_codec *codec) spec->multiout.dac_nids = ad1986a_laptop_dac_nids; break; case AD1986A_LAPTOP_EAPD: - spec->num_mixers = 3; - spec->mixers[0] = ad1986a_laptop_master_mixers; - spec->mixers[1] = ad1986a_laptop_eapd_mixers; - spec->mixers[2] = ad1986a_laptop_intmic_mixers; + spec->mixers[0] = ad1986a_laptop_eapd_mixers; spec->num_init_verbs = 2; spec->init_verbs[1] = ad1986a_eapd_init_verbs; spec->multiout.max_channels = 2; @@ -1108,9 +1122,7 @@ static int patch_ad1986a(struct hda_codec *codec) spec->input_mux = &ad1986a_laptop_eapd_capture_source; break; case AD1986A_SAMSUNG: - spec->num_mixers = 2; - spec->mixers[0] = ad1986a_laptop_master_mixers; - spec->mixers[1] = ad1986a_laptop_eapd_mixers; + spec->mixers[0] = ad1986a_samsung_mixers; spec->num_init_verbs = 3; spec->init_verbs[1] = ad1986a_eapd_init_verbs; spec->init_verbs[2] = ad1986a_automic_verbs; @@ -1123,28 +1135,8 @@ static int patch_ad1986a(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; codec->patch_ops.init = ad1986a_automic_init; break; - case AD1986A_SAMSUNG_P50: - spec->num_mixers = 2; - spec->mixers[0] = ad1986a_automute_master_mixers; - spec->mixers[1] = ad1986a_laptop_eapd_mixers; - spec->num_init_verbs = 4; - spec->init_verbs[1] = ad1986a_eapd_init_verbs; - spec->init_verbs[2] = ad1986a_automic_verbs; - spec->init_verbs[3] = ad1986a_hp_init_verbs; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; - if (!is_jack_available(codec, 0x25)) - spec->multiout.dig_out_nid = 0; - spec->input_mux = &ad1986a_automic_capture_source; - codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event; - codec->patch_ops.init = ad1986a_samsung_p50_init; - break; case AD1986A_LAPTOP_AUTOMUTE: - spec->num_mixers = 3; - spec->mixers[0] = ad1986a_automute_master_mixers; - spec->mixers[1] = ad1986a_laptop_eapd_mixers; - spec->mixers[2] = ad1986a_laptop_intmic_mixers; + spec->mixers[0] = ad1986a_laptop_automute_mixers; spec->num_init_verbs = 3; spec->init_verbs[1] = ad1986a_eapd_init_verbs; spec->init_verbs[2] = ad1986a_hp_init_verbs; @@ -1156,10 +1148,6 @@ static int patch_ad1986a(struct hda_codec *codec) spec->input_mux = &ad1986a_laptop_eapd_capture_source; codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; codec->patch_ops.init = ad1986a_hp_init; - /* Lenovo N100 seems to report the reversed bit - * for HP jack-sensing - */ - spec->inv_jack_detect = 1; break; case AD1986A_ULTRA: spec->mixers[0] = ad1986a_laptop_eapd_mixers; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 3a8e58c483df..334533197425 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -945,13 +945,12 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, static void alc_automute_pin(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int present, pincap; + unsigned int present; unsigned int nid = spec->autocfg.hp_pins[0]; int i; - pincap = snd_hda_query_pin_caps(codec, nid); - if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ - snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); + /* need to execute and sync at first */ + snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); present = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; @@ -1393,7 +1392,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { static void alc_automute_amp(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int val, mute, pincap; + unsigned int val, mute; hda_nid_t nid; int i; @@ -1402,10 +1401,6 @@ static void alc_automute_amp(struct hda_codec *codec) nid = spec->autocfg.hp_pins[i]; if (!nid) break; - pincap = snd_hda_query_pin_caps(codec, nid); - if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ - snd_hda_codec_read(codec, nid, 0, - AC_VERB_SET_PIN_SENSE, 0); val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); if (val & AC_PINSENSE_PRESENCE) { @@ -1476,10 +1471,6 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { /* Bias voltage on for external mic port */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Unselect Front Mic by default in input mixer 3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, /* Enable unsolicited event for HP jack */ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, /* Enable speaker output */ @@ -1569,22 +1560,18 @@ static struct hda_input_mux alc888_2_capture_sources[2] = { static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { /* Interal mic only available on one ADC */ { - .num_items = 5, + .num_items = 3, .items = { { "Ext Mic", 0x0 }, - { "Line In", 0x2 }, { "CD", 0x4 }, - { "Input Mix", 0xa }, { "Int Mic", 0xb }, }, }, { - .num_items = 4, + .num_items = 2, .items = { { "Ext Mic", 0x0 }, - { "Line In", 0x2 }, { "CD", 0x4 }, - { "Input Mix", 0xa }, }, } }; @@ -1652,17 +1639,6 @@ static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) alc_automute_amp(codec); } -static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x17; - alc_automute_amp(codec); -} - static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -8213,8 +8189,6 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -9090,7 +9064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", - ALC888_ACER_ASPIRE_6530G), + ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", ALC888_ACER_ASPIRE_6530G), /* default Acer -- disabled as it causes more problems. @@ -9343,7 +9317,7 @@ static struct alc_config_preset alc883_presets[] = { ARRAY_SIZE(alc888_2_capture_sources), .input_mux = alc888_acer_aspire_6530_sources, .unsol_event = alc_automute_amp_unsol_event, - .init_hook = alc888_acer_aspire_6530g_init_hook, + .init_hook = alc888_acer_aspire_4930g_init_hook, }, [ALC888_ACER_ASPIRE_8930G] = { .mixers = { alc888_base_mixer, @@ -12463,8 +12437,6 @@ static int alc268_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; - alc_ssid_check(codec, 0x15, 0x1b, 0x14); - return 1; } @@ -13373,8 +13345,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if (!spec->cap_mixer && !spec->no_analog) set_capture_mixer(spec); - alc_ssid_check(codec, 0x15, 0x1b, 0x14); - return 1; } diff --git a/trunk/sound/pci/lx6464es/lx6464es.c b/trunk/sound/pci/lx6464es/lx6464es.c index 11b8c6514b3d..18da2ef04d09 100644 --- a/trunk/sound/pci/lx6464es/lx6464es.c +++ b/trunk/sound/pci/lx6464es/lx6464es.c @@ -654,12 +654,13 @@ static int __devinit lx_init_ethersound_config(struct lx6464es *chip) int i; u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES); - /* configure 64 io channels */ - u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) | + u32 default_conf_es = (64 << IOCR_OUTPUTS_OFFSET) | (64 << IOCR_INPUTS_OFFSET) | - (64 << IOCR_OUTPUTS_OFFSET) | (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET); + u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) + | (default_conf_es & CONFES_WRITE_PART_MASK); + snd_printdd("->lx_init_ethersound\n"); chip->freq_ratio = FREQ_RATIO_SINGLE_MODE; diff --git a/trunk/sound/pci/oxygen/oxygen_mixer.c b/trunk/sound/pci/oxygen/oxygen_mixer.c index 304da169bfdc..5401c547c4e3 100644 --- a/trunk/sound/pci/oxygen/oxygen_mixer.c +++ b/trunk/sound/pci/oxygen/oxygen_mixer.c @@ -575,8 +575,10 @@ static int ac97_switch_put(struct snd_kcontrol *ctl, static int ac97_volume_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { + int stereo = (ctl->private_value >> 16) & 1; + info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 2; + info->count = stereo ? 2 : 1; info->value.integer.min = 0; info->value.integer.max = 0x1f; return 0; @@ -587,6 +589,7 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; unsigned int codec = (ctl->private_value >> 24) & 1; + int stereo = (ctl->private_value >> 16) & 1; unsigned int index = ctl->private_value & 0xff; u16 reg; @@ -594,7 +597,8 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, reg = oxygen_read_ac97(chip, codec, index); mutex_unlock(&chip->mutex); value->value.integer.value[0] = 31 - (reg & 0x1f); - value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); + if (stereo) + value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); return 0; } @@ -603,6 +607,7 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; unsigned int codec = (ctl->private_value >> 24) & 1; + int stereo = (ctl->private_value >> 16) & 1; unsigned int index = ctl->private_value & 0xff; u16 oldreg, newreg; int change; @@ -612,8 +617,11 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, newreg = oldreg; newreg = (newreg & ~0x1f) | (31 - (value->value.integer.value[0] & 0x1f)); - newreg = (newreg & ~0x1f00) | - ((31 - (value->value.integer.value[0] & 0x1f)) << 8); + if (stereo) + newreg = (newreg & ~0x1f00) | + ((31 - (value->value.integer.value[1] & 0x1f)) << 8); + else + newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); change = newreg != oldreg; if (change) oxygen_write_ac97(chip, codec, index, newreg); @@ -673,7 +681,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, .private_value = ((codec) << 24) | ((invert) << 16) | \ ((bitnr) << 8) | (index), \ } -#define AC97_VOLUME(xname, codec, index) { \ +#define AC97_VOLUME(xname, codec, index, stereo) { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ @@ -682,7 +690,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, .get = ac97_volume_get, \ .put = ac97_volume_put, \ .tlv = { .p = ac97_db_scale, }, \ - .private_value = ((codec) << 24) | (index), \ + .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ } static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); @@ -882,18 +890,18 @@ static const struct { }; static const struct snd_kcontrol_new ac97_controls[] = { - AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC), + AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), - AC97_VOLUME("CD Capture Volume", 0, AC97_CD), + AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), - AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX), + AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX, 1), AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1), }; static const struct snd_kcontrol_new ac97_fp_controls[] = { - AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE), + AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE, 1), AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,