diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 106 | ||||
-rw-r--r-- | sound/pci/ice1712/prodigy_hifi.c | 131 | ||||
-rw-r--r-- | sound/pci/korg1212/korg1212.c | 1 |
3 files changed, 204 insertions, 34 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9aafc6c86132..93d2ce891db6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3166,6 +3166,93 @@ static void alc256_shutup(struct hda_codec *codec) snd_hda_shutup_pins(codec); } +static void alc225_init(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; + bool hp1_pin_sense, hp2_pin_sense; + + if (!hp_pin) + return; + + msleep(30); + + hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); + hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(2); + + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ + + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(85); + + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(100); + + alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ +} + +static void alc225_shutup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; + bool hp1_pin_sense, hp2_pin_sense; + + if (!hp_pin) { + alc269_shutup(codec); + return; + } + + /* 3k pull low control for Headset jack. */ + alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); + + hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); + hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(2); + + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(85); + + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + + if (hp1_pin_sense || hp2_pin_sense) + msleep(100); + + alc_auto_setup_eapd(codec, false); + snd_hda_shutup_pins(codec); +} + static void alc_default_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -4569,6 +4656,12 @@ static void alc_determine_headset_type(struct hda_codec *codec) case 0x10ec0225: case 0x10ec0295: case 0x10ec0299: + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + msleep(80); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + alc_process_coef_fw(codec, alc225_pre_hsmode); alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); val = alc_read_coef_idx(codec, 0x45); @@ -4588,6 +4681,12 @@ static void alc_determine_headset_type(struct hda_codec *codec) alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); + + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + msleep(80); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); break; case 0x10ec0867: is_ctia = true; @@ -6924,12 +7023,11 @@ static int patch_alc269(struct hda_codec *codec) break; case 0x10ec0225: case 0x10ec0295: - spec->codec_variant = ALC269_TYPE_ALC225; - spec->gen.mixer_nid = 0; /* no loopback on ALC225 ALC295 */ - break; case 0x10ec0299: spec->codec_variant = ALC269_TYPE_ALC225; - spec->gen.mixer_nid = 0; /* no loopback on ALC299 */ + spec->shutup = alc225_shutup; + spec->init_hook = alc225_init; + spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */ break; case 0x10ec0234: case 0x10ec0274: diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 2697402b5195..8dabd4d0211d 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -965,13 +965,32 @@ static int prodigy_hd2_add_controls(struct snd_ice1712 *ice) return 0; } +static void wm8766_init(struct snd_ice1712 *ice) +{ + static unsigned short wm8766_inits[] = { + WM8766_RESET, 0x0000, + WM8766_DAC_CTRL, 0x0120, + WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ + WM8766_DAC_CTRL2, 0x0001, + WM8766_DAC_CTRL3, 0x0080, + WM8766_LDA1, 0x0100, + WM8766_LDA2, 0x0100, + WM8766_LDA3, 0x0100, + WM8766_RDA1, 0x0100, + WM8766_RDA2, 0x0100, + WM8766_RDA3, 0x0100, + WM8766_MUTE1, 0x0000, + WM8766_MUTE2, 0x0000, + }; + unsigned int i; -/* - * initialize the chip - */ -static int prodigy_hifi_init(struct snd_ice1712 *ice) + for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) + wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i + 1]); +} + +static void wm8776_init(struct snd_ice1712 *ice) { - static unsigned short wm_inits[] = { + static unsigned short wm8776_inits[] = { /* These come first to reduce init pop noise */ WM_ADC_MUX, 0x0003, /* ADC mute */ /* 0x00c0 replaced by 0x0003 */ @@ -982,7 +1001,76 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) WM_POWERDOWN, 0x0008, /* All power-up except HP */ WM_RESET, 0x0000, /* reset */ }; - static unsigned short wm_inits2[] = { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(wm8776_inits); i += 2) + wm_put(ice, wm8776_inits[i], wm8776_inits[i + 1]); +} + +#ifdef CONFIG_PM_SLEEP +static int prodigy_hifi_resume(struct snd_ice1712 *ice) +{ + static unsigned short wm8776_reinit_registers[] = { + WM_MASTER_CTRL, + WM_DAC_INT, + WM_ADC_INT, + WM_OUT_MUX, + WM_HP_ATTEN_L, + WM_HP_ATTEN_R, + WM_PHASE_SWAP, + WM_DAC_CTRL2, + WM_ADC_ATTEN_L, + WM_ADC_ATTEN_R, + WM_ALC_CTRL1, + WM_ALC_CTRL2, + WM_ALC_CTRL3, + WM_NOISE_GATE, + WM_ADC_MUX, + /* no DAC attenuation here */ + }; + struct prodigy_hifi_spec *spec = ice->spec; + int i, ch; + + mutex_lock(&ice->gpio_mutex); + + /* reinitialize WM8776 and re-apply old register values */ + wm8776_init(ice); + schedule_timeout_uninterruptible(1); + for (i = 0; i < ARRAY_SIZE(wm8776_reinit_registers); i++) + wm_put(ice, wm8776_reinit_registers[i], + wm_get(ice, wm8776_reinit_registers[i])); + + /* reinitialize WM8766 and re-apply volumes for all DACs */ + wm8766_init(ice); + for (ch = 0; ch < 2; ch++) { + wm_set_vol(ice, WM_DAC_ATTEN_L + ch, + spec->vol[2 + ch], spec->master[ch]); + + wm8766_set_vol(ice, WM8766_LDA1 + ch, + spec->vol[0 + ch], spec->master[ch]); + + wm8766_set_vol(ice, WM8766_LDA2 + ch, + spec->vol[4 + ch], spec->master[ch]); + + wm8766_set_vol(ice, WM8766_LDA3 + ch, + spec->vol[6 + ch], spec->master[ch]); + } + + /* unmute WM8776 DAC */ + wm_put(ice, WM_DAC_MUTE, 0x00); + wm_put(ice, WM_DAC_CTRL1, 0x90); + + mutex_unlock(&ice->gpio_mutex); + return 0; +} +#endif + +/* + * initialize the chip + */ +static int prodigy_hifi_init(struct snd_ice1712 *ice) +{ + static unsigned short wm8776_defaults[] = { WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ @@ -1010,22 +1098,6 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) WM_DAC_MUTE, 0x0000, /* DAC unmute */ WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ }; - static unsigned short wm8766_inits[] = { - WM8766_RESET, 0x0000, - WM8766_DAC_CTRL, 0x0120, - WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ - WM8766_DAC_CTRL2, 0x0001, - WM8766_DAC_CTRL3, 0x0080, - WM8766_LDA1, 0x0100, - WM8766_LDA2, 0x0100, - WM8766_LDA3, 0x0100, - WM8766_RDA1, 0x0100, - WM8766_RDA2, 0x0100, - WM8766_RDA3, 0x0100, - WM8766_MUTE1, 0x0000, - WM8766_MUTE2, 0x0000, - }; - struct prodigy_hifi_spec *spec; unsigned int i; @@ -1052,16 +1124,17 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) ice->spec = spec; /* initialize WM8776 codec */ - for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) - wm_put(ice, wm_inits[i], wm_inits[i+1]); + wm8776_init(ice); schedule_timeout_uninterruptible(1); - for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2) - wm_put(ice, wm_inits2[i], wm_inits2[i+1]); + for (i = 0; i < ARRAY_SIZE(wm8776_defaults); i += 2) + wm_put(ice, wm8776_defaults[i], wm8776_defaults[i + 1]); - /* initialize WM8766 codec */ - for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) - wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]); + wm8766_init(ice); +#ifdef CONFIG_PM_SLEEP + ice->pm_resume = &prodigy_hifi_resume; + ice->pm_suspend_enabled = 1; +#endif return 0; } diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index c7b007164c99..4206ba44d8bb 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -2348,7 +2348,6 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { - release_firmware(dsp_code); snd_printk(KERN_ERR "firmware not available\n"); snd_korg1212_free(korg1212); return err; |