Merge branch 'topic/vmaster-update' into topic/docbook-fix
authorTakashi Iwai <tiwai@suse.de>
Mon, 9 Mar 2009 14:21:57 +0000 (15:21 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 9 Mar 2009 14:21:57 +0000 (15:21 +0100)
14 files changed:
1  2 
Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
drivers/media/video/em28xx/em28xx-audio.c
drivers/media/video/saa7134/saa7134-alsa.c
include/linux/input.h
sound/arm/aaci.c
sound/core/jack.c
sound/drivers/mtpav.c
sound/pci/aw2/aw2-alsa.c
sound/pci/hda/hda_intel.c
sound/pci/intel8x0.c
sound/ppc/snd_ps3.c
sound/soc/soc-core.c
sound/usb/caiaq/caiaq-device.c
sound/usb/usbaudio.c

index 37b006cdf2f975823212f8ca14f4e55b8052e5f4,115962827c816f638d2af10adbe20d50c8f1accc..90f163c4bde9a038afb40bbf2d77b8bd60f7e392
  !Esound/pci/ac97/ac97_codec.c
  !Esound/pci/ac97/ac97_pcm.c
       </sect1>
+      <sect1><title>Virtual Master Control API</title>
+ !Esound/core/vmaster.c
+ !Iinclude/sound/control.h
+      </sect1>
    </chapter>
    <chapter><title>MIDI API</title>
       <sect1><title>Raw MIDI API</title>
@@@ -88,9 -92,6 +92,9 @@@
    <chapter><title>Miscellaneous Functions</title>
       <sect1><title>Hardware-Dependent Devices API</title>
  !Esound/core/hwdep.c
 +     </sect1>
 +     <sect1><title>Jack Abstraction Layer API</title>
 +!Esound/core/jack.c
       </sect1>
       <sect1><title>ISA DMA Helpers</title>
  !Esound/core/isadma.c
index 66579508e17569e92dd68de337dff1fd4b38f741,2ac738fa6a07e0cd66fac559fd3c9688060dff39..f132e31f6edd8c4bcd7e7262739255437195ec5e
@@@ -62,9 -62,15 +62,15 @@@ static int em28xx_isoc_audio_deinit(str
  
        dprintk("Stopping isoc\n");
        for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
-               usb_unlink_urb(dev->adev.urb[i]);
+               if (!irqs_disabled())
+                       usb_kill_urb(dev->adev.urb[i]);
+               else
+                       usb_unlink_urb(dev->adev.urb[i]);
                usb_free_urb(dev->adev.urb[i]);
                dev->adev.urb[i] = NULL;
+               kfree(dev->adev.transfer_buffer[i]);
+               dev->adev.transfer_buffer[i] = NULL;
        }
  
        return 0;
@@@ -389,11 -395,15 +395,15 @@@ static int snd_em28xx_capture_trigger(s
  static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
                                                    *substream)
  {
-       struct em28xx *dev;
+        unsigned long flags;
  
+       struct em28xx *dev;
        snd_pcm_uframes_t hwptr_done;
        dev = snd_pcm_substream_chip(substream);
+        spin_lock_irqsave(&dev->adev.slock, flags);
        hwptr_done = dev->adev.hwptr_done_capture;
+        spin_unlock_irqrestore(&dev->adev.slock, flags);
  
        return hwptr_done;
  }
@@@ -438,10 -448,9 +448,10 @@@ static int em28xx_audio_init(struct em2
        printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
                         "Rechberger\n");
  
 -      card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
 -      if (card == NULL)
 -              return -ENOMEM;
 +      err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
 +                            &card);
 +      if (err < 0)
 +              return err;
  
        spin_lock_init(&adev->slock);
        err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
        pcm->info_flags = 0;
        pcm->private_data = dev;
        strcpy(pcm->name, "Empia 28xx Capture");
