Commit 3d5a0863 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull sound fixes from Takashi Iwai:
 "This update contains mostly only fixes for Realtek HD-audio codec
  driver in addition to a long-standing sysfs warning bug fix for
  USB-audio.

  One significant fix for Realtek codecs is the update of EAPD init
  codes.  This avoids invalid COEF setups for some codec models and may
  fix "lost sound" in some cases.

  The rest are a bit high volume but only new quirks and ALC668-specific
  COEF tables"

* tag 'sound-3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/realtek - Restore default value for ALC668
  ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect
  ALSA: hda - fix mute led problem for three HP laptops
  ALSA: hda/realtek - Update Initial AMP for EAPD control
  ALSA: hda - change three SSID quirks to one pin quirk
  ALSA: hda - Set GPIO 4 low for a few HP machines
  ALSA: hda - Add ultra dock support for Thinkpad X240.
parents 381e3554 f3f9185f
...@@ -291,18 +291,14 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) ...@@ -291,18 +291,14 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
/* additional initialization for ALC888 variants */ /* additional initialization for ALC888 variants */
static void alc888_coef_init(struct hda_codec *codec) static void alc888_coef_init(struct hda_codec *codec)
{ {
if (alc_get_coef0(codec) == 0x20) switch (alc_get_coef0(codec) & 0x00f0) {
/* alc888S-VC */ /* alc888-VA */
alc_write_coef_idx(codec, 7, 0x830); case 0x00:
else
/* alc888-VB */ /* alc888-VB */
alc_write_coef_idx(codec, 7, 0x3030); case 0x10:
} alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
break;
/* additional initialization for ALC889 variants */ }
static void alc889_coef_init(struct hda_codec *codec)
{
alc_update_coef_idx(codec, 7, 0, 0x2010);
} }
/* turn on/off EAPD control (only if available) */ /* turn on/off EAPD control (only if available) */
...@@ -359,25 +355,15 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) ...@@ -359,25 +355,15 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
case 0x10ec0260: case 0x10ec0260:
alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010); alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
break; break;
case 0x10ec0262:
case 0x10ec0880: case 0x10ec0880:
case 0x10ec0882: case 0x10ec0882:
case 0x10ec0883: case 0x10ec0883:
case 0x10ec0885: case 0x10ec0885:
case 0x10ec0887: alc_update_coef_idx(codec, 7, 0, 0x2030);
/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
case 0x10ec0900:
alc889_coef_init(codec);
break; break;
case 0x10ec0888: case 0x10ec0888:
alc888_coef_init(codec); alc888_coef_init(codec);
break; break;
#if 0 /* XXX: This may cause the silent output on speaker on some machines */
case 0x10ec0267:
case 0x10ec0268:
alc_update_coef_idx(codec, 7, 0, 0x3000);
break;
#endif /* XXX */
} }
break; break;
} }
...@@ -1710,7 +1696,7 @@ static void alc889_fixup_coef(struct hda_codec *codec, ...@@ -1710,7 +1696,7 @@ static void alc889_fixup_coef(struct hda_codec *codec,
{ {
if (action != HDA_FIXUP_ACT_INIT) if (action != HDA_FIXUP_ACT_INIT)
return; return;
alc889_coef_init(codec); alc_update_coef_idx(codec, 7, 0, 0x2030);
} }
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
...@@ -3350,6 +3336,27 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, ...@@ -3350,6 +3336,27 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
} }
} }
static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
/* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
struct alc_spec *spec = codec->spec;
static const struct hda_verb gpio_init[] = {
{ 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
{}
};
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
spec->gpio_led = 0;
spec->cap_mute_led_nid = 0x18;
snd_hda_add_verbs(codec, gpio_init);
codec->power_filter = led_power_filter;
}
}
static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action) const struct hda_fixup *fix, int action)
{ {
...@@ -4217,6 +4224,7 @@ enum { ...@@ -4217,6 +4224,7 @@ enum {
ALC283_FIXUP_BXBT2807_MIC, ALC283_FIXUP_BXBT2807_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS, ALC282_FIXUP_ASPIRE_V5_PINS,
ALC280_FIXUP_HP_GPIO4,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -4680,7 +4688,10 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -4680,7 +4688,10 @@ static const struct hda_fixup alc269_fixups[] = {
{ }, { },
}, },
}, },
[ALC280_FIXUP_HP_GPIO4] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc280_fixup_hp_gpio4,
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -4728,21 +4739,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -4728,21 +4739,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x8004, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
/* ALC290 */ /* ALC290 */
SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2258, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
...@@ -4751,7 +4757,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -4751,7 +4757,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2277, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
...@@ -4804,7 +4809,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -4804,7 +4809,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
...@@ -4984,6 +4989,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { ...@@ -4984,6 +4989,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x17, 0x40000000}, {0x17, 0x40000000},
{0x1d, 0x40700001}, {0x1d, 0x40700001},
{0x21, 0x02211040}), {0x21, 0x02211040}),
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
{0x12, 0x90a60130},
{0x13, 0x40000000},
{0x14, 0x90170110},
{0x15, 0x0421101f},
{0x16, 0x411111f0},
{0x17, 0x411111f0},
{0x18, 0x411111f0},
{0x19, 0x411111f0},
{0x1a, 0x04a11020},
{0x1b, 0x411111f0},
{0x1d, 0x40748605},
{0x1e, 0x411111f0}),
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED, SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
{0x12, 0x90a60140}, {0x12, 0x90a60140},
{0x13, 0x40000000}, {0x13, 0x40000000},
...@@ -5651,6 +5669,35 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec, ...@@ -5651,6 +5669,35 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec,
} }
} }
static struct coef_fw alc668_coefs[] = {
WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
{}
};
static void alc668_restore_default_value(struct hda_codec *codec)
{
alc_process_coef_fw(codec, alc668_coefs);
}
enum { enum {
ALC662_FIXUP_ASPIRE, ALC662_FIXUP_ASPIRE,
ALC662_FIXUP_LED_GPIO1, ALC662_FIXUP_LED_GPIO1,
...@@ -6118,8 +6165,15 @@ static int patch_alc662(struct hda_codec *codec) ...@@ -6118,8 +6165,15 @@ static int patch_alc662(struct hda_codec *codec)
alc_fix_pll_init(codec, 0x20, 0x04, 15); alc_fix_pll_init(codec, 0x20, 0x04, 15);
switch (codec->vendor_id) {
case 0x10ec0668:
spec->init_hook = alc668_restore_default_value;
break;
default:
spec->init_hook = alc662_fill_coef; spec->init_hook = alc662_fill_coef;
alc662_fill_coef(codec); alc662_fill_coef(codec);
break;
}
snd_hda_pick_fixup(codec, alc662_fixup_models, snd_hda_pick_fixup(codec, alc662_fixup_models,
alc662_fixup_tbl, alc662_fixups); alc662_fixup_tbl, alc662_fixups);
......
...@@ -591,18 +591,19 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, ...@@ -591,18 +591,19 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
{ {
struct snd_card *card; struct snd_card *card;
struct list_head *p; struct list_head *p;
bool was_shutdown;
if (chip == (void *)-1L) if (chip == (void *)-1L)
return; return;
card = chip->card; card = chip->card;
down_write(&chip->shutdown_rwsem); down_write(&chip->shutdown_rwsem);
was_shutdown = chip->shutdown;
chip->shutdown = 1; chip->shutdown = 1;
up_write(&chip->shutdown_rwsem); up_write(&chip->shutdown_rwsem);
mutex_lock(&register_mutex); mutex_lock(&register_mutex);
chip->num_interfaces--; if (!was_shutdown) {
if (chip->num_interfaces <= 0) {
struct snd_usb_endpoint *ep; struct snd_usb_endpoint *ep;
snd_card_disconnect(card); snd_card_disconnect(card);
...@@ -622,6 +623,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, ...@@ -622,6 +623,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
list_for_each(p, &chip->mixer_list) { list_for_each(p, &chip->mixer_list) {
snd_usb_mixer_disconnect(p); snd_usb_mixer_disconnect(p);
} }
}
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
usb_chip[chip->index] = NULL; usb_chip[chip->index] = NULL;
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
snd_card_free_when_closed(card); snd_card_free_when_closed(card);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment