Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: line6: sync with upstream

Big upstream sync.

Signed-off-by: Markus Grabner <grabner@icg.tugraz.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Markus Grabner and committed by
Greg Kroah-Hartman
1027f476 4498dbcd

+2152 -1192
+65 -2
drivers/staging/line6/Kconfig
··· 1 - config LINE6_USB 1 + menuconfig LINE6_USB 2 2 tristate "Line6 USB support" 3 3 depends on USB && SND 4 4 select SND_RAWMIDI ··· 18 18 * Signal routing (record clean/processed guitar signal, 19 19 re-amping) 20 20 21 - Preliminary support for the Variax Workbench is included. 21 + Preliminary support for the Variax Workbench and TonePort 22 + devices is included. 22 23 24 + if LINE6_USB 25 + 26 + config LINE6_USB_DEBUG 27 + bool "print debug messages" 28 + default n 29 + help 30 + Say Y here to write debug messages to the syslog. 31 + 32 + If unsure, say N. 33 + 34 + config LINE6_USB_DUMP_CTRL 35 + bool "dump control messages" 36 + default n 37 + help 38 + Say Y here to write control messages sent to and received from 39 + Line6 devices to the syslog. 40 + 41 + If unsure, say N. 42 + 43 + config LINE6_USB_DUMP_MIDI 44 + bool "dump MIDI messages" 45 + default n 46 + help 47 + Say Y here to write MIDI messages sent to and received from 48 + Line6 devices to the syslog. 49 + 50 + If unsure, say N. 51 + 52 + config LINE6_USB_DUMP_PCM 53 + bool "dump PCM data" 54 + default n 55 + help 56 + Say Y here to write PCM data sent to and received from Line6 57 + devices to the syslog. This will produce a huge amount of 58 + syslog data during playback and capture. 59 + 60 + If unsure, say N. 61 + 62 + config LINE6_USB_RAW 63 + bool "raw data communication" 64 + default n 65 + help 66 + Say Y here to create special files which allow to send raw data 67 + to the device. This bypasses any sanity checks, so if you discover 68 + the code to erase the firmware, feel free to render your device 69 + useless, but only after reading the GPL section "NO WARRANTY". 70 + 71 + If unsure, say N. 72 + 73 + config LINE6_USB_IMPULSE_RESPONSE 74 + bool "measure impulse response" 75 + default n 76 + help 77 + Say Y here to add code to measure the impulse response of a Line6 78 + device. This is more accurate than user-space methods since it 79 + bypasses any PCM data buffering (e.g., by ALSA or jack). This is 80 + useful for assessing the performance of new devices, but is not 81 + required for normal operation. 82 + 83 + If unsure, say N. 84 + 85 + endif # LINE6_USB
+7 -6
drivers/staging/line6/audio.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - #include "audio.h" 14 - 15 12 #include <sound/core.h> 16 13 #include <sound/initval.h> 14 + 15 + #include "driver.h" 16 + #include "audio.h" 17 17 18 18 19 19 static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; ··· 36 36 37 37 line6->card = card; 38 38 39 + strcpy(card->id, line6->properties->id); 39 40 strcpy(card->driver, DRIVER_NAME); 40 - strcpy(card->shortname, "Line6-USB"); 41 + strcpy(card->shortname, line6->properties->name); 41 42 sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, 42 43 dev_name(line6->ifcdev)); /* 80 chars - see asound.h */ 43 44 return 0;
+2 -2
drivers/staging/line6/audio.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as
+117 -113
drivers/staging/line6/capture.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 - #include <linux/slab.h> 15 - 16 12 #include <sound/core.h> 17 13 #include <sound/pcm.h> 18 14 #include <sound/pcm_params.h> 19 15 20 16 #include "audio.h" 17 + #include "capture.h" 18 + #include "driver.h" 21 19 #include "pcm.h" 22 20 #include "pod.h" 23 - #include "capture.h" 21 + 24 22 25 23 /* 26 24 Find a free URB and submit it. 27 25 */ 28 - static int submit_audio_in_urb(struct snd_pcm_substream *substream) 26 + static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) 29 27 { 30 - unsigned int index; 28 + int index; 31 29 unsigned long flags; 32 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 33 30 int i, urb_size; 34 31 struct urb *urb_in; 35 32 ··· 34 37 index = 35 38 find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS); 36 39 37 - if (index >= LINE6_ISO_BUFFERS) { 40 + if (index < 0 || index >= LINE6_ISO_BUFFERS) { 38 41 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); 39 - dev_err(s2m(substream), "no free URB found\n"); 42 + dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 40 43 return -EINVAL; 41 44 } 42 45 ··· 55 58 line6pcm->buffer_in + 56 59 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 57 60 urb_in->transfer_buffer_length = urb_size; 58 - urb_in->context = substream; 61 + urb_in->context = line6pcm; 59 62 60 63 if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0) 61 64 set_bit(index, &line6pcm->active_urb_in); 62 65 else 63 - dev_err(s2m(substream), "URB in #%d submission failed\n", 64 - index); 66 + dev_err(line6pcm->line6->ifcdev, 67 + "URB in #%d submission failed\n", index); 65 68 66 69 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); 67 70 return 0; ··· 70 73 /* 71 74 Submit all currently available capture URBs. 72 75 */ 73 - static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream) 76 + int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm) 74 77 { 75 78 int ret, i; 76 79 77 80 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 78 - ret = submit_audio_in_urb(substream); 81 + ret = submit_audio_in_urb(line6pcm); 79 82 if (ret < 0) 80 83 return ret; 81 84 } ··· 86 89 /* 87 90 Unlink all currently active capture URBs. 88 91 */ 89 - static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm) 92 + void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm) 90 93 { 91 94 unsigned int i; 92 95 ··· 123 126 } while (--timeout > 0); 124 127 if (alive) 125 128 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); 126 - 127 - line6pcm->active_urb_in = 0; 128 - line6pcm->unlink_urb_in = 0; 129 129 } 130 130 131 131 /* 132 132 Unlink all currently active capture URBs, and wait for finishing. 133 133 */ 134 - void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) 134 + void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) 135 135 { 136 - unlink_audio_in_urbs(line6pcm); 136 + line6_unlink_audio_in_urbs(line6pcm); 137 137 wait_clear_audio_in_urbs(line6pcm); 138 138 } 139 139 140 140 /* 141 - Callback for completed capture URB. 141 + Copy data into ALSA capture buffer. 142 + */ 143 + void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) 144 + { 145 + struct snd_pcm_substream *substream = 146 + get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); 147 + struct snd_pcm_runtime *runtime = substream->runtime; 148 + const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 149 + int frames = fsize / bytes_per_frame; 150 + 151 + if (line6pcm->pos_in_done + frames > runtime->buffer_size) { 152 + /* 153 + The transferred area goes over buffer boundary, 154 + copy two separate chunks. 155 + */ 156 + int len; 157 + len = runtime->buffer_size - line6pcm->pos_in_done; 158 + 159 + if (len > 0) { 160 + memcpy(runtime->dma_area + 161 + line6pcm->pos_in_done * bytes_per_frame, fbuf, 162 + len * bytes_per_frame); 163 + memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, 164 + (frames - len) * bytes_per_frame); 165 + } else 166 + dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */ 167 + } else { 168 + /* copy single chunk */ 169 + memcpy(runtime->dma_area + 170 + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize); 171 + } 172 + 173 + if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size) 174 + line6pcm->pos_in_done -= runtime->buffer_size; 175 + } 176 + 177 + void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) 178 + { 179 + struct snd_pcm_substream *substream = 180 + get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); 181 + 182 + if ((line6pcm->bytes_in += length) >= line6pcm->period_in) { 183 + line6pcm->bytes_in %= line6pcm->period_in; 184 + snd_pcm_period_elapsed(substream); 185 + } 186 + } 187 + 188 + /* 189 + Callback for completed capture URB. 142 190 */ 143 191 static void audio_in_callback(struct urb *urb) 144 192 { 145 193 int i, index, length = 0, shutdown = 0; 146 - int frames; 147 194 unsigned long flags; 148 195 149 - struct snd_pcm_substream *substream = 150 - (struct snd_pcm_substream *)urb->context; 151 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 152 - const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 153 - struct snd_pcm_runtime *runtime = substream->runtime; 196 + struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 197 + 198 + line6pcm->last_frame_in = urb->start_frame; 154 199 155 200 /* find index of URB */ 156 201 for (index = 0; index < LINE6_ISO_BUFFERS; ++index) 157 202 if (urb == line6pcm->urb_audio_in[index]) 158 203 break; 159 204 160 - #if DO_DUMP_PCM_RECEIVE 205 + #ifdef CONFIG_LINE6_USB_DUMP_PCM 161 206 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 162 207 struct usb_iso_packet_descriptor *fout = 163 208 &urb->iso_frame_desc[i]; ··· 223 184 224 185 fbuf = urb->transfer_buffer + fin->offset; 225 186 fsize = fin->actual_length; 187 + 188 + if (fsize > line6pcm->max_packet_size) { 189 + dev_err(line6pcm->line6->ifcdev, 190 + "driver and/or device bug: packet too large (%d > %d)\n", 191 + fsize, line6pcm->max_packet_size); 192 + } 193 + 226 194 length += fsize; 227 195 228 - if (fsize > 0) { 229 - frames = fsize / bytes_per_frame; 196 + /* the following assumes LINE6_ISO_PACKETS == 1: */ 197 + #if LINE6_BACKUP_MONITOR_SIGNAL 198 + memcpy(line6pcm->prev_fbuf, fbuf, fsize); 199 + #else 200 + line6pcm->prev_fbuf = fbuf; 201 + #endif 202 + line6pcm->prev_fsize = fsize; 230 203 231 - if (line6pcm->pos_in_done + frames > 232 - runtime->buffer_size) { 233 - /* 234 - The transferred area goes over buffer 235 - boundary, copy two separate chunks. 236 - */ 237 - int len; 238 - len = 239 - runtime->buffer_size - 240 - line6pcm->pos_in_done; 241 - 242 - if (len > 0) { 243 - memcpy(runtime->dma_area + 244 - line6pcm->pos_in_done * 245 - bytes_per_frame, fbuf, 246 - len * bytes_per_frame); 247 - memcpy(runtime->dma_area, 248 - fbuf + len * bytes_per_frame, 249 - (frames - 250 - len) * bytes_per_frame); 251 - } else { 252 - /* this is somewhat paranoid */ 253 - dev_err(s2m(substream), 254 - "driver bug: len = %d\n", len); 255 - } 256 - } else { 257 - /* copy single chunk */ 258 - memcpy(runtime->dma_area + 259 - line6pcm->pos_in_done * bytes_per_frame, 260 - fbuf, fsize * bytes_per_frame); 261 - } 262 - 263 - line6pcm->pos_in_done += frames; 264 - if (line6pcm->pos_in_done >= runtime->buffer_size) 265 - line6pcm->pos_in_done -= runtime->buffer_size; 266 - } 204 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 205 + if (!(line6pcm->flags & MASK_PCM_IMPULSE)) 206 + #endif 207 + if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags) 208 + && (fsize > 0)) 209 + line6_capture_copy(line6pcm, fbuf, fsize); 267 210 } 268 211 269 212 clear_bit(index, &line6pcm->active_urb_in); 270 213 271 - if (test_bit(index, &line6pcm->unlink_urb_in)) 214 + if (test_and_clear_bit(index, &line6pcm->unlink_urb_in)) 272 215 shutdown = 1; 273 216 274 217 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); 275 218 276 219 if (!shutdown) { 277 - submit_audio_in_urb(substream); 220 + submit_audio_in_urb(line6pcm); 278 221 279 - line6pcm->bytes_in += length; 280 - if (line6pcm->bytes_in >= line6pcm->period_in) { 281 - line6pcm->bytes_in -= line6pcm->period_in; 282 - snd_pcm_period_elapsed(substream); 283 - } 222 + if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)) 223 + line6_capture_check_period(line6pcm, length); 284 224 } 285 225 } 286 226 ··· 312 294 return ret; 313 295 314 296 line6pcm->period_in = params_period_bytes(hw_params); 315 - line6pcm->buffer_in = 316 - kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * 317 - LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL); 318 - 319 - if (!line6pcm->buffer_in) { 320 - dev_err(s2m(substream), "cannot malloc buffer_in\n"); 321 - return -ENOMEM; 322 - } 323 - 324 297 return 0; 325 298 } 326 299 327 300 /* hw_free capture callback */ 328 301 static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream) 329 302 { 330 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 331 - unlink_wait_clear_audio_in_urbs(line6pcm); 332 - 333 - kfree(line6pcm->buffer_in); 334 - line6pcm->buffer_in = NULL; 335 - 336 303 return snd_pcm_lib_free_pages(substream); 337 304 } 338 305 339 306 /* trigger callback */ 340 - int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd) 307 + int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) 341 308 { 342 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 343 309 int err; 344 - line6pcm->count_in = 0; 345 310 346 311 switch (cmd) { 347 312 case SNDRV_PCM_TRIGGER_START: 348 - if (!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) { 349 - err = submit_audio_in_all_urbs(substream); 313 + #ifdef CONFIG_PM 314 + case SNDRV_PCM_TRIGGER_RESUME: 315 + #endif 316 + err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE); 350 317 351 - if (err < 0) { 352 - clear_bit(BIT_RUNNING_CAPTURE, 353 - &line6pcm->flags); 354 - return err; 355 - } 356 - } 318 + if (err < 0) 319 + return err; 357 320 358 321 break; 359 322 360 323 case SNDRV_PCM_TRIGGER_STOP: 361 - if (test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) 362 - unlink_audio_in_urbs(line6pcm); 324 + #ifdef CONFIG_PM 325 + case SNDRV_PCM_TRIGGER_SUSPEND: 326 + #endif 327 + err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE); 328 + 329 + if (err < 0) 330 + return err; 363 331 364 332 break; 365 333 ··· 366 362 367 363 /* capture operators */ 368 364 struct snd_pcm_ops snd_line6_capture_ops = { 369 - .open = snd_line6_capture_open, 370 - .close = snd_line6_capture_close, 371 - .ioctl = snd_pcm_lib_ioctl, 372 - .hw_params = snd_line6_capture_hw_params, 373 - .hw_free = snd_line6_capture_hw_free, 374 - .prepare = snd_line6_prepare, 375 - .trigger = snd_line6_trigger, 376 - .pointer = snd_line6_capture_pointer, 365 + .open = snd_line6_capture_open, 366 + .close = snd_line6_capture_close, 367 + .ioctl = snd_pcm_lib_ioctl, 368 + .hw_params = snd_line6_capture_hw_params, 369 + .hw_free = snd_line6_capture_hw_free, 370 + .prepare = snd_line6_prepare, 371 + .trigger = snd_line6_trigger, 372 + .pointer = snd_line6_capture_pointer, 377 373 }; 378 374 379 - int create_audio_in_urbs(struct snd_line6_pcm *line6pcm) 375 + int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) 380 376 { 381 377 int i; 382 378
+11 -10
drivers/staging/line6/capture.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define CAPTURE_H 14 14 15 15 16 - #include "driver.h" 17 - 18 16 #include <sound/pcm.h> 19 17 18 + #include "driver.h" 20 19 #include "pcm.h" 21 20 22 21 23 22 extern struct snd_pcm_ops snd_line6_capture_ops; 24 23 25 - 26 - extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm); 27 - extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream, 28 - int cmd); 29 - extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm); 30 - 24 + extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, 25 + int fsize); 26 + extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm); 27 + extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm); 28 + extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm); 29 + extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm 30 + *line6pcm); 31 + extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd); 31 32 32 33 #endif
+24 -22
drivers/staging/line6/control.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 12 #include <linux/usb.h> 15 13 16 14 #include "control.h" 15 + #include "driver.h" 17 16 #include "pod.h" 18 17 #include "usbdefs.h" 19 18 #include "variax.h" ··· 44 45 { 45 46 struct usb_interface *interface = to_usb_interface(dev); 46 47 struct usb_line6_pod *pod = usb_get_intfdata(interface); 47 - int retval = line6_wait_dump(&pod->dumpreq, 0); 48 + int retval = line6_dump_wait_interruptible(&pod->dumpreq); 48 49 if (retval < 0) 49 50 return retval; 50 51 return sprintf(buf, "%d\n", pod->prog_data.control[param]); ··· 62 63 if (retval) 63 64 return retval; 64 65 65 - pod_transmit_parameter(pod, param, value); 66 + line6_pod_transmit_parameter(pod, param, value); 66 67 return count; 67 68 } 68 69 ··· 70 71 { 71 72 struct usb_interface *interface = to_usb_interface(dev); 72 73 struct usb_line6_variax *variax = usb_get_intfdata(interface); 73 - int retval = line6_wait_dump(&variax->dumpreq, 0); 74 + int retval = line6_dump_wait_interruptible(&variax->dumpreq); 74 75 if (retval < 0) 75 76 return retval; 76 77 return sprintf(buf, "%d\n", variax->model_data.control[param]); ··· 79 80 static ssize_t variax_get_param_float(struct device *dev, char *buf, int param) 80 81 { 81 82 /* 82 - We do our own floating point handling here since floats in the 83 - kernel are problematic for at least two reasons: - many distros 84 - are still shipped with binary kernels optimized for the ancient 85 - 80386 without FPU 86 - - there isn't a printf("%f") 87 - (see http://www.kernelthread.com/publications/faq/335.html) 83 + We do our own floating point handling here since at the time 84 + this code was written (Jan 2006) it was highly discouraged to 85 + use floating point arithmetic in the kernel. If you think that 86 + this no longer applies, feel free to replace this by generic 87 + floating point code. 88 88 */ 89 89 90 90 static const int BIAS = 0x7f; ··· 95 97 struct usb_interface *interface = to_usb_interface(dev); 96 98 struct usb_line6_variax *variax = usb_get_intfdata(interface); 97 99 const unsigned char *p = variax->model_data.control + param; 98 - int retval = line6_wait_dump(&variax->dumpreq, 0); 100 + int retval = line6_dump_wait_interruptible(&variax->dumpreq); 99 101 if (retval < 0) 100 102 return retval; 101 103 ··· 528 530 static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, 529 531 line6_nop_write); 530 532 531 - int pod_create_files(int firmware, int type, struct device *dev) 533 + int line6_pod_create_files(int firmware, int type, struct device *dev) 532 534 { 533 535 int err; 534 536 CHECK_RETURN(device_create_file(dev, &dev_attr_tweak)); ··· 731 733 (dev, &dev_attr_band_6_gain__bass)); 732 734 return 0; 733 735 } 734 - EXPORT_SYMBOL(pod_create_files); 735 736 736 - void pod_remove_files(int firmware, int type, struct device *dev) 737 + EXPORT_SYMBOL(line6_pod_create_files); 738 + 739 + void line6_pod_remove_files(int firmware, int type, struct device *dev) 737 740 { 738 741 device_remove_file(dev, &dev_attr_tweak); 739 742 device_remove_file(dev, &dev_attr_wah_position); ··· 907 908 if (firmware >= 200) 908 909 device_remove_file(dev, &dev_attr_band_6_gain__bass); 909 910 } 910 - EXPORT_SYMBOL(pod_remove_files); 911 911 912 - int variax_create_files(int firmware, int type, struct device *dev) 912 + EXPORT_SYMBOL(line6_pod_remove_files); 913 + 914 + int line6_variax_create_files(int firmware, int type, struct device *dev) 913 915 { 914 916 int err; 915 917 CHECK_RETURN(device_create_file(dev, &dev_attr_body)); ··· 954 954 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring)); 955 955 return 0; 956 956 } 957 - EXPORT_SYMBOL(variax_create_files); 958 957 959 - void variax_remove_files(int firmware, int type, struct device *dev) 958 + EXPORT_SYMBOL(line6_variax_create_files); 959 + 960 + void line6_variax_remove_files(int firmware, int type, struct device *dev) 960 961 { 961 962 device_remove_file(dev, &dev_attr_body); 962 963 device_remove_file(dev, &dev_attr_pickup1_enable); ··· 999 998 device_remove_file(dev, &dev_attr_mix1); 1000 999 device_remove_file(dev, &dev_attr_pickup_wiring); 1001 1000 } 1002 - EXPORT_SYMBOL(variax_remove_files); 1001 + 1002 + EXPORT_SYMBOL(line6_variax_remove_files);
+54 -130
drivers/staging/line6/control.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 12 12 #ifndef LINE6_CONTROL_H 13 13 #define LINE6_CONTROL_H 14 14 15 - 16 15 /** 17 16 List of PODxt Pro controls. 18 17 See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6. 19 18 Comments after the number refer to the PODxt Pro firmware version required 20 19 for this feature. 20 + 21 + Please *don't* reformat this file since "control.c" is created automatically 22 + from "control.h", and this process depends on the exact formatting of the 23 + code and the comments below! 21 24 */ 25 + /* *INDENT-OFF* */ 22 26 enum { 23 27 POD_tweak = 1, 24 28 POD_wah_position = 4, 25 - 26 - /* device: LINE6_BITS_PODXTALL */ 27 - POD_compression_gain = 5, 28 - 29 + POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */ 29 30 POD_vol_pedal_position = 7, 30 31 POD_compression_threshold = 9, 31 32 POD_pan = 10, 32 33 POD_amp_model_setup = 11, 33 - POD_amp_model = 12, /* firmware: 2.0 */ 34 + POD_amp_model = 12, /* firmware: 2.0 */ 34 35 POD_drive = 13, 35 36 POD_bass = 14, 36 - 37 - /* device: LINE6_BITS_PODXTALL */ 38 - POD_mid = 15, 39 - 40 - /* device: LINE6_BITS_BASSPODXTALL */ 41 - POD_lowmid = 15, 42 - 43 - /* device: LINE6_BITS_PODXTALL */ 44 - POD_treble = 16, 45 - 46 - /* device: LINE6_BITS_BASSPODXTALL */ 47 - POD_highmid = 16, 48 - 37 + POD_mid = 15, /* device: LINE6_BITS_PODXTALL */ 38 + POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */ 39 + POD_treble = 16, /* device: LINE6_BITS_PODXTALL */ 40 + POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */ 49 41 POD_chan_vol = 17, 50 - 51 - /* device: LINE6_BITS_PODXTALL */ 52 - POD_reverb_mix = 18, 53 - 42 + POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */ 54 43 POD_effect_setup = 19, 55 44 POD_band_1_frequency = 20, /* firmware: 2.0 */ 56 - 57 - /* device: LINE6_BITS_PODXTALL */ 58 - POD_presence = 21, 59 - 60 - /* device: LINE6_BITS_BASSPODXTALL */ 61 - POD_treble__bass = 21, 62 - 45 + POD_presence = 21, /* device: LINE6_BITS_PODXTALL */ 46 + POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */ 63 47 POD_noise_gate_enable = 22, 64 48 POD_gate_threshold = 23, 65 49 POD_gate_decay_time = 24, ··· 54 70 POD_mod_param_1 = 29, 55 71 POD_delay_param_1 = 30, 56 72 POD_delay_param_1_note_value = 31, 57 - 58 - /* device: LINE6_BITS_BASSPODXTALL */ 59 - POD_band_2_frequency__bass = 32, /* firmware: 2.0 */ 60 - 73 + POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 61 74 POD_delay_param_2 = 33, 62 75 POD_delay_volume_mix = 34, 63 76 POD_delay_param_3 = 35, 64 - 65 - /* device: LINE6_BITS_PODXTALL */ 66 - POD_reverb_enable = 36, 67 - POD_reverb_type = 37, 68 - POD_reverb_decay = 38, 69 - POD_reverb_tone = 39, 70 - POD_reverb_pre_delay = 40, 71 - POD_reverb_pre_post = 41, 72 - POD_band_2_frequency = 42, 73 - 74 - /* device: LINE6_BITS_BASSPODXTALL */ 75 - POD_band_3_frequency__bass = 42, /* firmware: 2.0 */ 76 - 77 + POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */ 78 + POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */ 79 + POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */ 80 + POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */ 81 + POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */ 82 + POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */ 83 + POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 84 + POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 77 85 POD_wah_enable = 43, 78 - 79 - /* device: LINE6_BITS_BASSPODXTALL */ 80 - POD_modulation_lo_cut = 44, 81 - POD_delay_reverb_lo_cut = 45, 82 - 83 - /* device: LINE6_BITS_PODXTALL */ 84 - POD_volume_pedal_minimum = 46, /* firmware: 2.0 */ 85 - 86 - /* device: LINE6_BITS_BASSPODXTALL */ 87 - POD_eq_pre_post = 46, /* firmware: 2.0 */ 88 - 86 + POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */ 87 + POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */ 88 + POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 89 + POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 89 90 POD_volume_pre_post = 47, 90 - 91 - /* device: LINE6_BITS_BASSPODXTALL */ 92 - POD_di_model = 48, 93 - POD_di_delay = 49, 94 - 91 + POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */ 92 + POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */ 95 93 POD_mod_enable = 50, 96 94 POD_mod_param_1_note_value = 51, 97 95 POD_mod_param_2 = 52, 98 96 POD_mod_param_3 = 53, 99 97 POD_mod_param_4 = 54, 100 - 101 - /* device: LINE6_BITS_BASSPODXTALL */ 102 - POD_mod_param_5 = 55, 103 - 98 + POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */ 104 99 POD_mod_volume_mix = 56, 105 100 POD_mod_pre_post = 57, 106 101 POD_modulation_model = 58, 107 - 108 - /* device: LINE6_BITS_PODXTALL */ 109 - POD_band_3_frequency = 60, /* firmware: 2.0 */ 110 - 111 - /* device: LINE6_BITS_BASSPODXTALL */ 112 - POD_band_4_frequency__bass = 60, /* firmware: 2.0 */ 113 - 102 + POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 103 + POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 114 104 POD_mod_param_1_double_precision = 61, 115 105 POD_delay_param_1_double_precision = 62, 116 106 POD_eq_enable = 63, /* firmware: 2.0 */ 117 107 POD_tap = 64, 118 108 POD_volume_tweak_pedal_assign = 65, 119 - 120 - /* device: LINE6_BITS_BASSPODXTALL */ 121 - POD_band_5_frequency = 68, /* firmware: 2.0 */ 122 - 109 + POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 123 110 POD_tuner = 69, 124 111 POD_mic_selection = 70, 125 112 POD_cabinet_model = 71, 126 113 POD_stomp_model = 75, 127 114 POD_roomlevel = 76, 128 - 129 - /* device: LINE6_BITS_PODXTALL */ 130 - POD_band_4_frequency = 77, /* firmware: 2.0 */ 131 - 132 - /* device: LINE6_BITS_BASSPODXTALL */ 133 - POD_band_6_frequency = 77, /* firmware: 2.0 */ 134 - 115 + POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 116 + POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 135 117 POD_stomp_param_1_note_value = 78, 136 118 POD_stomp_param_2 = 79, 137 119 POD_stomp_param_3 = 80, 138 120 POD_stomp_param_4 = 81, 139 121 POD_stomp_param_5 = 82, 140 122 POD_stomp_param_6 = 83, 141 - 142 - /* device: LINE6_BITS_LIVE */ 143 - POD_amp_switch_select = 84, 144 - 123 + POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */ 145 124 POD_delay_param_4 = 85, 146 125 POD_delay_param_5 = 86, 147 126 POD_delay_pre_post = 87, 148 - 149 - /* device: LINE6_BITS_PODXTALL */ 150 - POD_delay_model = 88, 151 - 152 - /* device: LINE6_BITS_BASSPODXTALL */ 153 - POD_delay_verb_model = 88, 154 - 127 + POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */ 128 + POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */ 155 129 POD_tempo_msb = 89, 156 130 POD_tempo_lsb = 90, 157 131 POD_wah_model = 91, /* firmware: 3.0 */ 158 132 POD_bypass_volume = 105, /* firmware: 2.14 */ 159 - 160 - /* device: LINE6_BITS_PRO */ 161 - POD_fx_loop_on_off = 107, 162 - 133 + POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */ 163 134 POD_tweak_param_select = 108, 164 135 POD_amp1_engage = 111, 165 136 POD_band_1_gain = 114, /* firmware: 2.0 */ 166 - 167 - /* device: LINE6_BITS_BASSPODXTALL */ 168 - POD_band_2_gain__bass = 115, /* firmware: 2.0 */ 169 - 170 - /* device: LINE6_BITS_PODXTALL */ 171 - POD_band_2_gain = 116, /* firmware: 2.0 */ 172 - 173 - /* device: LINE6_BITS_BASSPODXTALL */ 174 - POD_band_3_gain__bass = 116, /* firmware: 2.0 */ 175 - 176 - /* device: LINE6_BITS_PODXTALL */ 177 - POD_band_3_gain = 117, /* firmware: 2.0 */ 178 - 179 - /* device: LINE6_BITS_BASSPODXTALL */ 180 - POD_band_4_gain__bass = 117, /* firmware: 2.0 */ 181 - POD_band_5_gain__bass = 118, /* firmware: 2.0 */ 182 - 183 - /* device: LINE6_BITS_PODXTALL */ 184 - POD_band_4_gain = 119, /* firmware: 2.0 */ 185 - 186 - /* device: LINE6_BITS_BASSPODXTALL */ 187 - POD_band_6_gain__bass = 119 /* firmware: 2.0 */ 137 + POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 138 + POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 139 + POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 140 + POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 141 + POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 142 + POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 143 + POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ 144 + POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ 188 145 }; 189 146 190 147 /** ··· 143 218 VARIAX_pickup2_position = 23, /* type: 24 bit float */ 144 219 VARIAX_pickup2_angle = 26, /* type: 24 bit float */ 145 220 VARIAX_pickup2_level = 29, /* type: 24 bit float */ 146 - VARIAX_pickup_phase = 32, /* 0: in phase, 147 - 1: out of phase */ 221 + VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */ 148 222 VARIAX_capacitance = 33, /* type: 24 bit float */ 149 223 VARIAX_tone_resistance = 36, /* type: 24 bit float */ 150 224 VARIAX_volume_resistance = 39, /* type: 24 bit float */ ··· 182 258 }; 183 259 184 260 185 - extern int pod_create_files(int firmware, int type, struct device *dev); 186 - extern void pod_remove_files(int firmware, int type, struct device *dev); 187 - extern int variax_create_files(int firmware, int type, struct device *dev); 188 - extern void variax_remove_files(int firmware, int type, struct device *dev); 261 + extern int line6_pod_create_files(int firmware, int type, struct device *dev); 262 + extern void line6_pod_remove_files(int firmware, int type, struct device *dev); 263 + extern int line6_variax_create_files(int firmware, int type, struct device *dev); 264 + extern void line6_variax_remove_files(int firmware, int type, struct device *dev); 189 265 190 266 191 267 #endif
+286 -132
drivers/staging/line6/driver.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as 8 8 * published by the Free Software Foundation, version 2. 9 9 * 10 10 */ 11 - 12 - #include "driver.h" 13 11 14 12 #include <linux/kernel.h> 15 13 #include <linux/module.h> ··· 17 19 #include "audio.h" 18 20 #include "capture.h" 19 21 #include "control.h" 22 + #include "driver.h" 20 23 #include "midi.h" 21 24 #include "playback.h" 22 25 #include "pod.h" ··· 29 30 30 31 #define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>" 31 32 #define DRIVER_DESC "Line6 USB Driver" 32 - #define DRIVER_VERSION "0.8.0" 33 + #define DRIVER_VERSION "0.9.0" 33 34 34 35 35 36 /* table of devices that work with this driver */ ··· 39 40 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) }, 40 41 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) }, 41 42 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) }, 43 + { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX) }, 44 + { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1) }, 45 + { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2) }, 42 46 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) }, 43 47 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) }, 44 48 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) }, ··· 56 54 MODULE_DEVICE_TABLE(usb, line6_id_table); 57 55 58 56 static struct line6_properties line6_properties_table[] = { 59 - { "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM }, 60 - { "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM }, 61 - { "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM }, 62 - { "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM }, 63 - { "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL_PCM }, 64 - { "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM }, 65 - { "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM }, 66 - { "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM }, 67 - { "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM }, 68 - { "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM }, 69 - { "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM }, 70 - { "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM }, 71 - { "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM }, 72 - { "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL } 57 + { "BassPODxt", "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM_HWMON }, 58 + { "BassPODxtLive", "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON }, 59 + { "BassPODxtPro", "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM_HWMON }, 60 + { "GuitarPort", "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM }, 61 + { "PocketPOD", "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL }, 62 + { "PODStudioGX", "POD Studio GX", LINE6_BIT_PODSTUDIO_GX, LINE6_BIT_PCM }, 63 + { "PODStudioUX1", "POD Studio UX1", LINE6_BIT_PODSTUDIO_UX1, LINE6_BIT_PCM }, 64 + { "PODStudioUX2", "POD Studio UX2", LINE6_BIT_PODSTUDIO_UX2, LINE6_BIT_PCM }, 65 + { "PODX3", "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM }, 66 + { "PODX3Live", "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM }, 67 + { "PODxt", "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM_HWMON }, 68 + { "PODxtLive", "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON }, 69 + { "PODxtPro", "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM_HWMON }, 70 + { "TonePortGX", "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM }, 71 + { "TonePortUX1", "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM }, 72 + { "TonePortUX2", "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM }, 73 + { "Variax", "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL } 73 74 }; 74 75 75 76 76 77 /* 77 78 This is Line6's MIDI manufacturer ID. 78 79 */ 79 - const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c }; 80 + const unsigned char line6_midi_id[] = { 81 + 0x00, 0x01, 0x0c 82 + }; 83 + 84 + /* 85 + Code to request version of POD, Variax interface 86 + (and maybe other devices). 87 + */ 88 + static const char line6_request_version0[] = { 89 + 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 90 + }; 91 + 92 + /* 93 + Copy of version request code with GFP_KERNEL flag for use in URB. 94 + */ 95 + static const char *line6_request_version; 96 + 80 97 81 98 struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; 82 - struct workqueue_struct *line6_workqueue; 83 99 84 100 85 101 /** ··· 124 104 */ 125 105 static int line6_start_listen(struct usb_line6 *line6) 126 106 { 107 + int err; 127 108 usb_fill_int_urb(line6->urb_listen, line6->usbdev, 128 109 usb_rcvintpipe(line6->usbdev, line6->ep_control_read), 129 110 line6->buffer_listen, LINE6_BUFSIZE_LISTEN, 130 111 line6_data_received, line6, line6->interval); 131 112 line6->urb_listen->actual_length = 0; 132 - return usb_submit_urb(line6->urb_listen, GFP_KERNEL); 113 + err = usb_submit_urb(line6->urb_listen, GFP_KERNEL); 114 + return err; 133 115 } 134 116 135 - #if DO_DUMP_ANY 117 + /* 118 + Stop listening on endpoint. 119 + */ 120 + static void line6_stop_listen(struct usb_line6 *line6) 121 + { 122 + usb_kill_urb(line6->urb_listen); 123 + } 124 + 125 + #ifdef CONFIG_LINE6_USB_DUMP_ANY 136 126 /* 137 127 Write hexdump to syslog. 138 128 */ ··· 182 152 } 183 153 #endif 184 154 185 - #if DO_DUMP_URB_RECEIVE 155 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 186 156 /* 187 157 Dump URB data to syslog. 188 158 */ ··· 199 169 #endif 200 170 201 171 /* 202 - Send raw message in pieces of max_packet_size bytes. 172 + Send raw message in pieces of wMaxPacketSize bytes. 203 173 */ 204 174 int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, 205 175 int size) 206 176 { 207 177 int i, done = 0; 208 - int actual_size; 209 178 210 - #if DO_DUMP_URB_SEND 179 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 211 180 line6_write_hexdump(line6, 'S', buffer, size); 212 181 #endif 213 182 214 - for (i = 0; i < size; i += actual_size) { 183 + for (i = 0; i < size; i += line6->max_packet_size) { 184 + int partial; 215 185 const char *frag_buf = buffer + i; 216 186 int frag_size = min(line6->max_packet_size, size - i); 217 187 int retval; ··· 220 190 usb_sndintpipe(line6->usbdev, 221 191 line6->ep_control_write), 222 192 (char *)frag_buf, frag_size, 223 - &actual_size, LINE6_TIMEOUT * HZ); 193 + &partial, LINE6_TIMEOUT * HZ); 224 194 225 195 if (retval) { 226 196 dev_err(line6->ifcdev, ··· 228 198 break; 229 199 } 230 200 231 - done += actual_size; 201 + done += frag_size; 232 202 } 233 203 234 204 return done; ··· 264 234 (char *)msg->buffer + done, bytes, 265 235 line6_async_request_sent, msg, line6->interval); 266 236 267 - #if DO_DUMP_URB_SEND 237 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 268 238 line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes); 269 239 #endif 270 240 ··· 280 250 } 281 251 282 252 return 0; 253 + } 254 + 255 + /* 256 + Setup and start timer. 257 + */ 258 + void line6_start_timer(struct timer_list *timer, unsigned int msecs, 259 + void (*function)(unsigned long), unsigned long data) 260 + { 261 + setup_timer(timer, function, data); 262 + timer->expires = jiffies + msecs * HZ / 1000; 263 + add_timer(timer); 283 264 } 284 265 285 266 /* ··· 330 289 } 331 290 332 291 /* 292 + Send asynchronous device version request. 293 + */ 294 + int line6_version_request_async(struct usb_line6 *line6) 295 + { 296 + return line6_send_raw_message_async(line6, line6_request_version, sizeof(line6_request_version0)); 297 + } 298 + 299 + /* 333 300 Send sysex message in pieces of wMaxPacketSize bytes. 334 301 */ 335 302 int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, 336 303 int size) 337 304 { 338 305 return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE; 306 + } 307 + 308 + /* 309 + Send sysex message in pieces of wMaxPacketSize bytes. 310 + */ 311 + int line6_send_sysex_message_async(struct usb_line6 *line6, const char *buffer, 312 + int size) 313 + { 314 + return line6_send_raw_message_async(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE; 339 315 } 340 316 341 317 /* ··· 363 305 char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, 364 306 int size) 365 307 { 366 - char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL); 308 + char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC); 367 309 368 310 if (!buffer) { 369 311 dev_err(line6->ifcdev, "out of memory\n"); ··· 390 332 if (urb->status == -ESHUTDOWN) 391 333 return; 392 334 393 - #if DO_DUMP_URB_RECEIVE 335 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 394 336 line6_dump_urb(urb); 395 337 #endif 396 338 397 - done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length); 339 + done = line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); 398 340 399 341 if (done < urb->actual_length) { 400 - midibuf_ignore(mb, done); 342 + line6_midibuf_ignore(mb, done); 401 343 DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length)); 402 344 } 403 345 404 346 for (;;) { 405 - done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN); 347 + done = line6_midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN); 406 348 407 349 if (done == 0) 408 350 break; 409 351 410 352 /* MIDI input filter */ 411 - if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive)) 353 + if (line6_midibuf_skip_message(mb, line6->line6midi->midi_mask_receive)) 412 354 continue; 413 355 414 356 line6->message_length = done; 415 - #if DO_DUMP_MIDI_RECEIVE 357 + #ifdef CONFIG_LINE6_USB_DUMP_MIDI 416 358 line6_write_hexdump(line6, 'r', line6->buffer_message, done); 417 359 #endif 418 360 line6_midi_receive(line6, line6->buffer_message, done); ··· 424 366 case LINE6_DEVID_PODXT: 425 367 case LINE6_DEVID_PODXTPRO: 426 368 case LINE6_DEVID_POCKETPOD: 427 - pod_process_message((struct usb_line6_pod *)line6); 369 + line6_pod_process_message((struct usb_line6_pod *)line6); 428 370 break; 429 371 430 372 case LINE6_DEVID_PODXTLIVE: 431 373 switch (line6->interface_number) { 432 374 case PODXTLIVE_INTERFACE_POD: 433 - pod_process_message((struct usb_line6_pod *)line6); 375 + line6_pod_process_message((struct usb_line6_pod *)line6); 434 376 break; 435 377 436 378 case PODXTLIVE_INTERFACE_VARIAX: 437 - variax_process_message((struct usb_line6_variax *)line6); 379 + line6_variax_process_message((struct usb_line6_variax *)line6); 438 380 break; 439 381 440 382 default: ··· 443 385 break; 444 386 445 387 case LINE6_DEVID_VARIAX: 446 - variax_process_message((struct usb_line6_variax *)line6); 388 + line6_variax_process_message((struct usb_line6_variax *)line6); 447 389 break; 448 390 449 391 default: ··· 454 396 line6_start_listen(line6); 455 397 } 456 398 457 - static int line6_send(struct usb_line6 *line6, unsigned char *buf, size_t len) 458 - { 459 - int retval; 460 - int partial; 461 - 462 - #if DO_DUMP_URB_SEND 463 - line6_write_hexdump(line6, 'S', buf, len); 464 - #endif 465 - 466 - retval = usb_interrupt_msg(line6->usbdev, 467 - usb_sndintpipe(line6->usbdev, 468 - line6->ep_control_write), 469 - buf, len, &partial, 470 - LINE6_TIMEOUT * HZ); 471 - 472 - if (retval) { 473 - dev_err(line6->ifcdev, 474 - "usb_interrupt_msg failed (%d)\n", retval); 475 - } 476 - 477 - if (partial != len) { 478 - dev_err(line6->ifcdev, 479 - "usb_interrupt_msg sent partial message (%d)\n", 480 - retval); 481 - } 482 - 483 - return retval; 484 - } 485 - 486 399 /* 487 400 Send channel number (i.e., switch to a different sound). 488 401 */ 489 402 int line6_send_program(struct usb_line6 *line6, int value) 490 403 { 404 + int retval; 491 405 unsigned char *buffer; 492 - size_t len = 2; 406 + int partial; 493 407 494 - buffer = kmalloc(len, GFP_KERNEL); 408 + buffer = kmalloc(2, GFP_KERNEL); 409 + 495 410 if (!buffer) { 496 411 dev_err(line6->ifcdev, "out of memory\n"); 497 412 return -ENOMEM; ··· 473 442 buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; 474 443 buffer[1] = value; 475 444 476 - return line6_send(line6, buffer, len); 445 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 446 + line6_write_hexdump(line6, 'S', buffer, 2); 447 + #endif 448 + 449 + retval = usb_interrupt_msg(line6->usbdev, 450 + usb_sndintpipe(line6->usbdev, 451 + line6->ep_control_write), 452 + buffer, 2, &partial, LINE6_TIMEOUT * HZ); 453 + 454 + if (retval) 455 + dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); 456 + 457 + kfree(buffer); 458 + return retval; 477 459 } 478 460 479 461 /* ··· 494 450 */ 495 451 int line6_transmit_parameter(struct usb_line6 *line6, int param, int value) 496 452 { 453 + int retval; 497 454 unsigned char *buffer; 498 - size_t len = 3; 455 + int partial; 499 456 500 - buffer = kmalloc(len, GFP_KERNEL); 457 + buffer = kmalloc(3, GFP_KERNEL); 458 + 501 459 if (!buffer) { 502 460 dev_err(line6->ifcdev, "out of memory\n"); 503 461 return -ENOMEM; ··· 509 463 buffer[1] = param; 510 464 buffer[2] = value; 511 465 512 - return line6_send(line6, buffer, len); 466 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 467 + line6_write_hexdump(line6, 'S', buffer, 3); 468 + #endif 469 + 470 + retval = usb_interrupt_msg(line6->usbdev, 471 + usb_sndintpipe(line6->usbdev, line6->ep_control_write), 472 + buffer, 3, &partial, LINE6_TIMEOUT * HZ); 473 + 474 + if (retval) 475 + dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); 476 + 477 + kfree(buffer); 478 + return retval; 513 479 } 514 480 515 481 /* ··· 535 477 536 478 /* query the serial number: */ 537 479 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, 538 - USB_TYPE_VENDOR | USB_RECIP_DEVICE 539 - | USB_DIR_OUT, 540 - (datalen << 8) | 0x21, address, 541 - NULL, 0, LINE6_TIMEOUT * HZ); 480 + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 481 + (datalen << 8) | 0x21, address, 482 + NULL, 0, LINE6_TIMEOUT * HZ); 542 483 543 484 if (ret < 0) { 544 485 dev_err(line6->ifcdev, "read request failed (error %d)\n", ret); ··· 656 599 /* 657 600 "write" request on "raw" special file. 658 601 */ 659 - #if CREATE_RAW_FILE 602 + #ifdef CONFIG_LINE6_USB_RAW 660 603 ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, 661 604 const char *buf, size_t count) 662 605 { ··· 694 637 kfree(line6); 695 638 } 696 639 697 - static void line6_list_devices(void) 698 - { 699 - int i; 700 - 701 - for (i = 0; i < LINE6_MAX_DEVICES; ++i) { 702 - struct usb_line6 *dev = line6_devices[i]; 703 - printk(KERN_INFO "Line6 device %d: ", i); 704 - 705 - if (dev == NULL) 706 - printk("(not used)\n"); 707 - else 708 - printk("%s:%d\n", dev->properties->name, dev->interface_number); 709 - } 710 - } 711 - 712 640 /* 713 641 Probe USB device. 714 642 */ ··· 716 674 if (usbdev == NULL) 717 675 return -ENODEV; 718 676 719 - /* increment reference counters: */ 720 - usb_get_intf(interface); 721 - usb_get_dev(usbdev); 722 - 723 677 /* we don't handle multiple configurations */ 724 678 if (usbdev->descriptor.bNumConfigurations != 1) { 725 679 ret = -ENODEV; ··· 727 689 u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor); 728 690 u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); 729 691 730 - if (idVendor == line6_id_table[devtype].idVendor 731 - && idProduct == line6_id_table[devtype].idProduct) 692 + if (idVendor == line6_id_table[devtype].idVendor && 693 + idProduct == line6_id_table[devtype].idProduct) 732 694 break; 733 695 } 734 696 ··· 757 719 758 720 switch (product) { 759 721 case LINE6_DEVID_BASSPODXTLIVE: 760 - case LINE6_DEVID_POCKETPOD: 761 722 case LINE6_DEVID_PODXTLIVE: 762 723 case LINE6_DEVID_VARIAX: 763 724 alternate = 1; 725 + break; 726 + 727 + case LINE6_DEVID_POCKETPOD: 728 + switch (interface_number) { 729 + case 0: 730 + return 0; /* this interface has no endpoints */ 731 + case 1: 732 + alternate = 0; 733 + break; 734 + default: 735 + MISSING_CASE; 736 + } 764 737 break; 765 738 766 739 case LINE6_DEVID_PODX3: ··· 795 746 alternate = 5; 796 747 break; 797 748 798 - case LINE6_DEVID_TONEPORT_GX: 799 749 case LINE6_DEVID_GUITARPORT: 750 + case LINE6_DEVID_PODSTUDIO_GX: 751 + case LINE6_DEVID_PODSTUDIO_UX1: 752 + case LINE6_DEVID_TONEPORT_GX: 753 + case LINE6_DEVID_TONEPORT_UX1: 800 754 alternate = 2; /* 1..4 seem to be ok */ 801 755 break; 802 756 803 - case LINE6_DEVID_TONEPORT_UX1: 804 757 case LINE6_DEVID_TONEPORT_UX2: 758 + case LINE6_DEVID_PODSTUDIO_UX2: 805 759 switch (interface_number) { 806 760 case 0: 807 761 /* defaults to 44.1kHz, 16-bit */ 808 762 alternate = 2; 809 763 break; 810 764 case 1: 811 - alternate = 0; 765 + /* don't know yet what this is ... 766 + alternate = 1; 812 767 break; 768 + */ 769 + return -ENODEV; 813 770 default: 814 771 MISSING_CASE; 815 772 } ··· 838 783 case LINE6_DEVID_BASSPODXT: 839 784 case LINE6_DEVID_BASSPODXTLIVE: 840 785 case LINE6_DEVID_BASSPODXTPRO: 841 - case LINE6_DEVID_POCKETPOD: 842 786 case LINE6_DEVID_PODXT: 843 787 case LINE6_DEVID_PODXTPRO: 844 788 size = sizeof(struct usb_line6_pod); 845 789 ep_read = 0x84; 846 790 ep_write = 0x03; 791 + break; 792 + 793 + case LINE6_DEVID_POCKETPOD: 794 + size = sizeof(struct usb_line6_pod); 795 + ep_read = 0x82; 796 + ep_write = 0x02; 847 797 break; 848 798 849 799 case LINE6_DEVID_PODX3: ··· 859 799 ep_write = 0x01; 860 800 break; 861 801 802 + case LINE6_DEVID_PODSTUDIO_GX: 803 + case LINE6_DEVID_PODSTUDIO_UX1: 804 + case LINE6_DEVID_PODSTUDIO_UX2: 862 805 case LINE6_DEVID_TONEPORT_GX: 863 806 case LINE6_DEVID_TONEPORT_UX1: 864 807 case LINE6_DEVID_TONEPORT_UX2: ··· 988 925 case LINE6_DEVID_PODX3LIVE: 989 926 case LINE6_DEVID_PODXT: 990 927 case LINE6_DEVID_PODXTPRO: 991 - ret = pod_init(interface, (struct usb_line6_pod *)line6); 928 + ret = line6_pod_init(interface, (struct usb_line6_pod *)line6); 992 929 break; 993 930 994 931 case LINE6_DEVID_PODXTLIVE: 995 932 switch (interface_number) { 996 933 case PODXTLIVE_INTERFACE_POD: 997 - ret = pod_init(interface, (struct usb_line6_pod *)line6); 934 + ret = line6_pod_init(interface, (struct usb_line6_pod *)line6); 998 935 break; 999 936 1000 937 case PODXTLIVE_INTERFACE_VARIAX: 1001 - ret = variax_init(interface, (struct usb_line6_variax *)line6); 938 + ret = line6_variax_init(interface, (struct usb_line6_variax *)line6); 1002 939 break; 1003 940 1004 941 default: ··· 1011 948 break; 1012 949 1013 950 case LINE6_DEVID_VARIAX: 1014 - ret = variax_init(interface, (struct usb_line6_variax *)line6); 951 + ret = line6_variax_init(interface, (struct usb_line6_variax *)line6); 1015 952 break; 1016 953 954 + case LINE6_DEVID_PODSTUDIO_GX: 955 + case LINE6_DEVID_PODSTUDIO_UX1: 956 + case LINE6_DEVID_PODSTUDIO_UX2: 1017 957 case LINE6_DEVID_TONEPORT_GX: 1018 958 case LINE6_DEVID_TONEPORT_UX1: 1019 959 case LINE6_DEVID_TONEPORT_UX2: 1020 960 case LINE6_DEVID_GUITARPORT: 1021 - ret = toneport_init(interface, (struct usb_line6_toneport *)line6); 961 + ret = line6_toneport_init(interface, (struct usb_line6_toneport *)line6); 1022 962 break; 1023 963 1024 964 default: ··· 1037 971 if (ret < 0) 1038 972 goto err_destruct; 1039 973 974 + /* creation of additional special files should go here */ 975 + 1040 976 dev_info(&interface->dev, "Line6 %s now attached\n", 1041 977 line6->properties->name); 1042 978 line6_devices[devnum] = line6; 1043 - line6_list_devices(); 979 + 980 + switch(product) { 981 + case LINE6_DEVID_PODX3: 982 + case LINE6_DEVID_PODX3LIVE: 983 + dev_info(&interface->dev, "NOTE: the Line6 %s is detected, but not yet supported\n", 984 + line6->properties->name); 985 + } 986 + 987 + /* increment reference counters: */ 988 + usb_get_intf(interface); 989 + usb_get_dev(usbdev); 990 + 1044 991 return 0; 1045 992 1046 993 err_destruct: ··· 1079 1000 if (usbdev == NULL) 1080 1001 return; 1081 1002 1003 + /* removal of additional special files should go here */ 1004 + 1082 1005 sysfs_remove_link(&interface->dev.kobj, "usb_device"); 1083 1006 1084 1007 interface_number = interface->cur_altsetting->desc.bInterfaceNumber; ··· 1088 1007 1089 1008 if (line6 != NULL) { 1090 1009 if (line6->urb_listen != NULL) 1091 - usb_kill_urb(line6->urb_listen); 1010 + line6_stop_listen(line6); 1092 1011 1093 1012 if (usbdev != line6->usbdev) 1094 1013 dev_err(line6->ifcdev, ··· 1103 1022 case LINE6_DEVID_PODX3LIVE: 1104 1023 case LINE6_DEVID_PODXT: 1105 1024 case LINE6_DEVID_PODXTPRO: 1106 - pod_disconnect(interface); 1025 + line6_pod_disconnect(interface); 1107 1026 break; 1108 1027 1109 1028 case LINE6_DEVID_PODXTLIVE: 1110 1029 switch (interface_number) { 1111 1030 case PODXTLIVE_INTERFACE_POD: 1112 - pod_disconnect(interface); 1031 + line6_pod_disconnect(interface); 1113 1032 break; 1114 1033 1115 1034 case PODXTLIVE_INTERFACE_VARIAX: 1116 - variax_disconnect(interface); 1035 + line6_variax_disconnect(interface); 1117 1036 break; 1118 1037 } 1119 1038 1120 1039 break; 1121 1040 1122 1041 case LINE6_DEVID_VARIAX: 1123 - variax_disconnect(interface); 1042 + line6_variax_disconnect(interface); 1124 1043 break; 1125 1044 1045 + case LINE6_DEVID_PODSTUDIO_GX: 1046 + case LINE6_DEVID_PODSTUDIO_UX1: 1047 + case LINE6_DEVID_PODSTUDIO_UX2: 1126 1048 case LINE6_DEVID_TONEPORT_GX: 1127 1049 case LINE6_DEVID_TONEPORT_UX1: 1128 1050 case LINE6_DEVID_TONEPORT_UX2: 1129 1051 case LINE6_DEVID_GUITARPORT: 1130 - toneport_disconnect(interface); 1052 + line6_toneport_disconnect(interface); 1131 1053 break; 1132 1054 1133 1055 default: ··· 1139 1055 1140 1056 dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name); 1141 1057 1142 - for (i = LINE6_MAX_DEVICES; i--;) { 1058 + for (i = LINE6_MAX_DEVICES; i--;) 1143 1059 if (line6_devices[i] == line6) 1144 1060 line6_devices[i] = NULL; 1145 - } 1146 1061 } 1147 1062 1148 1063 line6_destruct(interface); ··· 1149 1066 /* decrement reference counters: */ 1150 1067 usb_put_intf(interface); 1151 1068 usb_put_dev(usbdev); 1152 - 1153 - line6_list_devices(); 1154 1069 } 1070 + 1071 + #ifdef CONFIG_PM 1072 + 1073 + /* 1074 + Suspend Line6 device. 1075 + */ 1076 + static int line6_suspend(struct usb_interface *interface, pm_message_t message) 1077 + { 1078 + struct usb_line6 *line6 = usb_get_intfdata(interface); 1079 + struct snd_line6_pcm *line6pcm = line6->line6pcm; 1080 + 1081 + snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot); 1082 + 1083 + if (line6->properties->capabilities & LINE6_BIT_CONTROL) 1084 + line6_stop_listen(line6); 1085 + 1086 + if (line6pcm != NULL) { 1087 + snd_pcm_suspend_all(line6pcm->pcm); 1088 + line6_pcm_disconnect(line6pcm); 1089 + line6pcm->flags = 0; 1090 + } 1091 + 1092 + return 0; 1093 + } 1094 + 1095 + /* 1096 + Resume Line6 device. 1097 + */ 1098 + static int line6_resume(struct usb_interface *interface) 1099 + { 1100 + struct usb_line6 *line6 = usb_get_intfdata(interface); 1101 + 1102 + if (line6->properties->capabilities & LINE6_BIT_CONTROL) 1103 + line6_start_listen(line6); 1104 + 1105 + snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); 1106 + return 0; 1107 + } 1108 + 1109 + /* 1110 + Resume Line6 device after reset. 1111 + */ 1112 + static int line6_reset_resume(struct usb_interface *interface) 1113 + { 1114 + struct usb_line6 *line6 = usb_get_intfdata(interface); 1115 + 1116 + switch (line6->usbdev->descriptor.idProduct) { 1117 + case LINE6_DEVID_PODSTUDIO_GX: 1118 + case LINE6_DEVID_PODSTUDIO_UX1: 1119 + case LINE6_DEVID_PODSTUDIO_UX2: 1120 + case LINE6_DEVID_TONEPORT_GX: 1121 + case LINE6_DEVID_TONEPORT_UX1: 1122 + case LINE6_DEVID_TONEPORT_UX2: 1123 + case LINE6_DEVID_GUITARPORT: 1124 + line6_toneport_reset_resume((struct usb_line6_toneport *)line6); 1125 + } 1126 + 1127 + return line6_resume(interface); 1128 + } 1129 + 1130 + #endif /* CONFIG_PM */ 1155 1131 1156 1132 static struct usb_driver line6_driver = { 1157 1133 .name = DRIVER_NAME, 1158 1134 .probe = line6_probe, 1159 1135 .disconnect = line6_disconnect, 1136 + #ifdef CONFIG_PM 1137 + .suspend = line6_suspend, 1138 + .resume = line6_resume, 1139 + .reset_resume = line6_reset_resume, 1140 + #endif 1160 1141 .id_table = line6_id_table, 1161 1142 }; 1162 1143 ··· 1233 1086 1234 1087 printk(KERN_INFO "%s driver version %s%s\n", 1235 1088 DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION); 1236 - line6_workqueue = create_workqueue(DRIVER_NAME); 1237 - 1238 - if (line6_workqueue == NULL) { 1239 - err("couldn't create workqueue"); 1240 - return -EINVAL; 1241 - } 1242 1089 1243 1090 for (i = LINE6_MAX_DEVICES; i--;) 1244 1091 line6_devices[i] = NULL; 1245 1092 1246 1093 retval = usb_register(&line6_driver); 1247 1094 1248 - if (retval) 1095 + if (retval) { 1249 1096 err("usb_register failed. Error number %d", retval); 1097 + return retval; 1098 + } 1099 + 1100 + line6_request_version = kmalloc(sizeof(line6_request_version0), 1101 + GFP_KERNEL); 1102 + 1103 + if (line6_request_version == NULL) { 1104 + err("Out of memory"); 1105 + return -ENOMEM; 1106 + } 1107 + 1108 + memcpy((char *)line6_request_version, line6_request_version0, 1109 + sizeof(line6_request_version0)); 1250 1110 1251 1111 return retval; 1252 1112 } ··· 1263 1109 */ 1264 1110 static void __exit line6_exit(void) 1265 1111 { 1266 - destroy_workqueue(line6_workqueue); 1112 + kfree(line6_request_version); 1267 1113 usb_deregister(&line6_driver); 1268 1114 } 1269 1115
+45 -7
drivers/staging/line6/driver.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define DRIVER_H 14 14 15 15 16 - #include "config.h" 17 - 18 16 #include <linux/spinlock.h> 19 17 #include <linux/usb.h> 20 - #include <linux/wait.h> 21 18 #include <sound/core.h> 22 19 23 20 #include "midi.h" 24 21 22 + 25 23 #define DRIVER_NAME "line6usb" 24 + 25 + #if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM) 26 + #define CONFIG_LINE6_USB_DUMP_ANY 27 + #endif 26 28 27 29 #define LINE6_TIMEOUT 1 28 30 #define LINE6_MAX_DEVICES 8 29 31 #define LINE6_BUFSIZE_LISTEN 32 30 32 #define LINE6_MESSAGE_MAXLEN 256 31 - 32 33 33 34 /* 34 35 Line6 MIDI control commands ··· 55 54 56 55 #define LINE6_CHANNEL_MASK 0x0f 57 56 57 + #ifdef CONFIG_LINE6_USB_DEBUG 58 + #define DEBUG_MESSAGES(x) (x) 59 + #else 60 + #define DEBUG_MESSAGES(x) 61 + #endif 62 + 58 63 59 64 #define MISSING_CASE \ 60 65 printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \ ··· 74 67 return err; \ 75 68 } while (0) 76 69 70 + #define CHECK_STARTUP_PROGRESS(x, n) \ 71 + if((x) >= (n)) \ 72 + return; \ 73 + x = (n); 74 + 77 75 78 76 extern const unsigned char line6_midi_id[3]; 79 77 extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; 80 - extern struct workqueue_struct *line6_workqueue; 81 78 82 79 static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; 83 80 static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; ··· 91 80 Common properties of Line6 devices. 92 81 */ 93 82 struct line6_properties { 83 + /** 84 + Card id string (maximum 16 characters). 85 + This can be used to address the device in ALSA programs as 86 + "default:CARD=<id>" 87 + */ 88 + const char *id; 89 + 90 + /** 91 + Card short name (maximum 32 characters). 92 + */ 94 93 const char *name; 94 + 95 + /** 96 + Bit identifying this device in the line6usb driver. 97 + */ 95 98 int device_bit; 99 + 100 + /** 101 + Bit vector defining this device's capabilities in the 102 + line6usb driver. 103 + */ 96 104 int capabilities; 97 105 }; 98 106 ··· 221 191 const char *buffer, int size); 222 192 extern int line6_send_sysex_message(struct usb_line6 *line6, 223 193 const char *buffer, int size); 194 + extern int line6_send_sysex_message_async(struct usb_line6 *line6, 195 + const char *buffer, int size); 224 196 extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, 225 197 const char *buf, size_t count); 198 + extern void line6_start_timer(struct timer_list *timer, unsigned int msecs, 199 + void (*function)(unsigned long), unsigned long data); 226 200 extern int line6_transmit_parameter(struct usb_line6 *line6, int param, 227 201 int value); 202 + extern int line6_version_request_async(struct usb_line6 *line6); 228 203 extern int line6_write_data(struct usb_line6 *line6, int address, void *data, 229 204 size_t datalen); 205 + 206 + #ifdef CONFIG_LINE6_USB_DUMP_ANY 230 207 extern void line6_write_hexdump(struct usb_line6 *line6, char dir, 231 208 const unsigned char *buffer, int size); 209 + #endif 232 210 233 211 234 212 #endif
+18 -38
drivers/staging/line6/dumprequest.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 12 #include <linux/slab.h> 15 13 14 + #include "driver.h" 16 15 #include "dumprequest.h" 17 16 18 17 ··· 38 39 void line6_dump_finished(struct line6_dump_request *l6dr) 39 40 { 40 41 l6dr->in_progress = LINE6_DUMP_NONE; 41 - wake_up_interruptible(&l6dr->wait); 42 + wake_up(&l6dr->wait); 42 43 } 43 44 44 45 /* 45 46 Send an asynchronous channel dump request. 46 47 */ 47 48 int line6_dump_request_async(struct line6_dump_request *l6dr, 48 - struct usb_line6 *line6, int num) 49 + struct usb_line6 *line6, int num, int dest) 49 50 { 50 51 int ret; 51 - line6_invalidate_current(l6dr); 52 + line6_dump_started(l6dr, dest); 52 53 ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer, 53 54 l6dr->reqbufs[num].length); 54 55 ··· 59 60 } 60 61 61 62 /* 62 - Send an asynchronous dump request after a given interval. 63 + Wait for completion (interruptible). 63 64 */ 64 - void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds, 65 - void (*function)(unsigned long), void *data) 65 + int line6_dump_wait_interruptible(struct line6_dump_request *l6dr) 66 66 { 67 - l6dr->timer.expires = jiffies + seconds * HZ; 68 - l6dr->timer.function = function; 69 - l6dr->timer.data = (unsigned long)data; 70 - add_timer(&l6dr->timer); 67 + return wait_event_interruptible(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE); 71 68 } 72 69 73 70 /* 74 71 Wait for completion. 75 72 */ 76 - int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock) 73 + void line6_dump_wait(struct line6_dump_request *l6dr) 77 74 { 78 - int retval = 0; 79 - DECLARE_WAITQUEUE(wait, current); 80 - add_wait_queue(&l6dr->wait, &wait); 81 - current->state = TASK_INTERRUPTIBLE; 75 + wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE); 76 + } 82 77 83 - while (l6dr->in_progress) { 84 - if (nonblock) { 85 - retval = -EAGAIN; 86 - break; 87 - } 88 - 89 - if (signal_pending(current)) { 90 - retval = -ERESTARTSYS; 91 - break; 92 - } else 93 - schedule(); 94 - } 95 - 96 - current->state = TASK_RUNNING; 97 - remove_wait_queue(&l6dr->wait, &wait); 98 - return retval; 78 + /* 79 + Wait for completion (with timeout). 80 + */ 81 + int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout) 82 + { 83 + return wait_event_timeout(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE, timeout); 99 84 } 100 85 101 86 /* ··· 106 123 if (ret < 0) 107 124 return ret; 108 125 init_waitqueue_head(&l6dr->wait); 109 - init_timer(&l6dr->timer); 110 126 return 0; 111 127 } 112 128 ··· 130 148 if (l6dr->reqbufs[0].buffer == NULL) 131 149 return; 132 150 line6_dumpreq_destructbuf(l6dr, 0); 133 - l6dr->ok = 1; 134 - del_timer_sync(&l6dr->timer); 135 151 }
+7 -17
drivers/staging/line6/dumprequest.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 15 15 16 16 #include <linux/usb.h> 17 17 #include <linux/wait.h> 18 - 19 18 #include <sound/core.h> 20 19 21 20 ··· 55 56 int in_progress; 56 57 57 58 /** 58 - Timer for delayed dump request. 59 - */ 60 - struct timer_list timer; 61 - 62 - /** 63 - Flag if initial dump request has been successful. 64 - */ 65 - char ok; 66 - 67 - /** 68 59 Dump request buffers 69 60 */ 70 61 struct line6_dump_reqbuf reqbufs[1]; ··· 62 73 63 74 extern void line6_dump_finished(struct line6_dump_request *l6dr); 64 75 extern int line6_dump_request_async(struct line6_dump_request *l6dr, 65 - struct usb_line6 *line6, int num); 76 + struct usb_line6 *line6, int num, int dest); 66 77 extern void line6_dump_started(struct line6_dump_request *l6dr, int dest); 67 78 extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr); 68 79 extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num); ··· 71 82 extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, 72 83 const void *buf, size_t len, int num); 73 84 extern void line6_invalidate_current(struct line6_dump_request *l6dr); 74 - extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds, 75 - void (*function)(unsigned long), void *data); 76 - extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock); 85 + extern void line6_dump_wait(struct line6_dump_request *l6dr); 86 + extern int line6_dump_wait_interruptible(struct line6_dump_request *l6dr); 87 + extern int line6_dump_wait_timeout(struct line6_dump_request *l6dr, 88 + long timeout); 77 89 78 90 79 91 #endif
+20 -36
drivers/staging/line6/midi.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 - #include <linux/usb.h> 15 12 #include <linux/slab.h> 16 - 13 + #include <linux/usb.h> 17 14 #include <sound/core.h> 18 15 #include <sound/rawmidi.h> 19 16 20 17 #include "audio.h" 18 + #include "driver.h" 21 19 #include "midi.h" 22 20 #include "pod.h" 23 21 #include "usbdefs.h" 24 - 25 - 26 - #define USE_MIDIBUF 1 27 - #define OUTPUT_DUMP_ONLY 0 28 22 29 23 30 24 #define line6_rawmidi_substream_midi(substream) \ ··· 55 61 spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags); 56 62 57 63 for (;;) { 58 - req = min(midibuf_bytes_free(mb), line6->max_packet_size); 64 + req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size); 59 65 done = snd_rawmidi_transmit_peek(substream, chunk, req); 60 66 61 67 if (done == 0) 62 68 break; 63 69 64 - #if DO_DUMP_MIDI_SEND 70 + #ifdef CONFIG_LINE6_USB_DUMP_MIDI 65 71 line6_write_hexdump(line6, 's', chunk, done); 66 72 #endif 67 - midibuf_write(mb, chunk, done); 73 + line6_midibuf_write(mb, chunk, done); 68 74 snd_rawmidi_transmit_ack(substream, done); 69 75 } 70 76 71 77 for (;;) { 72 - done = midibuf_read(mb, chunk, line6->max_packet_size); 78 + done = line6_midibuf_read(mb, chunk, line6->max_packet_size); 73 79 74 80 if (done == 0) 75 81 break; 76 82 77 - if (midibuf_skip_message(mb, line6midi->midi_mask_transmit)) 83 + if (line6_midibuf_skip_message(mb, line6midi->midi_mask_transmit)) 78 84 continue; 79 85 80 86 send_midi_async(line6, chunk, done); ··· 109 115 } 110 116 111 117 if (num == 0) 112 - wake_up_interruptible(&line6->line6midi->send_wait); 118 + wake_up(&line6->line6midi->send_wait); 113 119 114 120 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 115 121 } ··· 133 139 return -ENOMEM; 134 140 } 135 141 136 - #if DO_DUMP_URB_SEND 142 + #ifdef CONFIG_LINE6_USB_DUMP_CTRL 137 143 line6_write_hexdump(line6, 'S', data, length); 138 144 #endif 139 145 ··· 170 176 case LINE6_DEVID_PODXTLIVE: 171 177 case LINE6_DEVID_PODXTPRO: 172 178 case LINE6_DEVID_POCKETPOD: 173 - pod_midi_postprocess((struct usb_line6_pod *)line6, data, 174 - length); 179 + line6_pod_midi_postprocess((struct usb_line6_pod *)line6, data, 180 + length); 175 181 break; 176 182 177 183 default: ··· 209 215 static void line6_midi_output_drain(struct snd_rawmidi_substream *substream) 210 216 { 211 217 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6; 212 - wait_queue_head_t *head = &line6->line6midi->send_wait; 213 - DECLARE_WAITQUEUE(wait, current); 214 - add_wait_queue(head, &wait); 215 - current->state = TASK_INTERRUPTIBLE; 216 - 217 - while (line6->line6midi->num_active_send_urbs > 0) 218 - if (signal_pending(current)) 219 - break; 220 - else 221 - schedule(); 222 - 223 - current->state = TASK_RUNNING; 224 - remove_wait_queue(head, &wait); 218 + struct snd_line6_midi *midi = line6->line6midi; 219 + wait_event_interruptible(midi->send_wait, midi->num_active_send_urbs == 0); 225 220 } 226 221 227 222 static int line6_midi_input_open(struct snd_rawmidi_substream *substream) ··· 267 284 268 285 rmidi->private_data = line6midi; 269 286 rmidi->private_free = line6_cleanup_midi; 287 + strcpy(rmidi->id, line6midi->line6->properties->id); 270 288 strcpy(rmidi->name, line6midi->line6->properties->name); 271 289 272 290 rmidi->info_flags = ··· 355 371 struct snd_line6_midi *line6midi = device->device_data; 356 372 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit); 357 373 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive); 358 - midibuf_destroy(&line6midi->midibuf_in); 359 - midibuf_destroy(&line6midi->midibuf_out); 374 + line6_midibuf_destroy(&line6midi->midibuf_in); 375 + line6_midibuf_destroy(&line6midi->midibuf_out); 360 376 return 0; 361 377 } 362 378 ··· 380 396 if (line6midi == NULL) 381 397 return -ENOMEM; 382 398 383 - err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); 399 + err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); 384 400 if (err < 0) 385 401 return err; 386 402 387 - err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); 403 + err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); 388 404 if (err < 0) 389 405 return err; 390 406
+2 -2
drivers/staging/line6/midi.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as
+41 -43
drivers/staging/line6/midibuf.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as 8 8 * published by the Free Software Foundation, version 2. 9 9 * 10 10 */ 11 - 12 - #include "config.h" 13 11 14 12 #include <linux/slab.h> 15 13 ··· 23 25 return length[(code >> 4) - 8]; 24 26 } else { 25 27 /* 26 - Note that according to the MIDI specification 0xf2 is 27 - the "Song Position Pointer", but this is used by Line6 28 - to send sysex messages to the host. 28 + Note that according to the MIDI specification 0xf2 is 29 + the "Song Position Pointer", but this is used by Line6 30 + to send sysex messages to the host. 29 31 */ 30 32 static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1, 31 33 1, 1, 1, -1, 1, 1 }; 32 34 return length[code & 0x0f]; 33 35 } 34 - } 35 - 36 - void midibuf_reset(struct MidiBuffer *this) 37 - { 38 - this->pos_read = this->pos_write = this->full = 0; 39 - this->command_prev = -1; 40 - } 41 - 42 - int midibuf_init(struct MidiBuffer *this, int size, int split) 43 - { 44 - this->buf = kmalloc(size, GFP_KERNEL); 45 - 46 - if (this->buf == NULL) 47 - return -ENOMEM; 48 - 49 - this->size = size; 50 - this->split = split; 51 - midibuf_reset(this); 52 - return 0; 53 - } 54 - 55 - void midibuf_status(struct MidiBuffer *this) 56 - { 57 - printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d " 58 - "full=%d command_prev=%02x\n", this->size, this->split, 59 - this->pos_read, this->pos_write, this->full, this->command_prev); 60 36 } 61 37 62 38 static int midibuf_is_empty(struct MidiBuffer *this) ··· 43 71 return this->full; 44 72 } 45 73 46 - int midibuf_bytes_free(struct MidiBuffer *this) 74 + void line6_midibuf_reset(struct MidiBuffer *this) 75 + { 76 + this->pos_read = this->pos_write = this->full = 0; 77 + this->command_prev = -1; 78 + } 79 + 80 + int line6_midibuf_init(struct MidiBuffer *this, int size, int split) 81 + { 82 + this->buf = kmalloc(size, GFP_KERNEL); 83 + 84 + if (this->buf == NULL) 85 + return -ENOMEM; 86 + 87 + this->size = size; 88 + this->split = split; 89 + line6_midibuf_reset(this); 90 + return 0; 91 + } 92 + 93 + void line6_midibuf_status(struct MidiBuffer *this) 94 + { 95 + printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d " 96 + "full=%d command_prev=%02x\n", this->size, this->split, 97 + this->pos_read, this->pos_write, this->full, this->command_prev); 98 + } 99 + 100 + int line6_midibuf_bytes_free(struct MidiBuffer *this) 47 101 { 48 102 return 49 103 midibuf_is_full(this) ? ··· 77 79 (this->pos_read - this->pos_write + this->size - 1) % this->size + 1; 78 80 } 79 81 80 - int midibuf_bytes_used(struct MidiBuffer *this) 82 + int line6_midibuf_bytes_used(struct MidiBuffer *this) 81 83 { 82 84 return 83 85 midibuf_is_empty(this) ? ··· 85 87 (this->pos_write - this->pos_read + this->size - 1) % this->size + 1; 86 88 } 87 89 88 - int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length) 90 + int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data, int length) 89 91 { 90 92 int bytes_free; 91 93 int length1, length2; ··· 100 102 skip_active_sense = 1; 101 103 } 102 104 103 - bytes_free = midibuf_bytes_free(this); 105 + bytes_free = line6_midibuf_bytes_free(this); 104 106 105 107 if (length > bytes_free) 106 108 length = bytes_free; ··· 127 129 return length + skip_active_sense; 128 130 } 129 131 130 - int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length) 132 + int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length) 131 133 { 132 134 int bytes_used; 133 135 int length1, length2; ··· 143 145 if (midibuf_is_empty(this)) 144 146 return 0; 145 147 146 - bytes_used = midibuf_bytes_used(this); 148 + bytes_used = line6_midibuf_bytes_used(this); 147 149 148 150 if (length > bytes_used) 149 151 length = bytes_used; ··· 230 232 return length + repeat; 231 233 } 232 234 233 - int midibuf_ignore(struct MidiBuffer *this, int length) 235 + int line6_midibuf_ignore(struct MidiBuffer *this, int length) 234 236 { 235 - int bytes_used = midibuf_bytes_used(this); 237 + int bytes_used = line6_midibuf_bytes_used(this); 236 238 237 239 if (length > bytes_used) 238 240 length = bytes_used; ··· 242 244 return length; 243 245 } 244 246 245 - int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask) 247 + int line6_midibuf_skip_message(struct MidiBuffer *this, unsigned short mask) 246 248 { 247 249 int cmd = this->command_prev; 248 250 ··· 253 255 return 0; 254 256 } 255 257 256 - void midibuf_destroy(struct MidiBuffer *this) 258 + void line6_midibuf_destroy(struct MidiBuffer *this) 257 259 { 258 260 kfree(this->buf); 259 261 this->buf = NULL;
+13 -13
drivers/staging/line6/midibuf.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 23 23 }; 24 24 25 25 26 - extern int midibuf_bytes_used(struct MidiBuffer *mb); 27 - extern int midibuf_bytes_free(struct MidiBuffer *mb); 28 - extern void midibuf_destroy(struct MidiBuffer *mb); 29 - extern int midibuf_ignore(struct MidiBuffer *mb, int length); 30 - extern int midibuf_init(struct MidiBuffer *mb, int size, int split); 31 - extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length); 32 - extern void midibuf_reset(struct MidiBuffer *mb); 33 - extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask); 34 - extern void midibuf_status(struct MidiBuffer *mb); 35 - extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data, 36 - int length); 26 + extern int line6_midibuf_bytes_used(struct MidiBuffer *mb); 27 + extern int line6_midibuf_bytes_free(struct MidiBuffer *mb); 28 + extern void line6_midibuf_destroy(struct MidiBuffer *mb); 29 + extern int line6_midibuf_ignore(struct MidiBuffer *mb, int length); 30 + extern int line6_midibuf_init(struct MidiBuffer *mb, int size, int split); 31 + extern int line6_midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length); 32 + extern void line6_midibuf_reset(struct MidiBuffer *mb); 33 + extern int line6_midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask); 34 + extern void line6_midibuf_status(struct MidiBuffer *mb); 35 + extern int line6_midibuf_write(struct MidiBuffer *mb, unsigned char *data, 36 + int length); 37 37 38 38 39 39 #endif
+241 -35
drivers/staging/line6/pcm.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 12 #include <linux/slab.h> 15 - 16 13 #include <sound/core.h> 17 14 #include <sound/control.h> 18 15 #include <sound/pcm.h> ··· 17 20 18 21 #include "audio.h" 19 22 #include "capture.h" 23 + #include "driver.h" 20 24 #include "playback.h" 21 25 #include "pod.h" 22 26 27 + 28 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 29 + 30 + static struct snd_line6_pcm* dev2pcm(struct device *dev) 31 + { 32 + struct usb_interface *interface = to_usb_interface(dev); 33 + struct usb_line6 *line6 = usb_get_intfdata(interface); 34 + struct snd_line6_pcm *line6pcm = line6->line6pcm; 35 + return line6pcm; 36 + } 37 + 38 + /* 39 + "read" request on "impulse_volume" special file. 40 + */ 41 + static ssize_t pcm_get_impulse_volume(struct device *dev, 42 + struct device_attribute *attr, 43 + char *buf) 44 + { 45 + return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume); 46 + } 47 + 48 + /* 49 + "write" request on "impulse_volume" special file. 50 + */ 51 + static ssize_t pcm_set_impulse_volume(struct device *dev, 52 + struct device_attribute *attr, 53 + const char *buf, size_t count) 54 + { 55 + struct snd_line6_pcm *line6pcm = dev2pcm(dev); 56 + int value = simple_strtoul(buf, NULL, 10); 57 + line6pcm->impulse_volume = value; 58 + 59 + if(value > 0) 60 + line6_pcm_start(line6pcm, MASK_PCM_IMPULSE); 61 + else 62 + line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE); 63 + 64 + return count; 65 + } 66 + 67 + /* 68 + "read" request on "impulse_period" special file. 69 + */ 70 + static ssize_t pcm_get_impulse_period(struct device *dev, 71 + struct device_attribute *attr, 72 + char *buf) 73 + { 74 + return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period); 75 + } 76 + 77 + /* 78 + "write" request on "impulse_period" special file. 79 + */ 80 + static ssize_t pcm_set_impulse_period(struct device *dev, 81 + struct device_attribute *attr, 82 + const char *buf, size_t count) 83 + { 84 + dev2pcm(dev)->impulse_period = simple_strtoul(buf, NULL, 10); 85 + return count; 86 + } 87 + 88 + static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume, pcm_set_impulse_volume); 89 + static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period, pcm_set_impulse_period); 90 + 91 + #endif 92 + 93 + int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels) 94 + { 95 + unsigned long flags_old = __sync_fetch_and_or(&line6pcm->flags, channels); 96 + unsigned long flags_new = flags_old | channels; 97 + int err = 0; 98 + 99 + #if LINE6_BACKUP_MONITOR_SIGNAL 100 + if (!(line6pcm->line6->properties->capabilities & LINE6_BIT_HWMON)) { 101 + line6pcm->prev_fbuf = kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL); 102 + 103 + if (!line6pcm->prev_fbuf) { 104 + dev_err(line6pcm->line6->ifcdev, "cannot malloc monitor buffer\n"); 105 + return -ENOMEM; 106 + } 107 + } 108 + #else 109 + line6pcm->prev_fbuf = NULL; 110 + #endif 111 + 112 + if (((flags_old & MASK_CAPTURE) == 0) && 113 + ((flags_new & MASK_CAPTURE) != 0)) { 114 + /* 115 + Waiting for completion of active URBs in the stop handler is 116 + a bug, we therefore report an error if capturing is restarted 117 + too soon. 118 + */ 119 + if(line6pcm->active_urb_in | line6pcm->unlink_urb_in) 120 + return -EBUSY; 121 + 122 + line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL); 123 + 124 + if (!line6pcm->buffer_in) { 125 + dev_err(line6pcm->line6->ifcdev, "cannot malloc capture buffer\n"); 126 + return -ENOMEM; 127 + } 128 + 129 + line6pcm->count_in = 0; 130 + line6pcm->prev_fsize = 0; 131 + err = line6_submit_audio_in_all_urbs(line6pcm); 132 + 133 + if (err < 0) { 134 + __sync_fetch_and_and(&line6pcm->flags, ~channels); 135 + return err; 136 + } 137 + } 138 + 139 + if (((flags_old & MASK_PLAYBACK) == 0) && 140 + ((flags_new & MASK_PLAYBACK) != 0)) { 141 + /* 142 + See comment above regarding PCM restart. 143 + */ 144 + if(line6pcm->active_urb_out | line6pcm->unlink_urb_out) 145 + return -EBUSY; 146 + 147 + line6pcm->buffer_out = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL); 148 + 149 + if (!line6pcm->buffer_out) { 150 + dev_err(line6pcm->line6->ifcdev, "cannot malloc playback buffer\n"); 151 + return -ENOMEM; 152 + } 153 + 154 + line6pcm->count_out = 0; 155 + err = line6_submit_audio_out_all_urbs(line6pcm); 156 + 157 + if (err < 0) { 158 + __sync_fetch_and_and(&line6pcm->flags, ~channels); 159 + return err; 160 + } 161 + } 162 + 163 + return 0; 164 + } 165 + 166 + int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels) 167 + { 168 + unsigned long flags_old = __sync_fetch_and_and(&line6pcm->flags, ~channels); 169 + unsigned long flags_new = flags_old & ~channels; 170 + 171 + if (((flags_old & MASK_CAPTURE) != 0) && 172 + ((flags_new & MASK_CAPTURE) == 0)) { 173 + line6_unlink_audio_in_urbs(line6pcm); 174 + kfree(line6pcm->buffer_in); 175 + line6pcm->buffer_in = NULL; 176 + } 177 + 178 + if (((flags_old & MASK_PLAYBACK) != 0) && 179 + ((flags_new & MASK_PLAYBACK) == 0)) { 180 + line6_unlink_audio_out_urbs(line6pcm); 181 + kfree(line6pcm->buffer_out); 182 + line6pcm->buffer_out = NULL; 183 + } 184 + 185 + #if LINE6_BACKUP_MONITOR_SIGNAL 186 + if (line6pcm->prev_fbuf != NULL) 187 + kfree(line6pcm->prev_fbuf); 188 + #endif 189 + 190 + return 0; 191 + } 23 192 24 193 /* trigger callback */ 25 194 int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) ··· 201 38 snd_pcm_group_for_each_entry(s, substream) { 202 39 switch (s->stream) { 203 40 case SNDRV_PCM_STREAM_PLAYBACK: 204 - err = snd_line6_playback_trigger(s, cmd); 41 + err = snd_line6_playback_trigger(line6pcm, cmd); 205 42 206 43 if (err < 0) { 207 44 spin_unlock_irqrestore(&line6pcm->lock_trigger, ··· 212 49 break; 213 50 214 51 case SNDRV_PCM_STREAM_CAPTURE: 215 - err = snd_line6_capture_trigger(s, cmd); 52 + err = snd_line6_capture_trigger(line6pcm, cmd); 216 53 217 54 if (err < 0) { 218 55 spin_unlock_irqrestore(&line6pcm->lock_trigger, ··· 223 60 break; 224 61 225 62 default: 226 - dev_err(s2m(substream), "Unknown stream direction %d\n", 63 + dev_err(line6pcm->line6->ifcdev, "Unknown stream direction %d\n", 227 64 s->stream); 228 65 } 229 66 } ··· 233 70 } 234 71 235 72 /* control info callback */ 236 - static int snd_line6_control_info(struct snd_kcontrol *kcontrol, 237 - struct snd_ctl_elem_info *uinfo) 73 + static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol, 74 + struct snd_ctl_elem_info *uinfo) 238 75 { 239 76 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 240 77 uinfo->count = 2; ··· 244 81 } 245 82 246 83 /* control get callback */ 247 - static int snd_line6_control_get(struct snd_kcontrol *kcontrol, 248 - struct snd_ctl_elem_value *ucontrol) 84 + static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol, 85 + struct snd_ctl_elem_value *ucontrol) 249 86 { 250 87 int i; 251 88 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 252 89 253 90 for (i = 2; i--;) 254 - ucontrol->value.integer.value[i] = line6pcm->volume[i]; 91 + ucontrol->value.integer.value[i] = line6pcm->volume_playback[i]; 255 92 256 93 return 0; 257 94 } 258 95 259 96 /* control put callback */ 260 - static int snd_line6_control_put(struct snd_kcontrol *kcontrol, 261 - struct snd_ctl_elem_value *ucontrol) 97 + static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol, 98 + struct snd_ctl_elem_value *ucontrol) 262 99 { 263 100 int i, changed = 0; 264 101 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 265 102 266 103 for (i = 2; i--;) 267 - if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) { 268 - line6pcm->volume[i] = ucontrol->value.integer.value[i]; 104 + if (line6pcm->volume_playback[i] != ucontrol->value.integer.value[i]) { 105 + line6pcm->volume_playback[i] = ucontrol->value.integer.value[i]; 269 106 changed = 1; 270 107 } 271 108 ··· 273 110 } 274 111 275 112 /* control definition */ 276 - static struct snd_kcontrol_new line6_control = { 113 + static struct snd_kcontrol_new line6_control_playback = { 277 114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 278 115 .name = "PCM Playback Volume", 279 116 .index = 0, 280 117 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 281 - .info = snd_line6_control_info, 282 - .get = snd_line6_control_get, 283 - .put = snd_line6_control_put 118 + .info = snd_line6_control_playback_info, 119 + .get = snd_line6_control_playback_get, 120 + .put = snd_line6_control_playback_put 284 121 }; 285 122 286 123 /* ··· 290 127 { 291 128 int i; 292 129 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); 130 + 131 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 132 + device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_volume); 133 + device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_period); 134 + #endif 293 135 294 136 for (i = LINE6_ISO_BUFFERS; i--;) { 295 137 if (line6pcm->urb_audio_out[i]) { ··· 328 160 /* set operators */ 329 161 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 330 162 &snd_line6_playback_ops); 331 - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops); 163 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 164 + &snd_line6_capture_ops); 332 165 333 166 /* pre-allocation of buffers */ 334 167 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, ··· 343 174 static int snd_line6_pcm_free(struct snd_device *device) 344 175 { 345 176 return 0; 177 + } 178 + 179 + /* 180 + Stop substream if still running. 181 + */ 182 + static void pcm_disconnect_substream(struct snd_pcm_substream *substream) 183 + { 184 + if(substream->runtime && snd_pcm_running(substream)) { 185 + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); 186 + } 187 + } 188 + 189 + /* 190 + Stop PCM stream. 191 + */ 192 + void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) 193 + { 194 + pcm_disconnect_substream(get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE)); 195 + pcm_disconnect_substream(get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)); 196 + line6_unlink_wait_clear_audio_out_urbs(line6pcm); 197 + line6_unlink_wait_clear_audio_in_urbs(line6pcm); 346 198 } 347 199 348 200 /* ··· 408 218 break; 409 219 410 220 case LINE6_DEVID_GUITARPORT: 221 + case LINE6_DEVID_PODSTUDIO_GX: 222 + case LINE6_DEVID_PODSTUDIO_UX1: 223 + case LINE6_DEVID_PODSTUDIO_UX2: 411 224 case LINE6_DEVID_TONEPORT_GX: 225 + case LINE6_DEVID_TONEPORT_UX1: 226 + case LINE6_DEVID_TONEPORT_UX2: 412 227 ep_read = 0x82; 413 228 ep_write = 0x01; 414 229 break; 415 230 416 - case LINE6_DEVID_TONEPORT_UX1: 417 - ep_read = 0x00; 418 - ep_write = 0x00; 419 - break; 420 - 231 + /* this is for interface_number == 1: 421 232 case LINE6_DEVID_TONEPORT_UX2: 233 + case LINE6_DEVID_PODSTUDIO_UX2: 422 234 ep_read = 0x87; 423 235 ep_write = 0x00; 424 236 break; 237 + */ 425 238 426 239 default: 427 240 MISSING_CASE; ··· 435 242 if (line6pcm == NULL) 436 243 return -ENOMEM; 437 244 438 - line6pcm->volume[0] = line6pcm->volume[1] = 128; 245 + line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; 246 + line6pcm->volume_monitor = 255; 439 247 line6pcm->line6 = line6; 440 248 line6pcm->ep_audio_read = ep_read; 441 249 line6pcm->ep_audio_write = ep_write; 442 250 line6pcm->max_packet_size = usb_maxpacket(line6->usbdev, 443 - usb_rcvintpipe(line6->usbdev, 251 + usb_rcvintpipe(line6->usbdev, 444 252 ep_read), 445 253 0); 446 254 line6pcm->properties = properties; ··· 462 268 spin_lock_init(&line6pcm->lock_audio_in); 463 269 spin_lock_init(&line6pcm->lock_trigger); 464 270 465 - err = create_audio_out_urbs(line6pcm); 271 + err = line6_create_audio_out_urbs(line6pcm); 466 272 if (err < 0) 467 273 return err; 468 274 469 - err = create_audio_in_urbs(line6pcm); 275 + err = line6_create_audio_in_urbs(line6pcm); 470 276 if (err < 0) 471 277 return err; 472 278 473 279 /* mixer: */ 474 - err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm)); 280 + err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control_playback, line6pcm)); 475 281 if (err < 0) 476 282 return err; 283 + 284 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 285 + /* impulse response test: */ 286 + err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume); 287 + if (err < 0) 288 + return err; 289 + 290 + err = device_create_file(line6->ifcdev, &dev_attr_impulse_period); 291 + if (err < 0) 292 + return err; 293 + 294 + line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; 295 + #endif 477 296 478 297 return 0; 479 298 } ··· 497 290 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 498 291 499 292 if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) { 500 - unlink_wait_clear_audio_out_urbs(line6pcm); 293 + line6pcm->count_out = 0; 501 294 line6pcm->pos_out = 0; 502 295 line6pcm->pos_out_done = 0; 503 - 504 - unlink_wait_clear_audio_in_urbs(line6pcm); 505 296 line6pcm->bytes_out = 0; 297 + line6pcm->count_in = 0; 506 298 line6pcm->pos_in_done = 0; 507 299 line6pcm->bytes_in = 0; 508 300 }
+119 -16
drivers/staging/line6/pcm.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 24 24 25 25 26 26 /* number of URBs */ 27 - #define LINE6_ISO_BUFFERS 8 27 + #define LINE6_ISO_BUFFERS 2 28 28 29 - /* number of USB frames per URB */ 30 - #define LINE6_ISO_PACKETS 2 29 + /* 30 + number of USB frames per URB 31 + The Line6 Windows driver always transmits two frames per packet, but 32 + the Linux driver performs significantly better (i.e., lower latency) 33 + with only one frame per packet. 34 + */ 35 + #define LINE6_ISO_PACKETS 1 31 36 32 37 /* in a "full speed" device (such as the PODxt Pro) this means 1ms */ 33 38 #define LINE6_ISO_INTERVAL 1 34 39 35 - /* this should be queried dynamically from the USB interface! */ 36 - #define LINE6_ISO_PACKET_SIZE_MAX 252 40 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 41 + #define LINE6_IMPULSE_DEFAULT_PERIOD 100 42 + #endif 43 + 44 + #define LINE6_BACKUP_MONITOR_SIGNAL 0 45 + #define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0 37 46 38 47 39 48 /* 40 - Extract the messaging device from the substream instance 49 + Get substream from Line6 PCM data structure 41 50 */ 42 - #define s2m(s) (((struct snd_line6_pcm *) \ 43 - snd_pcm_substream_chip(s))->line6->ifcdev) 51 + #define get_substream(line6pcm, stream) (line6pcm->pcm->streams[stream].substream) 44 52 45 53 54 + /* 55 + PCM mode bits and masks. 56 + "ALSA": operations triggered by applications via ALSA 57 + "MONITOR": software monitoring 58 + "IMPULSE": optional impulse response operation 59 + */ 46 60 enum { 47 - BIT_RUNNING_PLAYBACK, 48 - BIT_RUNNING_CAPTURE, 61 + /* individual bits: */ 62 + BIT_PCM_ALSA_PLAYBACK, 63 + BIT_PCM_ALSA_CAPTURE, 64 + BIT_PCM_MONITOR_PLAYBACK, 65 + BIT_PCM_MONITOR_CAPTURE, 66 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 67 + BIT_PCM_IMPULSE_PLAYBACK, 68 + BIT_PCM_IMPULSE_CAPTURE, 69 + #endif 49 70 BIT_PAUSE_PLAYBACK, 50 - BIT_PREPARED 71 + BIT_PREPARED, 72 + 73 + /* individual masks: */ 74 + MASK_PCM_ALSA_PLAYBACK = 1 << BIT_PCM_ALSA_PLAYBACK, 75 + MASK_PCM_ALSA_CAPTURE = 1 << BIT_PCM_ALSA_CAPTURE, 76 + MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK, 77 + MASK_PCM_MONITOR_CAPTURE = 1 << BIT_PCM_MONITOR_CAPTURE, 78 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 79 + MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK, 80 + MASK_PCM_IMPULSE_CAPTURE = 1 << BIT_PCM_IMPULSE_CAPTURE, 81 + #endif 82 + MASK_PAUSE_PLAYBACK = 1 << BIT_PAUSE_PLAYBACK, 83 + MASK_PREPARED = 1 << BIT_PREPARED, 84 + 85 + /* combined masks (by operation): */ 86 + MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE, 87 + MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE, 88 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 89 + MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE, 90 + #endif 91 + 92 + /* combined masks (by direction): */ 93 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 94 + MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_IMPULSE_PLAYBACK, 95 + MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE | MASK_PCM_IMPULSE_CAPTURE 96 + #else 97 + MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK, 98 + MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE 99 + #endif 51 100 }; 52 101 53 102 struct line6_pcm_properties { ··· 132 83 struct urb *urb_audio_in[LINE6_ISO_BUFFERS]; 133 84 134 85 /** 135 - Temporary buffer to hold data when playback buffer wraps. 86 + Temporary buffer for playback. 87 + Since the packet size is not known in advance, this buffer is 88 + large enough to store maximum size packets. 136 89 */ 137 - unsigned char *wrap_out; 90 + unsigned char *buffer_out; 138 91 139 92 /** 140 93 Temporary buffer for capture. ··· 144 93 large enough to store maximum size packets. 145 94 */ 146 95 unsigned char *buffer_in; 96 + 97 + /** 98 + Temporary buffer index for playback. 99 + */ 100 + int index_out; 101 + 102 + /** 103 + Previously captured frame (for software monitoring). 104 + */ 105 + unsigned char *prev_fbuf; 106 + 107 + /** 108 + Size of previously captured frame (for software monitoring). 109 + */ 110 + int prev_fsize; 147 111 148 112 /** 149 113 Free frame position in the playback buffer. ··· 270 204 /** 271 205 PCM playback volume (left and right). 272 206 */ 273 - int volume[2]; 207 + int volume_playback[2]; 208 + 209 + /** 210 + PCM monitor volume. 211 + */ 212 + int volume_monitor; 213 + 214 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 215 + /** 216 + Volume of impulse response test signal (if zero, test is disabled). 217 + */ 218 + int impulse_volume; 219 + 220 + /** 221 + Period of impulse response test signal. 222 + */ 223 + int impulse_period; 224 + 225 + /** 226 + Counter for impulse response test signal. 227 + */ 228 + int impulse_count; 229 + #endif 274 230 275 231 /** 276 232 Several status bits (see BIT_*). 277 233 */ 278 234 unsigned long flags; 235 + 236 + int last_frame_in, last_frame_out; 279 237 }; 280 238 281 239 ··· 307 217 struct line6_pcm_properties *properties); 308 218 extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); 309 219 extern int snd_line6_prepare(struct snd_pcm_substream *substream); 220 + extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); 221 + extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels); 222 + extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels); 223 + 224 + 225 + #define PRINT_FRAME_DIFF(op) { \ 226 + static int diff_prev = 1000; \ 227 + int diff = line6pcm->last_frame_out - line6pcm->last_frame_in; \ 228 + if((diff != diff_prev) && (abs(diff) < 100)) { \ 229 + printk("%s frame diff = %d\n", op, diff); \ 230 + diff_prev = diff; \ 231 + } \ 232 + } 310 233 311 234 312 235 #endif
+206 -96
drivers/staging/line6/playback.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 - #include <linux/slab.h> 15 - 16 12 #include <sound/core.h> 17 13 #include <sound/pcm.h> 18 14 #include <sound/pcm_params.h> 19 15 20 16 #include "audio.h" 17 + #include "capture.h" 18 + #include "driver.h" 21 19 #include "pcm.h" 22 20 #include "pod.h" 23 21 #include "playback.h" ··· 57 59 } 58 60 } 59 61 62 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 63 + 64 + /* 65 + Create signal for impulse response test. 66 + */ 67 + static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm, 68 + struct urb *urb_out, int bytes_per_frame) 69 + { 70 + int frames = urb_out->transfer_buffer_length / bytes_per_frame; 71 + 72 + if (bytes_per_frame == 4) { 73 + /* TODO: add code for TonePort etc. */ 74 + } else if (bytes_per_frame == 6) { 75 + int i, j; 76 + unsigned char *pi = line6pcm->prev_fbuf; 77 + unsigned char *po = urb_out->transfer_buffer; 78 + 79 + for (i = 0; i < frames; ++i) { 80 + for (j = 0; j < bytes_per_frame / 2; ++j) 81 + po[j] = pi[j]; 82 + 83 + for (; j < bytes_per_frame; ++j) 84 + po[j] = 0; 85 + 86 + pi += bytes_per_frame; 87 + po += bytes_per_frame; 88 + } 89 + 90 + if (--line6pcm->impulse_count <= 0) { 91 + ((unsigned char *)(urb_out-> 92 + transfer_buffer))[bytes_per_frame - 93 + 1] = 94 + line6pcm->impulse_volume; 95 + line6pcm->impulse_count = line6pcm->impulse_period; 96 + } 97 + } 98 + } 99 + 100 + #endif 101 + 102 + /* 103 + Add signal to buffer for software monitoring. 104 + */ 105 + static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, 106 + int volume, int bytes_per_frame) 107 + { 108 + if (volume == 0) 109 + return; /* zero volume - no change */ 110 + 111 + if (bytes_per_frame == 4) { 112 + short *pi, *po, *buf_end; 113 + pi = (short *)signal; 114 + po = (short *)urb_out->transfer_buffer; 115 + buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); 116 + 117 + for (; po < buf_end; ++pi, ++po) 118 + *po += (*pi * volume) >> 8; 119 + } 120 + 121 + /* 122 + We don't need to handle devices with 6 bytes per frame here 123 + since they all support hardware monitoring. 124 + */ 125 + } 126 + 60 127 /* 61 128 Find a free URB, prepare audio data, and submit URB. 62 129 */ 63 - static int submit_audio_out_urb(struct snd_pcm_substream *substream) 130 + static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) 64 131 { 65 132 int index; 66 133 unsigned long flags; 67 134 int i, urb_size, urb_frames; 68 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 69 135 const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 70 136 const int frame_increment = 71 137 line6pcm->properties->snd_line6_rates.rats[0].num_min; 72 138 const int frame_factor = 73 139 line6pcm->properties->snd_line6_rates.rats[0].den * 74 140 (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); 75 - struct snd_pcm_runtime *runtime = substream->runtime; 76 141 struct urb *urb_out; 77 142 78 143 spin_lock_irqsave(&line6pcm->lock_audio_out, flags); ··· 144 83 145 84 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 146 85 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 147 - dev_err(s2m(substream), "no free URB found\n"); 86 + dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 148 87 return -EINVAL; 149 88 } 150 89 ··· 153 92 154 93 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 155 94 /* compute frame size for given sampling rate */ 156 - int n, fs; 95 + int fsize = 0; 157 96 struct usb_iso_packet_descriptor *fout = 158 97 &urb_out->iso_frame_desc[i]; 159 - line6pcm->count_out += frame_increment; 160 - n = line6pcm->count_out / frame_factor; 161 - line6pcm->count_out -= n * frame_factor; 162 - fs = n * bytes_per_frame; 98 + 99 + if (line6pcm->flags & MASK_CAPTURE) { 100 + fsize = line6pcm->prev_fsize; 101 + } 102 + 103 + if (fsize == 0) { 104 + int n; 105 + line6pcm->count_out += frame_increment; 106 + n = line6pcm->count_out / frame_factor; 107 + line6pcm->count_out -= n * frame_factor; 108 + fsize = n * bytes_per_frame; 109 + } 110 + 163 111 fout->offset = urb_size; 164 - fout->length = fs; 165 - urb_size += fs; 112 + fout->length = fsize; 113 + urb_size += fsize; 114 + } 115 + 116 + if (urb_size == 0) { 117 + /* can't determine URB size */ 118 + spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 119 + dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); /* this is somewhat paranoid */ 120 + return -EINVAL; 166 121 } 167 122 168 123 urb_frames = urb_size / bytes_per_frame; 124 + urb_out->transfer_buffer = 125 + line6pcm->buffer_out + 126 + line6pcm->max_packet_size * line6pcm->index_out; 127 + urb_out->transfer_buffer_length = urb_size; 128 + urb_out->context = line6pcm; 169 129 170 - if (test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) { 171 - urb_out->transfer_buffer = line6pcm->wrap_out; 172 - memset(line6pcm->wrap_out, 0, urb_size); 173 - } else { 130 + if (++line6pcm->index_out == LINE6_ISO_BUFFERS) 131 + line6pcm->index_out = 0; 132 + 133 + if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) && 134 + !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) { 135 + struct snd_pcm_runtime *runtime = 136 + get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; 137 + 174 138 if (line6pcm->pos_out + urb_frames > runtime->buffer_size) { 175 139 /* 176 140 The transferred area goes over buffer boundary, ··· 203 117 */ 204 118 int len; 205 119 len = runtime->buffer_size - line6pcm->pos_out; 206 - urb_out->transfer_buffer = line6pcm->wrap_out; 207 120 208 121 if (len > 0) { 209 - memcpy(line6pcm->wrap_out, 122 + memcpy(urb_out->transfer_buffer, 210 123 runtime->dma_area + 211 124 line6pcm->pos_out * bytes_per_frame, 212 125 len * bytes_per_frame); 213 - memcpy(line6pcm->wrap_out + 126 + memcpy(urb_out->transfer_buffer + 214 127 len * bytes_per_frame, runtime->dma_area, 215 128 (urb_frames - len) * bytes_per_frame); 216 - } else { 217 - /* this is somewhat paranoid */ 218 - dev_err(s2m(substream), 219 - "driver bug: len = %d\n", len); 220 - } 129 + } else 130 + dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */ 221 131 } else { 132 + #if LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 222 133 /* set the buffer pointer */ 223 134 urb_out->transfer_buffer = 224 135 runtime->dma_area + 225 136 line6pcm->pos_out * bytes_per_frame; 137 + #else 138 + /* copy data */ 139 + memcpy(urb_out->transfer_buffer, 140 + runtime->dma_area + 141 + line6pcm->pos_out * bytes_per_frame, 142 + urb_out->transfer_buffer_length); 143 + #endif 226 144 } 145 + 146 + if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size) 147 + line6pcm->pos_out -= runtime->buffer_size; 148 + } else { 149 + memset(urb_out->transfer_buffer, 0, 150 + urb_out->transfer_buffer_length); 227 151 } 228 152 229 - line6pcm->pos_out += urb_frames; 230 - if (line6pcm->pos_out >= runtime->buffer_size) 231 - line6pcm->pos_out -= runtime->buffer_size; 153 + change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame); 232 154 233 - urb_out->transfer_buffer_length = urb_size; 234 - urb_out->context = substream; 235 - change_volume(urb_out, line6pcm->volume, bytes_per_frame); 236 - 237 - #if DO_DUMP_PCM_SEND 155 + if (line6pcm->prev_fbuf != 0) { 156 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 157 + if (line6pcm->flags & MASK_PCM_IMPULSE) { 158 + create_impulse_test_signal(line6pcm, urb_out, 159 + bytes_per_frame); 160 + if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) { 161 + line6_capture_copy(line6pcm, urb_out->transfer_buffer, 162 + urb_out->transfer_buffer_length); 163 + } 164 + } else { 165 + #endif 166 + if (! 167 + (line6pcm->line6->properties-> 168 + capabilities & LINE6_BIT_HWMON) 169 + && (line6pcm->flags & MASK_PLAYBACK) 170 + && (line6pcm->flags & MASK_CAPTURE)) 171 + add_monitor_signal(urb_out, line6pcm->prev_fbuf, 172 + line6pcm->volume_monitor, 173 + bytes_per_frame); 174 + #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 175 + } 176 + #endif 177 + } 178 + #ifdef CONFIG_LINE6_USB_DUMP_PCM 238 179 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 239 180 struct usb_iso_packet_descriptor *fout = 240 181 &urb_out->iso_frame_desc[i]; ··· 274 161 if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0) 275 162 set_bit(index, &line6pcm->active_urb_out); 276 163 else 277 - dev_err(s2m(substream), "URB out #%d submission failed\n", 278 - index); 164 + dev_err(line6pcm->line6->ifcdev, 165 + "URB out #%d submission failed\n", index); 279 166 280 167 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 281 168 return 0; ··· 284 171 /* 285 172 Submit all currently available playback URBs. 286 173 */ 287 - static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream) 174 + int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) 288 175 { 289 176 int ret, i; 290 177 291 178 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 292 - ret = submit_audio_out_urb(substream); 179 + ret = submit_audio_out_urb(line6pcm); 293 180 if (ret < 0) 294 181 return ret; 295 182 } ··· 300 187 /* 301 188 Unlink all currently active playback URBs. 302 189 */ 303 - static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) 190 + void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) 304 191 { 305 192 unsigned int i; 306 193 ··· 315 202 } 316 203 317 204 /* 318 - Wait until unlinking of all currently active playback URBs has been finished. 205 + Wait until unlinking of all currently active playback URBs has been finished. 319 206 */ 320 207 static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) 321 208 { ··· 336 223 } while (--timeout > 0); 337 224 if (alive) 338 225 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); 339 - 340 - line6pcm->active_urb_out = 0; 341 - line6pcm->unlink_urb_out = 0; 342 226 } 343 227 344 228 /* 345 229 Unlink all currently active playback URBs, and wait for finishing. 346 230 */ 347 - void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) 231 + void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) 348 232 { 349 - unlink_audio_out_urbs(line6pcm); 233 + line6_unlink_audio_out_urbs(line6pcm); 350 234 wait_clear_audio_out_urbs(line6pcm); 351 235 } 352 236 ··· 355 245 int i, index, length = 0, shutdown = 0; 356 246 unsigned long flags; 357 247 248 + struct snd_line6_pcm *line6pcm = 249 + (struct snd_line6_pcm *)urb->context; 358 250 struct snd_pcm_substream *substream = 359 - (struct snd_pcm_substream *)urb->context; 360 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 361 - struct snd_pcm_runtime *runtime = substream->runtime; 251 + get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); 252 + 253 + #if USE_CLEAR_BUFFER_WORKAROUND 254 + memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 255 + #endif 256 + 257 + line6pcm->last_frame_out = urb->start_frame; 362 258 363 259 /* find index of URB */ 364 260 for (index = LINE6_ISO_BUFFERS; index--;) ··· 378 262 length += urb->iso_frame_desc[i].length; 379 263 380 264 spin_lock_irqsave(&line6pcm->lock_audio_out, flags); 381 - line6pcm->pos_out_done += 382 - length / line6pcm->properties->bytes_per_frame; 383 265 384 - if (line6pcm->pos_out_done >= runtime->buffer_size) 385 - line6pcm->pos_out_done -= runtime->buffer_size; 266 + if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { 267 + struct snd_pcm_runtime *runtime = substream->runtime; 268 + line6pcm->pos_out_done += 269 + length / line6pcm->properties->bytes_per_frame; 270 + 271 + if (line6pcm->pos_out_done >= runtime->buffer_size) 272 + line6pcm->pos_out_done -= runtime->buffer_size; 273 + } 386 274 387 275 clear_bit(index, &line6pcm->active_urb_out); 388 276 ··· 396 276 break; 397 277 } 398 278 399 - if (test_bit(index, &line6pcm->unlink_urb_out)) 279 + if (test_and_clear_bit(index, &line6pcm->unlink_urb_out)) 400 280 shutdown = 1; 401 281 402 282 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 403 283 404 284 if (!shutdown) { 405 - submit_audio_out_urb(substream); 285 + submit_audio_out_urb(line6pcm); 406 286 407 - line6pcm->bytes_out += length; 408 - if (line6pcm->bytes_out >= line6pcm->period_out) { 409 - line6pcm->bytes_out -= line6pcm->period_out; 410 - snd_pcm_period_elapsed(substream); 287 + if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { 288 + if ((line6pcm->bytes_out += 289 + length) >= line6pcm->period_out) { 290 + line6pcm->bytes_out %= line6pcm->period_out; 291 + snd_pcm_period_elapsed(substream); 292 + } 411 293 } 412 294 } 413 295 } ··· 462 340 return ret; 463 341 464 342 line6pcm->period_out = params_period_bytes(hw_params); 465 - line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL); 466 - 467 - if (!line6pcm->wrap_out) { 468 - dev_err(s2m(substream), "cannot malloc wrap_out\n"); 469 - return -ENOMEM; 470 - } 471 - 472 343 return 0; 473 344 } 474 345 475 346 /* hw_free playback callback */ 476 347 static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream) 477 348 { 478 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 479 - unlink_wait_clear_audio_out_urbs(line6pcm); 480 - 481 - kfree(line6pcm->wrap_out); 482 - line6pcm->wrap_out = NULL; 483 - 484 349 return snd_pcm_lib_free_pages(substream); 485 350 } 486 351 487 352 /* trigger playback callback */ 488 - int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd) 353 + int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) 489 354 { 490 - struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 491 355 int err; 492 - line6pcm->count_out = 0; 493 356 494 357 switch (cmd) { 495 358 case SNDRV_PCM_TRIGGER_START: 496 - if (!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) { 497 - err = submit_audio_out_all_urbs(substream); 359 + #ifdef CONFIG_PM 360 + case SNDRV_PCM_TRIGGER_RESUME: 361 + #endif 362 + err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK); 498 363 499 - if (err < 0) { 500 - clear_bit(BIT_RUNNING_PLAYBACK, 501 - &line6pcm->flags); 502 - return err; 503 - } 504 - } 364 + if (err < 0) 365 + return err; 505 366 506 367 break; 507 368 508 369 case SNDRV_PCM_TRIGGER_STOP: 509 - if (test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) 510 - unlink_audio_out_urbs(line6pcm); 370 + #ifdef CONFIG_PM 371 + case SNDRV_PCM_TRIGGER_SUSPEND: 372 + #endif 373 + err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK); 374 + 375 + if (err < 0) 376 + return err; 511 377 512 378 break; 513 379 ··· 524 414 525 415 /* playback operators */ 526 416 struct snd_pcm_ops snd_line6_playback_ops = { 527 - .open = snd_line6_playback_open, 528 - .close = snd_line6_playback_close, 529 - .ioctl = snd_pcm_lib_ioctl, 530 - .hw_params = snd_line6_playback_hw_params, 531 - .hw_free = snd_line6_playback_hw_free, 532 - .prepare = snd_line6_prepare, 533 - .trigger = snd_line6_trigger, 534 - .pointer = snd_line6_playback_pointer, 417 + .open = snd_line6_playback_open, 418 + .close = snd_line6_playback_close, 419 + .ioctl = snd_pcm_lib_ioctl, 420 + .hw_params = snd_line6_playback_hw_params, 421 + .hw_free = snd_line6_playback_hw_free, 422 + .prepare = snd_line6_prepare, 423 + .trigger = snd_line6_trigger, 424 + .pointer = snd_line6_playback_pointer, 535 425 }; 536 426 537 - int create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 427 + int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 538 428 { 539 429 int i; 540 430
+20 -9
drivers/staging/line6/playback.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define PLAYBACK_H 14 14 15 15 16 + #include <sound/pcm.h> 17 + 16 18 #include "driver.h" 17 19 18 - #include <sound/pcm.h> 20 + 21 + /* 22 + When the TonePort is used with jack in full duplex mode and the outputs are 23 + not connected, the software monitor produces an ugly noise since everything 24 + written to the output buffer (i.e., the input signal) will be repeated in the 25 + next period (sounds like a delay effect). As a workaround, the output buffer 26 + is cleared after the data have been read, but there must be a better 27 + solution. Until one is found, this workaround can be used to fix the problem. 28 + */ 29 + #define USE_CLEAR_BUFFER_WORKAROUND 1 19 30 20 31 21 32 extern struct snd_pcm_ops snd_line6_playback_ops; 22 33 23 - 24 - extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm); 25 - extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream, 26 - int cmd); 27 - extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm); 28 - 34 + extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm); 35 + extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm); 36 + extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm); 37 + extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm 38 + *line6pcm); 39 + extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd); 29 40 30 41 #endif
+272 -204
drivers/staging/line6/pod.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 12 #include <linux/slab.h> 13 + #include <linux/wait.h> 14 + #include <sound/control.h> 15 15 16 16 #include "audio.h" 17 17 #include "capture.h" 18 18 #include "control.h" 19 + #include "driver.h" 19 20 #include "playback.h" 20 21 #include "pod.h" 21 22 ··· 46 45 POD_tuner_freq = 0x15, 47 46 POD_tuner_note = 0x16, 48 47 POD_tuner_pitch = 0x17, 49 - POD_system_invalid = 0x7fff 48 + POD_system_invalid = 0x10000 50 49 }; 51 50 52 51 enum { ··· 70 69 }; 71 70 72 71 static struct line6_pcm_properties pod_pcm_properties = { 73 - .snd_line6_playback_hw = { 72 + .snd_line6_playback_hw = { 74 73 .info = (SNDRV_PCM_INFO_MMAP | 75 - SNDRV_PCM_INFO_INTERLEAVED | 76 - SNDRV_PCM_INFO_BLOCK_TRANSFER | 77 - SNDRV_PCM_INFO_MMAP_VALID | 78 - SNDRV_PCM_INFO_PAUSE | 79 - SNDRV_PCM_INFO_SYNC_START), 74 + SNDRV_PCM_INFO_INTERLEAVED | 75 + SNDRV_PCM_INFO_BLOCK_TRANSFER | 76 + SNDRV_PCM_INFO_MMAP_VALID | 77 + SNDRV_PCM_INFO_PAUSE | 78 + #ifdef CONFIG_PM 79 + SNDRV_PCM_INFO_RESUME | 80 + #endif 81 + SNDRV_PCM_INFO_SYNC_START), 80 82 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 81 83 .rates = SNDRV_PCM_RATE_KNOT, 82 84 .rate_min = 39062, ··· 87 83 .channels_min = 2, 88 84 .channels_max = 2, 89 85 .buffer_bytes_max = 60000, 90 - .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */ 86 + .period_bytes_min = 64, 91 87 .period_bytes_max = 8192, 92 88 .periods_min = 1, 93 89 .periods_max = 1024 94 90 }, 95 - .snd_line6_capture_hw = { 91 + .snd_line6_capture_hw = { 96 92 .info = (SNDRV_PCM_INFO_MMAP | 97 - SNDRV_PCM_INFO_INTERLEAVED | 98 - SNDRV_PCM_INFO_BLOCK_TRANSFER | 99 - SNDRV_PCM_INFO_MMAP_VALID | 100 - SNDRV_PCM_INFO_SYNC_START), 93 + SNDRV_PCM_INFO_INTERLEAVED | 94 + SNDRV_PCM_INFO_BLOCK_TRANSFER | 95 + SNDRV_PCM_INFO_MMAP_VALID | 96 + #ifdef CONFIG_PM 97 + SNDRV_PCM_INFO_RESUME | 98 + #endif 99 + SNDRV_PCM_INFO_SYNC_START), 101 100 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 102 101 .rates = SNDRV_PCM_RATE_KNOT, 103 102 .rate_min = 39062, ··· 108 101 .channels_min = 2, 109 102 .channels_max = 2, 110 103 .buffer_bytes_max = 60000, 111 - .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */ 104 + .period_bytes_min = 64, 112 105 .period_bytes_max = 8192, 113 106 .periods_min = 1, 114 107 .periods_max = 1024 ··· 120 113 .bytes_per_frame = POD_BYTES_PER_FRAME 121 114 }; 122 115 123 - static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 }; 124 - static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 }; 125 - static const char pod_version_header[] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 }; 116 + static const char pod_request_channel[] = { 117 + 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 118 + }; 119 + 120 + static const char pod_version_header[] = { 121 + 0xf2, 0x7e, 0x7f, 0x06, 0x02 122 + }; 123 + 124 + 125 + /* forward declarations: */ 126 + static void pod_startup2(unsigned long data); 127 + static void pod_startup3(struct usb_line6_pod *pod); 128 + static void pod_startup4(struct usb_line6_pod *pod); 126 129 127 130 128 131 /* ··· 144 127 145 128 for (i = 0; i < POD_CONTROL_SIZE; i++) 146 129 set_bit(i, pod->param_dirty); 147 - } 148 - 149 - /* 150 - Send an asynchronous request for the POD firmware version and device ID. 151 - */ 152 - static int pod_version_request_async(struct usb_line6_pod *pod) 153 - { 154 - return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version)); 155 - } 156 - 157 - static void pod_create_files_work(struct work_struct *work) 158 - { 159 - struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work); 160 - 161 - pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev); 162 - } 163 - 164 - static void pod_startup_timeout(unsigned long arg) 165 - { 166 - enum { 167 - REQUEST_NONE, 168 - REQUEST_DUMP, 169 - REQUEST_VERSION 170 - }; 171 - 172 - int request = REQUEST_NONE; 173 - struct usb_line6_pod *pod = (struct usb_line6_pod *)arg; 174 - 175 - if (pod->dumpreq.ok) { 176 - if (!pod->versionreq_ok) 177 - request = REQUEST_VERSION; 178 - } else { 179 - if (pod->versionreq_ok) 180 - request = REQUEST_DUMP; 181 - else if (pod->startup_count++ & 1) 182 - request = REQUEST_DUMP; 183 - else 184 - request = REQUEST_VERSION; 185 - } 186 - 187 - switch (request) { 188 - case REQUEST_DUMP: 189 - line6_dump_request_async(&pod->dumpreq, &pod->line6, 0); 190 - break; 191 - 192 - case REQUEST_VERSION: 193 - pod_version_request_async(pod); 194 - break; 195 - 196 - default: 197 - return; 198 - } 199 - 200 - line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod); 201 130 } 202 131 203 132 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size) ··· 181 218 } 182 219 183 220 /* 184 - Handle SAVE button 221 + Handle SAVE button. 185 222 */ 186 223 static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index) 187 224 { ··· 192 229 /* 193 230 Process a completely received message. 194 231 */ 195 - void pod_process_message(struct usb_line6_pod *pod) 232 + void line6_pod_process_message(struct usb_line6_pod *pod) 196 233 { 197 234 const unsigned char *buf = pod->line6.buffer_message; 198 235 ··· 217 254 if ((buf[1] == POD_amp_model_setup) || 218 255 (buf[1] == POD_effect_setup)) 219 256 /* these also affect other settings */ 220 - line6_dump_request_async(&pod->dumpreq, &pod->line6, 0); 257 + line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT); 221 258 222 259 break; 223 260 ··· 226 263 pod->channel_num = buf[1]; 227 264 pod->dirty = 0; 228 265 set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags); 229 - line6_dump_request_async(&pod->dumpreq, &pod->line6, 0); 266 + line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT); 230 267 break; 231 268 232 269 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE: ··· 239 276 case LINE6_DUMP_CURRENT: 240 277 memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data)); 241 278 pod_mark_batch_all_dirty(pod); 242 - pod->dumpreq.ok = 1; 243 279 break; 244 280 245 281 case POD_DUMP_MEMORY: ··· 250 288 } 251 289 252 290 line6_dump_finished(&pod->dumpreq); 291 + pod_startup3(pod); 253 292 } else 254 293 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n", 255 294 pod->line6.message_length, (int)sizeof(pod->prog_data) + 7)); ··· 263 300 #define PROCESS_SYSTEM_PARAM(x) \ 264 301 case POD_ ## x: \ 265 302 pod->x.value = value; \ 266 - wake_up_interruptible(&pod->x.wait); \ 303 + wake_up(&pod->x.wait); \ 267 304 break; 268 305 269 306 switch (buf[6]) { ··· 294 331 case POD_SYSEX_CLIP: 295 332 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n")); 296 333 pod->clipping.value = 1; 297 - wake_up_interruptible(&pod->clipping.wait); 334 + wake_up(&pod->clipping.wait); 298 335 break; 299 336 300 337 case POD_SYSEX_STORE: ··· 305 342 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5])); 306 343 } 307 344 } else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { 308 - if (pod->versionreq_ok == 0) { 309 - pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; 310 - pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10]; 311 - pod->versionreq_ok = 1; 312 - 313 - /* Now we know the firmware version, so we schedule a bottom half 314 - handler to create the special files: */ 315 - INIT_WORK(&pod->create_files_work, pod_create_files_work); 316 - queue_work(line6_workqueue, &pod->create_files_work); 317 - } else 318 - DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n")); 345 + pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; 346 + pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10]; 347 + pod_startup4(pod); 319 348 } else 320 349 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n")); 321 350 ··· 332 377 *) This method fails if a param change message is "chopped" after the first 333 378 byte. 334 379 */ 335 - void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length) 380 + void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length) 336 381 { 337 382 int i; 338 383 ··· 367 412 /* 368 413 Transmit PODxt Pro control parameter. 369 414 */ 370 - void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value) 415 + void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value) 371 416 { 372 417 if (line6_transmit_parameter(&pod->line6, param, value) == 0) 373 418 pod_store_parameter(pod, param, value); ··· 466 511 char *p2; 467 512 char *last_non_space = buf; 468 513 469 - int retval = line6_wait_dump(&pod->dumpreq, 0); 514 + int retval = line6_dump_wait_interruptible(&pod->dumpreq); 470 515 if (retval < 0) 471 516 return retval; 472 517 ··· 543 588 { 544 589 struct usb_interface *interface = to_usb_interface(dev); 545 590 struct usb_line6_pod *pod = usb_get_intfdata(interface); 546 - int retval = line6_wait_dump(&pod->dumpreq, 0); 591 + int retval = line6_dump_wait_interruptible(&pod->dumpreq); 547 592 if (retval < 0) 548 593 return retval; 549 594 memcpy(buf, &pod->prog_data, sizeof(pod->prog_data)); ··· 561 606 562 607 if (count != sizeof(pod->prog_data)) { 563 608 dev_err(pod->line6.ifcdev, 564 - "data block must be exactly %zu bytes\n", 565 - sizeof(pod->prog_data)); 609 + "data block must be exactly %d bytes\n", 610 + (int)sizeof(pod->prog_data)); 566 611 return -EINVAL; 567 612 } 568 613 ··· 571 616 } 572 617 573 618 /* 574 - Request system parameter. 619 + Identify system parameters related to the tuner. 620 + */ 621 + static bool pod_is_tuner(int code) 622 + { 623 + return 624 + (code == POD_tuner_mute) || 625 + (code == POD_tuner_freq) || 626 + (code == POD_tuner_note) || 627 + (code == POD_tuner_pitch); 628 + } 629 + 630 + /* 631 + Get system parameter (as integer). 575 632 @param tuner non-zero, if code refers to a tuner parameter 576 633 */ 577 - static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign) 634 + static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value, int code, 635 + struct ValueWait *param, int sign) 578 636 { 579 637 char *sysex; 580 - int value; 581 638 static const int size = 1; 582 639 int retval = 0; 583 - DECLARE_WAITQUEUE(wait, current); 584 640 585 - if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner) 641 + if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && pod_is_tuner(code)) 586 642 return -ENODEV; 587 643 588 - /* send value request to tuner: */ 644 + /* send value request to device: */ 589 645 param->value = POD_system_invalid; 590 646 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size); 647 + 591 648 if (!sysex) 592 - return 0; 649 + return -ENOMEM; 650 + 593 651 sysex[SYSEX_DATA_OFS] = code; 594 652 line6_send_sysex_message(&pod->line6, sysex, size); 595 653 kfree(sysex); 596 654 597 - /* wait for tuner to respond: */ 598 - add_wait_queue(&param->wait, &wait); 599 - current->state = TASK_INTERRUPTIBLE; 600 - 601 - while (param->value == POD_system_invalid) { 602 - if (signal_pending(current)) { 603 - retval = -ERESTARTSYS; 604 - break; 605 - } else 606 - schedule(); 607 - } 608 - 609 - current->state = TASK_RUNNING; 610 - remove_wait_queue(&param->wait, &wait); 655 + /* wait for device to respond: */ 656 + retval = wait_event_interruptible(param->wait, param->value != POD_system_invalid); 611 657 612 658 if (retval < 0) 613 659 return retval; 614 660 615 - value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value; 661 + *value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value; 662 + 663 + if(*value == POD_system_invalid) 664 + *value = 0; /* don't report uninitialized values */ 665 + 666 + return 0; 667 + } 668 + 669 + /* 670 + Get system parameter (as string). 671 + @param tuner non-zero, if code refers to a tuner parameter 672 + */ 673 + static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf, int code, 674 + struct ValueWait *param, int sign) 675 + { 676 + int retval, value = 0; 677 + retval = pod_get_system_param_int(pod, &value, code, param, sign); 678 + 679 + if(retval < 0) 680 + return retval; 681 + 616 682 return sprintf(buf, "%d\n", value); 617 683 } 618 684 619 685 /* 620 - Send system parameter. 686 + Send system parameter (from integer). 621 687 @param tuner non-zero, if code refers to a tuner parameter 622 688 */ 623 - static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf, 624 - int count, int code, unsigned short mask, 625 - int tuner) 689 + static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, int code) 626 690 { 627 691 char *sysex; 628 692 static const int size = 5; 629 - unsigned short value; 630 - unsigned long result; 631 - int ret; 632 693 633 - if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner) 694 + if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && pod_is_tuner(code)) 634 695 return -EINVAL; 635 696 636 697 /* send value to tuner: */ 637 698 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size); 638 699 if (!sysex) 639 - return 0; 640 - 641 - ret = strict_strtoul(buf, 10, &result); 642 - if (ret) 643 - return ret; 644 - 645 - value = result & mask; 700 + return -ENOMEM; 646 701 sysex[SYSEX_DATA_OFS] = code; 647 702 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f; 648 703 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f; ··· 660 695 sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f; 661 696 line6_send_sysex_message(&pod->line6, sysex, size); 662 697 kfree(sysex); 663 - return count; 698 + return 0; 699 + } 700 + 701 + /* 702 + Send system parameter (from string). 703 + @param tuner non-zero, if code refers to a tuner parameter 704 + */ 705 + static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod, const char *buf, 706 + int count, int code, unsigned short mask) 707 + { 708 + int retval; 709 + unsigned short value = simple_strtoul(buf, NULL, 10) & mask; 710 + retval = pod_set_system_param_int(pod, value, code); 711 + return (retval < 0) ? retval : count; 664 712 } 665 713 666 714 /* ··· 684 706 { 685 707 struct usb_interface *interface = to_usb_interface(dev); 686 708 struct usb_line6_pod *pod = usb_get_intfdata(interface); 687 - int retval = line6_wait_dump(&pod->dumpreq, 0); 709 + int retval = line6_dump_wait_interruptible(&pod->dumpreq); 688 710 if (retval < 0) 689 711 return retval; 690 712 memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf)); ··· 703 725 704 726 if (count != sizeof(pod->prog_data)) { 705 727 dev_err(pod->line6.ifcdev, 706 - "data block must be exactly %zu bytes\n", 707 - sizeof(pod->prog_data)); 728 + "data block must be exactly %d bytes\n", 729 + (int)sizeof(pod->prog_data)); 708 730 return -EINVAL; 709 731 } 710 732 ··· 878 900 { 879 901 struct usb_interface *interface = to_usb_interface(dev); 880 902 struct usb_line6_pod *pod = usb_get_intfdata(interface); 881 - int err = 0; 882 - DECLARE_WAITQUEUE(wait, current); 883 - pod->clipping.value = 0; 884 - add_wait_queue(&pod->clipping.wait, &wait); 885 - current->state = TASK_INTERRUPTIBLE; 886 - 887 - while (pod->clipping.value == 0) { 888 - if (signal_pending(current)) { 889 - err = -ERESTARTSYS; 890 - break; 891 - } else 892 - schedule(); 893 - } 894 - 895 - current->state = TASK_RUNNING; 896 - remove_wait_queue(&pod->clipping.wait, &wait); 897 - return err; 903 + return wait_event_interruptible(pod->clipping.wait, pod->clipping.value != 0); 898 904 } 899 905 900 - #define POD_GET_SYSTEM_PARAM(code, tuner, sign) \ 906 + /* 907 + POD startup procedure. 908 + This is a sequence of functions with special requirements (e.g., must 909 + not run immediately after initialization, must not run in interrupt 910 + context). After the last one has finished, the device is ready to use. 911 + */ 912 + 913 + static void pod_startup1(struct usb_line6_pod *pod) 914 + { 915 + CHECK_STARTUP_PROGRESS(pod->startup_progress, 1); 916 + 917 + /* delay startup procedure: */ 918 + line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2, (unsigned long)pod); 919 + } 920 + 921 + static void pod_startup2(unsigned long data) 922 + { 923 + struct usb_line6_pod *pod = (struct usb_line6_pod *)data; 924 + CHECK_STARTUP_PROGRESS(pod->startup_progress, 2); 925 + 926 + /* current channel dump: */ 927 + line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT); 928 + } 929 + 930 + static void pod_startup3(struct usb_line6_pod *pod) 931 + { 932 + struct usb_line6 *line6 = &pod->line6; 933 + CHECK_STARTUP_PROGRESS(pod->startup_progress, 3); 934 + 935 + /* request firmware version: */ 936 + line6_version_request_async(line6); 937 + } 938 + 939 + static void pod_startup4(struct usb_line6_pod *pod) 940 + { 941 + CHECK_STARTUP_PROGRESS(pod->startup_progress, 4); 942 + 943 + /* schedule work for global work queue: */ 944 + schedule_work(&pod->startup_work); 945 + } 946 + 947 + static void pod_startup5(struct work_struct *work) 948 + { 949 + struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, startup_work); 950 + struct usb_line6 *line6 = &pod->line6; 951 + 952 + CHECK_STARTUP_PROGRESS(pod->startup_progress, 5); 953 + 954 + /* serial number: */ 955 + line6_read_serial_number(&pod->line6, &pod->serial_number); 956 + 957 + /* ALSA audio interface: */ 958 + line6_register_audio(line6); 959 + 960 + /* device files: */ 961 + line6_pod_create_files(pod->firmware_version, line6->properties->device_bit, line6->ifcdev); 962 + } 963 + 964 + #define POD_GET_SYSTEM_PARAM(code, sign) \ 901 965 static ssize_t pod_get_ ## code(struct device *dev, \ 902 966 struct device_attribute *attr, char *buf) \ 903 967 { \ 904 968 struct usb_interface *interface = to_usb_interface(dev); \ 905 969 struct usb_line6_pod *pod = usb_get_intfdata(interface); \ 906 - return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, \ 907 - tuner, sign); \ 970 + return pod_get_system_param_string(pod, buf, POD_ ## code, \ 971 + &pod->code, sign); \ 908 972 } 909 973 910 - #define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \ 911 - POD_GET_SYSTEM_PARAM(code, tuner, sign) \ 974 + #define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \ 975 + POD_GET_SYSTEM_PARAM(code, sign) \ 912 976 static ssize_t pod_set_ ## code(struct device *dev, \ 913 977 struct device_attribute *attr, \ 914 978 const char *buf, size_t count) \ 915 979 { \ 916 980 struct usb_interface *interface = to_usb_interface(dev); \ 917 981 struct usb_line6_pod *pod = usb_get_intfdata(interface); \ 918 - return pod_set_system_param(pod, buf, count, POD_ ## code, mask, \ 919 - tuner); \ 982 + return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \ 920 983 } 921 984 922 - POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0); 923 - POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0); 924 - POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0); 925 - POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0); 926 - POD_GET_SYSTEM_PARAM(tuner_note, 1, 1); 927 - POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1); 985 + POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0); 986 + POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0); 987 + POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0); 988 + POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0); 989 + POD_GET_SYSTEM_PARAM(tuner_note, 1); 990 + POD_GET_SYSTEM_PARAM(tuner_pitch, 1); 928 991 929 992 #undef GET_SET_SYSTEM_PARAM 930 993 #undef GET_SYSTEM_PARAM ··· 996 977 static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write); 997 978 static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write); 998 979 999 - #if CREATE_RAW_FILE 980 + #ifdef CONFIG_LINE6_USB_RAW 1000 981 static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); 1001 982 #endif 983 + 984 + /* control info callback */ 985 + static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol, 986 + struct snd_ctl_elem_info *uinfo) 987 + { 988 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 989 + uinfo->count = 1; 990 + uinfo->value.integer.min = 0; 991 + uinfo->value.integer.max = 65535; 992 + return 0; 993 + } 994 + 995 + /* control get callback */ 996 + static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol, 997 + struct snd_ctl_elem_value *ucontrol) 998 + { 999 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 1000 + struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; 1001 + ucontrol->value.integer.value[0] = pod->monitor_level.value; 1002 + return 0; 1003 + } 1004 + 1005 + /* control put callback */ 1006 + static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol, 1007 + struct snd_ctl_elem_value *ucontrol) 1008 + { 1009 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 1010 + struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; 1011 + 1012 + if(ucontrol->value.integer.value[0] == pod->monitor_level.value) 1013 + return 0; 1014 + 1015 + pod->monitor_level.value = ucontrol->value.integer.value[0]; 1016 + pod_set_system_param_int(pod, ucontrol->value.integer.value[0], POD_monitor_level); 1017 + return 1; 1018 + } 1019 + 1020 + /* control definition */ 1021 + static struct snd_kcontrol_new pod_control_monitor = { 1022 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1023 + .name = "Monitor Playback Volume", 1024 + .index = 0, 1025 + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1026 + .info = snd_pod_control_monitor_info, 1027 + .get = snd_pod_control_monitor_get, 1028 + .put = snd_pod_control_monitor_put 1029 + }; 1002 1030 1003 1031 /* 1004 1032 POD destructor. ··· 1064 998 1065 999 /* free dump request data: */ 1066 1000 line6_dumpreq_destruct(&pod->dumpreq); 1067 - 1068 - kfree(pod->buffer_versionreq); 1069 1001 } 1070 1002 1071 1003 /* ··· 1098 1034 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note)); 1099 1035 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch)); 1100 1036 1101 - #if CREATE_RAW_FILE 1037 + #ifdef CONFIG_LINE6_USB_RAW 1102 1038 CHECK_RETURN(device_create_file(dev, &dev_attr_raw)); 1103 1039 #endif 1104 1040 ··· 1106 1042 } 1107 1043 1108 1044 /* 1109 - Init POD device. 1045 + Try to init POD device. 1110 1046 */ 1111 - int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) 1047 + static int pod_try_init(struct usb_interface *interface, struct usb_line6_pod *pod) 1112 1048 { 1113 1049 int err; 1114 1050 struct usb_line6 *line6 = &pod->line6; ··· 1126 1062 init_waitqueue_head(&pod->tuner_note.wait); 1127 1063 init_waitqueue_head(&pod->tuner_pitch.wait); 1128 1064 init_waitqueue_head(&pod->clipping.wait); 1065 + init_timer(&pod->startup_timer); 1066 + INIT_WORK(&pod->startup_work, pod_startup5); 1129 1067 1130 1068 memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty)); 1131 1069 ··· 1136 1070 sizeof(pod_request_channel)); 1137 1071 if (err < 0) { 1138 1072 dev_err(&interface->dev, "Out of memory\n"); 1139 - pod_destruct(interface); 1140 - return -ENOMEM; 1141 - } 1142 - 1143 - pod->buffer_versionreq = kmemdup(pod_request_version, 1144 - sizeof(pod_request_version), 1145 - GFP_KERNEL); 1146 - 1147 - if (pod->buffer_versionreq == NULL) { 1148 - dev_err(&interface->dev, "Out of memory\n"); 1149 - pod_destruct(interface); 1150 1073 return -ENOMEM; 1151 1074 } 1152 1075 1153 1076 /* create sysfs entries: */ 1154 1077 err = pod_create_files2(&interface->dev); 1155 1078 if (err < 0) { 1156 - pod_destruct(interface); 1157 1079 return err; 1158 1080 } 1159 1081 1160 1082 /* initialize audio system: */ 1161 1083 err = line6_init_audio(line6); 1162 1084 if (err < 0) { 1163 - pod_destruct(interface); 1164 1085 return err; 1165 1086 } 1166 1087 1167 1088 /* initialize MIDI subsystem: */ 1168 1089 err = line6_init_midi(line6); 1169 1090 if (err < 0) { 1170 - pod_destruct(interface); 1171 1091 return err; 1172 1092 } 1173 1093 1174 1094 /* initialize PCM subsystem: */ 1175 1095 err = line6_init_pcm(line6, &pod_pcm_properties); 1176 1096 if (err < 0) { 1177 - pod_destruct(interface); 1178 1097 return err; 1179 1098 } 1180 1099 1181 - /* register audio system: */ 1182 - err = line6_register_audio(line6); 1100 + /* register monitor control: */ 1101 + err = snd_ctl_add(line6->card, snd_ctl_new1(&pod_control_monitor, line6->line6pcm)); 1183 1102 if (err < 0) { 1184 - pod_destruct(interface); 1185 1103 return err; 1186 1104 } 1105 + 1106 + /* 1107 + When the sound card is registered at this point, the PODxt Live 1108 + displays "Invalid Code Error 07", so we do it later in the event 1109 + handler. 1110 + */ 1187 1111 1188 1112 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) { 1189 - /* query some data: */ 1190 - line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY, 1191 - pod_startup_timeout, pod); 1192 - line6_read_serial_number(&pod->line6, &pod->serial_number); 1113 + pod->monitor_level.value = POD_system_invalid; 1114 + 1115 + /* initiate startup procedure: */ 1116 + pod_startup1(pod); 1193 1117 } 1194 1118 1195 1119 return 0; 1196 1120 } 1197 1121 1198 1122 /* 1123 + Init POD device (and clean up in case of failure). 1124 + */ 1125 + int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) 1126 + { 1127 + int err = pod_try_init(interface, pod); 1128 + 1129 + if (err < 0) { 1130 + pod_destruct(interface); 1131 + } 1132 + 1133 + return err; 1134 + } 1135 + 1136 + /* 1199 1137 POD device disconnected. 1200 1138 */ 1201 - void pod_disconnect(struct usb_interface *interface) 1139 + void line6_pod_disconnect(struct usb_interface *interface) 1202 1140 { 1203 1141 struct usb_line6_pod *pod; 1204 1142 ··· 1215 1145 struct device *dev = &interface->dev; 1216 1146 1217 1147 if (line6pcm != NULL) { 1218 - unlink_wait_clear_audio_out_urbs(line6pcm); 1219 - unlink_wait_clear_audio_in_urbs(line6pcm); 1148 + line6_pcm_disconnect(line6pcm); 1220 1149 } 1221 1150 1222 1151 if (dev != NULL) { 1223 1152 /* remove sysfs entries: */ 1224 - if (pod->versionreq_ok) 1225 - pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev); 1153 + line6_pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev); 1226 1154 1227 1155 device_remove_file(dev, &dev_attr_channel); 1228 1156 device_remove_file(dev, &dev_attr_clip); ··· 1247 1179 device_remove_file(dev, &dev_attr_tuner_note); 1248 1180 device_remove_file(dev, &dev_attr_tuner_pitch); 1249 1181 1250 - #if CREATE_RAW_FILE 1182 + #ifdef CONFIG_LINE6_USB_RAW 1251 1183 device_remove_file(dev, &dev_attr_raw); 1252 1184 #endif 1253 1185 }
+53 -61
drivers/staging/line6/pod.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define POD_H 14 14 15 15 16 - #include "driver.h" 17 - 16 + #include <linux/interrupt.h> 18 17 #include <linux/spinlock.h> 19 18 #include <linux/usb.h> 20 19 #include <linux/wait.h> 21 - #include <linux/workqueue.h> 22 20 23 21 #include <sound/core.h> 24 22 23 + #include "driver.h" 25 24 #include "dumprequest.h" 26 25 27 26 ··· 41 42 */ 42 43 #define POD_CONTROL_SIZE 0x80 43 44 #define POD_BUFSIZE_DUMPREQ 7 44 - #define POD_STARTUP_DELAY 3 45 - 45 + #define POD_STARTUP_DELAY 3000 46 46 47 47 /** 48 - Data structure for values that need to be requested explicitly. 49 - This is the case for system and tuner settings. 48 + Data structure for values that need to be requested explicitly. 49 + This is the case for system and tuner settings. 50 50 */ 51 51 struct ValueWait { 52 - unsigned short value; 52 + int value; 53 53 wait_queue_head_t wait; 54 54 }; 55 55 56 56 /** 57 - Binary PodXT Pro program dump 57 + Binary PODxt Pro program dump 58 58 */ 59 59 struct pod_program { 60 60 /** 61 - Header information (including program name). 61 + Header information (including program name). 62 62 */ 63 63 unsigned char header[0x20]; 64 64 65 65 /** 66 - Program parameters. 66 + Program parameters. 67 67 */ 68 68 unsigned char control[POD_CONTROL_SIZE]; 69 69 }; 70 70 71 71 struct usb_line6_pod { 72 72 /** 73 - Generic Line6 USB data. 73 + Generic Line6 USB data. 74 74 */ 75 75 struct usb_line6 line6; 76 76 77 77 /** 78 - Dump request structure. 78 + Dump request structure. 79 79 */ 80 80 struct line6_dump_request dumpreq; 81 81 82 82 /** 83 - Current program number. 83 + Current program number. 84 84 */ 85 85 unsigned char channel_num; 86 86 87 87 /** 88 - Current program settings. 88 + Current program settings. 89 89 */ 90 90 struct pod_program prog_data; 91 91 92 92 /** 93 - Buffer for data retrieved from or to be stored on PODxt Pro. 93 + Buffer for data retrieved from or to be stored on PODxt Pro. 94 94 */ 95 95 struct pod_program prog_data_buf; 96 96 97 97 /** 98 - Buffer for requesting version number. 99 - */ 100 - unsigned char *buffer_versionreq; 101 - 102 - /** 103 - Tuner mute mode. 98 + Tuner mute mode. 104 99 */ 105 100 struct ValueWait tuner_mute; 106 101 107 102 /** 108 - Tuner base frequency (typically 440Hz). 103 + Tuner base frequency (typically 440Hz). 109 104 */ 110 105 struct ValueWait tuner_freq; 111 106 112 107 /** 113 - Note received from tuner. 108 + Note received from tuner. 114 109 */ 115 110 struct ValueWait tuner_note; 116 111 117 112 /** 118 - Pitch value received from tuner. 113 + Pitch value received from tuner. 119 114 */ 120 115 struct ValueWait tuner_pitch; 121 116 122 117 /** 123 - Instrument monitor level. 118 + Instrument monitor level. 124 119 */ 125 120 struct ValueWait monitor_level; 126 121 127 122 /** 128 - Audio routing mode. 129 - 0: send processed guitar 130 - 1: send clean guitar 131 - 2: send clean guitar re-amp playback 132 - 3: send re-amp playback 123 + Audio routing mode. 124 + 0: send processed guitar 125 + 1: send clean guitar 126 + 2: send clean guitar re-amp playback 127 + 3: send re-amp playback 133 128 */ 134 129 struct ValueWait routing; 135 130 136 131 /** 137 - Wait for audio clipping event. 132 + Wait for audio clipping event. 138 133 */ 139 134 struct ValueWait clipping; 140 135 141 136 /** 142 - Bottom-half for creation of sysfs special files. 137 + Timer for device initializaton. 143 138 */ 144 - struct work_struct create_files_work; 139 + struct timer_list startup_timer; 145 140 146 141 /** 147 - Dirty flags for access to parameter data. 142 + Work handler for device initializaton. 143 + */ 144 + struct work_struct startup_work; 145 + 146 + /** 147 + Current progress in startup procedure. 148 + */ 149 + int startup_progress; 150 + 151 + /** 152 + Dirty flags for access to parameter data. 148 153 */ 149 154 unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)]; 150 155 151 156 /** 152 - Some atomic flags. 157 + Some atomic flags. 153 158 */ 154 159 unsigned long atomic_flags; 155 160 156 161 /** 157 - Counter for startup process. 158 - */ 159 - int startup_count; 160 - 161 - /** 162 - Serial number of device. 162 + Serial number of device. 163 163 */ 164 164 int serial_number; 165 165 166 166 /** 167 - Firmware version (x 100). 167 + Firmware version (x 100). 168 168 */ 169 169 int firmware_version; 170 170 171 171 /** 172 - Device ID. 172 + Device ID. 173 173 */ 174 174 int device_id; 175 175 176 176 /** 177 - Flag to indicate modification of current program settings. 177 + Flag to indicate modification of current program settings. 178 178 */ 179 179 char dirty; 180 180 181 181 /** 182 - Flag if initial firmware version request has been successful. 183 - */ 184 - char versionreq_ok; 185 - 186 - /** 187 - Flag to enable MIDI postprocessing. 182 + Flag to enable MIDI postprocessing. 188 183 */ 189 184 char midi_postprocess; 190 185 }; 191 186 192 187 193 - extern void pod_disconnect(struct usb_interface *interface); 194 - extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod); 195 - extern void pod_midi_postprocess(struct usb_line6_pod *pod, 196 - unsigned char *data, int length); 197 - extern void pod_process_message(struct usb_line6_pod *pod); 198 - extern void pod_receive_parameter(struct usb_line6_pod *pod, int param); 199 - extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param, 200 - int value); 188 + extern void line6_pod_disconnect(struct usb_interface *interface); 189 + extern int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod); 190 + extern void line6_pod_midi_postprocess(struct usb_line6_pod *pod, 191 + unsigned char *data, int length); 192 + extern void line6_pod_process_message(struct usb_line6_pod *pod); 193 + extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, 194 + int value); 201 195 202 196 203 197 #endif
+1 -1
drivers/staging/line6/revision.h
··· 1 1 #ifndef DRIVER_REVISION 2 2 /* current subversion revision */ 3 - #define DRIVER_REVISION " (revision 529)" 3 + #define DRIVER_REVISION " (revision 665)" 4 4 #endif
+270 -71
drivers/staging/line6/toneport.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * Emil Myhrman (emil.myhrman@gmail.com) 6 6 * 7 7 * This program is free software; you can redistribute it and/or ··· 10 10 * 11 11 */ 12 12 13 - #include "driver.h" 13 + #include <linux/wait.h> 14 + #include <sound/control.h> 14 15 15 16 #include "audio.h" 16 17 #include "capture.h" 18 + #include "driver.h" 17 19 #include "playback.h" 18 20 #include "toneport.h" 19 21 22 + 20 23 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2); 24 + 25 + 26 + #define TONEPORT_PCM_DELAY 1 27 + 21 28 22 29 static struct snd_ratden toneport_ratden = { 23 30 .num_min = 44100, ··· 35 28 36 29 static struct line6_pcm_properties toneport_pcm_properties = { 37 30 .snd_line6_playback_hw = { 38 - .info = (SNDRV_PCM_INFO_MMAP | 39 - SNDRV_PCM_INFO_INTERLEAVED | 40 - SNDRV_PCM_INFO_BLOCK_TRANSFER | 41 - SNDRV_PCM_INFO_MMAP_VALID | 42 - SNDRV_PCM_INFO_PAUSE | 43 - SNDRV_PCM_INFO_SYNC_START), 44 - .formats = SNDRV_PCM_FMTBIT_S16_LE, 45 - .rates = SNDRV_PCM_RATE_KNOT, 46 - .rate_min = 44100, 47 - .rate_max = 44100, 48 - .channels_min = 2, 49 - .channels_max = 2, 50 - .buffer_bytes_max = 60000, 51 - .period_bytes_min = 180 * 4, 52 - .period_bytes_max = 8192, 53 - .periods_min = 1, 54 - .periods_max = 1024}, 31 + .info = (SNDRV_PCM_INFO_MMAP | 32 + SNDRV_PCM_INFO_INTERLEAVED | 33 + SNDRV_PCM_INFO_BLOCK_TRANSFER | 34 + SNDRV_PCM_INFO_MMAP_VALID | 35 + SNDRV_PCM_INFO_PAUSE | 36 + #ifdef CONFIG_PM 37 + SNDRV_PCM_INFO_RESUME | 38 + #endif 39 + SNDRV_PCM_INFO_SYNC_START), 40 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 41 + .rates = SNDRV_PCM_RATE_KNOT, 42 + .rate_min = 44100, 43 + .rate_max = 44100, 44 + .channels_min = 2, 45 + .channels_max = 2, 46 + .buffer_bytes_max = 60000, 47 + .period_bytes_min = 64, 48 + .period_bytes_max = 8192, 49 + .periods_min = 1, 50 + .periods_max = 1024 51 + }, 55 52 .snd_line6_capture_hw = { 56 - .info = (SNDRV_PCM_INFO_MMAP | 57 - SNDRV_PCM_INFO_INTERLEAVED | 58 - SNDRV_PCM_INFO_BLOCK_TRANSFER | 59 - SNDRV_PCM_INFO_MMAP_VALID | 60 - SNDRV_PCM_INFO_SYNC_START), 61 - .formats = SNDRV_PCM_FMTBIT_S16_LE, 62 - .rates = SNDRV_PCM_RATE_KNOT, 63 - .rate_min = 44100, 64 - .rate_max = 44100, 65 - .channels_min = 2, 66 - .channels_max = 2, 67 - .buffer_bytes_max = 60000, 68 - .period_bytes_min = 188 * 4, 69 - .period_bytes_max = 8192, 70 - .periods_min = 1, 71 - .periods_max = 1024}, 53 + .info = (SNDRV_PCM_INFO_MMAP | 54 + SNDRV_PCM_INFO_INTERLEAVED | 55 + SNDRV_PCM_INFO_BLOCK_TRANSFER | 56 + SNDRV_PCM_INFO_MMAP_VALID | 57 + #ifdef CONFIG_PM 58 + SNDRV_PCM_INFO_RESUME | 59 + #endif 60 + SNDRV_PCM_INFO_SYNC_START), 61 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 62 + .rates = SNDRV_PCM_RATE_KNOT, 63 + .rate_min = 44100, 64 + .rate_max = 44100, 65 + .channels_min = 2, 66 + .channels_max = 2, 67 + .buffer_bytes_max = 60000, 68 + .period_bytes_min = 64, 69 + .period_bytes_max = 8192, 70 + .periods_min = 1, 71 + .periods_max = 1024 72 + }, 72 73 .snd_line6_rates = { 73 - .nrats = 1, 74 - .rats = &toneport_ratden}, 74 + .nrats = 1, 75 + .rats = &toneport_ratden 76 + }, 75 77 .bytes_per_frame = 4 76 78 }; 77 79 ··· 92 76 */ 93 77 static int led_red = 0x00; 94 78 static int led_green = 0x26; 79 + 80 + struct ToneportSourceInfo 81 + { 82 + const char *name; 83 + int code; 84 + }; 85 + 86 + static const struct ToneportSourceInfo toneport_source_info[] = { 87 + { "Microphone", 0x0a01 }, 88 + { "Line" , 0x0801 }, 89 + { "Instrument", 0x0b01 }, 90 + { "Inst & Mic", 0x0901 } 91 + }; 92 + 93 + static bool toneport_has_led(short product) 94 + { 95 + return 96 + (product == LINE6_DEVID_GUITARPORT) || 97 + (product == LINE6_DEVID_TONEPORT_GX); 98 + /* add your device here if you are missing support for the LEDs */ 99 + } 95 100 96 101 static void toneport_update_led(struct device *dev) 97 102 { ··· 166 129 static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, 167 130 toneport_set_led_green); 168 131 132 + 169 133 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) 170 134 { 171 135 int ret; ··· 182 144 183 145 return 0; 184 146 } 147 + 148 + /* monitor info callback */ 149 + static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol, 150 + struct snd_ctl_elem_info *uinfo) 151 + { 152 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 153 + uinfo->count = 1; 154 + uinfo->value.integer.min = 0; 155 + uinfo->value.integer.max = 256; 156 + return 0; 157 + } 158 + 159 + /* monitor get callback */ 160 + static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol, 161 + struct snd_ctl_elem_value *ucontrol) 162 + { 163 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 164 + ucontrol->value.integer.value[0] = line6pcm->volume_monitor; 165 + return 0; 166 + } 167 + 168 + /* monitor put callback */ 169 + static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol, 170 + struct snd_ctl_elem_value *ucontrol) 171 + { 172 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 173 + 174 + if(ucontrol->value.integer.value[0] == line6pcm->volume_monitor) 175 + return 0; 176 + 177 + line6pcm->volume_monitor = ucontrol->value.integer.value[0]; 178 + return 1; 179 + } 180 + 181 + /* source info callback */ 182 + static int snd_toneport_source_info(struct snd_kcontrol *kcontrol, 183 + struct snd_ctl_elem_info *uinfo) 184 + { 185 + const int size = ARRAY_SIZE(toneport_source_info); 186 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 187 + uinfo->count = 1; 188 + uinfo->value.enumerated.items = size; 189 + 190 + if(uinfo->value.enumerated.item >= size) 191 + uinfo->value.enumerated.item = size - 1; 192 + 193 + strcpy(uinfo->value.enumerated.name, 194 + toneport_source_info[uinfo->value.enumerated.item].name); 195 + 196 + return 0; 197 + } 198 + 199 + /* source get callback */ 200 + static int snd_toneport_source_get(struct snd_kcontrol *kcontrol, 201 + struct snd_ctl_elem_value *ucontrol) 202 + { 203 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 204 + struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)line6pcm->line6; 205 + ucontrol->value.enumerated.item[0] = toneport->source; 206 + return 0; 207 + } 208 + 209 + /* source put callback */ 210 + static int snd_toneport_source_put(struct snd_kcontrol *kcontrol, 211 + struct snd_ctl_elem_value *ucontrol) 212 + { 213 + struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 214 + struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)line6pcm->line6; 215 + 216 + if(ucontrol->value.enumerated.item[0] == toneport->source) 217 + return 0; 218 + 219 + toneport->source = ucontrol->value.enumerated.item[0]; 220 + toneport_send_cmd(toneport->line6.usbdev, toneport_source_info[toneport->source].code, 0x0000); 221 + return 1; 222 + } 223 + 224 + static void toneport_start_pcm(unsigned long arg) 225 + { 226 + struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; 227 + struct usb_line6 *line6 = &toneport->line6; 228 + line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR); 229 + } 230 + 231 + /* control definition */ 232 + static struct snd_kcontrol_new toneport_control_monitor = { 233 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 234 + .name = "Monitor Playback Volume", 235 + .index = 0, 236 + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 237 + .info = snd_toneport_monitor_info, 238 + .get = snd_toneport_monitor_get, 239 + .put = snd_toneport_monitor_put 240 + }; 241 + 242 + /* source selector definition */ 243 + static struct snd_kcontrol_new toneport_control_source = { 244 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 245 + .name = "PCM Capture Source", 246 + .index = 0, 247 + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 248 + .info = snd_toneport_source_info, 249 + .get = snd_toneport_source_get, 250 + .put = snd_toneport_source_put 251 + }; 185 252 186 253 /* 187 254 Toneport destructor. ··· 305 162 } 306 163 307 164 /* 308 - Init Toneport device. 165 + Setup Toneport device. 309 166 */ 310 - int toneport_init(struct usb_interface *interface, 311 - struct usb_line6_toneport *toneport) 167 + static void toneport_setup(struct usb_line6_toneport *toneport) 312 168 { 313 - int err, ticks; 169 + int ticks; 314 170 struct usb_line6 *line6 = &toneport->line6; 315 - struct usb_device *usbdev; 171 + struct usb_device *usbdev = line6->usbdev; 172 + 173 + /* sync time on device with host: */ 174 + ticks = (int)get_seconds(); 175 + line6_write_data(line6, 0x80c6, &ticks, 4); 176 + 177 + /* enable device: */ 178 + toneport_send_cmd(usbdev, 0x0301, 0x0000); 179 + 180 + /* initialize source select: */ 181 + switch(usbdev->descriptor.idProduct) { 182 + case LINE6_DEVID_TONEPORT_UX1: 183 + case LINE6_DEVID_PODSTUDIO_UX1: 184 + toneport_send_cmd(usbdev, toneport_source_info[toneport->source].code, 0x0000); 185 + } 186 + 187 + if (toneport_has_led(usbdev->descriptor.idProduct)) 188 + toneport_update_led(&usbdev->dev); 189 + } 190 + 191 + /* 192 + Try to init Toneport device. 193 + */ 194 + static int toneport_try_init(struct usb_interface *interface, 195 + struct usb_line6_toneport *toneport) 196 + { 197 + int err; 198 + struct usb_line6 *line6 = &toneport->line6; 199 + struct usb_device *usbdev = line6->usbdev; 316 200 317 201 if ((interface == NULL) || (toneport == NULL)) 318 202 return -ENODEV; ··· 347 177 /* initialize audio system: */ 348 178 err = line6_init_audio(line6); 349 179 if (err < 0) { 350 - toneport_destruct(interface); 351 180 return err; 352 181 } 353 182 354 183 /* initialize PCM subsystem: */ 355 184 err = line6_init_pcm(line6, &toneport_pcm_properties); 356 185 if (err < 0) { 357 - toneport_destruct(interface); 358 186 return err; 187 + } 188 + 189 + /* register monitor control: */ 190 + err = snd_ctl_add(line6->card, snd_ctl_new1(&toneport_control_monitor, line6->line6pcm)); 191 + if (err < 0) { 192 + return err; 193 + } 194 + 195 + /* register source select control: */ 196 + switch(usbdev->descriptor.idProduct) { 197 + case LINE6_DEVID_TONEPORT_UX1: 198 + case LINE6_DEVID_PODSTUDIO_UX1: 199 + err = snd_ctl_add(line6->card, snd_ctl_new1(&toneport_control_source, line6->line6pcm)); 200 + if (err < 0) { 201 + return err; 202 + } 359 203 } 360 204 361 205 /* register audio system: */ 362 206 err = line6_register_audio(line6); 363 207 if (err < 0) { 364 - toneport_destruct(interface); 365 208 return err; 366 209 } 367 210 368 - usbdev = line6->usbdev; 369 211 line6_read_serial_number(line6, &toneport->serial_number); 370 212 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); 371 213 372 - /* sync time on device with host: */ 373 - ticks = (int)get_seconds(); 374 - line6_write_data(line6, 0x80c6, &ticks, 4); 375 - 376 - /* 377 - seems to work without the first two... 378 - */ 379 - /* toneport_send_cmd(usbdev, 0x0201, 0x0002); */ 380 - /* toneport_send_cmd(usbdev, 0x0801, 0x0000); */ 381 - /* only one that works for me; on GP, TP might be different? */ 382 - toneport_send_cmd(usbdev, 0x0301, 0x0000); 383 - 384 - if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) { 385 - CHECK_RETURN(device_create_file 386 - (&interface->dev, &dev_attr_led_red)); 387 - CHECK_RETURN(device_create_file 388 - (&interface->dev, &dev_attr_led_green)); 389 - toneport_update_led(&usbdev->dev); 214 + if (toneport_has_led(usbdev->descriptor.idProduct)) { 215 + CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red)); 216 + CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green)); 390 217 } 218 + 219 + toneport_setup(toneport); 220 + 221 + init_timer(&toneport->timer); 222 + toneport->timer.expires = jiffies + TONEPORT_PCM_DELAY * HZ; 223 + toneport->timer.function = toneport_start_pcm; 224 + toneport->timer.data = (unsigned long)toneport; 225 + add_timer(&toneport->timer); 391 226 392 227 return 0; 393 228 } 394 229 395 230 /* 231 + Init Toneport device (and clean up in case of failure). 232 + */ 233 + int line6_toneport_init(struct usb_interface *interface, 234 + struct usb_line6_toneport *toneport) 235 + { 236 + int err = toneport_try_init(interface, toneport); 237 + 238 + if (err < 0) { 239 + toneport_destruct(interface); 240 + } 241 + 242 + return err; 243 + } 244 + 245 + /* 246 + Resume Toneport device after reset. 247 + */ 248 + void line6_toneport_reset_resume(struct usb_line6_toneport *toneport) 249 + { 250 + toneport_setup(toneport); 251 + } 252 + 253 + /* 396 254 Toneport device disconnected. 397 255 */ 398 - void toneport_disconnect(struct usb_interface *interface) 256 + void line6_toneport_disconnect(struct usb_interface *interface) 399 257 { 400 258 struct usb_line6_toneport *toneport; 401 259 402 260 if (interface == NULL) 403 261 return; 404 - toneport = usb_get_intfdata(interface); 405 262 406 - if (toneport->line6.usbdev->descriptor.idProduct != 407 - LINE6_DEVID_GUITARPORT) { 263 + toneport = usb_get_intfdata(interface); 264 + del_timer_sync(&toneport->timer); 265 + 266 + if (toneport_has_led(toneport->line6.usbdev->descriptor.idProduct)) { 408 267 device_remove_file(&interface->dev, &dev_attr_led_red); 409 268 device_remove_file(&interface->dev, &dev_attr_led_green); 410 269 } ··· 442 243 struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; 443 244 444 245 if (line6pcm != NULL) { 445 - unlink_wait_clear_audio_out_urbs(line6pcm); 446 - unlink_wait_clear_audio_in_urbs(line6pcm); 246 + line6_pcm_stop(line6pcm, MASK_PCM_MONITOR); 247 + line6_pcm_disconnect(line6pcm); 447 248 } 448 249 } 449 250
+21 -10
drivers/staging/line6/toneport.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define TONEPORT_H 14 14 15 15 16 - #include "driver.h" 17 - 18 16 #include <linux/usb.h> 19 17 #include <sound/core.h> 18 + 19 + #include "driver.h" 20 20 21 21 22 22 struct usb_line6_toneport { 23 23 /** 24 - Generic Line6 USB data. 24 + Generic Line6 USB data. 25 25 */ 26 26 struct usb_line6 line6; 27 27 28 28 /** 29 - Serial number of device. 29 + Source selector. 30 + */ 31 + int source; 32 + 33 + /** 34 + Serial number of device. 30 35 */ 31 36 int serial_number; 32 37 33 38 /** 34 - Firmware version (x 100). 39 + Firmware version (x 100). 35 40 */ 36 41 int firmware_version; 42 + 43 + /** 44 + Timer for delayed PCM startup. 45 + */ 46 + struct timer_list timer; 37 47 }; 38 48 39 49 40 - extern void toneport_disconnect(struct usb_interface *interface); 41 - extern int toneport_init(struct usb_interface *interface, 42 - struct usb_line6_toneport *toneport); 50 + extern void line6_toneport_disconnect(struct usb_interface *interface); 51 + extern int line6_toneport_init(struct usb_interface *interface, 52 + struct usb_line6_toneport *toneport); 53 + extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport); 43 54 44 55 45 56 #endif
+26 -16
drivers/staging/line6/usbdefs.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 4 * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) 5 5 * ··· 25 25 #define LINE6_DEVID_BASSPODXTPRO 0x4252 26 26 #define LINE6_DEVID_GUITARPORT 0x4750 27 27 #define LINE6_DEVID_POCKETPOD 0x5051 28 + #define LINE6_DEVID_PODSTUDIO_GX 0x4153 29 + #define LINE6_DEVID_PODSTUDIO_UX1 0x4150 30 + #define LINE6_DEVID_PODSTUDIO_UX2 0x4151 28 31 #define LINE6_DEVID_PODX3 0x414a 29 32 #define LINE6_DEVID_PODX3LIVE 0x414b 30 33 #define LINE6_DEVID_PODXT 0x5044 ··· 38 35 #define LINE6_DEVID_TONEPORT_UX2 0x4142 39 36 #define LINE6_DEVID_VARIAX 0x534d 40 37 41 - #define LINE6_BIT_BASSPODXT (1 << 0) 42 - #define LINE6_BIT_BASSPODXTLIVE (1 << 1) 43 - #define LINE6_BIT_BASSPODXTPRO (1 << 2) 44 - #define LINE6_BIT_GUITARPORT (1 << 3) 45 - #define LINE6_BIT_POCKETPOD (1 << 4) 46 - #define LINE6_BIT_PODX3 (1 << 5) 47 - #define LINE6_BIT_PODX3LIVE (1 << 6) 48 - #define LINE6_BIT_PODXT (1 << 7) 49 - #define LINE6_BIT_PODXTLIVE (1 << 8) 50 - #define LINE6_BIT_PODXTPRO (1 << 9) 51 - #define LINE6_BIT_TONEPORT_GX (1 << 10) 52 - #define LINE6_BIT_TONEPORT_UX1 (1 << 11) 53 - #define LINE6_BIT_TONEPORT_UX2 (1 << 12) 54 - #define LINE6_BIT_VARIAX (1 << 13) 38 + #define LINE6_BIT_BASSPODXT (1 << 0) 39 + #define LINE6_BIT_BASSPODXTLIVE (1 << 1) 40 + #define LINE6_BIT_BASSPODXTPRO (1 << 2) 41 + #define LINE6_BIT_GUITARPORT (1 << 3) 42 + #define LINE6_BIT_POCKETPOD (1 << 4) 43 + #define LINE6_BIT_PODSTUDIO_GX (1 << 5) 44 + #define LINE6_BIT_PODSTUDIO_UX1 (1 << 6) 45 + #define LINE6_BIT_PODSTUDIO_UX2 (1 << 7) 46 + #define LINE6_BIT_PODX3 (1 << 8) 47 + #define LINE6_BIT_PODX3LIVE (1 << 9) 48 + #define LINE6_BIT_PODXT (1 << 10) 49 + #define LINE6_BIT_PODXTLIVE (1 << 11) 50 + #define LINE6_BIT_PODXTPRO (1 << 12) 51 + #define LINE6_BIT_TONEPORT_GX (1 << 13) 52 + #define LINE6_BIT_TONEPORT_UX1 (1 << 14) 53 + #define LINE6_BIT_TONEPORT_UX2 (1 << 15) 54 + #define LINE6_BIT_VARIAX (1 << 16) 55 55 56 56 #define LINE6_BITS_PRO (LINE6_BIT_BASSPODXTPRO | \ 57 57 LINE6_BIT_PODXTPRO) ··· 72 66 #define LINE6_BIT_CONTROL (1 << 0) 73 67 /* device supports PCM input/output via USB */ 74 68 #define LINE6_BIT_PCM (1 << 1) 75 - #define LINE6_BIT_CONTROL_PCM (LINE6_BIT_CONTROL | LINE6_BIT_PCM) 69 + /* device support hardware monitoring */ 70 + #define LINE6_BIT_HWMON (1 << 2) 71 + 72 + #define LINE6_BIT_CONTROL_PCM_HWMON (LINE6_BIT_CONTROL | LINE6_BIT_PCM | LINE6_BIT_HWMON) 76 73 77 74 #define LINE6_FALLBACK_INTERVAL 10 78 75 #define LINE6_FALLBACK_MAXPACKETSIZE 16 76 + 79 77 80 78 #endif
+172 -75
drivers/staging/line6/variax.c
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 9 9 * 10 10 */ 11 11 12 - #include "driver.h" 13 - 14 12 #include <linux/slab.h> 15 13 16 14 #include "audio.h" 17 15 #include "control.h" 16 + #include "driver.h" 18 17 #include "variax.h" 19 18 20 19 ··· 25 26 #define VARIAX_OFFSET_ACTIVATE 7 26 27 27 28 29 + /* 30 + This message is sent by the device during initialization and identifies 31 + the connected guitar model. 32 + */ 33 + static const char variax_init_model[] = { 34 + 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02, 35 + 0x00 36 + }; 37 + 38 + /* 39 + This message is sent by the device during initialization and identifies 40 + the connected guitar version. 41 + */ 42 + static const char variax_init_version[] = { 43 + 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c, 44 + 0x07, 0x00, 0x00, 0x00 45 + }; 46 + 47 + /* 48 + This message is the last one sent by the device during initialization. 49 + */ 50 + static const char variax_init_done[] = { 51 + 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b 52 + }; 53 + 28 54 static const char variax_activate[] = { 29 55 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01, 30 56 0xf7 31 57 }; 58 + 32 59 static const char variax_request_bank[] = { 33 60 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7 34 61 }; 62 + 35 63 static const char variax_request_model1[] = { 36 64 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00, 37 65 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03, 38 66 0x00, 0x00, 0x00, 0xf7 39 67 }; 68 + 40 69 static const char variax_request_model2[] = { 41 70 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00, 42 71 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03, 43 72 0x00, 0x00, 0x00, 0xf7 44 73 }; 74 + 75 + 76 + /* forward declarations: */ 77 + static int variax_create_files2(struct device *dev); 78 + static void variax_startup2(unsigned long data); 79 + static void variax_startup4(unsigned long data); 80 + static void variax_startup5(unsigned long data); 45 81 46 82 47 83 /* ··· 94 60 } 95 61 } 96 62 97 - static void variax_activate_timeout(unsigned long arg) 63 + static void variax_activate_async(struct usb_line6_variax *variax, int a) 98 64 { 99 - struct usb_line6_variax *variax = (struct usb_line6_variax *)arg; 100 - variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1; 65 + variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a; 101 66 line6_send_raw_message_async(&variax->line6, variax->buffer_activate, 102 67 sizeof(variax_activate)); 103 68 } 104 69 105 70 /* 106 - Send an asynchronous activation request after a given interval. 71 + Variax startup procedure. 72 + This is a sequence of functions with special requirements (e.g., must 73 + not run immediately after initialization, must not run in interrupt 74 + context). After the last one has finished, the device is ready to use. 107 75 */ 108 - static void variax_activate_delayed(struct usb_line6_variax *variax, 109 - int seconds) 76 + 77 + static void variax_startup1(struct usb_line6_variax *variax) 110 78 { 111 - variax->activate_timer.expires = jiffies + seconds * HZ; 112 - variax->activate_timer.function = variax_activate_timeout; 113 - variax->activate_timer.data = (unsigned long)variax; 114 - add_timer(&variax->activate_timer); 79 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 1); 80 + 81 + /* delay startup procedure: */ 82 + line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY1, variax_startup2, (unsigned long)variax); 115 83 } 116 84 117 - static void variax_startup_timeout(unsigned long arg) 85 + static void variax_startup2(unsigned long data) 118 86 { 119 - struct usb_line6_variax *variax = (struct usb_line6_variax *)arg; 87 + struct usb_line6_variax *variax = (struct usb_line6_variax *)data; 88 + struct usb_line6 *line6 = &variax->line6; 89 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 2); 120 90 121 - if (variax->dumpreq.ok) 122 - return; 91 + /* request firmware version: */ 92 + line6_version_request_async(line6); 93 + } 123 94 124 - line6_dump_request_async(&variax->dumpreq, &variax->line6, 0); 125 - line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout, 126 - variax); 95 + static void variax_startup3(struct usb_line6_variax *variax) 96 + { 97 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 3); 98 + 99 + /* delay startup procedure: */ 100 + line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY3, variax_startup4, (unsigned long)variax); 101 + } 102 + 103 + static void variax_startup4(unsigned long data) 104 + { 105 + struct usb_line6_variax *variax = (struct usb_line6_variax *)data; 106 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 4); 107 + 108 + /* activate device: */ 109 + variax_activate_async(variax, 1); 110 + line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY4, variax_startup5, (unsigned long)variax); 111 + } 112 + 113 + static void variax_startup5(unsigned long data) 114 + { 115 + struct usb_line6_variax *variax = (struct usb_line6_variax *)data; 116 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 5); 117 + 118 + /* current model dump: */ 119 + line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1); 120 + /* passes 2 and 3 are performed implicitly before entering variax_startup6 */ 121 + } 122 + 123 + static void variax_startup6(struct usb_line6_variax *variax) 124 + { 125 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 6); 126 + 127 + /* schedule work for global work queue: */ 128 + schedule_work(&variax->startup_work); 129 + } 130 + 131 + static void variax_startup7(struct work_struct *work) 132 + { 133 + struct usb_line6_variax *variax = container_of(work, struct usb_line6_variax, startup_work); 134 + struct usb_line6 *line6 = &variax->line6; 135 + 136 + CHECK_STARTUP_PROGRESS(variax->startup_progress, 7); 137 + 138 + /* ALSA audio interface: */ 139 + line6_register_audio(&variax->line6); 140 + 141 + /* device files: */ 142 + line6_variax_create_files(0, 0, line6->ifcdev); 143 + variax_create_files2(line6->ifcdev); 127 144 } 128 145 129 146 /* 130 147 Process a completely received message. 131 148 */ 132 - void variax_process_message(struct usb_line6_variax *variax) 149 + void line6_variax_process_message(struct usb_line6_variax *variax) 133 150 { 134 151 const unsigned char *buf = variax->line6.buffer_message; 135 152 ··· 200 115 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE: 201 116 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST: 202 117 variax->model = buf[1]; 203 - line6_dump_request_async(&variax->dumpreq, &variax->line6, 0); 118 + line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1); 204 119 break; 205 120 206 121 case LINE6_RESET: 207 122 dev_info(variax->line6.ifcdev, "VARIAX reset\n"); 208 - variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY); 209 123 break; 210 124 211 125 case LINE6_SYSEX_BEGIN: ··· 216 132 case VARIAX_DUMP_PASS1: 217 133 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data, 218 134 (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2); 219 - line6_dump_request_async(&variax->dumpreq, &variax->line6, 1); 220 - line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2); 135 + line6_dump_request_async(&variax->dumpreq, &variax->line6, 1, VARIAX_DUMP_PASS2); 221 136 break; 222 137 223 138 case VARIAX_DUMP_PASS2: ··· 224 141 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, 225 142 (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2, 226 143 sizeof(variax->model_data.control) / 2 * 2); 227 - variax->dumpreq.ok = 1; 228 - line6_dump_request_async(&variax->dumpreq, &variax->line6, 2); 229 - line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3); 144 + line6_dump_request_async(&variax->dumpreq, &variax->line6, 2, VARIAX_DUMP_PASS3); 230 145 } 231 146 } else { 232 147 DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length)); 233 148 line6_dump_finished(&variax->dumpreq); 234 149 } 235 150 } else if (memcmp(buf + 1, variax_request_bank + 1, 236 - sizeof(variax_request_bank) - 2) == 0) { 151 + sizeof(variax_request_bank) - 2) == 0) { 237 152 memcpy(variax->bank, 238 153 buf + sizeof(variax_request_bank) - 1, 239 154 sizeof(variax->bank)); 240 - variax->dumpreq.ok = 1; 241 155 line6_dump_finished(&variax->dumpreq); 156 + variax_startup6(variax); 157 + } else if (memcmp(buf + 1, variax_init_model + 1, 158 + sizeof(variax_init_model) - 1) == 0) { 159 + memcpy(variax->guitar, 160 + buf + sizeof(variax_init_model), 161 + sizeof(variax->guitar)); 162 + } else if (memcmp(buf + 1, variax_init_version + 1, 163 + sizeof(variax_init_version) - 1) == 0) { 164 + variax_startup3(variax); 165 + } else if (memcmp(buf + 1, variax_init_done + 1, 166 + sizeof(variax_init_done) - 1) == 0) { 167 + /* notify of complete initialization: */ 168 + variax_startup4((unsigned long)variax); 242 169 } 243 170 244 171 break; ··· 349 256 if (ret) 350 257 return ret; 351 258 352 - variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0; 353 - line6_send_raw_message_async(&variax->line6, variax->buffer_activate, 354 - sizeof(variax_activate)); 259 + variax_activate_async(variax, value ? 1 : 0); 355 260 return count; 356 261 } 357 262 ··· 408 317 struct device_attribute *attr, char *buf) 409 318 { 410 319 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); 411 - line6_wait_dump(&variax->dumpreq, 0); 320 + line6_dump_wait_interruptible(&variax->dumpreq); 412 321 return get_string(buf, variax->model_data.name, 413 322 sizeof(variax->model_data.name)); 414 323 } ··· 420 329 struct device_attribute *attr, char *buf) 421 330 { 422 331 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); 423 - line6_wait_dump(&variax->dumpreq, 0); 332 + line6_dump_wait_interruptible(&variax->dumpreq); 424 333 return get_string(buf, variax->bank, sizeof(variax->bank)); 425 334 } 426 335 ··· 432 341 { 433 342 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); 434 343 int retval; 435 - retval = line6_wait_dump(&variax->dumpreq, 0); 344 + retval = line6_dump_wait_interruptible(&variax->dumpreq); 436 345 if (retval < 0) 437 346 return retval; 438 347 memcpy(buf, &variax->model_data.control, ··· 440 349 return sizeof(variax->model_data.control); 441 350 } 442 351 443 - #if CREATE_RAW_FILE 352 + /* 353 + "read" request on "guitar" special file. 354 + */ 355 + static ssize_t variax_get_guitar(struct device *dev, 356 + struct device_attribute *attr, char *buf) 357 + { 358 + struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); 359 + return sprintf(buf, "%s\n", variax->guitar); 360 + } 361 + 362 + #ifdef CONFIG_LINE6_USB_RAW 363 + 364 + static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax, int code, int size) 365 + { 366 + return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code, size); 367 + } 444 368 445 369 /* 446 370 "write" request on "raw" special file. ··· 502 396 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write); 503 397 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write); 504 398 static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active); 399 + static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write); 505 400 506 - #if CREATE_RAW_FILE 401 + #ifdef CONFIG_LINE6_USB_RAW 507 402 static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); 508 403 static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2); 509 404 #endif ··· 531 424 line6_dumpreq_destruct(&variax->dumpreq); 532 425 533 426 kfree(variax->buffer_activate); 534 - del_timer_sync(&variax->activate_timer); 535 427 } 536 428 537 429 /* ··· 546 440 CHECK_RETURN(device_create_file(dev, &dev_attr_bank)); 547 441 CHECK_RETURN(device_create_file(dev, &dev_attr_dump)); 548 442 CHECK_RETURN(device_create_file(dev, &dev_attr_active)); 549 - #if CREATE_RAW_FILE 443 + CHECK_RETURN(device_create_file(dev, &dev_attr_guitar)); 444 + #ifdef CONFIG_LINE6_USB_RAW 550 445 CHECK_RETURN(device_create_file(dev, &dev_attr_raw)); 551 446 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2)); 552 447 #endif ··· 555 448 } 556 449 557 450 /* 558 - Init workbench device. 451 + Try to init workbench device. 559 452 */ 560 - int variax_init(struct usb_interface *interface, 561 - struct usb_line6_variax *variax) 453 + static int variax_try_init(struct usb_interface *interface, 454 + struct usb_line6_variax *variax) 562 455 { 563 456 int err; 564 457 565 458 if ((interface == NULL) || (variax == NULL)) 566 459 return -ENODEV; 460 + 461 + init_timer(&variax->startup_timer); 462 + INIT_WORK(&variax->startup_work, variax_startup7); 567 463 568 464 /* initialize USB buffers: */ 569 465 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1, ··· 574 464 575 465 if (err < 0) { 576 466 dev_err(&interface->dev, "Out of memory\n"); 577 - variax_destruct(interface); 578 467 return err; 579 468 } 580 469 ··· 582 473 583 474 if (err < 0) { 584 475 dev_err(&interface->dev, "Out of memory\n"); 585 - variax_destruct(interface); 586 476 return err; 587 477 } 588 478 ··· 590 482 591 483 if (err < 0) { 592 484 dev_err(&interface->dev, "Out of memory\n"); 593 - variax_destruct(interface); 594 485 return err; 595 486 } 596 487 ··· 598 491 599 492 if (variax->buffer_activate == NULL) { 600 493 dev_err(&interface->dev, "Out of memory\n"); 601 - variax_destruct(interface); 602 494 return -ENOMEM; 603 - } 604 - 605 - init_timer(&variax->activate_timer); 606 - 607 - /* create sysfs entries: */ 608 - err = variax_create_files(0, 0, &interface->dev); 609 - if (err < 0) { 610 - variax_destruct(interface); 611 - return err; 612 - } 613 - 614 - err = variax_create_files2(&interface->dev); 615 - if (err < 0) { 616 - variax_destruct(interface); 617 - return err; 618 495 } 619 496 620 497 /* initialize audio system: */ 621 498 err = line6_init_audio(&variax->line6); 622 499 if (err < 0) { 623 - variax_destruct(interface); 624 500 return err; 625 501 } 626 502 627 503 /* initialize MIDI subsystem: */ 628 504 err = line6_init_midi(&variax->line6); 629 505 if (err < 0) { 630 - variax_destruct(interface); 631 506 return err; 632 507 } 633 508 634 - /* register audio system: */ 635 - err = line6_register_audio(&variax->line6); 509 + /* initiate startup procedure: */ 510 + variax_startup1(variax); 511 + return 0; 512 + } 513 + 514 + /* 515 + Init workbench device (and clean up in case of failure). 516 + */ 517 + int line6_variax_init(struct usb_interface *interface, 518 + struct usb_line6_variax *variax) 519 + { 520 + int err = variax_try_init(interface, variax); 521 + 636 522 if (err < 0) { 637 523 variax_destruct(interface); 638 - return err; 639 524 } 640 525 641 - variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY); 642 - line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY, 643 - variax_startup_timeout, variax); 644 - return 0; 526 + return err; 645 527 } 646 528 647 529 /* 648 530 Workbench device disconnected. 649 531 */ 650 - void variax_disconnect(struct usb_interface *interface) 532 + void line6_variax_disconnect(struct usb_interface *interface) 651 533 { 652 534 struct device *dev; 653 535 ··· 646 550 647 551 if (dev != NULL) { 648 552 /* remove sysfs entries: */ 649 - variax_remove_files(0, 0, dev); 553 + line6_variax_remove_files(0, 0, dev); 650 554 device_remove_file(dev, &dev_attr_model); 651 555 device_remove_file(dev, &dev_attr_volume); 652 556 device_remove_file(dev, &dev_attr_tone); ··· 654 558 device_remove_file(dev, &dev_attr_bank); 655 559 device_remove_file(dev, &dev_attr_dump); 656 560 device_remove_file(dev, &dev_attr_active); 657 - #if CREATE_RAW_FILE 561 + device_remove_file(dev, &dev_attr_guitar); 562 + #ifdef CONFIG_LINE6_USB_RAW 658 563 device_remove_file(dev, &dev_attr_raw); 659 564 device_remove_file(dev, &dev_attr_raw2); 660 565 #endif
+39 -25
drivers/staging/line6/variax.h
··· 1 1 /* 2 - * Line6 Linux USB driver - 0.8.0 2 + * Line6 Linux USB driver - 0.9.0 3 3 * 4 - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 4 + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as ··· 13 13 #define VARIAX_H 14 14 15 15 16 - #include "driver.h" 17 - 18 16 #include <linux/spinlock.h> 19 17 #include <linux/usb.h> 20 18 #include <linux/wait.h> 21 - 22 19 #include <sound/core.h> 23 20 21 + #include "driver.h" 24 22 #include "dumprequest.h" 25 23 26 24 27 - #define VARIAX_ACTIVATE_DELAY 10 28 - #define VARIAX_STARTUP_DELAY 3 25 + #define VARIAX_STARTUP_DELAY1 1000 26 + #define VARIAX_STARTUP_DELAY3 100 27 + #define VARIAX_STARTUP_DELAY4 100 29 28 30 29 31 30 enum { ··· 35 36 36 37 37 38 /** 38 - Binary Variax model dump 39 + Binary Variax model dump 39 40 */ 40 41 struct variax_model { 41 42 /** 42 - Header information (including program name). 43 + Header information (including program name). 43 44 */ 44 45 unsigned char name[18]; 45 46 46 47 /** 47 - Model parameters. 48 + Model parameters. 48 49 */ 49 50 unsigned char control[78 * 2]; 50 51 }; 51 52 52 53 struct usb_line6_variax { 53 54 /** 54 - Generic Line6 USB data. 55 + Generic Line6 USB data. 55 56 */ 56 57 struct usb_line6 line6; 57 58 58 59 /** 59 - Dump request structure. 60 - Append two extra buffers for 3-pass data query. 60 + Dump request structure. 61 + Append two extra buffers for 3-pass data query. 61 62 */ 62 63 struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2]; 63 64 64 65 /** 65 - Buffer for activation code. 66 + Buffer for activation code. 66 67 */ 67 68 unsigned char *buffer_activate; 68 69 69 70 /** 70 - Model number. 71 + Model number. 71 72 */ 72 73 int model; 73 74 74 75 /** 75 - Current model settings. 76 + Current model settings. 76 77 */ 77 78 struct variax_model model_data; 78 79 79 80 /** 80 - Name of current model bank. 81 + Name of connected guitar. 82 + */ 83 + unsigned char guitar[18]; 84 + 85 + /** 86 + Name of current model bank. 81 87 */ 82 88 unsigned char bank[18]; 83 89 84 90 /** 85 - Position of volume dial. 91 + Position of volume dial. 86 92 */ 87 93 int volume; 88 94 89 95 /** 90 - Position of tone control dial. 96 + Position of tone control dial. 91 97 */ 92 98 int tone; 93 99 94 100 /** 95 - Timer for delayed activation request. 101 + Handler for device initializaton. 96 102 */ 97 - struct timer_list activate_timer; 103 + struct work_struct startup_work; 104 + 105 + /** 106 + Timer for device initializaton. 107 + */ 108 + struct timer_list startup_timer; 109 + 110 + /** 111 + Current progress in startup procedure. 112 + */ 113 + int startup_progress; 98 114 }; 99 115 100 116 101 - extern void variax_disconnect(struct usb_interface *interface); 102 - extern int variax_init(struct usb_interface *interface, 103 - struct usb_line6_variax *variax); 104 - extern void variax_process_message(struct usb_line6_variax *variax); 117 + extern void line6_variax_disconnect(struct usb_interface *interface); 118 + extern int line6_variax_init(struct usb_interface *interface, 119 + struct usb_line6_variax *variax); 120 + extern void line6_variax_process_message(struct usb_line6_variax *variax); 105 121 106 122 107 123 #endif