+       snd_card_set_dev(card, &dev->udev->dev);
        strcpy(card->driver, "Empia Em28xx Audio");
        strcpy(card->shortname, "Em28xx Audio");
        strcpy(card->longname, "Empia Em28xx Audio");
index 482be1436e9262cb0511da8a3d07bb5232147d0d,c750d3dd57d20c2f8a858c342ada09b21fd1b1c1..8b0b64a89874dcbaa1e591c72af22074477a8c88
@@@ -990,10 -990,10 +990,10 @@@ static int alsa_card_saa7134_create(str
        if (!enable[devnum])
                return -ENODEV;
  
 -      card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
 -
 -      if (card == NULL)
 -              return -ENOMEM;
 +      err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
 +                            sizeof(snd_card_saa7134_t), &card);
 +      if (err < 0)
 +              return err;
  
        strcpy(card->driver, "SAA7134");
  
@@@ -1089,7 -1089,11 +1089,11 @@@ static int saa7134_alsa_init(void
  
        list_for_each(list,&saa7134_devlist) {
                dev = list_entry(list, struct saa7134_dev, devlist);
-               alsa_device_init(dev);
+               if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+                       printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+                               dev->name, saa7134_boards[dev->board].name);
+               else
+                       alsa_device_init(dev);
        }
  
        if (dev == NULL)
diff --combined include/linux/input.h
index adc13322d1d2a352b1e7a139f873e2b1e5ca78a1,1249a0c20a38258f7cf3064ece21f6e54dcbf254..6b28048fc56820152a1f95074b2721e285bab762
@@@ -16,7 -16,7 +16,7 @@@
  #include <sys/time.h>
  #include <sys/ioctl.h>
  #include <sys/types.h>
- #include <asm/types.h>
+ #include <linux/types.h>
  #endif
  
  /*
@@@ -661,7 -661,6 +661,7 @@@ struct input_absinfo 
  #define SW_DOCK                       0x05  /* set = plugged into dock */
  #define SW_LINEOUT_INSERT     0x06  /* set = inserted */
  #define SW_JACK_PHYSICAL_INSERT 0x07  /* set = mechanical switch set */
 +#define SW_VIDEOOUT_INSERT    0x08  /* set = inserted */
  #define SW_MAX                        0x0f
  #define SW_CNT                        (SW_MAX+1)
  
diff --combined sound/arm/aaci.c
index 7d39aac9ec14eafc88681773a2a2b86f69acf2e4,772901e41ecb5fe86d83633e0e2137847233a745..7fbd68fab944e08ecba5bd4424331007198705e2
@@@ -90,7 -90,7 +90,7 @@@ static void aaci_ac97_write(struct snd_
         */
        do {
                v = readl(aaci->base + AACI_SLFR);
-       } while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--);
+       } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
  
        if (!timeout)
                dev_err(&aaci->dev->dev,
@@@ -126,7 -126,7 +126,7 @@@ static unsigned short aaci_ac97_read(st
         */
        do {
                v = readl(aaci->base + AACI_SLFR);
-       } while ((v & SLFR_1TXB) && timeout--);
+       } while ((v & SLFR_1TXB) && --timeout);
  
        if (!timeout) {
                dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
        do {
                cond_resched();
                v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
-       } while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--);
+       } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
  
        if (!timeout) {
                dev_err(&aaci->dev->dev, "timeout on RX valid\n");
@@@ -995,11 -995,10 +995,11 @@@ static struct aaci * __devinit aaci_ini
  {
        struct aaci *aaci;
        struct snd_card *card;
 +      int err;
  
 -      card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 -                          THIS_MODULE, sizeof(struct aaci));
 -      if (card == NULL)
 +      err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 +                            THIS_MODULE, sizeof(struct aaci), &card);
 +      if (err < 0)
                return NULL;
  
        card->private_free = aaci_free_card;
