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