aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2008-03-19 03:19:41 -0400
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:28 -0400
commitf009ad9b39e6484d8e36e9e5029c07eab8c12e8f (patch)
tree79b4bc6bb9c9b9cbf5a410fc8e83120b46bdb310 /sound/pci/oxygen
parentfa5d8106cb52e5df28673f59cc25af520dc83382 (diff)
[ALSA] oxygen: change model-specific PCM device configuration
When specifying which PCM devices to use, model drivers now use flags that also specify the routing between PCM devices and DMA channels instead of just DMA channel bits. This simplifies some code that checks for these flags. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/hifier.c6
-rw-r--r--sound/pci/oxygen/oxygen.c22
-rw-r--r--sound/pci/oxygen/oxygen.h12
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c202
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c78
-rw-r--r--sound/pci/oxygen/virtuoso.c8
6 files changed, 176 insertions, 152 deletions
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 666f69a3312e..fa489ed3ed46 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -160,10 +160,10 @@ static const struct oxygen_model model_hifier = {
160 .update_dac_volume = update_ak4396_volume, 160 .update_dac_volume = update_ak4396_volume,
161 .update_dac_mute = update_ak4396_mute, 161 .update_dac_mute = update_ak4396_mute,
162 .model_data_size = sizeof(struct hifier_data), 162 .model_data_size = sizeof(struct hifier_data),
163 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
164 PLAYBACK_1_TO_SPDIF |
165 CAPTURE_0_FROM_I2S_1,
163 .dac_channels = 2, 166 .dac_channels = 2,
164 .used_channels = OXYGEN_CHANNEL_A |
165 OXYGEN_CHANNEL_SPDIF |
166 OXYGEN_CHANNEL_MULTICH,
167 .function_flags = 0, 167 .function_flags = 0,
168 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 168 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
169 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 169 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 542752442a95..9faf43c949b2 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -303,12 +303,13 @@ static const struct oxygen_model model_generic = {
303 .update_dac_mute = update_ak4396_mute, 303 .update_dac_mute = update_ak4396_mute,
304 .ac97_switch_hook = cmi9780_switch_hook, 304 .ac97_switch_hook = cmi9780_switch_hook,
305 .model_data_size = sizeof(struct generic_data), 305 .model_data_size = sizeof(struct generic_data),
306 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
307 PLAYBACK_1_TO_SPDIF |
308 PLAYBACK_2_TO_AC97_1 |
309 CAPTURE_0_FROM_I2S_1 |
310 CAPTURE_1_FROM_SPDIF |
311 CAPTURE_2_FROM_AC97_1,
306 .dac_channels = 8, 312 .dac_channels = 8,
307 .used_channels = OXYGEN_CHANNEL_A |
308 OXYGEN_CHANNEL_C |
309 OXYGEN_CHANNEL_SPDIF |
310 OXYGEN_CHANNEL_MULTICH |
311 OXYGEN_CHANNEL_AC97,
312 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, 313 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
313 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 314 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
314 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 315 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -327,12 +328,13 @@ static const struct oxygen_model model_meridian = {
327 .update_dac_mute = update_ak4396_mute, 328 .update_dac_mute = update_ak4396_mute,
328 .ac97_switch_hook = cmi9780_switch_hook, 329 .ac97_switch_hook = cmi9780_switch_hook,
329 .model_data_size = sizeof(struct generic_data), 330 .model_data_size = sizeof(struct generic_data),
331 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
332 PLAYBACK_1_TO_SPDIF |
333 PLAYBACK_2_TO_AC97_1 |
334 CAPTURE_0_FROM_I2S_2 |
335 CAPTURE_1_FROM_SPDIF |
336 CAPTURE_2_FROM_AC97_1,
330 .dac_channels = 8, 337 .dac_channels = 8,
331 .used_channels = OXYGEN_CHANNEL_B |
332 OXYGEN_CHANNEL_C |
333 OXYGEN_CHANNEL_SPDIF |
334 OXYGEN_CHANNEL_MULTICH |
335 OXYGEN_CHANNEL_AC97,
336 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, 338 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
337 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 339 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
338 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 340 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index ad50fb8b206b..fde995cf2edf 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,6 +16,16 @@
16#define PCM_AC97 5 16#define PCM_AC97 5
17#define PCM_COUNT 6 17#define PCM_COUNT 6
18 18
19/* model-specific configuration of outputs/inputs */
20#define PLAYBACK_0_TO_I2S 0x001
21#define PLAYBACK_1_TO_SPDIF 0x004
22#define PLAYBACK_2_TO_AC97_1 0x008
23#define CAPTURE_0_FROM_I2S_1 0x010
24#define CAPTURE_0_FROM_I2S_2 0x020
25#define CAPTURE_1_FROM_SPDIF 0x080
26#define CAPTURE_2_FROM_I2S_2 0x100
27#define CAPTURE_2_FROM_AC97_1 0x200
28
19enum { 29enum {
20 CONTROL_SPDIF_PCM, 30 CONTROL_SPDIF_PCM,
21 CONTROL_SPDIF_INPUT_BITS, 31 CONTROL_SPDIF_INPUT_BITS,
@@ -91,8 +101,8 @@ struct oxygen_model {
91 unsigned int reg, int mute); 101 unsigned int reg, int mute);
92 void (*gpio_changed)(struct oxygen *chip); 102 void (*gpio_changed)(struct oxygen *chip);
93 size_t model_data_size; 103 size_t model_data_size;
104 unsigned int pcm_dev_cfg;
94 u8 dac_channels; 105 u8 dac_channels;
95 u8 used_channels;
96 u8 function_flags; 106 u8 function_flags;
97 u16 dac_i2s_format; 107 u16 dac_i2s_format;
98 u16 adc_i2s_format; 108 u16 adc_i2s_format;
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 4e77b79b3b6e..6b5ff6e0fadd 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -737,90 +737,111 @@ static const struct snd_kcontrol_new controls[] = {
737 }, 737 },
738}; 738};
739 739
740static const struct snd_kcontrol_new monitor_a_controls[] = { 740static const struct {
741 unsigned int pcm_dev;
742 struct snd_kcontrol_new controls[2];
743} monitor_controls[] = {
741 { 744 {
742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 745 .pcm_dev = CAPTURE_0_FROM_I2S_1,
743 .name = "Analog Input Monitor Switch", 746 .controls = {
744 .info = snd_ctl_boolean_mono_info, 747 {
745 .get = monitor_get, 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
746 .put = monitor_put, 749 .name = "Analog Input Monitor Switch",
747 .private_value = OXYGEN_ADC_MONITOR_A, 750 .info = snd_ctl_boolean_mono_info,
751 .get = monitor_get,
752 .put = monitor_put,
753 .private_value = OXYGEN_ADC_MONITOR_A,
754 },
755 {
756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
757 .name = "Analog Input Monitor Volume",
758 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
759 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
760 .info = monitor_volume_info,
761 .get = monitor_get,
762 .put = monitor_put,
763 .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
764 | (1 << 8),
765 .tlv = { .p = monitor_db_scale, },
766 },
767 },
748 }, 768 },
749 { 769 {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 770 .pcm_dev = CAPTURE_0_FROM_I2S_2,
751 .name = "Analog Input Monitor Volume", 771 .controls = {
752 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 772 {
753 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
754 .info = monitor_volume_info, 774 .name = "Analog Input Monitor Switch",
755 .get = monitor_get, 775 .info = snd_ctl_boolean_mono_info,
756 .put = monitor_put, 776 .get = monitor_get,
757 .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL | (1 << 8), 777 .put = monitor_put,
758 .tlv = { .p = monitor_db_scale, }, 778 .private_value = OXYGEN_ADC_MONITOR_B,
779 },
780 {
781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
782 .name = "Analog Input Monitor Volume",
783 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
784 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
785 .info = monitor_volume_info,
786 .get = monitor_get,
787 .put = monitor_put,
788 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
789 | (1 << 8),
790 .tlv = { .p = monitor_db_scale, },
791 },
792 },
759 }, 793 },
760};
761static const struct snd_kcontrol_new monitor_b_controls[] = {
762 { 794 {
763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 795 .pcm_dev = CAPTURE_2_FROM_I2S_2,
764 .name = "Analog Input Monitor Switch", 796 .controls = {
765 .info = snd_ctl_boolean_mono_info, 797 {
766 .get = monitor_get, 798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
767 .put = monitor_put, 799 .name = "Analog Input Monitor Switch",
768 .private_value = OXYGEN_ADC_MONITOR_B, 800 .index = 1,
801 .info = snd_ctl_boolean_mono_info,
802 .get = monitor_get,
803 .put = monitor_put,
804 .private_value = OXYGEN_ADC_MONITOR_B,
805 },
806 {
807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
808 .name = "Analog Input Monitor Volume",
809 .index = 1,
810 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
811 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
812 .info = monitor_volume_info,
813 .get = monitor_get,
814 .put = monitor_put,
815 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
816 | (1 << 8),
817 .tlv = { .p = monitor_db_scale, },
818 },
819 },
769 }, 820 },
770 { 821 {
771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 822 .pcm_dev = CAPTURE_1_FROM_SPDIF,
772 .name = "Analog Input Monitor Volume", 823 .controls = {
773 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 824 {
774 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
775 .info = monitor_volume_info, 826 .name = "Digital Input Monitor Switch",
776 .get = monitor_get, 827 .info = snd_ctl_boolean_mono_info,
777 .put = monitor_put, 828 .get = monitor_get,
778 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL | (1 << 8), 829 .put = monitor_put,
779 .tlv = { .p = monitor_db_scale, }, 830 .private_value = OXYGEN_ADC_MONITOR_C,
780 }, 831 },
781}; 832 {
782static const struct snd_kcontrol_new monitor_2nd_b_controls[] = { 833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
783 { 834 .name = "Digital Input Monitor Volume",
784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
785 .name = "Analog Input Monitor Switch", 836 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
786 .index = 1, 837 .info = monitor_volume_info,
787 .info = snd_ctl_boolean_mono_info, 838 .get = monitor_get,
788 .get = monitor_get, 839 .put = monitor_put,
789 .put = monitor_put, 840 .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
790 .private_value = OXYGEN_ADC_MONITOR_B, 841 | (1 << 8),
791 }, 842 .tlv = { .p = monitor_db_scale, },
792 { 843 },
793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 844 },
794 .name = "Analog Input Monitor Volume",
795 .index = 1,
796 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
797 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
798 .info = monitor_volume_info,
799 .get = monitor_get,
800 .put = monitor_put,
801 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL | (1 << 8),
802 .tlv = { .p = monitor_db_scale, },
803 },
804};
805static const struct snd_kcontrol_new monitor_c_controls[] = {
806 {
807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
808 .name = "Digital Input Monitor Switch",
809 .info = snd_ctl_boolean_mono_info,
810 .get = monitor_get,
811 .put = monitor_put,
812 .private_value = OXYGEN_ADC_MONITOR_C,
813 },
814 {
815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
816 .name = "Digital Input Monitor Volume",
817 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
818 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
819 .info = monitor_volume_info,
820 .get = monitor_get,
821 .put = monitor_put,
822 .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL | (1 << 8),
823 .tlv = { .p = monitor_db_scale, },
824 }, 845 },
825}; 846};
826 847
@@ -905,32 +926,17 @@ static int add_controls(struct oxygen *chip,
905 926
906int oxygen_mixer_init(struct oxygen *chip) 927int oxygen_mixer_init(struct oxygen *chip)
907{ 928{
929 unsigned int i;
908 int err; 930 int err;
909 931
910 err = add_controls(chip, controls, ARRAY_SIZE(controls)); 932 err = add_controls(chip, controls, ARRAY_SIZE(controls));
911 if (err < 0) 933 if (err < 0)
912 return err; 934 return err;
913 if (chip->model->used_channels & OXYGEN_CHANNEL_A) { 935 for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
914 err = add_controls(chip, monitor_a_controls, 936 if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev))
915 ARRAY_SIZE(monitor_a_controls)); 937 continue;
916 if (err < 0) 938 err = add_controls(chip, monitor_controls[i].controls,
917 return err; 939 ARRAY_SIZE(monitor_controls[i].controls));
918 } else if (chip->model->used_channels & OXYGEN_CHANNEL_B) {
919 err = add_controls(chip, monitor_b_controls,
920 ARRAY_SIZE(monitor_b_controls));
921 if (err < 0)
922 return err;
923 }
924 if ((chip->model->used_channels & (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B))
925 == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B)) {
926 err = add_controls(chip, monitor_2nd_b_controls,
927 ARRAY_SIZE(monitor_2nd_b_controls));
928 if (err < 0)
929 return err;
930 }
931 if (chip->model->used_channels & OXYGEN_CHANNEL_C) {
932 err = add_controls(chip, monitor_c_controls,
933 ARRAY_SIZE(monitor_c_controls));
934 if (err < 0) 940 if (err < 0)
935 return err; 941 return err;
936 } 942 }
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index b70046aca657..b17c405e069d 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -119,7 +119,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
119 119
120 runtime->private_data = (void *)(uintptr_t)channel; 120 runtime->private_data = (void *)(uintptr_t)channel;
121 if (channel == PCM_B && chip->has_ac97_1 && 121 if (channel == PCM_B && chip->has_ac97_1 &&
122 (chip->model->used_channels & OXYGEN_CHANNEL_AC97)) 122 (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1))
123 runtime->hw = oxygen_ac97_hardware; 123 runtime->hw = oxygen_ac97_hardware;
124 else 124 else
125 runtime->hw = *oxygen_hardware[channel]; 125 runtime->hw = *oxygen_hardware[channel];
@@ -365,7 +365,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
365 return err; 365 return err;
366 366
367 is_ac97 = chip->has_ac97_1 && 367 is_ac97 = chip->has_ac97_1 &&
368 (chip->model->used_channels & OXYGEN_CHANNEL_AC97); 368 (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
369 369
370 spin_lock_irq(&chip->reg_lock); 370 spin_lock_irq(&chip->reg_lock);
371 oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, 371 oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
@@ -640,34 +640,39 @@ int oxygen_pcm_init(struct oxygen *chip)
640 int outs, ins; 640 int outs, ins;
641 int err; 641 int err;
642 642
643 outs = 1; /* OXYGEN_CHANNEL_MULTICH is always used */ 643 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_0_TO_I2S);
644 ins = !!(chip->model->used_channels & (OXYGEN_CHANNEL_A | 644 ins = !!(chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 |
645 OXYGEN_CHANNEL_B)); 645 CAPTURE_0_FROM_I2S_2));
646 err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); 646 if (outs | ins) {
647 if (err < 0) 647 err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm);
648 return err; 648 if (err < 0)
649 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); 649 return err;
650 if (chip->model->used_channels & OXYGEN_CHANNEL_A) 650 if (outs)
651 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 651 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
652 &oxygen_rec_a_ops); 652 &oxygen_multich_ops);
653 else if (chip->model->used_channels & OXYGEN_CHANNEL_B) 653 if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1)
654 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 654 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
655 &oxygen_rec_b_ops); 655 &oxygen_rec_a_ops);
656 pcm->private_data = chip; 656 else if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_2)
657 pcm->private_free = oxygen_pcm_free; 657 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
658 strcpy(pcm->name, "Analog"); 658 &oxygen_rec_b_ops);
659 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, 659 pcm->private_data = chip;
660 SNDRV_DMA_TYPE_DEV, 660 pcm->private_free = oxygen_pcm_free;
661 snd_dma_pci_data(chip->pci), 661 strcpy(pcm->name, "Analog");
662 512 * 1024, 2048 * 1024); 662 if (outs)
663 if (ins) 663 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
664 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 664 SNDRV_DMA_TYPE_DEV,
665 SNDRV_DMA_TYPE_DEV, 665 snd_dma_pci_data(chip->pci),
666 snd_dma_pci_data(chip->pci), 666 512 * 1024, 2048 * 1024);
667 128 * 1024, 256 * 1024); 667 if (ins)
668 668 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
669 outs = !!(chip->model->used_channels & OXYGEN_CHANNEL_SPDIF); 669 SNDRV_DMA_TYPE_DEV,
670 ins = !!(chip->model->used_channels & OXYGEN_CHANNEL_C); 670 snd_dma_pci_data(chip->pci),
671 128 * 1024, 256 * 1024);
672 }
673
674 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF);
675 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF);
671 if (outs | ins) { 676 if (outs | ins) {
672 err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); 677 err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
673 if (err < 0) 678 if (err < 0)
@@ -686,12 +691,13 @@ int oxygen_pcm_init(struct oxygen *chip)
686 128 * 1024, 256 * 1024); 691 128 * 1024, 256 * 1024);
687 } 692 }
688 693
689 outs = chip->has_ac97_1 && 694 if (chip->has_ac97_1) {
690 (chip->model->used_channels & OXYGEN_CHANNEL_AC97); 695 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_2_TO_AC97_1);
691 ins = outs || 696 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
692 (chip->model->used_channels & (OXYGEN_CHANNEL_A | 697 } else {
693 OXYGEN_CHANNEL_B)) 698 outs = 0;
694 == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B); 699 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_I2S_2);
700 }
695 if (outs | ins) { 701 if (outs | ins) {
696 err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", 702 err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
697 2, outs, ins, &pcm); 703 2, outs, ins, &pcm);
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 127dd664fc16..5cd1fac14132 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -348,11 +348,11 @@ static const struct oxygen_model model_xonar = {
348 .ac97_switch_hook = xonar_ac97_switch_hook, 348 .ac97_switch_hook = xonar_ac97_switch_hook,
349 .gpio_changed = xonar_gpio_changed, 349 .gpio_changed = xonar_gpio_changed,
350 .model_data_size = sizeof(struct xonar_data), 350 .model_data_size = sizeof(struct xonar_data),
351 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
352 PLAYBACK_1_TO_SPDIF |
353 CAPTURE_0_FROM_I2S_2 |
354 CAPTURE_1_FROM_SPDIF,
351 .dac_channels = 8, 355 .dac_channels = 8,
352 .used_channels = OXYGEN_CHANNEL_B |
353 OXYGEN_CHANNEL_C |
354 OXYGEN_CHANNEL_SPDIF |
355 OXYGEN_CHANNEL_MULTICH,
356 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, 356 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
357 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 357 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
358 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 358 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,