diff --combined sound/core/jack.c
index 43b10d6e522bc0e7b2c62bee63f0a5d94faa2250,077a85262c1c2592c8323b6f249fc645aaf5ecc7..c8254c667c6247cef5e402161b0b1ef076782a5e
  #include <sound/jack.h>
  #include <sound/core.h>
  
 +static int jack_types[] = {
 +      SW_HEADPHONE_INSERT,
 +      SW_MICROPHONE_INSERT,
 +      SW_LINEOUT_INSERT,
 +      SW_JACK_PHYSICAL_INSERT,
 +      SW_VIDEOOUT_INSERT,
 +};
 +
  static int snd_jack_dev_free(struct snd_device *device)
  {
        struct snd_jack *jack = device->device_data;
@@@ -55,7 -47,7 +55,7 @@@ static int snd_jack_dev_register(struc
        int err;
  
        snprintf(jack->name, sizeof(jack->name), "%s %s",
-                card->longname, jack->id);
+                card->shortname, jack->id);
        jack->input_dev->name = jack->name;
  
        /* Default to the sound card device. */
@@@ -87,7 -79,6 +87,7 @@@ int snd_jack_new(struct snd_card *card
  {
        struct snd_jack *jack;
        int err;
 +      int i;
        static struct snd_device_ops ops = {
                .dev_free = snd_jack_dev_free,
                .dev_register = snd_jack_dev_register,
  
        jack->type = type;
  
 -      if (type & SND_JACK_HEADPHONE)
 -              input_set_capability(jack->input_dev, EV_SW,
 -                                   SW_HEADPHONE_INSERT);
 -      if (type & SND_JACK_LINEOUT)
 -              input_set_capability(jack->input_dev, EV_SW,
 -                                   SW_LINEOUT_INSERT);
 -      if (type & SND_JACK_MICROPHONE)
 -              input_set_capability(jack->input_dev, EV_SW,
 -                                   SW_MICROPHONE_INSERT);
 -      if (type & SND_JACK_MECHANICAL)
 -              input_set_capability(jack->input_dev, EV_SW,
 -                                   SW_JACK_PHYSICAL_INSERT);
 +      for (i = 0; i < ARRAY_SIZE(jack_types); i++)
 +              if (type & (1 << i))
 +                      input_set_capability(jack->input_dev, EV_SW,
 +                                           jack_types[i]);
  
        err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
        if (err < 0)
@@@ -155,17 -154,21 +155,17 @@@ EXPORT_SYMBOL(snd_jack_set_parent)
   */
  void snd_jack_report(struct snd_jack *jack, int status)
  {
 +      int i;
 +
        if (!jack)
                return;
  
 -      if (jack->type & SND_JACK_HEADPHONE)
 -              input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
 -                                  status & SND_JACK_HEADPHONE);
 -      if (jack->type & SND_JACK_LINEOUT)
 -              input_report_switch(jack->input_dev, SW_LINEOUT_INSERT,
 -                                  status & SND_JACK_LINEOUT);
 -      if (jack->type & SND_JACK_MICROPHONE)
 -              input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
 -                                  status & SND_JACK_MICROPHONE);
 -      if (jack->type & SND_JACK_MECHANICAL)
 -              input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT,
 -                                  status & SND_JACK_MECHANICAL);
 +      for (i = 0; i < ARRAY_SIZE(jack_types); i++) {
 +              int testbit = 1 << i;
 +              if (jack->type & testbit)
 +                      input_report_switch(jack->input_dev, jack_types[i],
 +                                          status & testbit);
 +      }
  
        input_sync(jack->input_dev);
  }
diff --combined sound/drivers/mtpav.c
index c3e9833dcfd9af1ffc2d8c53e49a6894a9ed1ef3,48b64e6b26701e14ace4015b5df08b7f56408d5a..0e17d2b5ce19bedbee5f6d35fe076949283dd143
@@@ -696,9 -696,9 +696,9 @@@ static int __devinit snd_mtpav_probe(st
        int err;
        struct mtpav *mtp_card;
  
 -      card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card));
 -      if (! card)
 -              return -ENOMEM;
 +      err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card);
 +      if (err < 0)
 +              return err;
  
        mtp_card = card->private_data;
        spin_lock_init(&mtp_card->spinlock);
        mtp_card->card = card;
        mtp_card->irq = -1;
        mtp_card->share_irq = 0;
