diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 50 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 58 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 1 |
4 files changed, 110 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3827092cc1d2..14829210ef0b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -4536,7 +4536,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4536 | cfg->hp_outs--; | 4536 | cfg->hp_outs--; |
4537 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, | 4537 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, |
4538 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); | 4538 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); |
4539 | memmove(sequences_hp + i - 1, sequences_hp + i, | 4539 | memmove(sequences_hp + i, sequences_hp + i + 1, |
4540 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | 4540 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); |
4541 | } | 4541 | } |
4542 | } | 4542 | } |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 4ef5efaaaef1..488fd9ade1ba 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -972,6 +972,53 @@ static struct hda_verb cs_coef_init_verbs[] = { | |||
972 | {} /* terminator */ | 972 | {} /* terminator */ |
973 | }; | 973 | }; |
974 | 974 | ||
975 | /* Errata: CS4207 rev C0/C1/C2 Silicon | ||
976 | * | ||
977 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf | ||
978 | * | ||
979 | * 6. At high temperature (TA > +85°C), the digital supply current (IVD) | ||
980 | * may be excessive (up to an additional 200 μA), which is most easily | ||
981 | * observed while the part is being held in reset (RESET# active low). | ||
982 | * | ||
983 | * Root Cause: At initial powerup of the device, the logic that drives | ||
984 | * the clock and write enable to the S/PDIF SRC RAMs is not properly | ||
985 | * initialized. | ||
986 | * Certain random patterns will cause a steady leakage current in those | ||
987 | * RAM cells. The issue will resolve once the SRCs are used (turned on). | ||
988 | * | ||
989 | * Workaround: The following verb sequence briefly turns on the S/PDIF SRC | ||
990 | * blocks, which will alleviate the issue. | ||
991 | */ | ||
992 | |||
993 | static struct hda_verb cs_errata_init_verbs[] = { | ||
994 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | ||
995 | {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | ||
996 | |||
997 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
998 | {0x11, AC_VERB_SET_PROC_COEF, 0x9999}, | ||
999 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
1000 | {0x11, AC_VERB_SET_PROC_COEF, 0xa412}, | ||
1001 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
1002 | {0x11, AC_VERB_SET_PROC_COEF, 0x0009}, | ||
1003 | |||
1004 | {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */ | ||
1005 | {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */ | ||
1006 | |||
1007 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
1008 | {0x11, AC_VERB_SET_PROC_COEF, 0x2412}, | ||
1009 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
1010 | {0x11, AC_VERB_SET_PROC_COEF, 0x0000}, | ||
1011 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
1012 | {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, | ||
1013 | {0x11, AC_VERB_SET_PROC_STATE, 0x00}, | ||
1014 | |||
1015 | {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ | ||
1016 | {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ | ||
1017 | /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ | ||
1018 | |||
1019 | {} /* terminator */ | ||
1020 | }; | ||
1021 | |||
975 | /* SPDIF setup */ | 1022 | /* SPDIF setup */ |
976 | static void init_digital(struct hda_codec *codec) | 1023 | static void init_digital(struct hda_codec *codec) |
977 | { | 1024 | { |
@@ -991,6 +1038,9 @@ static int cs_init(struct hda_codec *codec) | |||
991 | { | 1038 | { |
992 | struct cs_spec *spec = codec->spec; | 1039 | struct cs_spec *spec = codec->spec; |
993 | 1040 | ||
1041 | /* init_verb sequence for C0/C1/C2 errata*/ | ||
1042 | snd_hda_sequence_write(codec, cs_errata_init_verbs); | ||
1043 | |||
994 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 1044 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
995 | 1045 | ||
996 | if (spec->gpio_mask) { | 1046 | if (spec->gpio_mask) { |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5cdb80edbd7f..71f9d6475b09 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -116,6 +116,7 @@ struct conexant_spec { | |||
116 | unsigned int dell_vostro:1; | 116 | unsigned int dell_vostro:1; |
117 | unsigned int ideapad:1; | 117 | unsigned int ideapad:1; |
118 | unsigned int thinkpad:1; | 118 | unsigned int thinkpad:1; |
119 | unsigned int hp_laptop:1; | ||
119 | 120 | ||
120 | unsigned int ext_mic_present; | 121 | unsigned int ext_mic_present; |
121 | unsigned int recording; | 122 | unsigned int recording; |
@@ -2299,6 +2300,18 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) | |||
2299 | } | 2300 | } |
2300 | } | 2301 | } |
2301 | 2302 | ||
2303 | /* toggle input of built-in digital mic and mic jack appropriately */ | ||
2304 | static void cxt5066_hp_laptop_automic(struct hda_codec *codec) | ||
2305 | { | ||
2306 | unsigned int present; | ||
2307 | |||
2308 | present = snd_hda_jack_detect(codec, 0x1b); | ||
2309 | snd_printdd("CXT5066: external microphone present=%d\n", present); | ||
2310 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, | ||
2311 | present ? 1 : 3); | ||
2312 | } | ||
2313 | |||
2314 | |||
2302 | /* toggle input of built-in digital mic and mic jack appropriately | 2315 | /* toggle input of built-in digital mic and mic jack appropriately |
2303 | order is: external mic -> dock mic -> interal mic */ | 2316 | order is: external mic -> dock mic -> interal mic */ |
2304 | static void cxt5066_thinkpad_automic(struct hda_codec *codec) | 2317 | static void cxt5066_thinkpad_automic(struct hda_codec *codec) |
@@ -2408,6 +2421,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res) | |||
2408 | } | 2421 | } |
2409 | 2422 | ||
2410 | /* unsolicited event for jack sensing */ | 2423 | /* unsolicited event for jack sensing */ |
2424 | static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res) | ||
2425 | { | ||
2426 | snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26); | ||
2427 | switch (res >> 26) { | ||
2428 | case CONEXANT_HP_EVENT: | ||
2429 | cxt5066_hp_automute(codec); | ||
2430 | break; | ||
2431 | case CONEXANT_MIC_EVENT: | ||
2432 | cxt5066_hp_laptop_automic(codec); | ||
2433 | break; | ||
2434 | } | ||
2435 | } | ||
2436 | |||
2437 | /* unsolicited event for jack sensing */ | ||
2411 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) | 2438 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) |
2412 | { | 2439 | { |
2413 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); | 2440 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); |
@@ -2989,6 +3016,14 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | |||
2989 | { } /* end */ | 3016 | { } /* end */ |
2990 | }; | 3017 | }; |
2991 | 3018 | ||
3019 | |||
3020 | static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { | ||
3021 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
3022 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
3023 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
3024 | { } /* end */ | ||
3025 | }; | ||
3026 | |||
2992 | /* initialize jack-sensing, too */ | 3027 | /* initialize jack-sensing, too */ |
2993 | static int cxt5066_init(struct hda_codec *codec) | 3028 | static int cxt5066_init(struct hda_codec *codec) |
2994 | { | 3029 | { |
@@ -3004,6 +3039,8 @@ static int cxt5066_init(struct hda_codec *codec) | |||
3004 | cxt5066_ideapad_automic(codec); | 3039 | cxt5066_ideapad_automic(codec); |
3005 | else if (spec->thinkpad) | 3040 | else if (spec->thinkpad) |
3006 | cxt5066_thinkpad_automic(codec); | 3041 | cxt5066_thinkpad_automic(codec); |
3042 | else if (spec->hp_laptop) | ||
3043 | cxt5066_hp_laptop_automic(codec); | ||
3007 | } | 3044 | } |
3008 | cxt5066_set_mic_boost(codec); | 3045 | cxt5066_set_mic_boost(codec); |
3009 | return 0; | 3046 | return 0; |
@@ -3031,6 +3068,7 @@ enum { | |||
3031 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ | 3068 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ |
3032 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ | 3069 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ |
3033 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ | 3070 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ |
3071 | CXT5066_HP_LAPTOP, /* HP Laptop */ | ||
3034 | CXT5066_MODELS | 3072 | CXT5066_MODELS |
3035 | }; | 3073 | }; |
3036 | 3074 | ||
@@ -3041,6 +3079,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
3041 | [CXT5066_DELL_VOSTO] = "dell-vostro", | 3079 | [CXT5066_DELL_VOSTO] = "dell-vostro", |
3042 | [CXT5066_IDEAPAD] = "ideapad", | 3080 | [CXT5066_IDEAPAD] = "ideapad", |
3043 | [CXT5066_THINKPAD] = "thinkpad", | 3081 | [CXT5066_THINKPAD] = "thinkpad", |
3082 | [CXT5066_HP_LAPTOP] = "hp-laptop", | ||
3044 | }; | 3083 | }; |
3045 | 3084 | ||
3046 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3085 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
@@ -3052,8 +3091,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3052 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), | 3091 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), |
3053 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | 3092 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
3054 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3093 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
3094 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), | ||
3055 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3095 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
3056 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | 3096 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), |
3097 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | ||
3057 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3098 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
3058 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3099 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
3059 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3100 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
@@ -3116,6 +3157,23 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3116 | spec->num_init_verbs++; | 3157 | spec->num_init_verbs++; |
3117 | spec->dell_automute = 1; | 3158 | spec->dell_automute = 1; |
3118 | break; | 3159 | break; |
3160 | case CXT5066_HP_LAPTOP: | ||
3161 | codec->patch_ops.init = cxt5066_init; | ||
3162 | codec->patch_ops.unsol_event = cxt5066_hp_laptop_event; | ||
3163 | spec->init_verbs[spec->num_init_verbs] = | ||
3164 | cxt5066_init_verbs_hp_laptop; | ||
3165 | spec->num_init_verbs++; | ||
3166 | spec->hp_laptop = 1; | ||
3167 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | ||
3168 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
3169 | /* no S/PDIF out */ | ||
3170 | spec->multiout.dig_out_nid = 0; | ||
3171 | /* input source automatically selected */ | ||
3172 | spec->input_mux = NULL; | ||
3173 | spec->port_d_mode = 0; | ||
3174 | spec->mic_boost = 3; /* default 30dB gain */ | ||
3175 | break; | ||
3176 | |||
3119 | case CXT5066_OLPC_XO_1_5: | 3177 | case CXT5066_OLPC_XO_1_5: |
3120 | codec->patch_ops.init = cxt5066_olpc_init; | 3178 | codec->patch_ops.init = cxt5066_olpc_init; |
3121 | codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; | 3179 | codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 627bf9963368..bcbf9160ed81 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5334,6 +5334,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5334 | 5334 | ||
5335 | static struct snd_pci_quirk beep_white_list[] = { | 5335 | static struct snd_pci_quirk beep_white_list[] = { |
5336 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 5336 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
5337 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | ||
5337 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 5338 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
5338 | {} | 5339 | {} |
5339 | }; | 5340 | }; |