aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c3
-rw-r--r--sound/pci/hda/patch_realtek.c150
2 files changed, 121 insertions, 32 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0e76ac2b2ac..d72bcff8d27 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4218,7 +4218,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
break;
case AC_JACK_MIC_IN: {
int preferred, alt;
- if (loc == AC_JACK_LOC_FRONT) {
+ if (loc == AC_JACK_LOC_FRONT ||
+ (loc & 0x30) == AC_JACK_LOC_INTERNAL) {
preferred = AUTO_PIN_FRONT_MIC;
alt = AUTO_PIN_MIC;
} else {
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9a23444e9e7..22b7c944f56 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -275,6 +275,18 @@ struct alc_mic_route {
#define MUX_IDX_UNDEF ((unsigned char)-1)
+struct alc_customize_define {
+ unsigned int sku_cfg;
+ unsigned char port_connectivity;
+ unsigned char check_sum;
+ unsigned char customization;
+ unsigned char external_amp;
+ unsigned int enable_pcbeep:1;
+ unsigned int platform_type:1;
+ unsigned int swap:1;
+ unsigned int override:1;
+};
+
struct alc_spec {
/* codec parameterization */
struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -332,6 +344,7 @@ struct alc_spec {
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
+ struct alc_customize_define cdefine;
struct snd_array kctls;
struct hda_input_mux private_imux[3];
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
@@ -1247,6 +1260,62 @@ static void alc_init_auto_mic(struct hda_codec *codec)
spec->unsol_event = alc_sku_unsol_event;
}
+static int alc_auto_parse_customize_define(struct hda_codec *codec)
+{
+ unsigned int ass, tmp, i;
+ unsigned nid = 0;
+ struct alc_spec *spec = codec->spec;
+
+ ass = codec->subsystem_id & 0xffff;
+ if (ass != codec->bus->pci->subsystem_device && (ass & 1))
+ goto do_sku;
+
+ nid = 0x1d;
+ if (codec->vendor_id == 0x10ec0260)
+ nid = 0x17;
+ ass = snd_hda_codec_get_pincfg(codec, nid);
+
+ if (!(ass & 1)) {
+ printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
+ codec->chip_name, ass);
+ return -1;
+ }
+
+ /* check sum */
+ tmp = 0;
+ for (i = 1; i < 16; i++) {
+ if ((ass >> i) & 1)
+ tmp++;
+ }
+ if (((ass >> 16) & 0xf) != tmp)
+ return -1;
+
+ spec->cdefine.port_connectivity = ass >> 30;
+ spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
+ spec->cdefine.check_sum = (ass >> 16) & 0xf;
+ spec->cdefine.customization = ass >> 8;
+do_sku:
+ spec->cdefine.sku_cfg = ass;
+ spec->cdefine.external_amp = (ass & 0x38) >> 3;
+ spec->cdefine.platform_type = (ass & 0x4) >> 2;
+ spec->cdefine.swap = (ass & 0x2) >> 1;
+ spec->cdefine.override = ass & 0x1;
+
+ snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
+ nid, spec->cdefine.sku_cfg);
+ snd_printd("SKU: port_connectivity=0x%x\n",
+ spec->cdefine.port_connectivity);
+ snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
+ snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
+ snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
+ snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
+ snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
+ snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
+ snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
+
+ return 0;
+}
+
/* check subsystem ID and set up device-specific initialization;
* return 1 if initialized, 0 if invalid SSID
*/
@@ -3780,6 +3849,17 @@ static struct hda_codec_ops alc_patch_ops = {
.reboot_notify = alc_shutup,
};
+/* replace the codec chip_name with the given string */
+static int alc_codec_rename(struct hda_codec *codec, const char *name)
+{
+ kfree(codec->chip_name);
+ codec->chip_name = kstrdup(name, GFP_KERNEL);
+ if (!codec->chip_name) {
+ alc_free(codec);
+ return -ENOMEM;
+ }
+ return 0;
+}
/*
* Test configuration for debugging
@@ -10271,6 +10351,8 @@ static int patch_alc882(struct hda_codec *codec)
codec->spec = spec;
+ alc_auto_parse_customize_define(codec);
+
switch (codec->vendor_id) {
case 0x10ec0882:
case 0x10ec0885:
@@ -10366,7 +10448,9 @@ static int patch_alc882(struct hda_codec *codec)
}
set_capture_mixer(codec);
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
+
+ if (spec->cdefine.enable_pcbeep)
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -12150,6 +12234,7 @@ static int patch_alc262(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
}
#endif
+ alc_auto_parse_customize_define(codec);
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
@@ -12228,7 +12313,7 @@ static int patch_alc262(struct hda_codec *codec)
}
if (!spec->cap_mixer && !spec->no_analog)
set_capture_mixer(codec);
- if (!spec->no_analog)
+ if (!spec->no_analog && spec->cdefine.enable_pcbeep)
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -14098,17 +14183,17 @@ static int patch_alc269(struct hda_codec *codec)
codec->spec = spec;
- alc_fix_pll_init(codec, 0x20, 0x04, 15);
+ alc_auto_parse_customize_define(codec);
if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
- kfree(codec->chip_name);
- codec->chip_name = kstrdup("ALC259", GFP_KERNEL);
- if (!codec->chip_name) {
- alc_free(codec);
- return -ENOMEM;
- }
+ if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+ spec->cdefine.platform_type == 1)
+ alc_codec_rename(codec, "ALC271X");
+ else
+ alc_codec_rename(codec, "ALC259");
is_alc269vb = 1;
- }
+ } else
+ alc_fix_pll_init(codec, 0x20, 0x04, 15);
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models,
@@ -14168,7 +14253,8 @@ static int patch_alc269(struct hda_codec *codec)
if (!spec->cap_mixer)
set_capture_mixer(codec);
- set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
+ if (spec->cdefine.enable_pcbeep)
+ set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
spec->vmaster_nid = 0x02;
@@ -18318,16 +18404,16 @@ static int patch_alc662(struct hda_codec *codec)
codec->spec = spec;
+ alc_auto_parse_customize_define(codec);
+
alc_fix_pll_init(codec, 0x20, 0x04, 15);
- if (alc_read_coef_idx(codec, 0)==0x8020){
- kfree(codec->chip_name);
- codec->chip_name = kstrdup("ALC661", GFP_KERNEL);
- if (!codec->chip_name) {
- alc_free(codec);
- return -ENOMEM;
- }
- }
+ if (alc_read_coef_idx(codec, 0) == 0x8020)
+ alc_codec_rename(codec, "ALC661");
+ else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
+ codec->bus->pci->subsystem_vendor == 0x1025 &&
+ spec->cdefine.platform_type == 1)
+ alc_codec_rename(codec, "ALC272X");
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
alc662_models,
@@ -18377,18 +18463,20 @@ static int patch_alc662(struct hda_codec *codec)
if (!spec->cap_mixer)
set_capture_mixer(codec);
- switch (codec->vendor_id) {
- case 0x10ec0662:
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- break;
- case 0x10ec0272:
- case 0x10ec0663:
- case 0x10ec0665:
- set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
- break;
- case 0x10ec0273:
- set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
- break;
+ if (spec->cdefine.enable_pcbeep) {
+ switch (codec->vendor_id) {
+ case 0x10ec0662:
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
+ break;
+ case 0x10ec0272:
+ case 0x10ec0663:
+ case 0x10ec0665:
+ set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
+ break;
+ case 0x10ec0273:
+ set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
+ break;
+ }
}
spec->vmaster_nid = 0x02;