aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c2
-rw-r--r--sound/pci/hda/patch_cirrus.c50
-rw-r--r--sound/pci/hda/patch_conexant.c58
-rw-r--r--sound/pci/hda/patch_realtek.c1
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
993static 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 */
976static void init_digital(struct hda_codec *codec) 1023static 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 */
2304static 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 */
2304static void cxt5066_thinkpad_automic(struct hda_codec *codec) 2317static 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 */
2424static 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 */
2411static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) 2438static 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
3020static 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 */
2993static int cxt5066_init(struct hda_codec *codec) 3028static 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
3046static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3085static 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
5335static struct snd_pci_quirk beep_white_list[] = { 5335static 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};