提交 3b98ec4e 编写于 作者: L Linus Torvalds

Merge tag 'sound-3.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Things get calming down, now we have only a few fix patches: a trivial
  fix for memory leak in usb-audio, a patch for the new HD-audio PCI id,
  a device-specific mute-LED fix, and a slightly big patch to cover the
  missing COEF inits of various Realtek codecs"

* tag 'sound-3.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Add mute LED control for Lenovo Ideapad Z560
  ALSA: hda/realtek - Change EAPD to verb control
  ALSA: usb-audio: Fix memory leak in FTU quirk
  ALSA: hda_intel: Add DeviceIDs for Sunrise Point-LP
......@@ -219,6 +219,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, LPT_LP},"
"{Intel, WPT_LP},"
"{Intel, SPT},"
"{Intel, SPT_LP},"
"{Intel, HPT},"
"{Intel, PBG},"
"{Intel, SCH},"
......@@ -2004,6 +2005,9 @@ static const struct pci_device_id azx_ids[] = {
/* Sunrise Point */
{ PCI_DEVICE(0x8086, 0xa170),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Sunrise Point-LP */
{ PCI_DEVICE(0x8086, 0x9d70),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Haswell */
{ PCI_DEVICE(0x8086, 0x0a0c),
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
......
......@@ -43,6 +43,7 @@ struct conexant_spec {
unsigned int num_eapds;
hda_nid_t eapds[4];
bool dynamic_eapd;
hda_nid_t mute_led_eapd;
unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
......@@ -163,6 +164,17 @@ static void cx_auto_vmaster_hook(void *private_data, int enabled)
cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
}
/* turn on/off EAPD according to Master switch (inversely!) for mute LED */
static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled)
{
struct hda_codec *codec = private_data;
struct conexant_spec *spec = codec->spec;
snd_hda_codec_write(codec, spec->mute_led_eapd, 0,
AC_VERB_SET_EAPD_BTLENABLE,
enabled ? 0x00 : 0x02);
}
static int cx_auto_build_controls(struct hda_codec *codec)
{
int err;
......@@ -223,6 +235,7 @@ enum {
CXT_FIXUP_TOSHIBA_P105,
CXT_FIXUP_HP_530,
CXT_FIXUP_CAP_MIX_AMP_5047,
CXT_FIXUP_MUTE_LED_EAPD,
};
/* for hda_fixup_thinkpad_acpi() */
......@@ -557,6 +570,18 @@ static void cxt_fixup_olpc_xo(struct hda_codec *codec,
}
}
static void cxt_fixup_mute_led_eapd(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct conexant_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mute_led_eapd = 0x1b;
spec->dynamic_eapd = 1;
spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook_mute_led;
}
}
/*
* Fix max input level on mixer widget to 0dB
* (originally it has 0x2b steps with 0dB offset 0x14)
......@@ -705,6 +730,10 @@ static const struct hda_fixup cxt_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = cxt_fixup_cap_mix_amp_5047,
},
[CXT_FIXUP_MUTE_LED_EAPD] = {
.type = HDA_FIXUP_FUNC,
.v.func = cxt_fixup_mute_led_eapd,
},
};
static const struct snd_pci_quirk cxt5045_fixups[] = {
......@@ -762,6 +791,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
......@@ -780,6 +810,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
{ .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" },
{ .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" },
{ .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" },
{ .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
{}
};
......
......@@ -288,6 +288,80 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
snd_hda_jack_unsol_event(codec, res >> 2);
}
/* Change EAPD to verb control */
static void alc_fill_eapd_coef(struct hda_codec *codec)
{
int coef;
coef = alc_get_coef0(codec);
switch (codec->vendor_id) {
case 0x10ec0262:
alc_update_coef_idx(codec, 0x7, 0, 1<<5);
break;
case 0x10ec0267:
case 0x10ec0268:
alc_update_coef_idx(codec, 0x7, 0, 1<<13);
break;
case 0x10ec0269:
if ((coef & 0x00f0) == 0x0010)
alc_update_coef_idx(codec, 0xd, 0, 1<<14);
if ((coef & 0x00f0) == 0x0020)
alc_update_coef_idx(codec, 0x4, 1<<15, 0);
if ((coef & 0x00f0) == 0x0030)
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break;
case 0x10ec0280:
case 0x10ec0284:
case 0x10ec0290:
case 0x10ec0292:
alc_update_coef_idx(codec, 0x4, 1<<15, 0);
break;
case 0x10ec0233:
case 0x10ec0255:
case 0x10ec0282:
case 0x10ec0283:
case 0x10ec0286:
case 0x10ec0288:
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break;
case 0x10ec0285:
case 0x10ec0293:
alc_update_coef_idx(codec, 0xa, 1<<13, 0);
break;
case 0x10ec0662:
if ((coef & 0x00f0) == 0x0030)
alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
break;
case 0x10ec0272:
case 0x10ec0273:
case 0x10ec0663:
case 0x10ec0665:
case 0x10ec0670:
case 0x10ec0671:
case 0x10ec0672:
alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
break;
case 0x10ec0668:
alc_update_coef_idx(codec, 0x7, 3<<13, 0);
break;
case 0x10ec0867:
alc_update_coef_idx(codec, 0x4, 1<<10, 0);
break;
case 0x10ec0888:
if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break;
case 0x10ec0892:
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break;
case 0x10ec0899:
case 0x10ec0900:
alc_update_coef_idx(codec, 0x7, 1<<1, 0);
break;
}
}
/* additional initialization for ALC888 variants */
static void alc888_coef_init(struct hda_codec *codec)
{
......@@ -339,6 +413,7 @@ static void alc_eapd_shutup(struct hda_codec *codec)
/* generic EAPD initialization */
static void alc_auto_init_amp(struct hda_codec *codec, int type)
{
alc_fill_eapd_coef(codec);
alc_auto_setup_eapd(codec, true);
switch (type) {
case ALC_INIT_GPIO1:
......@@ -5212,9 +5287,6 @@ static void alc269_fill_coef(struct hda_codec *codec)
}
}
/* Class D */
alc_update_coef_idx(codec, 0xd, 0, 1<<14);
/* HP */
alc_update_coef_idx(codec, 0x4, 0, 1<<11);
}
......@@ -6124,29 +6196,6 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
{}
};
static void alc662_fill_coef(struct hda_codec *codec)
{
int coef;
coef = alc_get_coef0(codec);
switch (codec->vendor_id) {
case 0x10ec0662:
if ((coef & 0x00f0) == 0x0030)
alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
break;
case 0x10ec0272:
case 0x10ec0273:
case 0x10ec0663:
case 0x10ec0665:
case 0x10ec0670:
case 0x10ec0671:
case 0x10ec0672:
alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
break;
}
}
/*
*/
static int patch_alc662(struct hda_codec *codec)
......@@ -6169,10 +6218,6 @@ static int patch_alc662(struct hda_codec *codec)
case 0x10ec0668:
spec->init_hook = alc668_restore_default_value;
break;
default:
spec->init_hook = alc662_fill_coef;
alc662_fill_coef(codec);
break;
}
snd_hda_pick_fixup(codec, alc662_fixup_models,
......
......@@ -885,6 +885,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
return changed;
}
static void kctl_private_value_free(struct snd_kcontrol *kctl)
{
kfree((void *)kctl->private_value);
}
static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
int validx, int bUnitID)
{
......@@ -919,6 +924,7 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
return -ENOMEM;
}
kctl->private_free = kctl_private_value_free;
err = snd_ctl_add(mixer->chip->card, kctl);
if (err < 0)
return err;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册