diff options
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r-- | sound/pci/cmipci.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 1eb3315d136d..316afb78488d 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -446,9 +446,6 @@ struct snd_stru_cmipci { | |||
446 | snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS]; | 446 | snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS]; |
447 | int mixer_res_status[CM_SAVED_MIXERS]; | 447 | int mixer_res_status[CM_SAVED_MIXERS]; |
448 | 448 | ||
449 | opl3_t *opl3; | ||
450 | snd_hwdep_t *opl3hwdep; | ||
451 | |||
452 | cmipci_pcm_t channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */ | 449 | cmipci_pcm_t channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */ |
453 | 450 | ||
454 | /* external MIDI */ | 451 | /* external MIDI */ |
@@ -2753,6 +2750,51 @@ static int snd_cmipci_dev_free(snd_device_t *device) | |||
2753 | return snd_cmipci_free(cm); | 2750 | return snd_cmipci_free(cm); |
2754 | } | 2751 | } |
2755 | 2752 | ||
2753 | static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port) | ||
2754 | { | ||
2755 | long iosynth; | ||
2756 | unsigned int val; | ||
2757 | opl3_t *opl3; | ||
2758 | int err; | ||
2759 | |||
2760 | /* first try FM regs in PCI port range */ | ||
2761 | iosynth = cm->iobase + CM_REG_FM_PCI; | ||
2762 | err = snd_opl3_create(cm->card, iosynth, iosynth + 2, | ||
2763 | OPL3_HW_OPL3, 1, &opl3); | ||
2764 | if (err < 0) { | ||
2765 | /* then try legacy ports */ | ||
2766 | val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK; | ||
2767 | iosynth = fm_port; | ||
2768 | switch (iosynth) { | ||
2769 | case 0x3E8: val |= CM_FMSEL_3E8; break; | ||
2770 | case 0x3E0: val |= CM_FMSEL_3E0; break; | ||
2771 | case 0x3C8: val |= CM_FMSEL_3C8; break; | ||
2772 | case 0x388: val |= CM_FMSEL_388; break; | ||
2773 | default: | ||
2774 | return 0; | ||
2775 | } | ||
2776 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val); | ||
2777 | /* enable FM */ | ||
2778 | snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); | ||
2779 | |||
2780 | if (snd_opl3_create(cm->card, iosynth, iosynth + 2, | ||
2781 | OPL3_HW_OPL3, 0, &opl3) < 0) { | ||
2782 | printk(KERN_ERR "cmipci: no OPL device at %#lx, " | ||
2783 | "skipping...\n", iosynth); | ||
2784 | /* disable FM */ | ||
2785 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, | ||
2786 | val & ~CM_FMSEL_MASK); | ||
2787 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); | ||
2788 | return 0; | ||
2789 | } | ||
2790 | } | ||
2791 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { | ||
2792 | printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n"); | ||
2793 | return err; | ||
2794 | } | ||
2795 | return 0; | ||
2796 | } | ||
2797 | |||
2756 | static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, | 2798 | static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, |
2757 | int dev, cmipci_t **rcmipci) | 2799 | int dev, cmipci_t **rcmipci) |
2758 | { | 2800 | { |
@@ -2762,8 +2804,8 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, | |||
2762 | .dev_free = snd_cmipci_dev_free, | 2804 | .dev_free = snd_cmipci_dev_free, |
2763 | }; | 2805 | }; |
2764 | unsigned int val = 0; | 2806 | unsigned int val = 0; |
2765 | long iomidi = mpu_port[dev]; | 2807 | long iomidi; |
2766 | long iosynth = fm_port[dev]; | 2808 | int integrated_midi; |
2767 | int pcm_index, pcm_spdif_index; | 2809 | int pcm_index, pcm_spdif_index; |
2768 | static struct pci_device_id intel_82437vx[] = { | 2810 | static struct pci_device_id intel_82437vx[] = { |
2769 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, | 2811 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, |
@@ -2867,52 +2909,28 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, | |||
2867 | return err; | 2909 | return err; |
2868 | } | 2910 | } |
2869 | 2911 | ||
2870 | /* set MPU address */ | 2912 | integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff; |
2871 | switch (iomidi) { | 2913 | if (integrated_midi) |
2872 | case 0x320: val = CM_VMPU_320; break; | 2914 | iomidi = cm->iobase + CM_REG_MPU_PCI; |
2873 | case 0x310: val = CM_VMPU_310; break; | 2915 | else { |
2874 | case 0x300: val = CM_VMPU_300; break; | 2916 | iomidi = mpu_port[dev]; |
2875 | case 0x330: val = CM_VMPU_330; break; | 2917 | switch (iomidi) { |
2876 | default: | 2918 | case 0x320: val = CM_VMPU_320; break; |
2877 | iomidi = 0; break; | 2919 | case 0x310: val = CM_VMPU_310; break; |
2878 | } | 2920 | case 0x300: val = CM_VMPU_300; break; |
2879 | if (iomidi > 0) { | 2921 | case 0x330: val = CM_VMPU_330; break; |
2880 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val); | 2922 | default: |
2881 | /* enable UART */ | 2923 | iomidi = 0; break; |
2882 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN); | 2924 | } |
2883 | } | 2925 | if (iomidi > 0) { |
2884 | 2926 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val); | |
2885 | /* set FM address */ | 2927 | /* enable UART */ |
2886 | val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK; | 2928 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN); |
2887 | switch (iosynth) { | ||
2888 | case 0x3E8: val |= CM_FMSEL_3E8; break; | ||
2889 | case 0x3E0: val |= CM_FMSEL_3E0; break; | ||
2890 | case 0x3C8: val |= CM_FMSEL_3C8; break; | ||
2891 | case 0x388: val |= CM_FMSEL_388; break; | ||
2892 | default: | ||
2893 | iosynth = 0; break; | ||
2894 | } | ||
2895 | if (iosynth > 0) { | ||
2896 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val); | ||
2897 | /* enable FM */ | ||
2898 | snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); | ||
2899 | |||
2900 | if (snd_opl3_create(card, iosynth, iosynth + 2, | ||
2901 | OPL3_HW_OPL3, 0, &cm->opl3) < 0) { | ||
2902 | printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth); | ||
2903 | iosynth = 0; | ||
2904 | } else { | ||
2905 | if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) { | ||
2906 | printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n"); | ||
2907 | return err; | ||
2908 | } | ||
2909 | } | 2929 | } |
2910 | } | 2930 | } |
2911 | if (! iosynth) { | 2931 | |
2912 | /* disable FM */ | 2932 | if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0) |
2913 | snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK); | 2933 | return err; |
2914 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); | ||
2915 | } | ||
2916 | 2934 | ||
2917 | /* reset mixer */ | 2935 | /* reset mixer */ |
2918 | snd_cmipci_mixer_write(cm, 0, 0); | 2936 | snd_cmipci_mixer_write(cm, 0, 0); |
@@ -2941,7 +2959,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, | |||
2941 | 2959 | ||
2942 | if (iomidi > 0) { | 2960 | if (iomidi > 0) { |
2943 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, | 2961 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, |
2944 | iomidi, 0, | 2962 | iomidi, integrated_midi, |
2945 | cm->irq, 0, &cm->rmidi)) < 0) { | 2963 | cm->irq, 0, &cm->rmidi)) < 0) { |
2946 | printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); | 2964 | printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); |
2947 | } | 2965 | } |