vserver 1.9.3
[linux-2.6.git] / sound / usb / usbaudio.c
index 6d5197c..1f3548c 100644 (file)
@@ -5,7 +5,7 @@
  *
  *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
  *
- *   Many codes borrowed from audio.c by 
+ *   Many codes borrowed from audio.c by
  *         Alan Cox (alan@lxorguk.ukuu.org.uk)
  *         Thomas Sailer (sailer@ife.ee.ethz.ch)
  *
@@ -58,8 +58,7 @@
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
 MODULE_DESCRIPTION("USB Audio");
 MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{Generic,USB Audio}}");
+MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
 
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
@@ -73,25 +72,18 @@ static int boot_devs;
 
 module_param_array(index, int, boot_devs, 0444);
 MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
 module_param_array(id, charp, boot_devs, 0444);
 MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
 module_param_array(enable, bool, boot_devs, 0444);
 MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 module_param_array(vid, int, boot_devs, 0444);
 MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
-MODULE_PARM_SYNTAX(vid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
 module_param_array(pid, int, boot_devs, 0444);
 MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
-MODULE_PARM_SYNTAX(pid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
 module_param(nrpacks, int, 0444);
 MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
-MODULE_PARM_SYNTAX(nrpacks, SNDRV_ENABLED ",allows:{{1,10}}");
 module_param(async_unlink, bool, 0444);
 MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
-MODULE_PARM_SYNTAX(async_unlink, SNDRV_BOOLEAN_TRUE_DESC);
 
 
 /*
@@ -104,7 +96,7 @@ MODULE_PARM_SYNTAX(async_unlink, SNDRV_BOOLEAN_TRUE_DESC);
  *
  */
 
-#define MAX_PACKS      10      
+#define MAX_PACKS      10
 #define MAX_PACKS_HS   (MAX_PACKS * 8) /* in high speed mode */
 #define MAX_URBS       5       /* max. 20ms long packets */
 #define SYNC_URBS      2       /* always two urbs for sync */
@@ -207,8 +199,6 @@ struct snd_usb_stream {
        struct list_head list;
 };
 
-#define chip_t snd_usb_stream_t
-
 
 /*
  * we keep the snd_usb_audio_t instances by ourselves for merging
@@ -354,7 +344,7 @@ static int prepare_capture_urb(snd_usb_substream_t *subs,
        if (! urb->bandwidth) {
                int bustime;
                bustime = usb_check_bandwidth(urb->dev, urb);
-               if (bustime < 0) 
+               if (bustime < 0)
                        return bustime;
                printk("urb %d: bandwidth = %d (packets = %d)\n", ctx->index, bustime, urb->number_of_packets);
                usb_claim_bandwidth(urb->dev, urb, bustime, 1);
@@ -826,7 +816,7 @@ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
 }
 
 
-/* 
+/*
  *  wait until all urbs are processed.
  */
 static int wait_clear_urbs(snd_usb_substream_t *subs)
@@ -1148,7 +1138,7 @@ static int init_usb_pitch(struct usb_device *dev, int iface,
        if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) {
                data[0] = 1;
                if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
-                                          USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
+                                          USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
                                           PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
                        snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
                                   dev->devnum, iface, ep);
@@ -1174,7 +1164,7 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
                data[1] = rate >> 8;
                data[2] = rate >> 16;
                if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
-                                          USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
+                                          USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
                                           SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
                        snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n",
                                   dev->devnum, iface, fmt->altsetting, rate, ep);
@@ -1183,9 +1173,9 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
                if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR,
                                           USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
                                           SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
-                       snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n",
+                       snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep 0x%x\n",
                                   dev->devnum, iface, fmt->altsetting, ep);
