diff options
Diffstat (limited to 'sound/pci/ac97/ac97_patch.c')
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 194 |
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 | ||
393 | int patch_yamaha_ymf753(struct snd_ac97 * ac97) | 381 | static 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 | ||
439 | int patch_wolfson03(struct snd_ac97 * ac97) | 427 | static 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 | ||
470 | int patch_wolfson04(struct snd_ac97 * ac97) | 458 | static 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 | ||
492 | int patch_wolfson05(struct snd_ac97 * ac97) | 480 | static 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 | ||
628 | int patch_wolfson11(struct snd_ac97 * ac97) | 616 | static 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 | ||
827 | int patch_wolfson13(struct snd_ac97 * ac97) | 815 | static 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 | */ |
847 | int patch_tritech_tr28028(struct snd_ac97 * ac97) | 835 | static 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 | ||
925 | int patch_sigmatel_stac9700(struct snd_ac97 * ac97) | 913 | static 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 | ||
972 | int patch_sigmatel_stac9708(struct snd_ac97 * ac97) | 960 | static 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 | ||
998 | int patch_sigmatel_stac9721(struct snd_ac97 * ac97) | 986 | static 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 | ||
1012 | int patch_sigmatel_stac9744(struct snd_ac97 * ac97) | 1000 | static 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 | ||
1024 | int patch_sigmatel_stac9756(struct snd_ac97 * ac97) | 1012 | static 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 | ||
1201 | int patch_sigmatel_stac9758(struct snd_ac97 * ac97) | 1189 | static 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 | ||
1275 | int patch_cirrus_spdif(struct snd_ac97 * ac97) | 1263 | static 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 | ||
1296 | int patch_cirrus_cs4299(struct snd_ac97 * ac97) | 1284 | static 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 | ||
1332 | int patch_conexant(struct snd_ac97 * ac97) | 1320 | static 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 | ||
1341 | int patch_cx20551(struct snd_ac97 *ac97) | 1329 | static 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 | ||
1433 | int patch_ad1819(struct snd_ac97 * ac97) | 1421 | static 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 | ||
1510 | int patch_ad1881(struct snd_ac97 * ac97) | 1498 | static 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 | ||
1598 | int patch_ad1885(struct snd_ac97 * ac97) | 1586 | static 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 | ||
1625 | int patch_ad1886(struct snd_ac97 * ac97) | 1613 | static 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 | ||
1847 | int patch_ad1981a(struct snd_ac97 *ac97) | 1835 | static 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 | ||
1880 | int patch_ad1981b(struct snd_ac97 *ac97) | 1868 | static 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 | ||
2017 | int patch_ad1888(struct snd_ac97 * ac97) | 2005 | static 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 | ||
2055 | int patch_ad1980(struct snd_ac97 * ac97) | 2043 | static 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 | ||
2171 | int patch_ad1985(struct snd_ac97 * ac97) | 2159 | static 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 | ||
2471 | int patch_ad1986(struct snd_ac97 * ac97) | 2459 | static 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 | ||
2564 | int patch_alc650(struct snd_ac97 * ac97) | 2552 | static 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 | ||
2716 | int patch_alc655(struct snd_ac97 * ac97) | 2704 | static 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 | ||
2818 | int patch_alc850(struct snd_ac97 *ac97) | 2807 | static 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 | ||
2878 | int patch_cm9738(struct snd_ac97 * ac97) | 2867 | static 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 | ||
2970 | int patch_cm9739(struct snd_ac97 * ac97) | 2959 | static 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 | ||
3144 | int patch_cm9761(struct snd_ac97 *ac97) | 3133 | static 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 | ||
3239 | int patch_cm9780(struct snd_ac97 *ac97) | 3228 | static 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 | ||
3282 | int patch_vt1616(struct snd_ac97 * ac97) | 3271 | static 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() */ | ||
3292 | static 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 | |||
3307 | static 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 | |||
3327 | static 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 | |||
3350 | static 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 | |||
3291 | int patch_vt1617a(struct snd_ac97 * ac97) | 3366 | int 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 | ||
3341 | int patch_it2646(struct snd_ac97 * ac97) | 3425 | static 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 | ||
3374 | int mpatch_si3036(struct snd_ac97 * ac97) | 3458 | static 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 | ||
3406 | int patch_lm4550(struct snd_ac97 *ac97) | 3490 | static 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 | ||
3441 | int patch_ucb1400(struct snd_ac97 * ac97) | 3525 | static 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 */ |