aboutsummaryrefslogtreecommitdiffstats
path: root/sound/ppc/awacs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/ppc/awacs.c')
-rw-r--r--sound/ppc/awacs.c73
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)
319static void awacs_amp_free(struct snd_pmac *chip) 319static 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
617static 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
624static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = { 624static 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 = {
688static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata = 688static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
689AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); 689AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
690 690
691static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata = 691static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata =
692AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
693
694static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata =
692AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); 695AWACS_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
772static int imac; 776static 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);