-                       return err;
+                       return 0; /* some devices don't support reading */
                }
                crate = data[0] | (data[1] << 8) | (data[2] << 16);
                if (crate != rate) {
@@ -1323,7 +1313,7 @@ static int snd_usb_hw_params(snd_pcm_substream_t *substream,
        ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
        if (ret < 0)
                return ret;
-       
+
        format = params_format(hw_params);
        rate = params_rate(hw_params);
        channels = params_channels(hw_params);
@@ -1482,7 +1472,7 @@ static int hw_rule_rate(snd_pcm_hw_params_t *params,
        snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
        unsigned int rmin, rmax;
        int changed;
-       
+
        hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
        changed = 0;
        rmin = rmax = 0;
@@ -1536,7 +1526,7 @@ static int hw_rule_channels(snd_pcm_hw_params_t *params,
        snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
        unsigned int rmin, rmax;
        int changed;
-       
+
        hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
        changed = 0;
        rmin = rmax = 0;
@@ -1590,7 +1580,7 @@ static int hw_rule_format(snd_pcm_hw_params_t *params,
        u64 fbits;
        u32 oldbits[2];
        int changed;
-       
+
        hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
        fbits = 0;
        list_for_each(p, &subs->fmt_list) {
@@ -1734,13 +1724,13 @@ static int setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
 
        if (check_hw_params_convention(subs)) {
                hwc_debug("setting extra hw constraints...\n");
-               if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
+               if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                               hw_rule_rate, subs,
                                               SNDRV_PCM_HW_PARAM_FORMAT,
                                               SNDRV_PCM_HW_PARAM_CHANNELS,
                                               -1)) < 0)
                        return err;
-               if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 
+               if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
                                               hw_rule_channels, subs,
                                               SNDRV_PCM_HW_PARAM_FORMAT,
                                               SNDRV_PCM_HW_PARAM_RATE,
@@ -2001,8 +1991,8 @@ static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffe
 
 static void proc_pcm_format_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
 {
-       snd_usb_stream_t *stream = snd_magic_cast(snd_usb_stream_t, entry->private_data, return);
-       
+       snd_usb_stream_t *stream = entry->private_data;
+
        snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
 
        if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
@@ -2089,7 +2079,7 @@ static void snd_usb_audio_stream_free(snd_usb_stream_t *stream)
        free_substream(&stream->substream[0]);
        free_substream(&stream->substream[1]);
        list_del(&stream->list);
-       snd_magic_kfree(stream);
+       kfree(stream);
 }
 
 static void snd_usb_audio_pcm_free(snd_pcm_t *pcm)
@@ -2146,7 +2136,7 @@ static int add_audio_endpoint(snd_usb_audio_t *chip, int stream, struct audiofor
        }
 
        /* create a new pcm */
-       as = snd_magic_kmalloc(snd_usb_stream_t, 0, GFP_KERNEL);
+       as = kmalloc(sizeof(*as), GFP_KERNEL);
        if (! as)
                return -ENOMEM;
        memset(as, 0, sizeof(*as));
@@ -2158,13 +2148,13 @@ static int add_audio_endpoint(snd_usb_audio_t *chip, int stream, struct audiofor
                          stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
                          &pcm);
        if (err < 0) {
-               snd_magic_kfree(as);
+               kfree(as);
                return err;
        }
        as->pcm = pcm;
        pcm->private_data = as;
        pcm->private_free = snd_usb_audio_pcm_free;
-       pcm->info_flags = SNDRV_PCM_INFO_NONATOMIC_OPS;
+       pcm->info_flags = 0;
        if (chip->pcm_devs > 0)
                sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
        else
@@ -2181,6 +2171,24 @@ static int add_audio_endpoint(snd_usb_audio_t *chip, int stream, struct audiofor
 }
 
 
+/*
+ * check if the device uses big-endian samples
+ */
+static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp)
+{
+       /* M-Audio */
+       if (dev->descriptor.idVendor == 0x0763) {
+               /* Quattro: captured data only */
+               if (dev->descriptor.idProduct == 0x2001 &&
+                   fp->endpoint & USB_DIR_IN)
+                       return 1;
+               /* Audiophile USB */
+               if (dev->descriptor.idProduct == 0x2003)
+                       return 1;
+       }
+       return 0;
+}
+
 /*
  * parse the audio format type I descriptor
  * and returns the corresponding pcm format
@@ -2217,17 +2225,13 @@ static int parse_audio_format_i_type(struct usb_device *dev, struct audioformat
                        pcm_format = SNDRV_PCM_FORMAT_S8;
                        break;
                case 2:
-                       /* M-Audio audiophile USB workaround */
-                       if (dev->descriptor.idVendor == 0x0763 &&
-                           dev->descriptor.idProduct == 0x2003)
+                       if (is_big_endian_format(dev, fp))
                                pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */
                        else
                                pcm_format = SNDRV_PCM_FORMAT_S16_LE;
                        break;
                case 3:
-                       /* M-Audio audiophile USB workaround */
-                       if (dev->descriptor.idVendor == 0x0763 &&
-                           dev->descriptor.idProduct == 0x2003)
+                       if (is_big_endian_format(dev, fp))
                                pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */
                        else
                                pcm_format = SNDRV_PCM_FORMAT_S24_3LE;
@@ -2281,7 +2285,7 @@ static int parse_audio_format_rates(struct usb_device *dev, struct audioformat *
 {
        int nr_rates = fmt[offset];
        if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
-               snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 
+               snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
                                   dev->devnum, fp->iface, fp->altsetting);
                return -1;
        }
@@ -2419,7 +2423,7 @@ static int parse_audio_format(struct usb_device *dev, struct audioformat *fp,
        }
 #endif
        return 0;
-}      
+}
 
 static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
 {
@@ -2465,22 +2469,22 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
                }
 
                if (fmt[0] < 7) {
-                       snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", 
+                       snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n",
                                   dev->devnum, iface_no, altno);
                        continue;
                }
 
                format = (fmt[6] << 8) | fmt[5]; /* remember the format value */
