diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-03-16 02:50:49 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-03-16 02:50:49 -0400 |
commit | a9104f989916aac5d92bfa2c51915d5985fb2e6c (patch) | |
tree | 17bef4eac561e3ac90d98d68190978e686712b67 /sound/pci | |
parent | ad6cfc2ac71180171e090e69ae8762ac511884b1 (diff) | |
parent | 89c0ac7cab2440a771ba1e2ab953186bc9c29786 (diff) |
Merge branch 'topic/misc' into fix/misc
Diffstat (limited to 'sound/pci')
112 files changed, 2895 insertions, 629 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 351654cf7b09..1298c68d6bf0 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -789,6 +789,7 @@ config SND_VIRTUOSO | |||
789 | Say Y here to include support for sound cards based on the | 789 | Say Y here to include support for sound cards based on the |
790 | Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, | 790 | Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, |
791 | Essence ST (Deluxe), and Essence STX. | 791 | Essence ST (Deluxe), and Essence STX. |
792 | Support for the DS is experimental. | ||
792 | Support for the HDAV1.3 (Deluxe) is very experimental. | 793 | Support for the HDAV1.3 (Deluxe) is very experimental. |
793 | 794 | ||
794 | To compile this driver as a module, choose M here: the module | 795 | To compile this driver as a module, choose M here: the module |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index d9266bae2849..1caf5e3c1f6a 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -544,25 +544,10 @@ static int patch_wolfson04(struct snd_ac97 * ac97) | |||
544 | return 0; | 544 | return 0; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97) | ||
548 | { | ||
549 | int err, i; | ||
550 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
551 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
552 | return err; | ||
553 | } | ||
554 | snd_ac97_write_cache(ac97, 0x72, 0x0808); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { | ||
559 | .build_specific = patch_wolfson_wm9705_specific, | ||
560 | }; | ||
561 | |||
562 | static int patch_wolfson05(struct snd_ac97 * ac97) | 547 | static int patch_wolfson05(struct snd_ac97 * ac97) |
563 | { | 548 | { |
564 | /* WM9705, WM9710 */ | 549 | /* WM9705, WM9710 */ |
565 | ac97->build_ops = &patch_wolfson_wm9705_ops; | 550 | ac97->build_ops = &patch_wolfson_wm9703_ops; |
566 | #ifdef CONFIG_TOUCHSCREEN_WM9705 | 551 | #ifdef CONFIG_TOUCHSCREEN_WM9705 |
567 | /* WM9705 touchscreen uses AUX and VIDEO for touch */ | 552 | /* WM9705 touchscreen uses AUX and VIDEO for touch */ |
568 | ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; | 553 | ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 8f5098f92c37..4382d0fa6b9a 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -1048,7 +1048,7 @@ snd_ad1889_remove(struct pci_dev *pci) | |||
1048 | pci_set_drvdata(pci, NULL); | 1048 | pci_set_drvdata(pci, NULL); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static struct pci_device_id snd_ad1889_ids[] = { | 1051 | static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = { |
1052 | { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, | 1052 | { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, |
1053 | { 0, }, | 1053 | { 0, }, |
1054 | }; | 1054 | }; |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index aaf4da68969c..5c6e322a48f0 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -275,7 +275,7 @@ struct snd_ali { | |||
275 | #endif | 275 | #endif |
276 | }; | 276 | }; |
277 | 277 | ||
278 | static struct pci_device_id snd_ali_ids[] = { | 278 | static DEFINE_PCI_DEVICE_TABLE(snd_ali_ids) = { |
279 | {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, | 279 | {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, |
280 | {0, } | 280 | {0, } |
281 | }; | 281 | }; |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 3aa35af7ca91..d7653cb7ac60 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -145,7 +145,7 @@ struct snd_als300_substream_data { | |||
145 | int block_counter_register; | 145 | int block_counter_register; |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static struct pci_device_id snd_als300_ids[] = { | 148 | static DEFINE_PCI_DEVICE_TABLE(snd_als300_ids) = { |
149 | { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 }, | 149 | { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 }, |
150 | { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS }, | 150 | { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS }, |
151 | { 0, } | 151 | { 0, } |
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 3dbacde1a5af..d75cf7b06426 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -117,7 +117,7 @@ struct snd_card_als4000 { | |||
117 | #endif | 117 | #endif |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static struct pci_device_id snd_als4000_ids[] = { | 120 | static DEFINE_PCI_DEVICE_TABLE(snd_als4000_ids) = { |
121 | { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */ | 121 | { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */ |
122 | { 0, } | 122 | { 0, } |
123 | }; | 123 | }; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 42b4fbbd8e2b..49d572a7b235 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -286,7 +286,7 @@ struct atiixp { | |||
286 | 286 | ||
287 | /* | 287 | /* |
288 | */ | 288 | */ |
289 | static struct pci_device_id snd_atiixp_ids[] = { | 289 | static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = { |
290 | { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ | 290 | { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ |
291 | { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ | 291 | { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ |
292 | { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ | 292 | { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index e7e147bf8eb2..91d7036b6411 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -261,7 +261,7 @@ struct atiixp_modem { | |||
261 | 261 | ||
262 | /* | 262 | /* |
263 | */ | 263 | */ |
264 | static struct pci_device_id snd_atiixp_ids[] = { | 264 | static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = { |
265 | { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */ | 265 | { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */ |
266 | { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */ | 266 | { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */ |
267 | { 0, } | 267 | { 0, } |
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c index c0e8c6b295cb..aa51cc7771dd 100644 --- a/sound/pci/au88x0/au8810.c +++ b/sound/pci/au88x0/au8810.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include "au8810.h" | 1 | #include "au8810.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = { |
4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,}, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,}, |
5 | {0,} | 5 | {0,} |
6 | }; | 6 | }; |
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c index a6527330df58..2f321e7306cd 100644 --- a/sound/pci/au88x0/au8820.c +++ b/sound/pci/au88x0/au8820.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include "au8820.h" | 1 | #include "au8820.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = { |
4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,}, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,}, |
5 | {0,} | 5 | {0,} |
6 | }; | 6 | }; |
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c index 6c702ad4352a..279b78f06d22 100644 --- a/sound/pci/au88x0/au8830.c +++ b/sound/pci/au88x0/au8830.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include "au8830.h" | 1 | #include "au8830.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = { |
4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,}, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,}, |
5 | {0,} | 5 | {0,} |
6 | }; | 6 | }; |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 4d34bb0d99d3..67921f93a41e 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard."); | |||
164 | module_param_array(enable, bool, NULL, 0444); | 164 | module_param_array(enable, bool, NULL, 0444); |
165 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); | 165 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); |
166 | 166 | ||
167 | static struct pci_device_id snd_aw2_ids[] = { | 167 | static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { |
168 | {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, | 168 | {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, |
169 | 0, 0, 0}, | 169 | 0, 0, 0}, |
170 | {0} | 170 | {0} |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 69867ace7860..4679ed83a43b 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -350,7 +350,7 @@ struct snd_azf3328 { | |||
350 | #endif | 350 | #endif |
351 | }; | 351 | }; |
352 | 352 | ||
353 | static const struct pci_device_id snd_azf3328_ids[] = { | 353 | static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = { |
354 | { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */ | 354 | { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */ |
355 | { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */ | 355 | { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */ |
356 | { 0, } | 356 | { 0, } |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 4e2b925a94cc..37e1b5df5ab8 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -795,7 +795,7 @@ fail: | |||
795 | .driver_data = SND_BT87X_BOARD_ ## id } | 795 | .driver_data = SND_BT87X_BOARD_ ## id } |
796 | /* driver_data is the card id for that device */ | 796 | /* driver_data is the card id for that device */ |
797 | 797 | ||
798 | static struct pci_device_id snd_bt87x_ids[] = { | 798 | static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_ids) = { |
799 | /* Hauppauge WinTV series */ | 799 | /* Hauppauge WinTV series */ |
800 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), | 800 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), |
801 | /* Hauppauge WinTV series */ | 801 | /* Hauppauge WinTV series */ |
@@ -964,7 +964,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci) | |||
964 | 964 | ||
965 | /* default entries for all Bt87x cards - it's not exported */ | 965 | /* default entries for all Bt87x cards - it's not exported */ |
966 | /* driver_data is set to 0 to call detection */ | 966 | /* driver_data is set to 0 to call detection */ |
967 | static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { | 967 | static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = { |
968 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), | 968 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), |
969 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), | 969 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), |
970 | { } | 970 | { } |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 15e4138bce17..0a3d3d6e77b4 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1875,7 +1875,7 @@ static int snd_ca0106_resume(struct pci_dev *pci) | |||
1875 | #endif | 1875 | #endif |
1876 | 1876 | ||
1877 | // PCI IDs | 1877 | // PCI IDs |
1878 | static struct pci_device_id snd_ca0106_ids[] = { | 1878 | static DEFINE_PCI_DEVICE_TABLE(snd_ca0106_ids) = { |
1879 | { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */ | 1879 | { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */ |
1880 | { 0, } | 1880 | { 0, } |
1881 | }; | 1881 | }; |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index a312bae08f52..1ded64e05643 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -2796,7 +2796,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {} | |||
2796 | #endif | 2796 | #endif |
2797 | 2797 | ||
2798 | 2798 | ||
2799 | static struct pci_device_id snd_cmipci_ids[] = { | 2799 | static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = { |
2800 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, | 2800 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, |
2801 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, | 2801 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, |
2802 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, | 2802 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, |
@@ -3018,7 +3018,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc | |||
3018 | int integrated_midi = 0; | 3018 | int integrated_midi = 0; |
3019 | char modelstr[16]; | 3019 | char modelstr[16]; |
3020 | int pcm_index, pcm_spdif_index; | 3020 | int pcm_index, pcm_spdif_index; |
3021 | static struct pci_device_id intel_82437vx[] = { | 3021 | static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = { |
3022 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, | 3022 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, |
3023 | { }, | 3023 | { }, |
3024 | }; | 3024 | }; |
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index e2e0359bb056..9edc65059e3e 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -494,7 +494,7 @@ struct cs4281 { | |||
494 | 494 | ||
495 | static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); | 495 | static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); |
496 | 496 | ||
497 | static struct pci_device_id snd_cs4281_ids[] = { | 497 | static DEFINE_PCI_DEVICE_TABLE(snd_cs4281_ids) = { |
498 | { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */ | 498 | { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */ |
499 | { 0, } | 499 | { 0, } |
500 | }; | 500 | }; |
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index 033aec430117..767fa7f06cd0 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c | |||
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control."); | |||
64 | module_param_array(mmap_valid, bool, NULL, 0444); | 64 | module_param_array(mmap_valid, bool, NULL, 0444); |
65 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); | 65 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); |
66 | 66 | ||
67 | static struct pci_device_id snd_cs46xx_ids[] = { | 67 | static DEFINE_PCI_DEVICE_TABLE(snd_cs46xx_ids) = { |
68 | { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */ | 68 | { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */ |
69 | { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */ | 69 | { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */ |
70 | { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */ | 70 | { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */ |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 1be96ead4244..3f99a5e8528c 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -2238,11 +2238,11 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97) | |||
2238 | 2238 | ||
2239 | /* set the desired CODEC mode */ | 2239 | /* set the desired CODEC mode */ |
2240 | if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { | 2240 | if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { |
2241 | snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); | 2241 | snd_printdd("cs46xx: CODEC1 mode %04x\n", 0x0); |
2242 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); | 2242 | snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0); |
2243 | } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { | 2243 | } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { |
2244 | snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); | 2244 | snd_printdd("cs46xx: CODEC2 mode %04x\n", 0x3); |
2245 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); | 2245 | snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3); |
2246 | } else { | 2246 | } else { |
2247 | snd_BUG(); /* should never happen ... */ | 2247 | snd_BUG(); /* should never happen ... */ |
2248 | } | 2248 | } |
@@ -2266,7 +2266,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97) | |||
2266 | return; | 2266 | return; |
2267 | 2267 | ||
2268 | /* test if we can write to the record gain volume register */ | 2268 | /* test if we can write to the record gain volume register */ |
2269 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); | 2269 | snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05); |
2270 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) | 2270 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) |
2271 | return; | 2271 | return; |
2272 | 2272 | ||
@@ -3597,7 +3597,7 @@ static struct cs_card_type __devinitdata cards[] = { | |||
3597 | #ifdef CONFIG_PM | 3597 | #ifdef CONFIG_PM |
3598 | static unsigned int saved_regs[] = { | 3598 | static unsigned int saved_regs[] = { |
3599 | BA0_ACOSV, | 3599 | BA0_ACOSV, |
3600 | BA0_ASER_FADDR, | 3600 | /*BA0_ASER_FADDR,*/ |
3601 | BA0_ASER_MASTER, | 3601 | BA0_ASER_MASTER, |
3602 | BA1_PVOL, | 3602 | BA1_PVOL, |
3603 | BA1_CVOL, | 3603 | BA1_CVOL, |
@@ -3644,6 +3644,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) | |||
3644 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3644 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3645 | int i; | 3645 | int i; |
3646 | #endif | 3646 | #endif |
3647 | unsigned int tmp; | ||
3647 | 3648 | ||
3648 | pci_set_power_state(pci, PCI_D0); | 3649 | pci_set_power_state(pci, PCI_D0); |
3649 | pci_restore_state(pci); | 3650 | pci_restore_state(pci); |
@@ -3685,6 +3686,15 @@ int snd_cs46xx_resume(struct pci_dev *pci) | |||
3685 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); | 3686 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3686 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | 3687 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); |
3687 | 3688 | ||
3689 | /* | ||
3690 | * Stop capture DMA. | ||
3691 | */ | ||
3692 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); | ||
3693 | chip->capt.ctl = tmp & 0x0000ffff; | ||
3694 | snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); | ||
3695 | |||
3696 | mdelay(5); | ||
3697 | |||
3688 | /* reset playback/capture */ | 3698 | /* reset playback/capture */ |
3689 | snd_cs46xx_set_play_sample_rate(chip, 8000); | 3699 | snd_cs46xx_set_play_sample_rate(chip, 8000); |
3690 | snd_cs46xx_set_capture_sample_rate(chip, 8000); | 3700 | snd_cs46xx_set_capture_sample_rate(chip, 8000); |
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index f4f0c8f5dad7..3e5ca8fb519f 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c | |||
@@ -298,6 +298,9 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) | |||
298 | if (ins->scbs[i].deleted) continue; | 298 | if (ins->scbs[i].deleted) continue; |
299 | 299 | ||
300 | cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); | 300 | cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); |
301 | #ifdef CONFIG_PM | ||
302 | kfree(ins->scbs[i].data); | ||
303 | #endif | ||
301 | } | 304 | } |
302 | 305 | ||
303 | kfree(ins->code.data); | 306 | kfree(ins->code.data); |
@@ -974,13 +977,11 @@ static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * nam | |||
974 | 977 | ||
975 | index = find_free_scb_index (ins); | 978 | index = find_free_scb_index (ins); |
976 | 979 | ||
980 | memset(&ins->scbs[index], 0, sizeof(ins->scbs[index])); | ||
977 | strcpy(ins->scbs[index].scb_name, name); | 981 | strcpy(ins->scbs[index].scb_name, name); |
978 | ins->scbs[index].address = dest; | 982 | ins->scbs[index].address = dest; |
979 | ins->scbs[index].index = index; | 983 | ins->scbs[index].index = index; |
980 | ins->scbs[index].proc_info = NULL; | ||
981 | ins->scbs[index].ref_count = 1; | 984 | ins->scbs[index].ref_count = 1; |
982 | ins->scbs[index].deleted = 0; | ||
983 | spin_lock_init(&ins->scbs[index].lock); | ||
984 | 985 | ||
985 | desc = (ins->scbs + index); | 986 | desc = (ins->scbs + index); |
986 | ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); | 987 | ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); |
@@ -1022,17 +1023,29 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) | |||
1022 | return desc; | 1023 | return desc; |
1023 | } | 1024 | } |
1024 | 1025 | ||
1026 | #define SCB_BYTES (0x10 * 4) | ||
1027 | |||
1025 | struct dsp_scb_descriptor * | 1028 | struct dsp_scb_descriptor * |
1026 | cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest) | 1029 | cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest) |
1027 | { | 1030 | { |
1028 | struct dsp_scb_descriptor * desc; | 1031 | struct dsp_scb_descriptor * desc; |
1029 | 1032 | ||
1033 | #ifdef CONFIG_PM | ||
1034 | /* copy the data for resume */ | ||
1035 | scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL); | ||
1036 | if (!scb_data) | ||
1037 | return NULL; | ||
1038 | #endif | ||
1039 | |||
1030 | desc = _map_scb (chip,name,dest); | 1040 | desc = _map_scb (chip,name,dest); |
1031 | if (desc) { | 1041 | if (desc) { |
1032 | desc->data = scb_data; | 1042 | desc->data = scb_data; |
1033 | _dsp_create_scb(chip,scb_data,dest); | 1043 | _dsp_create_scb(chip,scb_data,dest); |
1034 | } else { | 1044 | } else { |
1035 | snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); | 1045 | snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); |
1046 | #ifdef CONFIG_PM | ||
1047 | kfree(scb_data); | ||
1048 | #endif | ||
1036 | } | 1049 | } |
1037 | 1050 | ||
1038 | return desc; | 1051 | return desc; |
@@ -1988,7 +2001,28 @@ int cs46xx_dsp_resume(struct snd_cs46xx * chip) | |||
1988 | continue; | 2001 | continue; |
1989 | _dsp_create_scb(chip, s->data, s->address); | 2002 | _dsp_create_scb(chip, s->data, s->address); |
1990 | } | 2003 | } |
1991 | 2004 | for (i = 0; i < ins->nscb; i++) { | |
2005 | struct dsp_scb_descriptor *s = &ins->scbs[i]; | ||
2006 | if (s->deleted) | ||
2007 | continue; | ||
2008 | if (s->updated) | ||
2009 | cs46xx_dsp_spos_update_scb(chip, s); | ||
2010 | if (s->volume_set) | ||
2011 | cs46xx_dsp_scb_set_volume(chip, s, | ||
2012 | s->volume[0], s->volume[1]); | ||
2013 | } | ||
2014 | if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) { | ||
2015 | cs46xx_dsp_enable_spdif_hw(chip); | ||
2016 | snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2, | ||
2017 | (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10); | ||
2018 | if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) | ||
2019 | cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV, | ||
2020 | ins->spdif_csuv_stream); | ||
2021 | } | ||
2022 | if (chip->dsp_spos_instance->spdif_status_in) { | ||
2023 | cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005); | ||
2024 | cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff); | ||
2025 | } | ||
1992 | return 0; | 2026 | return 0; |
1993 | } | 2027 | } |
1994 | #endif | 2028 | #endif |
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h index f9e169d33c03..ca47a8114c7f 100644 --- a/sound/pci/cs46xx/dsp_spos.h +++ b/sound/pci/cs46xx/dsp_spos.h | |||
@@ -212,6 +212,7 @@ static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip, | |||
212 | (scb->address + SCBsubListPtr) << 2, | 212 | (scb->address + SCBsubListPtr) << 2, |
213 | (scb->sub_list_ptr->address << 0x10) | | 213 | (scb->sub_list_ptr->address << 0x10) | |
214 | (scb->next_scb_ptr->address)); | 214 | (scb->next_scb_ptr->address)); |
215 | scb->updated = 1; | ||
215 | } | 216 | } |
216 | 217 | ||
217 | static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, | 218 | static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, |
@@ -222,6 +223,9 @@ static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, | |||
222 | 223 | ||
223 | snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); | 224 | snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); |
224 | snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); | 225 | snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); |
226 | scb->volume_set = 1; | ||
227 | scb->volume[0] = left; | ||
228 | scb->volume[1] = right; | ||
225 | } | 229 | } |
226 | #endif /* __DSP_SPOS_H__ */ | 230 | #endif /* __DSP_SPOS_H__ */ |
227 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ | 231 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ |
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index dd7c41b037b4..00b148a10239 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c | |||
@@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, | |||
115 | static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) | 115 | static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) |
116 | { | 116 | { |
117 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 117 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
118 | unsigned long flags; | ||
119 | 118 | ||
120 | if ( scb->parent_scb_ptr ) { | 119 | if ( scb->parent_scb_ptr ) { |
121 | /* unlink parent SCB */ | 120 | /* unlink parent SCB */ |
@@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor | |||
153 | scb->next_scb_ptr = ins->the_null_scb; | 152 | scb->next_scb_ptr = ins->the_null_scb; |
154 | } | 153 | } |
155 | 154 | ||
156 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
157 | |||
158 | /* update parent first entry in DSP RAM */ | 155 | /* update parent first entry in DSP RAM */ |
159 | cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); | 156 | cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); |
160 | 157 | ||
@@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor | |||
162 | cs46xx_dsp_spos_update_scb(chip,scb); | 159 | cs46xx_dsp_spos_update_scb(chip,scb); |
163 | 160 | ||
164 | scb->parent_scb_ptr = NULL; | 161 | scb->parent_scb_ptr = NULL; |
165 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
166 | } | 162 | } |
167 | } | 163 | } |
168 | 164 | ||
@@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * | |||
197 | goto _end; | 193 | goto _end; |
198 | #endif | 194 | #endif |
199 | 195 | ||
200 | spin_lock_irqsave(&scb->lock, flags); | 196 | spin_lock_irqsave(&chip->reg_lock, flags); |
201 | _dsp_unlink_scb (chip,scb); | 197 | _dsp_unlink_scb (chip,scb); |
202 | spin_unlock_irqrestore(&scb->lock, flags); | 198 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
203 | 199 | ||
204 | cs46xx_dsp_proc_free_scb_desc(scb); | 200 | cs46xx_dsp_proc_free_scb_desc(scb); |
205 | if (snd_BUG_ON(!scb->scb_symbol)) | 201 | if (snd_BUG_ON(!scb->scb_symbol)) |
@@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * | |||
207 | remove_symbol (chip,scb->scb_symbol); | 203 | remove_symbol (chip,scb->scb_symbol); |
208 | 204 | ||
209 | ins->scbs[scb->index].deleted = 1; | 205 | ins->scbs[scb->index].deleted = 1; |
206 | #ifdef CONFIG_PM | ||
207 | kfree(ins->scbs[scb->index].data); | ||
208 | ins->scbs[scb->index].data = NULL; | ||
209 | #endif | ||
210 | 210 | ||
211 | if (scb->index < ins->scb_highest_frag_index) | 211 | if (scb->index < ins->scb_highest_frag_index) |
212 | ins->scb_highest_frag_index = scb->index; | 212 | ins->scb_highest_frag_index = scb->index; |
@@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip, | |||
1508 | chip->dsp_spos_instance->npcm_channels <= 0)) | 1508 | chip->dsp_spos_instance->npcm_channels <= 0)) |
1509 | return -EIO; | 1509 | return -EIO; |
1510 | 1510 | ||
1511 | spin_lock(&pcm_channel->src_scb->lock); | 1511 | spin_lock_irqsave(&chip->reg_lock, flags); |
1512 | |||
1513 | if (pcm_channel->unlinked) { | 1512 | if (pcm_channel->unlinked) { |
1514 | spin_unlock(&pcm_channel->src_scb->lock); | 1513 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1515 | return -EIO; | 1514 | return -EIO; |
1516 | } | 1515 | } |
1517 | 1516 | ||
1518 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1519 | pcm_channel->unlinked = 1; | 1517 | pcm_channel->unlinked = 1; |
1520 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1521 | 1518 | ||
1522 | _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); | 1519 | _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); |
1520 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1523 | 1521 | ||
1524 | spin_unlock(&pcm_channel->src_scb->lock); | ||
1525 | return 0; | 1522 | return 0; |
1526 | } | 1523 | } |
1527 | 1524 | ||
@@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1533 | struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; | 1530 | struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; |
1534 | unsigned long flags; | 1531 | unsigned long flags; |
1535 | 1532 | ||
1536 | spin_lock(&pcm_channel->src_scb->lock); | 1533 | spin_lock_irqsave(&chip->reg_lock, flags); |
1537 | 1534 | ||
1538 | if (pcm_channel->unlinked == 0) { | 1535 | if (pcm_channel->unlinked == 0) { |
1539 | spin_unlock(&pcm_channel->src_scb->lock); | 1536 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1540 | return -EIO; | 1537 | return -EIO; |
1541 | } | 1538 | } |
1542 | 1539 | ||
@@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1552 | snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); | 1549 | snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); |
1553 | pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; | 1550 | pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; |
1554 | 1551 | ||
1555 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1556 | |||
1557 | /* update SCB entry in DSP RAM */ | 1552 | /* update SCB entry in DSP RAM */ |
1558 | cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); | 1553 | cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); |
1559 | 1554 | ||
@@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1562 | 1557 | ||
1563 | pcm_channel->unlinked = 0; | 1558 | pcm_channel->unlinked = 0; |
1564 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1559 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1565 | |||
1566 | spin_unlock(&pcm_channel->src_scb->lock); | ||
1567 | return 0; | 1560 | return 0; |
1568 | } | 1561 | } |
1569 | 1562 | ||
@@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s | |||
1596 | 1589 | ||
1597 | int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) | 1590 | int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) |
1598 | { | 1591 | { |
1592 | unsigned long flags; | ||
1593 | |||
1599 | if (snd_BUG_ON(!src->parent_scb_ptr)) | 1594 | if (snd_BUG_ON(!src->parent_scb_ptr)) |
1600 | return -EINVAL; | 1595 | return -EINVAL; |
1601 | 1596 | ||
1602 | /* mute SCB */ | 1597 | /* mute SCB */ |
1603 | cs46xx_dsp_scb_set_volume (chip,src,0,0); | 1598 | cs46xx_dsp_scb_set_volume (chip,src,0,0); |
1604 | 1599 | ||
1600 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1605 | _dsp_unlink_scb (chip,src); | 1601 | _dsp_unlink_scb (chip,src); |
1602 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1606 | 1603 | ||
1607 | return 0; | 1604 | return 0; |
1608 | } | 1605 | } |
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index dc464321d0f3..207479a641cf 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c | |||
@@ -58,7 +58,7 @@ struct snd_cs5530 { | |||
58 | unsigned long pci_base; | 58 | unsigned long pci_base; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct pci_device_id snd_cs5530_ids[] = { | 61 | static DEFINE_PCI_DEVICE_TABLE(snd_cs5530_ids) = { |
62 | {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, | 62 | {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, |
63 | PCI_ANY_ID, 0, 0}, | 63 | PCI_ANY_ID, 0, 0}, |
64 | {0,} | 64 | {0,} |
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 91e7faf69bbb..afb803708416 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c | |||
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME); | |||
66 | module_param_array(enable, bool, NULL, 0444); | 66 | module_param_array(enable, bool, NULL, 0444); |
67 | MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME); | 67 | MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME); |
68 | 68 | ||
69 | static struct pci_device_id snd_cs5535audio_ids[] = { | 69 | static DEFINE_PCI_DEVICE_TABLE(snd_cs5535audio_ids) = { |
70 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) }, | 70 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) }, |
71 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) }, | 71 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) }, |
72 | {} | 72 | {} |
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 459c1f62783b..480cb1e905b6 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -1214,10 +1214,11 @@ static int atc_dev_free(struct snd_device *dev) | |||
1214 | return ct_atc_destroy(atc); | 1214 | return ct_atc_destroy(atc); |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | static int __devinit atc_identify_card(struct ct_atc *atc) | 1217 | static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid) |
1218 | { | 1218 | { |
1219 | const struct snd_pci_quirk *p; | 1219 | const struct snd_pci_quirk *p; |
1220 | const struct snd_pci_quirk *list; | 1220 | const struct snd_pci_quirk *list; |
1221 | u16 vendor_id, device_id; | ||
1221 | 1222 | ||
1222 | switch (atc->chip_type) { | 1223 | switch (atc->chip_type) { |
1223 | case ATC20K1: | 1224 | case ATC20K1: |
@@ -1231,13 +1232,19 @@ static int __devinit atc_identify_card(struct ct_atc *atc) | |||
1231 | default: | 1232 | default: |
1232 | return -ENOENT; | 1233 | return -ENOENT; |
1233 | } | 1234 | } |
1234 | p = snd_pci_quirk_lookup(atc->pci, list); | 1235 | if (ssid) { |
1236 | vendor_id = ssid >> 16; | ||
1237 | device_id = ssid & 0xffff; | ||
1238 | } else { | ||
1239 | vendor_id = atc->pci->subsystem_vendor; | ||
1240 | device_id = atc->pci->subsystem_device; | ||
1241 | } | ||
1242 | p = snd_pci_quirk_lookup_id(vendor_id, device_id, list); | ||
1235 | if (p) { | 1243 | if (p) { |
1236 | if (p->value < 0) { | 1244 | if (p->value < 0) { |
1237 | printk(KERN_ERR "ctxfi: " | 1245 | printk(KERN_ERR "ctxfi: " |
1238 | "Device %04x:%04x is black-listed\n", | 1246 | "Device %04x:%04x is black-listed\n", |
1239 | atc->pci->subsystem_vendor, | 1247 | vendor_id, device_id); |
1240 | atc->pci->subsystem_device); | ||
1241 | return -ENOENT; | 1248 | return -ENOENT; |
1242 | } | 1249 | } |
1243 | atc->model = p->value; | 1250 | atc->model = p->value; |
@@ -1250,8 +1257,7 @@ static int __devinit atc_identify_card(struct ct_atc *atc) | |||
1250 | atc->model_name = ct_subsys_name[atc->model]; | 1257 | atc->model_name = ct_subsys_name[atc->model]; |
1251 | snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", | 1258 | snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", |
1252 | atc->chip_name, atc->model_name, | 1259 | atc->chip_name, atc->model_name, |
1253 | atc->pci->subsystem_vendor, | 1260 | vendor_id, device_id); |
1254 | atc->pci->subsystem_device); | ||
1255 | return 0; | 1261 | return 0; |
1256 | } | 1262 | } |
1257 | 1263 | ||
@@ -1625,7 +1631,8 @@ static struct ct_atc atc_preset __devinitdata = { | |||
1625 | 1631 | ||
1626 | int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | 1632 | int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, |
1627 | unsigned int rsr, unsigned int msr, | 1633 | unsigned int rsr, unsigned int msr, |
1628 | int chip_type, struct ct_atc **ratc) | 1634 | int chip_type, unsigned int ssid, |
1635 | struct ct_atc **ratc) | ||
1629 | { | 1636 | { |
1630 | struct ct_atc *atc; | 1637 | struct ct_atc *atc; |
1631 | static struct snd_device_ops ops = { | 1638 | static struct snd_device_ops ops = { |
@@ -1651,7 +1658,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | |||
1651 | mutex_init(&atc->atc_mutex); | 1658 | mutex_init(&atc->atc_mutex); |
1652 | 1659 | ||
1653 | /* Find card model */ | 1660 | /* Find card model */ |
1654 | err = atc_identify_card(atc); | 1661 | err = atc_identify_card(atc, ssid); |
1655 | if (err < 0) { | 1662 | if (err < 0) { |
1656 | printk(KERN_ERR "ctatc: Card not recognised\n"); | 1663 | printk(KERN_ERR "ctatc: Card not recognised\n"); |
1657 | goto error1; | 1664 | goto error1; |
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index 9fd8a5708943..7167c0185d52 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h | |||
@@ -148,7 +148,7 @@ struct ct_atc { | |||
148 | 148 | ||
149 | int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | 149 | int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, |
150 | unsigned int rsr, unsigned int msr, int chip_type, | 150 | unsigned int rsr, unsigned int msr, int chip_type, |
151 | struct ct_atc **ratc); | 151 | unsigned int subsysid, struct ct_atc **ratc); |
152 | int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); | 152 | int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); |
153 | 153 | ||
154 | #endif /* CTATC_H */ | 154 | #endif /* CTATC_H */ |
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c index 76541748e7bc..f42e7e1a1074 100644 --- a/sound/pci/ctxfi/xfi.c +++ b/sound/pci/ctxfi/xfi.c | |||
@@ -32,6 +32,7 @@ module_param(multiple, uint, S_IRUGO); | |||
32 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 32 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
33 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 33 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
34 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 34 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
35 | static unsigned int subsystem[SNDRV_CARDS]; | ||
35 | 36 | ||
36 | module_param_array(index, int, NULL, 0444); | 37 | module_param_array(index, int, NULL, 0444); |
37 | MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); | 38 | MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); |
@@ -39,8 +40,10 @@ module_param_array(id, charp, NULL, 0444); | |||
39 | MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); | 40 | MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); |
40 | module_param_array(enable, bool, NULL, 0444); | 41 | module_param_array(enable, bool, NULL, 0444); |
41 | MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); | 42 | MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); |
43 | module_param_array(subsystem, int, NULL, 0444); | ||
44 | MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver"); | ||
42 | 45 | ||
43 | static struct pci_device_id ct_pci_dev_ids[] = { | 46 | static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = { |
44 | /* only X-Fi is supported, so... */ | 47 | /* only X-Fi is supported, so... */ |
45 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), | 48 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), |
46 | .driver_data = ATC20K1, | 49 | .driver_data = ATC20K1, |
@@ -85,7 +88,7 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
85 | multiple = 2; | 88 | multiple = 2; |
86 | } | 89 | } |
87 | err = ct_atc_create(card, pci, reference_rate, multiple, | 90 | err = ct_atc_create(card, pci, reference_rate, multiple, |
88 | pci_id->driver_data, &atc); | 91 | pci_id->driver_data, subsystem[dev], &atc); |
89 | if (err < 0) | 92 | if (err < 0) |
90 | goto error; | 93 | goto error; |
91 | 94 | ||
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c index 8c6db3aa3c1a..a65bafe0800f 100644 --- a/sound/pci/echoaudio/darla20.c +++ b/sound/pci/echoaudio/darla20.c | |||
@@ -63,7 +63,7 @@ static const struct firmware card_fw[] = { | |||
63 | {0, "darla20_dsp.fw"} | 63 | {0, "darla20_dsp.fw"} |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static struct pci_device_id snd_echo_ids[] = { | 66 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
67 | {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ | 67 | {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ |
68 | {0,} | 68 | {0,} |
69 | }; | 69 | }; |
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c index 29043301ebb8..20c7cbc89bb3 100644 --- a/sound/pci/echoaudio/darla20_dsp.c +++ b/sound/pci/echoaudio/darla20_dsp.c | |||
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
45 | chip->device_id = device_id; | 45 | chip->device_id = device_id; |
46 | chip->subdevice_id = subdevice_id; | 46 | chip->subdevice_id = subdevice_id; |
47 | chip->bad_board = TRUE; | 47 | chip->bad_board = TRUE; |
48 | chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; | 48 | chip->dsp_code_to_load = FW_DARLA20_DSP; |
49 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | 49 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; |
50 | chip->clock_state = GD_CLOCK_UNDEF; | 50 | chip->clock_state = GD_CLOCK_UNDEF; |
51 | /* Since this card has no ASIC, mark it as loaded so everything | 51 | /* Since this card has no ASIC, mark it as loaded so everything |
@@ -57,15 +57,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
57 | return err; | 57 | return err; |
58 | chip->bad_board = FALSE; | 58 | chip->bad_board = FALSE; |
59 | 59 | ||
60 | if ((err = init_line_levels(chip)) < 0) | ||
61 | return err; | ||
62 | |||
63 | DE_INIT(("init_hw done\n")); | 60 | DE_INIT(("init_hw done\n")); |
64 | return err; | 61 | return err; |
65 | } | 62 | } |
66 | 63 | ||
67 | 64 | ||
68 | 65 | ||
66 | static int set_mixer_defaults(struct echoaudio *chip) | ||
67 | { | ||
68 | return init_line_levels(chip); | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
69 | /* The Darla20 has no external clock sources */ | 73 | /* The Darla20 has no external clock sources */ |
70 | static u32 detect_input_clocks(const struct echoaudio *chip) | 74 | static u32 detect_input_clocks(const struct echoaudio *chip) |
71 | { | 75 | { |
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c index 04cbf3eaf05a..0a6c50bcd758 100644 --- a/sound/pci/echoaudio/darla24.c +++ b/sound/pci/echoaudio/darla24.c | |||
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = { | |||
67 | {0, "darla24_dsp.fw"} | 67 | {0, "darla24_dsp.fw"} |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static struct pci_device_id snd_echo_ids[] = { | 70 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
71 | {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ | 71 | {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ |
72 | {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ | 72 | {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ |
73 | {0,} | 73 | {0,} |
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c index 60228731841f..6da6663e9176 100644 --- a/sound/pci/echoaudio/darla24_dsp.c +++ b/sound/pci/echoaudio/darla24_dsp.c | |||
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
45 | chip->device_id = device_id; | 45 | chip->device_id = device_id; |
46 | chip->subdevice_id = subdevice_id; | 46 | chip->subdevice_id = subdevice_id; |
47 | chip->bad_board = TRUE; | 47 | chip->bad_board = TRUE; |
48 | chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; | 48 | chip->dsp_code_to_load = FW_DARLA24_DSP; |
49 | /* Since this card has no ASIC, mark it as loaded so everything | 49 | /* Since this card has no ASIC, mark it as loaded so everything |
50 | works OK */ | 50 | works OK */ |
51 | chip->asic_loaded = TRUE; | 51 | chip->asic_loaded = TRUE; |
@@ -56,15 +56,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
56 | return err; | 56 | return err; |
57 | chip->bad_board = FALSE; | 57 | chip->bad_board = FALSE; |
58 | 58 | ||
59 | if ((err = init_line_levels(chip)) < 0) | ||
60 | return err; | ||
61 | |||
62 | DE_INIT(("init_hw done\n")); | 59 | DE_INIT(("init_hw done\n")); |
63 | return err; | 60 | return err; |
64 | } | 61 | } |
65 | 62 | ||
66 | 63 | ||
67 | 64 | ||
65 | static int set_mixer_defaults(struct echoaudio *chip) | ||
66 | { | ||
67 | return init_line_levels(chip); | ||
68 | } | ||
69 | |||
70 | |||
71 | |||
68 | static u32 detect_input_clocks(const struct echoaudio *chip) | 72 | static u32 detect_input_clocks(const struct echoaudio *chip) |
69 | { | 73 | { |
70 | u32 clocks_from_dsp, clock_bits; | 74 | u32 clocks_from_dsp, clock_bits; |
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c index 4022e43a0053..f5142796989b 100644 --- a/sound/pci/echoaudio/echo3g.c +++ b/sound/pci/echoaudio/echo3g.c | |||
@@ -81,7 +81,7 @@ static const struct firmware card_fw[] = { | |||
81 | {0, "3g_asic.fw"} | 81 | {0, "3g_asic.fw"} |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static struct pci_device_id snd_echo_ids[] = { | 84 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
85 | {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ | 85 | {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ |
86 | {0,} | 86 | {0,} |
87 | }; | 87 | }; |
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c index 57967e580571..3cdc2ee2d1dd 100644 --- a/sound/pci/echoaudio/echo3g_dsp.c +++ b/sound/pci/echoaudio/echo3g_dsp.c | |||
@@ -61,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
61 | chip->subdevice_id = subdevice_id; | 61 | chip->subdevice_id = subdevice_id; |
62 | chip->bad_board = TRUE; | 62 | chip->bad_board = TRUE; |
63 | chip->has_midi = TRUE; | 63 | chip->has_midi = TRUE; |
64 | chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; | 64 | chip->dsp_code_to_load = FW_ECHO3G_DSP; |
65 | 65 | ||
66 | /* Load the DSP code and the ASIC on the PCI card and get | 66 | /* Load the DSP code and the ASIC on the PCI card and get |
67 | what type of external box is attached */ | 67 | what type of external box is attached */ |
@@ -97,20 +97,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
97 | chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | 97 | chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | |
98 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | 98 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | |
99 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | 99 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; |
100 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
101 | chip->professional_spdif = FALSE; | ||
102 | chip->non_audio_spdif = FALSE; | ||
103 | chip->bad_board = FALSE; | ||
104 | |||
105 | if ((err = init_line_levels(chip)) < 0) | ||
106 | return err; | ||
107 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
108 | if (err < 0) | ||
109 | return err; | ||
110 | err = set_phantom_power(chip, 0); | ||
111 | if (err < 0) | ||
112 | return err; | ||
113 | err = set_professional_spdif(chip, TRUE); | ||
114 | 100 | ||
115 | DE_INIT(("init_hw done\n")); | 101 | DE_INIT(("init_hw done\n")); |
116 | return err; | 102 | return err; |
@@ -118,6 +104,18 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
118 | 104 | ||
119 | 105 | ||
120 | 106 | ||
107 | static int set_mixer_defaults(struct echoaudio *chip) | ||
108 | { | ||
109 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
110 | chip->professional_spdif = FALSE; | ||
111 | chip->non_audio_spdif = FALSE; | ||
112 | chip->bad_board = FALSE; | ||
113 | chip->phantom_power = FALSE; | ||
114 | return init_line_levels(chip); | ||
115 | } | ||
116 | |||
117 | |||
118 | |||
121 | static int set_phantom_power(struct echoaudio *chip, char on) | 119 | static int set_phantom_power(struct echoaudio *chip, char on) |
122 | { | 120 | { |
123 | u32 control_reg = le32_to_cpu(chip->comm_page->control_register); | 121 | u32 control_reg = le32_to_cpu(chip->comm_page->control_register); |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 641d7f07392c..8dab82d7d19d 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -36,22 +36,61 @@ MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); | |||
36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; | 36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; |
37 | static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); | 37 | static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); |
38 | 38 | ||
39 | |||
40 | |||
39 | static int get_firmware(const struct firmware **fw_entry, | 41 | static int get_firmware(const struct firmware **fw_entry, |
40 | const struct firmware *frm, struct echoaudio *chip) | 42 | struct echoaudio *chip, const short fw_index) |
41 | { | 43 | { |
42 | int err; | 44 | int err; |
43 | char name[30]; | 45 | char name[30]; |
44 | DE_ACT(("firmware requested: %s\n", frm->data)); | 46 | |
45 | snprintf(name, sizeof(name), "ea/%s", frm->data); | 47 | #ifdef CONFIG_PM |
46 | if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) | 48 | if (chip->fw_cache[fw_index]) { |
49 | DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); | ||
50 | *fw_entry = chip->fw_cache[fw_index]; | ||
51 | return 0; | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); | ||
56 | snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); | ||
57 | err = request_firmware(fw_entry, name, pci_device(chip)); | ||
58 | if (err < 0) | ||
47 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); | 59 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); |
60 | #ifdef CONFIG_PM | ||
61 | else | ||
62 | chip->fw_cache[fw_index] = *fw_entry; | ||
63 | #endif | ||
48 | return err; | 64 | return err; |
49 | } | 65 | } |
50 | 66 | ||
67 | |||
68 | |||
51 | static void free_firmware(const struct firmware *fw_entry) | 69 | static void free_firmware(const struct firmware *fw_entry) |
52 | { | 70 | { |
71 | #ifdef CONFIG_PM | ||
72 | DE_ACT(("firmware not released (kept in cache)\n")); | ||
73 | #else | ||
53 | release_firmware(fw_entry); | 74 | release_firmware(fw_entry); |
54 | DE_ACT(("firmware released\n")); | 75 | DE_ACT(("firmware released\n")); |
76 | #endif | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
81 | static void free_firmware_cache(struct echoaudio *chip) | ||
82 | { | ||
83 | #ifdef CONFIG_PM | ||
84 | int i; | ||
85 | |||
86 | for (i = 0; i < 8 ; i++) | ||
87 | if (chip->fw_cache[i]) { | ||
88 | release_firmware(chip->fw_cache[i]); | ||
89 | DE_ACT(("release_firmware(%d)\n", i)); | ||
90 | } | ||
91 | |||
92 | DE_ACT(("firmware_cache released\n")); | ||
93 | #endif | ||
55 | } | 94 | } |
56 | 95 | ||
57 | 96 | ||
@@ -714,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
714 | 753 | ||
715 | spin_lock(&chip->lock); | 754 | spin_lock(&chip->lock); |
716 | switch (cmd) { | 755 | switch (cmd) { |
756 | case SNDRV_PCM_TRIGGER_RESUME: | ||
757 | DE_ACT(("pcm_trigger resume\n")); | ||
717 | case SNDRV_PCM_TRIGGER_START: | 758 | case SNDRV_PCM_TRIGGER_START: |
718 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 759 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
719 | DE_ACT(("pcm_trigger start\n")); | 760 | DE_ACT(("pcm_trigger start\n")); |
@@ -737,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
737 | err = start_transport(chip, channelmask, | 778 | err = start_transport(chip, channelmask, |
738 | chip->pipe_cyclic_mask); | 779 | chip->pipe_cyclic_mask); |
739 | break; | 780 | break; |
781 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
782 | DE_ACT(("pcm_trigger suspend\n")); | ||
740 | case SNDRV_PCM_TRIGGER_STOP: | 783 | case SNDRV_PCM_TRIGGER_STOP: |
741 | DE_ACT(("pcm_trigger stop\n")); | 784 | DE_ACT(("pcm_trigger stop\n")); |
742 | for (i = 0; i < DSP_MAXPIPES; i++) { | 785 | for (i = 0; i < DSP_MAXPIPES; i++) { |
@@ -1876,6 +1919,7 @@ static int snd_echo_free(struct echoaudio *chip) | |||
1876 | pci_disable_device(chip->pci); | 1919 | pci_disable_device(chip->pci); |
1877 | 1920 | ||
1878 | /* release chip data */ | 1921 | /* release chip data */ |
1922 | free_firmware_cache(chip); | ||
1879 | kfree(chip); | 1923 | kfree(chip); |
1880 | DE_INIT(("Chip freed.\n")); | 1924 | DE_INIT(("Chip freed.\n")); |
1881 | return 0; | 1925 | return 0; |
@@ -1913,18 +1957,27 @@ static __devinit int snd_echo_create(struct snd_card *card, | |||
1913 | return err; | 1957 | return err; |
1914 | pci_set_master(pci); | 1958 | pci_set_master(pci); |
1915 | 1959 | ||
1916 | /* allocate a chip-specific data */ | 1960 | /* Allocate chip if needed */ |
1917 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1961 | if (!*rchip) { |
1918 | if (!chip) { | 1962 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1919 | pci_disable_device(pci); | 1963 | if (!chip) { |
1920 | return -ENOMEM; | 1964 | pci_disable_device(pci); |
1965 | return -ENOMEM; | ||
1966 | } | ||
1967 | DE_INIT(("chip=%p\n", chip)); | ||
1968 | spin_lock_init(&chip->lock); | ||
1969 | chip->card = card; | ||
1970 | chip->pci = pci; | ||
1971 | chip->irq = -1; | ||
1972 | atomic_set(&chip->opencount, 0); | ||
1973 | mutex_init(&chip->mode_mutex); | ||
1974 | chip->can_set_rate = 1; | ||
1975 | } else { | ||
1976 | /* If this was called from the resume function, chip is | ||
1977 | * already allocated and it contains current card settings. | ||
1978 | */ | ||
1979 | chip = *rchip; | ||
1921 | } | 1980 | } |
1922 | DE_INIT(("chip=%p\n", chip)); | ||
1923 | |||
1924 | spin_lock_init(&chip->lock); | ||
1925 | chip->card = card; | ||
1926 | chip->pci = pci; | ||
1927 | chip->irq = -1; | ||
1928 | 1981 | ||
1929 | /* PCI resource allocation */ | 1982 | /* PCI resource allocation */ |
1930 | chip->dsp_registers_phys = pci_resource_start(pci, 0); | 1983 | chip->dsp_registers_phys = pci_resource_start(pci, 0); |
@@ -1964,7 +2017,9 @@ static __devinit int snd_echo_create(struct snd_card *card, | |||
1964 | chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; | 2017 | chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; |
1965 | 2018 | ||
1966 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | 2019 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); |
1967 | if (err) { | 2020 | if (err >= 0) |
2021 | err = set_mixer_defaults(chip); | ||
2022 | if (err < 0) { | ||
1968 | DE_INIT(("init_hw err=%d\n", err)); | 2023 | DE_INIT(("init_hw err=%d\n", err)); |
1969 | snd_echo_free(chip); | 2024 | snd_echo_free(chip); |
1970 | return err; | 2025 | return err; |
@@ -1975,9 +2030,6 @@ static __devinit int snd_echo_create(struct snd_card *card, | |||
1975 | snd_echo_free(chip); | 2030 | snd_echo_free(chip); |
1976 | return err; | 2031 | return err; |
1977 | } | 2032 | } |
1978 | atomic_set(&chip->opencount, 0); | ||
1979 | mutex_init(&chip->mode_mutex); | ||
1980 | chip->can_set_rate = 1; | ||
1981 | *rchip = chip; | 2033 | *rchip = chip; |
1982 | /* Init done ! */ | 2034 | /* Init done ! */ |
1983 | return 0; | 2035 | return 0; |
@@ -2010,6 +2062,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, | |||
2010 | 2062 | ||
2011 | snd_card_set_dev(card, &pci->dev); | 2063 | snd_card_set_dev(card, &pci->dev); |
2012 | 2064 | ||
2065 | chip = NULL; /* Tells snd_echo_create to allocate chip */ | ||
2013 | if ((err = snd_echo_create(card, pci, &chip)) < 0) { | 2066 | if ((err = snd_echo_create(card, pci, &chip)) < 0) { |
2014 | snd_card_free(card); | 2067 | snd_card_free(card); |
2015 | return err; | 2068 | return err; |
@@ -2149,6 +2202,112 @@ ctl_error: | |||
2149 | 2202 | ||
2150 | 2203 | ||
2151 | 2204 | ||
2205 | #if defined(CONFIG_PM) | ||
2206 | |||
2207 | static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) | ||
2208 | { | ||
2209 | struct echoaudio *chip = pci_get_drvdata(pci); | ||
2210 | |||
2211 | DE_INIT(("suspend start\n")); | ||
2212 | snd_pcm_suspend_all(chip->analog_pcm); | ||
2213 | snd_pcm_suspend_all(chip->digital_pcm); | ||
2214 | |||
2215 | #ifdef ECHOCARD_HAS_MIDI | ||
2216 | /* This call can sleep */ | ||
2217 | if (chip->midi_out) | ||
2218 | snd_echo_midi_output_trigger(chip->midi_out, 0); | ||
2219 | #endif | ||
2220 | spin_lock_irq(&chip->lock); | ||
2221 | if (wait_handshake(chip)) { | ||
2222 | spin_unlock_irq(&chip->lock); | ||
2223 | return -EIO; | ||
2224 | } | ||
2225 | clear_handshake(chip); | ||
2226 | if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) { | ||
2227 | spin_unlock_irq(&chip->lock); | ||
2228 | return -EIO; | ||
2229 | } | ||
2230 | spin_unlock_irq(&chip->lock); | ||
2231 | |||
2232 | chip->dsp_code = NULL; | ||
2233 | free_irq(chip->irq, chip); | ||
2234 | chip->irq = -1; | ||
2235 | pci_save_state(pci); | ||
2236 | pci_disable_device(pci); | ||
2237 | |||
2238 | DE_INIT(("suspend done\n")); | ||
2239 | return 0; | ||
2240 | } | ||
2241 | |||
2242 | |||
2243 | |||
2244 | static int snd_echo_resume(struct pci_dev *pci) | ||
2245 | { | ||
2246 | struct echoaudio *chip = pci_get_drvdata(pci); | ||
2247 | struct comm_page *commpage, *commpage_bak; | ||
2248 | u32 pipe_alloc_mask; | ||
2249 | int err; | ||
2250 | |||
2251 | DE_INIT(("resume start\n")); | ||
2252 | pci_restore_state(pci); | ||
2253 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); | ||
2254 | commpage = chip->comm_page; | ||
2255 | memcpy(commpage_bak, commpage, sizeof(struct comm_page)); | ||
2256 | |||
2257 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | ||
2258 | if (err < 0) { | ||
2259 | kfree(commpage_bak); | ||
2260 | DE_INIT(("resume init_hw err=%d\n", err)); | ||
2261 | snd_echo_free(chip); | ||
2262 | return err; | ||
2263 | } | ||
2264 | DE_INIT(("resume init OK\n")); | ||
2265 | |||
2266 | /* Temporarily set chip->pipe_alloc_mask=0 otherwise | ||
2267 | * restore_dsp_settings() fails. | ||
2268 | */ | ||
2269 | pipe_alloc_mask = chip->pipe_alloc_mask; | ||
2270 | chip->pipe_alloc_mask = 0; | ||
2271 | err = restore_dsp_rettings(chip); | ||
2272 | chip->pipe_alloc_mask = pipe_alloc_mask; | ||
2273 | if (err < 0) { | ||
2274 | kfree(commpage_bak); | ||
2275 | return err; | ||
2276 | } | ||
2277 | DE_INIT(("resume restore OK\n")); | ||
2278 | |||
2279 | memcpy(&commpage->audio_format, &commpage_bak->audio_format, | ||
2280 | sizeof(commpage->audio_format)); | ||
2281 | memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr, | ||
2282 | sizeof(commpage->sglist_addr)); | ||
2283 | memcpy(&commpage->midi_output, &commpage_bak->midi_output, | ||
2284 | sizeof(commpage->midi_output)); | ||
2285 | kfree(commpage_bak); | ||
2286 | |||
2287 | if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, | ||
2288 | ECHOCARD_NAME, chip)) { | ||
2289 | snd_echo_free(chip); | ||
2290 | snd_printk(KERN_ERR "cannot grab irq\n"); | ||
2291 | return -EBUSY; | ||
2292 | } | ||
2293 | chip->irq = pci->irq; | ||
2294 | DE_INIT(("resume irq=%d\n", chip->irq)); | ||
2295 | |||
2296 | #ifdef ECHOCARD_HAS_MIDI | ||
2297 | if (chip->midi_input_enabled) | ||
2298 | enable_midi_input(chip, TRUE); | ||
2299 | if (chip->midi_out) | ||
2300 | snd_echo_midi_output_trigger(chip->midi_out, 1); | ||
2301 | #endif | ||
2302 | |||
2303 | DE_INIT(("resume done\n")); | ||
2304 | return 0; | ||
2305 | } | ||
2306 | |||
2307 | #endif /* CONFIG_PM */ | ||
2308 | |||
2309 | |||
2310 | |||
2152 | static void __devexit snd_echo_remove(struct pci_dev *pci) | 2311 | static void __devexit snd_echo_remove(struct pci_dev *pci) |
2153 | { | 2312 | { |
2154 | struct echoaudio *chip; | 2313 | struct echoaudio *chip; |
@@ -2171,6 +2330,10 @@ static struct pci_driver driver = { | |||
2171 | .id_table = snd_echo_ids, | 2330 | .id_table = snd_echo_ids, |
2172 | .probe = snd_echo_probe, | 2331 | .probe = snd_echo_probe, |
2173 | .remove = __devexit_p(snd_echo_remove), | 2332 | .remove = __devexit_p(snd_echo_remove), |
2333 | #ifdef CONFIG_PM | ||
2334 | .suspend = snd_echo_suspend, | ||
2335 | .resume = snd_echo_resume, | ||
2336 | #endif /* CONFIG_PM */ | ||
2174 | }; | 2337 | }; |
2175 | 2338 | ||
2176 | 2339 | ||
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index f9490ae36c2e..1df974dcb5f4 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h | |||
@@ -442,13 +442,16 @@ struct echoaudio { | |||
442 | u16 device_id, subdevice_id; | 442 | u16 device_id, subdevice_id; |
443 | u16 *dsp_code; /* Current DSP code loaded, | 443 | u16 *dsp_code; /* Current DSP code loaded, |
444 | * NULL if nothing loaded */ | 444 | * NULL if nothing loaded */ |
445 | const struct firmware *dsp_code_to_load;/* DSP code to load */ | 445 | short dsp_code_to_load; /* DSP code to load */ |
446 | const struct firmware *asic_code; /* Current ASIC code */ | 446 | short asic_code; /* Current ASIC code */ |
447 | u32 comm_page_phys; /* Physical address of the | 447 | u32 comm_page_phys; /* Physical address of the |
448 | * memory seen by DSP */ | 448 | * memory seen by DSP */ |
449 | volatile u32 __iomem *dsp_registers; /* DSP's register base */ | 449 | volatile u32 __iomem *dsp_registers; /* DSP's register base */ |
450 | u32 active_mask; /* Chs. active mask or | 450 | u32 active_mask; /* Chs. active mask or |
451 | * punks out */ | 451 | * punks out */ |
452 | #ifdef CONFIG_PM | ||
453 | const struct firmware *fw_cache[8]; /* Cached firmwares */ | ||
454 | #endif | ||
452 | 455 | ||
453 | #ifdef ECHOCARD_HAS_MIDI | 456 | #ifdef ECHOCARD_HAS_MIDI |
454 | u16 mtc_state; /* State for MIDI input parsing state machine */ | 457 | u16 mtc_state; /* State for MIDI input parsing state machine */ |
@@ -464,11 +467,13 @@ static int load_firmware(struct echoaudio *chip); | |||
464 | static int wait_handshake(struct echoaudio *chip); | 467 | static int wait_handshake(struct echoaudio *chip); |
465 | static int send_vector(struct echoaudio *chip, u32 command); | 468 | static int send_vector(struct echoaudio *chip, u32 command); |
466 | static int get_firmware(const struct firmware **fw_entry, | 469 | static int get_firmware(const struct firmware **fw_entry, |
467 | const struct firmware *frm, struct echoaudio *chip); | 470 | struct echoaudio *chip, const short fw_index); |
468 | static void free_firmware(const struct firmware *fw_entry); | 471 | static void free_firmware(const struct firmware *fw_entry); |
469 | 472 | ||
470 | #ifdef ECHOCARD_HAS_MIDI | 473 | #ifdef ECHOCARD_HAS_MIDI |
471 | static int enable_midi_input(struct echoaudio *chip, char enable); | 474 | static int enable_midi_input(struct echoaudio *chip, char enable); |
475 | static void snd_echo_midi_output_trigger( | ||
476 | struct snd_rawmidi_substream *substream, int up); | ||
472 | static int midi_service_irq(struct echoaudio *chip); | 477 | static int midi_service_irq(struct echoaudio *chip); |
473 | static int __devinit snd_echo_midi_create(struct snd_card *card, | 478 | static int __devinit snd_echo_midi_create(struct snd_card *card, |
474 | struct echoaudio *chip); | 479 | struct echoaudio *chip); |
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index e32a74897921..658db44ef746 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -227,12 +227,11 @@ static int load_asic(struct echoaudio *chip) | |||
227 | /* Give the DSP a few milliseconds to settle down */ | 227 | /* Give the DSP a few milliseconds to settle down */ |
228 | mdelay(2); | 228 | mdelay(2); |
229 | 229 | ||
230 | err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, | 230 | err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC); |
231 | &card_fw[FW_3G_ASIC]); | ||
232 | if (err < 0) | 231 | if (err < 0) |
233 | return err; | 232 | return err; |
234 | 233 | ||
235 | chip->asic_code = &card_fw[FW_3G_ASIC]; | 234 | chip->asic_code = FW_3G_ASIC; |
236 | 235 | ||
237 | /* Now give the new ASIC some time to set up */ | 236 | /* Now give the new ASIC some time to set up */ |
238 | msleep(1000); | 237 | msleep(1000); |
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 4df51ef5e095..64417a733220 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c | |||
@@ -175,15 +175,15 @@ static inline int check_asic_status(struct echoaudio *chip) | |||
175 | #ifdef ECHOCARD_HAS_ASIC | 175 | #ifdef ECHOCARD_HAS_ASIC |
176 | 176 | ||
177 | /* Load ASIC code - done after the DSP is loaded */ | 177 | /* Load ASIC code - done after the DSP is loaded */ |
178 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | 178 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) |
179 | const struct firmware *asic) | ||
180 | { | 179 | { |
181 | const struct firmware *fw; | 180 | const struct firmware *fw; |
182 | int err; | 181 | int err; |
183 | u32 i, size; | 182 | u32 i, size; |
184 | u8 *code; | 183 | u8 *code; |
185 | 184 | ||
186 | if ((err = get_firmware(&fw, asic, chip)) < 0) { | 185 | err = get_firmware(&fw, chip, asic); |
186 | if (err < 0) { | ||
187 | snd_printk(KERN_WARNING "Firmware not found !\n"); | 187 | snd_printk(KERN_WARNING "Firmware not found !\n"); |
188 | return err; | 188 | return err; |
189 | } | 189 | } |
@@ -245,7 +245,8 @@ static int install_resident_loader(struct echoaudio *chip) | |||
245 | return 0; | 245 | return 0; |
246 | } | 246 | } |
247 | 247 | ||
248 | if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { | 248 | i = get_firmware(&fw, chip, FW_361_LOADER); |
249 | if (i < 0) { | ||
249 | snd_printk(KERN_WARNING "Firmware not found !\n"); | 250 | snd_printk(KERN_WARNING "Firmware not found !\n"); |
250 | return i; | 251 | return i; |
251 | } | 252 | } |
@@ -485,7 +486,8 @@ static int load_firmware(struct echoaudio *chip) | |||
485 | chip->dsp_code = NULL; | 486 | chip->dsp_code = NULL; |
486 | } | 487 | } |
487 | 488 | ||
488 | if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) | 489 | err = get_firmware(&fw, chip, chip->dsp_code_to_load); |
490 | if (err < 0) | ||
489 | return err; | 491 | return err; |
490 | err = load_dsp(chip, (u16 *)fw->data); | 492 | err = load_dsp(chip, (u16 *)fw->data); |
491 | free_firmware(fw); | 493 | free_firmware(fw); |
@@ -495,9 +497,6 @@ static int load_firmware(struct echoaudio *chip) | |||
495 | if ((box_type = load_asic(chip)) < 0) | 497 | if ((box_type = load_asic(chip)) < 0) |
496 | return box_type; /* error */ | 498 | return box_type; /* error */ |
497 | 499 | ||
498 | if ((err = restore_dsp_rettings(chip)) < 0) | ||
499 | return err; | ||
500 | |||
501 | return box_type; | 500 | return box_type; |
502 | } | 501 | } |
503 | 502 | ||
@@ -657,51 +656,106 @@ static void get_audio_meters(struct echoaudio *chip, long *meters) | |||
657 | 656 | ||
658 | static int restore_dsp_rettings(struct echoaudio *chip) | 657 | static int restore_dsp_rettings(struct echoaudio *chip) |
659 | { | 658 | { |
660 | int err; | 659 | int i, o, err; |
661 | DE_INIT(("restore_dsp_settings\n")); | 660 | DE_INIT(("restore_dsp_settings\n")); |
662 | 661 | ||
663 | if ((err = check_asic_status(chip)) < 0) | 662 | if ((err = check_asic_status(chip)) < 0) |
664 | return err; | 663 | return err; |
665 | 664 | ||
666 | /* @ Gina20/Darla20 only. Should be harmless for other cards. */ | 665 | /* Gina20/Darla20 only. Should be harmless for other cards. */ |
667 | chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; | 666 | chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; |
668 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; | 667 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; |
669 | chip->comm_page->handshake = 0xffffffff; | 668 | chip->comm_page->handshake = 0xffffffff; |
670 | 669 | ||
671 | if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) | 670 | /* Restore output busses */ |
671 | for (i = 0; i < num_busses_out(chip); i++) { | ||
672 | err = set_output_gain(chip, i, chip->output_gain[i]); | ||
673 | if (err < 0) | ||
674 | return err; | ||
675 | } | ||
676 | |||
677 | #ifdef ECHOCARD_HAS_VMIXER | ||
678 | for (i = 0; i < num_pipes_out(chip); i++) | ||
679 | for (o = 0; o < num_busses_out(chip); o++) { | ||
680 | err = set_vmixer_gain(chip, o, i, | ||
681 | chip->vmixer_gain[o][i]); | ||
682 | if (err < 0) | ||
683 | return err; | ||
684 | } | ||
685 | if (update_vmixer_level(chip) < 0) | ||
686 | return -EIO; | ||
687 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
688 | |||
689 | #ifdef ECHOCARD_HAS_MONITOR | ||
690 | for (o = 0; o < num_busses_out(chip); o++) | ||
691 | for (i = 0; i < num_busses_in(chip); i++) { | ||
692 | err = set_monitor_gain(chip, o, i, | ||
693 | chip->monitor_gain[o][i]); | ||
694 | if (err < 0) | ||
695 | return err; | ||
696 | } | ||
697 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
698 | |||
699 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
700 | for (i = 0; i < num_busses_in(chip); i++) { | ||
701 | err = set_input_gain(chip, i, chip->input_gain[i]); | ||
702 | if (err < 0) | ||
703 | return err; | ||
704 | } | ||
705 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
706 | |||
707 | err = update_output_line_level(chip); | ||
708 | if (err < 0) | ||
672 | return err; | 709 | return err; |
673 | 710 | ||
674 | if (chip->meters_enabled) | 711 | err = update_input_line_level(chip); |
675 | if (send_vector(chip, DSP_VC_METERS_ON) < 0) | 712 | if (err < 0) |
676 | return -EIO; | 713 | return err; |
677 | 714 | ||
678 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | 715 | err = set_sample_rate(chip, chip->sample_rate); |
679 | if (set_input_clock(chip, chip->input_clock) < 0) | 716 | if (err < 0) |
717 | return err; | ||
718 | |||
719 | if (chip->meters_enabled) { | ||
720 | err = send_vector(chip, DSP_VC_METERS_ON); | ||
721 | if (err < 0) | ||
722 | return err; | ||
723 | } | ||
724 | |||
725 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
726 | if (set_digital_mode(chip, chip->digital_mode) < 0) | ||
680 | return -EIO; | 727 | return -EIO; |
681 | #endif | 728 | #endif |
682 | 729 | ||
683 | #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH | 730 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
684 | if (set_output_clock(chip, chip->output_clock) < 0) | 731 | if (set_professional_spdif(chip, chip->professional_spdif) < 0) |
685 | return -EIO; | 732 | return -EIO; |
686 | #endif | 733 | #endif |
687 | 734 | ||
688 | if (update_output_line_level(chip) < 0) | 735 | #ifdef ECHOCARD_HAS_PHANTOM_POWER |
736 | if (set_phantom_power(chip, chip->phantom_power) < 0) | ||
689 | return -EIO; | 737 | return -EIO; |
738 | #endif | ||
690 | 739 | ||
691 | if (update_input_line_level(chip) < 0) | 740 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK |
741 | /* set_input_clock() also restores automute setting */ | ||
742 | if (set_input_clock(chip, chip->input_clock) < 0) | ||
692 | return -EIO; | 743 | return -EIO; |
744 | #endif | ||
693 | 745 | ||
694 | #ifdef ECHOCARD_HAS_VMIXER | 746 | #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH |
695 | if (update_vmixer_level(chip) < 0) | 747 | if (set_output_clock(chip, chip->output_clock) < 0) |
696 | return -EIO; | 748 | return -EIO; |
697 | #endif | 749 | #endif |
698 | 750 | ||
699 | if (wait_handshake(chip) < 0) | 751 | if (wait_handshake(chip) < 0) |
700 | return -EIO; | 752 | return -EIO; |
701 | clear_handshake(chip); | 753 | clear_handshake(chip); |
754 | if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) | ||
755 | return -EIO; | ||
702 | 756 | ||
703 | DE_INIT(("restore_dsp_rettings done\n")); | 757 | DE_INIT(("restore_dsp_rettings done\n")); |
704 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | 758 | return 0; |
705 | } | 759 | } |
706 | 760 | ||
707 | 761 | ||
@@ -918,9 +972,6 @@ static int init_dsp_comm_page(struct echoaudio *chip) | |||
918 | chip->card_name = ECHOCARD_NAME; | 972 | chip->card_name = ECHOCARD_NAME; |
919 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | 973 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ |
920 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | 974 | chip->dsp_code = NULL; /* Current DSP code not loaded */ |
921 | chip->digital_mode = DIGITAL_MODE_NONE; | ||
922 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
923 | chip->output_clock = ECHO_CLOCK_WORD; | ||
924 | chip->asic_loaded = FALSE; | 975 | chip->asic_loaded = FALSE; |
925 | memset(chip->comm_page, 0, sizeof(struct comm_page)); | 976 | memset(chip->comm_page, 0, sizeof(struct comm_page)); |
926 | 977 | ||
@@ -931,7 +982,6 @@ static int init_dsp_comm_page(struct echoaudio *chip) | |||
931 | chip->comm_page->midi_out_free_count = | 982 | chip->comm_page->midi_out_free_count = |
932 | cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); | 983 | cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); |
933 | chip->comm_page->sample_rate = cpu_to_le32(44100); | 984 | chip->comm_page->sample_rate = cpu_to_le32(44100); |
934 | chip->sample_rate = 44100; | ||
935 | 985 | ||
936 | /* Set line levels so we don't blast any inputs on startup */ | 986 | /* Set line levels so we don't blast any inputs on startup */ |
937 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); | 987 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); |
@@ -942,50 +992,21 @@ static int init_dsp_comm_page(struct echoaudio *chip) | |||
942 | 992 | ||
943 | 993 | ||
944 | 994 | ||
945 | /* This function initializes the several volume controls for busses and pipes. | 995 | /* This function initializes the chip structure with default values, ie. all |
946 | This MUST be called after the DSP is up and running ! */ | 996 | * muted and internal clock source. Then it copies the settings to the DSP. |
997 | * This MUST be called after the DSP is up and running ! | ||
998 | */ | ||
947 | static int init_line_levels(struct echoaudio *chip) | 999 | static int init_line_levels(struct echoaudio *chip) |
948 | { | 1000 | { |
949 | int st, i, o; | ||
950 | |||
951 | DE_INIT(("init_line_levels\n")); | 1001 | DE_INIT(("init_line_levels\n")); |
952 | 1002 | memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); | |
953 | /* Mute output busses */ | 1003 | memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); |
954 | for (i = 0; i < num_busses_out(chip); i++) | 1004 | memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); |
955 | if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) | 1005 | memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain)); |
956 | return st; | 1006 | chip->input_clock = ECHO_CLOCK_INTERNAL; |
957 | if ((st = update_output_line_level(chip))) | 1007 | chip->output_clock = ECHO_CLOCK_WORD; |
958 | return st; | 1008 | chip->sample_rate = 44100; |
959 | 1009 | return restore_dsp_rettings(chip); | |
960 | #ifdef ECHOCARD_HAS_VMIXER | ||
961 | /* Mute the Vmixer */ | ||
962 | for (i = 0; i < num_pipes_out(chip); i++) | ||
963 | for (o = 0; o < num_busses_out(chip); o++) | ||
964 | if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
965 | return st; | ||
966 | if ((st = update_vmixer_level(chip))) | ||
967 | return st; | ||
968 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
969 | |||
970 | #ifdef ECHOCARD_HAS_MONITOR | ||
971 | /* Mute the monitor mixer */ | ||
972 | for (o = 0; o < num_busses_out(chip); o++) | ||
973 | for (i = 0; i < num_busses_in(chip); i++) | ||
974 | if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
975 | return st; | ||
976 | if ((st = update_output_line_level(chip))) | ||
977 | return st; | ||
978 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
979 | |||
980 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
981 | for (i = 0; i < num_busses_in(chip); i++) | ||
982 | if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED))) | ||
983 | return st; | ||
984 | if ((st = update_input_line_level(chip))) | ||
985 | return st; | ||
986 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
987 | |||
988 | return 0; | ||
989 | } | 1010 | } |
990 | 1011 | ||
991 | 1012 | ||
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c index c0e64b8f52a4..2364f8a1bc21 100644 --- a/sound/pci/echoaudio/gina20.c +++ b/sound/pci/echoaudio/gina20.c | |||
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = { | |||
67 | {0, "gina20_dsp.fw"} | 67 | {0, "gina20_dsp.fw"} |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static struct pci_device_id snd_echo_ids[] = { | 70 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
71 | {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ | 71 | {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ |
72 | {0,} | 72 | {0,} |
73 | }; | 73 | }; |
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c index 3f1e7475faea..d1615a0579d1 100644 --- a/sound/pci/echoaudio/gina20_dsp.c +++ b/sound/pci/echoaudio/gina20_dsp.c | |||
@@ -49,7 +49,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
49 | chip->device_id = device_id; | 49 | chip->device_id = device_id; |
50 | chip->subdevice_id = subdevice_id; | 50 | chip->subdevice_id = subdevice_id; |
51 | chip->bad_board = TRUE; | 51 | chip->bad_board = TRUE; |
52 | chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; | 52 | chip->dsp_code_to_load = FW_GINA20_DSP; |
53 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | 53 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; |
54 | chip->clock_state = GD_CLOCK_UNDEF; | 54 | chip->clock_state = GD_CLOCK_UNDEF; |
55 | /* Since this card has no ASIC, mark it as loaded so everything | 55 | /* Since this card has no ASIC, mark it as loaded so everything |
@@ -62,17 +62,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
62 | return err; | 62 | return err; |
63 | chip->bad_board = FALSE; | 63 | chip->bad_board = FALSE; |
64 | 64 | ||
65 | if ((err = init_line_levels(chip)) < 0) | ||
66 | return err; | ||
67 | |||
68 | err = set_professional_spdif(chip, TRUE); | ||
69 | |||
70 | DE_INIT(("init_hw done\n")); | 65 | DE_INIT(("init_hw done\n")); |
71 | return err; | 66 | return err; |
72 | } | 67 | } |
73 | 68 | ||
74 | 69 | ||
75 | 70 | ||
71 | static int set_mixer_defaults(struct echoaudio *chip) | ||
72 | { | ||
73 | chip->professional_spdif = FALSE; | ||
74 | return init_line_levels(chip); | ||
75 | } | ||
76 | |||
77 | |||
78 | |||
76 | static u32 detect_input_clocks(const struct echoaudio *chip) | 79 | static u32 detect_input_clocks(const struct echoaudio *chip) |
77 | { | 80 | { |
78 | u32 clocks_from_dsp, clock_bits; | 81 | u32 clocks_from_dsp, clock_bits; |
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c index c36a78dd0b5e..616b55825a19 100644 --- a/sound/pci/echoaudio/gina24.c +++ b/sound/pci/echoaudio/gina24.c | |||
@@ -85,7 +85,7 @@ static const struct firmware card_fw[] = { | |||
85 | {0, "gina24_361_asic.fw"} | 85 | {0, "gina24_361_asic.fw"} |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct pci_device_id snd_echo_ids[] = { | 88 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
89 | {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ | 89 | {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ |
90 | {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ | 90 | {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ |
91 | {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ | 91 | {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ |
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c index 2fef37a2a5b9..98f7cfa81b5f 100644 --- a/sound/pci/echoaudio/gina24_dsp.c +++ b/sound/pci/echoaudio/gina24_dsp.c | |||
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force); | |||
33 | static int set_input_clock(struct echoaudio *chip, u16 clock); | 33 | static int set_input_clock(struct echoaudio *chip, u16 clock); |
34 | static int set_professional_spdif(struct echoaudio *chip, char prof); | 34 | static int set_professional_spdif(struct echoaudio *chip, char prof); |
35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | 35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); |
36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | 36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); |
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | 37 | static int check_asic_status(struct echoaudio *chip); |
39 | 38 | ||
40 | 39 | ||
@@ -58,19 +57,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | 57 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | |
59 | ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | | 58 | ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | |
60 | ECHO_CLOCK_BIT_ADAT; | 59 | ECHO_CLOCK_BIT_ADAT; |
61 | chip->professional_spdif = FALSE; | ||
62 | chip->digital_in_automute = TRUE; | ||
63 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
64 | 60 | ||
65 | /* Gina24 comes in both '301 and '361 flavors */ | 61 | /* Gina24 comes in both '301 and '361 flavors */ |
66 | if (chip->device_id == DEVICE_ID_56361) { | 62 | if (chip->device_id == DEVICE_ID_56361) { |
67 | chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; | 63 | chip->dsp_code_to_load = FW_GINA24_361_DSP; |
68 | chip->digital_modes = | 64 | chip->digital_modes = |
69 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | 65 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | |
70 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | 66 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | |
71 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | 67 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; |
72 | } else { | 68 | } else { |
73 | chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; | 69 | chip->dsp_code_to_load = FW_GINA24_301_DSP; |
74 | chip->digital_modes = | 70 | chip->digital_modes = |
75 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | 71 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | |
76 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | 72 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | |
@@ -82,19 +78,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
82 | return err; | 78 | return err; |
83 | chip->bad_board = FALSE; | 79 | chip->bad_board = FALSE; |
84 | 80 | ||
85 | if ((err = init_line_levels(chip)) < 0) | ||
86 | return err; | ||
87 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
88 | if (err < 0) | ||
89 | return err; | ||
90 | err = set_professional_spdif(chip, TRUE); | ||
91 | |||
92 | DE_INIT(("init_hw done\n")); | 81 | DE_INIT(("init_hw done\n")); |
93 | return err; | 82 | return err; |
94 | } | 83 | } |
95 | 84 | ||
96 | 85 | ||
97 | 86 | ||
87 | static int set_mixer_defaults(struct echoaudio *chip) | ||
88 | { | ||
89 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
90 | chip->professional_spdif = FALSE; | ||
91 | chip->digital_in_automute = TRUE; | ||
92 | return init_line_levels(chip); | ||
93 | } | ||
94 | |||
95 | |||
96 | |||
98 | static u32 detect_input_clocks(const struct echoaudio *chip) | 97 | static u32 detect_input_clocks(const struct echoaudio *chip) |
99 | { | 98 | { |
100 | u32 clocks_from_dsp, clock_bits; | 99 | u32 clocks_from_dsp, clock_bits; |
@@ -125,7 +124,7 @@ static int load_asic(struct echoaudio *chip) | |||
125 | { | 124 | { |
126 | u32 control_reg; | 125 | u32 control_reg; |
127 | int err; | 126 | int err; |
128 | const struct firmware *fw; | 127 | short asic; |
129 | 128 | ||
130 | if (chip->asic_loaded) | 129 | if (chip->asic_loaded) |
131 | return 1; | 130 | return 1; |
@@ -135,14 +134,15 @@ static int load_asic(struct echoaudio *chip) | |||
135 | 134 | ||
136 | /* Pick the correct ASIC for '301 or '361 Gina24 */ | 135 | /* Pick the correct ASIC for '301 or '361 Gina24 */ |
137 | if (chip->device_id == DEVICE_ID_56361) | 136 | if (chip->device_id == DEVICE_ID_56361) |
138 | fw = &card_fw[FW_GINA24_361_ASIC]; | 137 | asic = FW_GINA24_361_ASIC; |
139 | else | 138 | else |
140 | fw = &card_fw[FW_GINA24_301_ASIC]; | 139 | asic = FW_GINA24_301_ASIC; |
141 | 140 | ||
142 | if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) | 141 | err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic); |
142 | if (err < 0) | ||
143 | return err; | 143 | return err; |
144 | 144 | ||
145 | chip->asic_code = fw; | 145 | chip->asic_code = asic; |
146 | 146 | ||
147 | /* Now give the new ASIC a little time to set up */ | 147 | /* Now give the new ASIC a little time to set up */ |
148 | mdelay(10); | 148 | mdelay(10); |
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c index 0a58a7c1fd7c..776175c0bdad 100644 --- a/sound/pci/echoaudio/indigo.c +++ b/sound/pci/echoaudio/indigo.c | |||
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = { | |||
68 | {0, "indigo_dsp.fw"} | 68 | {0, "indigo_dsp.fw"} |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static struct pci_device_id snd_echo_ids[] = { | 71 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
72 | {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ | 72 | {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ |
73 | {0,} | 73 | {0,} |
74 | }; | 74 | }; |
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c index 0b2cd9c86277..5e85f14fe5a8 100644 --- a/sound/pci/echoaudio/indigo_dsp.c +++ b/sound/pci/echoaudio/indigo_dsp.c | |||
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
50 | chip->device_id = device_id; | 50 | chip->device_id = device_id; |
51 | chip->subdevice_id = subdevice_id; | 51 | chip->subdevice_id = subdevice_id; |
52 | chip->bad_board = TRUE; | 52 | chip->bad_board = TRUE; |
53 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; | 53 | chip->dsp_code_to_load = FW_INDIGO_DSP; |
54 | /* Since this card has no ASIC, mark it as loaded so everything | 54 | /* Since this card has no ASIC, mark it as loaded so everything |
55 | works OK */ | 55 | works OK */ |
56 | chip->asic_loaded = TRUE; | 56 | chip->asic_loaded = TRUE; |
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | if ((err = init_line_levels(chip)) < 0) | ||
64 | return err; | ||
65 | |||
66 | DE_INIT(("init_hw done\n")); | 63 | DE_INIT(("init_hw done\n")); |
67 | return err; | 64 | return err; |
68 | } | 65 | } |
69 | 66 | ||
70 | 67 | ||
71 | 68 | ||
69 | static int set_mixer_defaults(struct echoaudio *chip) | ||
70 | { | ||
71 | return init_line_levels(chip); | ||
72 | } | ||
73 | |||
74 | |||
75 | |||
72 | static u32 detect_input_clocks(const struct echoaudio *chip) | 76 | static u32 detect_input_clocks(const struct echoaudio *chip) |
73 | { | 77 | { |
74 | return ECHO_CLOCK_BIT_INTERNAL; | 78 | return ECHO_CLOCK_BIT_INTERNAL; |
diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c index 9ab625e15652..2e4ab3e34a74 100644 --- a/sound/pci/echoaudio/indigo_express_dsp.c +++ b/sound/pci/echoaudio/indigo_express_dsp.c | |||
@@ -61,6 +61,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
61 | 61 | ||
62 | control_reg |= clock; | 62 | control_reg |= clock; |
63 | if (control_reg != old_control_reg) { | 63 | if (control_reg != old_control_reg) { |
64 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
64 | chip->comm_page->control_register = cpu_to_le32(control_reg); | 65 | chip->comm_page->control_register = cpu_to_le32(control_reg); |
65 | chip->sample_rate = rate; | 66 | chip->sample_rate = rate; |
66 | clear_handshake(chip); | 67 | clear_handshake(chip); |
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c index 2db24d29332b..8816b0bd2ba6 100644 --- a/sound/pci/echoaudio/indigodj.c +++ b/sound/pci/echoaudio/indigodj.c | |||
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = { | |||
68 | {0, "indigo_dj_dsp.fw"} | 68 | {0, "indigo_dj_dsp.fw"} |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static struct pci_device_id snd_echo_ids[] = { | 71 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
72 | {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ | 72 | {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ |
73 | {0,} | 73 | {0,} |
74 | }; | 74 | }; |
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c index 08392916691e..68f3c8ccc1bf 100644 --- a/sound/pci/echoaudio/indigodj_dsp.c +++ b/sound/pci/echoaudio/indigodj_dsp.c | |||
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
50 | chip->device_id = device_id; | 50 | chip->device_id = device_id; |
51 | chip->subdevice_id = subdevice_id; | 51 | chip->subdevice_id = subdevice_id; |
52 | chip->bad_board = TRUE; | 52 | chip->bad_board = TRUE; |
53 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; | 53 | chip->dsp_code_to_load = FW_INDIGO_DJ_DSP; |
54 | /* Since this card has no ASIC, mark it as loaded so everything | 54 | /* Since this card has no ASIC, mark it as loaded so everything |
55 | works OK */ | 55 | works OK */ |
56 | chip->asic_loaded = TRUE; | 56 | chip->asic_loaded = TRUE; |
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | if ((err = init_line_levels(chip)) < 0) | ||
64 | return err; | ||
65 | |||
66 | DE_INIT(("init_hw done\n")); | 63 | DE_INIT(("init_hw done\n")); |
67 | return err; | 64 | return err; |
68 | } | 65 | } |
69 | 66 | ||
70 | 67 | ||
71 | 68 | ||
69 | static int set_mixer_defaults(struct echoaudio *chip) | ||
70 | { | ||
71 | return init_line_levels(chip); | ||
72 | } | ||
73 | |||
74 | |||
75 | |||
72 | static u32 detect_input_clocks(const struct echoaudio *chip) | 76 | static u32 detect_input_clocks(const struct echoaudio *chip) |
73 | { | 77 | { |
74 | return ECHO_CLOCK_BIT_INTERNAL; | 78 | return ECHO_CLOCK_BIT_INTERNAL; |
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c index 2e44316530a2..b1e3652f2f48 100644 --- a/sound/pci/echoaudio/indigodjx.c +++ b/sound/pci/echoaudio/indigodjx.c | |||
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = { | |||
68 | {0, "indigo_djx_dsp.fw"} | 68 | {0, "indigo_djx_dsp.fw"} |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static struct pci_device_id snd_echo_ids[] = { | 71 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
72 | {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/ | 72 | {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/ |
73 | {0,} | 73 | {0,} |
74 | }; | 74 | }; |
diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c index f591fc2ed960..bb9632c752a9 100644 --- a/sound/pci/echoaudio/indigodjx_dsp.c +++ b/sound/pci/echoaudio/indigodjx_dsp.c | |||
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
48 | chip->device_id = device_id; | 48 | chip->device_id = device_id; |
49 | chip->subdevice_id = subdevice_id; | 49 | chip->subdevice_id = subdevice_id; |
50 | chip->bad_board = TRUE; | 50 | chip->bad_board = TRUE; |
51 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJX_DSP]; | 51 | chip->dsp_code_to_load = FW_INDIGO_DJX_DSP; |
52 | /* Since this card has no ASIC, mark it as loaded so everything | 52 | /* Since this card has no ASIC, mark it as loaded so everything |
53 | works OK */ | 53 | works OK */ |
54 | chip->asic_loaded = TRUE; | 54 | chip->asic_loaded = TRUE; |
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
59 | return err; | 59 | return err; |
60 | chip->bad_board = FALSE; | 60 | chip->bad_board = FALSE; |
61 | 61 | ||
62 | err = init_line_levels(chip); | ||
63 | if (err < 0) | ||
64 | return err; | ||
65 | |||
66 | DE_INIT(("init_hw done\n")); | 62 | DE_INIT(("init_hw done\n")); |
67 | return err; | 63 | return err; |
68 | } | 64 | } |
65 | |||
66 | |||
67 | |||
68 | static int set_mixer_defaults(struct echoaudio *chip) | ||
69 | { | ||
70 | return init_line_levels(chip); | ||
71 | } | ||
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c index a60c0a0a89b7..1035125336d6 100644 --- a/sound/pci/echoaudio/indigoio.c +++ b/sound/pci/echoaudio/indigoio.c | |||
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = { | |||
69 | {0, "indigo_io_dsp.fw"} | 69 | {0, "indigo_io_dsp.fw"} |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct pci_device_id snd_echo_ids[] = { | 72 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
73 | {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ | 73 | {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ |
74 | {0,} | 74 | {0,} |
75 | }; | 75 | }; |
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c index 0604c8a85223..beb9a5b69892 100644 --- a/sound/pci/echoaudio/indigoio_dsp.c +++ b/sound/pci/echoaudio/indigoio_dsp.c | |||
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
50 | chip->device_id = device_id; | 50 | chip->device_id = device_id; |
51 | chip->subdevice_id = subdevice_id; | 51 | chip->subdevice_id = subdevice_id; |
52 | chip->bad_board = TRUE; | 52 | chip->bad_board = TRUE; |
53 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; | 53 | chip->dsp_code_to_load = FW_INDIGO_IO_DSP; |
54 | /* Since this card has no ASIC, mark it as loaded so everything | 54 | /* Since this card has no ASIC, mark it as loaded so everything |
55 | works OK */ | 55 | works OK */ |
56 | chip->asic_loaded = TRUE; | 56 | chip->asic_loaded = TRUE; |
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | if ((err = init_line_levels(chip)) < 0) | ||
64 | return err; | ||
65 | |||
66 | DE_INIT(("init_hw done\n")); | 63 | DE_INIT(("init_hw done\n")); |
67 | return err; | 64 | return err; |
68 | } | 65 | } |
69 | 66 | ||
70 | 67 | ||
71 | 68 | ||
69 | static int set_mixer_defaults(struct echoaudio *chip) | ||
70 | { | ||
71 | return init_line_levels(chip); | ||
72 | } | ||
73 | |||
74 | |||
75 | |||
72 | static u32 detect_input_clocks(const struct echoaudio *chip) | 76 | static u32 detect_input_clocks(const struct echoaudio *chip) |
73 | { | 77 | { |
74 | return ECHO_CLOCK_BIT_INTERNAL; | 78 | return ECHO_CLOCK_BIT_INTERNAL; |
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c index eb3819f9654a..60b7cb2753cf 100644 --- a/sound/pci/echoaudio/indigoiox.c +++ b/sound/pci/echoaudio/indigoiox.c | |||
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = { | |||
69 | {0, "indigo_iox_dsp.fw"} | 69 | {0, "indigo_iox_dsp.fw"} |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct pci_device_id snd_echo_ids[] = { | 72 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
73 | {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */ | 73 | {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */ |
74 | {0,} | 74 | {0,} |
75 | }; | 75 | }; |
diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c index f357521c79e6..394c6e76bcbc 100644 --- a/sound/pci/echoaudio/indigoiox_dsp.c +++ b/sound/pci/echoaudio/indigoiox_dsp.c | |||
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
48 | chip->device_id = device_id; | 48 | chip->device_id = device_id; |
49 | chip->subdevice_id = subdevice_id; | 49 | chip->subdevice_id = subdevice_id; |
50 | chip->bad_board = TRUE; | 50 | chip->bad_board = TRUE; |
51 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_IOX_DSP]; | 51 | chip->dsp_code_to_load = FW_INDIGO_IOX_DSP; |
52 | /* Since this card has no ASIC, mark it as loaded so everything | 52 | /* Since this card has no ASIC, mark it as loaded so everything |
53 | works OK */ | 53 | works OK */ |
54 | chip->asic_loaded = TRUE; | 54 | chip->asic_loaded = TRUE; |
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
59 | return err; | 59 | return err; |
60 | chip->bad_board = FALSE; | 60 | chip->bad_board = FALSE; |
61 | 61 | ||
62 | err = init_line_levels(chip); | ||
63 | if (err < 0) | ||
64 | return err; | ||
65 | |||
66 | DE_INIT(("init_hw done\n")); | 62 | DE_INIT(("init_hw done\n")); |
67 | return err; | 63 | return err; |
68 | } | 64 | } |
65 | |||
66 | |||
67 | |||
68 | static int set_mixer_defaults(struct echoaudio *chip) | ||
69 | { | ||
70 | return init_line_levels(chip); | ||
71 | } | ||
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c index 506194688995..8c3f5c5b5301 100644 --- a/sound/pci/echoaudio/layla20.c +++ b/sound/pci/echoaudio/layla20.c | |||
@@ -76,7 +76,7 @@ static const struct firmware card_fw[] = { | |||
76 | {0, "layla20_asic.fw"} | 76 | {0, "layla20_asic.fw"} |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct pci_device_id snd_echo_ids[] = { | 79 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
80 | {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ | 80 | {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ |
81 | {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ | 81 | {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ |
82 | {0,} | 82 | {0,} |
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c index 83750e9fd7b4..53ce94605044 100644 --- a/sound/pci/echoaudio/layla20_dsp.c +++ b/sound/pci/echoaudio/layla20_dsp.c | |||
@@ -31,8 +31,7 @@ | |||
31 | 31 | ||
32 | static int read_dsp(struct echoaudio *chip, u32 *data); | 32 | static int read_dsp(struct echoaudio *chip, u32 *data); |
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | 33 | static int set_professional_spdif(struct echoaudio *chip, char prof); |
34 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | 34 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); |
35 | const struct firmware *asic); | ||
36 | static int check_asic_status(struct echoaudio *chip); | 35 | static int check_asic_status(struct echoaudio *chip); |
37 | static int update_flags(struct echoaudio *chip); | 36 | static int update_flags(struct echoaudio *chip); |
38 | 37 | ||
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
54 | chip->subdevice_id = subdevice_id; | 53 | chip->subdevice_id = subdevice_id; |
55 | chip->bad_board = TRUE; | 54 | chip->bad_board = TRUE; |
56 | chip->has_midi = TRUE; | 55 | chip->has_midi = TRUE; |
57 | chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; | 56 | chip->dsp_code_to_load = FW_LAYLA20_DSP; |
58 | chip->input_clock_types = | 57 | chip->input_clock_types = |
59 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | 58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | |
60 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; | 59 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; |
@@ -65,17 +64,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
65 | return err; | 64 | return err; |
66 | chip->bad_board = FALSE; | 65 | chip->bad_board = FALSE; |
67 | 66 | ||
68 | if ((err = init_line_levels(chip)) < 0) | ||
69 | return err; | ||
70 | |||
71 | err = set_professional_spdif(chip, TRUE); | ||
72 | |||
73 | DE_INIT(("init_hw done\n")); | 67 | DE_INIT(("init_hw done\n")); |
74 | return err; | 68 | return err; |
75 | } | 69 | } |
76 | 70 | ||
77 | 71 | ||
78 | 72 | ||
73 | static int set_mixer_defaults(struct echoaudio *chip) | ||
74 | { | ||
75 | chip->professional_spdif = FALSE; | ||
76 | return init_line_levels(chip); | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
79 | static u32 detect_input_clocks(const struct echoaudio *chip) | 81 | static u32 detect_input_clocks(const struct echoaudio *chip) |
80 | { | 82 | { |
81 | u32 clocks_from_dsp, clock_bits; | 83 | u32 clocks_from_dsp, clock_bits; |
@@ -144,7 +146,7 @@ static int load_asic(struct echoaudio *chip) | |||
144 | return 0; | 146 | return 0; |
145 | 147 | ||
146 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, | 148 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, |
147 | &card_fw[FW_LAYLA20_ASIC]); | 149 | FW_LAYLA20_ASIC); |
148 | if (err < 0) | 150 | if (err < 0) |
149 | return err; | 151 | return err; |
150 | 152 | ||
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c index e09e3ea7781e..ed1cc0abc2b8 100644 --- a/sound/pci/echoaudio/layla24.c +++ b/sound/pci/echoaudio/layla24.c | |||
@@ -87,7 +87,7 @@ static const struct firmware card_fw[] = { | |||
87 | {0, "layla24_2S_asic.fw"} | 87 | {0, "layla24_2S_asic.fw"} |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static struct pci_device_id snd_echo_ids[] = { | 90 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
91 | {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ | 91 | {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ |
92 | {0,} | 92 | {0,} |
93 | }; | 93 | }; |
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c index d61b5cbcccad..8c041647f285 100644 --- a/sound/pci/echoaudio/layla24_dsp.c +++ b/sound/pci/echoaudio/layla24_dsp.c | |||
@@ -32,8 +32,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force); | |||
32 | static int set_input_clock(struct echoaudio *chip, u16 clock); | 32 | static int set_input_clock(struct echoaudio *chip, u16 clock); |
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | 33 | static int set_professional_spdif(struct echoaudio *chip, char prof); |
34 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | 34 | static int set_digital_mode(struct echoaudio *chip, u8 mode); |
35 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | 35 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); |
36 | const struct firmware *asic); | ||
37 | static int check_asic_status(struct echoaudio *chip); | 36 | static int check_asic_status(struct echoaudio *chip); |
38 | 37 | ||
39 | 38 | ||
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
54 | chip->subdevice_id = subdevice_id; | 53 | chip->subdevice_id = subdevice_id; |
55 | chip->bad_board = TRUE; | 54 | chip->bad_board = TRUE; |
56 | chip->has_midi = TRUE; | 55 | chip->has_midi = TRUE; |
57 | chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; | 56 | chip->dsp_code_to_load = FW_LAYLA24_DSP; |
58 | chip->input_clock_types = | 57 | chip->input_clock_types = |
59 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | 58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | |
60 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; | 59 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; |
@@ -62,9 +61,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
62 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | 61 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | |
63 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | 62 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | |
64 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | 63 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; |
65 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
66 | chip->professional_spdif = FALSE; | ||
67 | chip->digital_in_automute = TRUE; | ||
68 | 64 | ||
69 | if ((err = load_firmware(chip)) < 0) | 65 | if ((err = load_firmware(chip)) < 0) |
70 | return err; | 66 | return err; |
@@ -73,17 +69,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
73 | if ((err = init_line_levels(chip)) < 0) | 69 | if ((err = init_line_levels(chip)) < 0) |
74 | return err; | 70 | return err; |
75 | 71 | ||
76 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
77 | if (err < 0) | ||
78 | return err; | ||
79 | err = set_professional_spdif(chip, TRUE); | ||
80 | |||
81 | DE_INIT(("init_hw done\n")); | 72 | DE_INIT(("init_hw done\n")); |
82 | return err; | 73 | return err; |
83 | } | 74 | } |
84 | 75 | ||
85 | 76 | ||
86 | 77 | ||
78 | static int set_mixer_defaults(struct echoaudio *chip) | ||
79 | { | ||
80 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
81 | chip->professional_spdif = FALSE; | ||
82 | chip->digital_in_automute = TRUE; | ||
83 | return init_line_levels(chip); | ||
84 | } | ||
85 | |||
86 | |||
87 | |||
87 | static u32 detect_input_clocks(const struct echoaudio *chip) | 88 | static u32 detect_input_clocks(const struct echoaudio *chip) |
88 | { | 89 | { |
89 | u32 clocks_from_dsp, clock_bits; | 90 | u32 clocks_from_dsp, clock_bits; |
@@ -123,18 +124,18 @@ static int load_asic(struct echoaudio *chip) | |||
123 | 124 | ||
124 | /* Load the ASIC for the PCI card */ | 125 | /* Load the ASIC for the PCI card */ |
125 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, | 126 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, |
126 | &card_fw[FW_LAYLA24_1_ASIC]); | 127 | FW_LAYLA24_1_ASIC); |
127 | if (err < 0) | 128 | if (err < 0) |
128 | return err; | 129 | return err; |
129 | 130 | ||
130 | chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; | 131 | chip->asic_code = FW_LAYLA24_2S_ASIC; |
131 | 132 | ||
132 | /* Now give the new ASIC a little time to set up */ | 133 | /* Now give the new ASIC a little time to set up */ |
133 | mdelay(10); | 134 | mdelay(10); |
134 | 135 | ||
135 | /* Do the external one */ | 136 | /* Do the external one */ |
136 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, | 137 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, |
137 | &card_fw[FW_LAYLA24_2S_ASIC]); | 138 | FW_LAYLA24_2S_ASIC); |
138 | if (err < 0) | 139 | if (err < 0) |
139 | return FALSE; | 140 | return FALSE; |
140 | 141 | ||
@@ -299,7 +300,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
299 | /* Depending on what digital mode you want, Layla24 needs different ASICs | 300 | /* Depending on what digital mode you want, Layla24 needs different ASICs |
300 | loaded. This function checks the ASIC needed for the new mode and sees | 301 | loaded. This function checks the ASIC needed for the new mode and sees |
301 | if it matches the one already loaded. */ | 302 | if it matches the one already loaded. */ |
302 | static int switch_asic(struct echoaudio *chip, const struct firmware *asic) | 303 | static int switch_asic(struct echoaudio *chip, short asic) |
303 | { | 304 | { |
304 | s8 *monitors; | 305 | s8 *monitors; |
305 | 306 | ||
@@ -335,7 +336,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
335 | { | 336 | { |
336 | u32 control_reg; | 337 | u32 control_reg; |
337 | int err, incompatible_clock; | 338 | int err, incompatible_clock; |
338 | const struct firmware *asic; | 339 | short asic; |
339 | 340 | ||
340 | /* Set clock to "internal" if it's not compatible with the new mode */ | 341 | /* Set clock to "internal" if it's not compatible with the new mode */ |
341 | incompatible_clock = FALSE; | 342 | incompatible_clock = FALSE; |
@@ -344,12 +345,12 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
344 | case DIGITAL_MODE_SPDIF_RCA: | 345 | case DIGITAL_MODE_SPDIF_RCA: |
345 | if (chip->input_clock == ECHO_CLOCK_ADAT) | 346 | if (chip->input_clock == ECHO_CLOCK_ADAT) |
346 | incompatible_clock = TRUE; | 347 | incompatible_clock = TRUE; |
347 | asic = &card_fw[FW_LAYLA24_2S_ASIC]; | 348 | asic = FW_LAYLA24_2S_ASIC; |
348 | break; | 349 | break; |
349 | case DIGITAL_MODE_ADAT: | 350 | case DIGITAL_MODE_ADAT: |
350 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | 351 | if (chip->input_clock == ECHO_CLOCK_SPDIF) |
351 | incompatible_clock = TRUE; | 352 | incompatible_clock = TRUE; |
352 | asic = &card_fw[FW_LAYLA24_2A_ASIC]; | 353 | asic = FW_LAYLA24_2A_ASIC; |
353 | break; | 354 | break; |
354 | default: | 355 | default: |
355 | DE_ACT(("Digital mode not supported: %d\n", mode)); | 356 | DE_ACT(("Digital mode not supported: %d\n", mode)); |
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c index f05c8c097aa8..cc2bbfc65327 100644 --- a/sound/pci/echoaudio/mia.c +++ b/sound/pci/echoaudio/mia.c | |||
@@ -77,7 +77,7 @@ static const struct firmware card_fw[] = { | |||
77 | {0, "mia_dsp.fw"} | 77 | {0, "mia_dsp.fw"} |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static struct pci_device_id snd_echo_ids[] = { | 80 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
81 | {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ | 81 | {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ |
82 | {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ | 82 | {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ |
83 | {0,} | 83 | {0,} |
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c index 551405114cbc..6ebfa6e7ab9e 100644 --- a/sound/pci/echoaudio/mia_dsp.c +++ b/sound/pci/echoaudio/mia_dsp.c | |||
@@ -53,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
53 | chip->device_id = device_id; | 53 | chip->device_id = device_id; |
54 | chip->subdevice_id = subdevice_id; | 54 | chip->subdevice_id = subdevice_id; |
55 | chip->bad_board = TRUE; | 55 | chip->bad_board = TRUE; |
56 | chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; | 56 | chip->dsp_code_to_load = FW_MIA_DSP; |
57 | /* Since this card has no ASIC, mark it as loaded so everything | 57 | /* Since this card has no ASIC, mark it as loaded so everything |
58 | works OK */ | 58 | works OK */ |
59 | chip->asic_loaded = TRUE; | 59 | chip->asic_loaded = TRUE; |
@@ -66,15 +66,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
66 | return err; | 66 | return err; |
67 | chip->bad_board = FALSE; | 67 | chip->bad_board = FALSE; |
68 | 68 | ||
69 | if ((err = init_line_levels(chip))) | ||
70 | return err; | ||
71 | |||
72 | DE_INIT(("init_hw done\n")); | 69 | DE_INIT(("init_hw done\n")); |
73 | return err; | 70 | return err; |
74 | } | 71 | } |
75 | 72 | ||
76 | 73 | ||
77 | 74 | ||
75 | static int set_mixer_defaults(struct echoaudio *chip) | ||
76 | { | ||
77 | return init_line_levels(chip); | ||
78 | } | ||
79 | |||
80 | |||
81 | |||
78 | static u32 detect_input_clocks(const struct echoaudio *chip) | 82 | static u32 detect_input_clocks(const struct echoaudio *chip) |
79 | { | 83 | { |
80 | u32 clocks_from_dsp, clock_bits; | 84 | u32 clocks_from_dsp, clock_bits; |
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c index b05bad944901..3e7e01824b40 100644 --- a/sound/pci/echoaudio/mona.c +++ b/sound/pci/echoaudio/mona.c | |||
@@ -92,7 +92,7 @@ static const struct firmware card_fw[] = { | |||
92 | {0, "mona_2_asic.fw"} | 92 | {0, "mona_2_asic.fw"} |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static struct pci_device_id snd_echo_ids[] = { | 95 | static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { |
96 | {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ | 96 | {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ |
97 | {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ | 97 | {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ |
98 | {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ | 98 | {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ |
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index eaa619bd2a03..6e6a7eb555b8 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c | |||
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force); | |||
33 | static int set_input_clock(struct echoaudio *chip, u16 clock); | 33 | static int set_input_clock(struct echoaudio *chip, u16 clock); |
34 | static int set_professional_spdif(struct echoaudio *chip, char prof); | 34 | static int set_professional_spdif(struct echoaudio *chip, char prof); |
35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | 35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); |
36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | 36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); |
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | 37 | static int check_asic_status(struct echoaudio *chip); |
39 | 38 | ||
40 | 39 | ||
@@ -64,32 +63,30 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
64 | 63 | ||
65 | /* Mona comes in both '301 and '361 flavors */ | 64 | /* Mona comes in both '301 and '361 flavors */ |
66 | if (chip->device_id == DEVICE_ID_56361) | 65 | if (chip->device_id == DEVICE_ID_56361) |
67 | chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; | 66 | chip->dsp_code_to_load = FW_MONA_361_DSP; |
68 | else | 67 | else |
69 | chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; | 68 | chip->dsp_code_to_load = FW_MONA_301_DSP; |
70 | |||
71 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
72 | chip->professional_spdif = FALSE; | ||
73 | chip->digital_in_automute = TRUE; | ||
74 | 69 | ||
75 | if ((err = load_firmware(chip)) < 0) | 70 | if ((err = load_firmware(chip)) < 0) |
76 | return err; | 71 | return err; |
77 | chip->bad_board = FALSE; | 72 | chip->bad_board = FALSE; |
78 | 73 | ||
79 | if ((err = init_line_levels(chip)) < 0) | ||
80 | return err; | ||
81 | |||
82 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
83 | if (err < 0) | ||
84 | return err; | ||
85 | err = set_professional_spdif(chip, TRUE); | ||
86 | |||
87 | DE_INIT(("init_hw done\n")); | 74 | DE_INIT(("init_hw done\n")); |
88 | return err; | 75 | return err; |
89 | } | 76 | } |
90 | 77 | ||
91 | 78 | ||
92 | 79 | ||
80 | static int set_mixer_defaults(struct echoaudio *chip) | ||
81 | { | ||
82 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
83 | chip->professional_spdif = FALSE; | ||
84 | chip->digital_in_automute = TRUE; | ||
85 | return init_line_levels(chip); | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
93 | static u32 detect_input_clocks(const struct echoaudio *chip) | 90 | static u32 detect_input_clocks(const struct echoaudio *chip) |
94 | { | 91 | { |
95 | u32 clocks_from_dsp, clock_bits; | 92 | u32 clocks_from_dsp, clock_bits; |
@@ -120,7 +117,7 @@ static int load_asic(struct echoaudio *chip) | |||
120 | { | 117 | { |
121 | u32 control_reg; | 118 | u32 control_reg; |
122 | int err; | 119 | int err; |
123 | const struct firmware *asic; | 120 | short asic; |
124 | 121 | ||
125 | if (chip->asic_loaded) | 122 | if (chip->asic_loaded) |
126 | return 0; | 123 | return 0; |
@@ -128,9 +125,9 @@ static int load_asic(struct echoaudio *chip) | |||
128 | mdelay(10); | 125 | mdelay(10); |
129 | 126 | ||
130 | if (chip->device_id == DEVICE_ID_56361) | 127 | if (chip->device_id == DEVICE_ID_56361) |
131 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | 128 | asic = FW_MONA_361_1_ASIC48; |
132 | else | 129 | else |
133 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | 130 | asic = FW_MONA_301_1_ASIC48; |
134 | 131 | ||
135 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); | 132 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); |
136 | if (err < 0) | 133 | if (err < 0) |
@@ -141,7 +138,7 @@ static int load_asic(struct echoaudio *chip) | |||
141 | 138 | ||
142 | /* Do the external one */ | 139 | /* Do the external one */ |
143 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, | 140 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, |
144 | &card_fw[FW_MONA_2_ASIC]); | 141 | FW_MONA_2_ASIC); |
145 | if (err < 0) | 142 | if (err < 0) |
146 | return err; | 143 | return err; |
147 | 144 | ||
@@ -165,22 +162,22 @@ loaded. This function checks the ASIC needed for the new mode and sees | |||
165 | if it matches the one already loaded. */ | 162 | if it matches the one already loaded. */ |
166 | static int switch_asic(struct echoaudio *chip, char double_speed) | 163 | static int switch_asic(struct echoaudio *chip, char double_speed) |
167 | { | 164 | { |
168 | const struct firmware *asic; | ||
169 | int err; | 165 | int err; |
166 | short asic; | ||
170 | 167 | ||
171 | /* Check the clock detect bits to see if this is | 168 | /* Check the clock detect bits to see if this is |
172 | a single-speed clock or a double-speed clock; load | 169 | a single-speed clock or a double-speed clock; load |
173 | a new ASIC if necessary. */ | 170 | a new ASIC if necessary. */ |
174 | if (chip->device_id == DEVICE_ID_56361) { | 171 | if (chip->device_id == DEVICE_ID_56361) { |
175 | if (double_speed) | 172 | if (double_speed) |
176 | asic = &card_fw[FW_MONA_361_1_ASIC96]; | 173 | asic = FW_MONA_361_1_ASIC96; |
177 | else | 174 | else |
178 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | 175 | asic = FW_MONA_361_1_ASIC48; |
179 | } else { | 176 | } else { |
180 | if (double_speed) | 177 | if (double_speed) |
181 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | 178 | asic = FW_MONA_301_1_ASIC96; |
182 | else | 179 | else |
183 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | 180 | asic = FW_MONA_301_1_ASIC48; |
184 | } | 181 | } |
185 | 182 | ||
186 | if (asic != chip->asic_code) { | 183 | if (asic != chip->asic_code) { |
@@ -200,7 +197,7 @@ static int switch_asic(struct echoaudio *chip, char double_speed) | |||
200 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | 197 | static int set_sample_rate(struct echoaudio *chip, u32 rate) |
201 | { | 198 | { |
202 | u32 control_reg, clock; | 199 | u32 control_reg, clock; |
203 | const struct firmware *asic; | 200 | short asic; |
204 | char force_write; | 201 | char force_write; |
205 | 202 | ||
206 | /* Only set the clock for internal mode. */ | 203 | /* Only set the clock for internal mode. */ |
@@ -218,14 +215,14 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
218 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | 215 | if (chip->digital_mode == DIGITAL_MODE_ADAT) |
219 | return -EINVAL; | 216 | return -EINVAL; |
220 | if (chip->device_id == DEVICE_ID_56361) | 217 | if (chip->device_id == DEVICE_ID_56361) |
221 | asic = &card_fw[FW_MONA_361_1_ASIC96]; | 218 | asic = FW_MONA_361_1_ASIC96; |
222 | else | 219 | else |
223 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | 220 | asic = FW_MONA_301_1_ASIC96; |
224 | } else { | 221 | } else { |
225 | if (chip->device_id == DEVICE_ID_56361) | 222 | if (chip->device_id == DEVICE_ID_56361) |
226 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | 223 | asic = FW_MONA_361_1_ASIC48; |
227 | else | 224 | else |
228 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | 225 | asic = FW_MONA_301_1_ASIC48; |
229 | } | 226 | } |
230 | 227 | ||
231 | force_write = 0; | 228 | force_write = 0; |
@@ -410,8 +407,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
410 | case DIGITAL_MODE_ADAT: | 407 | case DIGITAL_MODE_ADAT: |
411 | /* If the current ASIC is the 96KHz ASIC, switch the ASIC | 408 | /* If the current ASIC is the 96KHz ASIC, switch the ASIC |
412 | and set to 48 KHz */ | 409 | and set to 48 KHz */ |
413 | if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || | 410 | if (chip->asic_code == FW_MONA_361_1_ASIC96 || |
414 | chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { | 411 | chip->asic_code == FW_MONA_301_1_ASIC96) { |
415 | set_sample_rate(chip, 48000); | 412 | set_sample_rate(chip, 48000); |
416 | } | 413 | } |
417 | control_reg |= GML_ADAT_MODE; | 414 | control_reg |= GML_ADAT_MODE; |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 168af67d938e..4203782d7cb7 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | |||
76 | /* | 76 | /* |
77 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 | 77 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 |
78 | */ | 78 | */ |
79 | static struct pci_device_id snd_emu10k1_ids[] = { | 79 | static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1_ids) = { |
80 | { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */ | 80 | { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */ |
81 | { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */ | 81 | { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */ |
82 | { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */ | 82 | { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */ |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 1d369ff73805..df47f738098d 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -1605,7 +1605,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci) | |||
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | // PCI IDs | 1607 | // PCI IDs |
1608 | static struct pci_device_id snd_emu10k1x_ids[] = { | 1608 | static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1x_ids) = { |
1609 | { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ | 1609 | { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ |
1610 | { 0, } | 1610 | { 0, } |
1611 | }; | 1611 | }; |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 2b82c5c723e1..c7fba5379813 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -443,7 +443,7 @@ struct ensoniq { | |||
443 | 443 | ||
444 | static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); | 444 | static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); |
445 | 445 | ||
446 | static struct pci_device_id snd_audiopci_ids[] = { | 446 | static DEFINE_PCI_DEVICE_TABLE(snd_audiopci_ids) = { |
447 | #ifdef CHIP1370 | 447 | #ifdef CHIP1370 |
448 | { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */ | 448 | { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */ |
449 | #endif | 449 | #endif |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index fb83e1ffa5cb..553b75217259 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -243,7 +243,7 @@ struct es1938 { | |||
243 | 243 | ||
244 | static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); | 244 | static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); |
245 | 245 | ||
246 | static struct pci_device_id snd_es1938_ids[] = { | 246 | static DEFINE_PCI_DEVICE_TABLE(snd_es1938_ids) = { |
247 | { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */ | 247 | { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */ |
248 | { 0, } | 248 | { 0, } |
249 | }; | 249 | }; |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index a11f453a6b6d..ecaea9fb48ec 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -551,7 +551,7 @@ struct es1968 { | |||
551 | 551 | ||
552 | static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); | 552 | static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); |
553 | 553 | ||
554 | static struct pci_device_id snd_es1968_ids[] = { | 554 | static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = { |
555 | /* Maestro 1 */ | 555 | /* Maestro 1 */ |
556 | { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, | 556 | { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, |
557 | /* Maestro 2 */ | 557 | /* Maestro 2 */ |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 83508b3964fb..e1baad74ea4b 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -205,7 +205,7 @@ struct fm801 { | |||
205 | #endif | 205 | #endif |
206 | }; | 206 | }; |
207 | 207 | ||
208 | static struct pci_device_id snd_fm801_ids[] = { | 208 | static DEFINE_PCI_DEVICE_TABLE(snd_fm801_ids) = { |
209 | { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ | 209 | { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ |
210 | { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ | 210 | { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ |
211 | { 0, } | 211 | { 0, } |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f98b47cd6cfb..26ceace88c96 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, | |||
824 | struct hda_pincfg *pin; | 824 | struct hda_pincfg *pin; |
825 | unsigned int oldcfg; | 825 | unsigned int oldcfg; |
826 | 826 | ||
827 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
828 | return -EINVAL; | ||
829 | |||
827 | oldcfg = snd_hda_codec_get_pincfg(codec, nid); | 830 | oldcfg = snd_hda_codec_get_pincfg(codec, nid); |
828 | pin = look_up_pincfg(codec, list, nid); | 831 | pin = look_up_pincfg(codec, list, nid); |
829 | if (!pin) { | 832 | if (!pin) { |
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec) | |||
899 | } | 902 | } |
900 | } | 903 | } |
901 | 904 | ||
905 | /** | ||
906 | * snd_hda_shutup_pins - Shut up all pins | ||
907 | * @codec: the HDA codec | ||
908 | * | ||
909 | * Clear all pin controls to shup up before suspend for avoiding click noise. | ||
910 | * The controls aren't cached so that they can be resumed properly. | ||
911 | */ | ||
912 | void snd_hda_shutup_pins(struct hda_codec *codec) | ||
913 | { | ||
914 | int i; | ||
915 | for (i = 0; i < codec->init_pins.used; i++) { | ||
916 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
917 | /* use read here for syncing after issuing each verb */ | ||
918 | snd_hda_codec_read(codec, pin->nid, 0, | ||
919 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
920 | } | ||
921 | } | ||
922 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | ||
923 | |||
902 | static void init_hda_cache(struct hda_cache_rec *cache, | 924 | static void init_hda_cache(struct hda_cache_rec *cache, |
903 | unsigned int record_size); | 925 | unsigned int record_size); |
904 | static void free_hda_cache(struct hda_cache_rec *cache); | 926 | static void free_hda_cache(struct hda_cache_rec *cache); |
@@ -931,6 +953,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
931 | #endif | 953 | #endif |
932 | list_del(&codec->list); | 954 | list_del(&codec->list); |
933 | snd_array_free(&codec->mixers); | 955 | snd_array_free(&codec->mixers); |
956 | snd_array_free(&codec->nids); | ||
934 | codec->bus->caddr_tbl[codec->addr] = NULL; | 957 | codec->bus->caddr_tbl[codec->addr] = NULL; |
935 | if (codec->patch_ops.free) | 958 | if (codec->patch_ops.free) |
936 | codec->patch_ops.free(codec); | 959 | codec->patch_ops.free(codec); |
@@ -985,7 +1008,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr | |||
985 | mutex_init(&codec->control_mutex); | 1008 | mutex_init(&codec->control_mutex); |
986 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1009 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
987 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1010 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
988 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); | 1011 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
1012 | snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); | ||
989 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); | 1013 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); |
990 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); | 1014 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); |
991 | if (codec->bus->modelname) { | 1015 | if (codec->bus->modelname) { |
@@ -1708,7 +1732,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1708 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1732 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); |
1709 | 1733 | ||
1710 | /** | 1734 | /** |
1711 | * snd_hda_ctl-add - Add a control element and assign to the codec | 1735 | * snd_hda_ctl_add - Add a control element and assign to the codec |
1712 | * @codec: HD-audio codec | 1736 | * @codec: HD-audio codec |
1713 | * @nid: corresponding NID (optional) | 1737 | * @nid: corresponding NID (optional) |
1714 | * @kctl: the control element to assign | 1738 | * @kctl: the control element to assign |
@@ -1723,19 +1747,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | |||
1723 | * | 1747 | * |
1724 | * snd_hda_ctl_add() checks the control subdev id field whether | 1748 | * snd_hda_ctl_add() checks the control subdev id field whether |
1725 | * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower | 1749 | * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower |
1726 | * bits value is taken as the NID to assign. | 1750 | * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit |
1751 | * specifies if kctl->private_value is a HDA amplifier value. | ||
1727 | */ | 1752 | */ |
1728 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | 1753 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, |
1729 | struct snd_kcontrol *kctl) | 1754 | struct snd_kcontrol *kctl) |
1730 | { | 1755 | { |
1731 | int err; | 1756 | int err; |
1757 | unsigned short flags = 0; | ||
1732 | struct hda_nid_item *item; | 1758 | struct hda_nid_item *item; |
1733 | 1759 | ||
1734 | if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { | 1760 | if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) { |
1761 | flags |= HDA_NID_ITEM_AMP; | ||
1735 | if (nid == 0) | 1762 | if (nid == 0) |
1736 | nid = kctl->id.subdevice & 0xffff; | 1763 | nid = get_amp_nid_(kctl->private_value); |
1737 | kctl->id.subdevice = 0; | ||
1738 | } | 1764 | } |
1765 | if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0) | ||
1766 | nid = kctl->id.subdevice & 0xffff; | ||
1767 | if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG)) | ||
1768 | kctl->id.subdevice = 0; | ||
1739 | err = snd_ctl_add(codec->bus->card, kctl); | 1769 | err = snd_ctl_add(codec->bus->card, kctl); |
1740 | if (err < 0) | 1770 | if (err < 0) |
1741 | return err; | 1771 | return err; |
@@ -1744,11 +1774,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | |||
1744 | return -ENOMEM; | 1774 | return -ENOMEM; |
1745 | item->kctl = kctl; | 1775 | item->kctl = kctl; |
1746 | item->nid = nid; | 1776 | item->nid = nid; |
1777 | item->flags = flags; | ||
1747 | return 0; | 1778 | return 0; |
1748 | } | 1779 | } |
1749 | EXPORT_SYMBOL_HDA(snd_hda_ctl_add); | 1780 | EXPORT_SYMBOL_HDA(snd_hda_ctl_add); |
1750 | 1781 | ||
1751 | /** | 1782 | /** |
1783 | * snd_hda_add_nid - Assign a NID to a control element | ||
1784 | * @codec: HD-audio codec | ||
1785 | * @nid: corresponding NID (optional) | ||
1786 | * @kctl: the control element to assign | ||
1787 | * @index: index to kctl | ||
1788 | * | ||
1789 | * Add the given control element to an array inside the codec instance. | ||
1790 | * This function is used when #snd_hda_ctl_add cannot be used for 1:1 | ||
1791 | * NID:KCTL mapping - for example "Capture Source" selector. | ||
1792 | */ | ||
1793 | int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, | ||
1794 | unsigned int index, hda_nid_t nid) | ||
1795 | { | ||
1796 | struct hda_nid_item *item; | ||
1797 | |||
1798 | if (nid > 0) { | ||
1799 | item = snd_array_new(&codec->nids); | ||
1800 | if (!item) | ||
1801 | return -ENOMEM; | ||
1802 | item->kctl = kctl; | ||
1803 | item->index = index; | ||
1804 | item->nid = nid; | ||
1805 | return 0; | ||
1806 | } | ||
1807 | return -EINVAL; | ||
1808 | } | ||
1809 | EXPORT_SYMBOL_HDA(snd_hda_add_nid); | ||
1810 | |||
1811 | /** | ||
1752 | * snd_hda_ctls_clear - Clear all controls assigned to the given codec | 1812 | * snd_hda_ctls_clear - Clear all controls assigned to the given codec |
1753 | * @codec: HD-audio codec | 1813 | * @codec: HD-audio codec |
1754 | */ | 1814 | */ |
@@ -1759,6 +1819,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec) | |||
1759 | for (i = 0; i < codec->mixers.used; i++) | 1819 | for (i = 0; i < codec->mixers.used; i++) |
1760 | snd_ctl_remove(codec->bus->card, items[i].kctl); | 1820 | snd_ctl_remove(codec->bus->card, items[i].kctl); |
1761 | snd_array_free(&codec->mixers); | 1821 | snd_array_free(&codec->mixers); |
1822 | snd_array_free(&codec->nids); | ||
1762 | } | 1823 | } |
1763 | 1824 | ||
1764 | /* pseudo device locking | 1825 | /* pseudo device locking |
@@ -3478,6 +3539,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
3478 | 3539 | ||
3479 | for (; knew->name; knew++) { | 3540 | for (; knew->name; knew++) { |
3480 | struct snd_kcontrol *kctl; | 3541 | struct snd_kcontrol *kctl; |
3542 | if (knew->iface == -1) /* skip this codec private value */ | ||
3543 | continue; | ||
3481 | kctl = snd_ctl_new1(knew, codec); | 3544 | kctl = snd_ctl_new1(knew, codec); |
3482 | if (!kctl) | 3545 | if (!kctl) |
3483 | return -ENOMEM; | 3546 | return -ENOMEM; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 0a770a28e71f..0c8f05cc56be 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -789,6 +789,7 @@ struct hda_codec { | |||
789 | u32 *wcaps; | 789 | u32 *wcaps; |
790 | 790 | ||
791 | struct snd_array mixers; /* list of assigned mixer elements */ | 791 | struct snd_array mixers; /* list of assigned mixer elements */ |
792 | struct snd_array nids; /* list of mapped mixer elements */ | ||
792 | 793 | ||
793 | struct hda_cache_rec amp_cache; /* cache for amp access */ | 794 | struct hda_cache_rec amp_cache; /* cache for amp access */ |
794 | struct hda_cache_rec cmd_cache; /* cache for other commands */ | 795 | struct hda_cache_rec cmd_cache; /* cache for other commands */ |
@@ -898,6 +899,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid, | |||
898 | unsigned int cfg); | 899 | unsigned int cfg); |
899 | int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, | 900 | int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, |
900 | hda_nid_t nid, unsigned int cfg); /* for hwdep */ | 901 | hda_nid_t nid, unsigned int cfg); /* for hwdep */ |
902 | void snd_hda_shutup_pins(struct hda_codec *codec); | ||
901 | 903 | ||
902 | /* | 904 | /* |
903 | * Mixer | 905 | * Mixer |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 092c6a7c2ff3..5ea21285ee1f 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec) | |||
861 | } | 861 | } |
862 | 862 | ||
863 | /* create input MUX if multiple sources are available */ | 863 | /* create input MUX if multiple sources are available */ |
864 | err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec)); | 864 | err = snd_hda_ctl_add(codec, spec->adc_node->nid, |
865 | snd_ctl_new1(&cap_sel, codec)); | ||
865 | if (err < 0) | 866 | if (err < 0) |
866 | return err; | 867 | return err; |
867 | 868 | ||
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 40ccb419b6e9..b36919c0d363 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \ | |||
293 | { \ | 293 | { \ |
294 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ | 294 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ |
295 | struct hda_codec *codec = hwdep->private_data; \ | 295 | struct hda_codec *codec = hwdep->private_data; \ |
296 | char *after; \ | 296 | unsigned long val; \ |
297 | codec->type = simple_strtoul(buf, &after, 0); \ | 297 | int err = strict_strtoul(buf, 0, &val); \ |
298 | if (err < 0) \ | ||
299 | return err; \ | ||
300 | codec->type = val; \ | ||
298 | return count; \ | 301 | return count; \ |
299 | } | 302 | } |
300 | 303 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3600e9cc9bc6..8d8e0b5aa248 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2683,7 +2683,7 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
2683 | } | 2683 | } |
2684 | 2684 | ||
2685 | /* PCI IDs */ | 2685 | /* PCI IDs */ |
2686 | static struct pci_device_id azx_ids[] = { | 2686 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
2687 | /* ICH 6..10 */ | 2687 | /* ICH 6..10 */ |
2688 | { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH }, | 2688 | { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH }, |
2689 | { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, | 2689 | { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, |
@@ -2723,32 +2723,10 @@ static struct pci_device_id azx_ids[] = { | |||
2723 | /* ULI M5461 */ | 2723 | /* ULI M5461 */ |
2724 | { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, | 2724 | { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, |
2725 | /* NVIDIA MCP */ | 2725 | /* NVIDIA MCP */ |
2726 | { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, | 2726 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), |
2727 | { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, | 2727 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2728 | { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, | 2728 | .class_mask = 0xffffff, |
2729 | { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, | 2729 | .driver_data = AZX_DRIVER_NVIDIA }, |
2730 | { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2731 | { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2732 | { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2733 | { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2734 | { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2735 | { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2736 | { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2737 | { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2738 | { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2739 | { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2740 | { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2741 | { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2742 | { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2743 | { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2744 | { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2745 | { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2746 | { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2747 | { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2748 | { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2749 | { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2750 | { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2751 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2752 | /* Teradici */ | 2730 | /* Teradici */ |
2753 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2731 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, |
2754 | /* Creative X-Fi (CA0110-IBG) */ | 2732 | /* Creative X-Fi (CA0110-IBG) */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 5778ae882b83..7cee364976ff 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -31,6 +31,7 @@ | |||
31 | * in snd_hda_ctl_add(), so that this value won't appear in the outside. | 31 | * in snd_hda_ctl_add(), so that this value won't appear in the outside. |
32 | */ | 32 | */ |
33 | #define HDA_SUBDEV_NID_FLAG (1U << 31) | 33 | #define HDA_SUBDEV_NID_FLAG (1U << 31) |
34 | #define HDA_SUBDEV_AMP_FLAG (1U << 30) | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * for mixer controls | 37 | * for mixer controls |
@@ -42,7 +43,7 @@ | |||
42 | /* mono volume with index (index=0,1,...) (channel=1,2) */ | 43 | /* mono volume with index (index=0,1,...) (channel=1,2) */ |
43 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 44 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
44 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 45 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
45 | .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ | 46 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
46 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 47 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ |
47 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 48 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ |
48 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ | 49 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ |
@@ -63,7 +64,7 @@ | |||
63 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ | 64 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ |
64 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 65 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
65 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 66 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
66 | .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ | 67 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
67 | .info = snd_hda_mixer_amp_switch_info, \ | 68 | .info = snd_hda_mixer_amp_switch_info, \ |
68 | .get = snd_hda_mixer_amp_switch_get, \ | 69 | .get = snd_hda_mixer_amp_switch_get, \ |
69 | .put = snd_hda_mixer_amp_switch_put, \ | 70 | .put = snd_hda_mixer_amp_switch_put, \ |
@@ -81,7 +82,7 @@ | |||
81 | /* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ | 82 | /* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ |
82 | #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 83 | #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
83 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 84 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
84 | .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ | 85 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
85 | .info = snd_hda_mixer_amp_switch_info, \ | 86 | .info = snd_hda_mixer_amp_switch_info, \ |
86 | .get = snd_hda_mixer_amp_switch_get, \ | 87 | .get = snd_hda_mixer_amp_switch_get, \ |
87 | .put = snd_hda_mixer_amp_switch_put_beep, \ | 88 | .put = snd_hda_mixer_amp_switch_put_beep, \ |
@@ -464,13 +465,20 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); | |||
464 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); | 465 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); |
465 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | 466 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); |
466 | 467 | ||
468 | /* flags for hda_nid_item */ | ||
469 | #define HDA_NID_ITEM_AMP (1<<0) | ||
470 | |||
467 | struct hda_nid_item { | 471 | struct hda_nid_item { |
468 | struct snd_kcontrol *kctl; | 472 | struct snd_kcontrol *kctl; |
473 | unsigned int index; | ||
469 | hda_nid_t nid; | 474 | hda_nid_t nid; |
475 | unsigned short flags; | ||
470 | }; | 476 | }; |
471 | 477 | ||
472 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | 478 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, |
473 | struct snd_kcontrol *kctl); | 479 | struct snd_kcontrol *kctl); |
480 | int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, | ||
481 | unsigned int index, hda_nid_t nid); | ||
474 | void snd_hda_ctls_clear(struct hda_codec *codec); | 482 | void snd_hda_ctls_clear(struct hda_codec *codec); |
475 | 483 | ||
476 | /* | 484 | /* |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index c9afc04adac8..f97d35de66c4 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -61,18 +61,29 @@ static const char *get_wid_type_name(unsigned int wid_value) | |||
61 | return "UNKNOWN Widget"; | 61 | return "UNKNOWN Widget"; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void print_nid_mixers(struct snd_info_buffer *buffer, | 64 | static void print_nid_array(struct snd_info_buffer *buffer, |
65 | struct hda_codec *codec, hda_nid_t nid) | 65 | struct hda_codec *codec, hda_nid_t nid, |
66 | struct snd_array *array) | ||
66 | { | 67 | { |
67 | int i; | 68 | int i; |
68 | struct hda_nid_item *items = codec->mixers.list; | 69 | struct hda_nid_item *items = array->list, *item; |
69 | struct snd_kcontrol *kctl; | 70 | struct snd_kcontrol *kctl; |
70 | for (i = 0; i < codec->mixers.used; i++) { | 71 | for (i = 0; i < array->used; i++) { |
71 | if (items[i].nid == nid) { | 72 | item = &items[i]; |
72 | kctl = items[i].kctl; | 73 | if (item->nid == nid) { |
74 | kctl = item->kctl; | ||
73 | snd_iprintf(buffer, | 75 | snd_iprintf(buffer, |
74 | " Control: name=\"%s\", index=%i, device=%i\n", | 76 | " Control: name=\"%s\", index=%i, device=%i\n", |
75 | kctl->id.name, kctl->id.index, kctl->id.device); | 77 | kctl->id.name, kctl->id.index + item->index, |
78 | kctl->id.device); | ||
79 | if (item->flags & HDA_NID_ITEM_AMP) | ||
80 | snd_iprintf(buffer, | ||
81 | " ControlAmp: chs=%lu, dir=%s, " | ||
82 | "idx=%lu, ofs=%lu\n", | ||
83 | get_amp_channels(kctl), | ||
84 | get_amp_direction(kctl) ? "Out" : "In", | ||
85 | get_amp_index(kctl), | ||
86 | get_amp_offset(kctl)); | ||
76 | } | 87 | } |
77 | } | 88 | } |
78 | } | 89 | } |
@@ -528,7 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer, | |||
528 | (data & (1<<i)) ? 1 : 0, | 539 | (data & (1<<i)) ? 1 : 0, |
529 | (unsol & (1<<i)) ? 1 : 0); | 540 | (unsol & (1<<i)) ? 1 : 0); |
530 | /* FIXME: add GPO and GPI pin information */ | 541 | /* FIXME: add GPO and GPI pin information */ |
531 | print_nid_mixers(buffer, codec, nid); | 542 | print_nid_array(buffer, codec, nid, &codec->mixers); |
543 | print_nid_array(buffer, codec, nid, &codec->nids); | ||
532 | } | 544 | } |
533 | 545 | ||
534 | static void print_codec_info(struct snd_info_entry *entry, | 546 | static void print_codec_info(struct snd_info_entry *entry, |
@@ -608,7 +620,8 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
608 | snd_iprintf(buffer, " CP"); | 620 | snd_iprintf(buffer, " CP"); |
609 | snd_iprintf(buffer, "\n"); | 621 | snd_iprintf(buffer, "\n"); |
610 | 622 | ||
611 | print_nid_mixers(buffer, codec, nid); | 623 | print_nid_array(buffer, codec, nid, &codec->mixers); |
624 | print_nid_array(buffer, codec, nid, &codec->nids); | ||
612 | print_nid_pcms(buffer, codec, nid); | 625 | print_nid_pcms(buffer, codec, nid); |
613 | 626 | ||
614 | /* volume knob is a special widget that always have connection | 627 | /* volume knob is a special widget that always have connection |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 69a941c7b158..214301d568fa 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -174,6 +174,7 @@ static struct snd_kcontrol_new ad_beep_mixer[] = { | |||
174 | static int ad198x_build_controls(struct hda_codec *codec) | 174 | static int ad198x_build_controls(struct hda_codec *codec) |
175 | { | 175 | { |
176 | struct ad198x_spec *spec = codec->spec; | 176 | struct ad198x_spec *spec = codec->spec; |
177 | struct snd_kcontrol *kctl; | ||
177 | unsigned int i; | 178 | unsigned int i; |
178 | int err; | 179 | int err; |
179 | 180 | ||
@@ -208,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
208 | if (!kctl) | 209 | if (!kctl) |
209 | return -ENOMEM; | 210 | return -ENOMEM; |
210 | kctl->private_value = spec->beep_amp; | 211 | kctl->private_value = spec->beep_amp; |
211 | err = snd_hda_ctl_add(codec, | 212 | err = snd_hda_ctl_add(codec, 0, kctl); |
212 | get_amp_nid_(spec->beep_amp), | ||
213 | kctl); | ||
214 | if (err < 0) | 213 | if (err < 0) |
215 | return err; | 214 | return err; |
216 | } | 215 | } |
@@ -239,6 +238,27 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
239 | } | 238 | } |
240 | 239 | ||
241 | ad198x_free_kctls(codec); /* no longer needed */ | 240 | ad198x_free_kctls(codec); /* no longer needed */ |
241 | |||
242 | /* assign Capture Source enums to NID */ | ||
243 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
244 | if (!kctl) | ||
245 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
246 | for (i = 0; kctl && i < kctl->count; i++) { | ||
247 | err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); | ||
248 | if (err < 0) | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | /* assign IEC958 enums to NID */ | ||
253 | kctl = snd_hda_find_mixer_ctl(codec, | ||
254 | SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); | ||
255 | if (kctl) { | ||
256 | err = snd_hda_add_nid(codec, kctl, 0, | ||
257 | spec->multiout.dig_out_nid); | ||
258 | if (err < 0) | ||
259 | return err; | ||
260 | } | ||
261 | |||
242 | return 0; | 262 | return 0; |
243 | } | 263 | } |
244 | 264 | ||
@@ -421,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
421 | return 0; | 441 | return 0; |
422 | } | 442 | } |
423 | 443 | ||
444 | static inline void ad198x_shutup(struct hda_codec *codec) | ||
445 | { | ||
446 | snd_hda_shutup_pins(codec); | ||
447 | } | ||
448 | |||
424 | static void ad198x_free_kctls(struct hda_codec *codec) | 449 | static void ad198x_free_kctls(struct hda_codec *codec) |
425 | { | 450 | { |
426 | struct ad198x_spec *spec = codec->spec; | 451 | struct ad198x_spec *spec = codec->spec; |
@@ -434,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec) | |||
434 | snd_array_free(&spec->kctls); | 459 | snd_array_free(&spec->kctls); |
435 | } | 460 | } |
436 | 461 | ||
462 | static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, | ||
463 | hda_nid_t hp) | ||
464 | { | ||
465 | struct ad198x_spec *spec = codec->spec; | ||
466 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
467 | !spec->inv_eapd ? 0x00 : 0x02); | ||
468 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
469 | !spec->inv_eapd ? 0x00 : 0x02); | ||
470 | } | ||
471 | |||
472 | static void ad198x_power_eapd(struct hda_codec *codec) | ||
473 | { | ||
474 | /* We currently only handle front, HP */ | ||
475 | switch (codec->vendor_id) { | ||
476 | case 0x11d41882: | ||
477 | case 0x11d4882a: | ||
478 | case 0x11d41884: | ||
479 | case 0x11d41984: | ||
480 | case 0x11d41883: | ||
481 | case 0x11d4184a: | ||
482 | case 0x11d4194a: | ||
483 | case 0x11d4194b: | ||
484 | ad198x_power_eapd_write(codec, 0x12, 0x11); | ||
485 | break; | ||
486 | case 0x11d41981: | ||
487 | case 0x11d41983: | ||
488 | ad198x_power_eapd_write(codec, 0x05, 0x06); | ||
489 | break; | ||
490 | case 0x11d41986: | ||
491 | ad198x_power_eapd_write(codec, 0x1b, 0x1a); | ||
492 | break; | ||
493 | case 0x11d41988: | ||
494 | case 0x11d4198b: | ||
495 | case 0x11d4989a: | ||
496 | case 0x11d4989b: | ||
497 | ad198x_power_eapd_write(codec, 0x29, 0x22); | ||
498 | break; | ||
499 | } | ||
500 | } | ||
501 | |||
437 | static void ad198x_free(struct hda_codec *codec) | 502 | static void ad198x_free(struct hda_codec *codec) |
438 | { | 503 | { |
439 | struct ad198x_spec *spec = codec->spec; | 504 | struct ad198x_spec *spec = codec->spec; |
@@ -441,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec) | |||
441 | if (!spec) | 506 | if (!spec) |
442 | return; | 507 | return; |
443 | 508 | ||
509 | ad198x_shutup(codec); | ||
444 | ad198x_free_kctls(codec); | 510 | ad198x_free_kctls(codec); |
445 | kfree(spec); | 511 | kfree(spec); |
446 | snd_hda_detach_beep_device(codec); | 512 | snd_hda_detach_beep_device(codec); |
447 | } | 513 | } |
448 | 514 | ||
515 | #ifdef SND_HDA_NEEDS_RESUME | ||
516 | static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) | ||
517 | { | ||
518 | ad198x_shutup(codec); | ||
519 | ad198x_power_eapd(codec); | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static int ad198x_resume(struct hda_codec *codec) | ||
524 | { | ||
525 | ad198x_init(codec); | ||
526 | snd_hda_codec_resume_amp(codec); | ||
527 | snd_hda_codec_resume_cache(codec); | ||
528 | return 0; | ||
529 | } | ||
530 | #endif | ||
531 | |||
449 | static struct hda_codec_ops ad198x_patch_ops = { | 532 | static struct hda_codec_ops ad198x_patch_ops = { |
450 | .build_controls = ad198x_build_controls, | 533 | .build_controls = ad198x_build_controls, |
451 | .build_pcms = ad198x_build_pcms, | 534 | .build_pcms = ad198x_build_pcms, |
@@ -454,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = { | |||
454 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 537 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
455 | .check_power_status = ad198x_check_power_status, | 538 | .check_power_status = ad198x_check_power_status, |
456 | #endif | 539 | #endif |
540 | #ifdef SND_HDA_NEEDS_RESUME | ||
541 | .suspend = ad198x_suspend, | ||
542 | .resume = ad198x_resume, | ||
543 | #endif | ||
544 | .reboot_notify = ad198x_shutup, | ||
457 | }; | 545 | }; |
458 | 546 | ||
459 | 547 | ||
@@ -701,6 +789,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | |||
701 | { | 789 | { |
702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 790 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
703 | .name = "External Amplifier", | 791 | .name = "External Amplifier", |
792 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, | ||
704 | .info = ad198x_eapd_info, | 793 | .info = ad198x_eapd_info, |
705 | .get = ad198x_eapd_get, | 794 | .get = ad198x_eapd_get, |
706 | .put = ad198x_eapd_put, | 795 | .put = ad198x_eapd_put, |
@@ -808,6 +897,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { | |||
808 | { | 897 | { |
809 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 898 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
810 | .name = "Master Playback Switch", | 899 | .name = "Master Playback Switch", |
900 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
811 | .info = snd_hda_mixer_amp_switch_info, | 901 | .info = snd_hda_mixer_amp_switch_info, |
812 | .get = snd_hda_mixer_amp_switch_get, | 902 | .get = snd_hda_mixer_amp_switch_get, |
813 | .put = ad1986a_hp_master_sw_put, | 903 | .put = ad1986a_hp_master_sw_put, |
@@ -1612,6 +1702,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = { | |||
1612 | HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), | 1702 | HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), |
1613 | { | 1703 | { |
1614 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1704 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1705 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x05, | ||
1615 | .name = "Master Playback Switch", | 1706 | .name = "Master Playback Switch", |
1616 | .info = ad198x_eapd_info, | 1707 | .info = ad198x_eapd_info, |
1617 | .get = ad198x_eapd_get, | 1708 | .get = ad198x_eapd_get, |
@@ -2136,6 +2227,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { | |||
2136 | { | 2227 | { |
2137 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2228 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2138 | .name = "External Amplifier", | 2229 | .name = "External Amplifier", |
2230 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x12, | ||
2139 | .info = ad198x_eapd_info, | 2231 | .info = ad198x_eapd_info, |
2140 | .get = ad198x_eapd_get, | 2232 | .get = ad198x_eapd_get, |
2141 | .put = ad198x_eapd_put, | 2233 | .put = ad198x_eapd_put, |
@@ -2257,6 +2349,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { | |||
2257 | { | 2349 | { |
2258 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2350 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2259 | .name = "IEC958 Playback Source", | 2351 | .name = "IEC958 Playback Source", |
2352 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, | ||
2260 | .info = ad1988_spdif_playback_source_info, | 2353 | .info = ad1988_spdif_playback_source_info, |
2261 | .get = ad1988_spdif_playback_source_get, | 2354 | .get = ad1988_spdif_playback_source_get, |
2262 | .put = ad1988_spdif_playback_source_put, | 2355 | .put = ad1988_spdif_playback_source_put, |
@@ -2372,6 +2465,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = { | |||
2372 | { } | 2465 | { } |
2373 | }; | 2466 | }; |
2374 | 2467 | ||
2468 | static struct hda_verb ad1988_spdif_in_init_verbs[] = { | ||
2469 | /* unmute SPDIF input pin */ | ||
2470 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2471 | { } | ||
2472 | }; | ||
2473 | |||
2375 | /* AD1989 has no ADC -> SPDIF route */ | 2474 | /* AD1989 has no ADC -> SPDIF route */ |
2376 | static struct hda_verb ad1989_spdif_init_verbs[] = { | 2475 | static struct hda_verb ad1989_spdif_init_verbs[] = { |
2377 | /* SPDIF-1 out pin */ | 2476 | /* SPDIF-1 out pin */ |
@@ -2589,7 +2688,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, | |||
2589 | if (! knew->name) | 2688 | if (! knew->name) |
2590 | return -ENOMEM; | 2689 | return -ENOMEM; |
2591 | if (get_amp_nid_(val)) | 2690 | if (get_amp_nid_(val)) |
2592 | knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); | 2691 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
2593 | knew->private_value = val; | 2692 | knew->private_value = val; |
2594 | return 0; | 2693 | return 0; |
2595 | } | 2694 | } |
@@ -3107,8 +3206,11 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3107 | ad1988_spdif_init_verbs; | 3206 | ad1988_spdif_init_verbs; |
3108 | } | 3207 | } |
3109 | } | 3208 | } |
3110 | if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) | 3209 | if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) { |
3111 | spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; | 3210 | spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; |
3211 | spec->init_verbs[spec->num_init_verbs++] = | ||
3212 | ad1988_spdif_in_init_verbs; | ||
3213 | } | ||
3112 | 3214 | ||
3113 | codec->patch_ops = ad198x_patch_ops; | 3215 | codec->patch_ops = ad198x_patch_ops; |
3114 | switch (board_config) { | 3216 | switch (board_config) { |
@@ -3747,6 +3849,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | |||
3747 | { | 3849 | { |
3748 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3850 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
3749 | .name = "Master Playback Switch", | 3851 | .name = "Master Playback Switch", |
3852 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
3750 | .info = snd_hda_mixer_amp_switch_info, | 3853 | .info = snd_hda_mixer_amp_switch_info, |
3751 | .get = snd_hda_mixer_amp_switch_get, | 3854 | .get = snd_hda_mixer_amp_switch_get, |
3752 | .put = ad1884a_mobile_master_sw_put, | 3855 | .put = ad1884a_mobile_master_sw_put, |
@@ -3775,6 +3878,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { | |||
3775 | { | 3878 | { |
3776 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3879 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
3777 | .name = "Master Playback Switch", | 3880 | .name = "Master Playback Switch", |
3881 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
3778 | .info = snd_hda_mixer_amp_switch_info, | 3882 | .info = snd_hda_mixer_amp_switch_info, |
3779 | .get = snd_hda_mixer_amp_switch_get, | 3883 | .get = snd_hda_mixer_amp_switch_get, |
3780 | .put = ad1884a_mobile_master_sw_put, | 3884 | .put = ad1884a_mobile_master_sw_put, |
@@ -4116,6 +4220,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { | |||
4116 | /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ | 4220 | /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ |
4117 | { | 4221 | { |
4118 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 4222 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
4223 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
4119 | .name = "Master Playback Switch", | 4224 | .name = "Master Playback Switch", |
4120 | .info = snd_hda_mixer_amp_switch_info, | 4225 | .info = snd_hda_mixer_amp_switch_info, |
4121 | .get = snd_hda_mixer_amp_switch_get, | 4226 | .get = snd_hda_mixer_amp_switch_get, |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index fe0423c39598..7de782a5b8f4 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -501,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index, | |||
501 | knew.private_value = pval; | 501 | knew.private_value = pval; |
502 | snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); | 502 | snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); |
503 | *kctlp = snd_ctl_new1(&knew, codec); | 503 | *kctlp = snd_ctl_new1(&knew, codec); |
504 | return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); | 504 | (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; |
505 | return snd_hda_ctl_add(codec, 0, *kctlp); | ||
505 | } | 506 | } |
506 | 507 | ||
507 | static int add_volume(struct hda_codec *codec, const char *name, | 508 | static int add_volume(struct hda_codec *codec, const char *name, |
@@ -514,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name, | |||
514 | knew.private_value = pval; | 515 | knew.private_value = pval; |
515 | snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); | 516 | snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); |
516 | *kctlp = snd_ctl_new1(&knew, codec); | 517 | *kctlp = snd_ctl_new1(&knew, codec); |
517 | return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); | 518 | (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; |
519 | return snd_hda_ctl_add(codec, 0, *kctlp); | ||
518 | } | 520 | } |
519 | 521 | ||
520 | static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) | 522 | static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) |
@@ -751,6 +753,7 @@ static int build_input(struct hda_codec *codec) | |||
751 | spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); | 753 | spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); |
752 | for (i = 0; i < 2; i++) { | 754 | for (i = 0; i < 2; i++) { |
753 | struct snd_kcontrol *kctl; | 755 | struct snd_kcontrol *kctl; |
756 | int n; | ||
754 | if (!spec->capture_bind[i]) | 757 | if (!spec->capture_bind[i]) |
755 | return -ENOMEM; | 758 | return -ENOMEM; |
756 | kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); | 759 | kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); |
@@ -760,6 +763,13 @@ static int build_input(struct hda_codec *codec) | |||
760 | err = snd_hda_ctl_add(codec, 0, kctl); | 763 | err = snd_hda_ctl_add(codec, 0, kctl); |
761 | if (err < 0) | 764 | if (err < 0) |
762 | return err; | 765 | return err; |
766 | for (n = 0; n < AUTO_PIN_LAST; n++) { | ||
767 | if (!spec->adc_nid[n]) | ||
768 | continue; | ||
769 | err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]); | ||
770 | if (err < 0) | ||
771 | return err; | ||
772 | } | ||
763 | } | 773 | } |
764 | 774 | ||
765 | if (spec->num_inputs > 1 && !spec->mic_detect) { | 775 | if (spec->num_inputs > 1 && !spec->mic_detect) { |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index a45c1169762b..ff60908f4554 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = { | |||
315 | static int cmi9880_build_controls(struct hda_codec *codec) | 315 | static int cmi9880_build_controls(struct hda_codec *codec) |
316 | { | 316 | { |
317 | struct cmi_spec *spec = codec->spec; | 317 | struct cmi_spec *spec = codec->spec; |
318 | int err; | 318 | struct snd_kcontrol *kctl; |
319 | int i, err; | ||
319 | 320 | ||
320 | err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); | 321 | err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); |
321 | if (err < 0) | 322 | if (err < 0) |
@@ -340,6 +341,14 @@ static int cmi9880_build_controls(struct hda_codec *codec) | |||
340 | if (err < 0) | 341 | if (err < 0) |
341 | return err; | 342 | return err; |
342 | } | 343 | } |
344 | |||
345 | /* assign Capture Source enums to NID */ | ||
346 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
347 | for (i = 0; kctl && i < kctl->count; i++) { | ||
348 | err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]); | ||
349 | if (err < 0) | ||
350 | return err; | ||
351 | } | ||
343 | return 0; | 352 | return 0; |
344 | } | 353 | } |
345 | 354 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index c578c28f368e..685015a53292 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -111,8 +111,22 @@ struct conexant_spec { | |||
111 | 111 | ||
112 | unsigned int dell_automute; | 112 | unsigned int dell_automute; |
113 | unsigned int port_d_mode; | 113 | unsigned int port_d_mode; |
114 | unsigned char ext_mic_bias; | ||
115 | unsigned int dell_vostro; | 114 | unsigned int dell_vostro; |
115 | |||
116 | unsigned int ext_mic_present; | ||
117 | unsigned int recording; | ||
118 | void (*capture_prepare)(struct hda_codec *codec); | ||
119 | void (*capture_cleanup)(struct hda_codec *codec); | ||
120 | |||
121 | /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors) | ||
122 | * through the microphone jack. | ||
123 | * When the user enables this through a mixer switch, both internal and | ||
124 | * external microphones are disabled. Gain is fixed at 0dB. In this mode, | ||
125 | * we also allow the bias to be configured through a separate mixer | ||
126 | * control. */ | ||
127 | unsigned int dc_enable; | ||
128 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ | ||
129 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ | ||
116 | }; | 130 | }; |
117 | 131 | ||
118 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 132 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
@@ -185,6 +199,8 @@ static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
185 | struct snd_pcm_substream *substream) | 199 | struct snd_pcm_substream *substream) |
186 | { | 200 | { |
187 | struct conexant_spec *spec = codec->spec; | 201 | struct conexant_spec *spec = codec->spec; |
202 | if (spec->capture_prepare) | ||
203 | spec->capture_prepare(codec); | ||
188 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], | 204 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
189 | stream_tag, 0, format); | 205 | stream_tag, 0, format); |
190 | return 0; | 206 | return 0; |
@@ -196,6 +212,8 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
196 | { | 212 | { |
197 | struct conexant_spec *spec = codec->spec; | 213 | struct conexant_spec *spec = codec->spec; |
198 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); | 214 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); |
215 | if (spec->capture_cleanup) | ||
216 | spec->capture_cleanup(codec); | ||
199 | return 0; | 217 | return 0; |
200 | } | 218 | } |
201 | 219 | ||
@@ -1723,6 +1741,22 @@ static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { | |||
1723 | {} | 1741 | {} |
1724 | }; | 1742 | }; |
1725 | 1743 | ||
1744 | static struct snd_kcontrol_new cxt5051_f700_mixers[] = { | ||
1745 | HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), | ||
1746 | HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), | ||
1747 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), | ||
1748 | { | ||
1749 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1750 | .name = "Master Playback Switch", | ||
1751 | .info = cxt_eapd_info, | ||
1752 | .get = cxt_eapd_get, | ||
1753 | .put = cxt5051_hp_master_sw_put, | ||
1754 | .private_value = 0x1a, | ||
1755 | }, | ||
1756 | |||
1757 | {} | ||
1758 | }; | ||
1759 | |||
1726 | static struct hda_verb cxt5051_init_verbs[] = { | 1760 | static struct hda_verb cxt5051_init_verbs[] = { |
1727 | /* Line in, Mic */ | 1761 | /* Line in, Mic */ |
1728 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1762 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
@@ -1813,6 +1847,32 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { | |||
1813 | { } /* end */ | 1847 | { } /* end */ |
1814 | }; | 1848 | }; |
1815 | 1849 | ||
1850 | static struct hda_verb cxt5051_f700_init_verbs[] = { | ||
1851 | /* Line in, Mic */ | ||
1852 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x03}, | ||
1853 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1854 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, | ||
1855 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, | ||
1856 | /* SPK */ | ||
1857 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1858 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1859 | /* HP, Amp */ | ||
1860 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1861 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1862 | /* DAC1 */ | ||
1863 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1864 | /* Record selector: Int mic */ | ||
1865 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, | ||
1866 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
1867 | /* SPDIF route: PCM */ | ||
1868 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1869 | /* EAPD */ | ||
1870 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
1871 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, | ||
1872 | {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT}, | ||
1873 | { } /* end */ | ||
1874 | }; | ||
1875 | |||
1816 | /* initialize jack-sensing, too */ | 1876 | /* initialize jack-sensing, too */ |
1817 | static int cxt5051_init(struct hda_codec *codec) | 1877 | static int cxt5051_init(struct hda_codec *codec) |
1818 | { | 1878 | { |
@@ -1832,6 +1892,7 @@ enum { | |||
1832 | CXT5051_HP, /* no docking */ | 1892 | CXT5051_HP, /* no docking */ |
1833 | CXT5051_HP_DV6736, /* HP without mic switch */ | 1893 | CXT5051_HP_DV6736, /* HP without mic switch */ |
1834 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ | 1894 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ |
1895 | CXT5051_F700, /* HP Compaq Presario F700 */ | ||
1835 | CXT5051_MODELS | 1896 | CXT5051_MODELS |
1836 | }; | 1897 | }; |
1837 | 1898 | ||
@@ -1840,6 +1901,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = { | |||
1840 | [CXT5051_HP] = "hp", | 1901 | [CXT5051_HP] = "hp", |
1841 | [CXT5051_HP_DV6736] = "hp-dv6736", | 1902 | [CXT5051_HP_DV6736] = "hp-dv6736", |
1842 | [CXT5051_LENOVO_X200] = "lenovo-x200", | 1903 | [CXT5051_LENOVO_X200] = "lenovo-x200", |
1904 | [CXT5051_F700] = "hp 700" | ||
1843 | }; | 1905 | }; |
1844 | 1906 | ||
1845 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | 1907 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { |
@@ -1849,6 +1911,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | |||
1849 | CXT5051_LAPTOP), | 1911 | CXT5051_LAPTOP), |
1850 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), | 1912 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), |
1851 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), | 1913 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), |
1914 | SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), | ||
1852 | {} | 1915 | {} |
1853 | }; | 1916 | }; |
1854 | 1917 | ||
@@ -1899,6 +1962,11 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1899 | case CXT5051_LENOVO_X200: | 1962 | case CXT5051_LENOVO_X200: |
1900 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; | 1963 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; |
1901 | break; | 1964 | break; |
1965 | case CXT5051_F700: | ||
1966 | spec->init_verbs[0] = cxt5051_f700_init_verbs; | ||
1967 | spec->mixers[0] = cxt5051_f700_mixers; | ||
1968 | spec->no_auto_mic = 1; | ||
1969 | break; | ||
1902 | } | 1970 | } |
1903 | 1971 | ||
1904 | return 0; | 1972 | return 0; |
@@ -1966,53 +2034,97 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
1966 | return 1; | 2034 | return 1; |
1967 | } | 2035 | } |
1968 | 2036 | ||
1969 | /* toggle input of built-in and mic jack appropriately */ | 2037 | static const struct hda_input_mux cxt5066_olpc_dc_bias = { |
1970 | static void cxt5066_automic(struct hda_codec *codec) | 2038 | .num_items = 3, |
2039 | .items = { | ||
2040 | { "Off", PIN_IN }, | ||
2041 | { "50%", PIN_VREF50 }, | ||
2042 | { "80%", PIN_VREF80 }, | ||
2043 | }, | ||
2044 | }; | ||
2045 | |||
2046 | static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec) | ||
1971 | { | 2047 | { |
1972 | struct conexant_spec *spec = codec->spec; | 2048 | struct conexant_spec *spec = codec->spec; |
1973 | struct hda_verb ext_mic_present[] = { | 2049 | /* Even though port F is the DC input, the bias is controlled on port B. |
1974 | /* enable external mic, port B */ | 2050 | * we also leave that port as an active input (but unselected) in DC mode |
1975 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, | 2051 | * just in case that is necessary to make the bias setting take effect. */ |
2052 | return snd_hda_codec_write_cache(codec, 0x1a, 0, | ||
2053 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2054 | cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index); | ||
2055 | } | ||
1976 | 2056 | ||
1977 | /* switch to external mic input */ | 2057 | /* OLPC defers mic widget control until when capture is started because the |
1978 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | 2058 | * microphone LED comes on as soon as these settings are put in place. if we |
2059 | * did this before recording, it would give the false indication that recording | ||
2060 | * is happening when it is not. */ | ||
2061 | static void cxt5066_olpc_select_mic(struct hda_codec *codec) | ||
2062 | { | ||
2063 | struct conexant_spec *spec = codec->spec; | ||
2064 | if (!spec->recording) | ||
2065 | return; | ||
1979 | 2066 | ||
1980 | /* disable internal mic, port C */ | 2067 | if (spec->dc_enable) { |
1981 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2068 | /* in DC mode we ignore presence detection and just use the jack |
1982 | {} | 2069 | * through our special DC port */ |
1983 | }; | 2070 | const struct hda_verb enable_dc_mode[] = { |
1984 | static struct hda_verb ext_mic_absent[] = { | 2071 | /* disble internal mic, port C */ |
1985 | /* enable internal mic, port C */ | 2072 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
1986 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2073 | |
2074 | /* enable DC capture, port F */ | ||
2075 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2076 | {}, | ||
2077 | }; | ||
2078 | |||
2079 | snd_hda_sequence_write(codec, enable_dc_mode); | ||
2080 | /* port B input disabled (and bias set) through the following call */ | ||
2081 | cxt5066_set_olpc_dc_bias(codec); | ||
2082 | return; | ||
2083 | } | ||
1987 | 2084 | ||
1988 | /* switch to internal mic input */ | 2085 | /* disable DC (port F) */ |
1989 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, | 2086 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); |
1990 | 2087 | ||
1991 | /* disable external mic, port B */ | 2088 | /* external mic, port B */ |
1992 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2089 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
1993 | {} | 2090 | spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0); |
1994 | }; | 2091 | |
2092 | /* internal mic, port C */ | ||
2093 | snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2094 | spec->ext_mic_present ? 0 : PIN_VREF80); | ||
2095 | } | ||
2096 | |||
2097 | /* toggle input of built-in and mic jack appropriately */ | ||
2098 | static void cxt5066_olpc_automic(struct hda_codec *codec) | ||
2099 | { | ||
2100 | struct conexant_spec *spec = codec->spec; | ||
1995 | unsigned int present; | 2101 | unsigned int present; |
1996 | 2102 | ||
1997 | present = snd_hda_jack_detect(codec, 0x1a); | 2103 | if (spec->dc_enable) /* don't do presence detection in DC mode */ |
1998 | if (present) { | 2104 | return; |
2105 | |||
2106 | present = snd_hda_codec_read(codec, 0x1a, 0, | ||
2107 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
2108 | if (present) | ||
1999 | snd_printdd("CXT5066: external microphone detected\n"); | 2109 | snd_printdd("CXT5066: external microphone detected\n"); |
2000 | snd_hda_sequence_write(codec, ext_mic_present); | 2110 | else |
2001 | } else { | ||
2002 | snd_printdd("CXT5066: external microphone absent\n"); | 2111 | snd_printdd("CXT5066: external microphone absent\n"); |
2003 | snd_hda_sequence_write(codec, ext_mic_absent); | 2112 | |
2004 | } | 2113 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, |
2114 | present ? 0 : 1); | ||
2115 | spec->ext_mic_present = !!present; | ||
2116 | |||
2117 | cxt5066_olpc_select_mic(codec); | ||
2005 | } | 2118 | } |
2006 | 2119 | ||
2007 | /* toggle input of built-in digital mic and mic jack appropriately */ | 2120 | /* toggle input of built-in digital mic and mic jack appropriately */ |
2008 | static void cxt5066_vostro_automic(struct hda_codec *codec) | 2121 | static void cxt5066_vostro_automic(struct hda_codec *codec) |
2009 | { | 2122 | { |
2010 | struct conexant_spec *spec = codec->spec; | ||
2011 | unsigned int present; | 2123 | unsigned int present; |
2012 | 2124 | ||
2013 | struct hda_verb ext_mic_present[] = { | 2125 | struct hda_verb ext_mic_present[] = { |
2014 | /* enable external mic, port B */ | 2126 | /* enable external mic, port B */ |
2015 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, | 2127 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
2016 | 2128 | ||
2017 | /* switch to external mic input */ | 2129 | /* switch to external mic input */ |
2018 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | 2130 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, |
@@ -2063,15 +2175,18 @@ static void cxt5066_hp_automute(struct hda_codec *codec) | |||
2063 | } | 2175 | } |
2064 | 2176 | ||
2065 | /* unsolicited event for jack sensing */ | 2177 | /* unsolicited event for jack sensing */ |
2066 | static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) | 2178 | static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res) |
2067 | { | 2179 | { |
2180 | struct conexant_spec *spec = codec->spec; | ||
2068 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); | 2181 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); |
2069 | switch (res >> 26) { | 2182 | switch (res >> 26) { |
2070 | case CONEXANT_HP_EVENT: | 2183 | case CONEXANT_HP_EVENT: |
2071 | cxt5066_hp_automute(codec); | 2184 | cxt5066_hp_automute(codec); |
2072 | break; | 2185 | break; |
2073 | case CONEXANT_MIC_EVENT: | 2186 | case CONEXANT_MIC_EVENT: |
2074 | cxt5066_automic(codec); | 2187 | /* ignore mic events in DC mode; we're always using the jack */ |
2188 | if (!spec->dc_enable) | ||
2189 | cxt5066_olpc_automic(codec); | ||
2075 | break; | 2190 | break; |
2076 | } | 2191 | } |
2077 | } | 2192 | } |
@@ -2101,6 +2216,15 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = { | |||
2101 | }, | 2216 | }, |
2102 | }; | 2217 | }; |
2103 | 2218 | ||
2219 | static int cxt5066_set_mic_boost(struct hda_codec *codec) | ||
2220 | { | ||
2221 | struct conexant_spec *spec = codec->spec; | ||
2222 | return snd_hda_codec_write_cache(codec, 0x17, 0, | ||
2223 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2224 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | | ||
2225 | cxt5066_analog_mic_boost.items[spec->mic_boost].index); | ||
2226 | } | ||
2227 | |||
2104 | static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, | 2228 | static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, |
2105 | struct snd_ctl_elem_info *uinfo) | 2229 | struct snd_ctl_elem_info *uinfo) |
2106 | { | 2230 | { |
@@ -2111,15 +2235,8 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, | |||
2111 | struct snd_ctl_elem_value *ucontrol) | 2235 | struct snd_ctl_elem_value *ucontrol) |
2112 | { | 2236 | { |
2113 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2237 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2114 | int val; | 2238 | struct conexant_spec *spec = codec->spec; |
2115 | hda_nid_t nid = kcontrol->private_value & 0xff; | 2239 | ucontrol->value.enumerated.item[0] = spec->mic_boost; |
2116 | int inout = (kcontrol->private_value & 0x100) ? | ||
2117 | AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT; | ||
2118 | |||
2119 | val = snd_hda_codec_read(codec, nid, 0, | ||
2120 | AC_VERB_GET_AMP_GAIN_MUTE, inout); | ||
2121 | |||
2122 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; | ||
2123 | return 0; | 2240 | return 0; |
2124 | } | 2241 | } |
2125 | 2242 | ||
@@ -2127,26 +2244,132 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2127 | struct snd_ctl_elem_value *ucontrol) | 2244 | struct snd_ctl_elem_value *ucontrol) |
2128 | { | 2245 | { |
2129 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2246 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2247 | struct conexant_spec *spec = codec->spec; | ||
2130 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; | 2248 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; |
2131 | unsigned int idx; | 2249 | unsigned int idx; |
2132 | hda_nid_t nid = kcontrol->private_value & 0xff; | 2250 | idx = ucontrol->value.enumerated.item[0]; |
2133 | int inout = (kcontrol->private_value & 0x100) ? | 2251 | if (idx >= imux->num_items) |
2134 | AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; | 2252 | idx = imux->num_items - 1; |
2253 | |||
2254 | spec->mic_boost = idx; | ||
2255 | if (!spec->dc_enable) | ||
2256 | cxt5066_set_mic_boost(codec); | ||
2257 | return 1; | ||
2258 | } | ||
2259 | |||
2260 | static void cxt5066_enable_dc(struct hda_codec *codec) | ||
2261 | { | ||
2262 | const struct hda_verb enable_dc_mode[] = { | ||
2263 | /* disable gain */ | ||
2264 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2265 | |||
2266 | /* switch to DC input */ | ||
2267 | {0x17, AC_VERB_SET_CONNECT_SEL, 3}, | ||
2268 | {} | ||
2269 | }; | ||
2270 | |||
2271 | /* configure as input source */ | ||
2272 | snd_hda_sequence_write(codec, enable_dc_mode); | ||
2273 | cxt5066_olpc_select_mic(codec); /* also sets configured bias */ | ||
2274 | } | ||
2275 | |||
2276 | static void cxt5066_disable_dc(struct hda_codec *codec) | ||
2277 | { | ||
2278 | /* reconfigure input source */ | ||
2279 | cxt5066_set_mic_boost(codec); | ||
2280 | /* automic also selects the right mic if we're recording */ | ||
2281 | cxt5066_olpc_automic(codec); | ||
2282 | } | ||
2283 | |||
2284 | static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol, | ||
2285 | struct snd_ctl_elem_value *ucontrol) | ||
2286 | { | ||
2287 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2288 | struct conexant_spec *spec = codec->spec; | ||
2289 | ucontrol->value.integer.value[0] = spec->dc_enable; | ||
2290 | return 0; | ||
2291 | } | ||
2292 | |||
2293 | static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol, | ||
2294 | struct snd_ctl_elem_value *ucontrol) | ||
2295 | { | ||
2296 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2297 | struct conexant_spec *spec = codec->spec; | ||
2298 | int dc_enable = !!ucontrol->value.integer.value[0]; | ||
2135 | 2299 | ||
2136 | if (!imux->num_items) | 2300 | if (dc_enable == spec->dc_enable) |
2137 | return 0; | 2301 | return 0; |
2302 | |||
2303 | spec->dc_enable = dc_enable; | ||
2304 | if (dc_enable) | ||
2305 | cxt5066_enable_dc(codec); | ||
2306 | else | ||
2307 | cxt5066_disable_dc(codec); | ||
2308 | |||
2309 | return 1; | ||
2310 | } | ||
2311 | |||
2312 | static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol, | ||
2313 | struct snd_ctl_elem_info *uinfo) | ||
2314 | { | ||
2315 | return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo); | ||
2316 | } | ||
2317 | |||
2318 | static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol, | ||
2319 | struct snd_ctl_elem_value *ucontrol) | ||
2320 | { | ||
2321 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2322 | struct conexant_spec *spec = codec->spec; | ||
2323 | ucontrol->value.enumerated.item[0] = spec->dc_input_bias; | ||
2324 | return 0; | ||
2325 | } | ||
2326 | |||
2327 | static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol, | ||
2328 | struct snd_ctl_elem_value *ucontrol) | ||
2329 | { | ||
2330 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2331 | struct conexant_spec *spec = codec->spec; | ||
2332 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; | ||
2333 | unsigned int idx; | ||
2334 | |||
2138 | idx = ucontrol->value.enumerated.item[0]; | 2335 | idx = ucontrol->value.enumerated.item[0]; |
2139 | if (idx >= imux->num_items) | 2336 | if (idx >= imux->num_items) |
2140 | idx = imux->num_items - 1; | 2337 | idx = imux->num_items - 1; |
2141 | 2338 | ||
2142 | snd_hda_codec_write_cache(codec, nid, 0, | 2339 | spec->dc_input_bias = idx; |
2143 | AC_VERB_SET_AMP_GAIN_MUTE, | 2340 | if (spec->dc_enable) |
2144 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | | 2341 | cxt5066_set_olpc_dc_bias(codec); |
2145 | imux->items[idx].index); | ||
2146 | |||
2147 | return 1; | 2342 | return 1; |
2148 | } | 2343 | } |
2149 | 2344 | ||
2345 | static void cxt5066_olpc_capture_prepare(struct hda_codec *codec) | ||
2346 | { | ||
2347 | struct conexant_spec *spec = codec->spec; | ||
2348 | /* mark as recording and configure the microphone widget so that the | ||
2349 | * recording LED comes on. */ | ||
2350 | spec->recording = 1; | ||
2351 | cxt5066_olpc_select_mic(codec); | ||
2352 | } | ||
2353 | |||
2354 | static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec) | ||
2355 | { | ||
2356 | struct conexant_spec *spec = codec->spec; | ||
2357 | const struct hda_verb disable_mics[] = { | ||
2358 | /* disable external mic, port B */ | ||
2359 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2360 | |||
2361 | /* disble internal mic, port C */ | ||
2362 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2363 | |||
2364 | /* disable DC capture, port F */ | ||
2365 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2366 | {}, | ||
2367 | }; | ||
2368 | |||
2369 | snd_hda_sequence_write(codec, disable_mics); | ||
2370 | spec->recording = 0; | ||
2371 | } | ||
2372 | |||
2150 | static struct hda_input_mux cxt5066_capture_source = { | 2373 | static struct hda_input_mux cxt5066_capture_source = { |
2151 | .num_items = 4, | 2374 | .num_items = 4, |
2152 | .items = { | 2375 | .items = { |
@@ -2187,6 +2410,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { | |||
2187 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 2410 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
2188 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 2411 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
2189 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, | 2412 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, |
2413 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
2190 | .info = snd_hda_mixer_amp_volume_info, | 2414 | .info = snd_hda_mixer_amp_volume_info, |
2191 | .get = snd_hda_mixer_amp_volume_get, | 2415 | .get = snd_hda_mixer_amp_volume_get, |
2192 | .put = snd_hda_mixer_amp_volume_put, | 2416 | .put = snd_hda_mixer_amp_volume_put, |
@@ -2198,6 +2422,24 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { | |||
2198 | {} | 2422 | {} |
2199 | }; | 2423 | }; |
2200 | 2424 | ||
2425 | static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { | ||
2426 | { | ||
2427 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2428 | .name = "DC Mode Enable Switch", | ||
2429 | .info = snd_ctl_boolean_mono_info, | ||
2430 | .get = cxt5066_olpc_dc_get, | ||
2431 | .put = cxt5066_olpc_dc_put, | ||
2432 | }, | ||
2433 | { | ||
2434 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2435 | .name = "DC Input Bias Enum", | ||
2436 | .info = cxt5066_olpc_dc_bias_enum_info, | ||
2437 | .get = cxt5066_olpc_dc_bias_enum_get, | ||
2438 | .put = cxt5066_olpc_dc_bias_enum_put, | ||
2439 | }, | ||
2440 | {} | ||
2441 | }; | ||
2442 | |||
2201 | static struct snd_kcontrol_new cxt5066_mixers[] = { | 2443 | static struct snd_kcontrol_new cxt5066_mixers[] = { |
2202 | { | 2444 | { |
2203 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2445 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -2210,11 +2452,10 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2210 | 2452 | ||
2211 | { | 2453 | { |
2212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2454 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2213 | .name = "Ext Mic Boost Capture Enum", | 2455 | .name = "Analog Mic Boost Capture Enum", |
2214 | .info = cxt5066_mic_boost_mux_enum_info, | 2456 | .info = cxt5066_mic_boost_mux_enum_info, |
2215 | .get = cxt5066_mic_boost_mux_enum_get, | 2457 | .get = cxt5066_mic_boost_mux_enum_get, |
2216 | .put = cxt5066_mic_boost_mux_enum_put, | 2458 | .put = cxt5066_mic_boost_mux_enum_put, |
2217 | .private_value = 0x17, | ||
2218 | }, | 2459 | }, |
2219 | 2460 | ||
2220 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), | 2461 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), |
@@ -2296,10 +2537,10 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { | |||
2296 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | 2537 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ |
2297 | 2538 | ||
2298 | /* Port B: external microphone */ | 2539 | /* Port B: external microphone */ |
2299 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, | 2540 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2300 | 2541 | ||
2301 | /* Port C: internal microphone */ | 2542 | /* Port C: internal microphone */ |
2302 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2543 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2303 | 2544 | ||
2304 | /* Port D: unused */ | 2545 | /* Port D: unused */ |
2305 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2546 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
@@ -2308,7 +2549,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { | |||
2308 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2549 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2309 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | 2550 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ |
2310 | 2551 | ||
2311 | /* Port F: unused */ | 2552 | /* Port F: external DC input through microphone port */ |
2312 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2553 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2313 | 2554 | ||
2314 | /* Port G: internal speakers */ | 2555 | /* Port G: internal speakers */ |
@@ -2428,8 +2669,22 @@ static int cxt5066_init(struct hda_codec *codec) | |||
2428 | cxt5066_hp_automute(codec); | 2669 | cxt5066_hp_automute(codec); |
2429 | if (spec->dell_vostro) | 2670 | if (spec->dell_vostro) |
2430 | cxt5066_vostro_automic(codec); | 2671 | cxt5066_vostro_automic(codec); |
2431 | else | 2672 | } |
2432 | cxt5066_automic(codec); | 2673 | cxt5066_set_mic_boost(codec); |
2674 | return 0; | ||
2675 | } | ||
2676 | |||
2677 | static int cxt5066_olpc_init(struct hda_codec *codec) | ||
2678 | { | ||
2679 | struct conexant_spec *spec = codec->spec; | ||
2680 | snd_printdd("CXT5066: init\n"); | ||
2681 | conexant_init(codec); | ||
2682 | cxt5066_hp_automute(codec); | ||
2683 | if (!spec->dc_enable) { | ||
2684 | cxt5066_set_mic_boost(codec); | ||
2685 | cxt5066_olpc_automic(codec); | ||
2686 | } else { | ||
2687 | cxt5066_enable_dc(codec); | ||
2433 | } | 2688 | } |
2434 | return 0; | 2689 | return 0; |
2435 | } | 2690 | } |
@@ -2470,7 +2725,7 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2470 | codec->spec = spec; | 2725 | codec->spec = spec; |
2471 | 2726 | ||
2472 | codec->patch_ops = conexant_patch_ops; | 2727 | codec->patch_ops = conexant_patch_ops; |
2473 | codec->patch_ops.init = cxt5066_init; | 2728 | codec->patch_ops.init = conexant_init; |
2474 | 2729 | ||
2475 | spec->dell_automute = 0; | 2730 | spec->dell_automute = 0; |
2476 | spec->multiout.max_channels = 2; | 2731 | spec->multiout.max_channels = 2; |
@@ -2483,7 +2738,6 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2483 | spec->input_mux = &cxt5066_capture_source; | 2738 | spec->input_mux = &cxt5066_capture_source; |
2484 | 2739 | ||
2485 | spec->port_d_mode = PIN_HP; | 2740 | spec->port_d_mode = PIN_HP; |
2486 | spec->ext_mic_bias = PIN_VREF80; | ||
2487 | 2741 | ||
2488 | spec->num_init_verbs = 1; | 2742 | spec->num_init_verbs = 1; |
2489 | spec->init_verbs[0] = cxt5066_init_verbs; | 2743 | spec->init_verbs[0] = cxt5066_init_verbs; |
@@ -2510,20 +2764,28 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2510 | spec->dell_automute = 1; | 2764 | spec->dell_automute = 1; |
2511 | break; | 2765 | break; |
2512 | case CXT5066_OLPC_XO_1_5: | 2766 | case CXT5066_OLPC_XO_1_5: |
2513 | codec->patch_ops.unsol_event = cxt5066_unsol_event; | 2767 | codec->patch_ops.init = cxt5066_olpc_init; |
2768 | codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; | ||
2514 | spec->init_verbs[0] = cxt5066_init_verbs_olpc; | 2769 | spec->init_verbs[0] = cxt5066_init_verbs_olpc; |
2515 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | 2770 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; |
2771 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc; | ||
2516 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 2772 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
2517 | spec->port_d_mode = 0; | 2773 | spec->port_d_mode = 0; |
2518 | spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; | 2774 | spec->mic_boost = 3; /* default 30dB gain */ |
2519 | 2775 | ||
2520 | /* no S/PDIF out */ | 2776 | /* no S/PDIF out */ |
2521 | spec->multiout.dig_out_nid = 0; | 2777 | spec->multiout.dig_out_nid = 0; |
2522 | 2778 | ||
2523 | /* input source automatically selected */ | 2779 | /* input source automatically selected */ |
2524 | spec->input_mux = NULL; | 2780 | spec->input_mux = NULL; |
2781 | |||
2782 | /* our capture hooks which allow us to turn on the microphone LED | ||
2783 | * at the right time */ | ||
2784 | spec->capture_prepare = cxt5066_olpc_capture_prepare; | ||
2785 | spec->capture_cleanup = cxt5066_olpc_capture_cleanup; | ||
2525 | break; | 2786 | break; |
2526 | case CXT5066_DELL_VOSTO: | 2787 | case CXT5066_DELL_VOSTO: |
2788 | codec->patch_ops.init = cxt5066_init; | ||
2527 | codec->patch_ops.unsol_event = cxt5066_vostro_event; | 2789 | codec->patch_ops.unsol_event = cxt5066_vostro_event; |
2528 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; | 2790 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; |
2529 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | 2791 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; |
@@ -2531,6 +2793,7 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2531 | spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; | 2793 | spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; |
2532 | spec->port_d_mode = 0; | 2794 | spec->port_d_mode = 0; |
2533 | spec->dell_vostro = 1; | 2795 | spec->dell_vostro = 1; |
2796 | spec->mic_boost = 3; /* default 30dB gain */ | ||
2534 | snd_hda_attach_beep_device(codec, 0x13); | 2797 | snd_hda_attach_beep_device(codec, 0x13); |
2535 | 2798 | ||
2536 | /* no S/PDIF out */ | 2799 | /* no S/PDIF out */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index da34095c707f..f628c33d80b3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -338,7 +338,7 @@ struct alc_spec { | |||
338 | void (*init_hook)(struct hda_codec *codec); | 338 | void (*init_hook)(struct hda_codec *codec); |
339 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | 339 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); |
340 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 340 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
341 | void (*power_hook)(struct hda_codec *codec, int power); | 341 | void (*power_hook)(struct hda_codec *codec); |
342 | #endif | 342 | #endif |
343 | 343 | ||
344 | /* for pin sensing */ | 344 | /* for pin sensing */ |
@@ -391,7 +391,7 @@ struct alc_config_preset { | |||
391 | void (*init_hook)(struct hda_codec *); | 391 | void (*init_hook)(struct hda_codec *); |
392 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 392 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
393 | struct hda_amp_list *loopbacks; | 393 | struct hda_amp_list *loopbacks; |
394 | void (*power_hook)(struct hda_codec *codec, int power); | 394 | void (*power_hook)(struct hda_codec *codec); |
395 | #endif | 395 | #endif |
396 | }; | 396 | }; |
397 | 397 | ||
@@ -633,6 +633,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | |||
633 | 633 | ||
634 | #define ALC_PIN_MODE(xname, nid, dir) \ | 634 | #define ALC_PIN_MODE(xname, nid, dir) \ |
635 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 635 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
636 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
636 | .info = alc_pin_mode_info, \ | 637 | .info = alc_pin_mode_info, \ |
637 | .get = alc_pin_mode_get, \ | 638 | .get = alc_pin_mode_get, \ |
638 | .put = alc_pin_mode_put, \ | 639 | .put = alc_pin_mode_put, \ |
@@ -684,6 +685,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, | |||
684 | } | 685 | } |
685 | #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ | 686 | #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ |
686 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 687 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
688 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
687 | .info = alc_gpio_data_info, \ | 689 | .info = alc_gpio_data_info, \ |
688 | .get = alc_gpio_data_get, \ | 690 | .get = alc_gpio_data_get, \ |
689 | .put = alc_gpio_data_put, \ | 691 | .put = alc_gpio_data_put, \ |
@@ -738,6 +740,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, | |||
738 | } | 740 | } |
739 | #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ | 741 | #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ |
740 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 742 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
743 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
741 | .info = alc_spdif_ctrl_info, \ | 744 | .info = alc_spdif_ctrl_info, \ |
742 | .get = alc_spdif_ctrl_get, \ | 745 | .get = alc_spdif_ctrl_get, \ |
743 | .put = alc_spdif_ctrl_put, \ | 746 | .put = alc_spdif_ctrl_put, \ |
@@ -791,6 +794,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, | |||
791 | 794 | ||
792 | #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ | 795 | #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ |
793 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 796 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
797 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
794 | .info = alc_eapd_ctrl_info, \ | 798 | .info = alc_eapd_ctrl_info, \ |
795 | .get = alc_eapd_ctrl_get, \ | 799 | .get = alc_eapd_ctrl_get, \ |
796 | .put = alc_eapd_ctrl_put, \ | 800 | .put = alc_eapd_ctrl_put, \ |
@@ -1840,14 +1844,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
1840 | spec->autocfg.speaker_pins[2] = 0x1b; | 1844 | spec->autocfg.speaker_pins[2] = 0x1b; |
1841 | } | 1845 | } |
1842 | 1846 | ||
1843 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
1844 | static void alc889_power_eapd(struct hda_codec *codec, int power) | ||
1845 | { | ||
1846 | set_eapd(codec, 0x14, power); | ||
1847 | set_eapd(codec, 0x15, power); | ||
1848 | } | ||
1849 | #endif | ||
1850 | |||
1851 | /* | 1847 | /* |
1852 | * ALC880 3-stack model | 1848 | * ALC880 3-stack model |
1853 | * | 1849 | * |
@@ -2450,6 +2446,15 @@ static const char *alc_slave_sws[] = { | |||
2450 | * build control elements | 2446 | * build control elements |
2451 | */ | 2447 | */ |
2452 | 2448 | ||
2449 | #define NID_MAPPING (-1) | ||
2450 | |||
2451 | #define SUBDEV_SPEAKER_ (0 << 6) | ||
2452 | #define SUBDEV_HP_ (1 << 6) | ||
2453 | #define SUBDEV_LINE_ (2 << 6) | ||
2454 | #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) | ||
2455 | #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) | ||
2456 | #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) | ||
2457 | |||
2453 | static void alc_free_kctls(struct hda_codec *codec); | 2458 | static void alc_free_kctls(struct hda_codec *codec); |
2454 | 2459 | ||
2455 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 2460 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
@@ -2464,8 +2469,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = { | |||
2464 | static int alc_build_controls(struct hda_codec *codec) | 2469 | static int alc_build_controls(struct hda_codec *codec) |
2465 | { | 2470 | { |
2466 | struct alc_spec *spec = codec->spec; | 2471 | struct alc_spec *spec = codec->spec; |
2467 | int err; | 2472 | struct snd_kcontrol *kctl; |
2468 | int i; | 2473 | struct snd_kcontrol_new *knew; |
2474 | int i, j, err; | ||
2475 | unsigned int u; | ||
2476 | hda_nid_t nid; | ||
2469 | 2477 | ||
2470 | for (i = 0; i < spec->num_mixers; i++) { | 2478 | for (i = 0; i < spec->num_mixers; i++) { |
2471 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 2479 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
@@ -2506,8 +2514,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2506 | if (!kctl) | 2514 | if (!kctl) |
2507 | return -ENOMEM; | 2515 | return -ENOMEM; |
2508 | kctl->private_value = spec->beep_amp; | 2516 | kctl->private_value = spec->beep_amp; |
2509 | err = snd_hda_ctl_add(codec, | 2517 | err = snd_hda_ctl_add(codec, 0, kctl); |
2510 | get_amp_nid_(spec->beep_amp), kctl); | ||
2511 | if (err < 0) | 2518 | if (err < 0) |
2512 | return err; | 2519 | return err; |
2513 | } | 2520 | } |
@@ -2534,6 +2541,75 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2534 | } | 2541 | } |
2535 | 2542 | ||
2536 | alc_free_kctls(codec); /* no longer needed */ | 2543 | alc_free_kctls(codec); /* no longer needed */ |
2544 | |||
2545 | /* assign Capture Source enums to NID */ | ||
2546 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
2547 | if (!kctl) | ||
2548 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
2549 | for (i = 0; kctl && i < kctl->count; i++) { | ||
2550 | hda_nid_t *nids = spec->capsrc_nids; | ||
2551 | if (!nids) | ||
2552 | nids = spec->adc_nids; | ||
2553 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); | ||
2554 | if (err < 0) | ||
2555 | return err; | ||
2556 | } | ||
2557 | if (spec->cap_mixer) { | ||
2558 | const char *kname = kctl ? kctl->id.name : NULL; | ||
2559 | for (knew = spec->cap_mixer; knew->name; knew++) { | ||
2560 | if (kname && strcmp(knew->name, kname) == 0) | ||
2561 | continue; | ||
2562 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
2563 | for (i = 0; kctl && i < kctl->count; i++) { | ||
2564 | err = snd_hda_add_nid(codec, kctl, i, | ||
2565 | spec->adc_nids[i]); | ||
2566 | if (err < 0) | ||
2567 | return err; | ||
2568 | } | ||
2569 | } | ||
2570 | } | ||
2571 | |||
2572 | /* other nid->control mapping */ | ||
2573 | for (i = 0; i < spec->num_mixers; i++) { | ||
2574 | for (knew = spec->mixers[i]; knew->name; knew++) { | ||
2575 | if (knew->iface != NID_MAPPING) | ||
2576 | continue; | ||
2577 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
2578 | if (kctl == NULL) | ||
2579 | continue; | ||
2580 | u = knew->subdevice; | ||
2581 | for (j = 0; j < 4; j++, u >>= 8) { | ||
2582 | nid = u & 0x3f; | ||
2583 | if (nid == 0) | ||
2584 | continue; | ||
2585 | switch (u & 0xc0) { | ||
2586 | case SUBDEV_SPEAKER_: | ||
2587 | nid = spec->autocfg.speaker_pins[nid]; | ||
2588 | break; | ||
2589 | case SUBDEV_LINE_: | ||
2590 | nid = spec->autocfg.line_out_pins[nid]; | ||
2591 | break; | ||
2592 | case SUBDEV_HP_: | ||
2593 | nid = spec->autocfg.hp_pins[nid]; | ||
2594 | break; | ||
2595 | default: | ||
2596 | continue; | ||
2597 | } | ||
2598 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
2599 | if (err < 0) | ||
2600 | return err; | ||
2601 | } | ||
2602 | u = knew->private_value; | ||
2603 | for (j = 0; j < 4; j++, u >>= 8) { | ||
2604 | nid = u & 0xff; | ||
2605 | if (nid == 0) | ||
2606 | continue; | ||
2607 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
2608 | if (err < 0) | ||
2609 | return err; | ||
2610 | } | ||
2611 | } | ||
2612 | } | ||
2537 | return 0; | 2613 | return 0; |
2538 | } | 2614 | } |
2539 | 2615 | ||
@@ -3616,6 +3692,11 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3616 | return 0; | 3692 | return 0; |
3617 | } | 3693 | } |
3618 | 3694 | ||
3695 | static inline void alc_shutup(struct hda_codec *codec) | ||
3696 | { | ||
3697 | snd_hda_shutup_pins(codec); | ||
3698 | } | ||
3699 | |||
3619 | static void alc_free_kctls(struct hda_codec *codec) | 3700 | static void alc_free_kctls(struct hda_codec *codec) |
3620 | { | 3701 | { |
3621 | struct alc_spec *spec = codec->spec; | 3702 | struct alc_spec *spec = codec->spec; |
@@ -3636,17 +3717,47 @@ static void alc_free(struct hda_codec *codec) | |||
3636 | if (!spec) | 3717 | if (!spec) |
3637 | return; | 3718 | return; |
3638 | 3719 | ||
3720 | alc_shutup(codec); | ||
3639 | alc_free_kctls(codec); | 3721 | alc_free_kctls(codec); |
3640 | kfree(spec); | 3722 | kfree(spec); |
3641 | snd_hda_detach_beep_device(codec); | 3723 | snd_hda_detach_beep_device(codec); |
3642 | } | 3724 | } |
3643 | 3725 | ||
3644 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3726 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3727 | static void alc_power_eapd(struct hda_codec *codec) | ||
3728 | { | ||
3729 | /* We currently only handle front, HP */ | ||
3730 | switch (codec->vendor_id) { | ||
3731 | case 0x10ec0260: | ||
3732 | snd_hda_codec_write(codec, 0x0f, 0, | ||
3733 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
3734 | snd_hda_codec_write(codec, 0x10, 0, | ||
3735 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
3736 | break; | ||
3737 | case 0x10ec0262: | ||
3738 | case 0x10ec0267: | ||
3739 | case 0x10ec0268: | ||
3740 | case 0x10ec0269: | ||
3741 | case 0x10ec0272: | ||
3742 | case 0x10ec0660: | ||
3743 | case 0x10ec0662: | ||
3744 | case 0x10ec0663: | ||
3745 | case 0x10ec0862: | ||
3746 | case 0x10ec0889: | ||
3747 | snd_hda_codec_write(codec, 0x14, 0, | ||
3748 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
3749 | snd_hda_codec_write(codec, 0x15, 0, | ||
3750 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
3751 | break; | ||
3752 | } | ||
3753 | } | ||
3754 | |||
3645 | static int alc_suspend(struct hda_codec *codec, pm_message_t state) | 3755 | static int alc_suspend(struct hda_codec *codec, pm_message_t state) |
3646 | { | 3756 | { |
3647 | struct alc_spec *spec = codec->spec; | 3757 | struct alc_spec *spec = codec->spec; |
3758 | alc_shutup(codec); | ||
3648 | if (spec && spec->power_hook) | 3759 | if (spec && spec->power_hook) |
3649 | spec->power_hook(codec, 0); | 3760 | spec->power_hook(codec); |
3650 | return 0; | 3761 | return 0; |
3651 | } | 3762 | } |
3652 | #endif | 3763 | #endif |
@@ -3654,16 +3765,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state) | |||
3654 | #ifdef SND_HDA_NEEDS_RESUME | 3765 | #ifdef SND_HDA_NEEDS_RESUME |
3655 | static int alc_resume(struct hda_codec *codec) | 3766 | static int alc_resume(struct hda_codec *codec) |
3656 | { | 3767 | { |
3657 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3658 | struct alc_spec *spec = codec->spec; | ||
3659 | #endif | ||
3660 | codec->patch_ops.init(codec); | 3768 | codec->patch_ops.init(codec); |
3661 | snd_hda_codec_resume_amp(codec); | 3769 | snd_hda_codec_resume_amp(codec); |
3662 | snd_hda_codec_resume_cache(codec); | 3770 | snd_hda_codec_resume_cache(codec); |
3663 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3664 | if (spec && spec->power_hook) | ||
3665 | spec->power_hook(codec, 1); | ||
3666 | #endif | ||
3667 | return 0; | 3771 | return 0; |
3668 | } | 3772 | } |
3669 | #endif | 3773 | #endif |
@@ -3683,6 +3787,7 @@ static struct hda_codec_ops alc_patch_ops = { | |||
3683 | .suspend = alc_suspend, | 3787 | .suspend = alc_suspend, |
3684 | .check_power_status = alc_check_power_status, | 3788 | .check_power_status = alc_check_power_status, |
3685 | #endif | 3789 | #endif |
3790 | .reboot_notify = alc_shutup, | ||
3686 | }; | 3791 | }; |
3687 | 3792 | ||
3688 | 3793 | ||
@@ -3839,6 +3944,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, | |||
3839 | #define PIN_CTL_TEST(xname,nid) { \ | 3944 | #define PIN_CTL_TEST(xname,nid) { \ |
3840 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3945 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
3841 | .name = xname, \ | 3946 | .name = xname, \ |
3947 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
3842 | .info = alc_test_pin_ctl_info, \ | 3948 | .info = alc_test_pin_ctl_info, \ |
3843 | .get = alc_test_pin_ctl_get, \ | 3949 | .get = alc_test_pin_ctl_get, \ |
3844 | .put = alc_test_pin_ctl_put, \ | 3950 | .put = alc_test_pin_ctl_put, \ |
@@ -3848,6 +3954,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, | |||
3848 | #define PIN_SRC_TEST(xname,nid) { \ | 3954 | #define PIN_SRC_TEST(xname,nid) { \ |
3849 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3955 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
3850 | .name = xname, \ | 3956 | .name = xname, \ |
3957 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
3851 | .info = alc_test_pin_src_info, \ | 3958 | .info = alc_test_pin_src_info, \ |
3852 | .get = alc_test_pin_src_get, \ | 3959 | .get = alc_test_pin_src_get, \ |
3853 | .put = alc_test_pin_src_put, \ | 3960 | .put = alc_test_pin_src_put, \ |
@@ -4387,7 +4494,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4387 | if (!knew->name) | 4494 | if (!knew->name) |
4388 | return -ENOMEM; | 4495 | return -ENOMEM; |
4389 | if (get_amp_nid_(val)) | 4496 | if (get_amp_nid_(val)) |
4390 | knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); | 4497 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
4391 | knew->private_value = val; | 4498 | knew->private_value = val; |
4392 | return 0; | 4499 | return 0; |
4393 | } | 4500 | } |
@@ -5182,6 +5289,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { | |||
5182 | { | 5289 | { |
5183 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5290 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5184 | .name = "Master Playback Switch", | 5291 | .name = "Master Playback Switch", |
5292 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
5185 | .info = snd_ctl_boolean_mono_info, | 5293 | .info = snd_ctl_boolean_mono_info, |
5186 | .get = alc260_hp_master_sw_get, | 5294 | .get = alc260_hp_master_sw_get, |
5187 | .put = alc260_hp_master_sw_put, | 5295 | .put = alc260_hp_master_sw_put, |
@@ -5220,6 +5328,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
5220 | { | 5328 | { |
5221 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5329 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5222 | .name = "Master Playback Switch", | 5330 | .name = "Master Playback Switch", |
5331 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
5223 | .info = snd_ctl_boolean_mono_info, | 5332 | .info = snd_ctl_boolean_mono_info, |
5224 | .get = alc260_hp_master_sw_get, | 5333 | .get = alc260_hp_master_sw_get, |
5225 | .put = alc260_hp_master_sw_put, | 5334 | .put = alc260_hp_master_sw_put, |
@@ -9528,7 +9637,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9528 | .setup = alc889_acer_aspire_8930g_setup, | 9637 | .setup = alc889_acer_aspire_8930g_setup, |
9529 | .init_hook = alc_automute_amp, | 9638 | .init_hook = alc_automute_amp, |
9530 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 9639 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
9531 | .power_hook = alc889_power_eapd, | 9640 | .power_hook = alc_power_eapd, |
9532 | #endif | 9641 | #endif |
9533 | }, | 9642 | }, |
9534 | [ALC888_ACER_ASPIRE_7730G] = { | 9643 | [ALC888_ACER_ASPIRE_7730G] = { |
@@ -10324,8 +10433,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
10324 | .info = snd_ctl_boolean_mono_info, \ | 10433 | .info = snd_ctl_boolean_mono_info, \ |
10325 | .get = alc262_hp_master_sw_get, \ | 10434 | .get = alc262_hp_master_sw_get, \ |
10326 | .put = alc262_hp_master_sw_put, \ | 10435 | .put = alc262_hp_master_sw_put, \ |
10436 | }, \ | ||
10437 | { \ | ||
10438 | .iface = NID_MAPPING, \ | ||
10439 | .name = "Master Playback Switch", \ | ||
10440 | .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ | ||
10327 | } | 10441 | } |
10328 | 10442 | ||
10443 | |||
10329 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 10444 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { |
10330 | ALC262_HP_MASTER_SWITCH, | 10445 | ALC262_HP_MASTER_SWITCH, |
10331 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 10446 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -10483,6 +10598,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | |||
10483 | .info = snd_ctl_boolean_mono_info, \ | 10598 | .info = snd_ctl_boolean_mono_info, \ |
10484 | .get = alc262_hippo_master_sw_get, \ | 10599 | .get = alc262_hippo_master_sw_get, \ |
10485 | .put = alc262_hippo_master_sw_put, \ | 10600 | .put = alc262_hippo_master_sw_put, \ |
10601 | }, \ | ||
10602 | { \ | ||
10603 | .iface = NID_MAPPING, \ | ||
10604 | .name = "Master Playback Switch", \ | ||
10605 | .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ | ||
10606 | (SUBDEV_SPEAKER(0) << 16), \ | ||
10486 | } | 10607 | } |
10487 | 10608 | ||
10488 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { | 10609 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { |
@@ -10963,11 +11084,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { | |||
10963 | { | 11084 | { |
10964 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 11085 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
10965 | .name = "Master Playback Switch", | 11086 | .name = "Master Playback Switch", |
11087 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
10966 | .info = snd_hda_mixer_amp_switch_info, | 11088 | .info = snd_hda_mixer_amp_switch_info, |
10967 | .get = snd_hda_mixer_amp_switch_get, | 11089 | .get = snd_hda_mixer_amp_switch_get, |
10968 | .put = alc262_fujitsu_master_sw_put, | 11090 | .put = alc262_fujitsu_master_sw_put, |
10969 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 11091 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
10970 | }, | 11092 | }, |
11093 | { | ||
11094 | .iface = NID_MAPPING, | ||
11095 | .name = "Master Playback Switch", | ||
11096 | .private_value = 0x1b, | ||
11097 | }, | ||
10971 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 11098 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
10972 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 11099 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
10973 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 11100 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
@@ -10998,6 +11125,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | |||
10998 | { | 11125 | { |
10999 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 11126 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
11000 | .name = "Master Playback Switch", | 11127 | .name = "Master Playback Switch", |
11128 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
11001 | .info = snd_hda_mixer_amp_switch_info, | 11129 | .info = snd_hda_mixer_amp_switch_info, |
11002 | .get = snd_hda_mixer_amp_switch_get, | 11130 | .get = snd_hda_mixer_amp_switch_get, |
11003 | .put = alc262_lenovo_3000_master_sw_put, | 11131 | .put = alc262_lenovo_3000_master_sw_put, |
@@ -11152,6 +11280,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { | |||
11152 | .get = alc_mux_enum_get, | 11280 | .get = alc_mux_enum_get, |
11153 | .put = alc262_ultra_mux_enum_put, | 11281 | .put = alc262_ultra_mux_enum_put, |
11154 | }, | 11282 | }, |
11283 | { | ||
11284 | .iface = NID_MAPPING, | ||
11285 | .name = "Capture Source", | ||
11286 | .private_value = 0x15, | ||
11287 | }, | ||
11155 | { } /* end */ | 11288 | { } /* end */ |
11156 | }; | 11289 | }; |
11157 | 11290 | ||
@@ -12170,6 +12303,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { | |||
12170 | { | 12303 | { |
12171 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 12304 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
12172 | .name = "Master Playback Switch", | 12305 | .name = "Master Playback Switch", |
12306 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
12173 | .info = snd_hda_mixer_amp_switch_info, | 12307 | .info = snd_hda_mixer_amp_switch_info, |
12174 | .get = snd_hda_mixer_amp_switch_get, | 12308 | .get = snd_hda_mixer_amp_switch_get, |
12175 | .put = alc268_acer_master_sw_put, | 12309 | .put = alc268_acer_master_sw_put, |
@@ -12185,6 +12319,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { | |||
12185 | { | 12319 | { |
12186 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 12320 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
12187 | .name = "Master Playback Switch", | 12321 | .name = "Master Playback Switch", |
12322 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
12188 | .info = snd_hda_mixer_amp_switch_info, | 12323 | .info = snd_hda_mixer_amp_switch_info, |
12189 | .get = snd_hda_mixer_amp_switch_get, | 12324 | .get = snd_hda_mixer_amp_switch_get, |
12190 | .put = alc268_acer_master_sw_put, | 12325 | .put = alc268_acer_master_sw_put, |
@@ -12202,6 +12337,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { | |||
12202 | { | 12337 | { |
12203 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 12338 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
12204 | .name = "Master Playback Switch", | 12339 | .name = "Master Playback Switch", |
12340 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
12205 | .info = snd_hda_mixer_amp_switch_info, | 12341 | .info = snd_hda_mixer_amp_switch_info, |
12206 | .get = snd_hda_mixer_amp_switch_get, | 12342 | .get = snd_hda_mixer_amp_switch_get, |
12207 | .put = alc268_acer_master_sw_put, | 12343 | .put = alc268_acer_master_sw_put, |
@@ -13155,6 +13291,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | |||
13155 | { | 13291 | { |
13156 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13292 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
13157 | .name = "Master Playback Switch", | 13293 | .name = "Master Playback Switch", |
13294 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
13158 | .info = snd_hda_mixer_amp_switch_info, | 13295 | .info = snd_hda_mixer_amp_switch_info, |
13159 | .get = snd_hda_mixer_amp_switch_get, | 13296 | .get = snd_hda_mixer_amp_switch_get, |
13160 | .put = alc268_acer_master_sw_put, | 13297 | .put = alc268_acer_master_sw_put, |
@@ -13175,6 +13312,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | |||
13175 | { | 13312 | { |
13176 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13313 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
13177 | .name = "Master Playback Switch", | 13314 | .name = "Master Playback Switch", |
13315 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
13178 | .info = snd_hda_mixer_amp_switch_info, | 13316 | .info = snd_hda_mixer_amp_switch_info, |
13179 | .get = snd_hda_mixer_amp_switch_get, | 13317 | .get = snd_hda_mixer_amp_switch_get, |
13180 | .put = alc268_acer_master_sw_put, | 13318 | .put = alc268_acer_master_sw_put, |
@@ -14939,9 +15077,13 @@ static int patch_alc861(struct hda_codec *codec) | |||
14939 | spec->vmaster_nid = 0x03; | 15077 | spec->vmaster_nid = 0x03; |
14940 | 15078 | ||
14941 | codec->patch_ops = alc_patch_ops; | 15079 | codec->patch_ops = alc_patch_ops; |
14942 | if (board_config == ALC861_AUTO) | 15080 | if (board_config == ALC861_AUTO) { |
14943 | spec->init_hook = alc861_auto_init; | 15081 | spec->init_hook = alc861_auto_init; |
14944 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15082 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
15083 | spec->power_hook = alc_power_eapd; | ||
15084 | #endif | ||
15085 | } | ||
15086 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
14945 | if (!spec->loopback.amplist) | 15087 | if (!spec->loopback.amplist) |
14946 | spec->loopback.amplist = alc861_loopbacks; | 15088 | spec->loopback.amplist = alc861_loopbacks; |
14947 | #endif | 15089 | #endif |
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 43b436c5d01b..f419ee8d75f0 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol, | |||
122 | #define SI3054_KCONTROL(kname,reg,mask) { \ | 122 | #define SI3054_KCONTROL(kname,reg,mask) { \ |
123 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 123 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
124 | .name = kname, \ | 124 | .name = kname, \ |
125 | .subdevice = HDA_SUBDEV_NID_FLAG | reg, \ | ||
125 | .info = si3054_switch_info, \ | 126 | .info = si3054_switch_info, \ |
126 | .get = si3054_switch_get, \ | 127 | .get = si3054_switch_get, \ |
127 | .put = si3054_switch_put, \ | 128 | .put = si3054_switch_put, \ |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 799ba2570902..dbffb5b5c69d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -2688,7 +2688,7 @@ static struct snd_kcontrol_new * | |||
2688 | stac_control_new(struct sigmatel_spec *spec, | 2688 | stac_control_new(struct sigmatel_spec *spec, |
2689 | struct snd_kcontrol_new *ktemp, | 2689 | struct snd_kcontrol_new *ktemp, |
2690 | const char *name, | 2690 | const char *name, |
2691 | hda_nid_t nid) | 2691 | unsigned int subdev) |
2692 | { | 2692 | { |
2693 | struct snd_kcontrol_new *knew; | 2693 | struct snd_kcontrol_new *knew; |
2694 | 2694 | ||
@@ -2704,8 +2704,7 @@ stac_control_new(struct sigmatel_spec *spec, | |||
2704 | spec->kctls.alloced--; | 2704 | spec->kctls.alloced--; |
2705 | return NULL; | 2705 | return NULL; |
2706 | } | 2706 | } |
2707 | if (nid) | 2707 | knew->subdevice = subdev; |
2708 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | ||
2709 | return knew; | 2708 | return knew; |
2710 | } | 2709 | } |
2711 | 2710 | ||
@@ -2715,7 +2714,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | |||
2715 | unsigned long val) | 2714 | unsigned long val) |
2716 | { | 2715 | { |
2717 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, | 2716 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, |
2718 | get_amp_nid_(val)); | 2717 | HDA_SUBDEV_AMP_FLAG); |
2719 | if (!knew) | 2718 | if (!knew) |
2720 | return -ENOMEM; | 2719 | return -ENOMEM; |
2721 | knew->index = idx; | 2720 | knew->index = idx; |
@@ -4160,34 +4159,52 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
4160 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | 4159 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
4161 | int enable); | 4160 | int enable); |
4162 | 4161 | ||
4162 | static inline int get_int_hint(struct hda_codec *codec, const char *key, | ||
4163 | int *valp) | ||
4164 | { | ||
4165 | const char *p; | ||
4166 | p = snd_hda_get_hint(codec, key); | ||
4167 | if (p) { | ||
4168 | unsigned long val; | ||
4169 | if (!strict_strtoul(p, 0, &val)) { | ||
4170 | *valp = val; | ||
4171 | return 1; | ||
4172 | } | ||
4173 | } | ||
4174 | return 0; | ||
4175 | } | ||
4176 | |||
4163 | /* override some hints from the hwdep entry */ | 4177 | /* override some hints from the hwdep entry */ |
4164 | static void stac_store_hints(struct hda_codec *codec) | 4178 | static void stac_store_hints(struct hda_codec *codec) |
4165 | { | 4179 | { |
4166 | struct sigmatel_spec *spec = codec->spec; | 4180 | struct sigmatel_spec *spec = codec->spec; |
4167 | const char *p; | ||
4168 | int val; | 4181 | int val; |
4169 | 4182 | ||
4170 | val = snd_hda_get_bool_hint(codec, "hp_detect"); | 4183 | val = snd_hda_get_bool_hint(codec, "hp_detect"); |
4171 | if (val >= 0) | 4184 | if (val >= 0) |
4172 | spec->hp_detect = val; | 4185 | spec->hp_detect = val; |
4173 | p = snd_hda_get_hint(codec, "gpio_mask"); | 4186 | if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { |
4174 | if (p) { | ||
4175 | spec->gpio_mask = simple_strtoul(p, NULL, 0); | ||
4176 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = | 4187 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = |
4177 | spec->gpio_mask; | 4188 | spec->gpio_mask; |
4178 | } | 4189 | } |
4179 | p = snd_hda_get_hint(codec, "gpio_dir"); | 4190 | if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) |
4180 | if (p) | 4191 | spec->gpio_mask &= spec->gpio_mask; |
4181 | spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | 4192 | if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) |
4182 | p = snd_hda_get_hint(codec, "gpio_data"); | 4193 | spec->gpio_dir &= spec->gpio_mask; |
4183 | if (p) | 4194 | if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) |
4184 | spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | 4195 | spec->eapd_mask &= spec->gpio_mask; |
4185 | p = snd_hda_get_hint(codec, "eapd_mask"); | 4196 | if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) |
4186 | if (p) | 4197 | spec->gpio_mute &= spec->gpio_mask; |
4187 | spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4188 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | 4198 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); |
4189 | if (val >= 0) | 4199 | if (val >= 0) |
4190 | spec->eapd_switch = val; | 4200 | spec->eapd_switch = val; |
4201 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); | ||
4202 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | ||
4203 | spec->gpio_mask |= spec->gpio_led; | ||
4204 | spec->gpio_dir |= spec->gpio_led; | ||
4205 | if (spec->gpio_led_polarity) | ||
4206 | spec->gpio_data |= spec->gpio_led; | ||
4207 | } | ||
4191 | } | 4208 | } |
4192 | 4209 | ||
4193 | static int stac92xx_init(struct hda_codec *codec) | 4210 | static int stac92xx_init(struct hda_codec *codec) |
@@ -4372,18 +4389,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec) | |||
4372 | static void stac92xx_shutup(struct hda_codec *codec) | 4389 | static void stac92xx_shutup(struct hda_codec *codec) |
4373 | { | 4390 | { |
4374 | struct sigmatel_spec *spec = codec->spec; | 4391 | struct sigmatel_spec *spec = codec->spec; |
4375 | int i; | ||
4376 | hda_nid_t nid; | ||
4377 | 4392 | ||
4378 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | 4393 | snd_hda_shutup_pins(codec); |
4379 | nid = codec->start_nid; | ||
4380 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4381 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4382 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4383 | if (wid_type == AC_WID_PIN) | ||
4384 | snd_hda_codec_read(codec, nid, 0, | ||
4385 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4386 | } | ||
4387 | 4394 | ||
4388 | if (spec->eapd_mask) | 4395 | if (spec->eapd_mask) |
4389 | stac_gpio_set(codec, spec->gpio_mask, | 4396 | stac_gpio_set(codec, spec->gpio_mask, |
@@ -5431,6 +5438,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | |||
5431 | return 0; | 5438 | return 0; |
5432 | } | 5439 | } |
5433 | 5440 | ||
5441 | /* HP dv7 bass switch - GPIO5 */ | ||
5442 | #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info | ||
5443 | static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, | ||
5444 | struct snd_ctl_elem_value *ucontrol) | ||
5445 | { | ||
5446 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
5447 | struct sigmatel_spec *spec = codec->spec; | ||
5448 | ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); | ||
5449 | return 0; | ||
5450 | } | ||
5451 | |||
5452 | static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, | ||
5453 | struct snd_ctl_elem_value *ucontrol) | ||
5454 | { | ||
5455 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
5456 | struct sigmatel_spec *spec = codec->spec; | ||
5457 | unsigned int gpio_data; | ||
5458 | |||
5459 | gpio_data = (spec->gpio_data & ~0x20) | | ||
5460 | (ucontrol->value.integer.value[0] ? 0x20 : 0); | ||
5461 | if (gpio_data == spec->gpio_data) | ||
5462 | return 0; | ||
5463 | spec->gpio_data = gpio_data; | ||
5464 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | ||
5465 | return 1; | ||
5466 | } | ||
5467 | |||
5468 | static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { | ||
5469 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5470 | .info = stac_hp_bass_gpio_info, | ||
5471 | .get = stac_hp_bass_gpio_get, | ||
5472 | .put = stac_hp_bass_gpio_put, | ||
5473 | }; | ||
5474 | |||
5475 | static int stac_add_hp_bass_switch(struct hda_codec *codec) | ||
5476 | { | ||
5477 | struct sigmatel_spec *spec = codec->spec; | ||
5478 | |||
5479 | if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl, | ||
5480 | "Bass Speaker Playback Switch", 0)) | ||
5481 | return -ENOMEM; | ||
5482 | |||
5483 | spec->gpio_mask |= 0x20; | ||
5484 | spec->gpio_dir |= 0x20; | ||
5485 | spec->gpio_data |= 0x20; | ||
5486 | return 0; | ||
5487 | } | ||
5488 | |||
5434 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5489 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
5435 | { | 5490 | { |
5436 | struct sigmatel_spec *spec; | 5491 | struct sigmatel_spec *spec; |
@@ -5674,6 +5729,15 @@ again: | |||
5674 | return err; | 5729 | return err; |
5675 | } | 5730 | } |
5676 | 5731 | ||
5732 | /* enable bass on HP dv7 */ | ||
5733 | if (spec->board_config == STAC_HP_DV5) { | ||
5734 | unsigned int cap; | ||
5735 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); | ||
5736 | cap &= AC_GPIO_IO_COUNT; | ||
5737 | if (cap >= 6) | ||
5738 | stac_add_hp_bass_switch(codec); | ||
5739 | } | ||
5740 | |||
5677 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 5741 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
5678 | 5742 | ||
5679 | return 0; | 5743 | return 0; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index b70e26ad263f..9ddc37300f6b 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -54,6 +54,8 @@ | |||
54 | #include "hda_codec.h" | 54 | #include "hda_codec.h" |
55 | #include "hda_local.h" | 55 | #include "hda_local.h" |
56 | 56 | ||
57 | #define NID_MAPPING (-1) | ||
58 | |||
57 | /* amp values */ | 59 | /* amp values */ |
58 | #define AMP_VAL_IDX_SHIFT 19 | 60 | #define AMP_VAL_IDX_SHIFT 19 |
59 | #define AMP_VAL_IDX_MASK (0x0f<<19) | 61 | #define AMP_VAL_IDX_MASK (0x0f<<19) |
@@ -157,6 +159,19 @@ struct via_spec { | |||
157 | #endif | 159 | #endif |
158 | }; | 160 | }; |
159 | 161 | ||
162 | static struct via_spec * via_new_spec(struct hda_codec *codec) | ||
163 | { | ||
164 | struct via_spec *spec; | ||
165 | |||
166 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
167 | if (spec == NULL) | ||
168 | return NULL; | ||
169 | |||
170 | codec->spec = spec; | ||
171 | spec->codec = codec; | ||
172 | return spec; | ||
173 | } | ||
174 | |||
160 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | 175 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) |
161 | { | 176 | { |
162 | u32 vendor_id = codec->vendor_id; | 177 | u32 vendor_id = codec->vendor_id; |
@@ -443,11 +458,27 @@ static int via_add_control(struct via_spec *spec, int type, const char *name, | |||
443 | if (!knew->name) | 458 | if (!knew->name) |
444 | return -ENOMEM; | 459 | return -ENOMEM; |
445 | if (get_amp_nid_(val)) | 460 | if (get_amp_nid_(val)) |
446 | knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); | 461 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
447 | knew->private_value = val; | 462 | knew->private_value = val; |
448 | return 0; | 463 | return 0; |
449 | } | 464 | } |
450 | 465 | ||
466 | static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | ||
467 | struct snd_kcontrol_new *tmpl) | ||
468 | { | ||
469 | struct snd_kcontrol_new *knew; | ||
470 | |||
471 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | ||
472 | knew = snd_array_new(&spec->kctls); | ||
473 | if (!knew) | ||
474 | return NULL; | ||
475 | *knew = *tmpl; | ||
476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); | ||
477 | if (!knew->name) | ||
478 | return NULL; | ||
479 | return 0; | ||
480 | } | ||
481 | |||
451 | static void via_free_kctls(struct hda_codec *codec) | 482 | static void via_free_kctls(struct hda_codec *codec) |
452 | { | 483 | { |
453 | struct via_spec *spec = codec->spec; | 484 | struct via_spec *spec = codec->spec; |
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol, | |||
1088 | struct snd_ctl_elem_value *ucontrol) | 1119 | struct snd_ctl_elem_value *ucontrol) |
1089 | { | 1120 | { |
1090 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1121 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1091 | struct via_spec *spec = codec->spec; | 1122 | hda_nid_t nid = kcontrol->private_value; |
1092 | hda_nid_t nid; | ||
1093 | unsigned int pinsel; | 1123 | unsigned int pinsel; |
1094 | 1124 | ||
1095 | switch (spec->codec_type) { | ||
1096 | case VT1718S: | ||
1097 | nid = 0x34; | ||
1098 | break; | ||
1099 | case VT2002P: | ||
1100 | nid = 0x35; | ||
1101 | break; | ||
1102 | case VT1812: | ||
1103 | nid = 0x3d; | ||
1104 | break; | ||
1105 | default: | ||
1106 | nid = spec->autocfg.hp_pins[0]; | ||
1107 | break; | ||
1108 | } | ||
1109 | /* use !! to translate conn sel 2 for VT1718S */ | 1125 | /* use !! to translate conn sel 2 for VT1718S */ |
1110 | pinsel = !!snd_hda_codec_read(codec, nid, 0, | 1126 | pinsel = !!snd_hda_codec_read(codec, nid, 0, |
1111 | AC_VERB_GET_CONNECT_SEL, | 1127 | AC_VERB_GET_CONNECT_SEL, |
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active) | |||
1127 | } | 1143 | } |
1128 | } | 1144 | } |
1129 | 1145 | ||
1146 | static hda_nid_t side_mute_channel(struct via_spec *spec) | ||
1147 | { | ||
1148 | switch (spec->codec_type) { | ||
1149 | case VT1708: return 0x1b; | ||
1150 | case VT1709_10CH: return 0x29; | ||
1151 | case VT1708B_8CH: /* fall thru */ | ||
1152 | case VT1708S: return 0x27; | ||
1153 | default: return 0; | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1130 | static int update_side_mute_status(struct hda_codec *codec) | 1157 | static int update_side_mute_status(struct hda_codec *codec) |
1131 | { | 1158 | { |
1132 | /* mute side channel */ | 1159 | /* mute side channel */ |
1133 | struct via_spec *spec = codec->spec; | 1160 | struct via_spec *spec = codec->spec; |
1134 | unsigned int parm = spec->hp_independent_mode | 1161 | unsigned int parm = spec->hp_independent_mode |
1135 | ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; | 1162 | ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; |
1136 | hda_nid_t sw3; | 1163 | hda_nid_t sw3 = side_mute_channel(spec); |
1137 | |||
1138 | switch (spec->codec_type) { | ||
1139 | case VT1708: | ||
1140 | sw3 = 0x1b; | ||
1141 | break; | ||
1142 | case VT1709_10CH: | ||
1143 | sw3 = 0x29; | ||
1144 | break; | ||
1145 | case VT1708B_8CH: | ||
1146 | case VT1708S: | ||
1147 | sw3 = 0x27; | ||
1148 | break; | ||
1149 | default: | ||
1150 | sw3 = 0; | ||
1151 | break; | ||
1152 | } | ||
1153 | 1164 | ||
1154 | if (sw3) | 1165 | if (sw3) |
1155 | snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1166 | snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1162 | { | 1173 | { |
1163 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1174 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1164 | struct via_spec *spec = codec->spec; | 1175 | struct via_spec *spec = codec->spec; |
1165 | hda_nid_t nid = spec->autocfg.hp_pins[0]; | 1176 | hda_nid_t nid = kcontrol->private_value; |
1166 | unsigned int pinsel = ucontrol->value.enumerated.item[0]; | 1177 | unsigned int pinsel = ucontrol->value.enumerated.item[0]; |
1167 | /* Get Independent Mode index of headphone pin widget */ | 1178 | /* Get Independent Mode index of headphone pin widget */ |
1168 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel | 1179 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel |
1169 | ? 1 : 0; | 1180 | ? 1 : 0; |
1170 | |||
1171 | switch (spec->codec_type) { | ||
1172 | case VT1718S: | ||
1173 | nid = 0x34; | ||
1174 | pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */ | ||
1175 | spec->multiout.num_dacs = 4; | ||
1176 | break; | ||
1177 | case VT2002P: | ||
1178 | nid = 0x35; | ||
1179 | break; | ||
1180 | case VT1812: | ||
1181 | nid = 0x3d; | ||
1182 | break; | ||
1183 | default: | ||
1184 | nid = spec->autocfg.hp_pins[0]; | ||
1185 | break; | ||
1186 | } | ||
1187 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); | 1181 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); |
1188 | 1182 | ||
1189 | if (spec->multiout.hp_nid && spec->multiout.hp_nid | 1183 | if (spec->multiout.hp_nid && spec->multiout.hp_nid |
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1207 | return 0; | 1201 | return 0; |
1208 | } | 1202 | } |
1209 | 1203 | ||
1210 | static struct snd_kcontrol_new via_hp_mixer[] = { | 1204 | static struct snd_kcontrol_new via_hp_mixer[2] = { |
1211 | { | 1205 | { |
1212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1206 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1213 | .name = "Independent HP", | 1207 | .name = "Independent HP", |
1214 | .count = 1, | ||
1215 | .info = via_independent_hp_info, | 1208 | .info = via_independent_hp_info, |
1216 | .get = via_independent_hp_get, | 1209 | .get = via_independent_hp_get, |
1217 | .put = via_independent_hp_put, | 1210 | .put = via_independent_hp_put, |
1218 | }, | 1211 | }, |
1219 | { } /* end */ | 1212 | { |
1213 | .iface = NID_MAPPING, | ||
1214 | .name = "Independent HP", | ||
1215 | }, | ||
1220 | }; | 1216 | }; |
1221 | 1217 | ||
1218 | static int via_hp_build(struct via_spec *spec) | ||
1219 | { | ||
1220 | struct snd_kcontrol_new *knew; | ||
1221 | hda_nid_t nid; | ||
1222 | |||
1223 | knew = via_clone_control(spec, &via_hp_mixer[0]); | ||
1224 | if (knew == NULL) | ||
1225 | return -ENOMEM; | ||
1226 | |||
1227 | switch (spec->codec_type) { | ||
1228 | case VT1718S: | ||
1229 | nid = 0x34; | ||
1230 | break; | ||
1231 | case VT2002P: | ||
1232 | nid = 0x35; | ||
1233 | break; | ||
1234 | case VT1812: | ||
1235 | nid = 0x3d; | ||
1236 | break; | ||
1237 | default: | ||
1238 | nid = spec->autocfg.hp_pins[0]; | ||
1239 | break; | ||
1240 | } | ||
1241 | |||
1242 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | ||
1243 | knew->private_value = nid; | ||
1244 | |||
1245 | knew = via_clone_control(spec, &via_hp_mixer[1]); | ||
1246 | if (knew == NULL) | ||
1247 | return -ENOMEM; | ||
1248 | knew->subdevice = side_mute_channel(spec); | ||
1249 | |||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1222 | static void notify_aa_path_ctls(struct hda_codec *codec) | 1253 | static void notify_aa_path_ctls(struct hda_codec *codec) |
1223 | { | 1254 | { |
1224 | int i; | 1255 | int i; |
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, | |||
1376 | return 1; | 1407 | return 1; |
1377 | } | 1408 | } |
1378 | 1409 | ||
1379 | static struct snd_kcontrol_new via_smart51_mixer[] = { | 1410 | static struct snd_kcontrol_new via_smart51_mixer[2] = { |
1380 | { | 1411 | { |
1381 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1412 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1382 | .name = "Smart 5.1", | 1413 | .name = "Smart 5.1", |
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = { | |||
1385 | .get = via_smart51_get, | 1416 | .get = via_smart51_get, |
1386 | .put = via_smart51_put, | 1417 | .put = via_smart51_put, |
1387 | }, | 1418 | }, |
1388 | {} /* end */ | 1419 | { |
1420 | .iface = NID_MAPPING, | ||
1421 | .name = "Smart 5.1", | ||
1422 | } | ||
1389 | }; | 1423 | }; |
1390 | 1424 | ||
1425 | static int via_smart51_build(struct via_spec *spec) | ||
1426 | { | ||
1427 | struct snd_kcontrol_new *knew; | ||
1428 | int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; | ||
1429 | hda_nid_t nid; | ||
1430 | int i; | ||
1431 | |||
1432 | knew = via_clone_control(spec, &via_smart51_mixer[0]); | ||
1433 | if (knew == NULL) | ||
1434 | return -ENOMEM; | ||
1435 | |||
1436 | for (i = 0; i < ARRAY_SIZE(index); i++) { | ||
1437 | nid = spec->autocfg.input_pins[index[i]]; | ||
1438 | if (nid) { | ||
1439 | knew = via_clone_control(spec, &via_smart51_mixer[1]); | ||
1440 | if (knew == NULL) | ||
1441 | return -ENOMEM; | ||
1442 | knew->subdevice = nid; | ||
1443 | } | ||
1444 | } | ||
1445 | |||
1446 | return 0; | ||
1447 | } | ||
1448 | |||
1391 | /* capture mixer elements */ | 1449 | /* capture mixer elements */ |
1392 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { | 1450 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { |
1393 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), | 1451 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), |
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = { | |||
1819 | static int via_build_controls(struct hda_codec *codec) | 1877 | static int via_build_controls(struct hda_codec *codec) |
1820 | { | 1878 | { |
1821 | struct via_spec *spec = codec->spec; | 1879 | struct via_spec *spec = codec->spec; |
1822 | int err; | 1880 | struct snd_kcontrol *kctl; |
1823 | int i; | 1881 | struct snd_kcontrol_new *knew; |
1882 | int err, i; | ||
1824 | 1883 | ||
1825 | for (i = 0; i < spec->num_mixers; i++) { | 1884 | for (i = 0; i < spec->num_mixers; i++) { |
1826 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 1885 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
@@ -1845,6 +1904,27 @@ static int via_build_controls(struct hda_codec *codec) | |||
1845 | return err; | 1904 | return err; |
1846 | } | 1905 | } |
1847 | 1906 | ||
1907 | /* assign Capture Source enums to NID */ | ||
1908 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
1909 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1910 | err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); | ||
1911 | if (err < 0) | ||
1912 | return err; | ||
1913 | } | ||
1914 | |||
1915 | /* other nid->control mapping */ | ||
1916 | for (i = 0; i < spec->num_mixers; i++) { | ||
1917 | for (knew = spec->mixers[i]; knew->name; knew++) { | ||
1918 | if (knew->iface != NID_MAPPING) | ||
1919 | continue; | ||
1920 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1921 | if (kctl == NULL) | ||
1922 | continue; | ||
1923 | err = snd_hda_add_nid(codec, kctl, 0, | ||
1924 | knew->subdevice); | ||
1925 | } | ||
1926 | } | ||
1927 | |||
1848 | /* init power states */ | 1928 | /* init power states */ |
1849 | set_jack_power_state(codec); | 1929 | set_jack_power_state(codec); |
1850 | analog_low_current_mode(codec, 1); | 1930 | analog_low_current_mode(codec, 1); |
@@ -2481,9 +2561,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
2481 | spec->input_mux = &spec->private_imux[0]; | 2561 | spec->input_mux = &spec->private_imux[0]; |
2482 | 2562 | ||
2483 | if (spec->hp_mux) | 2563 | if (spec->hp_mux) |
2484 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 2564 | via_hp_build(spec); |
2485 | 2565 | ||
2486 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 2566 | via_smart51_build(spec); |
2487 | return 1; | 2567 | return 1; |
2488 | } | 2568 | } |
2489 | 2569 | ||
@@ -2554,12 +2634,10 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2554 | int err; | 2634 | int err; |
2555 | 2635 | ||
2556 | /* create a codec specific record */ | 2636 | /* create a codec specific record */ |
2557 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2637 | spec = via_new_spec(codec); |
2558 | if (spec == NULL) | 2638 | if (spec == NULL) |
2559 | return -ENOMEM; | 2639 | return -ENOMEM; |
2560 | 2640 | ||
2561 | codec->spec = spec; | ||
2562 | |||
2563 | /* automatic parse from the BIOS config */ | 2641 | /* automatic parse from the BIOS config */ |
2564 | err = vt1708_parse_auto_config(codec); | 2642 | err = vt1708_parse_auto_config(codec); |
2565 | if (err < 0) { | 2643 | if (err < 0) { |
@@ -2597,7 +2675,6 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2597 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2675 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2598 | spec->loopback.amplist = vt1708_loopbacks; | 2676 | spec->loopback.amplist = vt1708_loopbacks; |
2599 | #endif | 2677 | #endif |
2600 | spec->codec = codec; | ||
2601 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); | 2678 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); |
2602 | return 0; | 2679 | return 0; |
2603 | } | 2680 | } |
@@ -3010,9 +3087,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
3010 | spec->input_mux = &spec->private_imux[0]; | 3087 | spec->input_mux = &spec->private_imux[0]; |
3011 | 3088 | ||
3012 | if (spec->hp_mux) | 3089 | if (spec->hp_mux) |
3013 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 3090 | via_hp_build(spec); |
3014 | 3091 | ||
3015 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 3092 | via_smart51_build(spec); |
3016 | return 1; | 3093 | return 1; |
3017 | } | 3094 | } |
3018 | 3095 | ||
@@ -3032,12 +3109,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
3032 | int err; | 3109 | int err; |
3033 | 3110 | ||
3034 | /* create a codec specific record */ | 3111 | /* create a codec specific record */ |
3035 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3112 | spec = via_new_spec(codec); |
3036 | if (spec == NULL) | 3113 | if (spec == NULL) |
3037 | return -ENOMEM; | 3114 | return -ENOMEM; |
3038 | 3115 | ||
3039 | codec->spec = spec; | ||
3040 | |||
3041 | err = vt1709_parse_auto_config(codec); | 3116 | err = vt1709_parse_auto_config(codec); |
3042 | if (err < 0) { | 3117 | if (err < 0) { |
3043 | via_free(codec); | 3118 | via_free(codec); |
@@ -3126,12 +3201,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
3126 | int err; | 3201 | int err; |
3127 | 3202 | ||
3128 | /* create a codec specific record */ | 3203 | /* create a codec specific record */ |
3129 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3204 | spec = via_new_spec(codec); |
3130 | if (spec == NULL) | 3205 | if (spec == NULL) |
3131 | return -ENOMEM; | 3206 | return -ENOMEM; |
3132 | 3207 | ||
3133 | codec->spec = spec; | ||
3134 | |||
3135 | err = vt1709_parse_auto_config(codec); | 3208 | err = vt1709_parse_auto_config(codec); |
3136 | if (err < 0) { | 3209 | if (err < 0) { |
3137 | via_free(codec); | 3210 | via_free(codec); |
@@ -3581,9 +3654,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
3581 | spec->input_mux = &spec->private_imux[0]; | 3654 | spec->input_mux = &spec->private_imux[0]; |
3582 | 3655 | ||
3583 | if (spec->hp_mux) | 3656 | if (spec->hp_mux) |
3584 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 3657 | via_hp_build(spec); |
3585 | 3658 | ||
3586 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 3659 | via_smart51_build(spec); |
3587 | return 1; | 3660 | return 1; |
3588 | } | 3661 | } |
3589 | 3662 | ||
@@ -3605,12 +3678,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
3605 | if (get_codec_type(codec) == VT1708BCE) | 3678 | if (get_codec_type(codec) == VT1708BCE) |
3606 | return patch_vt1708S(codec); | 3679 | return patch_vt1708S(codec); |
3607 | /* create a codec specific record */ | 3680 | /* create a codec specific record */ |
3608 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3681 | spec = via_new_spec(codec); |
3609 | if (spec == NULL) | 3682 | if (spec == NULL) |
3610 | return -ENOMEM; | 3683 | return -ENOMEM; |
3611 | 3684 | ||
3612 | codec->spec = spec; | ||
3613 | |||
3614 | /* automatic parse from the BIOS config */ | 3685 | /* automatic parse from the BIOS config */ |
3615 | err = vt1708B_parse_auto_config(codec); | 3686 | err = vt1708B_parse_auto_config(codec); |
3616 | if (err < 0) { | 3687 | if (err < 0) { |
@@ -3657,12 +3728,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
3657 | int err; | 3728 | int err; |
3658 | 3729 | ||
3659 | /* create a codec specific record */ | 3730 | /* create a codec specific record */ |
3660 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3731 | spec = via_new_spec(codec); |
3661 | if (spec == NULL) | 3732 | if (spec == NULL) |
3662 | return -ENOMEM; | 3733 | return -ENOMEM; |
3663 | 3734 | ||
3664 | codec->spec = spec; | ||
3665 | |||
3666 | /* automatic parse from the BIOS config */ | 3735 | /* automatic parse from the BIOS config */ |
3667 | err = vt1708B_parse_auto_config(codec); | 3736 | err = vt1708B_parse_auto_config(codec); |
3668 | if (err < 0) { | 3737 | if (err < 0) { |
@@ -4071,9 +4140,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4071 | spec->input_mux = &spec->private_imux[0]; | 4140 | spec->input_mux = &spec->private_imux[0]; |
4072 | 4141 | ||
4073 | if (spec->hp_mux) | 4142 | if (spec->hp_mux) |
4074 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4143 | via_hp_build(spec); |
4075 | 4144 | ||
4076 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 4145 | via_smart51_build(spec); |
4077 | return 1; | 4146 | return 1; |
4078 | } | 4147 | } |
4079 | 4148 | ||
@@ -4103,12 +4172,10 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
4103 | int err; | 4172 | int err; |
4104 | 4173 | ||
4105 | /* create a codec specific record */ | 4174 | /* create a codec specific record */ |
4106 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4175 | spec = via_new_spec(codec); |
4107 | if (spec == NULL) | 4176 | if (spec == NULL) |
4108 | return -ENOMEM; | 4177 | return -ENOMEM; |
4109 | 4178 | ||
4110 | codec->spec = spec; | ||
4111 | |||
4112 | /* automatic parse from the BIOS config */ | 4179 | /* automatic parse from the BIOS config */ |
4113 | err = vt1708S_parse_auto_config(codec); | 4180 | err = vt1708S_parse_auto_config(codec); |
4114 | if (err < 0) { | 4181 | if (err < 0) { |
@@ -4443,7 +4510,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
4443 | spec->input_mux = &spec->private_imux[0]; | 4510 | spec->input_mux = &spec->private_imux[0]; |
4444 | 4511 | ||
4445 | if (spec->hp_mux) | 4512 | if (spec->hp_mux) |
4446 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4513 | via_hp_build(spec); |
4447 | 4514 | ||
4448 | return 1; | 4515 | return 1; |
4449 | } | 4516 | } |
@@ -4464,12 +4531,10 @@ static int patch_vt1702(struct hda_codec *codec) | |||
4464 | int err; | 4531 | int err; |
4465 | 4532 | ||
4466 | /* create a codec specific record */ | 4533 | /* create a codec specific record */ |
4467 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4534 | spec = via_new_spec(codec); |
4468 | if (spec == NULL) | 4535 | if (spec == NULL) |
4469 | return -ENOMEM; | 4536 | return -ENOMEM; |
4470 | 4537 | ||
4471 | codec->spec = spec; | ||
4472 | |||
4473 | /* automatic parse from the BIOS config */ | 4538 | /* automatic parse from the BIOS config */ |
4474 | err = vt1702_parse_auto_config(codec); | 4539 | err = vt1702_parse_auto_config(codec); |
4475 | if (err < 0) { | 4540 | if (err < 0) { |
@@ -4865,9 +4930,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) | |||
4865 | spec->input_mux = &spec->private_imux[0]; | 4930 | spec->input_mux = &spec->private_imux[0]; |
4866 | 4931 | ||
4867 | if (spec->hp_mux) | 4932 | if (spec->hp_mux) |
4868 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4933 | via_hp_build(spec); |
4869 | 4934 | ||
4870 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 4935 | via_smart51_build(spec); |
4871 | 4936 | ||
4872 | return 1; | 4937 | return 1; |
4873 | } | 4938 | } |
@@ -4888,12 +4953,10 @@ static int patch_vt1718S(struct hda_codec *codec) | |||
4888 | int err; | 4953 | int err; |
4889 | 4954 | ||
4890 | /* create a codec specific record */ | 4955 | /* create a codec specific record */ |
4891 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4956 | spec = via_new_spec(codec); |
4892 | if (spec == NULL) | 4957 | if (spec == NULL) |
4893 | return -ENOMEM; | 4958 | return -ENOMEM; |
4894 | 4959 | ||
4895 | codec->spec = spec; | ||
4896 | |||
4897 | /* automatic parse from the BIOS config */ | 4960 | /* automatic parse from the BIOS config */ |
4898 | err = vt1718S_parse_auto_config(codec); | 4961 | err = vt1718S_parse_auto_config(codec); |
4899 | if (err < 0) { | 4962 | if (err < 0) { |
@@ -5014,6 +5077,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { | |||
5014 | { | 5077 | { |
5015 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5078 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5016 | .name = "Digital Mic Capture Switch", | 5079 | .name = "Digital Mic Capture Switch", |
5080 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x26, | ||
5017 | .count = 1, | 5081 | .count = 1, |
5018 | .info = vt1716s_dmic_info, | 5082 | .info = vt1716s_dmic_info, |
5019 | .get = vt1716s_dmic_get, | 5083 | .get = vt1716s_dmic_get, |
@@ -5361,9 +5425,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) | |||
5361 | spec->input_mux = &spec->private_imux[0]; | 5425 | spec->input_mux = &spec->private_imux[0]; |
5362 | 5426 | ||
5363 | if (spec->hp_mux) | 5427 | if (spec->hp_mux) |
5364 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 5428 | via_hp_build(spec); |
5365 | 5429 | ||
5366 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 5430 | via_smart51_build(spec); |
5367 | 5431 | ||
5368 | return 1; | 5432 | return 1; |
5369 | } | 5433 | } |
@@ -5384,12 +5448,10 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
5384 | int err; | 5448 | int err; |
5385 | 5449 | ||
5386 | /* create a codec specific record */ | 5450 | /* create a codec specific record */ |
5387 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5451 | spec = via_new_spec(codec); |
5388 | if (spec == NULL) | 5452 | if (spec == NULL) |
5389 | return -ENOMEM; | 5453 | return -ENOMEM; |
5390 | 5454 | ||
5391 | codec->spec = spec; | ||
5392 | |||
5393 | /* automatic parse from the BIOS config */ | 5455 | /* automatic parse from the BIOS config */ |
5394 | err = vt1716S_parse_auto_config(codec); | 5456 | err = vt1716S_parse_auto_config(codec); |
5395 | if (err < 0) { | 5457 | if (err < 0) { |
@@ -5719,7 +5781,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) | |||
5719 | spec->input_mux = &spec->private_imux[0]; | 5781 | spec->input_mux = &spec->private_imux[0]; |
5720 | 5782 | ||
5721 | if (spec->hp_mux) | 5783 | if (spec->hp_mux) |
5722 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 5784 | via_hp_build(spec); |
5723 | 5785 | ||
5724 | return 1; | 5786 | return 1; |
5725 | } | 5787 | } |
@@ -5741,12 +5803,10 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
5741 | int err; | 5803 | int err; |
5742 | 5804 | ||
5743 | /* create a codec specific record */ | 5805 | /* create a codec specific record */ |
5744 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5806 | spec = via_new_spec(codec); |
5745 | if (spec == NULL) | 5807 | if (spec == NULL) |
5746 | return -ENOMEM; | 5808 | return -ENOMEM; |
5747 | 5809 | ||
5748 | codec->spec = spec; | ||
5749 | |||
5750 | /* automatic parse from the BIOS config */ | 5810 | /* automatic parse from the BIOS config */ |
5751 | err = vt2002P_parse_auto_config(codec); | 5811 | err = vt2002P_parse_auto_config(codec); |
5752 | if (err < 0) { | 5812 | if (err < 0) { |
@@ -6070,7 +6130,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) | |||
6070 | spec->input_mux = &spec->private_imux[0]; | 6130 | spec->input_mux = &spec->private_imux[0]; |
6071 | 6131 | ||
6072 | if (spec->hp_mux) | 6132 | if (spec->hp_mux) |
6073 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 6133 | via_hp_build(spec); |
6074 | 6134 | ||
6075 | return 1; | 6135 | return 1; |
6076 | } | 6136 | } |
@@ -6092,12 +6152,10 @@ static int patch_vt1812(struct hda_codec *codec) | |||
6092 | int err; | 6152 | int err; |
6093 | 6153 | ||
6094 | /* create a codec specific record */ | 6154 | /* create a codec specific record */ |
6095 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 6155 | spec = via_new_spec(codec); |
6096 | if (spec == NULL) | 6156 | if (spec == NULL) |
6097 | return -ENOMEM; | 6157 | return -ENOMEM; |
6098 | 6158 | ||
6099 | codec->spec = spec; | ||
6100 | |||
6101 | /* automatic parse from the BIOS config */ | 6159 | /* automatic parse from the BIOS config */ |
6102 | err = vt1812_parse_auto_config(codec); | 6160 | err = vt1812_parse_auto_config(codec); |
6103 | if (err < 0) { | 6161 | if (err < 0) { |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index c7cff6f8168a..4fc6d8bc637e 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -106,7 +106,7 @@ module_param_array(dxr_enable, int, NULL, 0444); | |||
106 | MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); | 106 | MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); |
107 | 107 | ||
108 | 108 | ||
109 | static const struct pci_device_id snd_ice1712_ids[] = { | 109 | static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = { |
110 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ | 110 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ |
111 | { 0, } | 111 | { 0, } |
112 | }; | 112 | }; |
@@ -1180,6 +1180,10 @@ static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream) | |||
1180 | snd_pcm_set_sync(substream); | 1180 | snd_pcm_set_sync(substream); |
1181 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 1181 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
1182 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | 1182 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); |
1183 | if (is_pro_rate_locked(ice)) { | ||
1184 | runtime->hw.rate_min = PRO_RATE_DEFAULT; | ||
1185 | runtime->hw.rate_max = PRO_RATE_DEFAULT; | ||
1186 | } | ||
1183 | 1187 | ||
1184 | if (ice->spdif.ops.open) | 1188 | if (ice->spdif.ops.open) |
1185 | ice->spdif.ops.open(ice, substream); | 1189 | ice->spdif.ops.open(ice, substream); |
@@ -1197,6 +1201,11 @@ static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream) | |||
1197 | snd_pcm_set_sync(substream); | 1201 | snd_pcm_set_sync(substream); |
1198 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 1202 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
1199 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | 1203 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); |
1204 | if (is_pro_rate_locked(ice)) { | ||
1205 | runtime->hw.rate_min = PRO_RATE_DEFAULT; | ||
1206 | runtime->hw.rate_max = PRO_RATE_DEFAULT; | ||
1207 | } | ||
1208 | |||
1200 | return 0; | 1209 | return 0; |
1201 | } | 1210 | } |
1202 | 1211 | ||
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index ae29073eea93..c1498fa5545f 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(model, "Use the given board model."); | |||
94 | 94 | ||
95 | 95 | ||
96 | /* Both VT1720 and VT1724 have the same PCI IDs */ | 96 | /* Both VT1720 and VT1724 have the same PCI IDs */ |
97 | static const struct pci_device_id snd_vt1724_ids[] = { | 97 | static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = { |
98 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, | 98 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, |
99 | { 0, } | 99 | { 0, } |
100 | }; | 100 | }; |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index b990143636f1..6433e65c9507 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -420,7 +420,7 @@ struct intel8x0 { | |||
420 | u32 int_sta_mask; /* interrupt status mask */ | 420 | u32 int_sta_mask; /* interrupt status mask */ |
421 | }; | 421 | }; |
422 | 422 | ||
423 | static struct pci_device_id snd_intel8x0_ids[] = { | 423 | static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = { |
424 | { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */ | 424 | { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */ |
425 | { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */ | 425 | { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */ |
426 | { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */ | 426 | { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */ |
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 9e7d12e7673f..13cec1e5ced9 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -219,7 +219,7 @@ struct intel8x0m { | |||
219 | unsigned int pcm_pos_shift; | 219 | unsigned int pcm_pos_shift; |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static struct pci_device_id snd_intel8x0m_ids[] = { | 222 | static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = { |
223 | { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */ | 223 | { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */ |
224 | { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */ | 224 | { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */ |
225 | { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */ | 225 | { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */ |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 7cc38a11e997..6d795700be79 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -418,7 +418,7 @@ module_param_array(enable, bool, NULL, 0444); | |||
418 | MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard."); | 418 | MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard."); |
419 | MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>"); | 419 | MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>"); |
420 | 420 | ||
421 | static struct pci_device_id snd_korg1212_ids[] = { | 421 | static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = { |
422 | { | 422 | { |
423 | .vendor = 0x10b5, | 423 | .vendor = 0x10b5, |
424 | .device = 0x906d, | 424 | .device = 0x906d, |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 11b8c6514b3d..0cca56038cd9 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -55,7 +55,7 @@ static const char card_name[] = "LX6464ES"; | |||
55 | 55 | ||
56 | #define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056 | 56 | #define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056 |
57 | 57 | ||
58 | static struct pci_device_id snd_lx6464es_ids[] = { | 58 | static DEFINE_PCI_DEVICE_TABLE(snd_lx6464es_ids) = { |
59 | { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), | 59 | { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), |
60 | .subvendor = PCI_VENDOR_ID_DIGIGRAM, | 60 | .subvendor = PCI_VENDOR_ID_DIGIGRAM, |
61 | .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM | 61 | .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 75283fbb4b3f..b64e78139d63 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -861,7 +861,7 @@ struct snd_m3 { | |||
861 | /* | 861 | /* |
862 | * pci ids | 862 | * pci ids |
863 | */ | 863 | */ |
864 | static struct pci_device_id snd_m3_ids[] = { | 864 | static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = { |
865 | {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, | 865 | {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, |
866 | PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, | 866 | PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, |
867 | {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, | 867 | {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index a83d1968a845..7e8e7da592a9 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard."); | |||
60 | /* | 60 | /* |
61 | */ | 61 | */ |
62 | 62 | ||
63 | static struct pci_device_id snd_mixart_ids[] = { | 63 | static DEFINE_PCI_DEVICE_TABLE(snd_mixart_ids) = { |
64 | { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */ | 64 | { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */ |
65 | { 0, } | 65 | { 0, } |
66 | }; | 66 | }; |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 97a0731331a1..5a60492ac7b3 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -262,7 +262,7 @@ struct nm256 { | |||
262 | /* | 262 | /* |
263 | * PCI ids | 263 | * PCI ids |
264 | */ | 264 | */ |
265 | static struct pci_device_id snd_nm256_ids[] = { | 265 | static DEFINE_PCI_DEVICE_TABLE(snd_nm256_ids) = { |
266 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0}, | 266 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0}, |
267 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0}, | 267 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0}, |
268 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0}, | 268 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0}, |
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index 389941cf6100..acd8f15f7bff 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile | |||
@@ -2,7 +2,7 @@ snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o | |||
2 | snd-hifier-objs := hifier.o | 2 | snd-hifier-objs := hifier.o |
3 | snd-oxygen-objs := oxygen.o | 3 | snd-oxygen-objs := oxygen.o |
4 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ | 4 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ |
5 | xonar_pcm179x.o xonar_cs43xx.o xonar_hdmi.o | 5 | xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o |
6 | 6 | ||
7 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o | 7 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o |
8 | obj-$(CONFIG_SND_HIFIER) += snd-hifier.o | 8 | obj-$(CONFIG_SND_HIFIER) += snd-hifier.o |
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index e3c229b63311..5a87d683691f 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c | |||
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string"); | |||
48 | module_param_array(enable, bool, NULL, 0444); | 48 | module_param_array(enable, bool, NULL, 0444); |
49 | MODULE_PARM_DESC(enable, "enable card"); | 49 | MODULE_PARM_DESC(enable, "enable card"); |
50 | 50 | ||
51 | static struct pci_device_id hifier_ids[] __devinitdata = { | 51 | static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = { |
52 | { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, | 52 | { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, |
53 | { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, | 53 | { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, |
54 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, | 54 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, |
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index acbedebcffd9..289cb4dacfc7 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -72,7 +72,7 @@ enum { | |||
72 | MODEL_CLARO_HALO, /* HT-Omega Claro halo */ | 72 | MODEL_CLARO_HALO, /* HT-Omega Claro halo */ |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static struct pci_device_id oxygen_ids[] __devinitdata = { | 75 | static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { |
76 | { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, | 76 | { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, |
77 | { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, | 77 | { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, |
78 | { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, | 78 | { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, |
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 6accaf9580b2..f03a2f2cffee 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(id, "ID string"); | |||
40 | module_param_array(enable, bool, NULL, 0444); | 40 | module_param_array(enable, bool, NULL, 0444); |
41 | MODULE_PARM_DESC(enable, "enable card"); | 41 | MODULE_PARM_DESC(enable, "enable card"); |
42 | 42 | ||
43 | static struct pci_device_id xonar_ids[] __devinitdata = { | 43 | static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = { |
44 | { OXYGEN_PCI_SUBID(0x1043, 0x8269) }, | 44 | { OXYGEN_PCI_SUBID(0x1043, 0x8269) }, |
45 | { OXYGEN_PCI_SUBID(0x1043, 0x8275) }, | 45 | { OXYGEN_PCI_SUBID(0x1043, 0x8275) }, |
46 | { OXYGEN_PCI_SUBID(0x1043, 0x82b7) }, | 46 | { OXYGEN_PCI_SUBID(0x1043, 0x82b7) }, |
@@ -49,6 +49,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = { | |||
49 | { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, | 49 | { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, |
50 | { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, | 50 | { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, |
51 | { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, | 51 | { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, |
52 | { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, | ||
52 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, | 53 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, |
53 | { } | 54 | { } |
54 | }; | 55 | }; |
@@ -61,6 +62,8 @@ static int __devinit get_xonar_model(struct oxygen *chip, | |||
61 | return 0; | 62 | return 0; |
62 | if (get_xonar_cs43xx_model(chip, id) >= 0) | 63 | if (get_xonar_cs43xx_model(chip, id) >= 0) |
63 | return 0; | 64 | return 0; |
65 | if (get_xonar_wm87x6_model(chip, id) >= 0) | ||
66 | return 0; | ||
64 | return -EINVAL; | 67 | return -EINVAL; |
65 | } | 68 | } |
66 | 69 | ||
diff --git a/sound/pci/oxygen/wm8766.h b/sound/pci/oxygen/wm8766.h new file mode 100644 index 000000000000..e0e849a7eaeb --- /dev/null +++ b/sound/pci/oxygen/wm8766.h | |||
@@ -0,0 +1,73 @@ | |||
1 | #ifndef WM8766_H_INCLUDED | ||
2 | #define WM8766_H_INCLUDED | ||
3 | |||
4 | #define WM8766_LDA1 0x00 | ||
5 | #define WM8766_RDA1 0x01 | ||
6 | #define WM8766_DAC_CTRL 0x02 | ||
7 | #define WM8766_INT_CTRL 0x03 | ||
8 | #define WM8766_LDA2 0x04 | ||
9 | #define WM8766_RDA2 0x05 | ||
10 | #define WM8766_LDA3 0x06 | ||
11 | #define WM8766_RDA3 0x07 | ||
12 | #define WM8766_MASTDA 0x08 | ||
13 | #define WM8766_DAC_CTRL2 0x09 | ||
14 | #define WM8766_DAC_CTRL3 0x0a | ||
15 | #define WM8766_MUTE1 0x0c | ||
16 | #define WM8766_MUTE2 0x0f | ||
17 | #define WM8766_RESET 0x1f | ||
18 | |||
19 | /* LDAx/RDAx/MASTDA */ | ||
20 | #define WM8766_ATT_MASK 0x0ff | ||
21 | #define WM8766_UPDATE 0x100 | ||
22 | /* DAC_CTRL */ | ||
23 | #define WM8766_MUTEALL 0x001 | ||
24 | #define WM8766_DEEMPALL 0x002 | ||
25 | #define WM8766_PWDN 0x004 | ||
26 | #define WM8766_ATC 0x008 | ||
27 | #define WM8766_IZD 0x010 | ||
28 | #define WM8766_PL_LEFT_MASK 0x060 | ||
29 | #define WM8766_PL_LEFT_MUTE 0x000 | ||
30 | #define WM8766_PL_LEFT_LEFT 0x020 | ||
31 | #define WM8766_PL_LEFT_RIGHT 0x040 | ||
32 | #define WM8766_PL_LEFT_LRMIX 0x060 | ||
33 | #define WM8766_PL_RIGHT_MASK 0x180 | ||
34 | #define WM8766_PL_RIGHT_MUTE 0x000 | ||
35 | #define WM8766_PL_RIGHT_LEFT 0x080 | ||
36 | #define WM8766_PL_RIGHT_RIGHT 0x100 | ||
37 | #define WM8766_PL_RIGHT_LRMIX 0x180 | ||
38 | /* INT_CTRL */ | ||
39 | #define WM8766_FMT_MASK 0x003 | ||
40 | #define WM8766_FMT_RJUST 0x000 | ||
41 | #define WM8766_FMT_LJUST 0x001 | ||
42 | #define WM8766_FMT_I2S 0x002 | ||
43 | #define WM8766_FMT_DSP 0x003 | ||
44 | #define WM8766_LRP 0x004 | ||
45 | #define WM8766_BCP 0x008 | ||
46 | #define WM8766_IWL_MASK 0x030 | ||
47 | #define WM8766_IWL_16 0x000 | ||
48 | #define WM8766_IWL_20 0x010 | ||
49 | #define WM8766_IWL_24 0x020 | ||
50 | #define WM8766_IWL_32 0x030 | ||
51 | #define WM8766_PHASE_MASK 0x1c0 | ||
52 | /* DAC_CTRL2 */ | ||
53 | #define WM8766_ZCD 0x001 | ||
54 | #define WM8766_DZFM_MASK 0x006 | ||
55 | #define WM8766_DMUTE_MASK 0x038 | ||
56 | #define WM8766_DEEMP_MASK 0x1c0 | ||
57 | /* DAC_CTRL3 */ | ||
58 | #define WM8766_DACPD_MASK 0x00e | ||
59 | #define WM8766_PWRDNALL 0x010 | ||
60 | #define WM8766_MS 0x020 | ||
61 | #define WM8766_RATE_MASK 0x1c0 | ||
62 | #define WM8766_RATE_128 0x000 | ||
63 | #define WM8766_RATE_192 0x040 | ||
64 | #define WM8766_RATE_256 0x080 | ||
65 | #define WM8766_RATE_384 0x0c0 | ||
66 | #define WM8766_RATE_512 0x100 | ||
67 | #define WM8766_RATE_768 0x140 | ||
68 | /* MUTE1 */ | ||
69 | #define WM8766_MPD1 0x040 | ||
70 | /* MUTE2 */ | ||
71 | #define WM8766_MPD2 0x020 | ||
72 | |||
73 | #endif | ||
diff --git a/sound/pci/oxygen/wm8776.h b/sound/pci/oxygen/wm8776.h new file mode 100644 index 000000000000..1a96f5615727 --- /dev/null +++ b/sound/pci/oxygen/wm8776.h | |||
@@ -0,0 +1,177 @@ | |||
1 | #ifndef WM8776_H_INCLUDED | ||
2 | #define WM8776_H_INCLUDED | ||
3 | |||
4 | /* | ||
5 | * the following register names are from: | ||
6 | * wm8776.h -- WM8776 ASoC driver | ||
7 | * | ||
8 | * Copyright 2009 Wolfson Microelectronics plc | ||
9 | * | ||
10 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #define WM8776_HPLVOL 0x00 | ||
18 | #define WM8776_HPRVOL 0x01 | ||
19 | #define WM8776_HPMASTER 0x02 | ||
20 | #define WM8776_DACLVOL 0x03 | ||
21 | #define WM8776_DACRVOL 0x04 | ||
22 | #define WM8776_DACMASTER 0x05 | ||
23 | #define WM8776_PHASESWAP 0x06 | ||
24 | #define WM8776_DACCTRL1 0x07 | ||
25 | #define WM8776_DACMUTE 0x08 | ||
26 | #define WM8776_DACCTRL2 0x09 | ||
27 | #define WM8776_DACIFCTRL 0x0a | ||
28 | #define WM8776_ADCIFCTRL 0x0b | ||
29 | #define WM8776_MSTRCTRL 0x0c | ||
30 | #define WM8776_PWRDOWN 0x0d | ||
31 | #define WM8776_ADCLVOL 0x0e | ||
32 | #define WM8776_ADCRVOL 0x0f | ||
33 | #define WM8776_ALCCTRL1 0x10 | ||
34 | #define WM8776_ALCCTRL2 0x11 | ||
35 | #define WM8776_ALCCTRL3 0x12 | ||
36 | #define WM8776_NOISEGATE 0x13 | ||
37 | #define WM8776_LIMITER 0x14 | ||
38 | #define WM8776_ADCMUX 0x15 | ||
39 | #define WM8776_OUTMUX 0x16 | ||
40 | #define WM8776_RESET 0x17 | ||
41 | |||
42 | |||
43 | /* HPLVOL/HPRVOL/HPMASTER */ | ||
44 | #define WM8776_HPATT_MASK 0x07f | ||
45 | #define WM8776_HPZCEN 0x080 | ||
46 | #define WM8776_UPDATE 0x100 | ||
47 | |||
48 | /* DACLVOL/DACRVOL/DACMASTER */ | ||
49 | #define WM8776_DATT_MASK 0x0ff | ||
50 | /*#define WM8776_UPDATE 0x100*/ | ||
51 | |||
52 | /* PHASESWAP */ | ||
53 | #define WM8776_PH_MASK 0x003 | ||
54 | |||
55 | /* DACCTRL1 */ | ||
56 | #define WM8776_DZCEN 0x001 | ||
57 | #define WM8776_ATC 0x002 | ||
58 | #define WM8776_IZD 0x004 | ||
59 | #define WM8776_TOD 0x008 | ||
60 | #define WM8776_PL_LEFT_MASK 0x030 | ||
61 | #define WM8776_PL_LEFT_MUTE 0x000 | ||
62 | #define WM8776_PL_LEFT_LEFT 0x010 | ||
63 | #define WM8776_PL_LEFT_RIGHT 0x020 | ||
64 | #define WM8776_PL_LEFT_LRMIX 0x030 | ||
65 | #define WM8776_PL_RIGHT_MASK 0x0c0 | ||
66 | #define WM8776_PL_RIGHT_MUTE 0x000 | ||
67 | #define WM8776_PL_RIGHT_LEFT 0x040 | ||
68 | #define WM8776_PL_RIGHT_RIGHT 0x080 | ||
69 | #define WM8776_PL_RIGHT_LRMIX 0x0c0 | ||
70 | |||
71 | /* DACMUTE */ | ||
72 | #define WM8776_DMUTE 0x001 | ||
73 | |||
74 | /* DACCTRL2 */ | ||
75 | #define WM8776_DEEMPH 0x001 | ||
76 | #define WM8776_DZFM_MASK 0x006 | ||
77 | #define WM8776_DZFM_NONE 0x000 | ||
78 | #define WM8776_DZFM_LR 0x002 | ||
79 | #define WM8776_DZFM_BOTH 0x004 | ||
80 | #define WM8776_DZFM_EITHER 0x006 | ||
81 | |||
82 | /* DACIFCTRL */ | ||
83 | #define WM8776_DACFMT_MASK 0x003 | ||
84 | #define WM8776_DACFMT_RJUST 0x000 | ||
85 | #define WM8776_DACFMT_LJUST 0x001 | ||
86 | #define WM8776_DACFMT_I2S 0x002 | ||
87 | #define WM8776_DACFMT_DSP 0x003 | ||
88 | #define WM8776_DACLRP 0x004 | ||
89 | #define WM8776_DACBCP 0x008 | ||
90 | #define WM8776_DACWL_MASK 0x030 | ||
91 | #define WM8776_DACWL_16 0x000 | ||
92 | #define WM8776_DACWL_20 0x010 | ||
93 | #define WM8776_DACWL_24 0x020 | ||
94 | #define WM8776_DACWL_32 0x030 | ||
95 | |||
96 | /* ADCIFCTRL */ | ||
97 | #define WM8776_ADCFMT_MASK 0x003 | ||
98 | #define WM8776_ADCFMT_RJUST 0x000 | ||
99 | #define WM8776_ADCFMT_LJUST 0x001 | ||
100 | #define WM8776_ADCFMT_I2S 0x002 | ||
101 | #define WM8776_ADCFMT_DSP 0x003 | ||
102 | #define WM8776_ADCLRP 0x004 | ||
103 | #define WM8776_ADCBCP 0x008 | ||
104 | #define WM8776_ADCWL_MASK 0x030 | ||
105 | #define WM8776_ADCWL_16 0x000 | ||
106 | #define WM8776_ADCWL_20 0x010 | ||
107 | #define WM8776_ADCWL_24 0x020 | ||
108 | #define WM8776_ADCWL_32 0x030 | ||
109 | #define WM8776_ADCMCLK 0x040 | ||
110 | #define WM8776_ADCHPD 0x100 | ||
111 | |||
112 | /* MSTRCTRL */ | ||
113 | #define WM8776_ADCRATE_MASK 0x007 | ||
114 | #define WM8776_ADCRATE_256 0x002 | ||
115 | #define WM8776_ADCRATE_384 0x003 | ||
116 | #define WM8776_ADCRATE_512 0x004 | ||
117 | #define WM8776_ADCRATE_768 0x005 | ||
118 | #define WM8776_ADCOSR 0x008 | ||
119 | #define WM8776_DACRATE_MASK 0x070 | ||
120 | #define WM8776_DACRATE_128 0x000 | ||
121 | #define WM8776_DACRATE_192 0x010 | ||
122 | #define WM8776_DACRATE_256 0x020 | ||
123 | #define WM8776_DACRATE_384 0x030 | ||
124 | #define WM8776_DACRATE_512 0x040 | ||
125 | #define WM8776_DACRATE_768 0x050 | ||
126 | #define WM8776_DACMS 0x080 | ||
127 | #define WM8776_ADCMS 0x100 | ||
128 | |||
129 | /* PWRDOWN */ | ||
130 | #define WM8776_PDWN 0x001 | ||
131 | #define WM8776_ADCPD 0x002 | ||
132 | #define WM8776_DACPD 0x004 | ||
133 | #define WM8776_HPPD 0x008 | ||
134 | #define WM8776_AINPD 0x040 | ||
135 | |||
136 | /* ADCLVOL/ADCRVOL */ | ||
137 | #define WM8776_AGMASK 0x0ff | ||
138 | #define WM8776_ZCA 0x100 | ||
139 | |||
140 | /* ALCCTRL1 */ | ||
141 | #define WM8776_LCT_MASK 0x00f | ||
142 | #define WM8776_MAXGAIN_MASK 0x070 | ||
143 | #define WM8776_LCSEL_MASK 0x180 | ||
144 | #define WM8776_LCSEL_LIMITER 0x000 | ||
145 | #define WM8776_LCSEL_ALC_RIGHT 0x080 | ||
146 | #define WM8776_LCSEL_ALC_LEFT 0x100 | ||
147 | #define WM8776_LCSEL_ALC_STEREO 0x180 | ||
148 | |||
149 | /* ALCCTRL2 */ | ||
150 | #define WM8776_HLD_MASK 0x00f | ||
151 | #define WM8776_ALCZC 0x080 | ||
152 | #define WM8776_LCEN 0x100 | ||
153 | |||
154 | /* ALCCTRL3 */ | ||
155 | #define WM8776_ATK_MASK 0x00f | ||
156 | #define WM8776_DCY_MASK 0x0f0 | ||
157 | |||
158 | /* NOISEGATE */ | ||
159 | #define WM8776_NGAT 0x001 | ||
160 | #define WM8776_NGTH_MASK 0x01c | ||
161 | |||
162 | /* LIMITER */ | ||
163 | #define WM8776_MAXATTEN_MASK 0x00f | ||
164 | #define WM8776_TRANWIN_MASK 0x070 | ||
165 | |||
166 | /* ADCMUX */ | ||
167 | #define WM8776_AMX_MASK 0x01f | ||
168 | #define WM8776_MUTERA 0x040 | ||
169 | #define WM8776_MUTELA 0x080 | ||
170 | #define WM8776_LRBOTH 0x100 | ||
171 | |||
172 | /* OUTMUX */ | ||
173 | #define WM8776_MX_DAC 0x001 | ||
174 | #define WM8776_MX_AUX 0x002 | ||
175 | #define WM8776_MX_BYPASS 0x004 | ||
176 | |||
177 | #endif | ||
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h index 89b3ed814d64..b35343b0a9a5 100644 --- a/sound/pci/oxygen/xonar.h +++ b/sound/pci/oxygen/xonar.h | |||
@@ -35,6 +35,8 @@ int get_xonar_pcm179x_model(struct oxygen *chip, | |||
35 | const struct pci_device_id *id); | 35 | const struct pci_device_id *id); |
36 | int get_xonar_cs43xx_model(struct oxygen *chip, | 36 | int get_xonar_cs43xx_model(struct oxygen *chip, |
37 | const struct pci_device_id *id); | 37 | const struct pci_device_id *id); |
38 | int get_xonar_wm87x6_model(struct oxygen *chip, | ||
39 | const struct pci_device_id *id); | ||
38 | 40 | ||
39 | /* HDMI helper functions */ | 41 | /* HDMI helper functions */ |
40 | 42 | ||
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c new file mode 100644 index 000000000000..dbc4b89d74e4 --- /dev/null +++ b/sound/pci/oxygen/xonar_wm87x6.c | |||
@@ -0,0 +1,1021 @@ | |||
1 | /* | ||
2 | * card driver for models with WM8776/WM8766 DACs (Xonar DS) | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * | ||
6 | * | ||
7 | * This driver is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License, version 2. | ||
9 | * | ||
10 | * This driver is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this driver; if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Xonar DS | ||
21 | * -------- | ||
22 | * | ||
23 | * CMI8788: | ||
24 | * | ||
25 | * SPI 0 -> WM8766 (surround, center/LFE, back) | ||
26 | * SPI 1 -> WM8776 (front, input) | ||
27 | * | ||
28 | * GPIO 4 <- headphone detect | ||
29 | * GPIO 6 -> route input jack to input 1/2 (1/0) | ||
30 | * GPIO 7 -> enable output to speakers | ||
31 | * GPIO 8 -> enable output to speakers | ||
32 | */ | ||
33 | |||
34 | #include <linux/pci.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <sound/control.h> | ||
37 | #include <sound/core.h> | ||
38 | #include <sound/pcm.h> | ||
39 | #include <sound/pcm_params.h> | ||
40 | #include <sound/tlv.h> | ||
41 | #include "xonar.h" | ||
42 | #include "wm8776.h" | ||
43 | #include "wm8766.h" | ||
44 | |||
45 | #define GPIO_DS_HP_DETECT 0x0010 | ||
46 | #define GPIO_DS_INPUT_ROUTE 0x0040 | ||
47 | #define GPIO_DS_OUTPUT_ENABLE 0x0180 | ||
48 | |||
49 | #define LC_CONTROL_LIMITER 0x40000000 | ||
50 | #define LC_CONTROL_ALC 0x20000000 | ||
51 | |||
52 | struct xonar_wm87x6 { | ||
53 | struct xonar_generic generic; | ||
54 | u16 wm8776_regs[0x17]; | ||
55 | u16 wm8766_regs[0x10]; | ||
56 | struct snd_kcontrol *lc_controls[13]; | ||
57 | }; | ||
58 | |||
59 | static void wm8776_write(struct oxygen *chip, | ||
60 | unsigned int reg, unsigned int value) | ||
61 | { | ||
62 | struct xonar_wm87x6 *data = chip->model_data; | ||
63 | |||
64 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | | ||
65 | OXYGEN_SPI_DATA_LENGTH_2 | | ||
66 | OXYGEN_SPI_CLOCK_160 | | ||
67 | (1 << OXYGEN_SPI_CODEC_SHIFT) | | ||
68 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, | ||
69 | (reg << 9) | value); | ||
70 | if (reg < ARRAY_SIZE(data->wm8776_regs)) { | ||
71 | if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) | ||
72 | value &= ~WM8776_UPDATE; | ||
73 | data->wm8776_regs[reg] = value; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | static void wm8776_write_cached(struct oxygen *chip, | ||
78 | unsigned int reg, unsigned int value) | ||
79 | { | ||
80 | struct xonar_wm87x6 *data = chip->model_data; | ||
81 | |||
82 | if (reg >= ARRAY_SIZE(data->wm8776_regs) || | ||
83 | value != data->wm8776_regs[reg]) | ||
84 | wm8776_write(chip, reg, value); | ||
85 | } | ||
86 | |||
87 | static void wm8766_write(struct oxygen *chip, | ||
88 | unsigned int reg, unsigned int value) | ||
89 | { | ||
90 | struct xonar_wm87x6 *data = chip->model_data; | ||
91 | |||
92 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | | ||
93 | OXYGEN_SPI_DATA_LENGTH_2 | | ||
94 | OXYGEN_SPI_CLOCK_160 | | ||
95 | (0 << OXYGEN_SPI_CODEC_SHIFT) | | ||
96 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, | ||
97 | (reg << 9) | value); | ||
98 | if (reg < ARRAY_SIZE(data->wm8766_regs)) | ||
99 | data->wm8766_regs[reg] = value; | ||
100 | } | ||
101 | |||
102 | static void wm8766_write_cached(struct oxygen *chip, | ||
103 | unsigned int reg, unsigned int value) | ||
104 | { | ||
105 | struct xonar_wm87x6 *data = chip->model_data; | ||
106 | |||
107 | if (reg >= ARRAY_SIZE(data->wm8766_regs) || | ||
108 | value != data->wm8766_regs[reg]) { | ||
109 | if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || | ||
110 | (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) | ||
111 | value &= ~WM8766_UPDATE; | ||
112 | wm8766_write(chip, reg, value); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | static void wm8776_registers_init(struct oxygen *chip) | ||
117 | { | ||
118 | struct xonar_wm87x6 *data = chip->model_data; | ||
119 | |||
120 | wm8776_write(chip, WM8776_RESET, 0); | ||
121 | wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN | | ||
122 | WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT); | ||
123 | wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0); | ||
124 | wm8776_write(chip, WM8776_DACIFCTRL, | ||
125 | WM8776_DACFMT_LJUST | WM8776_DACWL_24); | ||
126 | wm8776_write(chip, WM8776_ADCIFCTRL, | ||
127 | data->wm8776_regs[WM8776_ADCIFCTRL]); | ||
128 | wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]); | ||
129 | wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]); | ||
130 | wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]); | ||
131 | wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] | | ||
132 | WM8776_UPDATE); | ||
133 | wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]); | ||
134 | wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]); | ||
135 | wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]); | ||
136 | wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]); | ||
137 | wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE); | ||
138 | } | ||
139 | |||
140 | static void wm8766_registers_init(struct oxygen *chip) | ||
141 | { | ||
142 | wm8766_write(chip, WM8766_RESET, 0); | ||
143 | wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); | ||
144 | wm8766_write(chip, WM8766_DAC_CTRL2, | ||
145 | WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); | ||
146 | wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]); | ||
147 | wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]); | ||
148 | wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]); | ||
149 | wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]); | ||
150 | wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]); | ||
151 | wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE); | ||
152 | } | ||
153 | |||
154 | static void wm8776_init(struct oxygen *chip) | ||
155 | { | ||
156 | struct xonar_wm87x6 *data = chip->model_data; | ||
157 | |||
158 | data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN; | ||
159 | data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN; | ||
160 | data->wm8776_regs[WM8776_ADCIFCTRL] = | ||
161 | WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK; | ||
162 | data->wm8776_regs[WM8776_MSTRCTRL] = | ||
163 | WM8776_ADCRATE_256 | WM8776_DACRATE_256; | ||
164 | data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD; | ||
165 | data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA; | ||
166 | data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA; | ||
167 | data->wm8776_regs[WM8776_ADCMUX] = 0x001; | ||
168 | wm8776_registers_init(chip); | ||
169 | } | ||
170 | |||
171 | static void xonar_ds_init(struct oxygen *chip) | ||
172 | { | ||
173 | struct xonar_wm87x6 *data = chip->model_data; | ||
174 | |||
175 | data->generic.anti_pop_delay = 300; | ||
176 | data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; | ||
177 | |||
178 | wm8776_init(chip); | ||
179 | wm8766_registers_init(chip); | ||
180 | |||
181 | oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, | ||
182 | GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); | ||
183 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); | ||
184 | oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); | ||
185 | chip->interrupt_mask |= OXYGEN_INT_GPIO; | ||
186 | |||
187 | xonar_enable_output(chip); | ||
188 | |||
189 | snd_component_add(chip->card, "WM8776"); | ||
190 | snd_component_add(chip->card, "WM8766"); | ||
191 | } | ||
192 | |||
193 | static void xonar_ds_cleanup(struct oxygen *chip) | ||
194 | { | ||
195 | xonar_disable_output(chip); | ||
196 | } | ||
197 | |||
198 | static void xonar_ds_suspend(struct oxygen *chip) | ||
199 | { | ||
200 | xonar_ds_cleanup(chip); | ||
201 | } | ||
202 | |||
203 | static void xonar_ds_resume(struct oxygen *chip) | ||
204 | { | ||
205 | wm8776_registers_init(chip); | ||
206 | wm8766_registers_init(chip); | ||
207 | xonar_enable_output(chip); | ||
208 | } | ||
209 | |||
210 | static void wm8776_adc_hardware_filter(unsigned int channel, | ||
211 | struct snd_pcm_hardware *hardware) | ||
212 | { | ||
213 | if (channel == PCM_A) { | ||
214 | hardware->rates = SNDRV_PCM_RATE_32000 | | ||
215 | SNDRV_PCM_RATE_44100 | | ||
216 | SNDRV_PCM_RATE_48000 | | ||
217 | SNDRV_PCM_RATE_64000 | | ||
218 | SNDRV_PCM_RATE_88200 | | ||
219 | SNDRV_PCM_RATE_96000; | ||
220 | hardware->rate_max = 96000; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static void set_wm87x6_dac_params(struct oxygen *chip, | ||
225 | struct snd_pcm_hw_params *params) | ||
226 | { | ||
227 | } | ||
228 | |||
229 | static void set_wm8776_adc_params(struct oxygen *chip, | ||
230 | struct snd_pcm_hw_params *params) | ||
231 | { | ||
232 | u16 reg; | ||
233 | |||
234 | reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256; | ||
235 | if (params_rate(params) > 48000) | ||
236 | reg |= WM8776_ADCOSR; | ||
237 | wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); | ||
238 | } | ||
239 | |||
240 | static void update_wm8776_volume(struct oxygen *chip) | ||
241 | { | ||
242 | struct xonar_wm87x6 *data = chip->model_data; | ||
243 | u8 to_change; | ||
244 | |||
245 | if (chip->dac_volume[0] == chip->dac_volume[1]) { | ||
246 | if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] || | ||
247 | chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) { | ||
248 | wm8776_write(chip, WM8776_DACMASTER, | ||
249 | chip->dac_volume[0] | WM8776_UPDATE); | ||
250 | data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0]; | ||
251 | data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0]; | ||
252 | } | ||
253 | } else { | ||
254 | to_change = (chip->dac_volume[0] != | ||
255 | data->wm8776_regs[WM8776_DACLVOL]) << 0; | ||
256 | to_change |= (chip->dac_volume[1] != | ||
257 | data->wm8776_regs[WM8776_DACLVOL]) << 1; | ||
258 | if (to_change & 1) | ||
259 | wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] | | ||
260 | ((to_change & 2) ? 0 : WM8776_UPDATE)); | ||
261 | if (to_change & 2) | ||
262 | wm8776_write(chip, WM8776_DACRVOL, | ||
263 | chip->dac_volume[1] | WM8776_UPDATE); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static void update_wm87x6_volume(struct oxygen *chip) | ||
268 | { | ||
269 | static const u8 wm8766_regs[6] = { | ||
270 | WM8766_LDA1, WM8766_RDA1, | ||
271 | WM8766_LDA2, WM8766_RDA2, | ||
272 | WM8766_LDA3, WM8766_RDA3, | ||
273 | }; | ||
274 | struct xonar_wm87x6 *data = chip->model_data; | ||
275 | unsigned int i; | ||
276 | u8 to_change; | ||
277 | |||
278 | update_wm8776_volume(chip); | ||
279 | if (chip->dac_volume[2] == chip->dac_volume[3] && | ||
280 | chip->dac_volume[2] == chip->dac_volume[4] && | ||
281 | chip->dac_volume[2] == chip->dac_volume[5] && | ||
282 | chip->dac_volume[2] == chip->dac_volume[6] && | ||
283 | chip->dac_volume[2] == chip->dac_volume[7]) { | ||
284 | to_change = 0; | ||
285 | for (i = 0; i < 6; ++i) | ||
286 | if (chip->dac_volume[2] != | ||
287 | data->wm8766_regs[wm8766_regs[i]]) | ||
288 | to_change = 1; | ||
289 | if (to_change) { | ||
290 | wm8766_write(chip, WM8766_MASTDA, | ||
291 | chip->dac_volume[2] | WM8766_UPDATE); | ||
292 | for (i = 0; i < 6; ++i) | ||
293 | data->wm8766_regs[wm8766_regs[i]] = | ||
294 | chip->dac_volume[2]; | ||
295 | } | ||
296 | } else { | ||
297 | to_change = 0; | ||
298 | for (i = 0; i < 6; ++i) | ||
299 | to_change |= (chip->dac_volume[2 + i] != | ||
300 | data->wm8766_regs[wm8766_regs[i]]) << i; | ||
301 | for (i = 0; i < 6; ++i) | ||
302 | if (to_change & (1 << i)) | ||
303 | wm8766_write(chip, wm8766_regs[i], | ||
304 | chip->dac_volume[2 + i] | | ||
305 | ((to_change & (0x3e << i)) | ||
306 | ? 0 : WM8766_UPDATE)); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static void update_wm8776_mute(struct oxygen *chip) | ||
311 | { | ||
312 | wm8776_write_cached(chip, WM8776_DACMUTE, | ||
313 | chip->dac_mute ? WM8776_DMUTE : 0); | ||
314 | } | ||
315 | |||
316 | static void update_wm87x6_mute(struct oxygen *chip) | ||
317 | { | ||
318 | update_wm8776_mute(chip); | ||
319 | wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD | | ||
320 | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); | ||
321 | } | ||
322 | |||
323 | static void xonar_ds_gpio_changed(struct oxygen *chip) | ||
324 | { | ||
325 | u16 bits; | ||
326 | |||
327 | bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); | ||
328 | snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); | ||
329 | } | ||
330 | |||
331 | static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, | ||
332 | struct snd_ctl_elem_value *value) | ||
333 | { | ||
334 | struct oxygen *chip = ctl->private_data; | ||
335 | struct xonar_wm87x6 *data = chip->model_data; | ||
336 | u16 bit = ctl->private_value & 0xffff; | ||
337 | unsigned int reg_index = (ctl->private_value >> 16) & 0xff; | ||
338 | bool invert = (ctl->private_value >> 24) & 1; | ||
339 | |||
340 | value->value.integer.value[0] = | ||
341 | ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert; | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int wm8776_bit_switch_put(struct snd_kcontrol *ctl, | ||
346 | struct snd_ctl_elem_value *value) | ||
347 | { | ||
348 | struct oxygen *chip = ctl->private_data; | ||
349 | struct xonar_wm87x6 *data = chip->model_data; | ||
350 | u16 bit = ctl->private_value & 0xffff; | ||
351 | u16 reg_value; | ||
352 | unsigned int reg_index = (ctl->private_value >> 16) & 0xff; | ||
353 | bool invert = (ctl->private_value >> 24) & 1; | ||
354 | int changed; | ||
355 | |||
356 | mutex_lock(&chip->mutex); | ||
357 | reg_value = data->wm8776_regs[reg_index] & ~bit; | ||
358 | if (value->value.integer.value[0] ^ invert) | ||
359 | reg_value |= bit; | ||
360 | changed = reg_value != data->wm8776_regs[reg_index]; | ||
361 | if (changed) | ||
362 | wm8776_write(chip, reg_index, reg_value); | ||
363 | mutex_unlock(&chip->mutex); | ||
364 | return changed; | ||
365 | } | ||
366 | |||
367 | static int wm8776_field_enum_info(struct snd_kcontrol *ctl, | ||
368 | struct snd_ctl_elem_info *info) | ||
369 | { | ||
370 | static const char *const hld[16] = { | ||
371 | "0 ms", "2.67 ms", "5.33 ms", "10.6 ms", | ||
372 | "21.3 ms", "42.7 ms", "85.3 ms", "171 ms", | ||
373 | "341 ms", "683 ms", "1.37 s", "2.73 s", | ||
374 | "5.46 s", "10.9 s", "21.8 s", "43.7 s", | ||
375 | }; | ||
376 | static const char *const atk_lim[11] = { | ||
377 | "0.25 ms", "0.5 ms", "1 ms", "2 ms", | ||
378 | "4 ms", "8 ms", "16 ms", "32 ms", | ||
379 | "64 ms", "128 ms", "256 ms", | ||
380 | }; | ||
381 | static const char *const atk_alc[11] = { | ||
382 | "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms", | ||
383 | "134 ms", "269 ms", "538 ms", "1.08 s", | ||
384 | "2.15 s", "4.3 s", "8.6 s", | ||
385 | }; | ||
386 | static const char *const dcy_lim[11] = { | ||
387 | "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms", | ||
388 | "19.2 ms", "38.4 ms", "76.8 ms", "154 ms", | ||
389 | "307 ms", "614 ms", "1.23 s", | ||
390 | }; | ||
391 | static const char *const dcy_alc[11] = { | ||
392 | "33.5 ms", "67.0 ms", "134 ms", "268 ms", | ||
393 | "536 ms", "1.07 s", "2.14 s", "4.29 s", | ||
394 | "8.58 s", "17.2 s", "34.3 s", | ||
395 | }; | ||
396 | static const char *const tranwin[8] = { | ||
397 | "0 us", "62.5 us", "125 us", "250 us", | ||
398 | "500 us", "1 ms", "2 ms", "4 ms", | ||
399 | }; | ||
400 | u8 max; | ||
401 | const char *const *names; | ||
402 | |||
403 | max = (ctl->private_value >> 12) & 0xf; | ||
404 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
405 | info->count = 1; | ||
406 | info->value.enumerated.items = max + 1; | ||
407 | if (info->value.enumerated.item > max) | ||
408 | info->value.enumerated.item = max; | ||
409 | switch ((ctl->private_value >> 24) & 0x1f) { | ||
410 | case WM8776_ALCCTRL2: | ||
411 | names = hld; | ||
412 | break; | ||
413 | case WM8776_ALCCTRL3: | ||
414 | if (((ctl->private_value >> 20) & 0xf) == 0) { | ||
415 | if (ctl->private_value & LC_CONTROL_LIMITER) | ||
416 | names = atk_lim; | ||
417 | else | ||
418 | names = atk_alc; | ||
419 | } else { | ||
420 | if (ctl->private_value & LC_CONTROL_LIMITER) | ||
421 | names = dcy_lim; | ||
422 | else | ||
423 | names = dcy_alc; | ||
424 | } | ||
425 | break; | ||
426 | case WM8776_LIMITER: | ||
427 | names = tranwin; | ||
428 | break; | ||
429 | default: | ||
430 | return -ENXIO; | ||
431 | } | ||
432 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int wm8776_field_volume_info(struct snd_kcontrol *ctl, | ||
437 | struct snd_ctl_elem_info *info) | ||
438 | { | ||
439 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
440 | info->count = 1; | ||
441 | info->value.integer.min = (ctl->private_value >> 8) & 0xf; | ||
442 | info->value.integer.max = (ctl->private_value >> 12) & 0xf; | ||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl) | ||
447 | { | ||
448 | struct oxygen *chip = ctl->private_data; | ||
449 | struct xonar_wm87x6 *data = chip->model_data; | ||
450 | unsigned int value, reg_index, mode; | ||
451 | u8 min, max, shift; | ||
452 | u16 mask, reg_value; | ||
453 | bool invert; | ||
454 | |||
455 | if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == | ||
456 | WM8776_LCSEL_LIMITER) | ||
457 | mode = LC_CONTROL_LIMITER; | ||
458 | else | ||
459 | mode = LC_CONTROL_ALC; | ||
460 | if (!(ctl->private_value & mode)) | ||
461 | return; | ||
462 | |||
463 | value = ctl->private_value & 0xf; | ||
464 | min = (ctl->private_value >> 8) & 0xf; | ||
465 | max = (ctl->private_value >> 12) & 0xf; | ||
466 | mask = (ctl->private_value >> 16) & 0xf; | ||
467 | shift = (ctl->private_value >> 20) & 0xf; | ||
468 | reg_index = (ctl->private_value >> 24) & 0x1f; | ||
469 | invert = (ctl->private_value >> 29) & 0x1; | ||
470 | |||
471 | if (invert) | ||
472 | value = max - (value - min); | ||
473 | reg_value = data->wm8776_regs[reg_index]; | ||
474 | reg_value &= ~(mask << shift); | ||
475 | reg_value |= value << shift; | ||
476 | wm8776_write_cached(chip, reg_index, reg_value); | ||
477 | } | ||
478 | |||
479 | static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value) | ||
480 | { | ||
481 | struct oxygen *chip = ctl->private_data; | ||
482 | u8 min, max; | ||
483 | int changed; | ||
484 | |||
485 | min = (ctl->private_value >> 8) & 0xf; | ||
486 | max = (ctl->private_value >> 12) & 0xf; | ||
487 | if (value < min || value > max) | ||
488 | return -EINVAL; | ||
489 | mutex_lock(&chip->mutex); | ||
490 | changed = value != (ctl->private_value & 0xf); | ||
491 | if (changed) { | ||
492 | ctl->private_value = (ctl->private_value & ~0xf) | value; | ||
493 | wm8776_field_set_from_ctl(ctl); | ||
494 | } | ||
495 | mutex_unlock(&chip->mutex); | ||
496 | return changed; | ||
497 | } | ||
498 | |||
499 | static int wm8776_field_enum_get(struct snd_kcontrol *ctl, | ||
500 | struct snd_ctl_elem_value *value) | ||
501 | { | ||
502 | value->value.enumerated.item[0] = ctl->private_value & 0xf; | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int wm8776_field_volume_get(struct snd_kcontrol *ctl, | ||
507 | struct snd_ctl_elem_value *value) | ||
508 | { | ||
509 | value->value.integer.value[0] = ctl->private_value & 0xf; | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int wm8776_field_enum_put(struct snd_kcontrol *ctl, | ||
514 | struct snd_ctl_elem_value *value) | ||
515 | { | ||
516 | return wm8776_field_set(ctl, value->value.enumerated.item[0]); | ||
517 | } | ||
518 | |||
519 | static int wm8776_field_volume_put(struct snd_kcontrol *ctl, | ||
520 | struct snd_ctl_elem_value *value) | ||
521 | { | ||
522 | return wm8776_field_set(ctl, value->value.integer.value[0]); | ||
523 | } | ||
524 | |||
525 | static int wm8776_hp_vol_info(struct snd_kcontrol *ctl, | ||
526 | struct snd_ctl_elem_info *info) | ||
527 | { | ||
528 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
529 | info->count = 2; | ||
530 | info->value.integer.min = 0x79 - 60; | ||
531 | info->value.integer.max = 0x7f; | ||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | static int wm8776_hp_vol_get(struct snd_kcontrol *ctl, | ||
536 | struct snd_ctl_elem_value *value) | ||
537 | { | ||
538 | struct oxygen *chip = ctl->private_data; | ||
539 | struct xonar_wm87x6 *data = chip->model_data; | ||
540 | |||
541 | mutex_lock(&chip->mutex); | ||
542 | value->value.integer.value[0] = | ||
543 | data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK; | ||
544 | value->value.integer.value[1] = | ||
545 | data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK; | ||
546 | mutex_unlock(&chip->mutex); | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int wm8776_hp_vol_put(struct snd_kcontrol *ctl, | ||
551 | struct snd_ctl_elem_value *value) | ||
552 | { | ||
553 | struct oxygen *chip = ctl->private_data; | ||
554 | struct xonar_wm87x6 *data = chip->model_data; | ||
555 | u8 to_update; | ||
556 | |||
557 | mutex_lock(&chip->mutex); | ||
558 | to_update = (value->value.integer.value[0] != | ||
559 | (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK)) | ||
560 | << 0; | ||
561 | to_update |= (value->value.integer.value[1] != | ||
562 | (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK)) | ||
563 | << 1; | ||
564 | if (value->value.integer.value[0] == value->value.integer.value[1]) { | ||
565 | if (to_update) { | ||
566 | wm8776_write(chip, WM8776_HPMASTER, | ||
567 | value->value.integer.value[0] | | ||
568 | WM8776_HPZCEN | WM8776_UPDATE); | ||
569 | data->wm8776_regs[WM8776_HPLVOL] = | ||
570 | value->value.integer.value[0] | WM8776_HPZCEN; | ||
571 | data->wm8776_regs[WM8776_HPRVOL] = | ||
572 | value->value.integer.value[0] | WM8776_HPZCEN; | ||
573 | } | ||
574 | } else { | ||
575 | if (to_update & 1) | ||
576 | wm8776_write(chip, WM8776_HPLVOL, | ||
577 | value->value.integer.value[0] | | ||
578 | WM8776_HPZCEN | | ||
579 | ((to_update & 2) ? 0 : WM8776_UPDATE)); | ||
580 | if (to_update & 2) | ||
581 | wm8776_write(chip, WM8776_HPRVOL, | ||
582 | value->value.integer.value[1] | | ||
583 | WM8776_HPZCEN | WM8776_UPDATE); | ||
584 | } | ||
585 | mutex_unlock(&chip->mutex); | ||
586 | return to_update != 0; | ||
587 | } | ||
588 | |||
589 | static int wm8776_input_mux_get(struct snd_kcontrol *ctl, | ||
590 | struct snd_ctl_elem_value *value) | ||
591 | { | ||
592 | struct oxygen *chip = ctl->private_data; | ||
593 | struct xonar_wm87x6 *data = chip->model_data; | ||
594 | unsigned int mux_bit = ctl->private_value; | ||
595 | |||
596 | value->value.integer.value[0] = | ||
597 | !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static int wm8776_input_mux_put(struct snd_kcontrol *ctl, | ||
602 | struct snd_ctl_elem_value *value) | ||
603 | { | ||
604 | struct oxygen *chip = ctl->private_data; | ||
605 | struct xonar_wm87x6 *data = chip->model_data; | ||
606 | unsigned int mux_bit = ctl->private_value; | ||
607 | u16 reg; | ||
608 | int changed; | ||
609 | |||
610 | mutex_lock(&chip->mutex); | ||
611 | reg = data->wm8776_regs[WM8776_ADCMUX]; | ||
612 | if (value->value.integer.value[0]) { | ||
613 | reg &= ~0x003; | ||
614 | reg |= mux_bit; | ||
615 | } else | ||
616 | reg &= ~mux_bit; | ||
617 | changed = reg != data->wm8776_regs[WM8776_ADCMUX]; | ||
618 | if (changed) { | ||
619 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, | ||
620 | reg & 1 ? GPIO_DS_INPUT_ROUTE : 0, | ||
621 | GPIO_DS_INPUT_ROUTE); | ||
622 | wm8776_write(chip, WM8776_ADCMUX, reg); | ||
623 | } | ||
624 | mutex_unlock(&chip->mutex); | ||
625 | return changed; | ||
626 | } | ||
627 | |||
628 | static int wm8776_input_vol_info(struct snd_kcontrol *ctl, | ||
629 | struct snd_ctl_elem_info *info) | ||
630 | { | ||
631 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
632 | info->count = 2; | ||
633 | info->value.integer.min = 0xa5; | ||
634 | info->value.integer.max = 0xff; | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int wm8776_input_vol_get(struct snd_kcontrol *ctl, | ||
639 | struct snd_ctl_elem_value *value) | ||
640 | { | ||
641 | struct oxygen *chip = ctl->private_data; | ||
642 | struct xonar_wm87x6 *data = chip->model_data; | ||
643 | |||
644 | mutex_lock(&chip->mutex); | ||
645 | value->value.integer.value[0] = | ||
646 | data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK; | ||
647 | value->value.integer.value[1] = | ||
648 | data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK; | ||
649 | mutex_unlock(&chip->mutex); | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int wm8776_input_vol_put(struct snd_kcontrol *ctl, | ||
654 | struct snd_ctl_elem_value *value) | ||
655 | { | ||
656 | struct oxygen *chip = ctl->private_data; | ||
657 | struct xonar_wm87x6 *data = chip->model_data; | ||
658 | int changed = 0; | ||
659 | |||
660 | mutex_lock(&chip->mutex); | ||
661 | changed = (value->value.integer.value[0] != | ||
662 | (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) || | ||
663 | (value->value.integer.value[1] != | ||
664 | (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK)); | ||
665 | wm8776_write_cached(chip, WM8776_ADCLVOL, | ||
666 | value->value.integer.value[0] | WM8776_ZCA); | ||
667 | wm8776_write_cached(chip, WM8776_ADCRVOL, | ||
668 | value->value.integer.value[1] | WM8776_ZCA); | ||
669 | mutex_unlock(&chip->mutex); | ||
670 | return changed; | ||
671 | } | ||
672 | |||
673 | static int wm8776_level_control_info(struct snd_kcontrol *ctl, | ||
674 | struct snd_ctl_elem_info *info) | ||
675 | { | ||
676 | static const char *const names[3] = { | ||
677 | "None", "Peak Limiter", "Automatic Level Control" | ||
678 | }; | ||
679 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
680 | info->count = 1; | ||
681 | info->value.enumerated.items = 3; | ||
682 | if (info->value.enumerated.item >= 3) | ||
683 | info->value.enumerated.item = 2; | ||
684 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | static int wm8776_level_control_get(struct snd_kcontrol *ctl, | ||
689 | struct snd_ctl_elem_value *value) | ||
690 | { | ||
691 | struct oxygen *chip = ctl->private_data; | ||
692 | struct xonar_wm87x6 *data = chip->model_data; | ||
693 | |||
694 | if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN)) | ||
695 | value->value.enumerated.item[0] = 0; | ||
696 | else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == | ||
697 | WM8776_LCSEL_LIMITER) | ||
698 | value->value.enumerated.item[0] = 1; | ||
699 | else | ||
700 | value->value.enumerated.item[0] = 2; | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static void activate_control(struct oxygen *chip, | ||
705 | struct snd_kcontrol *ctl, unsigned int mode) | ||
706 | { | ||
707 | unsigned int access; | ||
708 | |||
709 | if (ctl->private_value & mode) | ||
710 | access = 0; | ||
711 | else | ||
712 | access = SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
713 | if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) { | ||
714 | ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
715 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
716 | } | ||
717 | } | ||
718 | |||
719 | static int wm8776_level_control_put(struct snd_kcontrol *ctl, | ||
720 | struct snd_ctl_elem_value *value) | ||
721 | { | ||
722 | struct oxygen *chip = ctl->private_data; | ||
723 | struct xonar_wm87x6 *data = chip->model_data; | ||
724 | unsigned int mode = 0, i; | ||
725 | u16 ctrl1, ctrl2; | ||
726 | int changed; | ||
727 | |||
728 | if (value->value.enumerated.item[0] >= 3) | ||
729 | return -EINVAL; | ||
730 | mutex_lock(&chip->mutex); | ||
731 | changed = value->value.enumerated.item[0] != ctl->private_value; | ||
732 | if (changed) { | ||
733 | ctl->private_value = value->value.enumerated.item[0]; | ||
734 | ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1]; | ||
735 | ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2]; | ||
736 | switch (value->value.enumerated.item[0]) { | ||
737 | default: | ||
738 | wm8776_write_cached(chip, WM8776_ALCCTRL2, | ||
739 | ctrl2 & ~WM8776_LCEN); | ||
740 | break; | ||
741 | case 1: | ||
742 | wm8776_write_cached(chip, WM8776_ALCCTRL1, | ||
743 | (ctrl1 & ~WM8776_LCSEL_MASK) | | ||
744 | WM8776_LCSEL_LIMITER); | ||
745 | wm8776_write_cached(chip, WM8776_ALCCTRL2, | ||
746 | ctrl2 | WM8776_LCEN); | ||
747 | mode = LC_CONTROL_LIMITER; | ||
748 | break; | ||
749 | case 2: | ||
750 | wm8776_write_cached(chip, WM8776_ALCCTRL1, | ||
751 | (ctrl1 & ~WM8776_LCSEL_MASK) | | ||
752 | WM8776_LCSEL_ALC_STEREO); | ||
753 | wm8776_write_cached(chip, WM8776_ALCCTRL2, | ||
754 | ctrl2 | WM8776_LCEN); | ||
755 | mode = LC_CONTROL_ALC; | ||
756 | break; | ||
757 | } | ||
758 | for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i) | ||
759 | activate_control(chip, data->lc_controls[i], mode); | ||
760 | } | ||
761 | mutex_unlock(&chip->mutex); | ||
762 | return changed; | ||
763 | } | ||
764 | |||
765 | static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) | ||
766 | { | ||
767 | static const char *const names[2] = { | ||
768 | "None", "High-pass Filter" | ||
769 | }; | ||
770 | |||
771 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
772 | info->count = 1; | ||
773 | info->value.enumerated.items = 2; | ||
774 | if (info->value.enumerated.item >= 2) | ||
775 | info->value.enumerated.item = 1; | ||
776 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | ||
781 | { | ||
782 | struct oxygen *chip = ctl->private_data; | ||
783 | struct xonar_wm87x6 *data = chip->model_data; | ||
784 | |||
785 | value->value.enumerated.item[0] = | ||
786 | !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD); | ||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | ||
791 | { | ||
792 | struct oxygen *chip = ctl->private_data; | ||
793 | struct xonar_wm87x6 *data = chip->model_data; | ||
794 | unsigned int reg; | ||
795 | int changed; | ||
796 | |||
797 | mutex_lock(&chip->mutex); | ||
798 | reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD; | ||
799 | if (!value->value.enumerated.item[0]) | ||
800 | reg |= WM8776_ADCHPD; | ||
801 | changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL]; | ||
802 | if (changed) | ||
803 | wm8776_write(chip, WM8776_ADCIFCTRL, reg); | ||
804 | mutex_unlock(&chip->mutex); | ||
805 | return changed; | ||
806 | } | ||
807 | |||
808 | #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \ | ||
809 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
810 | .name = xname, \ | ||
811 | .info = snd_ctl_boolean_mono_info, \ | ||
812 | .get = wm8776_bit_switch_get, \ | ||
813 | .put = wm8776_bit_switch_put, \ | ||
814 | .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \ | ||
815 | } | ||
816 | #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \ | ||
817 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
818 | .name = xname, \ | ||
819 | .private_value = (initval) | ((min) << 8) | ((max) << 12) | \ | ||
820 | ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags) | ||
821 | #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\ | ||
822 | _WM8776_FIELD_CTL(xname " Capture Enum", \ | ||
823 | reg, shift, init, min, max, mask, flags), \ | ||
824 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
825 | SNDRV_CTL_ELEM_ACCESS_INACTIVE, \ | ||
826 | .info = wm8776_field_enum_info, \ | ||
827 | .get = wm8776_field_enum_get, \ | ||
828 | .put = wm8776_field_enum_put, \ | ||
829 | } | ||
830 | #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \ | ||
831 | _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \ | ||
832 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
833 | SNDRV_CTL_ELEM_ACCESS_INACTIVE | \ | ||
834 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ | ||
835 | .info = wm8776_field_volume_info, \ | ||
836 | .get = wm8776_field_volume_get, \ | ||
837 | .put = wm8776_field_volume_put, \ | ||
838 | .tlv = { .p = tlv_p }, \ | ||
839 | } | ||
840 | |||
841 | static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0); | ||
842 | static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0); | ||
843 | static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0); | ||
844 | static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0); | ||
845 | static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0); | ||
846 | static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0); | ||
847 | static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0); | ||
848 | static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0); | ||
849 | |||
850 | static const struct snd_kcontrol_new ds_controls[] = { | ||
851 | { | ||
852 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
853 | .name = "Headphone Playback Volume", | ||
854 | .info = wm8776_hp_vol_info, | ||
855 | .get = wm8776_hp_vol_get, | ||
856 | .put = wm8776_hp_vol_put, | ||
857 | .tlv = { .p = wm8776_hp_db_scale }, | ||
858 | }, | ||
859 | WM8776_BIT_SWITCH("Headphone Playback Switch", | ||
860 | WM8776_PWRDOWN, WM8776_HPPD, 1, 0), | ||
861 | { | ||
862 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
863 | .name = "Input Capture Volume", | ||
864 | .info = wm8776_input_vol_info, | ||
865 | .get = wm8776_input_vol_get, | ||
866 | .put = wm8776_input_vol_put, | ||
867 | .tlv = { .p = wm8776_adc_db_scale }, | ||
868 | }, | ||
869 | { | ||
870 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
871 | .name = "Line Capture Switch", | ||
872 | .info = snd_ctl_boolean_mono_info, | ||
873 | .get = wm8776_input_mux_get, | ||
874 | .put = wm8776_input_mux_put, | ||
875 | .private_value = 1 << 0, | ||
876 | }, | ||
877 | { | ||
878 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
879 | .name = "Mic Capture Switch", | ||
880 | .info = snd_ctl_boolean_mono_info, | ||
881 | .get = wm8776_input_mux_get, | ||
882 | .put = wm8776_input_mux_put, | ||
883 | .private_value = 1 << 1, | ||
884 | }, | ||
885 | WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), | ||
886 | { | ||
887 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
888 | .name = "ADC Filter Capture Enum", | ||
889 | .info = hpf_info, | ||
890 | .get = hpf_get, | ||
891 | .put = hpf_put, | ||
892 | }, | ||
893 | { | ||
894 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
895 | .name = "Level Control Capture Enum", | ||
896 | .info = wm8776_level_control_info, | ||
897 | .get = wm8776_level_control_get, | ||
898 | .put = wm8776_level_control_put, | ||
899 | .private_value = 0, | ||
900 | }, | ||
901 | }; | ||
902 | static const struct snd_kcontrol_new lc_controls[] = { | ||
903 | WM8776_FIELD_CTL_VOLUME("Limiter Threshold", | ||
904 | WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, | ||
905 | LC_CONTROL_LIMITER, wm8776_lct_db_scale), | ||
906 | WM8776_FIELD_CTL_ENUM("Limiter Attack Time", | ||
907 | WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, | ||
908 | LC_CONTROL_LIMITER), | ||
909 | WM8776_FIELD_CTL_ENUM("Limiter Decay Time", | ||
910 | WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, | ||
911 | LC_CONTROL_LIMITER), | ||
912 | WM8776_FIELD_CTL_ENUM("Limiter Transient Window", | ||
913 | WM8776_LIMITER, 4, 2, 0, 7, 0x7, | ||
914 | LC_CONTROL_LIMITER), | ||
915 | WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation", | ||
916 | WM8776_LIMITER, 0, 6, 3, 12, 0xf, | ||
917 | LC_CONTROL_LIMITER, | ||
918 | wm8776_maxatten_lim_db_scale), | ||
919 | WM8776_FIELD_CTL_VOLUME("ALC Target Level", | ||
920 | WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, | ||
921 | LC_CONTROL_ALC, wm8776_lct_db_scale), | ||
922 | WM8776_FIELD_CTL_ENUM("ALC Attack Time", | ||
923 | WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, | ||
924 | LC_CONTROL_ALC), | ||
925 | WM8776_FIELD_CTL_ENUM("ALC Decay Time", | ||
926 | WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, | ||
927 | LC_CONTROL_ALC), | ||
928 | WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain", | ||
929 | WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7, | ||
930 | LC_CONTROL_ALC, wm8776_maxgain_db_scale), | ||
931 | WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation", | ||
932 | WM8776_LIMITER, 0, 10, 10, 15, 0xf, | ||
933 | LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale), | ||
934 | WM8776_FIELD_CTL_ENUM("ALC Hold Time", | ||
935 | WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf, | ||
936 | LC_CONTROL_ALC), | ||
937 | WM8776_BIT_SWITCH("Noise Gate Capture Switch", | ||
938 | WM8776_NOISEGATE, WM8776_NGAT, 0, | ||
939 | LC_CONTROL_ALC), | ||
940 | WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold", | ||
941 | WM8776_NOISEGATE, 2, 0, 0, 7, 0x7, | ||
942 | LC_CONTROL_ALC, wm8776_ngth_db_scale), | ||
943 | }; | ||
944 | |||
945 | static int xonar_ds_control_filter(struct snd_kcontrol_new *template) | ||
946 | { | ||
947 | if (!strncmp(template->name, "CD Capture ", 11)) | ||
948 | return 1; /* no CD input */ | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static int xonar_ds_mixer_init(struct oxygen *chip) | ||
953 | { | ||
954 | struct xonar_wm87x6 *data = chip->model_data; | ||
955 | unsigned int i; | ||
956 | struct snd_kcontrol *ctl; | ||
957 | int err; | ||
958 | |||
959 | for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) { | ||
960 | ctl = snd_ctl_new1(&ds_controls[i], chip); | ||
961 | if (!ctl) | ||
962 | return -ENOMEM; | ||
963 | err = snd_ctl_add(chip->card, ctl); | ||
964 | if (err < 0) | ||
965 | return err; | ||
966 | } | ||
967 | BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); | ||
968 | for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { | ||
969 | ctl = snd_ctl_new1(&lc_controls[i], chip); | ||
970 | if (!ctl) | ||
971 | return -ENOMEM; | ||
972 | err = snd_ctl_add(chip->card, ctl); | ||
973 | if (err < 0) | ||
974 | return err; | ||
975 | data->lc_controls[i] = ctl; | ||
976 | } | ||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | static const struct oxygen_model model_xonar_ds = { | ||
981 | .shortname = "Xonar DS", | ||
982 | .longname = "Asus Virtuoso 200", | ||
983 | .chip = "AV200", | ||
984 | .init = xonar_ds_init, | ||
985 | .control_filter = xonar_ds_control_filter, | ||
986 | .mixer_init = xonar_ds_mixer_init, | ||
987 | .cleanup = xonar_ds_cleanup, | ||
988 | .suspend = xonar_ds_suspend, | ||
989 | .resume = xonar_ds_resume, | ||
990 | .pcm_hardware_filter = wm8776_adc_hardware_filter, | ||
991 | .get_i2s_mclk = oxygen_default_i2s_mclk, | ||
992 | .set_dac_params = set_wm87x6_dac_params, | ||
993 | .set_adc_params = set_wm8776_adc_params, | ||
994 | .update_dac_volume = update_wm87x6_volume, | ||
995 | .update_dac_mute = update_wm87x6_mute, | ||
996 | .gpio_changed = xonar_ds_gpio_changed, | ||
997 | .dac_tlv = wm87x6_dac_db_scale, | ||
998 | .model_data_size = sizeof(struct xonar_wm87x6), | ||
999 | .device_config = PLAYBACK_0_TO_I2S | | ||
1000 | PLAYBACK_1_TO_SPDIF | | ||
1001 | CAPTURE_0_FROM_I2S_1, | ||
1002 | .dac_channels = 8, | ||
1003 | .dac_volume_min = 255 - 2*60, | ||
1004 | .dac_volume_max = 255, | ||
1005 | .function_flags = OXYGEN_FUNCTION_SPI, | ||
1006 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | ||
1007 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | ||
1008 | }; | ||
1009 | |||
1010 | int __devinit get_xonar_wm87x6_model(struct oxygen *chip, | ||
1011 | const struct pci_device_id *id) | ||
1012 | { | ||
1013 | switch (id->subdevice) { | ||
1014 | case 0x838e: | ||
1015 | chip->model = model_xonar_ds; | ||
1016 | break; | ||
1017 | default: | ||
1018 | return -EINVAL; | ||
1019 | } | ||
1020 | return 0; | ||
1021 | } | ||
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 833e9c7b27c7..95cfde27d25c 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -94,7 +94,7 @@ enum { | |||
94 | PCI_ID_LAST | 94 | PCI_ID_LAST |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static struct pci_device_id pcxhr_ids[] = { | 97 | static DEFINE_PCI_DEVICE_TABLE(pcxhr_ids) = { |
98 | { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, | 98 | { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, |
99 | { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, | 99 | { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, |
100 | { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, | 100 | { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index e66ef2b69b5d..ad4462677615 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -506,7 +506,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip); | |||
506 | /* | 506 | /* |
507 | */ | 507 | */ |
508 | 508 | ||
509 | static struct pci_device_id snd_riptide_ids[] = { | 509 | static DEFINE_PCI_DEVICE_TABLE(snd_riptide_ids) = { |
510 | { PCI_DEVICE(0x127a, 0x4310) }, | 510 | { PCI_DEVICE(0x127a, 0x4310) }, |
511 | { PCI_DEVICE(0x127a, 0x4320) }, | 511 | { PCI_DEVICE(0x127a, 0x4320) }, |
512 | { PCI_DEVICE(0x127a, 0x4330) }, | 512 | { PCI_DEVICE(0x127a, 0x4330) }, |
@@ -515,7 +515,7 @@ static struct pci_device_id snd_riptide_ids[] = { | |||
515 | }; | 515 | }; |
516 | 516 | ||
517 | #ifdef SUPPORT_JOYSTICK | 517 | #ifdef SUPPORT_JOYSTICK |
518 | static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { | 518 | static DEFINE_PCI_DEVICE_TABLE(snd_riptide_joystick_ids) = { |
519 | { PCI_DEVICE(0x127a, 0x4312) }, | 519 | { PCI_DEVICE(0x127a, 0x4312) }, |
520 | { PCI_DEVICE(0x127a, 0x4322) }, | 520 | { PCI_DEVICE(0x127a, 0x4322) }, |
521 | { PCI_DEVICE(0x127a, 0x4332) }, | 521 | { PCI_DEVICE(0x127a, 0x4332) }, |
@@ -1974,9 +1974,9 @@ snd_riptide_proc_read(struct snd_info_entry *entry, | |||
1974 | } | 1974 | } |
1975 | snd_iprintf(buffer, "Paths:\n"); | 1975 | snd_iprintf(buffer, "Paths:\n"); |
1976 | i = getpaths(cif, p); | 1976 | i = getpaths(cif, p); |
1977 | while (i--) { | 1977 | while (i >= 2) { |
1978 | snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]); | 1978 | i -= 2; |
1979 | i--; | 1979 | snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]); |
1980 | } | 1980 | } |
1981 | snd_iprintf(buffer, "\n"); | 1981 | snd_iprintf(buffer, "\n"); |
1982 | } | 1982 | } |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index f977dba7cbd0..d5e1c6eb7b7b 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -226,7 +226,7 @@ struct rme32 { | |||
226 | struct snd_kcontrol *spdif_ctl; | 226 | struct snd_kcontrol *spdif_ctl; |
227 | }; | 227 | }; |
228 | 228 | ||
229 | static struct pci_device_id snd_rme32_ids[] = { | 229 | static DEFINE_PCI_DEVICE_TABLE(snd_rme32_ids) = { |
230 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,}, | 230 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,}, |
231 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,}, | 231 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,}, |
232 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,}, | 232 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,}, |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 2ba5c0fd55db..9d5252bc870c 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -231,7 +231,7 @@ struct rme96 { | |||
231 | struct snd_kcontrol *spdif_ctl; | 231 | struct snd_kcontrol *spdif_ctl; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct pci_device_id snd_rme96_ids[] = { | 234 | static DEFINE_PCI_DEVICE_TABLE(snd_rme96_ids) = { |
235 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, }, | 235 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, }, |
236 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, }, | 236 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, }, |
237 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, }, | 237 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, }, |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 7bb827c7d806..52c6eb57cc3f 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -585,7 +585,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d | |||
585 | } | 585 | } |
586 | 586 | ||
587 | 587 | ||
588 | static struct pci_device_id snd_hdsp_ids[] = { | 588 | static DEFINE_PCI_DEVICE_TABLE(snd_hdsp_ids) = { |
589 | { | 589 | { |
590 | .vendor = PCI_VENDOR_ID_XILINX, | 590 | .vendor = PCI_VENDOR_ID_XILINX, |
591 | .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, | 591 | .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index a1b10d1a384d..3d72c1effeef 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -512,7 +512,7 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { | |||
512 | }; | 512 | }; |
513 | 513 | ||
514 | 514 | ||
515 | static struct pci_device_id snd_hdspm_ids[] __devinitdata = { | 515 | static DEFINE_PCI_DEVICE_TABLE(snd_hdspm_ids) = { |
516 | { | 516 | { |
517 | .vendor = PCI_VENDOR_ID_XILINX, | 517 | .vendor = PCI_VENDOR_ID_XILINX, |
518 | .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI, | 518 | .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI, |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index bc539abb2105..44a3e2d8c556 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -314,7 +314,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d | |||
314 | } | 314 | } |
315 | 315 | ||
316 | 316 | ||
317 | static struct pci_device_id snd_rme9652_ids[] = { | 317 | static DEFINE_PCI_DEVICE_TABLE(snd_rme9652_ids) = { |
318 | { | 318 | { |
319 | .vendor = 0x10ee, | 319 | .vendor = 0x10ee, |
320 | .device = 0x3fc4, | 320 | .device = 0x3fc4, |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 1a5ff0611072..7e3e8fbc90fe 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); | |||
48 | module_param(enable, bool, 0444); | 48 | module_param(enable, bool, 0444); |
49 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); | 49 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); |
50 | 50 | ||
51 | static struct pci_device_id snd_sis7019_ids[] = { | 51 | static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { |
52 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, | 52 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, |
53 | { 0, } | 53 | { 0, } |
54 | }; | 54 | }; |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 1f6406c4534d..337b9facadfd 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -242,7 +242,7 @@ struct sonicvibes { | |||
242 | #endif | 242 | #endif |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct pci_device_id snd_sonic_ids[] = { | 245 | static DEFINE_PCI_DEVICE_TABLE(snd_sonic_ids) = { |
246 | { PCI_VDEVICE(S3, 0xca00), 0, }, | 246 | { PCI_VDEVICE(S3, 0xca00), 0, }, |
247 | { 0, } | 247 | { 0, } |
248 | }; | 248 | }; |
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index 21cef97d478d..6d0581841d7a 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c | |||
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM."); | |||
62 | module_param_array(wavetable_size, int, NULL, 0444); | 62 | module_param_array(wavetable_size, int, NULL, 0444); |
63 | MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); | 63 | MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); |
64 | 64 | ||
65 | static struct pci_device_id snd_trident_ids[] = { | 65 | static DEFINE_PCI_DEVICE_TABLE(snd_trident_ids) = { |
66 | {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), | 66 | {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), |
67 | PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, | 67 | PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, |
68 | {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), | 68 | {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 03d6aea19749..7e494b6a1d0e 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -401,7 +401,7 @@ struct via82xx { | |||
401 | #endif | 401 | #endif |
402 | }; | 402 | }; |
403 | 403 | ||
404 | static struct pci_device_id snd_via82xx_ids[] = { | 404 | static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_ids) = { |
405 | /* 0x1106, 0x3058 */ | 405 | /* 0x1106, 0x3058 */ |
406 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */ | 406 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */ |
407 | /* 0x1106, 0x3059 */ | 407 | /* 0x1106, 0x3059 */ |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 47eb61561dfc..f7e8bbbe3953 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -260,7 +260,7 @@ struct via82xx_modem { | |||
260 | struct snd_info_entry *proc_entry; | 260 | struct snd_info_entry *proc_entry; |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static struct pci_device_id snd_via82xx_modem_ids[] = { | 263 | static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_modem_ids) = { |
264 | { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, }, | 264 | { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, }, |
265 | { 0, } | 265 | { 0, } |
266 | }; | 266 | }; |
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index fc9136c3e0d7..99a9a814be0b 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c | |||
@@ -60,7 +60,7 @@ enum { | |||
60 | VX_PCI_VX222_NEW | 60 | VX_PCI_VX222_NEW |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static struct pci_device_id snd_vx222_ids[] = { | 63 | static DEFINE_PCI_DEVICE_TABLE(snd_vx222_ids) = { |
64 | { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ | 64 | { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ |
65 | { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ | 65 | { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ |
66 | { 0, } | 66 | { 0, } |
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index e6b18b90d451..80c682113381 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address"); | |||
66 | module_param_array(rear_switch, bool, NULL, 0444); | 66 | module_param_array(rear_switch, bool, NULL, 0444); |
67 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); | 67 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); |
68 | 68 | ||
69 | static struct pci_device_id snd_ymfpci_ids[] = { | 69 | static DEFINE_PCI_DEVICE_TABLE(snd_ymfpci_ids) = { |
70 | { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */ | 70 | { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */ |
71 | { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */ | 71 | { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */ |
72 | { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */ | 72 | { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */ |