ALSA: asihpi - Minor code cleanup
[safe/jmp/linux-2.6] / sound / pci / cmipci.c
index 3a2d942..329968e 100644 (file)
@@ -20,7 +20,6 @@
 /* Does not work. Warning may block system in capture mode */
 /* #define USE_VAR48KRATE */
 
-#include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -869,6 +868,13 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
        snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
        //snd_printd("cmipci: chformat = %08x\n", val);
 
+       if (!rec->is_dac && cm->chip_version) {
+               if (runtime->rate > 44100)
+                       snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K);
+               else
+                       snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K);
+       }
+
        rec->running = 0;
        spin_unlock_irq(&cm->reg_lock);
 
@@ -935,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
                                                struct snd_pcm_substream *substream)
 {
        size_t ptr;
-       unsigned int reg;
+       unsigned int reg, rem, tries;
+
        if (!rec->running)
                return 0;
 #if 1 // this seems better..
        reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
-       ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1);
-       ptr >>= rec->shift;
+       for (tries = 0; tries < 3; tries++) {
+               rem = snd_cmipci_read_w(cm, reg);
+               if (rem < rec->dma_size)
+                       goto ok;
+       } 
+       printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
+       return SNDRV_PCM_POS_XRUN;
+ok:
+       ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
 #else
        reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
        ptr = snd_cmipci_read(cm, reg) - rec->offset;
@@ -1400,6 +1414,11 @@ static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream)
                else
                        snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
        }
+       if (snd_pcm_format_width(substream->runtime->format) > 16)
+               snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
+       else
+               snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
+
        spin_unlock_irq(&cm->reg_lock);
 
        return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
@@ -1411,6 +1430,7 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
 
        spin_lock_irq(&cm->reg_lock);
        snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
+       snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
        spin_unlock_irq(&cm->reg_lock);
 
        return snd_cmipci_hw_free(subs);
@@ -1562,7 +1582,8 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif =
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
                                 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
-       .formats =              SNDRV_PCM_FMTBIT_S16_LE,
+       .formats =              SNDRV_PCM_FMTBIT_S16_LE |
+                               SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
        .rates =                SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
        .rate_min =             44100,
        .rate_max =             48000,
@@ -2289,7 +2310,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
        CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
        CMIPCI_SB_SW_MONO("Mic Playback Switch", 0),
        CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0),
-       CMIPCI_SB_VOL_MONO("PC Speaker Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
+       CMIPCI_SB_VOL_MONO("Beep Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
        CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
        CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
        CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
@@ -2297,7 +2318,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
        CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
        CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
        CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
-       CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
+       CMIPCI_DOUBLE("Beep Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
        CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
 };
 
@@ -2344,7 +2365,8 @@ static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
 {
        struct cmipci_switch_args *args;
        args = (struct cmipci_switch_args *)kcontrol->private_value;
-       snd_assert(args != NULL, return -EINVAL);
+       if (snd_BUG_ON(!args))
+               return -EINVAL;
        return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
 }
 
@@ -2388,7 +2410,8 @@ static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
 {
        struct cmipci_switch_args *args;
        args = (struct cmipci_switch_args *)kcontrol->private_value;
-       snd_assert(args != NULL, return -EINVAL);
+       if (snd_BUG_ON(!args))
+               return -EINVAL;
        return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
 }
 
@@ -2637,10 +2660,8 @@ static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata =
 };
 
 /* card control switches */
-static struct snd_kcontrol_new snd_cmipci_control_switches[] __devinitdata = {
-       // DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */
-       DEFINE_CARD_SWITCH("Modem", modem),
-};
+static struct snd_kcontrol_new snd_cmipci_modem_switch __devinitdata =
+DEFINE_CARD_SWITCH("Modem", modem);
 
 
 static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
@@ -2651,7 +2672,8 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic
        unsigned int idx;
        int err;
 
-       snd_assert(cm != NULL && cm->card != NULL, return -EINVAL);
+       if (snd_BUG_ON(!cm || !cm->card))
+               return -EINVAL;
 
        card = cm->card;
 
@@ -2721,20 +2743,25 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic
        }
 
        /* card switches */
-       sw = snd_cmipci_control_switches;
-       for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_control_switches); idx++, sw++) {
-               err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
+       /*
+        * newer chips don't have the register bits to force modem link
+        * detection; the bit that was FLINKON now mutes CH1
+        */
+       if (cm->chip_version < 39) {
+               err = snd_ctl_add(cm->card,
+                                 snd_ctl_new1(&snd_cmipci_modem_switch, cm));
                if (err < 0)
                        return err;
        }
 
        for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
-               struct snd_ctl_elem_id id;
+               struct snd_ctl_elem_id elem_id;
                struct snd_kcontrol *ctl;
-               memset(&id, 0, sizeof(id));
-               id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-               strcpy(id.name, cm_saved_mixer[idx].name);
-               if ((ctl = snd_ctl_find_id(cm->card, &id)) != NULL)
+               memset(&elem_id, 0, sizeof(elem_id));
+               elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+               strcpy(elem_id.name, cm_saved_mixer[idx].name);
+               ctl = snd_ctl_find_id(cm->card, &elem_id);
+               if (ctl)
                        cm->mixer_res_ctl[idx] = ctl;
        }
 
@@ -2777,12 +2804,12 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
 #endif
 
 
-static struct pci_device_id snd_cmipci_ids[] = {
-       {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_AL, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = {
+       {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0},
+       {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0},
+       {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
+       {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B), 0},
+       {PCI_VDEVICE(AL, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
        {0,},
 };
 
@@ -2917,8 +2944,6 @@ static int snd_cmipci_free(struct cmipci *cm)
                /* reset mixer */
                snd_cmipci_mixer_write(cm, 0, 0);
 
-               synchronize_irq(cm->irq);
-
                free_irq(cm->irq, cm);
        }
 
@@ -2997,11 +3022,11 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
                .dev_free =     snd_cmipci_dev_free,
        };
        unsigned int val;
-       long iomidi;
+       long iomidi = 0;
        int integrated_midi = 0;
        char modelstr[16];
        int pcm_index, pcm_spdif_index;
-       static struct pci_device_id intel_82437vx[] = {
+       static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = {
                { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
                { },
        };
@@ -3255,9 +3280,9 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci,
                return -ENOENT;
        }
 
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
+       err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+       if (err < 0)
+               return err;
        
        switch (pci->device) {
        case PCI_DEVICE_ID_CMEDIA_CM8738: