diff options
Diffstat (limited to 'sound/ppc/awacs.c')
-rw-r--r-- | sound/ppc/awacs.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 566a6d0daf4a..7bd33e6552ab 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c | |||
@@ -319,7 +319,8 @@ static void awacs_amp_set_master(struct awacs_amp *amp, int vol) | |||
319 | static void awacs_amp_free(struct snd_pmac *chip) | 319 | static void awacs_amp_free(struct snd_pmac *chip) |
320 | { | 320 | { |
321 | struct awacs_amp *amp = chip->mixer_data; | 321 | struct awacs_amp *amp = chip->mixer_data; |
322 | snd_assert(amp, return); | 322 | if (!amp) |
323 | return; | ||
323 | kfree(amp); | 324 | kfree(amp); |
324 | chip->mixer_data = NULL; | 325 | chip->mixer_data = NULL; |
325 | chip->mixer_free = NULL; | 326 | chip->mixer_free = NULL; |
@@ -345,8 +346,7 @@ static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol, | |||
345 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 346 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
346 | int index = kcontrol->private_value; | 347 | int index = kcontrol->private_value; |
347 | struct awacs_amp *amp = chip->mixer_data; | 348 | struct awacs_amp *amp = chip->mixer_data; |
348 | snd_assert(amp, return -EINVAL); | 349 | |
349 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
350 | ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31); | 350 | ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31); |
351 | ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31); | 351 | ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31); |
352 | return 0; | 352 | return 0; |
@@ -359,8 +359,6 @@ static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol, | |||
359 | int index = kcontrol->private_value; | 359 | int index = kcontrol->private_value; |
360 | int vol[2]; | 360 | int vol[2]; |
361 | struct awacs_amp *amp = chip->mixer_data; | 361 | struct awacs_amp *amp = chip->mixer_data; |
362 | snd_assert(amp, return -EINVAL); | ||
363 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
364 | 362 | ||
365 | vol[0] = (31 - (ucontrol->value.integer.value[0] & 31)) | 363 | vol[0] = (31 - (ucontrol->value.integer.value[0] & 31)) |
366 | | (amp->amp_vol[index][0] & 32); | 364 | | (amp->amp_vol[index][0] & 32); |
@@ -375,8 +373,7 @@ static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol, | |||
375 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 373 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
376 | int index = kcontrol->private_value; | 374 | int index = kcontrol->private_value; |
377 | struct awacs_amp *amp = chip->mixer_data; | 375 | struct awacs_amp *amp = chip->mixer_data; |
378 | snd_assert(amp, return -EINVAL); | 376 | |
379 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
380 | ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32) | 377 | ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32) |
381 | ? 0 : 1; | 378 | ? 0 : 1; |
382 | ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32) | 379 | ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32) |
@@ -391,8 +388,6 @@ static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol, | |||
391 | int index = kcontrol->private_value; | 388 | int index = kcontrol->private_value; |
392 | int vol[2]; | 389 | int vol[2]; |
393 | struct awacs_amp *amp = chip->mixer_data; | 390 | struct awacs_amp *amp = chip->mixer_data; |
394 | snd_assert(amp, return -EINVAL); | ||
395 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
396 | 391 | ||
397 | vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32) | 392 | vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32) |
398 | | (amp->amp_vol[index][0] & 31); | 393 | | (amp->amp_vol[index][0] & 31); |
@@ -417,8 +412,7 @@ static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol, | |||
417 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 412 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
418 | int index = kcontrol->private_value; | 413 | int index = kcontrol->private_value; |
419 | struct awacs_amp *amp = chip->mixer_data; | 414 | struct awacs_amp *amp = chip->mixer_data; |
420 | snd_assert(amp, return -EINVAL); | 415 | |
421 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
422 | ucontrol->value.integer.value[0] = amp->amp_tone[index]; | 416 | ucontrol->value.integer.value[0] = amp->amp_tone[index]; |
423 | return 0; | 417 | return 0; |
424 | } | 418 | } |
@@ -430,8 +424,7 @@ static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol, | |||
430 | int index = kcontrol->private_value; | 424 | int index = kcontrol->private_value; |
431 | struct awacs_amp *amp = chip->mixer_data; | 425 | struct awacs_amp *amp = chip->mixer_data; |
432 | unsigned int val; | 426 | unsigned int val; |
433 | snd_assert(amp, return -EINVAL); | 427 | |
434 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | ||
435 | val = ucontrol->value.integer.value[0]; | 428 | val = ucontrol->value.integer.value[0]; |
436 | if (val > 14) | 429 | if (val > 14) |
437 | return -EINVAL; | 430 | return -EINVAL; |
@@ -458,7 +451,7 @@ static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol, | |||
458 | { | 451 | { |
459 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 452 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
460 | struct awacs_amp *amp = chip->mixer_data; | 453 | struct awacs_amp *amp = chip->mixer_data; |
461 | snd_assert(amp, return -EINVAL); | 454 | |
462 | ucontrol->value.integer.value[0] = amp->amp_master; | 455 | ucontrol->value.integer.value[0] = amp->amp_master; |
463 | return 0; | 456 | return 0; |
464 | } | 457 | } |
@@ -469,7 +462,7 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol, | |||
469 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 462 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
470 | struct awacs_amp *amp = chip->mixer_data; | 463 | struct awacs_amp *amp = chip->mixer_data; |
471 | unsigned int val; | 464 | unsigned int val; |
472 | snd_assert(amp, return -EINVAL); | 465 | |
473 | val = ucontrol->value.integer.value[0]; | 466 | val = ucontrol->value.integer.value[0]; |
474 | if (val > 99) | 467 | if (val > 99) |
475 | return -EINVAL; | 468 | return -EINVAL; |
@@ -621,6 +614,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = { | |||
621 | AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), | 614 | AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), |
622 | }; | 615 | }; |
623 | 616 | ||
617 | static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = { | ||
618 | AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), | ||
619 | AWACS_VOLUME("Master Playback Volume", 5, 6, 1), | ||
620 | AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), | ||
621 | AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0), | ||
622 | }; | ||
623 | |||
624 | static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = { | 624 | static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = { |
625 | AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), | 625 | AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), |
626 | AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), | 626 | AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), |
@@ -688,7 +688,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = { | |||
688 | static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata = | 688 | static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata = |
689 | AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); | 689 | AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); |
690 | 690 | ||
691 | static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata = | 691 | static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata = |
692 | AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1); | ||
693 | |||
694 | static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata = | ||
692 | AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); | 695 | AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); |
693 | 696 | ||
694 | 697 | ||
@@ -765,11 +768,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip) | |||
765 | 768 | ||
766 | #define IS_PM7500 (machine_is_compatible("AAPL,7500")) | 769 | #define IS_PM7500 (machine_is_compatible("AAPL,7500")) |
767 | #define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) | 770 | #define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) |
768 | #define IS_IMAC (machine_is_compatible("PowerMac2,1") \ | 771 | #define IS_IMAC1 (machine_is_compatible("PowerMac2,1")) |
769 | || machine_is_compatible("PowerMac2,2") \ | 772 | #define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \ |
770 | || machine_is_compatible("PowerMac4,1")) | 773 | || machine_is_compatible("PowerMac4,1")) |
774 | #define IS_G4AGP (machine_is_compatible("PowerMac3,1")) | ||
771 | 775 | ||
772 | static int imac; | 776 | static int imac1, imac2; |
773 | 777 | ||
774 | #ifdef PMAC_SUPPORT_AUTOMUTE | 778 | #ifdef PMAC_SUPPORT_AUTOMUTE |
775 | /* | 779 | /* |
@@ -815,13 +819,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify) | |||
815 | { | 819 | { |
816 | int reg = chip->awacs_reg[1] | 820 | int reg = chip->awacs_reg[1] |
817 | | (MASK_HDMUTE | MASK_SPKMUTE); | 821 | | (MASK_HDMUTE | MASK_SPKMUTE); |
818 | if (imac) { | 822 | if (imac1) { |
823 | reg &= ~MASK_SPKMUTE; | ||
824 | reg |= MASK_PAROUT1; | ||
825 | } else if (imac2) { | ||
819 | reg &= ~MASK_SPKMUTE; | 826 | reg &= ~MASK_SPKMUTE; |
820 | reg &= ~MASK_PAROUT1; | 827 | reg &= ~MASK_PAROUT1; |
821 | } | 828 | } |
822 | if (snd_pmac_awacs_detect_headphone(chip)) | 829 | if (snd_pmac_awacs_detect_headphone(chip)) |
823 | reg &= ~MASK_HDMUTE; | 830 | reg &= ~MASK_HDMUTE; |
824 | else if (imac) | 831 | else if (imac1) |
832 | reg &= ~MASK_PAROUT1; | ||
833 | else if (imac2) | ||
825 | reg |= MASK_PAROUT1; | 834 | reg |= MASK_PAROUT1; |
826 | else | 835 | else |
827 | reg &= ~MASK_SPKMUTE; | 836 | reg &= ~MASK_SPKMUTE; |
@@ -850,9 +859,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip) | |||
850 | { | 859 | { |
851 | int pm7500 = IS_PM7500; | 860 | int pm7500 = IS_PM7500; |
852 | int beige = IS_BEIGE; | 861 | int beige = IS_BEIGE; |
862 | int g4agp = IS_G4AGP; | ||
863 | int imac; | ||
853 | int err, vol; | 864 | int err, vol; |
854 | 865 | ||
855 | imac = IS_IMAC; | 866 | imac1 = IS_IMAC1; |
867 | imac2 = IS_IMAC2; | ||
868 | imac = imac1 || imac2; | ||
856 | /* looks like MASK_GAINLINE triggers something, so we set here | 869 | /* looks like MASK_GAINLINE triggers something, so we set here |
857 | * as start-up | 870 | * as start-up |
858 | */ | 871 | */ |
@@ -939,7 +952,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) | |||
939 | snd_pmac_awacs_mixers); | 952 | snd_pmac_awacs_mixers); |
940 | if (err < 0) | 953 | if (err < 0) |
941 | return err; | 954 | return err; |
942 | if (beige) | 955 | if (beige || g4agp) |
943 | ; | 956 | ; |
944 | else if (chip->model == PMAC_SCREAMER) | 957 | else if (chip->model == PMAC_SCREAMER) |
945 | err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2), | 958 | err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2), |
@@ -961,13 +974,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip) | |||
961 | err = build_mixers(chip, | 974 | err = build_mixers(chip, |
962 | ARRAY_SIZE(snd_pmac_screamer_mixers_imac), | 975 | ARRAY_SIZE(snd_pmac_screamer_mixers_imac), |
963 | snd_pmac_screamer_mixers_imac); | 976 | snd_pmac_screamer_mixers_imac); |
977 | else if (g4agp) | ||
978 | err = build_mixers(chip, | ||
979 | ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp), | ||
980 | snd_pmac_screamer_mixers_g4agp); | ||
964 | else | 981 | else |
965 | err = build_mixers(chip, | 982 | err = build_mixers(chip, |
966 | ARRAY_SIZE(snd_pmac_awacs_mixers_pmac), | 983 | ARRAY_SIZE(snd_pmac_awacs_mixers_pmac), |
967 | snd_pmac_awacs_mixers_pmac); | 984 | snd_pmac_awacs_mixers_pmac); |
968 | if (err < 0) | 985 | if (err < 0) |
969 | return err; | 986 | return err; |
970 | chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac) | 987 | chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp) |
971 | ? &snd_pmac_awacs_master_sw_imac | 988 | ? &snd_pmac_awacs_master_sw_imac |
972 | : &snd_pmac_awacs_master_sw, chip); | 989 | : &snd_pmac_awacs_master_sw, chip); |
973 | err = snd_ctl_add(chip->card, chip->master_sw_ctl); | 990 | err = snd_ctl_add(chip->card, chip->master_sw_ctl); |
@@ -1004,15 +1021,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip) | |||
1004 | snd_pmac_awacs_speaker_vol); | 1021 | snd_pmac_awacs_speaker_vol); |
1005 | if (err < 0) | 1022 | if (err < 0) |
1006 | return err; | 1023 | return err; |
1007 | chip->speaker_sw_ctl = snd_ctl_new1(imac | 1024 | chip->speaker_sw_ctl = snd_ctl_new1(imac1 |
1008 | ? &snd_pmac_awacs_speaker_sw_imac | 1025 | ? &snd_pmac_awacs_speaker_sw_imac1 |
1026 | : imac2 | ||
1027 | ? &snd_pmac_awacs_speaker_sw_imac2 | ||
1009 | : &snd_pmac_awacs_speaker_sw, chip); | 1028 | : &snd_pmac_awacs_speaker_sw, chip); |
1010 | err = snd_ctl_add(chip->card, chip->speaker_sw_ctl); | 1029 | err = snd_ctl_add(chip->card, chip->speaker_sw_ctl); |
1011 | if (err < 0) | 1030 | if (err < 0) |
1012 | return err; | 1031 | return err; |
1013 | } | 1032 | } |
1014 | 1033 | ||
1015 | if (beige) | 1034 | if (beige || g4agp) |
1016 | err = build_mixers(chip, | 1035 | err = build_mixers(chip, |
1017 | ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige), | 1036 | ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige), |
1018 | snd_pmac_screamer_mic_boost_beige); | 1037 | snd_pmac_screamer_mic_boost_beige); |