aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c238
1 files changed, 184 insertions, 54 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 886d8e46bb37..53538b0f9991 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -276,6 +276,18 @@ struct alc_mic_route {
276 276
277#define MUX_IDX_UNDEF ((unsigned char)-1) 277#define MUX_IDX_UNDEF ((unsigned char)-1)
278 278
279struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
289};
290
279struct alc_spec { 291struct alc_spec {
280 /* codec parameterization */ 292 /* codec parameterization */
281 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 293 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -333,6 +345,7 @@ struct alc_spec {
333 345
334 /* dynamic controls, init_verbs and input_mux */ 346 /* dynamic controls, init_verbs and input_mux */
335 struct auto_pin_cfg autocfg; 347 struct auto_pin_cfg autocfg;
348 struct alc_customize_define cdefine;
336 struct snd_array kctls; 349 struct snd_array kctls;
337 struct hda_input_mux private_imux[3]; 350 struct hda_input_mux private_imux[3];
338 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 351 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
@@ -1248,6 +1261,62 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1248 spec->unsol_event = alc_sku_unsol_event; 1261 spec->unsol_event = alc_sku_unsol_event;
1249} 1262}
1250 1263
1264static int alc_auto_parse_customize_define(struct hda_codec *codec)
1265{
1266 unsigned int ass, tmp, i;
1267 unsigned nid = 0;
1268 struct alc_spec *spec = codec->spec;
1269
1270 ass = codec->subsystem_id & 0xffff;
1271 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1272 goto do_sku;
1273
1274 nid = 0x1d;
1275 if (codec->vendor_id == 0x10ec0260)
1276 nid = 0x17;
1277 ass = snd_hda_codec_get_pincfg(codec, nid);
1278
1279 if (!(ass & 1)) {
1280 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1281 codec->chip_name, ass);
1282 return -1;
1283 }
1284
1285 /* check sum */
1286 tmp = 0;
1287 for (i = 1; i < 16; i++) {
1288 if ((ass >> i) & 1)
1289 tmp++;
1290 }
1291 if (((ass >> 16) & 0xf) != tmp)
1292 return -1;
1293
1294 spec->cdefine.port_connectivity = ass >> 30;
1295 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1296 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1297 spec->cdefine.customization = ass >> 8;
1298do_sku:
1299 spec->cdefine.sku_cfg = ass;
1300 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1301 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1302 spec->cdefine.swap = (ass & 0x2) >> 1;
1303 spec->cdefine.override = ass & 0x1;
1304
1305 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1306 nid, spec->cdefine.sku_cfg);
1307 snd_printd("SKU: port_connectivity=0x%x\n",
1308 spec->cdefine.port_connectivity);
1309 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1310 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1311 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1312 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1313 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1314 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1315 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1316
1317 return 0;
1318}
1319
1251/* check subsystem ID and set up device-specific initialization; 1320/* check subsystem ID and set up device-specific initialization;
1252 * return 1 if initialized, 0 if invalid SSID 1321 * return 1 if initialized, 0 if invalid SSID
1253 */ 1322 */
@@ -3415,6 +3484,10 @@ static int alc_init(struct hda_codec *codec)
3415 if (spec->init_hook) 3484 if (spec->init_hook)
3416 spec->init_hook(codec); 3485 spec->init_hook(codec);
3417 3486
3487#ifdef CONFIG_SND_HDA_POWER_SAVE
3488 if (codec->patch_ops.check_power_status)
3489 codec->patch_ops.check_power_status(codec, 0x01);
3490#endif
3418 return 0; 3491 return 0;
3419} 3492}
3420 3493
@@ -3775,6 +3848,10 @@ static int alc_resume(struct hda_codec *codec)
3775 codec->patch_ops.init(codec); 3848 codec->patch_ops.init(codec);
3776 snd_hda_codec_resume_amp(codec); 3849 snd_hda_codec_resume_amp(codec);
3777 snd_hda_codec_resume_cache(codec); 3850 snd_hda_codec_resume_cache(codec);
3851#ifdef CONFIG_SND_HDA_POWER_SAVE
3852 if (codec->patch_ops.check_power_status)
3853 codec->patch_ops.check_power_status(codec, 0x01);
3854#endif
3778 return 0; 3855 return 0;
3779} 3856}
3780#endif 3857#endif
@@ -3797,6 +3874,17 @@ static struct hda_codec_ops alc_patch_ops = {
3797 .reboot_notify = alc_shutup, 3874 .reboot_notify = alc_shutup,
3798}; 3875};
3799 3876
3877/* replace the codec chip_name with the given string */
3878static int alc_codec_rename(struct hda_codec *codec, const char *name)
3879{
3880 kfree(codec->chip_name);
3881 codec->chip_name = kstrdup(name, GFP_KERNEL);
3882 if (!codec->chip_name) {
3883 alc_free(codec);
3884 return -ENOMEM;
3885 }
3886 return 0;
3887}
3800 3888
3801/* 3889/*
3802 * Test configuration for debugging 3890 * Test configuration for debugging
@@ -10189,21 +10277,20 @@ static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10189 10277
10190static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10278static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10191 hda_nid_t nid, int pin_type, 10279 hda_nid_t nid, int pin_type,
10192 int dac_idx) 10280 hda_nid_t dac)
10193{ 10281{
10194 /* set as output */
10195 struct alc_spec *spec = codec->spec;
10196 int idx; 10282 int idx;
10197 10283
10284 /* set as output */
10198 alc_set_pin_output(codec, nid, pin_type); 10285 alc_set_pin_output(codec, nid, pin_type);
10199 if (dac_idx >= spec->multiout.num_dacs) 10286
10200 return; 10287 if (dac == 0x25)
10201 if (spec->multiout.dac_nids[dac_idx] == 0x25)
10202 idx = 4; 10288 idx = 4;
10289 else if (dac >= 0x02 && dac <= 0x05)
10290 idx = dac - 2;
10203 else 10291 else
10204 idx = spec->multiout.dac_nids[dac_idx] - 2; 10292 return;
10205 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10293 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10206
10207} 10294}
10208 10295
10209static void alc882_auto_init_multi_out(struct hda_codec *codec) 10296static void alc882_auto_init_multi_out(struct hda_codec *codec)
@@ -10216,22 +10303,29 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
10216 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10217 if (nid) 10304 if (nid)
10218 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10305 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10219 i); 10306 spec->multiout.dac_nids[i]);
10220 } 10307 }
10221} 10308}
10222 10309
10223static void alc882_auto_init_hp_out(struct hda_codec *codec) 10310static void alc882_auto_init_hp_out(struct hda_codec *codec)
10224{ 10311{
10225 struct alc_spec *spec = codec->spec; 10312 struct alc_spec *spec = codec->spec;
10226 hda_nid_t pin; 10313 hda_nid_t pin, dac;
10227 10314
10228 pin = spec->autocfg.hp_pins[0]; 10315 pin = spec->autocfg.hp_pins[0];
10229 if (pin) /* connect to front */ 10316 if (pin) {
10230 /* use dac 0 */ 10317 dac = spec->multiout.hp_nid;
10231 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 10318 if (!dac)
10319 dac = spec->multiout.dac_nids[0]; /* to front */
10320 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10321 }
10232 pin = spec->autocfg.speaker_pins[0]; 10322 pin = spec->autocfg.speaker_pins[0];
10233 if (pin) 10323 if (pin) {
10234 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 10324 dac = spec->multiout.extra_out_nid[0];
10325 if (!dac)
10326 dac = spec->multiout.dac_nids[0]; /* to front */
10327 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10328 }
10235} 10329}
10236 10330
10237static void alc882_auto_init_analog_input(struct hda_codec *codec) 10331static void alc882_auto_init_analog_input(struct hda_codec *codec)
@@ -10347,15 +10441,15 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10347 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10441 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10348 if (err < 0) 10442 if (err < 0)
10349 return err; 10443 return err;
10444 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10445 "Headphone");
10446 if (err < 0)
10447 return err;
10350 err = alc880_auto_create_extra_out(spec, 10448 err = alc880_auto_create_extra_out(spec,
10351 spec->autocfg.speaker_pins[0], 10449 spec->autocfg.speaker_pins[0],
10352 "Speaker"); 10450 "Speaker");
10353 if (err < 0) 10451 if (err < 0)
10354 return err; 10452 return err;
10355 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10356 "Headphone");
10357 if (err < 0)
10358 return err;
10359 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10453 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10360 if (err < 0) 10454 if (err < 0)
10361 return err; 10455 return err;
@@ -10425,6 +10519,8 @@ static int patch_alc882(struct hda_codec *codec)
10425 10519
10426 codec->spec = spec; 10520 codec->spec = spec;
10427 10521
10522 alc_auto_parse_customize_define(codec);
10523
10428 switch (codec->vendor_id) { 10524 switch (codec->vendor_id) {
10429 case 0x10ec0882: 10525 case 0x10ec0882:
10430 case 0x10ec0885: 10526 case 0x10ec0885:
@@ -10484,9 +10580,6 @@ static int patch_alc882(struct hda_codec *codec)
10484 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10580 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10485 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10581 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10486 10582
10487 if (codec->vendor_id == 0x10ec0888)
10488 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
10489
10490 if (!spec->adc_nids && spec->input_mux) { 10583 if (!spec->adc_nids && spec->input_mux) {
10491 int i, j; 10584 int i, j;
10492 spec->num_adc_nids = 0; 10585 spec->num_adc_nids = 0;
@@ -10521,7 +10614,9 @@ static int patch_alc882(struct hda_codec *codec)
10521 } 10614 }
10522 10615
10523 set_capture_mixer(codec); 10616 set_capture_mixer(codec);
10524 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10617
10618 if (spec->cdefine.enable_pcbeep)
10619 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10525 10620
10526 if (board_config == ALC882_AUTO) 10621 if (board_config == ALC882_AUTO)
10527 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10622 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
@@ -12308,6 +12403,7 @@ static int patch_alc262(struct hda_codec *codec)
12308 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12403 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12309 } 12404 }
12310#endif 12405#endif
12406 alc_auto_parse_customize_define(codec);
12311 12407
12312 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12408 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12313 12409
@@ -12386,7 +12482,7 @@ static int patch_alc262(struct hda_codec *codec)
12386 } 12482 }
12387 if (!spec->cap_mixer && !spec->no_analog) 12483 if (!spec->cap_mixer && !spec->no_analog)
12388 set_capture_mixer(codec); 12484 set_capture_mixer(codec);
12389 if (!spec->no_analog) 12485 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
12390 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12486 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12391 12487
12392 spec->vmaster_nid = 0x0c; 12488 spec->vmaster_nid = 0x0c;
@@ -14005,6 +14101,35 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14005 /* NID is set in alc_build_pcms */ 14101 /* NID is set in alc_build_pcms */
14006}; 14102};
14007 14103
14104#ifdef CONFIG_SND_HDA_POWER_SAVE
14105static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14106{
14107 switch (codec->subsystem_id) {
14108 case 0x103c1586:
14109 return 1;
14110 }
14111 return 0;
14112}
14113
14114static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14115{
14116 /* update mute-LED according to the speaker mute state */
14117 if (nid == 0x01 || nid == 0x14) {
14118 int pinval;
14119 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14120 HDA_AMP_MUTE)
14121 pinval = 0x24;
14122 else
14123 pinval = 0x20;
14124 /* mic2 vref pin is used for mute LED control */
14125 snd_hda_codec_update_cache(codec, 0x19, 0,
14126 AC_VERB_SET_PIN_WIDGET_CONTROL,
14127 pinval);
14128 }
14129 return alc_check_power_status(codec, nid);
14130}
14131#endif /* CONFIG_SND_HDA_POWER_SAVE */
14132
14008/* 14133/*
14009 * BIOS auto configuration 14134 * BIOS auto configuration
14010 */ 14135 */
@@ -14082,7 +14207,7 @@ enum {
14082 ALC269_FIXUP_SONY_VAIO, 14207 ALC269_FIXUP_SONY_VAIO,
14083}; 14208};
14084 14209
14085const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14210static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14211 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14087 {} 14212 {}
14088}; 14213};
@@ -14290,17 +14415,17 @@ static int patch_alc269(struct hda_codec *codec)
14290 14415
14291 codec->spec = spec; 14416 codec->spec = spec;
14292 14417
14293 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14418 alc_auto_parse_customize_define(codec);
14294 14419
14295 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14420 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14296 kfree(codec->chip_name); 14421 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14297 codec->chip_name = kstrdup("ALC259", GFP_KERNEL); 14422 spec->cdefine.platform_type == 1)
14298 if (!codec->chip_name) { 14423 alc_codec_rename(codec, "ALC271X");
14299 alc_free(codec); 14424 else
14300 return -ENOMEM; 14425 alc_codec_rename(codec, "ALC259");
14301 }
14302 is_alc269vb = 1; 14426 is_alc269vb = 1;
14303 } 14427 } else
14428 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14304 14429
14305 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14430 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14306 alc269_models, 14431 alc269_models,
@@ -14365,7 +14490,8 @@ static int patch_alc269(struct hda_codec *codec)
14365 14490
14366 if (!spec->cap_mixer) 14491 if (!spec->cap_mixer)
14367 set_capture_mixer(codec); 14492 set_capture_mixer(codec);
14368 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14493 if (spec->cdefine.enable_pcbeep)
14494 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14369 14495
14370 if (board_config == ALC269_AUTO) 14496 if (board_config == ALC269_AUTO)
14371 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 14497 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
@@ -14378,6 +14504,8 @@ static int patch_alc269(struct hda_codec *codec)
14378#ifdef CONFIG_SND_HDA_POWER_SAVE 14504#ifdef CONFIG_SND_HDA_POWER_SAVE
14379 if (!spec->loopback.amplist) 14505 if (!spec->loopback.amplist)
14380 spec->loopback.amplist = alc269_loopbacks; 14506 spec->loopback.amplist = alc269_loopbacks;
14507 if (alc269_mic2_for_mute_led(codec))
14508 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14381#endif 14509#endif
14382 14510
14383 return 0; 14511 return 0;
@@ -18525,16 +18653,16 @@ static int patch_alc662(struct hda_codec *codec)
18525 18653
18526 codec->spec = spec; 18654 codec->spec = spec;
18527 18655
18656 alc_auto_parse_customize_define(codec);
18657
18528 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18658 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18529 18659
18530 if (alc_read_coef_idx(codec, 0)==0x8020){ 18660 if (alc_read_coef_idx(codec, 0) == 0x8020)
18531 kfree(codec->chip_name); 18661 alc_codec_rename(codec, "ALC661");
18532 codec->chip_name = kstrdup("ALC661", GFP_KERNEL); 18662 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18533 if (!codec->chip_name) { 18663 codec->bus->pci->subsystem_vendor == 0x1025 &&
18534 alc_free(codec); 18664 spec->cdefine.platform_type == 1)
18535 return -ENOMEM; 18665 alc_codec_rename(codec, "ALC272X");
18536 }
18537 }
18538 18666
18539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18667 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18540 alc662_models, 18668 alc662_models,
@@ -18584,18 +18712,20 @@ static int patch_alc662(struct hda_codec *codec)
18584 if (!spec->cap_mixer) 18712 if (!spec->cap_mixer)
18585 set_capture_mixer(codec); 18713 set_capture_mixer(codec);
18586 18714
18587 switch (codec->vendor_id) { 18715 if (spec->cdefine.enable_pcbeep) {
18588 case 0x10ec0662: 18716 switch (codec->vendor_id) {
18589 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18717 case 0x10ec0662:
18590 break; 18718 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18591 case 0x10ec0272: 18719 break;
18592 case 0x10ec0663: 18720 case 0x10ec0272:
18593 case 0x10ec0665: 18721 case 0x10ec0663:
18594 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18722 case 0x10ec0665:
18595 break; 18723 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18596 case 0x10ec0273: 18724 break;
18597 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18725 case 0x10ec0273:
18598 break; 18726 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18727 break;
18728 }
18599 } 18729 }
18600 spec->vmaster_nid = 0x02; 18730 spec->vmaster_nid = 0x02;
18601 18731