This patch removes the roland_ua100_hack functions from usbaudio.c and
replaces them with a new composite quirk which allows several quirks for
one device, and a quirk for a fixed PCM interface.

Additionally, it adds PCM playback support for the SC-D70. PCM recording
and mixer controls for the SC-D70 are still missing.


- add composite and PCM interface quirks
- add pcm playback support for the SC-D70


Index: alsa-kernel/usb/usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.35
diff -u -r1.35 usbaudio.c
--- alsa-kernel/usb/usbaudio.c  13 Jan 2003 09:50:26 -0000      1.35
+++ alsa-kernel/usb/usbaudio.c  21 Jan 2003 07:49:36 -0000
@@ -1918,75 +1918,58 @@
        return 0;
 }

-static int snd_usb_roland_ua100_hack_intf(snd_usb_audio_t *chip, int ifnum)
+/*
+ * create a stream for an endpoint/altsetting without proper descriptors
+ */
+static int create_fixed_stream_quirk(snd_usb_audio_t *chip,
+                                    struct usb_interface *iface,
+                                    const snd_usb_audio_quirk_t *quirk)
 {
        struct audioformat *fp;
-       int err;
+       struct usb_host_interface *alts;
+       int stream, err;

        fp = kmalloc(sizeof(*fp), GFP_KERNEL);
        if (! fp) {
                snd_printk(KERN_ERR "cannot malloc\n");
                return -ENOMEM;
        }
-       memset(fp, 0, sizeof(*fp));
-       fp->format = SNDRV_PCM_FORMAT_S16_LE;
-       fp->channels = ifnum == 0 ? 4 : 2;
-       fp->iface = ifnum;
-       fp->altsetting = 1;
-       fp->altset_idx = 1;
-       fp->attributes = ifnum == 0 ? 0 : EP_CS_ATTR_FILL_MAX;
-       fp->endpoint = ifnum == 0 ? 0x01 : 0x81;
-       fp->ep_attr = ifnum == 0 ? 0x09 : 0x05;
-       fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
-       fp->rate_min = fp->rate_max = 44100;
-
-       err = add_audio_endpoint(chip, ifnum == 0 ? SNDRV_PCM_STREAM_PLAYBACK
-                                : SNDRV_PCM_STREAM_CAPTURE, fp);
+       memcpy(fp, quirk->data, sizeof(*fp));
+       stream = (fp->endpoint & USB_DIR_IN)
+               ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+       err = add_audio_endpoint(chip, stream, fp);
        if (err < 0) {
                kfree(fp);
                return err;
        }
-       usb_set_interface(chip->dev, ifnum, 0);
+       alts = &iface->altsetting[fp->altset_idx];
+       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);
        return 0;
 }

-static int snd_usb_roland_ua100_hack(snd_usb_audio_t *chip)
+static int snd_usb_create_quirk(snd_usb_audio_t *chip,
+                               struct usb_interface *iface,
+                               const snd_usb_audio_quirk_t *quirk);
+
+/*
+ * handle the quirk(s) for the current interface
+ */
+static int create_composite_quirk(snd_usb_audio_t *chip,
+                                 struct usb_interface *iface,
+                                 const snd_usb_audio_quirk_t *quirk)
 {
-       static const snd_usb_midi_endpoint_info_t ep_quirk = {
-               .out_cables = 0x0007,
-               .in_cables  = 0x0007
-       };
-       static const snd_usb_audio_quirk_t midi_quirk = {
-               .vendor_name = "Roland",
-               .product_name = "UA-100",
-               .ifnum = 2,
-               .type = QUIRK_MIDI_FIXED_ENDPOINT,
-               .data = &ep_quirk
-       };
-       struct usb_host_config *cfg = chip->dev->actconfig;
-       struct usb_interface *iface;
+       struct usb_host_interface *alts = &iface->altsetting[0];
+       int ifnum = get_iface_desc(alts)->bInterfaceNumber;
        int err;

-       if (get_cfg_desc(cfg)->bNumInterfaces != 3) {
-               snd_printdd(KERN_ERR "invalid UA-100 descriptor\n");
-               return -ENXIO;
-       }
-       /* if 0: output */
-       if ((err = snd_usb_roland_ua100_hack_intf(chip, 0)) < 0)
-               return err;
-       /* if 1: input */
-       iface = &cfg->interface[1];
-       if (! usb_interface_claimed(iface)) {
-               if ((err = snd_usb_roland_ua100_hack_intf(chip, 1)) < 0)
-                       return err;
-               usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1);
-       }
-       /* if 2: MIDI */
-       iface = &cfg->interface[2];
-       if (! usb_interface_claimed(iface)) {
-               if ((err = snd_usb_create_midi_interface(chip, iface, &midi_quirk)) < 
0)
-                       return err;
-               usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1);
+       for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
+               if (quirk->ifnum == ifnum) {
+                       err = snd_usb_create_quirk(chip, iface, quirk);
+                       if (err < 0)
+                               return err;
+               }
        }
        return 0;
 }
