aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-08-24 10:22:21 -0400
committerTakashi Iwai <tiwai@suse.de>2011-08-24 10:24:04 -0400
commite92d4b08d756e11f89a5d7e7d45a3ab9387bd25a (patch)
tree7ae320b633f33928f04eee4415f34542af96cd82
parenta301fed4b91dca95b64d9689480421aac9d79e3a (diff)
ALSA: hda - Rewrite Lenovo X200 quirk with pincfg-fix using auto-parser
Introduce the pincfg table to patch_conexant.c for fixing up the extra pin-configuration for auto-parser. As an example, Lenovo X200 model is replaced with this new mechanism. (This also fixes the wrong mixer elements for docking-station I/O in the previous model quirk automagically.) Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt1
-rw-r--r--sound/pci/hda/patch_conexant.c93
2 files changed, 50 insertions, 44 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 57e80eb78d72..708543699f7e 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -237,7 +237,6 @@ Conexant 5051
237 hp-dv6736 HP dv6736 237 hp-dv6736 HP dv6736
238 hp-f700 HP Compaq Presario F700 238 hp-f700 HP Compaq Presario F700
239 ideapad Lenovo IdeaPad laptop 239 ideapad Lenovo IdeaPad laptop
240 lenovo-x200 Lenovo X200 laptop
241 toshiba Toshiba Satellite M300 240 toshiba Toshiba Satellite M300
242 241
243Conexant 5066 242Conexant 5066
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 5616444a8ed7..197ad936c84d 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1867,39 +1867,6 @@ static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1867 { } /* end */ 1867 { } /* end */
1868}; 1868};
1869 1869
1870static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1871 /* Line in, Mic */
1872 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1873 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1877 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1878 /* SPK */
1879 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1880 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1881 /* HP, Amp */
1882 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1883 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1884 /* Docking HP */
1885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1886 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1887 /* DAC1 */
1888 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1889 /* Record selector: Internal mic */
1890 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1893 /* SPDIF route: PCM */
1894 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1895 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1896 /* EAPD */
1897 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1898 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1899 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1900 { } /* end */
1901};
1902
1903static const struct hda_verb cxt5051_f700_init_verbs[] = { 1870static const struct hda_verb cxt5051_f700_init_verbs[] = {
1904 /* Line in, Mic */ 1871 /* Line in, Mic */
1905 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1872 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
@@ -1968,7 +1935,6 @@ enum {
1968 CXT5051_LAPTOP, /* Laptops w/ EAPD support */ 1935 CXT5051_LAPTOP, /* Laptops w/ EAPD support */
1969 CXT5051_HP, /* no docking */ 1936 CXT5051_HP, /* no docking */
1970 CXT5051_HP_DV6736, /* HP without mic switch */ 1937 CXT5051_HP_DV6736, /* HP without mic switch */
1971 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1972 CXT5051_F700, /* HP Compaq Presario F700 */ 1938 CXT5051_F700, /* HP Compaq Presario F700 */
1973 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1939 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1974 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1940 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
@@ -1980,7 +1946,6 @@ static const char *const cxt5051_models[CXT5051_MODELS] = {
1980 [CXT5051_LAPTOP] = "laptop", 1946 [CXT5051_LAPTOP] = "laptop",
1981 [CXT5051_HP] = "hp", 1947 [CXT5051_HP] = "hp",
1982 [CXT5051_HP_DV6736] = "hp-dv6736", 1948 [CXT5051_HP_DV6736] = "hp-dv6736",
1983 [CXT5051_LENOVO_X200] = "lenovo-x200",
1984 [CXT5051_F700] = "hp-700", 1949 [CXT5051_F700] = "hp-700",
1985 [CXT5051_TOSHIBA] = "toshiba", 1950 [CXT5051_TOSHIBA] = "toshiba",
1986 [CXT5051_IDEAPAD] = "ideapad", 1951 [CXT5051_IDEAPAD] = "ideapad",
@@ -1995,7 +1960,6 @@ static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1995 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1960 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1996 CXT5051_LAPTOP), 1961 CXT5051_LAPTOP),
1997 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1962 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1998 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1999 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), 1963 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
2000 {} 1964 {}
2001}; 1965};
@@ -2053,13 +2017,6 @@ static int patch_cxt5051(struct hda_codec *codec)
2053 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 2017 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
2054 spec->auto_mic = 0; 2018 spec->auto_mic = 0;
2055 break; 2019 break;
2056 case CXT5051_LENOVO_X200:
2057 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
2058 /* Thinkpad X301 does not have S/PDIF wired and no ability
2059 to use a docking station. */
2060 if (codec->subsystem_id == 0x17aa211f)
2061 spec->multiout.dig_out_nid = 0;
2062 break;
2063 case CXT5051_F700: 2020 case CXT5051_F700:
2064 spec->init_verbs[0] = cxt5051_f700_init_verbs; 2021 spec->init_verbs[0] = cxt5051_f700_init_verbs;
2065 spec->mixers[0] = cxt5051_f700_mixers; 2022 spec->mixers[0] = cxt5051_f700_mixers;
@@ -4385,6 +4342,53 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
4385 .reboot_notify = snd_hda_shutup_pins, 4342 .reboot_notify = snd_hda_shutup_pins,
4386}; 4343};
4387 4344
4345/*
4346 * pin fix-up
4347 */
4348struct cxt_pincfg {
4349 hda_nid_t nid;
4350 u32 val;
4351};
4352
4353static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg)
4354{
4355 for (; cfg->nid; cfg++)
4356 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
4357
4358}
4359
4360static void apply_pin_fixup(struct hda_codec *codec,
4361 const struct snd_pci_quirk *quirk,
4362 const struct cxt_pincfg **table)
4363{
4364 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
4365 if (quirk) {
4366 snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
4367 quirk->name);
4368 apply_pincfg(codec, table[quirk->value]);
4369 }
4370}
4371
4372enum {
4373 CXT_PINCFG_LENOVO_X200,
4374};
4375
4376static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4377 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4378 { 0x17, 0x21a11000 }, /* dock-mic */
4379 { 0x19, 0x2121103f }, /* dock-HP */
4380 {}
4381};
4382
4383static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
4384 [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
4385};
4386
4387static const struct snd_pci_quirk cxt_fixups[] = {
4388 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
4389 {}
4390};
4391
4388static int patch_conexant_auto(struct hda_codec *codec) 4392static int patch_conexant_auto(struct hda_codec *codec)
4389{ 4393{
4390 struct conexant_spec *spec; 4394 struct conexant_spec *spec;
@@ -4398,6 +4402,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
4398 return -ENOMEM; 4402 return -ENOMEM;
4399 codec->spec = spec; 4403 codec->spec = spec;
4400 codec->pin_amp_workaround = 1; 4404 codec->pin_amp_workaround = 1;
4405
4406 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4407
4401 err = cx_auto_search_adcs(codec); 4408 err = cx_auto_search_adcs(codec);
4402 if (err < 0) 4409 if (err < 0)
4403 return err; 4410 return err;