aboutsummaryrefslogtreecommitdiffstats
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.c194
1 files changed, 139 insertions, 55 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index b188a4df58cb..3eac0f86266c 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -23,20 +23,8 @@
23 * 23 *
24 */ 24 */
25 25
26#include <sound/driver.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/mutex.h>
31
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/control.h>
35#include <sound/tlv.h>
36#include <sound/ac97_codec.h>
37#include "ac97_patch.h"
38#include "ac97_id.h"
39#include "ac97_local.h" 26#include "ac97_local.h"
27#include "ac97_patch.h"
40 28
41/* 29/*
42 * Chip specific initialization 30 * Chip specific initialization
@@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
390 .build_post_spdif = patch_yamaha_ymf753_post_spdif 378 .build_post_spdif = patch_yamaha_ymf753_post_spdif
391}; 379};
392 380
393int patch_yamaha_ymf753(struct snd_ac97 * ac97) 381static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
394{ 382{
395 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. 383 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
396 This chip has nonstandard and extended behaviour with regard to its S/PDIF output. 384 This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
@@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
436 .build_specific = patch_wolfson_wm9703_specific, 424 .build_specific = patch_wolfson_wm9703_specific,
437}; 425};
438 426
439int patch_wolfson03(struct snd_ac97 * ac97) 427static int patch_wolfson03(struct snd_ac97 * ac97)
440{ 428{
441 ac97->build_ops = &patch_wolfson_wm9703_ops; 429 ac97->build_ops = &patch_wolfson_wm9703_ops;
442 return 0; 430 return 0;
@@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
467 .build_specific = patch_wolfson_wm9704_specific, 455 .build_specific = patch_wolfson_wm9704_specific,
468}; 456};
469 457
470int patch_wolfson04(struct snd_ac97 * ac97) 458static int patch_wolfson04(struct snd_ac97 * ac97)
471{ 459{
472 /* WM9704M/9704Q */ 460 /* WM9704M/9704Q */
473 ac97->build_ops = &patch_wolfson_wm9704_ops; 461 ac97->build_ops = &patch_wolfson_wm9704_ops;
@@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
489 .build_specific = patch_wolfson_wm9705_specific, 477 .build_specific = patch_wolfson_wm9705_specific,
490}; 478};
491 479
492int patch_wolfson05(struct snd_ac97 * ac97) 480static int patch_wolfson05(struct snd_ac97 * ac97)
493{ 481{
494 /* WM9705, WM9710 */ 482 /* WM9705, WM9710 */
495 ac97->build_ops = &patch_wolfson_wm9705_ops; 483 ac97->build_ops = &patch_wolfson_wm9705_ops;
@@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
625 .build_specific = patch_wolfson_wm9711_specific, 613 .build_specific = patch_wolfson_wm9711_specific,
626}; 614};
627 615
628int patch_wolfson11(struct snd_ac97 * ac97) 616static int patch_wolfson11(struct snd_ac97 * ac97)
629{ 617{
630 /* WM9711, WM9712 */ 618 /* WM9711, WM9712 */
631 ac97->build_ops = &patch_wolfson_wm9711_ops; 619 ac97->build_ops = &patch_wolfson_wm9711_ops;
@@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
824#endif 812#endif
825}; 813};
826 814
827int patch_wolfson13(struct snd_ac97 * ac97) 815static int patch_wolfson13(struct snd_ac97 * ac97)
828{ 816{
829 /* WM9713, WM9714 */ 817 /* WM9713, WM9714 */
830 ac97->build_ops = &patch_wolfson_wm9713_ops; 818 ac97->build_ops = &patch_wolfson_wm9713_ops;
@@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97)
844/* 832/*
845 * Tritech codec 833 * Tritech codec
846 */ 834 */
847int patch_tritech_tr28028(struct snd_ac97 * ac97) 835static int patch_tritech_tr28028(struct snd_ac97 * ac97)
848{ 836{
849 snd_ac97_write_cache(ac97, 0x26, 0x0300); 837 snd_ac97_write_cache(ac97, 0x26, 0x0300);
850 snd_ac97_write_cache(ac97, 0x26, 0x0000); 838 snd_ac97_write_cache(ac97, 0x26, 0x0000);
@@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
922 .build_specific = patch_sigmatel_stac97xx_specific 910 .build_specific = patch_sigmatel_stac97xx_specific
923}; 911};
924 912
925int patch_sigmatel_stac9700(struct snd_ac97 * ac97) 913static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
926{ 914{
927 ac97->build_ops = &patch_sigmatel_stac9700_ops; 915 ac97->build_ops = &patch_sigmatel_stac9700_ops;
928 return 0; 916 return 0;
@@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
969 .build_specific = patch_sigmatel_stac9708_specific 957 .build_specific = patch_sigmatel_stac9708_specific
970}; 958};
971 959
972int patch_sigmatel_stac9708(struct snd_ac97 * ac97) 960static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
973{ 961{
974 unsigned int codec72, codec6c; 962 unsigned int codec72, codec6c;
975 963
@@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
995 return 0; 983 return 0;
996} 984}
997 985
998int patch_sigmatel_stac9721(struct snd_ac97 * ac97) 986static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
999{ 987{
1000 ac97->build_ops = &patch_sigmatel_stac9700_ops; 988 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1001 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { 989 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
@@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
1009 return 0; 997 return 0;
1010} 998}
1011 999
1012int patch_sigmatel_stac9744(struct snd_ac97 * ac97) 1000static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
1013{ 1001{
1014 // patch for SigmaTel 1002 // patch for SigmaTel
1015 ac97->build_ops = &patch_sigmatel_stac9700_ops; 1003 ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
1021 return 0; 1009 return 0;
1022} 1010}
1023 1011
1024int patch_sigmatel_stac9756(struct snd_ac97 * ac97) 1012static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
1025{ 1013{
1026 // patch for SigmaTel 1014 // patch for SigmaTel
1027 ac97->build_ops = &patch_sigmatel_stac9700_ops; 1015 ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
1198 .build_specific = patch_sigmatel_stac9758_specific 1186 .build_specific = patch_sigmatel_stac9758_specific
1199}; 1187};
1200 1188
1201int patch_sigmatel_stac9758(struct snd_ac97 * ac97) 1189static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
1202{ 1190{
1203 static unsigned short regs[4] = { 1191 static unsigned short regs[4] = {
1204 AC97_SIGMATEL_OUTSEL, 1192 AC97_SIGMATEL_OUTSEL,
@@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = {
1272 .build_spdif = patch_cirrus_build_spdif 1260 .build_spdif = patch_cirrus_build_spdif
1273}; 1261};
1274 1262
1275int patch_cirrus_spdif(struct snd_ac97 * ac97) 1263static int patch_cirrus_spdif(struct snd_ac97 * ac97)
1276{ 1264{
1277 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. 1265 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
1278 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* 1266 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
@@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97)
1293 return 0; 1281 return 0;
1294} 1282}
1295 1283
1296int patch_cirrus_cs4299(struct snd_ac97 * ac97) 1284static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
1297{ 1285{
1298 /* force the detection of PC Beep */ 1286 /* force the detection of PC Beep */
1299 ac97->flags |= AC97_HAS_PC_BEEP; 1287 ac97->flags |= AC97_HAS_PC_BEEP;
@@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = {
1329 .build_spdif = patch_conexant_build_spdif 1317 .build_spdif = patch_conexant_build_spdif
1330}; 1318};
1331 1319
1332int patch_conexant(struct snd_ac97 * ac97) 1320static int patch_conexant(struct snd_ac97 * ac97)
1333{ 1321{
1334 ac97->build_ops = &patch_conexant_ops; 1322 ac97->build_ops = &patch_conexant_ops;
1335 ac97->flags |= AC97_CX_SPDIF; 1323 ac97->flags |= AC97_CX_SPDIF;
@@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97)
1338 return 0; 1326 return 0;
1339} 1327}
1340 1328
1341int patch_cx20551(struct snd_ac97 *ac97) 1329static int patch_cx20551(struct snd_ac97 *ac97)
1342{ 1330{
1343 snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); 1331 snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
1344 return 0; 1332 return 0;
@@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = {
1430 { } /* terminator */ 1418 { } /* terminator */
1431}; 1419};
1432 1420
1433int patch_ad1819(struct snd_ac97 * ac97) 1421static int patch_ad1819(struct snd_ac97 * ac97)
1434{ 1422{
1435 unsigned short scfg; 1423 unsigned short scfg;
1436 1424
@@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = {
1507#endif 1495#endif
1508}; 1496};
1509 1497
1510int patch_ad1881(struct snd_ac97 * ac97) 1498static int patch_ad1881(struct snd_ac97 * ac97)
1511{ 1499{
1512 static const char cfg_idxs[3][2] = { 1500 static const char cfg_idxs[3][2] = {
1513 {2, 1}, 1501 {2, 1},
@@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = {
1595#endif 1583#endif
1596}; 1584};
1597 1585
1598int patch_ad1885(struct snd_ac97 * ac97) 1586static int patch_ad1885(struct snd_ac97 * ac97)
1599{ 1587{
1600 patch_ad1881(ac97); 1588 patch_ad1881(ac97);
1601 /* This is required to deal with the Intel D815EEAL2 */ 1589 /* This is required to deal with the Intel D815EEAL2 */
@@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = {
1622#endif 1610#endif
1623}; 1611};
1624 1612
1625int patch_ad1886(struct snd_ac97 * ac97) 1613static int patch_ad1886(struct snd_ac97 * ac97)
1626{ 1614{
1627 patch_ad1881(ac97); 1615 patch_ad1881(ac97);
1628 /* Presario700 workaround */ 1616 /* Presario700 workaround */
@@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
1844 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); 1832 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
1845} 1833}
1846 1834
1847int patch_ad1981a(struct snd_ac97 *ac97) 1835static int patch_ad1981a(struct snd_ac97 *ac97)
1848{ 1836{
1849 patch_ad1881(ac97); 1837 patch_ad1881(ac97);
1850 ac97->build_ops = &patch_ad1981a_build_ops; 1838 ac97->build_ops = &patch_ad1981a_build_ops;
@@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1877#endif 1865#endif
1878}; 1866};
1879 1867
1880int patch_ad1981b(struct snd_ac97 *ac97) 1868static int patch_ad1981b(struct snd_ac97 *ac97)
1881{ 1869{
1882 patch_ad1881(ac97); 1870 patch_ad1881(ac97);
1883 ac97->build_ops = &patch_ad1981b_build_ops; 1871 ac97->build_ops = &patch_ad1981b_build_ops;
@@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
2014 .update_jacks = ad1888_update_jacks, 2002 .update_jacks = ad1888_update_jacks,
2015}; 2003};
2016 2004
2017int patch_ad1888(struct snd_ac97 * ac97) 2005static int patch_ad1888(struct snd_ac97 * ac97)
2018{ 2006{
2019 unsigned short misc; 2007 unsigned short misc;
2020 2008
@@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
2052 .update_jacks = ad1888_update_jacks, 2040 .update_jacks = ad1888_update_jacks,
2053}; 2041};
2054 2042
2055int patch_ad1980(struct snd_ac97 * ac97) 2043static int patch_ad1980(struct snd_ac97 * ac97)
2056{ 2044{
2057 patch_ad1888(ac97); 2045 patch_ad1888(ac97);
2058 ac97->build_ops = &patch_ad1980_build_ops; 2046 ac97->build_ops = &patch_ad1980_build_ops;
@@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
2168 .update_jacks = ad1985_update_jacks, 2156 .update_jacks = ad1985_update_jacks,
2169}; 2157};
2170 2158
2171int patch_ad1985(struct snd_ac97 * ac97) 2159static int patch_ad1985(struct snd_ac97 * ac97)
2172{ 2160{
2173 unsigned short misc; 2161 unsigned short misc;
2174 2162
@@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = {
2468 .update_jacks = ad1986_update_jacks, 2456 .update_jacks = ad1986_update_jacks,
2469}; 2457};
2470 2458
2471int patch_ad1986(struct snd_ac97 * ac97) 2459static int patch_ad1986(struct snd_ac97 * ac97)
2472{ 2460{
2473 patch_ad1881(ac97); 2461 patch_ad1881(ac97);
2474 ac97->build_ops = &patch_ad1986_build_ops; 2462 ac97->build_ops = &patch_ad1986_build_ops;
@@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
2561 .update_jacks = alc650_update_jacks 2549 .update_jacks = alc650_update_jacks
2562}; 2550};
2563 2551
2564int patch_alc650(struct snd_ac97 * ac97) 2552static int patch_alc650(struct snd_ac97 * ac97)
2565{ 2553{
2566 unsigned short val; 2554 unsigned short val;
2567 2555
@@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = {
2713 .update_jacks = alc655_update_jacks 2701 .update_jacks = alc655_update_jacks
2714}; 2702};
2715 2703
2716int patch_alc655(struct snd_ac97 * ac97) 2704static int patch_alc655(struct snd_ac97 * ac97)
2717{ 2705{
2718 unsigned int val; 2706 unsigned int val;
2719 2707
@@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97)
2739 (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ 2727 (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
2740 ac97->subsystem_device == 0x0161 || /* LG K1 Express */ 2728 ac97->subsystem_device == 0x0161 || /* LG K1 Express */
2741 ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ 2729 ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
2730 ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
2742 ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ 2731 ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */
2743 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2732 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2744 else 2733 else
@@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = {
2815 .update_jacks = alc850_update_jacks 2804 .update_jacks = alc850_update_jacks
2816}; 2805};
2817 2806
2818int patch_alc850(struct snd_ac97 *ac97) 2807static int patch_alc850(struct snd_ac97 *ac97)
2819{ 2808{
2820 ac97->build_ops = &patch_alc850_ops; 2809 ac97->build_ops = &patch_alc850_ops;
2821 2810
@@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = {
2875 .update_jacks = cm9738_update_jacks 2864 .update_jacks = cm9738_update_jacks
2876}; 2865};
2877 2866
2878int patch_cm9738(struct snd_ac97 * ac97) 2867static int patch_cm9738(struct snd_ac97 * ac97)
2879{ 2868{
2880 ac97->build_ops = &patch_cm9738_ops; 2869 ac97->build_ops = &patch_cm9738_ops;
2881 /* FIXME: can anyone confirm below? */ 2870 /* FIXME: can anyone confirm below? */
@@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = {
2967 .update_jacks = cm9739_update_jacks 2956 .update_jacks = cm9739_update_jacks
2968}; 2957};
2969 2958
2970int patch_cm9739(struct snd_ac97 * ac97) 2959static int patch_cm9739(struct snd_ac97 * ac97)
2971{ 2960{
2972 unsigned short val; 2961 unsigned short val;
2973 2962
@@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = {
3141 .update_jacks = cm9761_update_jacks 3130 .update_jacks = cm9761_update_jacks
3142}; 3131};
3143 3132
3144int patch_cm9761(struct snd_ac97 *ac97) 3133static int patch_cm9761(struct snd_ac97 *ac97)
3145{ 3134{
3146 unsigned short val; 3135 unsigned short val;
3147 3136
@@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = {
3236 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ 3225 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
3237}; 3226};
3238 3227
3239int patch_cm9780(struct snd_ac97 *ac97) 3228static int patch_cm9780(struct snd_ac97 *ac97)
3240{ 3229{
3241 unsigned short val; 3230 unsigned short val;
3242 3231
@@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = {
3279 .build_specific = patch_vt1616_specific 3268 .build_specific = patch_vt1616_specific
3280}; 3269};
3281 3270
3282int patch_vt1616(struct snd_ac97 * ac97) 3271static int patch_vt1616(struct snd_ac97 * ac97)
3283{ 3272{
3284 ac97->build_ops = &patch_vt1616_ops; 3273 ac97->build_ops = &patch_vt1616_ops;
3285 return 0; 3274 return 0;
@@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97)
3288/* 3277/*
3289 * VT1617A codec 3278 * VT1617A codec
3290 */ 3279 */
3280
3281/*
3282 * unfortunately, the vt1617a stashes the twiddlers required for
3283 * nooding the i/o jacks on 2 different regs. * thameans that we cant
3284 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3285 * are own funcs.
3286 *
3287 * NB: this is absolutely and utterly different from the vt1618. dunno
3288 * about the 1616.
3289 */
3290
3291/* copied from ac97_surround_jack_mode_info() */
3292static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
3293 struct snd_ctl_elem_info *uinfo)
3294{
3295 /* ordering in this list reflects vt1617a docs for Reg 20 and
3296 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
3297 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
3298 * counter-intuitive */
3299
3300 static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
3301 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3302 "LineIn Mic2", "LineIn Mic2 Mic1",
3303 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3304 return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
3305}
3306
3307static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3308 struct snd_ctl_elem_value *ucontrol)
3309{
3310 ushort usSM51, usMS;
3311
3312 struct snd_ac97 *pac97;
3313
3314 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3315
3316 /* grab our desirec bits, then mash them together in a manner
3317 * consistent with Table 6 on page 17 in the 1617a docs */
3318
3319 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
3320 usMS = snd_ac97_read(pac97, 0x20) >> 8;
3321
3322 ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
3323
3324 return 0;
3325}
3326
3327static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
3328 struct snd_ctl_elem_value *ucontrol)
3329{
3330 ushort usSM51, usMS, usReg;
3331
3332 struct snd_ac97 *pac97;
3333
3334 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3335
3336 usSM51 = ucontrol->value.enumerated.item[0] >> 1;
3337 usMS = ucontrol->value.enumerated.item[0] & 1;
3338
3339 /* push our values into the register - consider that things will be left
3340 * in a funky state if the write fails */
3341
3342 usReg = snd_ac97_read(pac97, 0x7a);
3343 snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
3344 usReg = snd_ac97_read(pac97, 0x20);
3345 snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
3346
3347 return 0;
3348}
3349
3350static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
3351
3352 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3353 /*
3354 * These are used to enable/disable surround sound on motherboards
3355 * that have 3 bidirectional analog jacks
3356 */
3357 {
3358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3359 .name = "Smart 5.1 Select",
3360 .info = snd_ac97_vt1617a_smart51_info,
3361 .get = snd_ac97_vt1617a_smart51_get,
3362 .put = snd_ac97_vt1617a_smart51_put,
3363 },
3364};
3365
3291int patch_vt1617a(struct snd_ac97 * ac97) 3366int patch_vt1617a(struct snd_ac97 * ac97)
3292{ 3367{
3293 /* bring analog power consumption to normal, like WinXP driver 3368 int err = 0;
3294 * for EPIA SP 3369
3370 /* we choose to not fail out at this point, but we tell the
3371 caller when we return */
3372
3373 err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
3374 ARRAY_SIZE(snd_ac97_controls_vt1617a));
3375
3376 /* bring analog power consumption to normal by turning off the
3377 * headphone amplifier, like WinXP driver for EPIA SP
3295 */ 3378 */
3296 snd_ac97_write_cache(ac97, 0x5c, 0x20); 3379 snd_ac97_write_cache(ac97, 0x5c, 0x20);
3297 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 3380 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
3298 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 3381 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
3299 ac97->build_ops = &patch_vt1616_ops; 3382 ac97->build_ops = &patch_vt1616_ops;
3300 return 0; 3383
3384 return err;
3301} 3385}
3302 3386
3303/* 3387/*
@@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = {
3338 .update_jacks = it2646_update_jacks 3422 .update_jacks = it2646_update_jacks
3339}; 3423};
3340 3424
3341int patch_it2646(struct snd_ac97 * ac97) 3425static int patch_it2646(struct snd_ac97 * ac97)
3342{ 3426{
3343 ac97->build_ops = &patch_it2646_ops; 3427 ac97->build_ops = &patch_it2646_ops;
3344 /* full DAC volume */ 3428 /* full DAC volume */
@@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = {
3371 .build_specific = patch_si3036_specific, 3455 .build_specific = patch_si3036_specific,
3372}; 3456};
3373 3457
3374int mpatch_si3036(struct snd_ac97 * ac97) 3458static int mpatch_si3036(struct snd_ac97 * ac97)
3375{ 3459{
3376 ac97->build_ops = &patch_si3036_ops; 3460 ac97->build_ops = &patch_si3036_ops;
3377 snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); 3461 snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
@@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = {
3403 { } /* terminator */ 3487 { } /* terminator */
3404}; 3488};
3405 3489
3406int patch_lm4550(struct snd_ac97 *ac97) 3490static int patch_lm4550(struct snd_ac97 *ac97)
3407{ 3491{
3408 ac97->res_table = lm4550_restbl; 3492 ac97->res_table = lm4550_restbl;
3409 return 0; 3493 return 0;
@@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = {
3438 .build_specific = patch_ucb1400_specific, 3522 .build_specific = patch_ucb1400_specific,
3439}; 3523};
3440 3524
3441int patch_ucb1400(struct snd_ac97 * ac97) 3525static int patch_ucb1400(struct snd_ac97 * ac97)
3442{ 3526{
3443 ac97->build_ops = &patch_ucb1400_ops; 3527 ac97->build_ops = &patch_ucb1400_ops;
3444 /* enable headphone driver and smart low power mode by default */ 3528 /* enable headphone driver and smart low power mode by default */