diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 908 |
1 files changed, 648 insertions, 260 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a432e6efd19b..5f00589cb791 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/jack.h> | ||
31 | #include "hda_codec.h" | 32 | #include "hda_codec.h" |
32 | #include "hda_local.h" | 33 | #include "hda_local.h" |
33 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
@@ -282,6 +283,12 @@ struct alc_mic_route { | |||
282 | unsigned char amix_idx; | 283 | unsigned char amix_idx; |
283 | }; | 284 | }; |
284 | 285 | ||
286 | struct alc_jack { | ||
287 | hda_nid_t nid; | ||
288 | int type; | ||
289 | struct snd_jack *jack; | ||
290 | }; | ||
291 | |||
285 | #define MUX_IDX_UNDEF ((unsigned char)-1) | 292 | #define MUX_IDX_UNDEF ((unsigned char)-1) |
286 | 293 | ||
287 | struct alc_customize_define { | 294 | struct alc_customize_define { |
@@ -294,6 +301,7 @@ struct alc_customize_define { | |||
294 | unsigned int platform_type:1; | 301 | unsigned int platform_type:1; |
295 | unsigned int swap:1; | 302 | unsigned int swap:1; |
296 | unsigned int override:1; | 303 | unsigned int override:1; |
304 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ | ||
297 | }; | 305 | }; |
298 | 306 | ||
299 | struct alc_spec { | 307 | struct alc_spec { |
@@ -357,6 +365,9 @@ struct alc_spec { | |||
357 | /* PCM information */ | 365 | /* PCM information */ |
358 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | 366 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
359 | 367 | ||
368 | /* jack detection */ | ||
369 | struct snd_array jacks; | ||
370 | |||
360 | /* dynamic controls, init_verbs and input_mux */ | 371 | /* dynamic controls, init_verbs and input_mux */ |
361 | struct auto_pin_cfg autocfg; | 372 | struct auto_pin_cfg autocfg; |
362 | struct alc_customize_define cdefine; | 373 | struct alc_customize_define cdefine; |
@@ -383,6 +394,7 @@ struct alc_spec { | |||
383 | unsigned int no_analog :1; /* digital I/O only */ | 394 | unsigned int no_analog :1; /* digital I/O only */ |
384 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | 395 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ |
385 | int init_amp; | 396 | int init_amp; |
397 | int codec_variant; /* flag for other variants */ | ||
386 | 398 | ||
387 | /* for virtual master */ | 399 | /* for virtual master */ |
388 | hda_nid_t vmaster_nid; | 400 | hda_nid_t vmaster_nid; |
@@ -846,7 +858,7 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | |||
846 | { | 858 | { |
847 | unsigned int val = PIN_IN; | 859 | unsigned int val = PIN_IN; |
848 | 860 | ||
849 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { | 861 | if (auto_pin_type == AUTO_PIN_MIC) { |
850 | unsigned int pincap; | 862 | unsigned int pincap; |
851 | unsigned int oldval; | 863 | unsigned int oldval; |
852 | oldval = snd_hda_codec_read(codec, nid, 0, | 864 | oldval = snd_hda_codec_read(codec, nid, 0, |
@@ -866,6 +878,28 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | |||
866 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); | 878 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); |
867 | } | 879 | } |
868 | 880 | ||
881 | static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) | ||
882 | { | ||
883 | struct alc_spec *spec = codec->spec; | ||
884 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
885 | |||
886 | if (!cfg->line_outs) { | ||
887 | while (cfg->line_outs < AUTO_CFG_MAX_OUTS && | ||
888 | cfg->line_out_pins[cfg->line_outs]) | ||
889 | cfg->line_outs++; | ||
890 | } | ||
891 | if (!cfg->speaker_outs) { | ||
892 | while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && | ||
893 | cfg->speaker_pins[cfg->speaker_outs]) | ||
894 | cfg->speaker_outs++; | ||
895 | } | ||
896 | if (!cfg->hp_outs) { | ||
897 | while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && | ||
898 | cfg->hp_pins[cfg->hp_outs]) | ||
899 | cfg->hp_outs++; | ||
900 | } | ||
901 | } | ||
902 | |||
869 | /* | 903 | /* |
870 | */ | 904 | */ |
871 | static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) | 905 | static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) |
@@ -934,6 +968,8 @@ static void setup_preset(struct hda_codec *codec, | |||
934 | 968 | ||
935 | if (preset->setup) | 969 | if (preset->setup) |
936 | preset->setup(codec); | 970 | preset->setup(codec); |
971 | |||
972 | alc_fixup_autocfg_pin_nums(codec); | ||
937 | } | 973 | } |
938 | 974 | ||
939 | /* Enable GPIO mask and set output */ | 975 | /* Enable GPIO mask and set output */ |
@@ -990,25 +1026,136 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
990 | alc_fix_pll(codec); | 1026 | alc_fix_pll(codec); |
991 | } | 1027 | } |
992 | 1028 | ||
993 | static void alc_automute_pin(struct hda_codec *codec) | 1029 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
1030 | static void alc_free_jack_priv(struct snd_jack *jack) | ||
1031 | { | ||
1032 | struct alc_jack *jacks = jack->private_data; | ||
1033 | jacks->nid = 0; | ||
1034 | jacks->jack = NULL; | ||
1035 | } | ||
1036 | |||
1037 | static int alc_add_jack(struct hda_codec *codec, | ||
1038 | hda_nid_t nid, int type) | ||
1039 | { | ||
1040 | struct alc_spec *spec; | ||
1041 | struct alc_jack *jack; | ||
1042 | const char *name; | ||
1043 | int err; | ||
1044 | |||
1045 | spec = codec->spec; | ||
1046 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | ||
1047 | jack = snd_array_new(&spec->jacks); | ||
1048 | if (!jack) | ||
1049 | return -ENOMEM; | ||
1050 | |||
1051 | jack->nid = nid; | ||
1052 | jack->type = type; | ||
1053 | name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; | ||
1054 | |||
1055 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
1056 | if (err < 0) | ||
1057 | return err; | ||
1058 | jack->jack->private_data = jack; | ||
1059 | jack->jack->private_free = alc_free_jack_priv; | ||
1060 | return 0; | ||
1061 | } | ||
1062 | |||
1063 | static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
994 | { | 1064 | { |
995 | struct alc_spec *spec = codec->spec; | 1065 | struct alc_spec *spec = codec->spec; |
996 | unsigned int nid = spec->autocfg.hp_pins[0]; | 1066 | struct alc_jack *jacks = spec->jacks.list; |
1067 | |||
1068 | if (jacks) { | ||
1069 | int i; | ||
1070 | for (i = 0; i < spec->jacks.used; i++) { | ||
1071 | if (jacks->nid == nid) { | ||
1072 | unsigned int present; | ||
1073 | present = snd_hda_jack_detect(codec, nid); | ||
1074 | |||
1075 | present = (present) ? jacks->type : 0; | ||
1076 | |||
1077 | snd_jack_report(jacks->jack, present); | ||
1078 | } | ||
1079 | jacks++; | ||
1080 | } | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | static int alc_init_jacks(struct hda_codec *codec) | ||
1085 | { | ||
1086 | struct alc_spec *spec = codec->spec; | ||
1087 | int err; | ||
1088 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | ||
1089 | unsigned int mic_nid = spec->ext_mic.pin; | ||
1090 | |||
1091 | if (hp_nid) { | ||
1092 | err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); | ||
1093 | if (err < 0) | ||
1094 | return err; | ||
1095 | alc_report_jack(codec, hp_nid); | ||
1096 | } | ||
1097 | |||
1098 | if (mic_nid) { | ||
1099 | err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); | ||
1100 | if (err < 0) | ||
1101 | return err; | ||
1102 | alc_report_jack(codec, mic_nid); | ||
1103 | } | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | #else | ||
1108 | static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
1109 | { | ||
1110 | } | ||
1111 | |||
1112 | static inline int alc_init_jacks(struct hda_codec *codec) | ||
1113 | { | ||
1114 | return 0; | ||
1115 | } | ||
1116 | #endif | ||
1117 | |||
1118 | static void alc_automute_speaker(struct hda_codec *codec, int pinctl) | ||
1119 | { | ||
1120 | struct alc_spec *spec = codec->spec; | ||
1121 | unsigned int mute; | ||
1122 | hda_nid_t nid; | ||
997 | int i; | 1123 | int i; |
998 | 1124 | ||
999 | if (!nid) | 1125 | spec->jack_present = 0; |
1000 | return; | 1126 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
1001 | spec->jack_present = snd_hda_jack_detect(codec, nid); | 1127 | nid = spec->autocfg.hp_pins[i]; |
1128 | if (!nid) | ||
1129 | break; | ||
1130 | if (snd_hda_jack_detect(codec, nid)) { | ||
1131 | spec->jack_present = 1; | ||
1132 | break; | ||
1133 | } | ||
1134 | alc_report_jack(codec, spec->autocfg.hp_pins[i]); | ||
1135 | } | ||
1136 | |||
1137 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1138 | /* Toggle internal speakers muting */ | ||
1002 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | 1139 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
1003 | nid = spec->autocfg.speaker_pins[i]; | 1140 | nid = spec->autocfg.speaker_pins[i]; |
1004 | if (!nid) | 1141 | if (!nid) |
1005 | break; | 1142 | break; |
1006 | snd_hda_codec_write(codec, nid, 0, | 1143 | if (pinctl) { |
1144 | snd_hda_codec_write(codec, nid, 0, | ||
1007 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1145 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1008 | spec->jack_present ? 0 : PIN_OUT); | 1146 | spec->jack_present ? 0 : PIN_OUT); |
1147 | } else { | ||
1148 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
1149 | HDA_AMP_MUTE, mute); | ||
1150 | } | ||
1009 | } | 1151 | } |
1010 | } | 1152 | } |
1011 | 1153 | ||
1154 | static void alc_automute_pin(struct hda_codec *codec) | ||
1155 | { | ||
1156 | alc_automute_speaker(codec, 1); | ||
1157 | } | ||
1158 | |||
1012 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 1159 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
1013 | hda_nid_t nid) | 1160 | hda_nid_t nid) |
1014 | { | 1161 | { |
@@ -1090,6 +1237,7 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1090 | AC_VERB_SET_CONNECT_SEL, | 1237 | AC_VERB_SET_CONNECT_SEL, |
1091 | alive->mux_idx); | 1238 | alive->mux_idx); |
1092 | } | 1239 | } |
1240 | alc_report_jack(codec, spec->ext_mic.pin); | ||
1093 | 1241 | ||
1094 | /* FIXME: analog mixer */ | 1242 | /* FIXME: analog mixer */ |
1095 | } | 1243 | } |
@@ -1236,24 +1384,35 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1236 | static void alc_init_auto_hp(struct hda_codec *codec) | 1384 | static void alc_init_auto_hp(struct hda_codec *codec) |
1237 | { | 1385 | { |
1238 | struct alc_spec *spec = codec->spec; | 1386 | struct alc_spec *spec = codec->spec; |
1387 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1388 | int i; | ||
1239 | 1389 | ||
1240 | if (!spec->autocfg.hp_pins[0]) | 1390 | if (!cfg->hp_pins[0]) { |
1241 | return; | 1391 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
1392 | return; | ||
1393 | } | ||
1242 | 1394 | ||
1243 | if (!spec->autocfg.speaker_pins[0]) { | 1395 | if (!cfg->speaker_pins[0]) { |
1244 | if (spec->autocfg.line_out_pins[0] && | 1396 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) |
1245 | spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1246 | spec->autocfg.speaker_pins[0] = | ||
1247 | spec->autocfg.line_out_pins[0]; | ||
1248 | else | ||
1249 | return; | 1397 | return; |
1398 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
1399 | sizeof(cfg->speaker_pins)); | ||
1400 | cfg->speaker_outs = cfg->line_outs; | ||
1250 | } | 1401 | } |
1251 | 1402 | ||
1252 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | 1403 | if (!cfg->hp_pins[0]) { |
1253 | spec->autocfg.hp_pins[0]); | 1404 | memcpy(cfg->hp_pins, cfg->line_out_pins, |
1254 | snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, | 1405 | sizeof(cfg->hp_pins)); |
1406 | cfg->hp_outs = cfg->line_outs; | ||
1407 | } | ||
1408 | |||
1409 | for (i = 0; i < cfg->hp_outs; i++) { | ||
1410 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | ||
1411 | cfg->hp_pins[i]); | ||
1412 | snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, | ||
1255 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1413 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1256 | AC_USRSP_EN | ALC880_HP_EVENT); | 1414 | AC_USRSP_EN | ALC880_HP_EVENT); |
1415 | } | ||
1257 | spec->unsol_event = alc_sku_unsol_event; | 1416 | spec->unsol_event = alc_sku_unsol_event; |
1258 | } | 1417 | } |
1259 | 1418 | ||
@@ -1265,30 +1424,28 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1265 | int i; | 1424 | int i; |
1266 | 1425 | ||
1267 | /* there must be only two mic inputs exclusively */ | 1426 | /* there must be only two mic inputs exclusively */ |
1268 | for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) | 1427 | for (i = 0; i < cfg->num_inputs; i++) |
1269 | if (cfg->input_pins[i]) | 1428 | if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) |
1270 | return; | 1429 | return; |
1271 | 1430 | ||
1272 | fixed = ext = 0; | 1431 | fixed = ext = 0; |
1273 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) { | 1432 | for (i = 0; i < cfg->num_inputs; i++) { |
1274 | hda_nid_t nid = cfg->input_pins[i]; | 1433 | hda_nid_t nid = cfg->inputs[i].pin; |
1275 | unsigned int defcfg; | 1434 | unsigned int defcfg; |
1276 | if (!nid) | ||
1277 | return; | ||
1278 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 1435 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
1279 | switch (get_defcfg_connect(defcfg)) { | 1436 | switch (snd_hda_get_input_pin_attr(defcfg)) { |
1280 | case AC_JACK_PORT_FIXED: | 1437 | case INPUT_PIN_ATTR_INT: |
1281 | if (fixed) | 1438 | if (fixed) |
1282 | return; /* already occupied */ | 1439 | return; /* already occupied */ |
1283 | fixed = nid; | 1440 | fixed = nid; |
1284 | break; | 1441 | break; |
1285 | case AC_JACK_PORT_COMPLEX: | 1442 | case INPUT_PIN_ATTR_UNUSED: |
1443 | return; /* invalid entry */ | ||
1444 | default: | ||
1286 | if (ext) | 1445 | if (ext) |
1287 | return; /* already occupied */ | 1446 | return; /* already occupied */ |
1288 | ext = nid; | 1447 | ext = nid; |
1289 | break; | 1448 | break; |
1290 | default: | ||
1291 | return; /* invalid entry */ | ||
1292 | } | 1449 | } |
1293 | } | 1450 | } |
1294 | if (!ext || !fixed) | 1451 | if (!ext || !fixed) |
@@ -1308,6 +1465,11 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1308 | spec->unsol_event = alc_sku_unsol_event; | 1465 | spec->unsol_event = alc_sku_unsol_event; |
1309 | } | 1466 | } |
1310 | 1467 | ||
1468 | /* Could be any non-zero and even value. When used as fixup, tells | ||
1469 | * the driver to ignore any present sku defines. | ||
1470 | */ | ||
1471 | #define ALC_FIXUP_SKU_IGNORE (2) | ||
1472 | |||
1311 | static int alc_auto_parse_customize_define(struct hda_codec *codec) | 1473 | static int alc_auto_parse_customize_define(struct hda_codec *codec) |
1312 | { | 1474 | { |
1313 | unsigned int ass, tmp, i; | 1475 | unsigned int ass, tmp, i; |
@@ -1316,6 +1478,13 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec) | |||
1316 | 1478 | ||
1317 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ | 1479 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ |
1318 | 1480 | ||
1481 | if (spec->cdefine.fixup) { | ||
1482 | ass = spec->cdefine.sku_cfg; | ||
1483 | if (ass == ALC_FIXUP_SKU_IGNORE) | ||
1484 | return -1; | ||
1485 | goto do_sku; | ||
1486 | } | ||
1487 | |||
1319 | ass = codec->subsystem_id & 0xffff; | 1488 | ass = codec->subsystem_id & 0xffff; |
1320 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) | 1489 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
1321 | goto do_sku; | 1490 | goto do_sku; |
@@ -1383,6 +1552,13 @@ static int alc_subsystem_id(struct hda_codec *codec, | |||
1383 | unsigned nid; | 1552 | unsigned nid; |
1384 | struct alc_spec *spec = codec->spec; | 1553 | struct alc_spec *spec = codec->spec; |
1385 | 1554 | ||
1555 | if (spec->cdefine.fixup) { | ||
1556 | ass = spec->cdefine.sku_cfg; | ||
1557 | if (ass == ALC_FIXUP_SKU_IGNORE) | ||
1558 | return 0; | ||
1559 | goto do_sku; | ||
1560 | } | ||
1561 | |||
1386 | ass = codec->subsystem_id & 0xffff; | 1562 | ass = codec->subsystem_id & 0xffff; |
1387 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) | 1563 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) |
1388 | goto do_sku; | 1564 | goto do_sku; |
@@ -1502,6 +1678,7 @@ struct alc_pincfg { | |||
1502 | }; | 1678 | }; |
1503 | 1679 | ||
1504 | struct alc_fixup { | 1680 | struct alc_fixup { |
1681 | unsigned int sku; | ||
1505 | const struct alc_pincfg *pins; | 1682 | const struct alc_pincfg *pins; |
1506 | const struct hda_verb *verbs; | 1683 | const struct hda_verb *verbs; |
1507 | }; | 1684 | }; |
@@ -1512,12 +1689,22 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1512 | int pre_init) | 1689 | int pre_init) |
1513 | { | 1690 | { |
1514 | const struct alc_pincfg *cfg; | 1691 | const struct alc_pincfg *cfg; |
1692 | struct alc_spec *spec; | ||
1515 | 1693 | ||
1516 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 1694 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
1517 | if (!quirk) | 1695 | if (!quirk) |
1518 | return; | 1696 | return; |
1519 | fix += quirk->value; | 1697 | fix += quirk->value; |
1520 | cfg = fix->pins; | 1698 | cfg = fix->pins; |
1699 | if (pre_init && fix->sku) { | ||
1700 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1701 | snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", | ||
1702 | codec->chip_name, quirk->name); | ||
1703 | #endif | ||
1704 | spec = codec->spec; | ||
1705 | spec->cdefine.sku_cfg = fix->sku; | ||
1706 | spec->cdefine.fixup = 1; | ||
1707 | } | ||
1521 | if (pre_init && cfg) { | 1708 | if (pre_init && cfg) { |
1522 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1709 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1523 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", | 1710 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", |
@@ -1546,6 +1733,15 @@ static int alc_read_coef_idx(struct hda_codec *codec, | |||
1546 | return val; | 1733 | return val; |
1547 | } | 1734 | } |
1548 | 1735 | ||
1736 | static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, | ||
1737 | unsigned int coef_val) | ||
1738 | { | ||
1739 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, | ||
1740 | coef_idx); | ||
1741 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, | ||
1742 | coef_val); | ||
1743 | } | ||
1744 | |||
1549 | /* set right pin controls for digital I/O */ | 1745 | /* set right pin controls for digital I/O */ |
1550 | static void alc_auto_init_digital(struct hda_codec *codec) | 1746 | static void alc_auto_init_digital(struct hda_codec *codec) |
1551 | { | 1747 | { |
@@ -1723,31 +1919,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1723 | 1919 | ||
1724 | static void alc_automute_amp(struct hda_codec *codec) | 1920 | static void alc_automute_amp(struct hda_codec *codec) |
1725 | { | 1921 | { |
1726 | struct alc_spec *spec = codec->spec; | 1922 | alc_automute_speaker(codec, 0); |
1727 | unsigned int mute; | ||
1728 | hda_nid_t nid; | ||
1729 | int i; | ||
1730 | |||
1731 | spec->jack_present = 0; | ||
1732 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { | ||
1733 | nid = spec->autocfg.hp_pins[i]; | ||
1734 | if (!nid) | ||
1735 | break; | ||
1736 | if (snd_hda_jack_detect(codec, nid)) { | ||
1737 | spec->jack_present = 1; | ||
1738 | break; | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1743 | /* Toggle internal speakers muting */ | ||
1744 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | ||
1745 | nid = spec->autocfg.speaker_pins[i]; | ||
1746 | if (!nid) | ||
1747 | break; | ||
1748 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
1749 | HDA_AMP_MUTE, mute); | ||
1750 | } | ||
1751 | } | 1923 | } |
1752 | 1924 | ||
1753 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, | 1925 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, |
@@ -3602,10 +3774,7 @@ static int alc_init(struct hda_codec *codec) | |||
3602 | if (spec->init_hook) | 3774 | if (spec->init_hook) |
3603 | spec->init_hook(codec); | 3775 | spec->init_hook(codec); |
3604 | 3776 | ||
3605 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3777 | hda_call_check_power_status(codec, 0x01); |
3606 | if (codec->patch_ops.check_power_status) | ||
3607 | codec->patch_ops.check_power_status(codec, 0x01); | ||
3608 | #endif | ||
3609 | return 0; | 3778 | return 0; |
3610 | } | 3779 | } |
3611 | 3780 | ||
@@ -4001,10 +4170,7 @@ static int alc_resume(struct hda_codec *codec) | |||
4001 | codec->patch_ops.init(codec); | 4170 | codec->patch_ops.init(codec); |
4002 | snd_hda_codec_resume_amp(codec); | 4171 | snd_hda_codec_resume_amp(codec); |
4003 | snd_hda_codec_resume_cache(codec); | 4172 | snd_hda_codec_resume_cache(codec); |
4004 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4173 | hda_call_check_power_status(codec, 0x01); |
4005 | if (codec->patch_ops.check_power_status) | ||
4006 | codec->patch_ops.check_power_status(codec, 0x01); | ||
4007 | #endif | ||
4008 | return 0; | 4174 | return 0; |
4009 | } | 4175 | } |
4010 | #endif | 4176 | #endif |
@@ -4729,7 +4895,7 @@ static struct snd_kcontrol_new alc880_control_templates[] = { | |||
4729 | 4895 | ||
4730 | /* add dynamic controls */ | 4896 | /* add dynamic controls */ |
4731 | static int add_control(struct alc_spec *spec, int type, const char *name, | 4897 | static int add_control(struct alc_spec *spec, int type, const char *name, |
4732 | unsigned long val) | 4898 | int cidx, unsigned long val) |
4733 | { | 4899 | { |
4734 | struct snd_kcontrol_new *knew; | 4900 | struct snd_kcontrol_new *knew; |
4735 | 4901 | ||
@@ -4741,6 +4907,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4741 | knew->name = kstrdup(name, GFP_KERNEL); | 4907 | knew->name = kstrdup(name, GFP_KERNEL); |
4742 | if (!knew->name) | 4908 | if (!knew->name) |
4743 | return -ENOMEM; | 4909 | return -ENOMEM; |
4910 | knew->index = cidx; | ||
4744 | if (get_amp_nid_(val)) | 4911 | if (get_amp_nid_(val)) |
4745 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | 4912 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
4746 | knew->private_value = val; | 4913 | knew->private_value = val; |
@@ -4749,17 +4916,21 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4749 | 4916 | ||
4750 | static int add_control_with_pfx(struct alc_spec *spec, int type, | 4917 | static int add_control_with_pfx(struct alc_spec *spec, int type, |
4751 | const char *pfx, const char *dir, | 4918 | const char *pfx, const char *dir, |
4752 | const char *sfx, unsigned long val) | 4919 | const char *sfx, int cidx, unsigned long val) |
4753 | { | 4920 | { |
4754 | char name[32]; | 4921 | char name[32]; |
4755 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); | 4922 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); |
4756 | return add_control(spec, type, name, val); | 4923 | return add_control(spec, type, name, cidx, val); |
4757 | } | 4924 | } |
4758 | 4925 | ||
4759 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ | 4926 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ |
4760 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) | 4927 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) |
4761 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ | 4928 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ |
4762 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) | 4929 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) |
4930 | #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ | ||
4931 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) | ||
4932 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ | ||
4933 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) | ||
4763 | 4934 | ||
4764 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) | 4935 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) |
4765 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) | 4936 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) |
@@ -4912,16 +5083,16 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
4912 | 5083 | ||
4913 | /* create input playback/capture controls for the given pin */ | 5084 | /* create input playback/capture controls for the given pin */ |
4914 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | 5085 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
4915 | const char *ctlname, | 5086 | const char *ctlname, int ctlidx, |
4916 | int idx, hda_nid_t mix_nid) | 5087 | int idx, hda_nid_t mix_nid) |
4917 | { | 5088 | { |
4918 | int err; | 5089 | int err; |
4919 | 5090 | ||
4920 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, | 5091 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, |
4921 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 5092 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4922 | if (err < 0) | 5093 | if (err < 0) |
4923 | return err; | 5094 | return err; |
4924 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, | 5095 | err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, |
4925 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 5096 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4926 | if (err < 0) | 5097 | if (err < 0) |
4927 | return err; | 5098 | return err; |
@@ -4942,20 +5113,27 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, | |||
4942 | { | 5113 | { |
4943 | struct alc_spec *spec = codec->spec; | 5114 | struct alc_spec *spec = codec->spec; |
4944 | struct hda_input_mux *imux = &spec->private_imux[0]; | 5115 | struct hda_input_mux *imux = &spec->private_imux[0]; |
4945 | int i, err, idx; | 5116 | int i, err, idx, type, type_idx = 0; |
4946 | 5117 | ||
4947 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5118 | for (i = 0; i < cfg->num_inputs; i++) { |
4948 | hda_nid_t pin; | 5119 | hda_nid_t pin; |
5120 | const char *label; | ||
4949 | 5121 | ||
4950 | pin = cfg->input_pins[i]; | 5122 | pin = cfg->inputs[i].pin; |
4951 | if (!alc_is_input_pin(codec, pin)) | 5123 | if (!alc_is_input_pin(codec, pin)) |
4952 | continue; | 5124 | continue; |
4953 | 5125 | ||
5126 | type = cfg->inputs[i].type; | ||
5127 | if (i > 0 && type == cfg->inputs[i - 1].type) | ||
5128 | type_idx++; | ||
5129 | else | ||
5130 | type_idx = 0; | ||
5131 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
4954 | if (mixer) { | 5132 | if (mixer) { |
4955 | idx = get_connection_index(codec, mixer, pin); | 5133 | idx = get_connection_index(codec, mixer, pin); |
4956 | if (idx >= 0) { | 5134 | if (idx >= 0) { |
4957 | err = new_analog_input(spec, pin, | 5135 | err = new_analog_input(spec, pin, |
4958 | auto_pin_cfg_labels[i], | 5136 | label, type_idx, |
4959 | idx, mixer); | 5137 | idx, mixer); |
4960 | if (err < 0) | 5138 | if (err < 0) |
4961 | return err; | 5139 | return err; |
@@ -4967,12 +5145,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, | |||
4967 | idx = get_connection_index(codec, cap1, pin); | 5145 | idx = get_connection_index(codec, cap1, pin); |
4968 | if (idx < 0 && cap2) | 5146 | if (idx < 0 && cap2) |
4969 | idx = get_connection_index(codec, cap2, pin); | 5147 | idx = get_connection_index(codec, cap2, pin); |
4970 | if (idx >= 0) { | 5148 | if (idx >= 0) |
4971 | imux->items[imux->num_items].label = | 5149 | snd_hda_add_imux_item(imux, label, idx, NULL); |
4972 | auto_pin_cfg_labels[i]; | ||
4973 | imux->items[imux->num_items].index = idx; | ||
4974 | imux->num_items++; | ||
4975 | } | ||
4976 | } | 5150 | } |
4977 | return 0; | 5151 | return 0; |
4978 | } | 5152 | } |
@@ -5044,12 +5218,13 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec) | |||
5044 | static void alc880_auto_init_analog_input(struct hda_codec *codec) | 5218 | static void alc880_auto_init_analog_input(struct hda_codec *codec) |
5045 | { | 5219 | { |
5046 | struct alc_spec *spec = codec->spec; | 5220 | struct alc_spec *spec = codec->spec; |
5221 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5047 | int i; | 5222 | int i; |
5048 | 5223 | ||
5049 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5224 | for (i = 0; i < cfg->num_inputs; i++) { |
5050 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5225 | hda_nid_t nid = cfg->inputs[i].pin; |
5051 | if (alc_is_input_pin(codec, nid)) { | 5226 | if (alc_is_input_pin(codec, nid)) { |
5052 | alc_set_input_pin(codec, nid, i); | 5227 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
5053 | if (nid != ALC880_PIN_CD_NID && | 5228 | if (nid != ALC880_PIN_CD_NID && |
5054 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | 5229 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
5055 | snd_hda_codec_write(codec, nid, 0, | 5230 | snd_hda_codec_write(codec, nid, 0, |
@@ -5214,19 +5389,13 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
5214 | static void fixup_single_adc(struct hda_codec *codec) | 5389 | static void fixup_single_adc(struct hda_codec *codec) |
5215 | { | 5390 | { |
5216 | struct alc_spec *spec = codec->spec; | 5391 | struct alc_spec *spec = codec->spec; |
5217 | hda_nid_t pin = 0; | 5392 | struct auto_pin_cfg *cfg = &spec->autocfg; |
5218 | int i; | 5393 | int i; |
5219 | 5394 | ||
5220 | /* search for the input pin; there must be only one */ | 5395 | /* search for the input pin; there must be only one */ |
5221 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5396 | if (cfg->num_inputs != 1) |
5222 | if (spec->autocfg.input_pins[i]) { | ||
5223 | pin = spec->autocfg.input_pins[i]; | ||
5224 | break; | ||
5225 | } | ||
5226 | } | ||
5227 | if (!pin) | ||
5228 | return; | 5397 | return; |
5229 | i = init_capsrc_for_pin(codec, pin); | 5398 | i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); |
5230 | if (i >= 0) { | 5399 | if (i >= 0) { |
5231 | /* use only this ADC */ | 5400 | /* use only this ADC */ |
5232 | if (spec->capsrc_nids) | 5401 | if (spec->capsrc_nids) |
@@ -5279,6 +5448,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5279 | int num_nids) | 5448 | int num_nids) |
5280 | { | 5449 | { |
5281 | struct alc_spec *spec = codec->spec; | 5450 | struct alc_spec *spec = codec->spec; |
5451 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5282 | int n; | 5452 | int n; |
5283 | hda_nid_t fallback_adc = 0, fallback_cap = 0; | 5453 | hda_nid_t fallback_adc = 0, fallback_cap = 0; |
5284 | 5454 | ||
@@ -5304,10 +5474,8 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5304 | fallback_adc = adc; | 5474 | fallback_adc = adc; |
5305 | fallback_cap = cap; | 5475 | fallback_cap = cap; |
5306 | } | 5476 | } |
5307 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5477 | for (i = 0; i < cfg->num_inputs; i++) { |
5308 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5478 | hda_nid_t nid = cfg->inputs[i].pin; |
5309 | if (!nid) | ||
5310 | continue; | ||
5311 | for (j = 0; j < nconns; j++) { | 5479 | for (j = 0; j < nconns; j++) { |
5312 | if (conn[j] == nid) | 5480 | if (conn[j] == nid) |
5313 | break; | 5481 | break; |
@@ -5315,7 +5483,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5315 | if (j >= nconns) | 5483 | if (j >= nconns) |
5316 | break; | 5484 | break; |
5317 | } | 5485 | } |
5318 | if (i >= AUTO_PIN_LAST) { | 5486 | if (i >= cfg->num_inputs) { |
5319 | int num_adcs = spec->num_adc_nids; | 5487 | int num_adcs = spec->num_adc_nids; |
5320 | spec->private_adc_nids[num_adcs] = adc; | 5488 | spec->private_adc_nids[num_adcs] = adc; |
5321 | spec->private_capsrc_nids[num_adcs] = cap; | 5489 | spec->private_capsrc_nids[num_adcs] = cap; |
@@ -6683,12 +6851,13 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
6683 | static void alc260_auto_init_analog_input(struct hda_codec *codec) | 6851 | static void alc260_auto_init_analog_input(struct hda_codec *codec) |
6684 | { | 6852 | { |
6685 | struct alc_spec *spec = codec->spec; | 6853 | struct alc_spec *spec = codec->spec; |
6854 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
6686 | int i; | 6855 | int i; |
6687 | 6856 | ||
6688 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 6857 | for (i = 0; i < cfg->num_inputs; i++) { |
6689 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 6858 | hda_nid_t nid = cfg->inputs[i].pin; |
6690 | if (nid >= 0x12) { | 6859 | if (nid >= 0x12) { |
6691 | alc_set_input_pin(codec, nid, i); | 6860 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
6692 | if (nid != ALC260_PIN_CD_NID && | 6861 | if (nid != ALC260_PIN_CD_NID && |
6693 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | 6862 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
6694 | snd_hda_codec_write(codec, nid, 0, | 6863 | snd_hda_codec_write(codec, nid, 0, |
@@ -6810,14 +6979,12 @@ enum { | |||
6810 | PINFIX_HP_DC5750, | 6979 | PINFIX_HP_DC5750, |
6811 | }; | 6980 | }; |
6812 | 6981 | ||
6813 | static struct alc_pincfg alc260_hp_dc5750_pinfix[] = { | ||
6814 | { 0x11, 0x90130110 }, /* speaker */ | ||
6815 | { } | ||
6816 | }; | ||
6817 | |||
6818 | static const struct alc_fixup alc260_fixups[] = { | 6982 | static const struct alc_fixup alc260_fixups[] = { |
6819 | [PINFIX_HP_DC5750] = { | 6983 | [PINFIX_HP_DC5750] = { |
6820 | .pins = alc260_hp_dc5750_pinfix | 6984 | .pins = (const struct alc_pincfg[]) { |
6985 | { 0x11, 0x90130110 }, /* speaker */ | ||
6986 | { } | ||
6987 | } | ||
6821 | }, | 6988 | }, |
6822 | }; | 6989 | }; |
6823 | 6990 | ||
@@ -10461,32 +10628,33 @@ static struct alc_config_preset alc882_presets[] = { | |||
10461 | enum { | 10628 | enum { |
10462 | PINFIX_ABIT_AW9D_MAX, | 10629 | PINFIX_ABIT_AW9D_MAX, |
10463 | PINFIX_PB_M5210, | 10630 | PINFIX_PB_M5210, |
10464 | }; | 10631 | PINFIX_ACER_ASPIRE_7736, |
10465 | |||
10466 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | ||
10467 | { 0x15, 0x01080104 }, /* side */ | ||
10468 | { 0x16, 0x01011012 }, /* rear */ | ||
10469 | { 0x17, 0x01016011 }, /* clfe */ | ||
10470 | { } | ||
10471 | }; | ||
10472 | |||
10473 | static const struct hda_verb pb_m5210_verbs[] = { | ||
10474 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
10475 | {} | ||
10476 | }; | 10632 | }; |
10477 | 10633 | ||
10478 | static const struct alc_fixup alc882_fixups[] = { | 10634 | static const struct alc_fixup alc882_fixups[] = { |
10479 | [PINFIX_ABIT_AW9D_MAX] = { | 10635 | [PINFIX_ABIT_AW9D_MAX] = { |
10480 | .pins = alc882_abit_aw9d_pinfix | 10636 | .pins = (const struct alc_pincfg[]) { |
10637 | { 0x15, 0x01080104 }, /* side */ | ||
10638 | { 0x16, 0x01011012 }, /* rear */ | ||
10639 | { 0x17, 0x01016011 }, /* clfe */ | ||
10640 | { } | ||
10641 | } | ||
10481 | }, | 10642 | }, |
10482 | [PINFIX_PB_M5210] = { | 10643 | [PINFIX_PB_M5210] = { |
10483 | .verbs = pb_m5210_verbs | 10644 | .verbs = (const struct hda_verb[]) { |
10645 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
10646 | {} | ||
10647 | } | ||
10648 | }, | ||
10649 | [PINFIX_ACER_ASPIRE_7736] = { | ||
10650 | .sku = ALC_FIXUP_SKU_IGNORE, | ||
10484 | }, | 10651 | }, |
10485 | }; | 10652 | }; |
10486 | 10653 | ||
10487 | static struct snd_pci_quirk alc882_fixup_tbl[] = { | 10654 | static struct snd_pci_quirk alc882_fixup_tbl[] = { |
10488 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | 10655 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), |
10489 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 10656 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
10657 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), | ||
10490 | {} | 10658 | {} |
10491 | }; | 10659 | }; |
10492 | 10660 | ||
@@ -10535,16 +10703,21 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
10535 | { | 10703 | { |
10536 | struct alc_spec *spec = codec->spec; | 10704 | struct alc_spec *spec = codec->spec; |
10537 | hda_nid_t pin, dac; | 10705 | hda_nid_t pin, dac; |
10706 | int i; | ||
10538 | 10707 | ||
10539 | pin = spec->autocfg.hp_pins[0]; | 10708 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
10540 | if (pin) { | 10709 | pin = spec->autocfg.hp_pins[i]; |
10710 | if (!pin) | ||
10711 | break; | ||
10541 | dac = spec->multiout.hp_nid; | 10712 | dac = spec->multiout.hp_nid; |
10542 | if (!dac) | 10713 | if (!dac) |
10543 | dac = spec->multiout.dac_nids[0]; /* to front */ | 10714 | dac = spec->multiout.dac_nids[0]; /* to front */ |
10544 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | 10715 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); |
10545 | } | 10716 | } |
10546 | pin = spec->autocfg.speaker_pins[0]; | 10717 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
10547 | if (pin) { | 10718 | pin = spec->autocfg.speaker_pins[i]; |
10719 | if (!pin) | ||
10720 | break; | ||
10548 | dac = spec->multiout.extra_out_nid[0]; | 10721 | dac = spec->multiout.extra_out_nid[0]; |
10549 | if (!dac) | 10722 | if (!dac) |
10550 | dac = spec->multiout.dac_nids[0]; /* to front */ | 10723 | dac = spec->multiout.dac_nids[0]; /* to front */ |
@@ -10555,13 +10728,12 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
10555 | static void alc882_auto_init_analog_input(struct hda_codec *codec) | 10728 | static void alc882_auto_init_analog_input(struct hda_codec *codec) |
10556 | { | 10729 | { |
10557 | struct alc_spec *spec = codec->spec; | 10730 | struct alc_spec *spec = codec->spec; |
10731 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
10558 | int i; | 10732 | int i; |
10559 | 10733 | ||
10560 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 10734 | for (i = 0; i < cfg->num_inputs; i++) { |
10561 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 10735 | hda_nid_t nid = cfg->inputs[i].pin; |
10562 | if (!nid) | 10736 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
10563 | continue; | ||
10564 | alc_set_input_pin(codec, nid, i); | ||
10565 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | 10737 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) |
10566 | snd_hda_codec_write(codec, nid, 0, | 10738 | snd_hda_codec_write(codec, nid, 0, |
10567 | AC_VERB_SET_AMP_GAIN_MUTE, | 10739 | AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -10623,24 +10795,23 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) | |||
10623 | static int alc_auto_add_mic_boost(struct hda_codec *codec) | 10795 | static int alc_auto_add_mic_boost(struct hda_codec *codec) |
10624 | { | 10796 | { |
10625 | struct alc_spec *spec = codec->spec; | 10797 | struct alc_spec *spec = codec->spec; |
10626 | int err; | 10798 | struct auto_pin_cfg *cfg = &spec->autocfg; |
10799 | int i, err; | ||
10627 | hda_nid_t nid; | 10800 | hda_nid_t nid; |
10628 | 10801 | ||
10629 | nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; | 10802 | for (i = 0; i < cfg->num_inputs; i++) { |
10630 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | 10803 | if (cfg->inputs[i].type > AUTO_PIN_MIC) |
10631 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 10804 | break; |
10632 | "Mic Boost", | 10805 | nid = cfg->inputs[i].pin; |
10633 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10806 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { |
10634 | if (err < 0) | 10807 | char label[32]; |
10635 | return err; | 10808 | snprintf(label, sizeof(label), "%s Boost", |
10636 | } | 10809 | hda_get_autocfg_input_label(codec, cfg, i)); |
10637 | nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; | 10810 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, |
10638 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | ||
10639 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
10640 | "Front Mic Boost", | ||
10641 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10811 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
10642 | if (err < 0) | 10812 | if (err < 0) |
10643 | return err; | 10813 | return err; |
10814 | } | ||
10644 | } | 10815 | } |
10645 | return 0; | 10816 | return 0; |
10646 | } | 10817 | } |
@@ -10726,8 +10897,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
10726 | 10897 | ||
10727 | codec->spec = spec; | 10898 | codec->spec = spec; |
10728 | 10899 | ||
10729 | alc_auto_parse_customize_define(codec); | ||
10730 | |||
10731 | switch (codec->vendor_id) { | 10900 | switch (codec->vendor_id) { |
10732 | case 0x10ec0882: | 10901 | case 0x10ec0882: |
10733 | case 0x10ec0885: | 10902 | case 0x10ec0885: |
@@ -10755,6 +10924,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
10755 | if (board_config == ALC882_AUTO) | 10924 | if (board_config == ALC882_AUTO) |
10756 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); | 10925 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); |
10757 | 10926 | ||
10927 | alc_auto_parse_customize_define(codec); | ||
10928 | |||
10758 | if (board_config == ALC882_AUTO) { | 10929 | if (board_config == ALC882_AUTO) { |
10759 | /* automatic parse from the BIOS config */ | 10930 | /* automatic parse from the BIOS config */ |
10760 | err = alc882_parse_auto_config(codec); | 10931 | err = alc882_parse_auto_config(codec); |
@@ -10835,6 +11006,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
10835 | codec->patch_ops = alc_patch_ops; | 11006 | codec->patch_ops = alc_patch_ops; |
10836 | if (board_config == ALC882_AUTO) | 11007 | if (board_config == ALC882_AUTO) |
10837 | spec->init_hook = alc882_auto_init; | 11008 | spec->init_hook = alc882_auto_init; |
11009 | |||
11010 | alc_init_jacks(codec); | ||
10838 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 11011 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
10839 | if (!spec->loopback.amplist) | 11012 | if (!spec->loopback.amplist) |
10840 | spec->loopback.amplist = alc882_loopbacks; | 11013 | spec->loopback.amplist = alc882_loopbacks; |
@@ -11831,7 +12004,7 @@ static int alc262_check_volbit(hda_nid_t nid) | |||
11831 | } | 12004 | } |
11832 | 12005 | ||
11833 | static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, | 12006 | static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, |
11834 | const char *pfx, int *vbits) | 12007 | const char *pfx, int *vbits, int idx) |
11835 | { | 12008 | { |
11836 | unsigned long val; | 12009 | unsigned long val; |
11837 | int vbit; | 12010 | int vbit; |
@@ -11846,11 +12019,11 @@ static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, | |||
11846 | val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); | 12019 | val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); |
11847 | else | 12020 | else |
11848 | val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); | 12021 | val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); |
11849 | return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); | 12022 | return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val); |
11850 | } | 12023 | } |
11851 | 12024 | ||
11852 | static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, | 12025 | static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, |
11853 | const char *pfx) | 12026 | const char *pfx, int idx) |
11854 | { | 12027 | { |
11855 | unsigned long val; | 12028 | unsigned long val; |
11856 | 12029 | ||
@@ -11860,7 +12033,7 @@ static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, | |||
11860 | val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); | 12033 | val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); |
11861 | else | 12034 | else |
11862 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | 12035 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); |
11863 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | 12036 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val); |
11864 | } | 12037 | } |
11865 | 12038 | ||
11866 | /* add playback controls from the parsed DAC table */ | 12039 | /* add playback controls from the parsed DAC table */ |
@@ -11869,7 +12042,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11869 | { | 12042 | { |
11870 | const char *pfx; | 12043 | const char *pfx; |
11871 | int vbits; | 12044 | int vbits; |
11872 | int err; | 12045 | int i, err; |
11873 | 12046 | ||
11874 | spec->multiout.num_dacs = 1; /* only use one dac */ | 12047 | spec->multiout.num_dacs = 1; /* only use one dac */ |
11875 | spec->multiout.dac_nids = spec->private_dac_nids; | 12048 | spec->multiout.dac_nids = spec->private_dac_nids; |
@@ -11879,39 +12052,52 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11879 | pfx = "Master"; | 12052 | pfx = "Master"; |
11880 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | 12053 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) |
11881 | pfx = "Speaker"; | 12054 | pfx = "Speaker"; |
12055 | else if (cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
12056 | pfx = "Headphone"; | ||
11882 | else | 12057 | else |
11883 | pfx = "Front"; | 12058 | pfx = "Front"; |
11884 | err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx); | 12059 | for (i = 0; i < 2; i++) { |
11885 | if (err < 0) | 12060 | err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); |
11886 | return err; | 12061 | if (err < 0) |
11887 | err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker"); | 12062 | return err; |
11888 | if (err < 0) | 12063 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
11889 | return err; | 12064 | err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i], |
11890 | err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone"); | 12065 | "Speaker", i); |
11891 | if (err < 0) | 12066 | if (err < 0) |
11892 | return err; | 12067 | return err; |
12068 | } | ||
12069 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { | ||
12070 | err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i], | ||
12071 | "Headphone", i); | ||
12072 | if (err < 0) | ||
12073 | return err; | ||
12074 | } | ||
12075 | } | ||
11893 | 12076 | ||
11894 | vbits = alc262_check_volbit(cfg->line_out_pins[0]) | | 12077 | vbits = alc262_check_volbit(cfg->line_out_pins[0]) | |
11895 | alc262_check_volbit(cfg->speaker_pins[0]) | | 12078 | alc262_check_volbit(cfg->speaker_pins[0]) | |
11896 | alc262_check_volbit(cfg->hp_pins[0]); | 12079 | alc262_check_volbit(cfg->hp_pins[0]); |
11897 | if (vbits == 1 || vbits == 2) | 12080 | if (vbits == 1 || vbits == 2) |
11898 | pfx = "Master"; /* only one mixer is used */ | 12081 | pfx = "Master"; /* only one mixer is used */ |
11899 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
11900 | pfx = "Speaker"; | ||
11901 | else | ||
11902 | pfx = "Front"; | ||
11903 | vbits = 0; | 12082 | vbits = 0; |
11904 | err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits); | 12083 | for (i = 0; i < 2; i++) { |
11905 | if (err < 0) | 12084 | err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx, |
11906 | return err; | 12085 | &vbits, i); |
11907 | err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker", | 12086 | if (err < 0) |
11908 | &vbits); | 12087 | return err; |
11909 | if (err < 0) | 12088 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
11910 | return err; | 12089 | err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i], |
11911 | err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone", | 12090 | "Speaker", &vbits, i); |
11912 | &vbits); | 12091 | if (err < 0) |
11913 | if (err < 0) | 12092 | return err; |
11914 | return err; | 12093 | } |
12094 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { | ||
12095 | err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i], | ||
12096 | "Headphone", &vbits, i); | ||
12097 | if (err < 0) | ||
12098 | return err; | ||
12099 | } | ||
12100 | } | ||
11915 | return 0; | 12101 | return 0; |
11916 | } | 12102 | } |
11917 | 12103 | ||
@@ -12199,6 +12385,35 @@ static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { | |||
12199 | {} | 12385 | {} |
12200 | }; | 12386 | }; |
12201 | 12387 | ||
12388 | /* | ||
12389 | * Pin config fixes | ||
12390 | */ | ||
12391 | enum { | ||
12392 | PINFIX_FSC_H270, | ||
12393 | }; | ||
12394 | |||
12395 | static const struct alc_fixup alc262_fixups[] = { | ||
12396 | [PINFIX_FSC_H270] = { | ||
12397 | .pins = (const struct alc_pincfg[]) { | ||
12398 | { 0x14, 0x99130110 }, /* speaker */ | ||
12399 | { 0x15, 0x0221142f }, /* front HP */ | ||
12400 | { 0x1b, 0x0121141f }, /* rear HP */ | ||
12401 | { } | ||
12402 | } | ||
12403 | }, | ||
12404 | [PINFIX_PB_M5210] = { | ||
12405 | .verbs = (const struct hda_verb[]) { | ||
12406 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
12407 | {} | ||
12408 | } | ||
12409 | }, | ||
12410 | }; | ||
12411 | |||
12412 | static struct snd_pci_quirk alc262_fixup_tbl[] = { | ||
12413 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), | ||
12414 | {} | ||
12415 | }; | ||
12416 | |||
12202 | 12417 | ||
12203 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 12418 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
12204 | #define alc262_loopbacks alc880_loopbacks | 12419 | #define alc262_loopbacks alc880_loopbacks |
@@ -12622,6 +12837,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
12622 | board_config = ALC262_AUTO; | 12837 | board_config = ALC262_AUTO; |
12623 | } | 12838 | } |
12624 | 12839 | ||
12840 | if (board_config == ALC262_AUTO) | ||
12841 | alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1); | ||
12842 | |||
12625 | if (board_config == ALC262_AUTO) { | 12843 | if (board_config == ALC262_AUTO) { |
12626 | /* automatic parse from the BIOS config */ | 12844 | /* automatic parse from the BIOS config */ |
12627 | err = alc262_parse_auto_config(codec); | 12845 | err = alc262_parse_auto_config(codec); |
@@ -12690,11 +12908,16 @@ static int patch_alc262(struct hda_codec *codec) | |||
12690 | if (!spec->no_analog && has_cdefine_beep(codec)) | 12908 | if (!spec->no_analog && has_cdefine_beep(codec)) |
12691 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 12909 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
12692 | 12910 | ||
12911 | if (board_config == ALC262_AUTO) | ||
12912 | alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0); | ||
12913 | |||
12693 | spec->vmaster_nid = 0x0c; | 12914 | spec->vmaster_nid = 0x0c; |
12694 | 12915 | ||
12695 | codec->patch_ops = alc_patch_ops; | 12916 | codec->patch_ops = alc_patch_ops; |
12696 | if (board_config == ALC262_AUTO) | 12917 | if (board_config == ALC262_AUTO) |
12697 | spec->init_hook = alc262_auto_init; | 12918 | spec->init_hook = alc262_auto_init; |
12919 | |||
12920 | alc_init_jacks(codec); | ||
12698 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 12921 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
12699 | if (!spec->loopback.amplist) | 12922 | if (!spec->loopback.amplist) |
12700 | spec->loopback.amplist = alc262_loopbacks; | 12923 | spec->loopback.amplist = alc262_loopbacks; |
@@ -13310,8 +13533,10 @@ static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, | |||
13310 | static void alc268_auto_init_multi_out(struct hda_codec *codec) | 13533 | static void alc268_auto_init_multi_out(struct hda_codec *codec) |
13311 | { | 13534 | { |
13312 | struct alc_spec *spec = codec->spec; | 13535 | struct alc_spec *spec = codec->spec; |
13313 | hda_nid_t nid = spec->autocfg.line_out_pins[0]; | 13536 | int i; |
13314 | if (nid) { | 13537 | |
13538 | for (i = 0; i < spec->autocfg.line_outs; i++) { | ||
13539 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
13315 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 13540 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
13316 | alc268_auto_set_output_and_unmute(codec, nid, pin_type); | 13541 | alc268_auto_set_output_and_unmute(codec, nid, pin_type); |
13317 | } | 13542 | } |
@@ -13321,13 +13546,19 @@ static void alc268_auto_init_hp_out(struct hda_codec *codec) | |||
13321 | { | 13546 | { |
13322 | struct alc_spec *spec = codec->spec; | 13547 | struct alc_spec *spec = codec->spec; |
13323 | hda_nid_t pin; | 13548 | hda_nid_t pin; |
13549 | int i; | ||
13324 | 13550 | ||
13325 | pin = spec->autocfg.hp_pins[0]; | 13551 | for (i = 0; i < spec->autocfg.hp_outs; i++) { |
13326 | if (pin) | 13552 | pin = spec->autocfg.hp_pins[i]; |
13327 | alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); | 13553 | alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); |
13328 | pin = spec->autocfg.speaker_pins[0]; | 13554 | } |
13329 | if (pin) | 13555 | for (i = 0; i < spec->autocfg.speaker_outs; i++) { |
13556 | pin = spec->autocfg.speaker_pins[i]; | ||
13330 | alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); | 13557 | alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); |
13558 | } | ||
13559 | if (spec->autocfg.mono_out_pin) | ||
13560 | snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0, | ||
13561 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
13331 | } | 13562 | } |
13332 | 13563 | ||
13333 | static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) | 13564 | static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) |
@@ -13766,6 +13997,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
13766 | if (board_config == ALC268_AUTO) | 13997 | if (board_config == ALC268_AUTO) |
13767 | spec->init_hook = alc268_auto_init; | 13998 | spec->init_hook = alc268_auto_init; |
13768 | 13999 | ||
14000 | alc_init_jacks(codec); | ||
14001 | |||
13769 | return 0; | 14002 | return 0; |
13770 | } | 14003 | } |
13771 | 14004 | ||
@@ -14132,6 +14365,7 @@ static void alc269_speaker_automute(struct hda_codec *codec) | |||
14132 | HDA_AMP_MUTE, bits); | 14365 | HDA_AMP_MUTE, bits); |
14133 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 14366 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
14134 | HDA_AMP_MUTE, bits); | 14367 | HDA_AMP_MUTE, bits); |
14368 | alc_report_jack(codec, nid); | ||
14135 | } | 14369 | } |
14136 | 14370 | ||
14137 | /* unsolicited event for HP jack sensing */ | 14371 | /* unsolicited event for HP jack sensing */ |
@@ -14386,6 +14620,13 @@ static int alc275_setup_dual_adc(struct hda_codec *codec) | |||
14386 | return 0; | 14620 | return 0; |
14387 | } | 14621 | } |
14388 | 14622 | ||
14623 | /* different alc269-variants */ | ||
14624 | enum { | ||
14625 | ALC269_TYPE_NORMAL, | ||
14626 | ALC269_TYPE_ALC259, | ||
14627 | ALC269_TYPE_ALC271X, | ||
14628 | }; | ||
14629 | |||
14389 | /* | 14630 | /* |
14390 | * BIOS auto configuration | 14631 | * BIOS auto configuration |
14391 | */ | 14632 | */ |
@@ -14403,7 +14644,11 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14403 | err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); | 14644 | err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); |
14404 | if (err < 0) | 14645 | if (err < 0) |
14405 | return err; | 14646 | return err; |
14406 | err = alc269_auto_create_input_ctls(codec, &spec->autocfg); | 14647 | if (spec->codec_variant == ALC269_TYPE_NORMAL) |
14648 | err = alc269_auto_create_input_ctls(codec, &spec->autocfg); | ||
14649 | else | ||
14650 | err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0, | ||
14651 | 0x22, 0); | ||
14407 | if (err < 0) | 14652 | if (err < 0) |
14408 | return err; | 14653 | return err; |
14409 | 14654 | ||
@@ -14414,7 +14659,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14414 | if (spec->kctls.list) | 14659 | if (spec->kctls.list) |
14415 | add_mixer(spec, spec->kctls.list); | 14660 | add_mixer(spec, spec->kctls.list); |
14416 | 14661 | ||
14417 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { | 14662 | if (spec->codec_variant != ALC269_TYPE_NORMAL) { |
14418 | add_verb(spec, alc269vb_init_verbs); | 14663 | add_verb(spec, alc269vb_init_verbs); |
14419 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); | 14664 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); |
14420 | } else { | 14665 | } else { |
@@ -14461,19 +14706,71 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14461 | alc_inithook(codec); | 14706 | alc_inithook(codec); |
14462 | } | 14707 | } |
14463 | 14708 | ||
14709 | #ifdef SND_HDA_NEEDS_RESUME | ||
14710 | static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | ||
14711 | { | ||
14712 | int val = alc_read_coef_idx(codec, 0x04); | ||
14713 | if (power_up) | ||
14714 | val |= 1 << 11; | ||
14715 | else | ||
14716 | val &= ~(1 << 11); | ||
14717 | alc_write_coef_idx(codec, 0x04, val); | ||
14718 | } | ||
14719 | |||
14720 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
14721 | static int alc269_suspend(struct hda_codec *codec, pm_message_t state) | ||
14722 | { | ||
14723 | struct alc_spec *spec = codec->spec; | ||
14724 | |||
14725 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) | ||
14726 | alc269_toggle_power_output(codec, 0); | ||
14727 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14728 | alc269_toggle_power_output(codec, 0); | ||
14729 | msleep(150); | ||
14730 | } | ||
14731 | |||
14732 | alc_shutup(codec); | ||
14733 | if (spec && spec->power_hook) | ||
14734 | spec->power_hook(codec); | ||
14735 | return 0; | ||
14736 | } | ||
14737 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
14738 | |||
14739 | static int alc269_resume(struct hda_codec *codec) | ||
14740 | { | ||
14741 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14742 | alc269_toggle_power_output(codec, 0); | ||
14743 | msleep(150); | ||
14744 | } | ||
14745 | |||
14746 | codec->patch_ops.init(codec); | ||
14747 | |||
14748 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | ||
14749 | alc269_toggle_power_output(codec, 1); | ||
14750 | msleep(200); | ||
14751 | } | ||
14752 | |||
14753 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) | ||
14754 | alc269_toggle_power_output(codec, 1); | ||
14755 | |||
14756 | snd_hda_codec_resume_amp(codec); | ||
14757 | snd_hda_codec_resume_cache(codec); | ||
14758 | hda_call_check_power_status(codec, 0x01); | ||
14759 | return 0; | ||
14760 | } | ||
14761 | #endif /* SND_HDA_NEEDS_RESUME */ | ||
14762 | |||
14464 | enum { | 14763 | enum { |
14465 | ALC269_FIXUP_SONY_VAIO, | 14764 | ALC269_FIXUP_SONY_VAIO, |
14466 | ALC269_FIXUP_DELL_M101Z, | 14765 | ALC269_FIXUP_DELL_M101Z, |
14467 | }; | 14766 | }; |
14468 | 14767 | ||
14469 | static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { | ||
14470 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, | ||
14471 | {} | ||
14472 | }; | ||
14473 | |||
14474 | static const struct alc_fixup alc269_fixups[] = { | 14768 | static const struct alc_fixup alc269_fixups[] = { |
14475 | [ALC269_FIXUP_SONY_VAIO] = { | 14769 | [ALC269_FIXUP_SONY_VAIO] = { |
14476 | .verbs = alc269_sony_vaio_fixup_verbs | 14770 | .verbs = (const struct hda_verb[]) { |
14771 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, | ||
14772 | {} | ||
14773 | } | ||
14477 | }, | 14774 | }, |
14478 | [ALC269_FIXUP_DELL_M101Z] = { | 14775 | [ALC269_FIXUP_DELL_M101Z] = { |
14479 | .verbs = (const struct hda_verb[]) { | 14776 | .verbs = (const struct hda_verb[]) { |
@@ -14486,8 +14783,7 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14486 | }; | 14783 | }; |
14487 | 14784 | ||
14488 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14785 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
14489 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14786 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
14490 | SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | ||
14491 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 14787 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
14492 | {} | 14788 | {} |
14493 | }; | 14789 | }; |
@@ -14689,12 +14985,46 @@ static struct alc_config_preset alc269_presets[] = { | |||
14689 | }, | 14985 | }, |
14690 | }; | 14986 | }; |
14691 | 14987 | ||
14988 | static int alc269_fill_coef(struct hda_codec *codec) | ||
14989 | { | ||
14990 | int val; | ||
14991 | |||
14992 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { | ||
14993 | alc_write_coef_idx(codec, 0xf, 0x960b); | ||
14994 | alc_write_coef_idx(codec, 0xe, 0x8817); | ||
14995 | } | ||
14996 | |||
14997 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { | ||
14998 | alc_write_coef_idx(codec, 0xf, 0x960b); | ||
14999 | alc_write_coef_idx(codec, 0xe, 0x8814); | ||
15000 | } | ||
15001 | |||
15002 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | ||
15003 | val = alc_read_coef_idx(codec, 0x04); | ||
15004 | /* Power up output pin */ | ||
15005 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | ||
15006 | } | ||
15007 | |||
15008 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
15009 | val = alc_read_coef_idx(codec, 0xd); | ||
15010 | if ((val & 0x0c00) >> 10 != 0x1) { | ||
15011 | /* Capless ramp up clock control */ | ||
15012 | alc_write_coef_idx(codec, 0xd, val | 1<<10); | ||
15013 | } | ||
15014 | val = alc_read_coef_idx(codec, 0x17); | ||
15015 | if ((val & 0x01c0) >> 6 != 0x4) { | ||
15016 | /* Class D power on reset */ | ||
15017 | alc_write_coef_idx(codec, 0x17, val | 1<<7); | ||
15018 | } | ||
15019 | } | ||
15020 | return 0; | ||
15021 | } | ||
15022 | |||
14692 | static int patch_alc269(struct hda_codec *codec) | 15023 | static int patch_alc269(struct hda_codec *codec) |
14693 | { | 15024 | { |
14694 | struct alc_spec *spec; | 15025 | struct alc_spec *spec; |
14695 | int board_config; | 15026 | int board_config; |
14696 | int err; | 15027 | int err; |
14697 | int is_alc269vb = 0; | ||
14698 | 15028 | ||
14699 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 15029 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
14700 | if (spec == NULL) | 15030 | if (spec == NULL) |
@@ -14706,14 +15036,18 @@ static int patch_alc269(struct hda_codec *codec) | |||
14706 | 15036 | ||
14707 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ | 15037 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ |
14708 | if (codec->bus->pci->subsystem_vendor == 0x1025 && | 15038 | if (codec->bus->pci->subsystem_vendor == 0x1025 && |
14709 | spec->cdefine.platform_type == 1) | 15039 | spec->cdefine.platform_type == 1) { |
14710 | alc_codec_rename(codec, "ALC271X"); | 15040 | alc_codec_rename(codec, "ALC271X"); |
14711 | else | 15041 | spec->codec_variant = ALC269_TYPE_ALC271X; |
15042 | } else { | ||
14712 | alc_codec_rename(codec, "ALC259"); | 15043 | alc_codec_rename(codec, "ALC259"); |
14713 | is_alc269vb = 1; | 15044 | spec->codec_variant = ALC269_TYPE_ALC259; |
15045 | } | ||
14714 | } else | 15046 | } else |
14715 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 15047 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
14716 | 15048 | ||
15049 | alc269_fill_coef(codec); | ||
15050 | |||
14717 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 15051 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
14718 | alc269_models, | 15052 | alc269_models, |
14719 | alc269_cfg_tbl); | 15053 | alc269_cfg_tbl); |
@@ -14770,7 +15104,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
14770 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 15104 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
14771 | 15105 | ||
14772 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ | 15106 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ |
14773 | if (!is_alc269vb) { | 15107 | if (spec->codec_variant != ALC269_TYPE_NORMAL) { |
14774 | spec->adc_nids = alc269_adc_nids; | 15108 | spec->adc_nids = alc269_adc_nids; |
14775 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 15109 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
14776 | spec->capsrc_nids = alc269_capsrc_nids; | 15110 | spec->capsrc_nids = alc269_capsrc_nids; |
@@ -14792,8 +15126,16 @@ static int patch_alc269(struct hda_codec *codec) | |||
14792 | spec->vmaster_nid = 0x02; | 15126 | spec->vmaster_nid = 0x02; |
14793 | 15127 | ||
14794 | codec->patch_ops = alc_patch_ops; | 15128 | codec->patch_ops = alc_patch_ops; |
15129 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
15130 | codec->patch_ops.suspend = alc269_suspend; | ||
15131 | #endif | ||
15132 | #ifdef SND_HDA_NEEDS_RESUME | ||
15133 | codec->patch_ops.resume = alc269_resume; | ||
15134 | #endif | ||
14795 | if (board_config == ALC269_AUTO) | 15135 | if (board_config == ALC269_AUTO) |
14796 | spec->init_hook = alc269_auto_init; | 15136 | spec->init_hook = alc269_auto_init; |
15137 | |||
15138 | alc_init_jacks(codec); | ||
14797 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15139 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
14798 | if (!spec->loopback.amplist) | 15140 | if (!spec->loopback.amplist) |
14799 | spec->loopback.amplist = alc269_loopbacks; | 15141 | spec->loopback.amplist = alc269_loopbacks; |
@@ -15606,12 +15948,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
15606 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 15948 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
15607 | { | 15949 | { |
15608 | struct alc_spec *spec = codec->spec; | 15950 | struct alc_spec *spec = codec->spec; |
15951 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
15609 | int i; | 15952 | int i; |
15610 | 15953 | ||
15611 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 15954 | for (i = 0; i < cfg->num_inputs; i++) { |
15612 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 15955 | hda_nid_t nid = cfg->inputs[i].pin; |
15613 | if (nid >= 0x0c && nid <= 0x11) | 15956 | if (nid >= 0x0c && nid <= 0x11) |
15614 | alc_set_input_pin(codec, nid, i); | 15957 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
15615 | } | 15958 | } |
15616 | } | 15959 | } |
15617 | 15960 | ||
@@ -15840,15 +16183,13 @@ enum { | |||
15840 | PINFIX_FSC_AMILO_PI1505, | 16183 | PINFIX_FSC_AMILO_PI1505, |
15841 | }; | 16184 | }; |
15842 | 16185 | ||
15843 | static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = { | ||
15844 | { 0x0b, 0x0221101f }, /* HP */ | ||
15845 | { 0x0f, 0x90170310 }, /* speaker */ | ||
15846 | { } | ||
15847 | }; | ||
15848 | |||
15849 | static const struct alc_fixup alc861_fixups[] = { | 16186 | static const struct alc_fixup alc861_fixups[] = { |
15850 | [PINFIX_FSC_AMILO_PI1505] = { | 16187 | [PINFIX_FSC_AMILO_PI1505] = { |
15851 | .pins = alc861_fsc_amilo_pi1505_pinfix | 16188 | .pins = (const struct alc_pincfg[]) { |
16189 | { 0x0b, 0x0221101f }, /* HP */ | ||
16190 | { 0x0f, 0x90170310 }, /* speaker */ | ||
16191 | { } | ||
16192 | } | ||
15852 | }, | 16193 | }, |
15853 | }; | 16194 | }; |
15854 | 16195 | ||
@@ -16600,12 +16941,13 @@ static void alc861vd_auto_init_hp_out(struct hda_codec *codec) | |||
16600 | static void alc861vd_auto_init_analog_input(struct hda_codec *codec) | 16941 | static void alc861vd_auto_init_analog_input(struct hda_codec *codec) |
16601 | { | 16942 | { |
16602 | struct alc_spec *spec = codec->spec; | 16943 | struct alc_spec *spec = codec->spec; |
16944 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
16603 | int i; | 16945 | int i; |
16604 | 16946 | ||
16605 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16947 | for (i = 0; i < cfg->num_inputs; i++) { |
16606 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 16948 | hda_nid_t nid = cfg->inputs[i].pin; |
16607 | if (alc_is_input_pin(codec, nid)) { | 16949 | if (alc_is_input_pin(codec, nid)) { |
16608 | alc_set_input_pin(codec, nid, i); | 16950 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
16609 | if (nid != ALC861VD_PIN_CD_NID && | 16951 | if (nid != ALC861VD_PIN_CD_NID && |
16610 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | 16952 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
16611 | snd_hda_codec_write(codec, nid, 0, | 16953 | snd_hda_codec_write(codec, nid, 0, |
@@ -16815,16 +17157,14 @@ enum { | |||
16815 | }; | 17157 | }; |
16816 | 17158 | ||
16817 | /* reset GPIO1 */ | 17159 | /* reset GPIO1 */ |
16818 | static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = { | ||
16819 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
16820 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
16821 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
16822 | { } | ||
16823 | }; | ||
16824 | |||
16825 | static const struct alc_fixup alc861vd_fixups[] = { | 17160 | static const struct alc_fixup alc861vd_fixups[] = { |
16826 | [ALC660VD_FIX_ASUS_GPIO1] = { | 17161 | [ALC660VD_FIX_ASUS_GPIO1] = { |
16827 | .verbs = alc660vd_fix_asus_gpio1_verbs, | 17162 | .verbs = (const struct hda_verb[]) { |
17163 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
17164 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
17165 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
17166 | { } | ||
17167 | } | ||
16828 | }, | 17168 | }, |
16829 | }; | 17169 | }; |
16830 | 17170 | ||
@@ -18838,12 +19178,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) | |||
18838 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | 19178 | static void alc662_auto_init_analog_input(struct hda_codec *codec) |
18839 | { | 19179 | { |
18840 | struct alc_spec *spec = codec->spec; | 19180 | struct alc_spec *spec = codec->spec; |
19181 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
18841 | int i; | 19182 | int i; |
18842 | 19183 | ||
18843 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 19184 | for (i = 0; i < cfg->num_inputs; i++) { |
18844 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 19185 | hda_nid_t nid = cfg->inputs[i].pin; |
18845 | if (alc_is_input_pin(codec, nid)) { | 19186 | if (alc_is_input_pin(codec, nid)) { |
18846 | alc_set_input_pin(codec, nid, i); | 19187 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
18847 | if (nid != ALC662_PIN_CD_NID && | 19188 | if (nid != ALC662_PIN_CD_NID && |
18848 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | 19189 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
18849 | snd_hda_codec_write(codec, nid, 0, | 19190 | snd_hda_codec_write(codec, nid, 0, |
@@ -18935,10 +19276,40 @@ static void alc662_auto_init(struct hda_codec *codec) | |||
18935 | alc_inithook(codec); | 19276 | alc_inithook(codec); |
18936 | } | 19277 | } |
18937 | 19278 | ||
19279 | enum { | ||
19280 | ALC662_FIXUP_ASPIRE, | ||
19281 | ALC662_FIXUP_IDEAPAD, | ||
19282 | }; | ||
19283 | |||
19284 | static const struct alc_fixup alc662_fixups[] = { | ||
19285 | [ALC662_FIXUP_ASPIRE] = { | ||
19286 | .pins = (const struct alc_pincfg[]) { | ||
19287 | { 0x15, 0x99130112 }, /* subwoofer */ | ||
19288 | { } | ||
19289 | } | ||
19290 | }, | ||
19291 | [ALC662_FIXUP_IDEAPAD] = { | ||
19292 | .pins = (const struct alc_pincfg[]) { | ||
19293 | { 0x17, 0x99130112 }, /* subwoofer */ | ||
19294 | { } | ||
19295 | } | ||
19296 | }, | ||
19297 | }; | ||
19298 | |||
19299 | static struct snd_pci_quirk alc662_fixup_tbl[] = { | ||
19300 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | ||
19301 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | ||
19302 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | ||
19303 | {} | ||
19304 | }; | ||
19305 | |||
19306 | |||
19307 | |||
18938 | static int patch_alc662(struct hda_codec *codec) | 19308 | static int patch_alc662(struct hda_codec *codec) |
18939 | { | 19309 | { |
18940 | struct alc_spec *spec; | 19310 | struct alc_spec *spec; |
18941 | int err, board_config; | 19311 | int err, board_config; |
19312 | int coef; | ||
18942 | 19313 | ||
18943 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 19314 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
18944 | if (!spec) | 19315 | if (!spec) |
@@ -18950,12 +19321,15 @@ static int patch_alc662(struct hda_codec *codec) | |||
18950 | 19321 | ||
18951 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 19322 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
18952 | 19323 | ||
18953 | if (alc_read_coef_idx(codec, 0) == 0x8020) | 19324 | coef = alc_read_coef_idx(codec, 0); |
19325 | if (coef == 0x8020 || coef == 0x8011) | ||
18954 | alc_codec_rename(codec, "ALC661"); | 19326 | alc_codec_rename(codec, "ALC661"); |
18955 | else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && | 19327 | else if (coef & (1 << 14) && |
18956 | codec->bus->pci->subsystem_vendor == 0x1025 && | 19328 | codec->bus->pci->subsystem_vendor == 0x1025 && |
18957 | spec->cdefine.platform_type == 1) | 19329 | spec->cdefine.platform_type == 1) |
18958 | alc_codec_rename(codec, "ALC272X"); | 19330 | alc_codec_rename(codec, "ALC272X"); |
19331 | else if (coef == 0x4011) | ||
19332 | alc_codec_rename(codec, "ALC656"); | ||
18959 | 19333 | ||
18960 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | 19334 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, |
18961 | alc662_models, | 19335 | alc662_models, |
@@ -18967,6 +19341,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
18967 | } | 19341 | } |
18968 | 19342 | ||
18969 | if (board_config == ALC662_AUTO) { | 19343 | if (board_config == ALC662_AUTO) { |
19344 | alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1); | ||
18970 | /* automatic parse from the BIOS config */ | 19345 | /* automatic parse from the BIOS config */ |
18971 | err = alc662_parse_auto_config(codec); | 19346 | err = alc662_parse_auto_config(codec); |
18972 | if (err < 0) { | 19347 | if (err < 0) { |
@@ -19025,8 +19400,13 @@ static int patch_alc662(struct hda_codec *codec) | |||
19025 | spec->vmaster_nid = 0x02; | 19400 | spec->vmaster_nid = 0x02; |
19026 | 19401 | ||
19027 | codec->patch_ops = alc_patch_ops; | 19402 | codec->patch_ops = alc_patch_ops; |
19028 | if (board_config == ALC662_AUTO) | 19403 | if (board_config == ALC662_AUTO) { |
19029 | spec->init_hook = alc662_auto_init; | 19404 | spec->init_hook = alc662_auto_init; |
19405 | alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0); | ||
19406 | } | ||
19407 | |||
19408 | alc_init_jacks(codec); | ||
19409 | |||
19030 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 19410 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
19031 | if (!spec->loopback.amplist) | 19411 | if (!spec->loopback.amplist) |
19032 | spec->loopback.amplist = alc662_loopbacks; | 19412 | spec->loopback.amplist = alc662_loopbacks; |
@@ -19070,6 +19450,39 @@ static hda_nid_t alc680_adc_nids[3] = { | |||
19070 | /* | 19450 | /* |
19071 | * Analog capture ADC cgange | 19451 | * Analog capture ADC cgange |
19072 | */ | 19452 | */ |
19453 | static void alc680_rec_autoswitch(struct hda_codec *codec) | ||
19454 | { | ||
19455 | struct alc_spec *spec = codec->spec; | ||
19456 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19457 | int pin_found = 0; | ||
19458 | int type_found = AUTO_PIN_LAST; | ||
19459 | hda_nid_t nid; | ||
19460 | int i; | ||
19461 | |||
19462 | for (i = 0; i < cfg->num_inputs; i++) { | ||
19463 | nid = cfg->inputs[i].pin; | ||
19464 | if (!(snd_hda_query_pin_caps(codec, nid) & | ||
19465 | AC_PINCAP_PRES_DETECT)) | ||
19466 | continue; | ||
19467 | if (snd_hda_jack_detect(codec, nid)) { | ||
19468 | if (cfg->inputs[i].type < type_found) { | ||
19469 | type_found = cfg->inputs[i].type; | ||
19470 | pin_found = nid; | ||
19471 | } | ||
19472 | } | ||
19473 | } | ||
19474 | |||
19475 | nid = 0x07; | ||
19476 | if (pin_found) | ||
19477 | snd_hda_get_connections(codec, pin_found, &nid, 1); | ||
19478 | |||
19479 | if (nid != spec->cur_adc) | ||
19480 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
19481 | spec->cur_adc = nid; | ||
19482 | snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, | ||
19483 | spec->cur_adc_format); | ||
19484 | } | ||
19485 | |||
19073 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | 19486 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
19074 | struct hda_codec *codec, | 19487 | struct hda_codec *codec, |
19075 | unsigned int stream_tag, | 19488 | unsigned int stream_tag, |
@@ -19077,24 +19490,12 @@ static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
19077 | struct snd_pcm_substream *substream) | 19490 | struct snd_pcm_substream *substream) |
19078 | { | 19491 | { |
19079 | struct alc_spec *spec = codec->spec; | 19492 | struct alc_spec *spec = codec->spec; |
19080 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19081 | unsigned int pre_mic, pre_line; | ||
19082 | |||
19083 | pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19084 | pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]); | ||
19085 | 19493 | ||
19494 | spec->cur_adc = 0x07; | ||
19086 | spec->cur_adc_stream_tag = stream_tag; | 19495 | spec->cur_adc_stream_tag = stream_tag; |
19087 | spec->cur_adc_format = format; | 19496 | spec->cur_adc_format = format; |
19088 | 19497 | ||
19089 | if (pre_mic || pre_line) { | 19498 | alc680_rec_autoswitch(codec); |
19090 | if (pre_mic) | ||
19091 | snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0, | ||
19092 | format); | ||
19093 | else | ||
19094 | snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0, | ||
19095 | format); | ||
19096 | } else | ||
19097 | snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format); | ||
19098 | return 0; | 19499 | return 0; |
19099 | } | 19500 | } |
19100 | 19501 | ||
@@ -19180,6 +19581,7 @@ static struct hda_verb alc680_init_verbs[] = { | |||
19180 | 19581 | ||
19181 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 19582 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
19182 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | 19583 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, |
19584 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | ||
19183 | 19585 | ||
19184 | { } | 19586 | { } |
19185 | }; | 19587 | }; |
@@ -19192,25 +19594,11 @@ static void alc680_base_setup(struct hda_codec *codec) | |||
19192 | spec->autocfg.hp_pins[0] = 0x16; | 19594 | spec->autocfg.hp_pins[0] = 0x16; |
19193 | spec->autocfg.speaker_pins[0] = 0x14; | 19595 | spec->autocfg.speaker_pins[0] = 0x14; |
19194 | spec->autocfg.speaker_pins[1] = 0x15; | 19596 | spec->autocfg.speaker_pins[1] = 0x15; |
19195 | spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18; | 19597 | spec->autocfg.num_inputs = 2; |
19196 | spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19; | 19598 | spec->autocfg.inputs[0].pin = 0x18; |
19197 | } | 19599 | spec->autocfg.inputs[0].type = AUTO_PIN_MIC; |
19198 | 19600 | spec->autocfg.inputs[1].pin = 0x19; | |
19199 | static void alc680_rec_autoswitch(struct hda_codec *codec) | 19601 | spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; |
19200 | { | ||
19201 | struct alc_spec *spec = codec->spec; | ||
19202 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19203 | unsigned int present; | ||
19204 | hda_nid_t new_adc; | ||
19205 | |||
19206 | present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19207 | |||
19208 | new_adc = present ? 0x8 : 0x7; | ||
19209 | __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1); | ||
19210 | snd_hda_codec_setup_stream(codec, new_adc, | ||
19211 | spec->cur_adc_stream_tag, 0, | ||
19212 | spec->cur_adc_format); | ||
19213 | |||
19214 | } | 19602 | } |
19215 | 19603 | ||
19216 | static void alc680_unsol_event(struct hda_codec *codec, | 19604 | static void alc680_unsol_event(struct hda_codec *codec, |