diff options
author | Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 2005-07-29 05:41:55 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-08-30 02:43:05 -0400 |
commit | 3998b70fd0ab40a276147a0f55816d383fcbeb54 (patch) | |
tree | f2730dcfca4393a29f24dc3c89724d7f8fc8ddde /sound/pci/ac97 | |
parent | 1fdab81e675c6ef76a49b8aabb7eaf4be51d1b80 (diff) |
[ALSA] WM97xx AC97 codec controls
AC97 Codec
o Enhanced current WM97xx support to provide additional controls and
use the kcontrol suffix naming convention.
o Added AC97_HAS_NO_MIC, AC97_HAS_NO_TONE and AC97_HAS_NO_STD_PCM.
o Cleaned up WM97xx related comments.
o Removed some wm9713 double mono controls and replaced with stereo
controls.
Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 44 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 429 |
2 files changed, 364 insertions, 109 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6983eea226da..cbf790270c30 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -1307,16 +1307,18 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | /* build master tone controls */ | 1309 | /* build master tone controls */ |
1310 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { | 1310 | if (!(ac97->flags & AC97_HAS_NO_TONE)) { |
1311 | for (idx = 0; idx < 2; idx++) { | 1311 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { |
1312 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) | 1312 | for (idx = 0; idx < 2; idx++) { |
1313 | return err; | 1313 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) |
1314 | if (ac97->id == AC97_ID_YMF753) { | 1314 | return err; |
1315 | kctl->private_value &= ~(0xff << 16); | 1315 | if (ac97->id == AC97_ID_YMF753) { |
1316 | kctl->private_value |= 7 << 16; | 1316 | kctl->private_value &= ~(0xff << 16); |
1317 | kctl->private_value |= 7 << 16; | ||
1318 | } | ||
1317 | } | 1319 | } |
1320 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1318 | } | 1321 | } |
1319 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1320 | } | 1322 | } |
1321 | 1323 | ||
1322 | /* build PC Speaker controls */ | 1324 | /* build PC Speaker controls */ |
@@ -1339,11 +1341,13 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1339 | } | 1341 | } |
1340 | 1342 | ||
1341 | /* build MIC controls */ | 1343 | /* build MIC controls */ |
1342 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { | 1344 | if (!(ac97->flags & AC97_HAS_NO_MIC)) { |
1343 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) | 1345 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { |
1344 | return err; | 1346 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) |
1345 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) | 1347 | return err; |
1346 | return err; | 1348 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) |
1349 | return err; | ||
1350 | } | ||
1347 | } | 1351 | } |
1348 | 1352 | ||
1349 | /* build Line controls */ | 1353 | /* build Line controls */ |
@@ -1402,12 +1406,14 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1402 | } | 1406 | } |
1403 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); | 1407 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); |
1404 | } else { | 1408 | } else { |
1405 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) | 1409 | if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { |
1406 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); | 1410 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) |
1407 | else | 1411 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); |
1408 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); | 1412 | else |
1409 | if (err < 0) | 1413 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); |
1410 | return err; | 1414 | if (err < 0) |
1415 | return err; | ||
1416 | } | ||
1411 | } | 1417 | } |
1412 | 1418 | ||
1413 | /* build Capture controls */ | 1419 | /* build Capture controls */ |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 66edc857d3e6..d4bb99fc896c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -370,141 +370,387 @@ int patch_yamaha_ymf753(ac97_t * ac97) | |||
370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. | 370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. |
371 | */ | 371 | */ |
372 | 372 | ||
373 | int patch_wolfson03(ac97_t * ac97) | 373 | static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = { |
374 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
375 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
376 | }; | ||
377 | |||
378 | int patch_wolfson_wm9703_specific(ac97_t * ac97) | ||
374 | { | 379 | { |
375 | /* This is known to work for the ViewSonic ViewPad 1000 | 380 | /* This is known to work for the ViewSonic ViewPad 1000 |
376 | Randolph Bentson <bentson@holmsjoen.com> */ | 381 | * Randolph Bentson <bentson@holmsjoen.com> |
382 | * WM9703/9707/9708/9717 | ||
383 | */ | ||
384 | int err, i; | ||
385 | |||
386 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
387 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
388 | return err; | ||
389 | } | ||
390 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
391 | return 0; | ||
392 | } | ||
377 | 393 | ||
378 | // WM9703/9707/9708/9717 | 394 | static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { |
379 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 395 | .build_specific = patch_wolfson_wm9703_specific, |
380 | snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000); | 396 | }; |
397 | |||
398 | int patch_wolfson03(ac97_t * ac97) | ||
399 | { | ||
400 | ac97->build_ops = &patch_wolfson_wm9703_ops; | ||
381 | return 0; | 401 | return 0; |
382 | } | 402 | } |
383 | 403 | ||
384 | int patch_wolfson04(ac97_t * ac97) | 404 | static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = { |
405 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
406 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
407 | AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1), | ||
408 | AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1), | ||
409 | AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1), | ||
410 | AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), | ||
411 | }; | ||
412 | |||
413 | int patch_wolfson_wm9704_specific(ac97_t * ac97) | ||
385 | { | 414 | { |
386 | // WM9704M/9704Q | 415 | int err, i; |
387 | // set front and rear mixer volume | 416 | for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) { |
388 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 417 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0) |
389 | snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808); | 418 | return err; |
390 | 419 | } | |
391 | // patch for DVD noise | 420 | /* patch for DVD noise */ |
392 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); | 421 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); |
393 | |||
394 | // init vol | ||
395 | snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808); | ||
396 | |||
397 | // set rear surround volume | ||
398 | snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); | ||
399 | return 0; | 422 | return 0; |
400 | } | 423 | } |
401 | 424 | ||
425 | static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { | ||
426 | .build_specific = patch_wolfson_wm9704_specific, | ||
427 | }; | ||
428 | |||
429 | int patch_wolfson04(ac97_t * ac97) | ||
430 | { | ||
431 | /* WM9704M/9704Q */ | ||
432 | ac97->build_ops = &patch_wolfson_wm9704_ops; | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | int patch_wolfson_wm9705_specific(ac97_t * ac97) | ||
437 | { | ||
438 | int err, i; | ||
439 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
440 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
441 | return err; | ||
442 | } | ||
443 | snd_ac97_write_cache(ac97, 0x72, 0x0808); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { | ||
448 | .build_specific = patch_wolfson_wm9705_specific, | ||
449 | }; | ||
450 | |||
402 | int patch_wolfson05(ac97_t * ac97) | 451 | int patch_wolfson05(ac97_t * ac97) |
403 | { | 452 | { |
404 | // WM9705, WM9710 | 453 | /* WM9705, WM9710 */ |
405 | // set front mixer volume | 454 | ac97->build_ops = &patch_wolfson_wm9705_ops; |
406 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 455 | return 0; |
456 | } | ||
457 | |||
458 | static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
459 | static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"}; | ||
460 | static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; | ||
461 | static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"}; | ||
462 | static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; | ||
463 | static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"}; | ||
464 | static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
465 | static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; | ||
466 | static const char* wm9711_rec_sel[] = | ||
467 | {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"}; | ||
468 | static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"}; | ||
469 | |||
470 | static const struct ac97_enum wm9711_enum[] = { | ||
471 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select), | ||
472 | AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix), | ||
473 | AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src), | ||
474 | AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc), | ||
475 | AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc), | ||
476 | AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base), | ||
477 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain), | ||
478 | AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic), | ||
479 | AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel), | ||
480 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type), | ||
481 | }; | ||
482 | |||
483 | static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = { | ||
484 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
485 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
486 | AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
487 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
488 | AC97_ENUM("ALC Function", wm9711_enum[0]), | ||
489 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1), | ||
490 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), | ||
491 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
492 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
493 | AC97_ENUM("ALC NG Type", wm9711_enum[9]), | ||
494 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), | ||
495 | |||
496 | AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1), | ||
497 | AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1), | ||
498 | AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), | ||
499 | AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), | ||
500 | |||
501 | AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), | ||
502 | AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), | ||
503 | AC97_ENUM("Out3 Mux", wm9711_enum[2]), | ||
504 | AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), | ||
505 | AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), | ||
506 | |||
507 | AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), | ||
508 | AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1), | ||
509 | AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1), | ||
510 | AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1), | ||
511 | AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1), | ||
512 | AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1), | ||
513 | |||
514 | AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1), | ||
515 | AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1), | ||
516 | AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1), | ||
517 | AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1), | ||
518 | AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1), | ||
519 | AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1), | ||
520 | |||
521 | AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1), | ||
522 | AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1), | ||
523 | |||
524 | AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1), | ||
525 | AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1), | ||
526 | AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1), | ||
527 | |||
528 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
529 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1), | ||
530 | AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1), | ||
531 | |||
532 | AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), | ||
533 | AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]), | ||
534 | AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), | ||
535 | AC97_ENUM("Capture Select", wm9711_enum[8]), | ||
536 | |||
537 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), | ||
538 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), | ||
539 | |||
540 | AC97_ENUM("Bass Control", wm9711_enum[5]), | ||
541 | AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), | ||
542 | AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), | ||
543 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
544 | |||
545 | AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), | ||
546 | AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), | ||
547 | AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), | ||
548 | AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | ||
549 | |||
550 | AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), | ||
551 | AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), | ||
552 | AC97_ENUM("Mic Select Source", wm9711_enum[7]), | ||
553 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), | ||
554 | AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | ||
555 | |||
556 | AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), | ||
557 | AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), | ||
558 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), | ||
559 | }; | ||
560 | |||
561 | int patch_wolfson_wm9711_specific(ac97_t * ac97) | ||
562 | { | ||
563 | int err, i; | ||
564 | |||
565 | for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) { | ||
566 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0) | ||
567 | return err; | ||
568 | } | ||
569 | snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808); | ||
570 | snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808); | ||
571 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808); | ||
572 | snd_ac97_write_cache(ac97, AC97_AUX, 0x0808); | ||
573 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | ||
574 | snd_ac97_write_cache(ac97, AC97_CD, 0x0000); | ||
407 | return 0; | 575 | return 0; |
408 | } | 576 | } |
409 | 577 | ||
578 | static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { | ||
579 | .build_specific = patch_wolfson_wm9711_specific, | ||
580 | }; | ||
581 | |||
410 | int patch_wolfson11(ac97_t * ac97) | 582 | int patch_wolfson11(ac97_t * ac97) |
411 | { | 583 | { |
412 | // WM9711, WM9712 | 584 | /* WM9711, WM9712 */ |
413 | // set out3 volume | 585 | ac97->build_ops = &patch_wolfson_wm9711_ops; |
414 | snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808); | 586 | |
587 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC | | ||
588 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | ||
589 | |||
415 | return 0; | 590 | return 0; |
416 | } | 591 | } |
417 | 592 | ||
418 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; | 593 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; |
419 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; | 594 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; |
420 | static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; | 595 | static const char* wm9713_rec_src[] = |
421 | static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"}; | 596 | {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix", |
597 | "Mono Mix", "Zh"}; | ||
598 | static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
599 | static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
600 | static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"}; | ||
601 | static const char* wm9713_spk_pga[] = | ||
602 | {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"}; | ||
603 | static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"}; | ||
604 | static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"}; | ||
605 | static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"}; | ||
606 | static const char* wm9713_dac_inv[] = | ||
607 | {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R", | ||
608 | "Headphone Mix Mono", "NC", "Vmid"}; | ||
609 | static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"}; | ||
610 | static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"}; | ||
422 | 611 | ||
423 | static const struct ac97_enum wm9713_enum[] = { | 612 | static const struct ac97_enum wm9713_enum[] = { |
424 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), | 613 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), |
425 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), | 614 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), |
426 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), | 615 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), |
427 | AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), | 616 | AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src), |
428 | AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), | 617 | AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), |
618 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), | ||
619 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), | ||
620 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga), | ||
621 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga), | ||
622 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), | ||
623 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), | ||
624 | AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv), | ||
625 | AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base), | ||
626 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), | ||
429 | }; | 627 | }; |
430 | 628 | ||
431 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { | 629 | static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = { |
432 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), | 630 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), |
433 | AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), | 631 | AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), |
434 | AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), | 632 | AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1), |
435 | AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), | 633 | AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1), |
436 | }; | 634 | |
437 | 635 | AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), | |
438 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { | 636 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1), |
439 | AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), | 637 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1), |
440 | AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), | 638 | AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1), |
441 | AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), | 639 | |
442 | AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), | 640 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), |
443 | }; | 641 | AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), |
444 | 642 | AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1), | |
445 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { | 643 | AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1), |
446 | AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), | 644 | AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), |
447 | AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), | 645 | AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]), |
448 | AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), | 646 | AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), |
449 | AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), | 647 | |
450 | AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1), | 648 | AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1), |
451 | AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), | 649 | AC97_ENUM("Capture Volume Steps", wm9713_enum[4]), |
452 | AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) | 650 | AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0), |
651 | AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), | ||
652 | |||
653 | AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]), | ||
654 | AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), | ||
655 | AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]), | ||
656 | AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), | ||
657 | AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), | ||
658 | AC97_ENUM("Capture Select", wm9713_enum[3]), | ||
659 | |||
660 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
661 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
662 | AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
663 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
664 | AC97_ENUM("ALC Function", wm9713_enum[5]), | ||
665 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), | ||
666 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0), | ||
667 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
668 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
669 | AC97_ENUM("ALC NG Type", wm9713_enum[13]), | ||
670 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0), | ||
671 | |||
672 | AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0), | ||
673 | AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0), | ||
674 | AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0), | ||
675 | AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1), | ||
676 | AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1), | ||
677 | AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1), | ||
678 | |||
679 | AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1), | ||
680 | AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1), | ||
681 | AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1), | ||
682 | AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1), | ||
683 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
684 | AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), | ||
685 | |||
686 | AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), | ||
687 | AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), | ||
688 | AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), | ||
689 | AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), | ||
690 | AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), | ||
691 | AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), | ||
692 | |||
693 | AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
694 | AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), | ||
695 | AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1), | ||
696 | AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1), | ||
697 | AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1), | ||
698 | AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1), | ||
699 | |||
700 | AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1), | ||
701 | AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1), | ||
702 | AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1), | ||
703 | AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1), | ||
704 | AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1), | ||
705 | AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1), | ||
706 | |||
707 | AC97_ENUM("Mono Input Mux", wm9713_enum[6]), | ||
708 | AC97_ENUM("Master Input Mux", wm9713_enum[7]), | ||
709 | AC97_ENUM("Headphone Input Mux", wm9713_enum[8]), | ||
710 | AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]), | ||
711 | AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]), | ||
712 | |||
713 | AC97_ENUM("Bass Control", wm9713_enum[12]), | ||
714 | AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), | ||
715 | AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1), | ||
716 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0), | ||
717 | AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1), | ||
718 | AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1), | ||
453 | }; | 719 | }; |
454 | 720 | ||
455 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = { | 721 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = { |
456 | AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1), | 722 | AC97_ENUM("Inv Input Mux", wm9713_enum[11]), |
457 | AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1), | 723 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0), |
458 | AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0), | 724 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), |
459 | AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1), | 725 | AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), |
460 | }; | 726 | }; |
461 | 727 | ||
462 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = { | 728 | static int patch_wolfson_wm9713_3d (ac97_t * ac97) |
463 | AC97_ENUM("Record to Headphone Path", wm9713_enum[1]), | 729 | { |
464 | AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0), | 730 | int err, i; |
465 | AC97_ENUM("Record to Mono Path", wm9713_enum[2]), | 731 | |
466 | AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0), | 732 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) { |
467 | AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0), | 733 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0) |
468 | AC97_ENUM("Record Select Left", wm9713_enum[3]), | 734 | return err; |
469 | AC97_ENUM("Record Select Right", wm9713_enum[4]), | 735 | } |
470 | }; | 736 | return 0; |
737 | } | ||
471 | 738 | ||
472 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) | 739 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) |
473 | { | 740 | { |
474 | int err, i; | 741 | int err, i; |
475 | 742 | ||
476 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) { | 743 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) { |
477 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0) | 744 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0) |
478 | return err; | 745 | return err; |
479 | } | 746 | } |
480 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | 747 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); |
481 | |||
482 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) { | ||
483 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0) | ||
484 | return err; | ||
485 | } | ||
486 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); | 748 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); |
487 | |||
488 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) { | ||
489 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0) | ||
490 | return err; | ||
491 | } | ||
492 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); | 749 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); |
493 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); | 750 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); |
494 | |||
495 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) { | ||
496 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0) | ||
497 | return err; | ||
498 | } | ||
499 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); | 751 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); |
500 | |||
501 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) { | ||
502 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0) | ||
503 | return err; | ||
504 | } | ||
505 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); | 752 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); |
506 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); | 753 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); |
507 | |||
508 | return 0; | 754 | return 0; |
509 | } | 755 | } |
510 | 756 | ||
@@ -525,6 +771,7 @@ static void patch_wolfson_wm9713_resume (ac97_t * ac97) | |||
525 | 771 | ||
526 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | 772 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { |
527 | .build_specific = patch_wolfson_wm9713_specific, | 773 | .build_specific = patch_wolfson_wm9713_specific, |
774 | .build_3d = patch_wolfson_wm9713_3d, | ||
528 | #ifdef CONFIG_PM | 775 | #ifdef CONFIG_PM |
529 | .suspend = patch_wolfson_wm9713_suspend, | 776 | .suspend = patch_wolfson_wm9713_suspend, |
530 | .resume = patch_wolfson_wm9713_resume | 777 | .resume = patch_wolfson_wm9713_resume |
@@ -533,10 +780,12 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | |||
533 | 780 | ||
534 | int patch_wolfson13(ac97_t * ac97) | 781 | int patch_wolfson13(ac97_t * ac97) |
535 | { | 782 | { |
783 | /* WM9713, WM9714 */ | ||
536 | ac97->build_ops = &patch_wolfson_wm9713_ops; | 784 | ac97->build_ops = &patch_wolfson_wm9713_ops; |
537 | 785 | ||
538 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | | 786 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | |
539 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | 787 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE | |
788 | AC97_HAS_NO_STD_PCM; | ||
540 | 789 | ||
541 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); | 790 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); |
542 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); | 791 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); |