Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6dfeb703 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Tested-by: default avatarDirk Hohndel <hohndel@infradead.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent e2301a4d
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -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;
	}