int ret;
        struct urb *urb_in;
 
-       spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+       spin_lock_irqsave(&line6pcm->in.lock, flags);
        index =
-           find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
+           find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS);
 
        if (index < 0 || index >= LINE6_ISO_BUFFERS) {
-               spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+               spin_unlock_irqrestore(&line6pcm->in.lock, flags);
                dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
                return -EINVAL;
        }
 
-       urb_in = line6pcm->urb_audio_in[index];
+       urb_in = line6pcm->in.urbs[index];
        urb_size = 0;
 
        for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
        }
 
        urb_in->transfer_buffer =
-           line6pcm->buffer_in +
+           line6pcm->in.buffer +
            index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
        urb_in->transfer_buffer_length = urb_size;
        urb_in->context = line6pcm;
        ret = usb_submit_urb(urb_in, GFP_ATOMIC);
 
        if (ret == 0)
-               set_bit(index, &line6pcm->active_urb_in);
+               set_bit(index, &line6pcm->in.active_urbs);
        else
                dev_err(line6pcm->line6->ifcdev,
                        "URB in #%d submission failed (%d)\n", index, ret);
 
-       spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+       spin_unlock_irqrestore(&line6pcm->in.lock, flags);
        return 0;
 }
 
        unsigned int i;
 
        for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (test_bit(i, &line6pcm->active_urb_in)) {
-                       if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
-                               struct urb *u = line6pcm->urb_audio_in[i];
+               if (test_bit(i, &line6pcm->in.active_urbs)) {
+                       if (!test_and_set_bit(i, &line6pcm->in.unlink_urbs)) {
+                               struct urb *u = line6pcm->in.urbs[i];
 
                                usb_unlink_urb(u);
                        }
        do {
                alive = 0;
                for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-                       if (test_bit(i, &line6pcm->active_urb_in))
+                       if (test_bit(i, &line6pcm->in.active_urbs))
                                alive++;
                }
                if (!alive)
        if (runtime == NULL)
                return;
 
-       if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+       if (line6pcm->in.pos_done + frames > runtime->buffer_size) {
                /*
                   The transferred area goes over buffer boundary,
                   copy two separate chunks.
                 */
                int len;
 
-               len = runtime->buffer_size - line6pcm->pos_in_done;
+               len = runtime->buffer_size - line6pcm->in.pos_done;
 
                if (len > 0) {
                        memcpy(runtime->dma_area +
-                              line6pcm->pos_in_done * bytes_per_frame, fbuf,
+                              line6pcm->in.pos_done * bytes_per_frame, fbuf,
                               len * bytes_per_frame);
                        memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
                               (frames - len) * bytes_per_frame);
        } else {
                /* copy single chunk */
                memcpy(runtime->dma_area +
-                      line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize);
+                      line6pcm->in.pos_done * bytes_per_frame, fbuf, fsize);
        }
 
-       line6pcm->pos_in_done += frames;
-       if (line6pcm->pos_in_done >= runtime->buffer_size)
-               line6pcm->pos_in_done -= runtime->buffer_size;
+       line6pcm->in.pos_done += frames;
+       if (line6pcm->in.pos_done >= runtime->buffer_size)
+               line6pcm->in.pos_done -= runtime->buffer_size;
 }
 
 void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
        struct snd_pcm_substream *substream =
            get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
 
-       line6pcm->bytes_in += length;
-       if (line6pcm->bytes_in >= line6pcm->period_in) {
-               line6pcm->bytes_in %= line6pcm->period_in;
+       line6pcm->in.bytes += length;
+       if (line6pcm->in.bytes >= line6pcm->in.period) {
+               line6pcm->in.bytes %= line6pcm->in.period;
                snd_pcm_period_elapsed(substream);
        }
 }
 
 void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
 {
-       kfree(line6pcm->buffer_in);
-       line6pcm->buffer_in = NULL;
+       kfree(line6pcm->in.buffer);
+       line6pcm->in.buffer = NULL;
 }
 
 /*
 
        struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
 
-       line6pcm->last_frame_in = urb->start_frame;
+       line6pcm->in.last_frame = urb->start_frame;
 
        /* find index of URB */
        for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
-               if (urb == line6pcm->urb_audio_in[index])
+               if (urb == line6pcm->in.urbs[index])
                        break;
 
