aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/ac97_codec.h5
-rw-r--r--sound/pci/ac97/ac97_codec.c83
2 files changed, 54 insertions, 34 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index b602f475cdbb..f1dcefe4532b 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -96,6 +96,10 @@
96#define AC97_FUNC_INFO 0x68 /* Function Information */ 96#define AC97_FUNC_INFO 0x68 /* Function Information */
97#define AC97_SENSE_INFO 0x6a /* Sense Details */ 97#define AC97_SENSE_INFO 0x6a /* Sense Details */
98 98
99/* volume controls */
100#define AC97_MUTE_MASK_MONO 0x8000
101#define AC97_MUTE_MASK_STEREO 0x8080
102
99/* slot allocation */ 103/* slot allocation */
100#define AC97_SLOT_TAG 0 104#define AC97_SLOT_TAG 0
101#define AC97_SLOT_CMD_ADDR 1 105#define AC97_SLOT_CMD_ADDR 1
@@ -138,6 +142,7 @@
138#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */ 142#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
139#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */ 143#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
140#define AC97_BC_ADC_MASK 0x0300 144#define AC97_BC_ADC_MASK 0x0300
145#define AC97_BC_3D_TECH_ID_MASK 0x7c00 /* Per-vendor ID of 3D enhancement */
141 146
142/* general purpose */ 147/* general purpose */
143#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */ 148#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index cb62d178b3e0..2cc56b5c5397 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -590,9 +590,9 @@ static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
590 snd_ac97_page_restore(ac97, page_save); 590 snd_ac97_page_restore(ac97, page_save);
591#ifdef CONFIG_SND_AC97_POWER_SAVE 591#ifdef CONFIG_SND_AC97_POWER_SAVE
592 /* check analog mixer power-down */ 592 /* check analog mixer power-down */
593 if ((val_mask & 0x8000) && 593 if ((val_mask & AC97_PD_EAPD) &&
594 (kcontrol->private_value & (1<<30))) { 594 (kcontrol->private_value & (1<<30))) {
595 if (val & 0x8000) 595 if (val & AC97_PD_EAPD)
596 ac97->power_up &= ~(1 << (reg>>1)); 596 ac97->power_up &= ~(1 << (reg>>1));
597 else 597 else
598 ac97->power_up |= 1 << (reg>>1); 598 ac97->power_up |= 1 << (reg>>1);
@@ -1035,20 +1035,20 @@ static int snd_ac97_dev_free(struct snd_device *device)
1035 1035
1036static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) 1036static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg)
1037{ 1037{
1038 unsigned short val, mask = 0x8000; 1038 unsigned short val, mask = AC97_MUTE_MASK_MONO;
1039 1039
1040 if (! snd_ac97_valid_reg(ac97, reg)) 1040 if (! snd_ac97_valid_reg(ac97, reg))
1041 return 0; 1041 return 0;
1042 1042
1043 switch (reg) { 1043 switch (reg) {
1044 case AC97_MASTER_TONE: 1044 case AC97_MASTER_TONE:
1045 return ac97->caps & 0x04 ? 1 : 0; 1045 return ac97->caps & AC97_BC_BASS_TREBLE ? 1 : 0;
1046 case AC97_HEADPHONE: 1046 case AC97_HEADPHONE:
1047 return ac97->caps & 0x10 ? 1 : 0; 1047 return ac97->caps & AC97_BC_HEADPHONE ? 1 : 0;
1048 case AC97_REC_GAIN_MIC: 1048 case AC97_REC_GAIN_MIC:
1049 return ac97->caps & 0x01 ? 1 : 0; 1049 return ac97->caps & AC97_BC_DEDICATED_MIC ? 1 : 0;
1050 case AC97_3D_CONTROL: 1050 case AC97_3D_CONTROL:
1051 if (ac97->caps & 0x7c00) { 1051 if (ac97->caps & AC97_BC_3D_TECH_ID_MASK) {
1052 val = snd_ac97_read(ac97, reg); 1052 val = snd_ac97_read(ac97, reg);
1053 /* if nonzero - fixed and we can't set it */ 1053 /* if nonzero - fixed and we can't set it */
1054 return val == 0; 1054 return val == 0;
@@ -1104,7 +1104,10 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
1104 *lo_max = *hi_max = 0; 1104 *lo_max = *hi_max = 0;
1105 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { 1105 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
1106 unsigned short val; 1106 unsigned short val;
1107 snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); 1107 snd_ac97_write(
1108 ac97, reg,
1109 AC97_MUTE_MASK_STEREO | cbit[i] | (cbit[i] << 8)
1110 );
1108 /* Do the read twice due to buffers on some ac97 codecs. 1111 /* Do the read twice due to buffers on some ac97 codecs.
1109 * e.g. The STAC9704 returns exactly what you wrote to the register 1112 * e.g. The STAC9704 returns exactly what you wrote to the register
1110 * if you read it immediately. This causes the detect routine to fail. 1113 * if you read it immediately. This causes the detect routine to fail.
@@ -1139,14 +1142,14 @@ static void snd_ac97_change_volume_params2(struct snd_ac97 * ac97, int reg, int
1139 unsigned short val, val1; 1142 unsigned short val, val1;
1140 1143
1141 *max = 63; 1144 *max = 63;
1142 val = 0x8080 | (0x20 << shift); 1145 val = AC97_MUTE_MASK_STEREO | (0x20 << shift);
1143 snd_ac97_write(ac97, reg, val); 1146 snd_ac97_write(ac97, reg, val);
1144 val1 = snd_ac97_read(ac97, reg); 1147 val1 = snd_ac97_read(ac97, reg);
1145 if (val != val1) { 1148 if (val != val1) {
1146 *max = 31; 1149 *max = 31;
1147 } 1150 }
1148 /* reset volume to zero */ 1151 /* reset volume to zero */
1149 snd_ac97_write_cache(ac97, reg, 0x8080); 1152 snd_ac97_write_cache(ac97, reg, AC97_MUTE_MASK_STEREO);
1150} 1153}
1151 1154
1152static inline int printable(unsigned int x) 1155static inline int printable(unsigned int x)
@@ -1183,16 +1186,16 @@ static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg,
1183 if (! snd_ac97_valid_reg(ac97, reg)) 1186 if (! snd_ac97_valid_reg(ac97, reg))
1184 return 0; 1187 return 0;
1185 1188
1186 mute_mask = 0x8000; 1189 mute_mask = AC97_MUTE_MASK_MONO;
1187 val = snd_ac97_read(ac97, reg); 1190 val = snd_ac97_read(ac97, reg);
1188 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) { 1191 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
1189 /* check whether both mute bits work */ 1192 /* check whether both mute bits work */
1190 val1 = val | 0x8080; 1193 val1 = val | AC97_MUTE_MASK_STEREO;
1191 snd_ac97_write(ac97, reg, val1); 1194 snd_ac97_write(ac97, reg, val1);
1192 if (val1 == snd_ac97_read(ac97, reg)) 1195 if (val1 == snd_ac97_read(ac97, reg))
1193 mute_mask = 0x8080; 1196 mute_mask = AC97_MUTE_MASK_STEREO;
1194 } 1197 }
1195 if (mute_mask == 0x8080) { 1198 if (mute_mask == AC97_MUTE_MASK_STEREO) {
1196 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1); 1199 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
1197 if (check_amix) 1200 if (check_amix)
1198 tmp.private_value |= (1 << 30); 1201 tmp.private_value |= (1 << 30);
@@ -1268,9 +1271,11 @@ static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigne
1268 err = snd_ctl_add(card, kctl); 1271 err = snd_ctl_add(card, kctl);
1269 if (err < 0) 1272 if (err < 0)
1270 return err; 1273 return err;
1271 snd_ac97_write_cache(ac97, reg, 1274 snd_ac97_write_cache(
1272 (snd_ac97_read(ac97, reg) & 0x8080) | 1275 ac97, reg,
1273 lo_max | (hi_max << 8)); 1276 (snd_ac97_read(ac97, reg) & AC97_MUTE_MASK_STEREO)
1277 | lo_max | (hi_max << 8)
1278 );
1274 return 0; 1279 return 0;
1275} 1280}
1276 1281
@@ -1332,7 +1337,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1332 return err; 1337 return err;
1333 } 1338 }
1334 1339
1335 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1340 ac97->regs[AC97_CENTER_LFE_MASTER] = AC97_MUTE_MASK_STEREO;
1336 1341
1337 /* build center controls */ 1342 /* build center controls */
1338 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) 1343 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
@@ -1410,8 +1415,12 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1410 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0) 1415 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
1411 return err; 1416 return err;
1412 set_tlv_db_scale(kctl, db_scale_4bit); 1417 set_tlv_db_scale(kctl, db_scale_4bit);
1413 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 1418 snd_ac97_write_cache(
1414 snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e); 1419 ac97,
1420 AC97_PC_BEEP,
1421 (snd_ac97_read(ac97, AC97_PC_BEEP)
1422 | AC97_MUTE_MASK_MONO | 0x001e)
1423 );
1415 } 1424 }
1416 1425
1417 /* build Phone controls */ 1426 /* build Phone controls */
@@ -1545,7 +1554,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1545 } 1554 }
1546 1555
1547 /* build Simulated Stereo Enhancement control */ 1556 /* build Simulated Stereo Enhancement control */
1548 if (ac97->caps & 0x0008) { 1557 if (ac97->caps & AC97_BC_SIM_STEREO) {
1549 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0) 1558 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
1550 return err; 1559 return err;
1551 } 1560 }
@@ -1557,7 +1566,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1557 } 1566 }
1558 1567
1559 /* build Loudness control */ 1568 /* build Loudness control */
1560 if (ac97->caps & 0x0020) { 1569 if (ac97->caps & AC97_BC_LOUDNESS) {
1561 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0) 1570 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
1562 return err; 1571 return err;
1563 } 1572 }
@@ -2542,8 +2551,8 @@ void snd_ac97_resume(struct snd_ac97 *ac97)
2542 schedule_timeout_uninterruptible(1); 2551 schedule_timeout_uninterruptible(1);
2543 } while (time_after_eq(end_time, jiffies)); 2552 } while (time_after_eq(end_time, jiffies));
2544 /* FIXME: extra delay */ 2553 /* FIXME: extra delay */
2545 ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); 2554 ac97->bus->ops->write(ac97, AC97_MASTER, AC97_MUTE_MASK_MONO);
2546 if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) 2555 if (snd_ac97_read(ac97, AC97_MASTER) != AC97_MUTE_MASK_MONO)
2547 msleep(250); 2556 msleep(250);
2548 } else { 2557 } else {
2549 end_time = jiffies + msecs_to_jiffies(100); 2558 end_time = jiffies + msecs_to_jiffies(100);
@@ -2747,12 +2756,12 @@ static int master_mute_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
2747 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2756 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2748 unsigned short mask; 2757 unsigned short mask;
2749 if (shift != rshift) 2758 if (shift != rshift)
2750 mask = 0x8080; 2759 mask = AC97_MUTE_MASK_STEREO;
2751 else 2760 else
2752 mask = 0x8000; 2761 mask = AC97_MUTE_MASK_MONO;
2753 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2762 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2754 (ac97->regs[AC97_MASTER] & mask) == mask ? 2763 (ac97->regs[AC97_MASTER] & mask) == mask ?
2755 0x8000 : 0); 2764 AC97_PD_EAPD : 0);
2756 } 2765 }
2757 return err; 2766 return err;
2758} 2767}
@@ -2765,7 +2774,10 @@ static int tune_mute_led(struct snd_ac97 *ac97)
2765 return -ENOENT; 2774 return -ENOENT;
2766 msw->put = master_mute_sw_put; 2775 msw->put = master_mute_sw_put;
2767 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2776 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2768 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2777 snd_ac97_update_bits(
2778 ac97, AC97_POWERDOWN,
2779 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2780 );
2769 ac97->scaps |= AC97_SCAP_EAPD_LED; 2781 ac97->scaps |= AC97_SCAP_EAPD_LED;
2770 return 0; 2782 return 0;
2771} 2783}
@@ -2780,12 +2792,12 @@ static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol,
2780 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2792 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2781 unsigned short mask; 2793 unsigned short mask;
2782 if (shift != rshift) 2794 if (shift != rshift)
2783 mask = 0x8080; 2795 mask = AC97_MUTE_MASK_STEREO;
2784 else 2796 else
2785 mask = 0x8000; 2797 mask = AC97_MUTE_MASK_MONO;
2786 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2798 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2787 (ac97->regs[AC97_MASTER] & mask) == mask ? 2799 (ac97->regs[AC97_MASTER] & mask) == mask ?
2788 0x8000 : 0); 2800 AC97_PD_EAPD : 0);
2789 } 2801 }
2790 return err; 2802 return err;
2791} 2803}
@@ -2801,7 +2813,10 @@ static int tune_hp_mute_led(struct snd_ac97 *ac97)
2801 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2813 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2802 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch"); 2814 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
2803 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume"); 2815 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
2804 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2816 snd_ac97_update_bits(
2817 ac97, AC97_POWERDOWN,
2818 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2819 );
2805 return 0; 2820 return 0;
2806} 2821}
2807 2822