aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/ac97/ac97_patch.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ac97/ac97_patch.c')
-rw-r--r--sound/pci/ac97/ac97_patch.c174
1 files changed, 119 insertions, 55 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 7337abdbe4e..99176221541 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -27,6 +27,15 @@
#include "ac97_patch.h"
/*
+ * Forward declarations
+ */
+
+static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
+ const char *name);
+static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
+ const unsigned int *tlv, const char **slaves);
+
+/*
* Chip specific initialization
*/
@@ -371,7 +380,7 @@ static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
+static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
.build_spdif = patch_yamaha_ymf743_build_spdif,
.build_3d = patch_yamaha_ymf7x3_3d,
};
@@ -455,7 +464,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
+static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
.build_3d = patch_yamaha_ymf7x3_3d,
.build_post_spdif = patch_yamaha_ymf753_post_spdif
};
@@ -502,7 +511,7 @@ static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
+static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
.build_specific = patch_wolfson_wm9703_specific,
};
@@ -533,7 +542,7 @@ static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
+static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
.build_specific = patch_wolfson_wm9704_specific,
};
@@ -544,25 +553,10 @@ static int patch_wolfson04(struct snd_ac97 * ac97)
return 0;
}
-static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97)
-{
- int err, i;
- for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
- return err;
- }
- snd_ac97_write_cache(ac97, 0x72, 0x0808);
- return 0;
-}
-
-static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
- .build_specific = patch_wolfson_wm9705_specific,
-};
-
static int patch_wolfson05(struct snd_ac97 * ac97)
{
/* WM9705, WM9710 */
- ac97->build_ops = &patch_wolfson_wm9705_ops;
+ ac97->build_ops = &patch_wolfson_wm9703_ops;
#ifdef CONFIG_TOUCHSCREEN_WM9705
/* WM9705 touchscreen uses AUX and VIDEO for touch */
ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
@@ -692,7 +686,7 @@ static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
+static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
.build_specific = patch_wolfson_wm9711_specific,
};
@@ -800,12 +794,12 @@ AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
-AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
-AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
-AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1),
-AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1),
-AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1),
-AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1),
+AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
+AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
+AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
+AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
+AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
+AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
@@ -886,7 +880,7 @@ static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
}
#endif
-static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
+static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
.build_specific = patch_wolfson_wm9713_specific,
.build_3d = patch_wolfson_wm9713_3d,
#ifdef CONFIG_PM
@@ -991,7 +985,7 @@ static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
+static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
.build_3d = patch_sigmatel_stac9700_3d,
.build_specific = patch_sigmatel_stac97xx_specific
};
@@ -1038,7 +1032,7 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
return patch_sigmatel_stac97xx_specific(ac97);
}
-static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
+static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
.build_3d = patch_sigmatel_stac9708_3d,
.build_specific = patch_sigmatel_stac9708_specific
};
@@ -1267,7 +1261,7 @@ static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
+static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
.build_3d = patch_sigmatel_stac9700_3d,
.build_specific = patch_sigmatel_stac9758_specific
};
@@ -1342,7 +1336,7 @@ static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_cirrus_ops = {
+static const struct snd_ac97_build_ops patch_cirrus_ops = {
.build_spdif = patch_cirrus_build_spdif
};
@@ -1399,7 +1393,7 @@ static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_conexant_ops = {
+static const struct snd_ac97_build_ops patch_conexant_ops = {
.build_spdif = patch_conexant_build_spdif
};
@@ -1575,7 +1569,7 @@ static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int
}
}
-static struct snd_ac97_build_ops patch_ad1881_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
#ifdef CONFIG_PM
.resume = ad18xx_resume
#endif
@@ -1662,7 +1656,7 @@ static int patch_ad1885_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_ad1885_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
.build_specific = &patch_ad1885_specific,
#ifdef CONFIG_PM
.resume = ad18xx_resume
@@ -1689,7 +1683,7 @@ static int patch_ad1886_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_ad1886_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
.build_specific = &patch_ad1886_specific,
#ifdef CONFIG_PM
.resume = ad18xx_resume
@@ -1867,11 +1861,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
0x10140523, /* Thinkpad R40 */
0x10140534, /* Thinkpad X31 */
0x10140537, /* Thinkpad T41p */
+ 0x1014053e, /* Thinkpad R40e */
0x10140554, /* Thinkpad T42p/R50p */
0x10140567, /* Thinkpad T43p 2668-G7U */
0x10140581, /* Thinkpad X41-2527 */
+ 0x10280160, /* Dell Dimension 2400 */
0x104380b0, /* Asus A7V8X-MX */
0x11790241, /* Toshiba Satellite A-15 S127 */
+ 0x1179ff10, /* Toshiba P500 */
0x144dc01a, /* Samsung NP-X20C004/SEG */
0 /* end */
};
@@ -1893,7 +1890,7 @@ static int patch_ad1981a_specific(struct snd_ac97 * ac97)
ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
}
-static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1981a_specific,
#ifdef CONFIG_PM
@@ -1912,6 +1909,7 @@ static unsigned int ad1981_jacks_whitelist[] = {
0x103c0944, /* HP nc6220 */
0x103c0934, /* HP nc8220 */
0x103c006d, /* HP nx9105 */
+ 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
0x17340088, /* FSC Scenic-W */
0 /* end */
};
@@ -1948,7 +1946,7 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97)
ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
}
-static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1981b_specific,
#ifdef CONFIG_PM
@@ -2087,7 +2085,7 @@ static int patch_ad1888_specific(struct snd_ac97 *ac97)
return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
}
-static struct snd_ac97_build_ops patch_ad1888_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1888_specific,
#ifdef CONFIG_PM
@@ -2136,7 +2134,7 @@ static int patch_ad1980_specific(struct snd_ac97 *ac97)
return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
}
-static struct snd_ac97_build_ops patch_ad1980_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1980_specific,
#ifdef CONFIG_PM
@@ -2251,7 +2249,7 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
ARRAY_SIZE(snd_ac97_ad1985_controls));
}
-static struct snd_ac97_build_ops patch_ad1985_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1985_specific,
#ifdef CONFIG_PM
@@ -2543,7 +2541,7 @@ static int patch_ad1986_specific(struct snd_ac97 *ac97)
ARRAY_SIZE(snd_ac97_ad1985_controls));
}
-static struct snd_ac97_build_ops patch_ad1986_build_ops = {
+static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1986_specific,
#ifdef CONFIG_PM
@@ -2597,6 +2595,21 @@ static void alc650_update_jacks(struct snd_ac97 *ac97)
shared ? 0 : 0x100);
}
+static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
+ struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
+
+ if (map) {
+ if (ucontrol->value.integer.value[0])
+ map->chmap = snd_pcm_std_chmaps;
+ else
+ map->chmap = snd_pcm_alt_chmaps;
+ }
+ return snd_ac97_put_volsw(kcontrol, ucontrol);
+}
+
static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
@@ -2610,7 +2623,14 @@ static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
/* 9: Line-In/Surround share */
/* 10: Mic/CLFE share */
/* 11-13: in IEC958 controls */
- AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Swap Surround Slot",
+ .info = snd_ac97_info_volsw,
+ .get = snd_ac97_get_volsw,
+ .put = alc650_swap_surround_put,
+ .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
+ },
#if 0 /* always set in patch_alc650 */
AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
@@ -2648,7 +2668,7 @@ static int patch_alc650_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_alc650_ops = {
+static const struct snd_ac97_build_ops patch_alc650_ops = {
.build_specific = patch_alc650_specific,
.update_jacks = alc650_update_jacks
};
@@ -2800,7 +2820,7 @@ static int patch_alc655_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_alc655_ops = {
+static const struct snd_ac97_build_ops patch_alc655_ops = {
.build_specific = patch_alc655_specific,
.update_jacks = alc655_update_jacks
};
@@ -2912,7 +2932,7 @@ static int patch_alc850_specific(struct snd_ac97 *ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_alc850_ops = {
+static const struct snd_ac97_build_ops patch_alc850_ops = {
.build_specific = patch_alc850_specific,
.update_jacks = alc850_update_jacks
};
@@ -2952,6 +2972,49 @@ static int patch_alc850(struct snd_ac97 *ac97)
return 0;
}
+static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
+{
+ struct snd_kcontrol *kctl_3d_center =
+ snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
+ struct snd_kcontrol *kctl_3d_depth =
+ snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
+
+ /*
+ * 3D register is different from AC97 standard layout
+ * (also do some renaming, to resemble Windows driver naming)
+ */
+ if (kctl_3d_center) {
+ kctl_3d_center->private_value =
+ AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
+ snd_ac97_rename_vol_ctl(ac97,
+ "3D Control - Center", "3D Control - Width"
+ );
+ }
+ if (kctl_3d_depth)
+ kctl_3d_depth->private_value =
+ AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
+
+ /* Aztech Windows driver calls the
+ equivalent control "Modem Playback", thus rename it: */
+ snd_ac97_rename_vol_ctl(ac97,
+ "Master Mono Playback", "Modem Playback"
+ );
+ snd_ac97_rename_vol_ctl(ac97,
+ "Headphone Playback", "FM Synth Playback"
+ );
+
+ return 0;
+}
+
+static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
+ .build_specific = patch_aztech_azf3328_specific
+};
+
+static int patch_aztech_azf3328(struct snd_ac97 *ac97)
+{
+ ac97->build_ops = &patch_aztech_azf3328_ops;
+ return 0;
+}
/*
* C-Media CM97xx codecs
@@ -2974,7 +3037,7 @@ static int patch_cm9738_specific(struct snd_ac97 * ac97)
return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
}
-static struct snd_ac97_build_ops patch_cm9738_ops = {
+static const struct snd_ac97_build_ops patch_cm9738_ops = {
.build_specific = patch_cm9738_specific,
.update_jacks = cm9738_update_jacks
};
@@ -3065,7 +3128,7 @@ static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
}
-static struct snd_ac97_build_ops patch_cm9739_ops = {
+static const struct snd_ac97_build_ops patch_cm9739_ops = {
.build_specific = patch_cm9739_specific,
.build_post_spdif = patch_cm9739_post_spdif,
.update_jacks = cm9739_update_jacks
@@ -3239,7 +3302,7 @@ static int patch_cm9761_specific(struct snd_ac97 * ac97)
return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
}
-static struct snd_ac97_build_ops patch_cm9761_ops = {
+static const struct snd_ac97_build_ops patch_cm9761_ops = {
.build_specific = patch_cm9761_specific,
.build_post_spdif = patch_cm9761_post_spdif,
.update_jacks = cm9761_update_jacks
@@ -3335,7 +3398,7 @@ static int patch_cm9780_specific(struct snd_ac97 *ac97)
return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
}
-static struct snd_ac97_build_ops patch_cm9780_ops = {
+static const struct snd_ac97_build_ops patch_cm9780_ops = {
.build_specific = patch_cm9780_specific,
.build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
};
@@ -3414,7 +3477,8 @@ static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
sctl = snd_ac97_find_mixer_ctl(ac97, *s);
if (!sctl) {
- snd_printdd("Cannot find slave %s, skipped\n", *s);
+ dev_dbg(ac97->bus->card->dev,
+ "Cannot find slave %s, skipped\n", *s);
continue;
}
err = snd_ctl_add_slave(kctl, sctl);
@@ -3455,7 +3519,7 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_vt1616_ops = {
+static const struct snd_ac97_build_ops patch_vt1616_ops = {
.build_specific = patch_vt1616_specific
};
@@ -3809,7 +3873,7 @@ static int patch_it2646_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_it2646_ops = {
+static const struct snd_ac97_build_ops patch_it2646_ops = {
.build_specific = patch_it2646_specific,
.update_jacks = it2646_update_jacks
};
@@ -3843,7 +3907,7 @@ static int patch_si3036_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_si3036_ops = {
+static const struct snd_ac97_build_ops patch_si3036_ops = {
.build_specific = patch_si3036_specific,
};
@@ -3910,7 +3974,7 @@ static int patch_ucb1400_specific(struct snd_ac97 * ac97)
return 0;
}
-static struct snd_ac97_build_ops patch_ucb1400_ops = {
+static const struct snd_ac97_build_ops patch_ucb1400_ops = {
.build_specific = patch_ucb1400_specific,
};