diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-08-24 10:22:21 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-08-24 10:24:04 -0400 |
commit | e92d4b08d756e11f89a5d7e7d45a3ab9387bd25a (patch) | |
tree | 7ae320b633f33928f04eee4415f34542af96cd82 | |
parent | a301fed4b91dca95b64d9689480421aac9d79e3a (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.txt | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 93 |
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 | ||
243 | Conexant 5066 | 242 | Conexant 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 | ||
1870 | static 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 | |||
1903 | static const struct hda_verb cxt5051_f700_init_verbs[] = { | 1870 | static 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 | */ | ||
4348 | struct cxt_pincfg { | ||
4349 | hda_nid_t nid; | ||
4350 | u32 val; | ||
4351 | }; | ||
4352 | |||
4353 | static 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 | |||
4360 | static 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 | |||
4372 | enum { | ||
4373 | CXT_PINCFG_LENOVO_X200, | ||
4374 | }; | ||
4375 | |||
4376 | static 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 | |||
4383 | static const struct cxt_pincfg *cxt_pincfg_tbl[] = { | ||
4384 | [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, | ||
4385 | }; | ||
4386 | |||
4387 | static const struct snd_pci_quirk cxt_fixups[] = { | ||
4388 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), | ||
4389 | {} | ||
4390 | }; | ||
4391 | |||
4388 | static int patch_conexant_auto(struct hda_codec *codec) | 4392 | static 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; |