aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorKailang Yang <kailang@realtek.com>2010-03-19 06:23:45 -0400
committerTakashi Iwai <tiwai@suse.de>2010-03-19 06:38:53 -0400
commitda00c24493bf6ae3772dfe7343dca033ebc75955 (patch)
tree05019a7555bd1406fef9c95df1ac98a5acc191a9 /sound/pci/hda
parent6ff86a3f33e84c430aeb8ff3b7f68b1c052ec1e9 (diff)
ALSA: hda - Add parse customize define function for Realtek codecs
Added alc_auto_parse_customize_define() to parse the Realtek-specific attributes from SKU. Also enable beep controls only when the proper attribute bit is set. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_realtek.c112
1 files changed, 96 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4ec57633af88..245e1afa5896 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -275,6 +275,18 @@ struct alc_mic_route {
275 275
276#define MUX_IDX_UNDEF ((unsigned char)-1) 276#define MUX_IDX_UNDEF ((unsigned char)-1)
277 277
278struct alc_customize_define {
279 unsigned int sku_cfg;
280 unsigned char port_connectivity;
281 unsigned char check_sum;
282 unsigned char customization;
283 unsigned char external_amp;
284 unsigned int enable_pcbeep:1;
285 unsigned int platform_type:1;
286 unsigned int swap:1;
287 unsigned int override:1;
288};
289
278struct alc_spec { 290struct alc_spec {
279 /* codec parameterization */ 291 /* codec parameterization */
280 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 292 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -332,6 +344,7 @@ struct alc_spec {
332 344
333 /* dynamic controls, init_verbs and input_mux */ 345 /* dynamic controls, init_verbs and input_mux */
334 struct auto_pin_cfg autocfg; 346 struct auto_pin_cfg autocfg;
347 struct alc_customize_define cdefine;
335 struct snd_array kctls; 348 struct snd_array kctls;
336 struct hda_input_mux private_imux[3]; 349 struct hda_input_mux private_imux[3];
337 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 350 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
@@ -1247,6 +1260,62 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1247 spec->unsol_event = alc_sku_unsol_event; 1260 spec->unsol_event = alc_sku_unsol_event;
1248} 1261}
1249 1262
1263static int alc_auto_parse_customize_define(struct hda_codec *codec)
1264{
1265 unsigned int ass, tmp, i;
1266 unsigned nid;
1267 struct alc_spec *spec = codec->spec;
1268
1269 ass = codec->subsystem_id & 0xffff;
1270 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1271 goto do_sku;
1272
1273 nid = 0x1d;
1274 if (codec->vendor_id == 0x10ec0260)
1275 nid = 0x17;
1276 ass = snd_hda_codec_get_pincfg(codec, nid);
1277
1278 if (!(ass & 1)) {
1279 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1280 codec->chip_name, ass);
1281 return -1;
1282 }
1283
1284 /* check sum */
1285 tmp = 0;
1286 for (i = 1; i < 16; i++) {
1287 if ((ass >> i) & 1)
1288 tmp++;
1289 }
1290 if (((ass >> 16) & 0xf) != tmp)
1291 return -1;
1292
1293 spec->cdefine.port_connectivity = ass >> 30;
1294 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1295 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1296 spec->cdefine.customization = ass >> 8;
1297do_sku:
1298 spec->cdefine.sku_cfg = ass;
1299 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1300 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1301 spec->cdefine.swap = (ass & 0x2) >> 1;
1302 spec->cdefine.override = ass & 0x1;
1303
1304 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1305 nid, spec->cdefine.sku_cfg);
1306 snd_printd("SKU: port_connectivity=0x%x\n",
1307 spec->cdefine.port_connectivity);
1308 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1309 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1310 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1311 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1312 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1313 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1314 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1315
1316 return 0;
1317}
1318
1250/* check subsystem ID and set up device-specific initialization; 1319/* check subsystem ID and set up device-specific initialization;
1251 * return 1 if initialized, 0 if invalid SSID 1320 * return 1 if initialized, 0 if invalid SSID
1252 */ 1321 */
@@ -3779,7 +3848,6 @@ static struct hda_codec_ops alc_patch_ops = {
3779 .reboot_notify = alc_shutup, 3848 .reboot_notify = alc_shutup,
3780}; 3849};
3781 3850
3782
3783/* 3851/*
3784 * Test configuration for debugging 3852 * Test configuration for debugging
3785 * 3853 *
@@ -10267,6 +10335,8 @@ static int patch_alc882(struct hda_codec *codec)
10267 10335
10268 codec->spec = spec; 10336 codec->spec = spec;
10269 10337
10338 alc_auto_parse_customize_define(codec);
10339
10270 switch (codec->vendor_id) { 10340 switch (codec->vendor_id) {
10271 case 0x10ec0882: 10341 case 0x10ec0882:
10272 case 0x10ec0885: 10342 case 0x10ec0885:
@@ -10362,7 +10432,9 @@ static int patch_alc882(struct hda_codec *codec)
10362 } 10432 }
10363 10433
10364 set_capture_mixer(codec); 10434 set_capture_mixer(codec);
10365 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10435
10436 if (spec->cdefine.enable_pcbeep)
10437 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10366 10438
10367 spec->vmaster_nid = 0x0c; 10439 spec->vmaster_nid = 0x0c;
10368 10440
@@ -12146,6 +12218,7 @@ static int patch_alc262(struct hda_codec *codec)
12146 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12218 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12147 } 12219 }
12148#endif 12220#endif
12221 alc_auto_parse_customize_define(codec);
12149 12222
12150 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12223 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12151 12224
@@ -12224,7 +12297,7 @@ static int patch_alc262(struct hda_codec *codec)
12224 } 12297 }
12225 if (!spec->cap_mixer && !spec->no_analog) 12298 if (!spec->cap_mixer && !spec->no_analog)
12226 set_capture_mixer(codec); 12299 set_capture_mixer(codec);
12227 if (!spec->no_analog) 12300 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
12228 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12301 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12229 12302
12230 spec->vmaster_nid = 0x0c; 12303 spec->vmaster_nid = 0x0c;
@@ -14094,6 +14167,8 @@ static int patch_alc269(struct hda_codec *codec)
14094 14167
14095 codec->spec = spec; 14168 codec->spec = spec;
14096 14169
14170 alc_auto_parse_customize_define(codec);
14171
14097 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14172 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14098 14173
14099 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14174 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
@@ -14164,7 +14239,8 @@ static int patch_alc269(struct hda_codec *codec)
14164 14239
14165 if (!spec->cap_mixer) 14240 if (!spec->cap_mixer)
14166 set_capture_mixer(codec); 14241 set_capture_mixer(codec);
14167 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14242 if (spec->cdefine.enable_pcbeep)
14243 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14168 14244
14169 spec->vmaster_nid = 0x02; 14245 spec->vmaster_nid = 0x02;
14170 14246
@@ -18314,6 +18390,8 @@ static int patch_alc662(struct hda_codec *codec)
18314 18390
18315 codec->spec = spec; 18391 codec->spec = spec;
18316 18392
18393 alc_auto_parse_customize_define(codec);
18394
18317 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18395 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18318 18396
18319 if (alc_read_coef_idx(codec, 0)==0x8020){ 18397 if (alc_read_coef_idx(codec, 0)==0x8020){
@@ -18373,18 +18451,20 @@ static int patch_alc662(struct hda_codec *codec)
18373 if (!spec->cap_mixer) 18451 if (!spec->cap_mixer)
18374 set_capture_mixer(codec); 18452 set_capture_mixer(codec);
18375 18453
18376 switch (codec->vendor_id) { 18454 if (spec->cdefine.enable_pcbeep) {
18377 case 0x10ec0662: 18455 switch (codec->vendor_id) {
18378 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18456 case 0x10ec0662:
18379 break; 18457 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18380 case 0x10ec0272: 18458 break;
18381 case 0x10ec0663: 18459 case 0x10ec0272:
18382 case 0x10ec0665: 18460 case 0x10ec0663:
18383 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18461 case 0x10ec0665:
18384 break; 18462 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18385 case 0x10ec0273: 18463 break;
18386 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18464 case 0x10ec0273:
18387 break; 18465 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18466 break;
18467 }
18388 } 18468 }
18389 spec->vmaster_nid = 0x02; 18469 spec->vmaster_nid = 0x02;
18390 18470