ALSA: hda - Fix invalid pin and GPIO for Apple laptops with CS codecs
The PCI SSID 8086:7270 is commonly used for multiple Apple machines, thus we can't use it as identifier for a unique model. Because of this conflict, some machines show weird behavior. For example, MacBook Air shows Front and Surround speakers although only Surround works due to the wrongly overridden pin-configuration for imac27. This patch fixes two things: - Stop the wrong pin-config override of imac27 by removing PCI SSID entry for avoiding the wrong mappings, - Add the generic GPIO setup for Apple machines by checking the codec SSID vendor bits Tested-by: Linus Torvalds <torvalds@linux-foundation.org> Tested-by: Dirk Hohndel <hohndel@infradead.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
e2301a4de2
commit
6dfeb703e3
1 changed files with 23 additions and 9 deletions
|
@ -58,6 +58,8 @@ struct cs_spec {
|
|||
unsigned int gpio_mask;
|
||||
unsigned int gpio_dir;
|
||||
unsigned int gpio_data;
|
||||
unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */
|
||||
unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */
|
||||
|
||||
struct hda_pcm pcm_rec[2]; /* PCM information */
|
||||
|
||||
|
@ -76,6 +78,7 @@ enum {
|
|||
CS420X_MBP53,
|
||||
CS420X_MBP55,
|
||||
CS420X_IMAC27,
|
||||
CS420X_APPLE,
|
||||
CS420X_AUTO,
|
||||
CS420X_MODELS
|
||||
};
|
||||
|
@ -928,10 +931,9 @@ static void cs_automute(struct hda_codec *codec)
|
|||
spdif_present ? 0 : PIN_OUT);
|
||||
}
|
||||
}
|
||||
if (spec->board_config == CS420X_MBP53 ||
|
||||
spec->board_config == CS420X_MBP55 ||
|
||||
spec->board_config == CS420X_IMAC27) {
|
||||
unsigned int gpio = hp_present ? 0x02 : 0x08;
|
||||
if (spec->gpio_eapd_hp) {
|
||||
unsigned int gpio = hp_present ?
|
||||
spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
|
||||
snd_hda_codec_write(codec, 0x01, 0,
|
||||
AC_VERB_SET_GPIO_DATA, gpio);
|
||||
}
|
||||
|
@ -1276,6 +1278,7 @@ static const char * const cs420x_models[CS420X_MODELS] = {
|
|||
[CS420X_MBP53] = "mbp53",
|
||||
[CS420X_MBP55] = "mbp55",
|
||||
[CS420X_IMAC27] = "imac27",
|
||||
[CS420X_IMAC27] = "apple",
|
||||
[CS420X_AUTO] = "auto",
|
||||
};
|
||||
|
||||
|
@ -1285,7 +1288,13 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
|
|||
SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
|
||||
SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
|
||||
SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
|
||||
SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
|
||||
/* this conflicts with too many other models */
|
||||
/*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
|
@ -1367,6 +1376,10 @@ static int patch_cs420x(struct hda_codec *codec)
|
|||
spec->board_config =
|
||||
snd_hda_check_board_config(codec, CS420X_MODELS,
|
||||
cs420x_models, cs420x_cfg_tbl);
|
||||
if (spec->board_config < 0)
|
||||
spec->board_config =
|
||||
snd_hda_check_board_codec_sid_config(codec,
|
||||
CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
|
||||
if (spec->board_config >= 0)
|
||||
fix_pincfg(codec, spec->board_config, cs_pincfgs);
|
||||
|
||||
|
@ -1374,10 +1387,11 @@ static int patch_cs420x(struct hda_codec *codec)
|
|||
case CS420X_IMAC27:
|
||||
case CS420X_MBP53:
|
||||
case CS420X_MBP55:
|
||||
/* GPIO1 = headphones */
|
||||
/* GPIO3 = speakers */
|
||||
spec->gpio_mask = 0x0a;
|
||||
spec->gpio_dir = 0x0a;
|
||||
case CS420X_APPLE:
|
||||
spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
|
||||
spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
|
||||
spec->gpio_mask = spec->gpio_dir =
|
||||
spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue