1/* 2 * Line6 Linux USB driver - 0.8.0 3 * 4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2. 9 * 10 */ 11 12#include "driver.h" 13 14#include <linux/usb.h> 15#include <linux/slab.h> 16 17#include <sound/core.h> 18#include <sound/rawmidi.h> 19 20#include "audio.h" 21#include "midi.h" 22#include "pod.h" 23#include "usbdefs.h" 24 25 26#define USE_MIDIBUF 1 27#define OUTPUT_DUMP_ONLY 0 28 29 30#define line6_rawmidi_substream_midi(substream) \ 31 ((struct snd_line6_midi *)((substream)->rmidi->private_data)) 32 33 34static int send_midi_async(struct usb_line6 *line6, unsigned char *data, 35 int length); 36 37 38/* 39 Pass data received via USB to MIDI. 40*/ 41void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, 42 int length) 43{ 44 if (line6->line6midi->substream_receive) 45 snd_rawmidi_receive(line6->line6midi->substream_receive, 46 data, length); 47} 48 49/* 50 Read data from MIDI buffer and transmit them via USB. 51*/ 52static void line6_midi_transmit(struct snd_rawmidi_substream *substream) 53{ 54 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6; 55 struct snd_line6_midi *line6midi = line6->line6midi; 56 struct MidiBuffer *mb = &line6midi->midibuf_out; 57 unsigned long flags; 58 unsigned char chunk[line6->max_packet_size]; 59 int req, done; 60 61 spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags); 62 63 for (;;) { 64 req = min(midibuf_bytes_free(mb), line6->max_packet_size); 65 done = snd_rawmidi_transmit_peek(substream, chunk, req); 66 67 if (done == 0) 68 break; 69 70#if DO_DUMP_MIDI_SEND 71 line6_write_hexdump(line6, 's', chunk, done); 72#endif 73 midibuf_write(mb, chunk, done); 74 snd_rawmidi_transmit_ack(substream, done); 75 } 76 77 for (;;) { 78 done = midibuf_read(mb, chunk, line6->max_packet_size); 79 80 if (done == 0) 81 break; 82 83 if (midibuf_skip_message(mb, line6midi->midi_mask_transmit)) 84 continue; 85 86 send_midi_async(line6, chunk, done); 87 } 88 89 spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags); 90} 91 92/* 93 Notification of completion of MIDI transmission. 94*/ 95static void midi_sent(struct urb *urb) 96{ 97 unsigned long flags; 98 int status; 99 int num; 100 struct usb_line6 *line6 = (struct usb_line6 *)urb->context; 101 102 status = urb->status; 103 kfree(urb->transfer_buffer); 104 usb_free_urb(urb); 105 106 if (status == -ESHUTDOWN) 107 return; 108 109 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 110 num = --line6->line6midi->num_active_send_urbs; 111 112 if (num == 0) { 113 line6_midi_transmit(line6->line6midi->substream_transmit); 114 num = line6->line6midi->num_active_send_urbs; 115 } 116 117 if (num == 0) 118 wake_up_interruptible(&line6->line6midi->send_wait); 119 120 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 121} 122 123/* 124 Send an asynchronous MIDI message. 125 Assumes that line6->line6midi->send_urb_lock is held 126 (i.e., this function is serialized). 127*/ 128static int send_midi_async(struct usb_line6 *line6, unsigned char *data, 129 int length) 130{ 131 struct urb *urb; 132 int retval; 133 unsigned char *transfer_buffer; 134 135 urb = usb_alloc_urb(0, GFP_ATOMIC); 136 137 if (urb == 0) { 138 dev_err(line6->ifcdev, "Out of memory\n"); 139 return -ENOMEM; 140 } 141 142#if DO_DUMP_URB_SEND 143 line6_write_hexdump(line6, 'S', data, length); 144#endif 145 146 transfer_buffer = kmalloc(length, GFP_ATOMIC); 147 148 if (transfer_buffer == 0) { 149 usb_free_urb(urb); 150 dev_err(line6->ifcdev, "Out of memory\n"); 151 return -ENOMEM; 152 } 153 154 memcpy(transfer_buffer, data, length); 155 usb_fill_int_urb(urb, line6->usbdev, 156 usb_sndbulkpipe(line6->usbdev, 157 line6->ep_control_write), 158 transfer_buffer, length, midi_sent, line6, 159 line6->interval); 160 urb->actual_length = 0; 161 retval = usb_submit_urb(urb, GFP_ATOMIC); 162 163 if (retval < 0) { 164 dev_err(line6->ifcdev, "usb_submit_urb failed\n"); 165 usb_free_urb(urb); 166 return -EINVAL; 167 } 168 169 ++line6->line6midi->num_active_send_urbs; 170 171 switch (line6->usbdev->descriptor.idProduct) { 172 case LINE6_DEVID_BASSPODXT: 173 case LINE6_DEVID_BASSPODXTLIVE: 174 case LINE6_DEVID_BASSPODXTPRO: 175 case LINE6_DEVID_PODXT: 176 case LINE6_DEVID_PODXTLIVE: 177 case LINE6_DEVID_PODXTPRO: 178 case LINE6_DEVID_POCKETPOD: 179 pod_midi_postprocess((struct usb_line6_pod *)line6, data, 180 length); 181 break; 182 183 default: 184 MISSING_CASE; 185 } 186 187 return 0; 188} 189 190static int line6_midi_output_open(struct snd_rawmidi_substream *substream) 191{ 192 return 0; 193} 194 195static int line6_midi_output_close(struct snd_rawmidi_substream *substream) 196{ 197 return 0; 198} 199 200static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream, 201 int up) 202{ 203 unsigned long flags; 204 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6; 205 206 line6->line6midi->substream_transmit = substream; 207 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 208 209 if (line6->line6midi->num_active_send_urbs == 0) 210 line6_midi_transmit(substream); 211 212 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 213} 214 215static void line6_midi_output_drain(struct snd_rawmidi_substream *substream) 216{ 217 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6; 218 wait_queue_head_t *head = &line6->line6midi->send_wait; 219 DECLARE_WAITQUEUE(wait, current); 220 add_wait_queue(head, &wait); 221 current->state = TASK_INTERRUPTIBLE; 222 223 while (line6->line6midi->num_active_send_urbs > 0) 224 if (signal_pending(current)) 225 break; 226 else 227 schedule(); 228 229 current->state = TASK_RUNNING; 230 remove_wait_queue(head, &wait); 231} 232 233static int line6_midi_input_open(struct snd_rawmidi_substream *substream) 234{ 235 return 0; 236} 237 238static int line6_midi_input_close(struct snd_rawmidi_substream *substream) 239{ 240 return 0; 241} 242 243static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream, 244 int up) 245{ 246 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6; 247 248 if (up) 249 line6->line6midi->substream_receive = substream; 250 else 251 line6->line6midi->substream_receive = 0; 252} 253 254static struct snd_rawmidi_ops line6_midi_output_ops = { 255 .open = line6_midi_output_open, 256 .close = line6_midi_output_close, 257 .trigger = line6_midi_output_trigger, 258 .drain = line6_midi_output_drain, 259}; 260 261static struct snd_rawmidi_ops line6_midi_input_ops = { 262 .open = line6_midi_input_open, 263 .close = line6_midi_input_close, 264 .trigger = line6_midi_input_trigger, 265}; 266 267/* 268 Cleanup the Line6 MIDI device. 269*/ 270static void line6_cleanup_midi(struct snd_rawmidi *rmidi) 271{ 272} 273 274/* Create a MIDI device */ 275static int snd_line6_new_midi(struct snd_line6_midi *line6midi) 276{ 277 struct snd_rawmidi *rmidi; 278 int err; 279 280 err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1, 281 &rmidi); 282 if (err < 0) 283 return err; 284 285 rmidi->private_data = line6midi; 286 rmidi->private_free = line6_cleanup_midi; 287 strcpy(rmidi->name, line6midi->line6->properties->name); 288 289 rmidi->info_flags = 290 SNDRV_RAWMIDI_INFO_OUTPUT | 291 SNDRV_RAWMIDI_INFO_INPUT | 292 SNDRV_RAWMIDI_INFO_DUPLEX; 293 294 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 295 &line6_midi_output_ops); 296 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 297 &line6_midi_input_ops); 298 return 0; 299} 300 301/* 302 "read" request on "midi_mask_transmit" special file. 303*/ 304static ssize_t midi_get_midi_mask_transmit(struct device *dev, 305 struct device_attribute *attr, 306 char *buf) 307{ 308 struct usb_interface *interface = to_usb_interface(dev); 309 struct usb_line6 *line6 = usb_get_intfdata(interface); 310 return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit); 311} 312 313/* 314 "write" request on "midi_mask" special file. 315*/ 316static ssize_t midi_set_midi_mask_transmit(struct device *dev, 317 struct device_attribute *attr, 318 const char *buf, size_t count) 319{ 320 struct usb_interface *interface = to_usb_interface(dev); 321 struct usb_line6 *line6 = usb_get_intfdata(interface); 322 unsigned long value; 323 int ret; 324 325 ret = strict_strtoul(buf, 10, &value); 326 if (ret) 327 return ret; 328 329 line6->line6midi->midi_mask_transmit = value; 330 return count; 331} 332 333/* 334 "read" request on "midi_mask_receive" special file. 335*/ 336static ssize_t midi_get_midi_mask_receive(struct device *dev, 337 struct device_attribute *attr, 338 char *buf) 339{ 340 struct usb_interface *interface = to_usb_interface(dev); 341 struct usb_line6 *line6 = usb_get_intfdata(interface); 342 return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive); 343} 344 345/* 346 "write" request on "midi_mask" special file. 347*/ 348static ssize_t midi_set_midi_mask_receive(struct device *dev, 349 struct device_attribute *attr, 350 const char *buf, size_t count) 351{ 352 struct usb_interface *interface = to_usb_interface(dev); 353 struct usb_line6 *line6 = usb_get_intfdata(interface); 354 unsigned long value; 355 int ret; 356 357 ret = strict_strtoul(buf, 10, &value); 358 if (ret) 359 return ret; 360 361 line6->line6midi->midi_mask_receive = value; 362 return count; 363} 364 365static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); 366static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); 367 368/* MIDI device destructor */ 369static int snd_line6_midi_free(struct snd_device *device) 370{ 371 struct snd_line6_midi *line6midi = device->device_data; 372 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit); 373 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive); 374 midibuf_destroy(&line6midi->midibuf_in); 375 midibuf_destroy(&line6midi->midibuf_out); 376 return 0; 377} 378 379/* 380 Initialize the Line6 MIDI subsystem. 381*/ 382int line6_init_midi(struct usb_line6 *line6) 383{ 384 static struct snd_device_ops midi_ops = { 385 .dev_free = snd_line6_midi_free, 386 }; 387 388 int err; 389 struct snd_line6_midi *line6midi; 390 391 if (!(line6->properties->capabilities & LINE6_BIT_CONTROL)) 392 return 0; /* skip MIDI initialization and report success */ 393 394 line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL); 395 396 if (line6midi == NULL) 397 return -ENOMEM; 398 399 err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); 400 if (err < 0) 401 return err; 402 403 err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); 404 if (err < 0) 405 return err; 406 407 line6midi->line6 = line6; 408 line6midi->midi_mask_transmit = 1; 409 line6midi->midi_mask_receive = 4; 410 line6->line6midi = line6midi; 411 412 err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi, 413 &midi_ops); 414 if (err < 0) 415 return err; 416 417 snd_card_set_dev(line6->card, line6->ifcdev); 418 419 err = snd_line6_new_midi(line6midi); 420 if (err < 0) 421 return err; 422 423 err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit); 424 if (err < 0) 425 return err; 426 427 err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive); 428 if (err < 0) 429 return err; 430 431 init_waitqueue_head(&line6midi->send_wait); 432 spin_lock_init(&line6midi->send_urb_lock); 433 spin_lock_init(&line6midi->midi_transmit_lock); 434 return 0; 435} 436