161864d84STakashi Iwai /* 261864d84STakashi Iwai * Line6 Linux USB driver - 0.9.1beta 361864d84STakashi Iwai * 461864d84STakashi Iwai * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 561864d84STakashi Iwai * 661864d84STakashi Iwai * This program is free software; you can redistribute it and/or 761864d84STakashi Iwai * modify it under the terms of the GNU General Public License as 861864d84STakashi Iwai * published by the Free Software Foundation, version 2. 961864d84STakashi Iwai * 1061864d84STakashi Iwai */ 1161864d84STakashi Iwai 1261864d84STakashi Iwai #include <linux/slab.h> 1361864d84STakashi Iwai #include <linux/usb.h> 14*ccddbe4aSTakashi Iwai #include <linux/export.h> 1561864d84STakashi Iwai #include <sound/core.h> 1661864d84STakashi Iwai #include <sound/rawmidi.h> 1761864d84STakashi Iwai 1861864d84STakashi Iwai #include "audio.h" 1961864d84STakashi Iwai #include "driver.h" 2061864d84STakashi Iwai #include "midi.h" 2161864d84STakashi Iwai #include "usbdefs.h" 2261864d84STakashi Iwai 2361864d84STakashi Iwai #define line6_rawmidi_substream_midi(substream) \ 2461864d84STakashi Iwai ((struct snd_line6_midi *)((substream)->rmidi->private_data)) 2561864d84STakashi Iwai 2661864d84STakashi Iwai static int send_midi_async(struct usb_line6 *line6, unsigned char *data, 2761864d84STakashi Iwai int length); 2861864d84STakashi Iwai 2961864d84STakashi Iwai /* 3061864d84STakashi Iwai Pass data received via USB to MIDI. 3161864d84STakashi Iwai */ 3261864d84STakashi Iwai void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, 3361864d84STakashi Iwai int length) 3461864d84STakashi Iwai { 3561864d84STakashi Iwai if (line6->line6midi->substream_receive) 3661864d84STakashi Iwai snd_rawmidi_receive(line6->line6midi->substream_receive, 3761864d84STakashi Iwai data, length); 3861864d84STakashi Iwai } 3961864d84STakashi Iwai 4061864d84STakashi Iwai /* 4161864d84STakashi Iwai Read data from MIDI buffer and transmit them via USB. 4261864d84STakashi Iwai */ 4361864d84STakashi Iwai static void line6_midi_transmit(struct snd_rawmidi_substream *substream) 4461864d84STakashi Iwai { 4561864d84STakashi Iwai struct usb_line6 *line6 = 4661864d84STakashi Iwai line6_rawmidi_substream_midi(substream)->line6; 4761864d84STakashi Iwai struct snd_line6_midi *line6midi = line6->line6midi; 4861864d84STakashi Iwai struct midi_buffer *mb = &line6midi->midibuf_out; 4961864d84STakashi Iwai unsigned long flags; 5061864d84STakashi Iwai unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE]; 5161864d84STakashi Iwai int req, done; 5261864d84STakashi Iwai 5361864d84STakashi Iwai spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags); 5461864d84STakashi Iwai 5561864d84STakashi Iwai for (;;) { 5661864d84STakashi Iwai req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size); 5761864d84STakashi Iwai done = snd_rawmidi_transmit_peek(substream, chunk, req); 5861864d84STakashi Iwai 5961864d84STakashi Iwai if (done == 0) 6061864d84STakashi Iwai break; 6161864d84STakashi Iwai 6261864d84STakashi Iwai line6_midibuf_write(mb, chunk, done); 6361864d84STakashi Iwai snd_rawmidi_transmit_ack(substream, done); 6461864d84STakashi Iwai } 6561864d84STakashi Iwai 6661864d84STakashi Iwai for (;;) { 6761864d84STakashi Iwai done = line6_midibuf_read(mb, chunk, 6861864d84STakashi Iwai LINE6_FALLBACK_MAXPACKETSIZE); 6961864d84STakashi Iwai 7061864d84STakashi Iwai if (done == 0) 7161864d84STakashi Iwai break; 7261864d84STakashi Iwai 7361864d84STakashi Iwai send_midi_async(line6, chunk, done); 7461864d84STakashi Iwai } 7561864d84STakashi Iwai 7661864d84STakashi Iwai spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags); 7761864d84STakashi Iwai } 7861864d84STakashi Iwai 7961864d84STakashi Iwai /* 8061864d84STakashi Iwai Notification of completion of MIDI transmission. 8161864d84STakashi Iwai */ 8261864d84STakashi Iwai static void midi_sent(struct urb *urb) 8361864d84STakashi Iwai { 8461864d84STakashi Iwai unsigned long flags; 8561864d84STakashi Iwai int status; 8661864d84STakashi Iwai int num; 8761864d84STakashi Iwai struct usb_line6 *line6 = (struct usb_line6 *)urb->context; 8861864d84STakashi Iwai 8961864d84STakashi Iwai status = urb->status; 9061864d84STakashi Iwai kfree(urb->transfer_buffer); 9161864d84STakashi Iwai usb_free_urb(urb); 9261864d84STakashi Iwai 9361864d84STakashi Iwai if (status == -ESHUTDOWN) 9461864d84STakashi Iwai return; 9561864d84STakashi Iwai 9661864d84STakashi Iwai spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 9761864d84STakashi Iwai num = --line6->line6midi->num_active_send_urbs; 9861864d84STakashi Iwai 9961864d84STakashi Iwai if (num == 0) { 10061864d84STakashi Iwai line6_midi_transmit(line6->line6midi->substream_transmit); 10161864d84STakashi Iwai num = line6->line6midi->num_active_send_urbs; 10261864d84STakashi Iwai } 10361864d84STakashi Iwai 10461864d84STakashi Iwai if (num == 0) 10561864d84STakashi Iwai wake_up(&line6->line6midi->send_wait); 10661864d84STakashi Iwai 10761864d84STakashi Iwai spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 10861864d84STakashi Iwai } 10961864d84STakashi Iwai 11061864d84STakashi Iwai /* 11161864d84STakashi Iwai Send an asynchronous MIDI message. 11261864d84STakashi Iwai Assumes that line6->line6midi->send_urb_lock is held 11361864d84STakashi Iwai (i.e., this function is serialized). 11461864d84STakashi Iwai */ 11561864d84STakashi Iwai static int send_midi_async(struct usb_line6 *line6, unsigned char *data, 11661864d84STakashi Iwai int length) 11761864d84STakashi Iwai { 11861864d84STakashi Iwai struct urb *urb; 11961864d84STakashi Iwai int retval; 12061864d84STakashi Iwai unsigned char *transfer_buffer; 12161864d84STakashi Iwai 12261864d84STakashi Iwai urb = usb_alloc_urb(0, GFP_ATOMIC); 12361864d84STakashi Iwai 12461864d84STakashi Iwai if (urb == NULL) { 12561864d84STakashi Iwai dev_err(line6->ifcdev, "Out of memory\n"); 12661864d84STakashi Iwai return -ENOMEM; 12761864d84STakashi Iwai } 12861864d84STakashi Iwai 12961864d84STakashi Iwai transfer_buffer = kmemdup(data, length, GFP_ATOMIC); 13061864d84STakashi Iwai 13161864d84STakashi Iwai if (transfer_buffer == NULL) { 13261864d84STakashi Iwai usb_free_urb(urb); 13361864d84STakashi Iwai dev_err(line6->ifcdev, "Out of memory\n"); 13461864d84STakashi Iwai return -ENOMEM; 13561864d84STakashi Iwai } 13661864d84STakashi Iwai 13761864d84STakashi Iwai usb_fill_int_urb(urb, line6->usbdev, 13861864d84STakashi Iwai usb_sndbulkpipe(line6->usbdev, 13961864d84STakashi Iwai line6->properties->ep_ctrl_w), 14061864d84STakashi Iwai transfer_buffer, length, midi_sent, line6, 14161864d84STakashi Iwai line6->interval); 14261864d84STakashi Iwai urb->actual_length = 0; 14361864d84STakashi Iwai retval = usb_submit_urb(urb, GFP_ATOMIC); 14461864d84STakashi Iwai 14561864d84STakashi Iwai if (retval < 0) { 14661864d84STakashi Iwai dev_err(line6->ifcdev, "usb_submit_urb failed\n"); 14761864d84STakashi Iwai usb_free_urb(urb); 14861864d84STakashi Iwai return retval; 14961864d84STakashi Iwai } 15061864d84STakashi Iwai 15161864d84STakashi Iwai ++line6->line6midi->num_active_send_urbs; 15261864d84STakashi Iwai return 0; 15361864d84STakashi Iwai } 15461864d84STakashi Iwai 15561864d84STakashi Iwai static int line6_midi_output_open(struct snd_rawmidi_substream *substream) 15661864d84STakashi Iwai { 15761864d84STakashi Iwai return 0; 15861864d84STakashi Iwai } 15961864d84STakashi Iwai 16061864d84STakashi Iwai static int line6_midi_output_close(struct snd_rawmidi_substream *substream) 16161864d84STakashi Iwai { 16261864d84STakashi Iwai return 0; 16361864d84STakashi Iwai } 16461864d84STakashi Iwai 16561864d84STakashi Iwai static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream, 16661864d84STakashi Iwai int up) 16761864d84STakashi Iwai { 16861864d84STakashi Iwai unsigned long flags; 16961864d84STakashi Iwai struct usb_line6 *line6 = 17061864d84STakashi Iwai line6_rawmidi_substream_midi(substream)->line6; 17161864d84STakashi Iwai 17261864d84STakashi Iwai line6->line6midi->substream_transmit = substream; 17361864d84STakashi Iwai spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 17461864d84STakashi Iwai 17561864d84STakashi Iwai if (line6->line6midi->num_active_send_urbs == 0) 17661864d84STakashi Iwai line6_midi_transmit(substream); 17761864d84STakashi Iwai 17861864d84STakashi Iwai spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 17961864d84STakashi Iwai } 18061864d84STakashi Iwai 18161864d84STakashi Iwai static void line6_midi_output_drain(struct snd_rawmidi_substream *substream) 18261864d84STakashi Iwai { 18361864d84STakashi Iwai struct usb_line6 *line6 = 18461864d84STakashi Iwai line6_rawmidi_substream_midi(substream)->line6; 18561864d84STakashi Iwai struct snd_line6_midi *midi = line6->line6midi; 18661864d84STakashi Iwai 18761864d84STakashi Iwai wait_event_interruptible(midi->send_wait, 18861864d84STakashi Iwai midi->num_active_send_urbs == 0); 18961864d84STakashi Iwai } 19061864d84STakashi Iwai 19161864d84STakashi Iwai static int line6_midi_input_open(struct snd_rawmidi_substream *substream) 19261864d84STakashi Iwai { 19361864d84STakashi Iwai return 0; 19461864d84STakashi Iwai } 19561864d84STakashi Iwai 19661864d84STakashi Iwai static int line6_midi_input_close(struct snd_rawmidi_substream *substream) 19761864d84STakashi Iwai { 19861864d84STakashi Iwai return 0; 19961864d84STakashi Iwai } 20061864d84STakashi Iwai 20161864d84STakashi Iwai static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream, 20261864d84STakashi Iwai int up) 20361864d84STakashi Iwai { 20461864d84STakashi Iwai struct usb_line6 *line6 = 20561864d84STakashi Iwai line6_rawmidi_substream_midi(substream)->line6; 20661864d84STakashi Iwai 20761864d84STakashi Iwai if (up) 20861864d84STakashi Iwai line6->line6midi->substream_receive = substream; 20961864d84STakashi Iwai else 21061864d84STakashi Iwai line6->line6midi->substream_receive = NULL; 21161864d84STakashi Iwai } 21261864d84STakashi Iwai 21361864d84STakashi Iwai static struct snd_rawmidi_ops line6_midi_output_ops = { 21461864d84STakashi Iwai .open = line6_midi_output_open, 21561864d84STakashi Iwai .close = line6_midi_output_close, 21661864d84STakashi Iwai .trigger = line6_midi_output_trigger, 21761864d84STakashi Iwai .drain = line6_midi_output_drain, 21861864d84STakashi Iwai }; 21961864d84STakashi Iwai 22061864d84STakashi Iwai static struct snd_rawmidi_ops line6_midi_input_ops = { 22161864d84STakashi Iwai .open = line6_midi_input_open, 22261864d84STakashi Iwai .close = line6_midi_input_close, 22361864d84STakashi Iwai .trigger = line6_midi_input_trigger, 22461864d84STakashi Iwai }; 22561864d84STakashi Iwai 22661864d84STakashi Iwai /* 22761864d84STakashi Iwai Cleanup the Line6 MIDI device. 22861864d84STakashi Iwai */ 22961864d84STakashi Iwai static void line6_cleanup_midi(struct snd_rawmidi *rmidi) 23061864d84STakashi Iwai { 23161864d84STakashi Iwai } 23261864d84STakashi Iwai 23361864d84STakashi Iwai /* Create a MIDI device */ 23461864d84STakashi Iwai static int snd_line6_new_midi(struct snd_line6_midi *line6midi) 23561864d84STakashi Iwai { 23661864d84STakashi Iwai struct snd_rawmidi *rmidi; 23761864d84STakashi Iwai int err; 23861864d84STakashi Iwai 23961864d84STakashi Iwai err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1, 24061864d84STakashi Iwai &rmidi); 24161864d84STakashi Iwai if (err < 0) 24261864d84STakashi Iwai return err; 24361864d84STakashi Iwai 24461864d84STakashi Iwai rmidi->private_data = line6midi; 24561864d84STakashi Iwai rmidi->private_free = line6_cleanup_midi; 24661864d84STakashi Iwai strcpy(rmidi->id, line6midi->line6->properties->id); 24761864d84STakashi Iwai strcpy(rmidi->name, line6midi->line6->properties->name); 24861864d84STakashi Iwai 24961864d84STakashi Iwai rmidi->info_flags = 25061864d84STakashi Iwai SNDRV_RAWMIDI_INFO_OUTPUT | 25161864d84STakashi Iwai SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; 25261864d84STakashi Iwai 25361864d84STakashi Iwai snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 25461864d84STakashi Iwai &line6_midi_output_ops); 25561864d84STakashi Iwai snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 25661864d84STakashi Iwai &line6_midi_input_ops); 25761864d84STakashi Iwai return 0; 25861864d84STakashi Iwai } 25961864d84STakashi Iwai 26061864d84STakashi Iwai /* MIDI device destructor */ 26161864d84STakashi Iwai static int snd_line6_midi_free(struct snd_device *device) 26261864d84STakashi Iwai { 26361864d84STakashi Iwai struct snd_line6_midi *line6midi = device->device_data; 26461864d84STakashi Iwai 26561864d84STakashi Iwai line6_midibuf_destroy(&line6midi->midibuf_in); 26661864d84STakashi Iwai line6_midibuf_destroy(&line6midi->midibuf_out); 26761864d84STakashi Iwai return 0; 26861864d84STakashi Iwai } 26961864d84STakashi Iwai 27061864d84STakashi Iwai /* 27161864d84STakashi Iwai Initialize the Line6 MIDI subsystem. 27261864d84STakashi Iwai */ 27361864d84STakashi Iwai int line6_init_midi(struct usb_line6 *line6) 27461864d84STakashi Iwai { 27561864d84STakashi Iwai static struct snd_device_ops midi_ops = { 27661864d84STakashi Iwai .dev_free = snd_line6_midi_free, 27761864d84STakashi Iwai }; 27861864d84STakashi Iwai 27961864d84STakashi Iwai int err; 28061864d84STakashi Iwai struct snd_line6_midi *line6midi; 28161864d84STakashi Iwai 28261864d84STakashi Iwai if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { 28361864d84STakashi Iwai /* skip MIDI initialization and report success */ 28461864d84STakashi Iwai return 0; 28561864d84STakashi Iwai } 28661864d84STakashi Iwai 28761864d84STakashi Iwai line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL); 28861864d84STakashi Iwai 28961864d84STakashi Iwai if (line6midi == NULL) 29061864d84STakashi Iwai return -ENOMEM; 29161864d84STakashi Iwai 29261864d84STakashi Iwai err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); 29361864d84STakashi Iwai if (err < 0) { 29461864d84STakashi Iwai kfree(line6midi); 29561864d84STakashi Iwai return err; 29661864d84STakashi Iwai } 29761864d84STakashi Iwai 29861864d84STakashi Iwai err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); 29961864d84STakashi Iwai if (err < 0) { 30061864d84STakashi Iwai kfree(line6midi->midibuf_in.buf); 30161864d84STakashi Iwai kfree(line6midi); 30261864d84STakashi Iwai return err; 30361864d84STakashi Iwai } 30461864d84STakashi Iwai 30561864d84STakashi Iwai line6midi->line6 = line6; 30661864d84STakashi Iwai line6->line6midi = line6midi; 30761864d84STakashi Iwai 30861864d84STakashi Iwai err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi, 30961864d84STakashi Iwai &midi_ops); 31061864d84STakashi Iwai if (err < 0) 31161864d84STakashi Iwai return err; 31261864d84STakashi Iwai 31361864d84STakashi Iwai err = snd_line6_new_midi(line6midi); 31461864d84STakashi Iwai if (err < 0) 31561864d84STakashi Iwai return err; 31661864d84STakashi Iwai 31761864d84STakashi Iwai init_waitqueue_head(&line6midi->send_wait); 31861864d84STakashi Iwai spin_lock_init(&line6midi->send_urb_lock); 31961864d84STakashi Iwai spin_lock_init(&line6midi->midi_transmit_lock); 32061864d84STakashi Iwai return 0; 32161864d84STakashi Iwai } 322*ccddbe4aSTakashi Iwai EXPORT_SYMBOL_GPL(line6_init_midi); 323