@@ -2000,8 +1983,10 @@
        case QUIRK_MIDI_YAMAHA:
        case QUIRK_MIDI_MIDIMAN:
                return snd_usb_create_midi_interface(chip, iface, quirk);
-       case QUIRK_ROLAND_UA100:
-               return snd_usb_roland_ua100_hack(chip);
+       case QUIRK_COMPOSITE:
+               return create_composite_quirk(chip, iface, quirk);
+       case QUIRK_AUDIO_FIXED_ENDPOINT:
+               return create_fixed_stream_quirk(chip, iface, quirk);
        default:
                snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
                return -ENXIO;
Index: alsa-kernel/usb/usbaudio.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.h,v
retrieving revision 1.13
diff -u -r1.13 usbaudio.h
--- alsa-kernel/usb/usbaudio.h  13 Jan 2003 09:50:26 -0000      1.13
+++ alsa-kernel/usb/usbaudio.h  21 Jan 2003 07:49:36 -0000
@@ -151,7 +151,8 @@
 #define QUIRK_MIDI_FIXED_ENDPOINT      0
 #define QUIRK_MIDI_YAMAHA              1
 #define QUIRK_MIDI_MIDIMAN             2
-#define QUIRK_ROLAND_UA100             3
+#define QUIRK_COMPOSITE                        3
+#define QUIRK_AUDIO_FIXED_ENDPOINT     4

 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
 typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
@@ -176,7 +177,10 @@
 /* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
  * structure (out_cables and in_cables only) */

-/* for QUIRK_ROLAND_UA100, data is NULL */
+/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
+ * structures, terminated with .ifnum = -1 */
+
+/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */

 /*
  */
Index: alsa-kernel/usb/usbquirks.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbquirks.h,v
retrieving revision 1.12
diff -u -r1.12 usbquirks.h
--- alsa-kernel/usb/usbquirks.h 10 Jan 2003 10:31:58 -0000      1.12
+++ alsa-kernel/usb/usbquirks.h 21 Jan 2003 07:49:38 -0000
@@ -242,8 +242,55 @@
        .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
                .vendor_name = "Roland",
                .product_name = "UA-100",
-               .ifnum = 0,
-               .type = QUIRK_ROLAND_UA100
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = & (const snd_usb_audio_quirk_t[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = & (const struct audioformat) {
+                                       .format = SNDRV_PCM_FORMAT_S16_LE,
+                                       .channels = 4,
+                                       .iface = 0,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .attributes = 0,
+                                       .endpoint = 0x01,
+                                       .ep_attr = 0x09,
+                                       .rates = SNDRV_PCM_RATE_CONTINUOUS,
+                                       .rate_min = 44100,
+                                       .rate_max = 44100,
+                               }
+                       },
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = & (const struct audioformat) {
+                                       .format = SNDRV_PCM_FORMAT_S16_LE,
+                                       .channels = 2,
+                                       .iface = 1,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .attributes = EP_CS_ATTR_FILL_MAX,
+                                       .endpoint = 0x81,
+                                       .ep_attr = 0x05,
+                                       .rates = SNDRV_PCM_RATE_CONTINUOUS,
+                                       .rate_min = 44100,
+                                       .rate_max = 44100,
+                               }
+                       },
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+                               .data = & (const snd_usb_midi_endpoint_info_t) {
+                                       .out_cables = 0x0007,
+                                       .in_cables  = 0x0007
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
        }
 },
 {
@@ -355,11 +402,37 @@
        .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
                .vendor_name = "Roland",
                .product_name = "SC-D70",
-               .ifnum = 2,
-               .type = QUIRK_MIDI_FIXED_ENDPOINT,
-               .data = & (const snd_usb_midi_endpoint_info_t) {
-                       .out_cables = 0x0007,
-                       .in_cables  = 0x0007
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = & (const snd_usb_audio_quirk_t[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = & (const struct audioformat) {
+                                       .format = SNDRV_PCM_FORMAT_S24_3LE,
+                                       .channels = 2,
+                                       .iface = 0,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .attributes = 0,
+                                       .endpoint = 0x01,
+                                       .ep_attr = 0x01,
+                                       .rates = SNDRV_PCM_RATE_CONTINUOUS,
+                                       .rate_min = 44100,
+                                       .rate_max = 44100,
+                               }
+                       },
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+                               .data = & (const snd_usb_midi_endpoint_info_t) {
+                                       .out_cables = 0x0007,
+                                       .in_cables  = 0x0007
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
                }
        }
 },



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to