struct audioformat {
        struct list_head list;
-       snd_pcm_format_t format;        /* format type */
+       u64 formats;                    /* ALSA format bits */
        unsigned int channels;          /* # channels */
        unsigned int fmt_type;          /* USB audio format type (1-3) */
        unsigned int frame_size;        /* samples per frame for non-audio */
 
                if (subs->endpoint == fp->endpoint) {
                        list_add_tail(&fp->list, &subs->fmt_list);
                        subs->num_formats++;
-                       subs->formats |= 1ULL << fp->format;
+                       subs->formats |= fp->formats;
                        return 0;
                }
        }
                 */
                if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
                    fp && fp->altsetting == 1 && fp->channels == 1 &&
-                   fp->format == SNDRV_PCM_FORMAT_S16_LE &&
+                   fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
                    protocol == UAC_VERSION_1 &&
                    le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
                                                        fp->maxpacksize * 2)
 
                        return -1;
        }
 
-       fp->format = pcm_format;
+       fp->formats = 1uLL << pcm_format;
 
        /* gather possible sample rates */
        /* audio class v1 reports possible sample rates as part of the
        switch (format) {
        case UAC_FORMAT_TYPE_II_AC3:
                /* FIXME: there is no AC3 format defined yet */
-               // fp->format = SNDRV_PCM_FORMAT_AC3;
-               fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
+               // fp->formats = SNDRV_PCM_FMTBIT_AC3;
+               fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
                break;
        case UAC_FORMAT_TYPE_II_MPEG:
-               fp->format = SNDRV_PCM_FORMAT_MPEG;
+               fp->formats = SNDRV_PCM_FMTBIT_MPEG;
                break;
        default:
                snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected.  processed as MPEG.\n",
                           chip->dev->devnum, fp->iface, fp->altsetting, format);
-               fp->format = SNDRV_PCM_FORMAT_MPEG;
+               fp->formats = SNDRV_PCM_FMTBIT_MPEG;
                break;
        }
 
 
        list_for_each(p, &subs->fmt_list) {
                struct audioformat *fp;
                fp = list_entry(p, struct audioformat, list);
-               if (fp->format != format || fp->channels != channels)
+               if (!(fp->formats & (1uLL << format)))
+                       continue;
+               if (fp->channels != channels)
                        continue;
                if (rate < fp->rate_min || rate > fp->rate_max)
                        continue;
        struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
        struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
        struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
+       struct snd_mask check_fmts;
        unsigned int ptime;
 
        /* check the format */
-       if (!snd_mask_test(fmts, fp->format)) {
+       snd_mask_none(&check_fmts);
+       check_fmts.bits[0] = (u32)fp->formats;
+       check_fmts.bits[1] = (u32)(fp->formats >> 32);
+       snd_mask_intersect(&check_fmts, fmts);
+       if (snd_mask_empty(&check_fmts)) {
                hwc_debug("   > check: no supported format %d\n", fp->format);
                return 0;
        }
                fp = list_entry(p, struct audioformat, list);
                if (!hw_check_valid_format(subs, params, fp))
                        continue;
-               fbits |= (1ULL << fp->format);
+               fbits |= fp->formats;
        }
 
        oldbits[0] = fmt->bits[0];
 
 
        list_for_each(p, &subs->fmt_list) {
                struct audioformat *fp;
+               snd_pcm_format_t fmt;
                fp = list_entry(p, struct audioformat, list);
                snd_iprintf(buffer, "  Interface %d\n", fp->iface);
                snd_iprintf(buffer, "    Altset %d\n", fp->altsetting);
-               snd_iprintf(buffer, "    Format: %s\n",
-                           snd_pcm_format_name(fp->format));
+               snd_iprintf(buffer, "    Format:");
+               for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
+                       if (fp->formats & (1uLL << fmt))
+                               snd_iprintf(buffer, " %s",
+                                           snd_pcm_format_name(fmt));
+               snd_iprintf(buffer, "\n");
                snd_iprintf(buffer, "    Channels: %d\n", fp->channels);
                snd_iprintf(buffer, "    Endpoint: %d %s (%s)\n",
                            fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
 
                                .ifnum = 0,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S16_LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
                                        .channels = 4,
                                        .iface = 0,
                                        .altsetting = 1,
                                .ifnum = 1,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S16_LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
                                        .channels = 2,
                                        .iface = 1,
                                        .altsetting = 1,
                                .ifnum = 0,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S24_3LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                                        .channels = 2,
                                        .iface = 0,
                                        .altsetting = 1,
                                .ifnum = 1,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S24_3LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                                        .channels = 2,
                                        .iface = 1,
                                        .altsetting = 1,
                                .ifnum = 1,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S24_3LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                                        .channels = 2,
                                        .iface = 1,
                                        .altsetting = 1,
                                .ifnum = 2,
                                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                                .data = & (const struct audioformat) {
-                                       .format = SNDRV_PCM_FORMAT_S24_3LE,
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                                        .channels = 2,
                                        .iface = 2,
                                        .altsetting = 1,
 
                             const struct snd_usb_audio_quirk *quirk)
 {
        static const struct audioformat ua_format = {
-               .format = SNDRV_PCM_FORMAT_S24_3LE,
+               .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                .channels = 2,
                .fmt_type = UAC_FORMAT_TYPE_I,
                .altsetting = 1,
 
        urb->number_of_packets = ctx->packets;
        urb->transfer_buffer_length = offs * stride;
        memset(urb->transfer_buffer,
-              subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
+              runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
               offs * stride);
        return 0;
 }
        snd_usb_set_pcm_ops(as->pcm, stream);
 
        list_add_tail(&fp->list, &subs->fmt_list);
-       subs->formats |= 1ULL << fp->format;
+       subs->formats |= fp->formats;
        subs->endpoint = fp->endpoint;
        subs->num_formats++;
        subs->fmt_type = fp->fmt_type;