aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorSam Revitch <samr7@cs.washington.edu>2006-05-10 09:09:17 -0400
committerJaroslav Kysela <perex@suse.cz>2006-06-22 15:33:31 -0400
commit62fe78e90dc25b269362034487dc450cd8453e8c (patch)
treeeebf3a6431a50c179ffd5d019666bddad4f1cb3e /sound/pci/hda/patch_sigmatel.c
parent4d1a70dad0e1c44dc0725de6de25aceead48599e (diff)
[ALSA] hda-codec - Add support for Apple Mac Mini (early 2006)
Add support for some audio quirks of the Apple Mac Mini (early 2006) Signed-off-by: Sam Revitch <samr7@cs.washington.edu> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6d8224dc033b..36f199442fdc 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -41,6 +41,7 @@
41#define STAC_REF 0 41#define STAC_REF 0
42#define STAC_D945GTP3 1 42#define STAC_D945GTP3 1
43#define STAC_D945GTP5 2 43#define STAC_D945GTP5 2
44#define STAC_MACMINI 3
44 45
45struct sigmatel_spec { 46struct sigmatel_spec {
46 struct snd_kcontrol_new *mixers[4]; 47 struct snd_kcontrol_new *mixers[4];
@@ -52,6 +53,7 @@ struct sigmatel_spec {
52 unsigned int mic_switch: 1; 53 unsigned int mic_switch: 1;
53 unsigned int alt_switch: 1; 54 unsigned int alt_switch: 1;
54 unsigned int hp_detect: 1; 55 unsigned int hp_detect: 1;
56 unsigned int gpio_mute: 1;
55 57
56 /* playback */ 58 /* playback */
57 struct hda_multi_out multiout; 59 struct hda_multi_out multiout;
@@ -293,6 +295,7 @@ static unsigned int *stac922x_brd_tbl[] = {
293 ref922x_pin_configs, 295 ref922x_pin_configs,
294 d945gtp3_pin_configs, 296 d945gtp3_pin_configs,
295 d945gtp5_pin_configs, 297 d945gtp5_pin_configs,
298 NULL, /* STAC_MACMINI */
296}; 299};
297 300
298static struct hda_board_config stac922x_cfg_tbl[] = { 301static struct hda_board_config stac922x_cfg_tbl[] = {
@@ -324,6 +327,9 @@ static struct hda_board_config stac922x_cfg_tbl[] = {
324 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 327 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
325 .pci_subdevice = 0x0417, 328 .pci_subdevice = 0x0417,
326 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ 329 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */
330 { .pci_subvendor = 0x8384,
331 .pci_subdevice = 0x7680,
332 .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */
327 {} /* terminator */ 333 {} /* terminator */
328}; 334};
329 335
@@ -841,6 +847,19 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
841 } 847 }
842 } 848 }
843 849
850 if (imux->num_items == 1) {
851 /*
852 * Set the current input for the muxes.
853 * The STAC9221 has two input muxes with identical source
854 * NID lists. Hopefully this won't get confused.
855 */
856 for (i = 0; i < spec->num_muxes; i++) {
857 snd_hda_codec_write(codec, spec->mux_nids[i], 0,
858 AC_VERB_SET_CONNECT_SEL,
859 imux->items[0].index);
860 }
861 }
862
844 return 0; 863 return 0;
845} 864}
846 865
@@ -946,6 +965,45 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
946 return 1; 965 return 1;
947} 966}
948 967
968/*
969 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
970 * funky external mute control using GPIO pins.
971 */
972
973static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
974{
975 unsigned int gpiostate, gpiomask, gpiodir;
976
977 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
978 AC_VERB_GET_GPIO_DATA, 0);
979
980 if (!muted)
981 gpiostate |= (1 << pin);
982 else
983 gpiostate &= ~(1 << pin);
984
985 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
986 AC_VERB_GET_GPIO_MASK, 0);
987 gpiomask |= (1 << pin);
988
989 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
990 AC_VERB_GET_GPIO_DIRECTION, 0);
991 gpiodir |= (1 << pin);
992
993 /* AppleHDA seems to do this -- WTF is this verb?? */
994 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
995
996 snd_hda_codec_write(codec, codec->afg, 0,
997 AC_VERB_SET_GPIO_MASK, gpiomask);
998 snd_hda_codec_write(codec, codec->afg, 0,
999 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1000
1001 msleep(1);
1002
1003 snd_hda_codec_write(codec, codec->afg, 0,
1004 AC_VERB_SET_GPIO_DATA, gpiostate);
1005}
1006
949static int stac92xx_init(struct hda_codec *codec) 1007static int stac92xx_init(struct hda_codec *codec)
950{ 1008{
951 struct sigmatel_spec *spec = codec->spec; 1009 struct sigmatel_spec *spec = codec->spec;
@@ -982,6 +1040,11 @@ static int stac92xx_init(struct hda_codec *codec)
982 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, 1040 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
983 AC_PINCTL_IN_EN); 1041 AC_PINCTL_IN_EN);
984 1042
1043 if (spec->gpio_mute) {
1044 stac922x_gpio_mute(codec, 0, 0);
1045 stac922x_gpio_mute(codec, 1, 0);
1046 }
1047
985 return 0; 1048 return 0;
986} 1049}
987 1050
@@ -1132,7 +1195,7 @@ static int patch_stac922x(struct hda_codec *codec)
1132 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1195 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);
1133 if (spec->board_config < 0) 1196 if (spec->board_config < 0)
1134 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); 1197 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
1135 else { 1198 else if (stac922x_brd_tbl[spec->board_config] != NULL) {
1136 spec->num_pins = 10; 1199 spec->num_pins = 10;
1137 spec->pin_nids = stac922x_pin_nids; 1200 spec->pin_nids = stac922x_pin_nids;
1138 spec->pin_configs = stac922x_brd_tbl[spec->board_config]; 1201 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
@@ -1154,6 +1217,9 @@ static int patch_stac922x(struct hda_codec *codec)
1154 return err; 1217 return err;
1155 } 1218 }
1156 1219
1220 if (spec->board_config == STAC_MACMINI)
1221 spec->gpio_mute = 1;
1222
1157 codec->patch_ops = stac92xx_patch_ops; 1223 codec->patch_ops = stac92xx_patch_ops;
1158 1224
1159 return 0; 1225 return 0;