-       spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+       spin_lock_irqsave(&line6pcm->in.lock, flags);
 
        for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
                char *fbuf;
                                line6_capture_copy(line6pcm, fbuf, fsize);
        }
 
-       clear_bit(index, &line6pcm->active_urb_in);
+       clear_bit(index, &line6pcm->in.active_urbs);
 
-       if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
+       if (test_and_clear_bit(index, &line6pcm->in.unlink_urbs))
                shutdown = 1;
 
-       spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+       spin_unlock_irqrestore(&line6pcm->in.lock, flags);
 
        if (!shutdown) {
                submit_audio_in_urb(line6pcm);
                return ret;
        }
 
-       line6pcm->period_in = params_period_bytes(hw_params);
+       line6pcm->in.period = params_period_bytes(hw_params);
        return 0;
 }
 
 {
        struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 
-       return line6pcm->pos_in_done;
+       return line6pcm->in.pos_done;
 }
 
 /* capture operators */
                struct urb *urb;
 
                /* URB for audio in: */
-               urb = line6pcm->urb_audio_in[i] =
+               urb = line6pcm->in.urbs[i] =
                    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
                if (urb == NULL)
 
 
        if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
                /* Invoked multiple times in a row so allocate once only */
-               if (!line6pcm->buffer_in) {
-                       line6pcm->buffer_in =
+               if (!line6pcm->in.buffer) {
+                       line6pcm->in.buffer =
                                kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
                                        line6pcm->max_packet_size, GFP_KERNEL);
-                       if (!line6pcm->buffer_in) {
+                       if (!line6pcm->in.buffer) {
                                err = -ENOMEM;
                                goto pcm_acquire_error;
                        }
                   a bug, we therefore report an error if capturing is restarted
                   too soon.
                 */
-               if (line6pcm->active_urb_in || line6pcm->unlink_urb_in) {
+               if (line6pcm->in.active_urbs || line6pcm->in.unlink_urbs) {
                        dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
                        err = -EBUSY;
                        goto pcm_acquire_error;
                }
 
-               line6pcm->count_in = 0;
+               line6pcm->in.count = 0;
                line6pcm->prev_fsize = 0;
                err = line6_submit_audio_in_all_urbs(line6pcm);
 
 
        if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
                /* Invoked multiple times in a row so allocate once only */
-               if (!line6pcm->buffer_out) {
-                       line6pcm->buffer_out =
+               if (!line6pcm->out.buffer) {
+                       line6pcm->out.buffer =
                                kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
                                        line6pcm->max_packet_size, GFP_KERNEL);
-                       if (!line6pcm->buffer_out) {
+                       if (!line6pcm->out.buffer) {
                                err = -ENOMEM;
                                goto pcm_acquire_error;
                        }
                /*
                  See comment above regarding PCM restart.
                */
-               if (line6pcm->active_urb_out || line6pcm->unlink_urb_out) {
+               if (line6pcm->out.active_urbs || line6pcm->out.unlink_urbs) {
                        dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
                        return -EBUSY;
                }
 
-               line6pcm->count_out = 0;
+               line6pcm->out.count = 0;
                err = line6_submit_audio_out_all_urbs(line6pcm);
 
                if (err < 0)
        struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
 
        for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (line6pcm->urb_audio_out[i]) {
-                       usb_kill_urb(line6pcm->urb_audio_out[i]);
-                       usb_free_urb(line6pcm->urb_audio_out[i]);
+               if (line6pcm->out.urbs[i]) {
+                       usb_kill_urb(line6pcm->out.urbs[i]);
+                       usb_free_urb(line6pcm->out.urbs[i]);
                }
-               if (line6pcm->urb_audio_in[i]) {
-                       usb_kill_urb(line6pcm->urb_audio_in[i]);
-                       usb_free_urb(line6pcm->urb_audio_in[i]);
+               if (line6pcm->in.urbs[i]) {
+                       usb_kill_urb(line6pcm->in.urbs[i]);
+                       usb_free_urb(line6pcm->in.urbs[i]);
                }
        }
        kfree(line6pcm);
                        usb_maxpacket(line6->usbdev,
                                usb_sndisocpipe(line6->usbdev, ep_write), 1));
 
-       spin_lock_init(&line6pcm->lock_audio_out);
-       spin_lock_init(&line6pcm->lock_audio_in);
+       spin_lock_init(&line6pcm->out.lock);
+       spin_lock_init(&line6pcm->in.lock);
        line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
 
        line6->line6pcm = line6pcm;
        }
 
        if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
-               line6pcm->count_out = 0;
-               line6pcm->pos_out = 0;
-               line6pcm->pos_out_done = 0;
-               line6pcm->bytes_out = 0;
-               line6pcm->count_in = 0;
-               line6pcm->pos_in_done = 0;
-               line6pcm->bytes_in = 0;
+               line6pcm->out.count = 0;
+               line6pcm->out.pos = 0;
+               line6pcm->out.pos_done = 0;
+               line6pcm->out.bytes = 0;
+               line6pcm->in.count = 0;
+               line6pcm->in.pos_done = 0;
+               line6pcm->in.bytes = 0;
        }
 
        return 0;
 
        int bytes_per_frame;
 };
 
-struct snd_line6_pcm {
-       /**
-                Pointer back to the Line 6 driver data structure.
-       */
-       struct usb_line6 *line6;
+struct line6_pcm_stream {
+       /* allocated URBs */
+       struct urb *urbs[LINE6_ISO_BUFFERS];
 
-       /**
-                Properties.
-       */
-       struct line6_pcm_properties *properties;
+       /* Temporary buffer;
+        * Since the packet size is not known in advance, this buffer is
+        * large enough to store maximum size packets.
+        */
+       unsigned char *buffer;
 
-       /**
-                ALSA pcm stream
-       */
-       struct snd_pcm *pcm;
+       /* Free frame position in the buffer. */
+       snd_pcm_uframes_t pos;
 
-       /**
-                URBs for audio playback.
-       */
-       struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
+       /* Count processed bytes;
+        * This is modulo period size (to determine when a period is finished).
+        */
+       unsigned bytes;
 
-       /**
-                URBs for audio capture.
-       */
-       struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
+       /* Counter to create desired sample rate */
+       unsigned count;
 
-       /**
-                Temporary buffer for playback.
-                Since the packet size is not known in advance, this buffer is
-                large enough to store maximum size packets.
-       */
-       unsigned char *buffer_out;
+       /* period size in bytes */
+       unsigned period;
 
-       /**
-                Temporary buffer for capture.
-                Since the packet size is not known in advance, this buffer is
-                large enough to store maximum size packets.
-       */
-       unsigned char *buffer_in;
+       /* Processed frame position in the buffer;
+        * The contents of the ring buffer have been consumed by the USB
+        * subsystem (i.e., sent to the USB device) up to this position.
+        */
+       snd_pcm_uframes_t pos_done;
 
-       /**
-                Previously captured frame (for software monitoring).
-       */
-       unsigned char *prev_fbuf;
+       /* Bit mask of active URBs */
+       unsigned long active_urbs;
 
-       /**
-                Size of previously captured frame (for software monitoring).
-       */
-       int prev_fsize;
-
-       /**
-                Free frame position in the playback buffer.
-       */
-       snd_pcm_uframes_t pos_out;
+       /* Bit mask of URBs currently being unlinked */
+       unsigned long unlink_urbs;
 
-       /**
-                Count processed bytes for playback.
-                This is modulo period size (to determine when a period is
-                finished).
-       */
-       unsigned bytes_out;
+       /* Spin lock to protect updates of the buffer positions (not contents)
+        */
+       spinlock_t lock;
 
-       /**
-                Counter to create desired playback sample rate.
-       */
-       unsigned count_out;
-
-       /**
-                Playback period size in bytes
-       */
-       unsigned period_out;
+       int last_frame;
+};
 
+struct snd_line6_pcm {
        /**
-                Processed frame position in the playback buffer.
-                The contents of the output ring buffer have been consumed by
-                the USB subsystem (i.e., sent to the USB device) up to this
-                position.
+                Pointer back to the Line 6 driver data structure.
        */
-       snd_pcm_uframes_t pos_out_done;
+       struct usb_line6 *line6;
 
        /**
-                Count processed bytes for capture.
-                This is modulo period size (to determine when a period is
-                finished).
+                Properties.
        */
-       unsigned bytes_in;
+       struct line6_pcm_properties *properties;
 
        /**
-                Counter to create desired capture sample rate.
+                ALSA pcm stream
        */
-       unsigned count_in;
+       struct snd_pcm *pcm;
 
-       /**
-                Capture period size in bytes
-       */
-       unsigned period_in;
+       /* Capture and playback streams */
+       struct line6_pcm_stream in;
+       struct line6_pcm_stream out;
 
        /**
-                Processed frame position in the capture buffer.
-                The contents of the output ring buffer have been consumed by
-                the USB subsystem (i.e., sent to the USB device) up to this
-                position.
+                Previously captured frame (for software monitoring).
        */
-       snd_pcm_uframes_t pos_in_done;
+       unsigned char *prev_fbuf;
 
        /**
-                Bit mask of active playback URBs.
+                Size of previously captured frame (for software monitoring).
        */
-       unsigned long active_urb_out;
+       int prev_fsize;
 
        /**
                 Maximum size of USB packet.
        */
        int max_packet_size;
 
-       /**
-                Bit mask of active capture URBs.
-       */
-       unsigned long active_urb_in;
-
-       /**
-                Bit mask of playback URBs currently being unlinked.
-       */
-       unsigned long unlink_urb_out;
-
-       /**
-                Bit mask of capture URBs currently being unlinked.
-       */
-       unsigned long unlink_urb_in;
-
-       /**
-                Spin lock to protect updates of the playback buffer positions (not
-                contents!)
-       */
-       spinlock_t lock_audio_out;
-
-       /**
-                Spin lock to protect updates of the capture buffer positions (not
-                contents!)
-       */
-       spinlock_t lock_audio_in;
-
        /**
                 PCM playback volume (left and right).
        */
                 Several status bits (see LINE6_BIT_*).
        */
        unsigned long flags;
-
-       int last_frame_in, last_frame_out;
 };
 
 extern int line6_init_pcm(struct usb_line6 *line6,
 
            (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
        struct urb *urb_out;
 
-       spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+       spin_lock_irqsave(&line6pcm->out.lock, flags);
        index =
-           find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
+           find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS);
 
        if (index < 0 || index >= LINE6_ISO_BUFFERS) {
-               spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+               spin_unlock_irqrestore(&line6pcm->out.lock, flags);
                dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
                return -EINVAL;
        }
 
-       urb_out = line6pcm->urb_audio_out[index];
+       urb_out = line6pcm->out.urbs[index];
        urb_size = 0;
 
        for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
                if (fsize == 0) {
                        int n;
 
-                       line6pcm->count_out += frame_increment;
-                       n = line6pcm->count_out / frame_factor;
-                       line6pcm->count_out -= n * frame_factor;
+                       line6pcm->out.count += frame_increment;
+                       n = line6pcm->out.count / frame_factor;
+                       line6pcm->out.count -= n * frame_factor;
                        fsize = n * bytes_per_frame;
                }
 
 
        if (urb_size == 0) {
                /* can't determine URB size */
-               spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+               spin_unlock_irqrestore(&line6pcm->out.lock, flags);
                dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
                return -EINVAL;
        }
 
        urb_frames = urb_size / bytes_per_frame;
        urb_out->transfer_buffer =
-           line6pcm->buffer_out +
+           line6pcm->out.buffer +
            index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
        urb_out->transfer_buffer_length = urb_size;
        urb_out->context = line6pcm;
                struct snd_pcm_runtime *runtime =
                    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
 
-               if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
+               if (line6pcm->out.pos + urb_frames > runtime->buffer_size) {
                        /*
                           The transferred area goes over buffer boundary,
                           copy the data to the temp buffer.
                         */
                        int len;
 
-                       len = runtime->buffer_size - line6pcm->pos_out;
+                       len = runtime->buffer_size - line6pcm->out.pos;
 
                        if (len > 0) {
                                memcpy(urb_out->transfer_buffer,
                                       runtime->dma_area +
-                                      line6pcm->pos_out * bytes_per_frame,
+                                      line6pcm->out.pos * bytes_per_frame,
                                       len * bytes_per_frame);
                                memcpy(urb_out->transfer_buffer +
                                       len * bytes_per_frame, runtime->dma_area,
                } else {
                        memcpy(urb_out->transfer_buffer,
                               runtime->dma_area +
-                              line6pcm->pos_out * bytes_per_frame,
+                              line6pcm->out.pos * bytes_per_frame,
                               urb_out->transfer_buffer_length);
                }
 
-               line6pcm->pos_out += urb_frames;
-               if (line6pcm->pos_out >= runtime->buffer_size)
-                       line6pcm->pos_out -= runtime->buffer_size;
+               line6pcm->out.pos += urb_frames;
+               if (line6pcm->out.pos >= runtime->buffer_size)
+                       line6pcm->out.pos -= runtime->buffer_size;
        } else {
                memset(urb_out->transfer_buffer, 0,
                       urb_out->transfer_buffer_length);
        ret = usb_submit_urb(urb_out, GFP_ATOMIC);
 
        if (ret == 0)
-               set_bit(index, &line6pcm->active_urb_out);
+               set_bit(index, &line6pcm->out.active_urbs);
        else
                dev_err(line6pcm->line6->ifcdev,
                        "URB out #%d submission failed (%d)\n", index, ret);
 
-       spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+       spin_unlock_irqrestore(&line6pcm->out.lock, flags);
        return 0;
 }
 
        unsigned int i;
 
        for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (test_bit(i, &line6pcm->active_urb_out)) {
-                       if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
-                               struct urb *u = line6pcm->urb_audio_out[i];
+               if (test_bit(i, &line6pcm->out.active_urbs)) {
+                       if (!test_and_set_bit(i, &line6pcm->out.unlink_urbs)) {
+                               struct urb *u = line6pcm->out.urbs[i];
 
                                usb_unlink_urb(u);
                        }
        do {
                alive = 0;
                for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-                       if (test_bit(i, &line6pcm->active_urb_out))
+                       if (test_bit(i, &line6pcm->out.active_urbs))
                                alive++;
                }
                if (!alive)
 
 void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
 {
-       kfree(line6pcm->buffer_out);
-       line6pcm->buffer_out = NULL;
+       kfree(line6pcm->out.buffer);
+       line6pcm->out.buffer = NULL;
 }
 
 /*
        memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
 #endif
 
-       line6pcm->last_frame_out = urb->start_frame;
+       line6pcm->out.last_frame = urb->start_frame;
 
        /* find index of URB */
        for (index = 0; index < LINE6_ISO_BUFFERS; index++)
-               if (urb == line6pcm->urb_audio_out[index])
+               if (urb == line6pcm->out.urbs[index])
                        break;
 
        if (index >= LINE6_ISO_BUFFERS)
        for (i = 0; i < LINE6_ISO_PACKETS; i++)
                length += urb->iso_frame_desc[i].length;
 
-       spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+       spin_lock_irqsave(&line6pcm->out.lock, flags);
 
        if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {
                struct snd_pcm_runtime *runtime = substream->runtime;
 
-               line6pcm->pos_out_done +=
+               line6pcm->out.pos_done +=
                    length / line6pcm->properties->bytes_per_frame;
 
-               if (line6pcm->pos_out_done >= runtime->buffer_size)
-                       line6pcm->pos_out_done -= runtime->buffer_size;
+               if (line6pcm->out.pos_done >= runtime->buffer_size)
+                       line6pcm->out.pos_done -= runtime->buffer_size;
        }
 
-       clear_bit(index, &line6pcm->active_urb_out);
+       clear_bit(index, &line6pcm->out.active_urbs);
 
        for (i = 0; i < LINE6_ISO_PACKETS; i++)
                if (urb->iso_frame_desc[i].status == -EXDEV) {
                        break;
                }
 
-       if (test_and_clear_bit(index, &line6pcm->unlink_urb_out))
+       if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs))
                shutdown = 1;
 
-       spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+       spin_unlock_irqrestore(&line6pcm->out.lock, flags);
 
        if (!shutdown) {
                submit_audio_out_urb(line6pcm);
 
                if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM,
                             &line6pcm->flags)) {
-                       line6pcm->bytes_out += length;
-                       if (line6pcm->bytes_out >= line6pcm->period_out) {
-                               line6pcm->bytes_out %= line6pcm->period_out;
+                       line6pcm->out.bytes += length;
+                       if (line6pcm->out.bytes >= line6pcm->out.period) {
+                               line6pcm->out.bytes %= line6pcm->out.period;
                                snd_pcm_period_elapsed(substream);
                        }
                }
                return ret;
        }
 
-       line6pcm->period_out = params_period_bytes(hw_params);
+       line6pcm->out.period = params_period_bytes(hw_params);
        return 0;
 }
 
 {
        struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 
-       return line6pcm->pos_out_done;
+       return line6pcm->out.pos_done;
 }
 
 /* playback operators */
                struct urb *urb;
 
                /* URB for audio out: */
-               urb = line6pcm->urb_audio_out[i] =
+               urb = line6pcm->out.urbs[i] =
                    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
                if (urb == NULL)