-       mtp_card->inmidiport = 0xffffffff;
        mtp_card->inmidistate = 0;
        mtp_card->outmidihwport = 0xffffffff;
        init_timer(&mtp_card->timer);
        if (err < 0)
                goto __error;
  
+       mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
        err = snd_mtpav_get_ISA(mtp_card);
        if (err < 0)
                goto __error;
diff --combined sound/pci/aw2/aw2-alsa.c
index eefcbf648ee1d95e4d80dae4c4043f75f2aa8fd7,c7c54e7748e9ac6fdbf09f1d4bb11f7106d1bfc3..8eea29fc42fe8b7d56769ba9d40de84f38fc400f
@@@ -165,7 -165,7 +165,7 @@@ module_param_array(enable, bool, NULL, 
  MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
  
  static struct pci_device_id snd_aw2_ids[] = {
-       {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, PCI_ANY_ID, PCI_ANY_ID,
+       {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0,
         0, 0, 0},
        {0}
  };
@@@ -368,9 -368,9 +368,9 @@@ static int __devinit snd_aw2_probe(stru
        }
  
        /* (2) Create card instance */
 -      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;
  
        /* (3) Create main component */
        err = snd_aw2_create(card, pci, &chip);
index ad5df2ae6f7d6d638611e7cbf8d60af1105e1e60,5e909e0da04b4b64d18ee9979f38cbaaa853e354..6df2c93fc05da30b88e96d67f4802b5da1626fce
@@@ -996,10 -996,11 +996,11 @@@ static irqreturn_t azx_interrupt(int ir
                                spin_unlock(&chip->reg_lock);
                                snd_pcm_period_elapsed(azx_dev->substream);
                                spin_lock(&chip->reg_lock);
-                       } else {
+                       } else if (chip->bus && chip->bus->workq) {
                                /* bogus IRQ, process it later */
                                azx_dev->irq_pending = 1;
-                               schedule_work(&chip->irq_pending_work);
+                               queue_work(chip->bus->workq,
+                                          &chip->irq_pending_work);
                        }
                }
        }
