aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-24 10:06:23 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:29:47 -0500
commitd32410b1095cf93e8e31f8919de46f496d7b3ce0 (patch)
tree8d4b825c568c6bde3fa751320fa1e03e26052773 /sound
parentb2ec642362eef10f660e2b857dda12e2d61e0198 (diff)
[ALSA] hda-codec - Fix/enhance AD1988 support
Modules: HDA Codec driver Fix/enhance AD1988 support code. - Fix for h/w bug of AD1988A rev 2 - The BIOS auto-configuration is added and used as fallback Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_analog.c572
1 files changed, 531 insertions, 41 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 3799d8a1afae..fabcbcf77a10 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * HD audio interface patch for AD1981HD, AD1983, AD1986A 2 * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988
3 * 3 *
4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> 4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
5 * 5 *
@@ -31,7 +31,7 @@ struct ad198x_spec {
31 struct snd_kcontrol_new *mixers[5]; 31 struct snd_kcontrol_new *mixers[5];
32 int num_mixers; 32 int num_mixers;
33 33
34 const struct hda_verb *init_verbs[3]; /* initialization verbs 34 const struct hda_verb *init_verbs[5]; /* initialization verbs
35 * don't forget NULL termination! 35 * don't forget NULL termination!
36 */ 36 */
37 unsigned int num_init_verbs; 37 unsigned int num_init_verbs;
@@ -62,6 +62,13 @@ struct ad198x_spec {
62 62
63 struct semaphore amp_mutex; /* PCM volume/mute control mutex */ 63 struct semaphore amp_mutex; /* PCM volume/mute control mutex */
64 unsigned int spdif_route; 64 unsigned int spdif_route;
65
66 /* dynamic controls, init_verbs and input_mux */
67 struct auto_pin_cfg autocfg;
68 unsigned int num_kctl_alloc, num_kctl_used;
69 struct snd_kcontrol_new *kctl_alloc;
70 struct hda_input_mux private_imux;
71 hda_nid_t private_dac_nids[4];
65}; 72};
66 73
67/* 74/*
@@ -284,6 +291,14 @@ static int ad198x_build_pcms(struct hda_codec *codec)
284 291
285static void ad198x_free(struct hda_codec *codec) 292static void ad198x_free(struct hda_codec *codec)
286{ 293{
294 struct ad198x_spec *spec = codec->spec;
295 unsigned int i;
296
297 if (spec->kctl_alloc) {
298 for (i = 0; i < spec->num_kctl_used; i++)
299 kfree(spec->kctl_alloc[i].name);
300 kfree(spec->kctl_alloc);
301 }
287 kfree(codec->spec); 302 kfree(codec->spec);
288} 303}
289 304
@@ -867,7 +882,7 @@ static int patch_ad1981(struct hda_codec *codec)
867 * 882 *
868 * Output pins and routes 883 * Output pins and routes
869 * 884 *
870 * Pin Mix Sel DAC 885 * Pin Mix Sel DAC (*)
871 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 886 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
872 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 887 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
873 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a 888 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a
@@ -878,6 +893,8 @@ static int patch_ad1981(struct hda_codec *codec)
878 * port-H 0x25 (mute) <- 0x28 <- 0a 893 * port-H 0x25 (mute) <- 0x28 <- 0a
879 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 894 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
880 * 895 *
896 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
897 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
881 * 898 *
882 * Input pins and routes 899 * Input pins and routes
883 * 900 *
@@ -893,11 +910,8 @@ static int patch_ad1981(struct hda_codec *codec)
893 * 910 *
894 * 911 *
895 * DAC assignment 912 * DAC assignment
896 * front DAC - 04 913 * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
897 * surr DAC - 06 914 * 3stack - front/surr/CLFE/opt DACs - 04/0a/05/03
898 * CLFE DAC - 05
899 * side DAC - 0a
900 * opt DAC - 03
901 * 915 *
902 * Inputs of Analog Mix (0x20) 916 * Inputs of Analog Mix (0x20)
903 * 0:Port-B (front mic) 917 * 0:Port-B (front mic)
@@ -957,18 +971,35 @@ enum {
957 AD1988_3STACK_DIG, 971 AD1988_3STACK_DIG,
958 AD1988_LAPTOP, 972 AD1988_LAPTOP,
959 AD1988_LAPTOP_DIG, 973 AD1988_LAPTOP_DIG,
974 AD1988_AUTO,
960 AD1988_MODEL_LAST, 975 AD1988_MODEL_LAST,
961}; 976};
962 977
978/* reivision id to check workarounds */
979#define AD1988A_REV2 0x100200
980
963 981
964/* 982/*
965 * mixers 983 * mixers
966 */ 984 */
967 985
968static hda_nid_t ad1988_dac_nids[4] = { 986static hda_nid_t ad1988_6stack_dac_nids[4] = {
969 0x04, 0x06, 0x05, 0x0a 987 0x04, 0x06, 0x05, 0x0a
970}; 988};
971 989
990static hda_nid_t ad1988_3stack_dac_nids[3] = {
991 0x04, 0x0a, 0x05
992};
993
994/* for AD1988A revision-2, DAC2-4 are swapped */
995static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
996 0x04, 0x05, 0x0a, 0x06
997};
998
999static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1000 0x04, 0x06, 0x0a
1001};
1002
972static hda_nid_t ad1988_adc_nids[3] = { 1003static hda_nid_t ad1988_adc_nids[3] = {
973 0x08, 0x09, 0x0f 1004 0x08, 0x09, 0x0f
974}; 1005};
@@ -1068,13 +1099,23 @@ static int ad1988_eapd_put(struct snd_kcontrol *kcontrol,
1068} 1099}
1069 1100
1070/* 6-stack mode */ 1101/* 6-stack mode */
1071static struct snd_kcontrol_new ad1988_6stack_mixers[] = { 1102static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
1072 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1103 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1073 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1104 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1074 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 1105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1075 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 1106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1076 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 1107 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1108};
1109
1110static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
1111 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1112 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1113 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1114 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
1115 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1116};
1077 1117
1118static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
1078 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 1119 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1079 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 1120 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 1121 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
@@ -1105,16 +1146,25 @@ static struct snd_kcontrol_new ad1988_6stack_mixers[] = {
1105}; 1146};
1106 1147
1107/* 3-stack mode */ 1148/* 3-stack mode */
1108static struct snd_kcontrol_new ad1988_3stack_mixers[] = { 1149static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
1109 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1150 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1110 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 1152 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 1153 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1154};
1155
1156static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
1157 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1158 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1159 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1160 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
1161};
1113 1162
1163static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
1114 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 1164 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1115 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 1165 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
1116 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 1166 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
1117 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), 1167 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
1118 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 1168 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1119 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 1169 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1120 1170
@@ -1391,11 +1441,11 @@ static struct hda_verb ad1988_3stack_ch2_init[] = {
1391 1441
1392static struct hda_verb ad1988_3stack_ch6_init[] = { 1442static struct hda_verb ad1988_3stack_ch6_init[] = {
1393 /* set port-C to surround out */ 1443 /* set port-C to surround out */
1394 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1395 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1444 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1445 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1396 /* set port-E to CLFE out */ 1446 /* set port-E to CLFE out */
1397 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1398 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1448 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1399 { } /* end */ 1449 { } /* end */
1400}; 1450};
1401 1451
@@ -1431,15 +1481,17 @@ static struct hda_verb ad1988_3stack_init_verbs[] = {
1431 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1432 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1433 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1483 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1434 /* Port-C line-in/surround path */ 1484 /* Port-C line-in/surround path - 6ch mode as default */
1435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1436 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1437 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1487 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1488 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
1438 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1489 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
1439 /* Port-E mic-in/CLFE path */ 1490 /* Port-E mic-in/CLFE path - 6ch mode as default */
1440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1441 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1442 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1493 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1494 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x06 */
1443 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 1495 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
1444 /* mute analog mix */ 1496 /* mute analog mix */
1445 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1497 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -1546,6 +1598,420 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
1546 1598
1547 1599
1548/* 1600/*
1601 * Automatic parse of I/O pins from the BIOS configuration
1602 */
1603
1604#define NUM_CONTROL_ALLOC 32
1605#define NUM_VERB_ALLOC 32
1606
1607enum {
1608 AD_CTL_WIDGET_VOL,
1609 AD_CTL_WIDGET_MUTE,
1610 AD_CTL_BIND_MUTE,
1611};
1612static struct snd_kcontrol_new ad1988_control_templates[] = {
1613 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
1614 HDA_CODEC_MUTE(NULL, 0, 0, 0),
1615 HDA_BIND_MUTE(NULL, 0, 0, 0),
1616};
1617
1618/* add dynamic controls */
1619static int add_control(struct ad198x_spec *spec, int type, const char *name,
1620 unsigned long val)
1621{
1622 struct snd_kcontrol_new *knew;
1623
1624 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1625 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1626
1627 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1628 if (! knew)
1629 return -ENOMEM;
1630 if (spec->kctl_alloc) {
1631 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1632 kfree(spec->kctl_alloc);
1633 }
1634 spec->kctl_alloc = knew;
1635 spec->num_kctl_alloc = num;
1636 }
1637
1638 knew = &spec->kctl_alloc[spec->num_kctl_used];
1639 *knew = ad1988_control_templates[type];
1640 knew->name = kstrdup(name, GFP_KERNEL);
1641 if (! knew->name)
1642 return -ENOMEM;
1643 knew->private_value = val;
1644 spec->num_kctl_used++;
1645 return 0;
1646}
1647
1648#define AD1988_PIN_CD_NID 0x18
1649#define AD1988_PIN_BEEP_NID 0x10
1650
1651static hda_nid_t ad1988_mixer_nids[8] = {
1652 /* A B C D E F G H */
1653 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
1654};
1655
1656static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
1657{
1658 static hda_nid_t idx_to_dac[8] = {
1659 /* A B C D E F G H */
1660 0x04, 0x06, 0x0a, 0x04, 0x05, 0x06, 0x05, 0x0a
1661 };
1662 static hda_nid_t idx_to_dac_rev2[8] = {
1663 /* A B C D E F G H */
1664 0x04, 0x05, 0x06, 0x04, 0x0a, 0x05, 0x0a, 0x06
1665 };
1666 if (codec->revision_id == AD1988A_REV2)
1667 return idx_to_dac_rev2[idx];
1668 else
1669 return idx_to_dac[idx];
1670}
1671
1672static hda_nid_t ad1988_boost_nids[8] = {
1673 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
1674};
1675
1676static int ad1988_pin_idx(hda_nid_t nid)
1677{
1678 static hda_nid_t ad1988_io_pins[8] = {
1679 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
1680 };
1681 int i;
1682 for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
1683 if (ad1988_io_pins[i] == nid)
1684 return i;
1685 return 0; /* should be -1 */
1686}
1687
1688static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
1689{
1690 static int loopback_idx[8] = {
1691 2, 0, 1, 3, 4, 5, 1, 4
1692 };
1693 switch (nid) {
1694 case AD1988_PIN_CD_NID:
1695 return 6;
1696 default:
1697 return loopback_idx[ad1988_pin_idx(nid)];
1698 }
1699}
1700
1701static int ad1988_pin_to_adc_idx(hda_nid_t nid)
1702{
1703 static int adc_idx[8] = {
1704 0, 1, 2, 8, 4, 3, 6, 7
1705 };
1706 switch (nid) {
1707 case AD1988_PIN_CD_NID:
1708 return 5;
1709 default:
1710 return adc_idx[ad1988_pin_idx(nid)];
1711 }
1712}
1713
1714/* fill in the dac_nids table from the parsed pin configuration */
1715static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
1716 const struct auto_pin_cfg *cfg)
1717{
1718 struct ad198x_spec *spec = codec->spec;
1719 int i, idx;
1720
1721 spec->multiout.dac_nids = spec->private_dac_nids;
1722
1723 /* check the pins hardwired to audio widget */
1724 for (i = 0; i < cfg->line_outs; i++) {
1725 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
1726 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
1727 }
1728 spec->multiout.num_dacs = cfg->line_outs;
1729 return 0;
1730}
1731
1732/* add playback controls from the parsed DAC table */
1733static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
1734 const struct auto_pin_cfg *cfg)
1735{
1736 char name[32];
1737 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
1738 hda_nid_t nid;
1739 int i, err;
1740
1741 for (i = 0; i < cfg->line_outs; i++) {
1742 hda_nid_t dac = spec->multiout.dac_nids[i];
1743 if (! dac)
1744 continue;
1745 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
1746 if (i == 2) {
1747 /* Center/LFE */
1748 err = add_control(spec, AD_CTL_WIDGET_VOL,
1749 "Center Playback Volume",
1750 HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
1751 if (err < 0)
1752 return err;
1753 err = add_control(spec, AD_CTL_WIDGET_VOL,
1754 "LFE Playback Volume",
1755 HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
1756 if (err < 0)
1757 return err;
1758 err = add_control(spec, AD_CTL_BIND_MUTE,
1759 "Center Playback Switch",
1760 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
1761 if (err < 0)
1762 return err;
1763 err = add_control(spec, AD_CTL_BIND_MUTE,
1764 "LFE Playback Switch",
1765 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
1766 if (err < 0)
1767 return err;
1768 } else {
1769 sprintf(name, "%s Playback Volume", chname[i]);
1770 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
1771 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
1772 if (err < 0)
1773 return err;
1774 sprintf(name, "%s Playback Switch", chname[i]);
1775 err = add_control(spec, AD_CTL_BIND_MUTE, name,
1776 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
1777 if (err < 0)
1778 return err;
1779 }
1780 }
1781 return 0;
1782}
1783
1784/* add playback controls for speaker and HP outputs */
1785static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
1786 const char *pfx)
1787{
1788 struct ad198x_spec *spec = codec->spec;
1789 hda_nid_t nid;
1790 int idx, err;
1791 char name[32];
1792
1793 if (! pin)
1794 return 0;
1795
1796 idx = ad1988_pin_idx(pin);
1797 nid = ad1988_idx_to_dac(codec, idx);
1798 if (! spec->multiout.dac_nids[0]) {
1799 /* use this as the primary output */
1800 spec->multiout.dac_nids[0] = nid;
1801 if (! spec->multiout.num_dacs)
1802 spec->multiout.num_dacs = 1;
1803 } else
1804 /* specify the DAC as the extra output */
1805 spec->multiout.hp_nid = nid;
1806 /* control HP volume/switch on the output mixer amp */
1807 sprintf(name, "%s Playback Volume", pfx);
1808 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
1809 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
1810 return err;
1811 nid = ad1988_mixer_nids[idx];
1812 sprintf(name, "%s Playback Switch", pfx);
1813 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
1814 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
1815 return err;
1816 return 0;
1817}
1818
1819/* create input playback/capture controls for the given pin */
1820static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
1821 const char *ctlname, int boost)
1822{
1823 char name[32];
1824 int err, idx;
1825
1826 sprintf(name, "%s Playback Volume", ctlname);
1827 idx = ad1988_pin_to_loopback_idx(pin);
1828 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
1829 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
1830 return err;
1831 sprintf(name, "%s Playback Switch", ctlname);
1832 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
1833 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
1834 return err;
1835 if (boost) {
1836 hda_nid_t bnid;
1837 idx = ad1988_pin_idx(pin);
1838 bnid = ad1988_boost_nids[idx];
1839 if (bnid) {
1840 sprintf(name, "%s Boost", ctlname);
1841 return add_control(spec, AD_CTL_WIDGET_VOL, name,
1842 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
1843
1844 }
1845 }
1846 return 0;
1847}
1848
1849/* create playback/capture controls for input pins */
1850static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
1851 const struct auto_pin_cfg *cfg)
1852{
1853 static char *labels[AUTO_PIN_LAST] = {
1854 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
1855 };
1856 struct hda_input_mux *imux = &spec->private_imux;
1857 int i, err;
1858
1859 for (i = 0; i < AUTO_PIN_LAST; i++) {
1860 err = new_analog_input(spec, cfg->input_pins[i], labels[i],
1861 i <= AUTO_PIN_FRONT_MIC);
1862 if (err < 0)
1863 return err;
1864 imux->items[imux->num_items].label = labels[i];
1865 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
1866 imux->num_items++;
1867 }
1868 imux->items[imux->num_items].label = "Mix";
1869 imux->items[imux->num_items].index = 9;
1870 imux->num_items++;
1871
1872 if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
1873 "Analog Mix Playback Volume",
1874 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
1875 return err;
1876 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
1877 "Analog Mix Playback Switch",
1878 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
1879 return err;
1880
1881 return 0;
1882}
1883
1884static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
1885 hda_nid_t nid, int pin_type,
1886 int dac_idx)
1887{
1888 /* set as output */
1889 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1890 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
1891 switch (nid) {
1892 case 0x11: /* port-A - DAC 04 */
1893 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
1894 break;
1895 case 0x14: /* port-B - DAC 06 */
1896 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
1897 break;
1898 case 0x15: /* port-C - DAC 05 */
1899 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
1900 break;
1901 case 0x17: /* port-E - DAC 06 */
1902 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
1903 break;
1904 case 0x13: /* mono - DAC 04 */
1905 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
1906 break;
1907 }
1908}
1909
1910static void ad1988_auto_init_multi_out(struct hda_codec *codec)
1911{
1912 struct ad198x_spec *spec = codec->spec;
1913 int i;
1914
1915 for (i = 0; i < spec->autocfg.line_outs; i++) {
1916 hda_nid_t nid = spec->autocfg.line_out_pins[i];
1917 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
1918 }
1919}
1920
1921static void ad1988_auto_init_extra_out(struct hda_codec *codec)
1922{
1923 struct ad198x_spec *spec = codec->spec;
1924 hda_nid_t pin;
1925
1926 pin = spec->autocfg.speaker_pin;
1927 if (pin) /* connect to front */
1928 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
1929 pin = spec->autocfg.hp_pin;
1930 if (pin) /* connect to front */
1931 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
1932}
1933
1934static void ad1988_auto_init_analog_input(struct hda_codec *codec)
1935{
1936 struct ad198x_spec *spec = codec->spec;
1937 int i, idx;
1938
1939 for (i = 0; i < AUTO_PIN_LAST; i++) {
1940 hda_nid_t nid = spec->autocfg.input_pins[i];
1941 if (! nid)
1942 continue;
1943 switch (nid) {
1944 case 0x15: /* port-C */
1945 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
1946 break;
1947 case 0x17: /* port-E */
1948 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
1949 break;
1950 }
1951 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1952 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
1953 if (nid != AD1988_PIN_CD_NID)
1954 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1955 AMP_OUT_MUTE);
1956 idx = ad1988_pin_idx(nid);
1957 if (ad1988_boost_nids[idx])
1958 snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
1959 AC_VERB_SET_AMP_GAIN_MUTE,
1960 AMP_OUT_ZERO);
1961 }
1962}
1963
1964/* parse the BIOS configuration and set up the alc_spec */
1965/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
1966static int ad1988_parse_auto_config(struct hda_codec *codec)
1967{
1968 struct ad198x_spec *spec = codec->spec;
1969 int err;
1970
1971 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
1972 return err;
1973 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
1974 return err;
1975 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
1976 ! spec->autocfg.hp_pin)
1977 return 0; /* can't find valid BIOS pin config */
1978 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
1979 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
1980 "Speaker")) < 0 ||
1981 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
1982 "Headphone")) < 0 ||
1983 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
1984 return err;
1985
1986 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1987
1988 if (spec->autocfg.dig_out_pin)
1989 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
1990 if (spec->autocfg.dig_in_pin)
1991 spec->dig_in_nid = AD1988_SPDIF_IN;
1992
1993 if (spec->kctl_alloc)
1994 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1995
1996 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
1997
1998 spec->input_mux = &spec->private_imux;
1999
2000 return 1;
2001}
2002
2003/* init callback for auto-configuration model -- overriding the default init */
2004static int ad1988_auto_init(struct hda_codec *codec)
2005{
2006 ad198x_init(codec);
2007 ad1988_auto_init_multi_out(codec);
2008 ad1988_auto_init_extra_out(codec);
2009 ad1988_auto_init_analog_input(codec);
2010 return 0;
2011}
2012
2013
2014/*
1549 */ 2015 */
1550 2016
1551static struct hda_board_config ad1988_cfg_tbl[] = { 2017static struct hda_board_config ad1988_cfg_tbl[] = {
@@ -1555,6 +2021,7 @@ static struct hda_board_config ad1988_cfg_tbl[] = {
1555 { .modelname = "3stack-dig", .config = AD1988_3STACK_DIG }, 2021 { .modelname = "3stack-dig", .config = AD1988_3STACK_DIG },
1556 { .modelname = "laptop", .config = AD1988_LAPTOP }, 2022 { .modelname = "laptop", .config = AD1988_LAPTOP },
1557 { .modelname = "laptop-dig", .config = AD1988_LAPTOP_DIG }, 2023 { .modelname = "laptop-dig", .config = AD1988_LAPTOP_DIG },
2024 { .modelname = "auto", .config = AD1988_AUTO },
1558 {} 2025 {}
1559}; 2026};
1560 2027
@@ -1572,8 +2039,20 @@ static int patch_ad1988(struct hda_codec *codec)
1572 2039
1573 board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl); 2040 board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl);
1574 if (board_config < 0 || board_config >= AD1988_MODEL_LAST) { 2041 if (board_config < 0 || board_config >= AD1988_MODEL_LAST) {
1575 printk(KERN_INFO "hda_codec: Unknown model for AD1988, using 6stack model...\n"); 2042 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
1576 board_config = AD1988_6STACK; 2043 board_config = AD1988_AUTO;
2044 }
2045
2046 if (board_config == AD1988_AUTO) {
2047 /* automatic parse from the BIOS config */
2048 int err = ad1988_parse_auto_config(codec);
2049 if (err < 0) {
2050 ad198x_free(codec);
2051 return err;
2052 } else if (! err) {
2053 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n");
2054 board_config = AD1988_6STACK;
2055 }
1577 } 2056 }
1578 2057
1579 switch (board_config) { 2058 switch (board_config) {
@@ -1581,13 +2060,17 @@ static int patch_ad1988(struct hda_codec *codec)
1581 case AD1988_6STACK_DIG: 2060 case AD1988_6STACK_DIG:
1582 spec->multiout.max_channels = 8; 2061 spec->multiout.max_channels = 8;
1583 spec->multiout.num_dacs = 4; 2062 spec->multiout.num_dacs = 4;
1584 spec->multiout.dac_nids = ad1988_dac_nids; 2063 if (codec->revision_id == AD1988A_REV2)
1585 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 2064 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
1586 spec->adc_nids = ad1988_adc_nids; 2065 else
1587 spec->capsrc_nids = ad1988_capsrc_nids; 2066 spec->multiout.dac_nids = ad1988_6stack_dac_nids;
1588 spec->input_mux = &ad1988_6stack_capture_source; 2067 spec->input_mux = &ad1988_6stack_capture_source;
1589 spec->num_mixers = 1; 2068 spec->num_mixers = 2;
1590 spec->mixers[0] = ad1988_6stack_mixers; 2069 if (codec->revision_id == AD1988A_REV2)
2070 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
2071 else
2072 spec->mixers[0] = ad1988_6stack_mixers1;
2073 spec->mixers[1] = ad1988_6stack_mixers2;
1591 spec->num_init_verbs = 1; 2074 spec->num_init_verbs = 1;
1592 spec->init_verbs[0] = ad1988_6stack_init_verbs; 2075 spec->init_verbs[0] = ad1988_6stack_init_verbs;
1593 if (board_config == AD1988_6STACK_DIG) { 2076 if (board_config == AD1988_6STACK_DIG) {
@@ -1599,15 +2082,19 @@ static int patch_ad1988(struct hda_codec *codec)
1599 case AD1988_3STACK_DIG: 2082 case AD1988_3STACK_DIG:
1600 spec->multiout.max_channels = 6; 2083 spec->multiout.max_channels = 6;
1601 spec->multiout.num_dacs = 3; 2084 spec->multiout.num_dacs = 3;
1602 spec->multiout.dac_nids = ad1988_dac_nids; 2085 if (codec->revision_id == AD1988A_REV2)
1603 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 2086 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
1604 spec->adc_nids = ad1988_adc_nids; 2087 else
1605 spec->capsrc_nids = ad1988_capsrc_nids; 2088 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
1606 spec->input_mux = &ad1988_6stack_capture_source; 2089 spec->input_mux = &ad1988_6stack_capture_source;
1607 spec->channel_mode = ad1988_3stack_modes; 2090 spec->channel_mode = ad1988_3stack_modes;
1608 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); 2091 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
1609 spec->num_mixers = 1; 2092 spec->num_mixers = 2;
1610 spec->mixers[0] = ad1988_3stack_mixers; 2093 if (codec->revision_id == AD1988A_REV2)
2094 spec->mixers[0] = ad1988_3stack_mixers1_rev2;
2095 else
2096 spec->mixers[0] = ad1988_3stack_mixers1;
2097 spec->mixers[1] = ad1988_3stack_mixers2;
1611 spec->num_init_verbs = 1; 2098 spec->num_init_verbs = 1;
1612 spec->init_verbs[0] = ad1988_3stack_init_verbs; 2099 spec->init_verbs[0] = ad1988_3stack_init_verbs;
1613 if (board_config == AD1988_3STACK_DIG) 2100 if (board_config == AD1988_3STACK_DIG)
@@ -1617,10 +2104,7 @@ static int patch_ad1988(struct hda_codec *codec)
1617 case AD1988_LAPTOP_DIG: 2104 case AD1988_LAPTOP_DIG:
1618 spec->multiout.max_channels = 2; 2105 spec->multiout.max_channels = 2;
1619 spec->multiout.num_dacs = 1; 2106 spec->multiout.num_dacs = 1;
1620 spec->multiout.dac_nids = ad1988_dac_nids; 2107 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
1621 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
1622 spec->adc_nids = ad1988_adc_nids;
1623 spec->capsrc_nids = ad1988_capsrc_nids;
1624 spec->input_mux = &ad1988_laptop_capture_source; 2108 spec->input_mux = &ad1988_laptop_capture_source;
1625 spec->num_mixers = 1; 2109 spec->num_mixers = 1;
1626 spec->mixers[0] = ad1988_laptop_mixers; 2110 spec->mixers[0] = ad1988_laptop_mixers;
@@ -1631,6 +2115,9 @@ static int patch_ad1988(struct hda_codec *codec)
1631 break; 2115 break;
1632 } 2116 }
1633 2117
2118 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
2119 spec->adc_nids = ad1988_adc_nids;
2120 spec->capsrc_nids = ad1988_capsrc_nids;
1634 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers; 2121 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
1635 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs; 2122 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
1636 if (spec->multiout.dig_out_nid) { 2123 if (spec->multiout.dig_out_nid) {
@@ -1642,6 +2129,9 @@ static int patch_ad1988(struct hda_codec *codec)
1642 2129
1643 codec->patch_ops = ad198x_patch_ops; 2130 codec->patch_ops = ad198x_patch_ops;
1644 switch (board_config) { 2131 switch (board_config) {
2132 case AD1988_AUTO:
2133 codec->patch_ops.init = ad1988_auto_init;
2134 break;
1645 case AD1988_LAPTOP: 2135 case AD1988_LAPTOP:
1646 case AD1988_LAPTOP_DIG: 2136 case AD1988_LAPTOP_DIG:
1647 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; 2137 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;