-                       
+
                /* get format type */
                fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE);
                if (!fmt) {
-                       snd_printk(KERN_ERR "%d:%u:%d : no FORMAT_TYPE desc\n", 
+                       snd_printk(KERN_ERR "%d:%u:%d : no FORMAT_TYPE desc\n",
                                   dev->devnum, iface_no, altno);
                        continue;
                }
                if (fmt[0] < 8) {
-                       snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 
+                       snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
                                   dev->devnum, iface_no, altno);
                        continue;
                }
@@ -2490,7 +2494,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
                if (!csep && altsd->bNumEndpoints >= 2)
                        csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
                if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
-                       snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n", 
+                       snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n",
                                   dev->devnum, iface_no, altno);
                        continue;
                }
@@ -2920,14 +2924,14 @@ static int snd_usb_create_quirk(snd_usb_audio_t *chip,
  */
 static void proc_audio_usbbus_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
 {
-       snd_usb_audio_t *chip = snd_magic_cast(snd_usb_audio_t, entry->private_data, return);
+       snd_usb_audio_t *chip = entry->private_data;
        if (! chip->shutdown)
                snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
 }
 
 static void proc_audio_usbid_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
 {
-       snd_usb_audio_t *chip = snd_magic_cast(snd_usb_audio_t, entry->private_data, return);
+       snd_usb_audio_t *chip = entry->private_data;
        if (! chip->shutdown)
                snd_iprintf(buffer, "%04x:%04x\n", chip->dev->descriptor.idVendor, chip->dev->descriptor.idProduct);
 }
@@ -2950,13 +2954,13 @@ static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
 
 static int snd_usb_audio_free(snd_usb_audio_t *chip)
 {
-       snd_magic_kfree(chip);
+       kfree(chip);
        return 0;
 }
 
 static int snd_usb_audio_dev_free(snd_device_t *device)
 {
-       snd_usb_audio_t *chip = snd_magic_cast(snd_usb_audio_t, device->device_data, return -ENXIO);
+       snd_usb_audio_t *chip = device->device_data;
        return snd_usb_audio_free(chip);
 }
 
@@ -2975,7 +2979,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
        static snd_device_ops_t ops = {
                .dev_free =     snd_usb_audio_dev_free,
        };
-       
+
        *rchip = NULL;
 
        if (snd_usb_get_speed(dev) != USB_SPEED_FULL &&
@@ -2990,7 +2994,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
                return -ENOMEM;
        }
 
-       chip = snd_magic_kcalloc(snd_usb_audio_t, 0, GFP_KERNEL);
+       chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
        if (! chip) {
                snd_card_free(card);
                return -ENOMEM;
@@ -3171,7 +3175,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
 
 /*
  * we need to take care of counter, since disconnection can be called also
- * many times as well as usb_audio_probe(). 
+ * many times as well as usb_audio_probe().
  */
 static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
 {
@@ -3182,7 +3186,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
        if (ptr == (void *)-1L)
                return;
 
-       chip = snd_magic_cast(snd_usb_audio_t, ptr, return);
+       chip = ptr;
        card = chip->card;
        down(&register_mutex);
        chip->shutdown = 1;