@@@ -1741,7 -1742,6 +1742,6 @@@ static void azx_clear_irq_pending(struc
        for (i = 0; i < chip->num_streams; i++)
                chip->azx_dev[i].irq_pending = 0;
        spin_unlock_irq(&chip->reg_lock);
-       flush_scheduled_work();
  }
  
  static struct snd_pcm_ops azx_pcm_ops = {
@@@ -1947,16 -1947,13 +1947,13 @@@ static int azx_suspend(struct pci_dev *
        return 0;
  }
  
- static int azx_resume_early(struct pci_dev *pci)
- {
-       return pci_restore_state(pci);
- }
  static int azx_resume(struct pci_dev *pci)
  {
        struct snd_card *card = pci_get_drvdata(pci);
        struct azx *chip = card->private_data;
  
+       pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
        if (pci_enable_device(pci) < 0) {
                printk(KERN_ERR "hda-intel: pci_enable_device failed, "
                       "disabling device\n");
@@@ -2098,6 -2095,8 +2095,8 @@@ static struct snd_pci_quirk probe_mask_
        SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
        /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
        SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
+       /* conflict of ALC268 in slot#3 (digital I/O); a temporary fix */
+       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba laptop", 0x03),
        {}
  };
  
@@@ -2335,10 -2334,10 +2334,10 @@@ static int __devinit azx_probe(struct p
                return -ENOENT;
        }
  
 -      card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 -      if (!card) {
 +      err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
 +      if (err < 0) {
                snd_printk(KERN_ERR SFX "Error creating card!\n");
 -              return -ENOMEM;
 +              return err;
        }
  
        err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
@@@ -2468,7 -2467,6 +2467,6 @@@ static struct pci_driver driver = 
        .remove = __devexit_p(azx_remove),
  #ifdef CONFIG_PM
        .suspend = azx_suspend,
-       .resume_early = azx_resume_early,
        .resume = azx_resume,
  #endif
  };
diff --combined sound/pci/intel8x0.c
index 671ff65db0298974494d7ca6e362c7a7559dc57e,e900cdc84849ae7a7e8eb1225c917ebfc8639dd3..608655e9275e5e27e846665dd6dff1f91a010fc1
@@@ -617,7 -617,7 +617,7 @@@ static int snd_intel8x0_ali_codec_semap
        int time = 100;
        if (chip->buggy_semaphore)
                return 0; /* just ignore ... */
-       while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
+       while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
                udelay(1);
        if (! time && ! chip->in_ac97_init)
                snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
@@@ -3058,9 -3058,9 +3058,9 @@@ static int __devinit snd_intel8x0_probe
        int err;
        struct shortname_table *name;
  
 -      card = snd_card_new(index, id, THIS_MODULE, 0);
 -      if (card == NULL)
 -              return -ENOMEM;
 +      err = snd_card_create(index, id, THIS_MODULE, 0, &card);
 +      if (err < 0)
 +              return err;
  
        if (spdif_aclink < 0)
                spdif_aclink = check_default_spdif_aclink(pci);
diff --combined sound/ppc/snd_ps3.c
index ef2c3f417175aaec7b2cd656e43866f28f9289db,ff321110ec029604bd8cd0e4862940fe1e1b88c4..f361c26506aacefd1b5a683c232163294c6f9480
@@@ -477,7 -477,7 +477,7 @@@ static int snd_ps3_pcm_prepare(struct s
                card->dma_start_bus_addr[SND_PS3_CH_R] =
                        runtime->dma_addr + (runtime->dma_bytes / 2);
  
-               pr_debug("%s: vaddr=%p bus=%#lx\n", __func__,
+               pr_debug("%s: vaddr=%p bus=%#llx\n", __func__,
                         card->dma_start_vaddr[SND_PS3_CH_L],
                         card->dma_start_bus_addr[SND_PS3_CH_L]);
  
@@@ -969,9 -969,11 +969,9 @@@ static int __init snd_ps3_driver_probe(
        }
  
        /* create card instance */
 -      the_card.card = snd_card_new(index, id, THIS_MODULE, 0);
 -      if (!the_card.card) {
 -              ret = -ENXIO;
 +      ret = snd_card_create(index, id, THIS_MODULE, 0, &the_card.card);
 +      if (ret < 0)
                goto clean_irq;
 -      }
  
        strcpy(the_card.card->driver, "PS3");
        strcpy(the_card.card->shortname, "PS3");
                pr_info("%s: nullbuffer alloc failed\n", __func__);
                goto clean_preallocate;
        }
-       pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__,
+       pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__,
                 the_card.null_buffer_start_vaddr,
                 the_card.null_buffer_start_dma_addr);
        /* set default sample rate/word width */
diff --combined sound/soc/soc-core.c
index 318dfdd54d7f00065002d1d834e382bd827dea07,ec3f8bb4b51d9805d827279e8b025aeeb12d657a..637f0d1ea98ed46811e960aefe13b866c3683355
@@@ -1311,17 -1311,17 +1311,17 @@@ int snd_soc_new_pcms(struct snd_soc_dev
  {
        struct snd_soc_codec *codec = socdev->codec;
        struct snd_soc_card *card = socdev->card;
 -      int ret = 0, i;
 +      int ret, i;
  
        mutex_lock(&codec->mutex);
  
        /* register a sound card */
 -      codec->card = snd_card_new(idx, xid, codec->owner, 0);
 -      if (!codec->card) {
 +      ret = snd_card_create(idx, xid, codec->owner, 0, &codec->card);
 +      if (ret < 0) {
                printk(KERN_ERR "asoc: can't create sound card for codec %s\n",
                        codec->name);
                mutex_unlock(&codec->mutex);
 -              return -ENODEV;
 +              return ret;
        }
  
        codec->card->dev = socdev->dev;
@@@ -1385,7 -1385,10 +1385,10 @@@ int snd_soc_init_card(struct snd_soc_de
  
        mutex_lock(&codec->mutex);
  #ifdef CONFIG_SND_SOC_AC97_BUS
-       if (ac97) {
+       /* Only instantiate AC97 if not already done by the adaptor
+        * for the generic AC97 subsystem.
+        */
+       if (ac97 && strcmp(codec->name, "AC97") != 0) {
                ret = soc_ac97_dev_register(codec);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: AC97 device register failed\n");
@@@ -1584,37 -1587,6 +1587,6 @@@ int snd_soc_put_enum_double(struct snd_
  }
  EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
  
- /**
-  * snd_soc_info_value_enum_double - semi enumerated double mixer info callback
-  * @kcontrol: mixer control
-  * @uinfo: control element information
-  *
-  * Callback to provide information about a double semi enumerated
-  * mixer control.
-  *
-  * Semi enumerated mixer: the enumerated items are referred as values. Can be
-  * used for handling bitfield coded enumeration for example.
-  *
-  * Returns 0 for success.
-  */
- int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_info *uinfo)
- {
-       struct soc_value_enum *e = (struct soc_value_enum *)
-                       kcontrol->private_value;
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-       uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
-       uinfo->value.enumerated.items = e->max;
-       if (uinfo->value.enumerated.item > e->max - 1)
-               uinfo->value.enumerated.item = e->max - 1;
-       strcpy(uinfo->value.enumerated.name,
-               e->texts[uinfo->value.enumerated.item]);
-       return 0;
- }
- EXPORT_SYMBOL_GPL(snd_soc_info_value_enum_double);
  /**
   * snd_soc_get_value_enum_double - semi enumerated double mixer get callback
   * @kcontrol: mixer control
@@@ -1631,8 -1603,7 +1603,7 @@@ int snd_soc_get_value_enum_double(struc
        struct snd_ctl_elem_value *ucontrol)
  {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct soc_value_enum *e = (struct soc_value_enum *)
-                       kcontrol->private_value;
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned short reg_val, val, mux;
  
        reg_val = snd_soc_read(codec, e->reg);
@@@ -1671,8 -1642,7 +1642,7 @@@ int snd_soc_put_value_enum_double(struc
        struct snd_ctl_elem_value *ucontrol)
  {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct soc_value_enum *e = (struct soc_value_enum *)
-                       kcontrol->private_value;
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned short val;
        unsigned short mask;
  
index 55a9075cb097371e67a86fd3558e80047f128f1d,41c36b055f6b3f980b7c8217ce6b1496efe6bc43..09aed2363cc94f466aca559730f64f03f5e0ac08
@@@ -42,7 -42,7 +42,7 @@@
  #endif
  
  MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
- MODULE_DESCRIPTION("caiaq USB audio, version 1.3.9");
+ MODULE_DESCRIPTION("caiaq USB audio, version 1.3.10");
  MODULE_LICENSE("GPL");
  MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
                         "{Native Instruments, RigKontrol3},"
@@@ -336,10 -336,9 +336,10 @@@ static void __devinit setup_card(struc
                log("Unable to set up control system (ret=%d)\n", ret);
  }
  
 -static struct snd_card* create_card(struct usb_device* usb_dev)
 +static int create_card(struct usb_device* usb_dev, struct snd_card **cardp)
  {
        int devnum;
 +      int err;
        struct snd_card *card;
        struct snd_usb_caiaqdev *dev;
  
                        break;
  
        if (devnum >= SNDRV_CARDS)
 -              return NULL;
 +              return -ENODEV;
  
 -      card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, 
 -                                      sizeof(struct snd_usb_caiaqdev));
 -      if (!card)
 -              return NULL;
 +      err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, 
 +                            sizeof(struct snd_usb_caiaqdev), &card);
 +      if (err < 0)
 +              return err;
  
        dev = caiaqdev(card);
        dev->chip.dev = usb_dev;
        spin_lock_init(&dev->spinlock);
        snd_card_set_dev(card, &usb_dev->dev);
  
 -      return card;
 +      *cardp = card;
 +      return 0;
  }
  
  static int __devinit init_card(struct snd_usb_caiaqdev *dev)
@@@ -443,10 -441,10 +443,10 @@@ static int __devinit snd_probe(struct u
        struct snd_card *card;
        struct usb_device *device = interface_to_usbdev(intf);
        
 -      card = create_card(device);
 +      ret = create_card(device, &card);
        
 -      if (!card)
 -              return -ENOMEM;
 +      if (ret < 0)
 +              return ret;
                        
        usb_set_intfdata(intf, card);
        ret = init_card(caiaqdev(card));
diff --combined sound/usb/usbaudio.c
index eec32e1a3020ccfe23798e005e0a97a636676b2b,19e37451c216182ebdc9d800f304a66f5e6bc9e7..8f3cdb37a0ec3ddd7723eb1a5eb34e82de295157
@@@ -2524,7 -2524,6 +2524,6 @@@ static int parse_audio_format_rates(str
                 * build the rate table and bitmap flags
                 */
                int r, idx;
-               unsigned int nonzero_rates = 0;
  
                fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
                if (fp->rate_table == NULL) {
                        return -1;
                }
  
-               fp->nr_rates = nr_rates;
-               fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
+               fp->nr_rates = 0;
+               fp->rate_min = fp->rate_max = 0;
                for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
                        unsigned int rate = combine_triple(&fmt[idx]);
+                       if (!rate)
+                               continue;
                        /* C-Media CM6501 mislabels its 96 kHz altsetting */
                        if (rate == 48000 && nr_rates == 1 &&
-                           chip->usb_id == USB_ID(0x0d8c, 0x0201) &&
+                           (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
+                            chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
                            fp->altsetting == 5 && fp->maxpacksize == 392)
                                rate = 96000;
-                       fp->rate_table[r] = rate;
-                       nonzero_rates |= rate;
-                       if (rate < fp->rate_min)
+                       fp->rate_table[fp->nr_rates] = rate;
+                       if (!fp->rate_min || rate < fp->rate_min)
                                fp->rate_min = rate;
-                       else if (rate > fp->rate_max)
+                       if (!fp->rate_max || rate > fp->rate_max)
                                fp->rate_max = rate;
                        fp->rates |= snd_pcm_rate_to_rate_bit(rate);
+                       fp->nr_rates++;
                }
-               if (!nonzero_rates) {
+               if (!fp->nr_rates) {
                        hwc_debug("All rates were zero. Skipping format!\n");
                        return -1;
                }
@@@ -2966,6 -2968,7 +2968,7 @@@ static int create_fixed_stream_quirk(st
                return -EINVAL;
        }
        alts = &iface->altsetting[fp->altset_idx];
+       fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
        usb_set_interface(chip->dev, fp->iface, 0);
        init_usb_pitch(chip->dev, fp->iface, alts, fp);
        init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);
@@@ -3463,10 -3466,10 +3466,10 @@@ static int snd_usb_audio_create(struct 
                return -ENXIO;
        }
  
 -      card = snd_card_new(index[idx], id[idx], THIS_MODULE, 0);
 -      if (card == NULL) {
 +      err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
 +      if (err < 0) {
                snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
 -              return -ENOMEM;
 +              return err;
        }
  
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);