omap2+: add drm device
[pandora-kernel.git] / sound / oss / midi_synth.c
1 /*
2  * sound/oss/midi_synth.c
3  *
4  * High level midi sequencer manager for dumb MIDI interfaces.
5  */
6 /*
7  * Copyright (C) by Hannu Savolainen 1993-1997
8  *
9  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10  * Version 2 (June 1991). See the "COPYING" file distributed with this software
11  * for more info.
12  */
13 /*
14  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
15  * Andrew Veliath  : fixed running status in MIDI input state machine
16  */
17 #define USE_SEQ_MACROS
18 #define USE_SIMPLE_MACROS
19
20 #include "sound_config.h"
21
22 #define _MIDI_SYNTH_C_
23
24 #include "midi_synth.h"
25
26 static int      midi2synth[MAX_MIDI_DEV];
27 static int      sysex_state[MAX_MIDI_DEV] =
28 {0};
29 static unsigned char prev_out_status[MAX_MIDI_DEV];
30
31 #define STORE(cmd) \
32 { \
33   int len; \
34   unsigned char obuf[8]; \
35   cmd; \
36   seq_input_event(obuf, len); \
37 }
38
39 #define _seqbuf obuf
40 #define _seqbufptr 0
41 #define _SEQ_ADVBUF(x) len=x
42
43 void
44 do_midi_msg(int synthno, unsigned char *msg, int mlen)
45 {
46         switch (msg[0] & 0xf0)
47           {
48           case 0x90:
49                   if (msg[2] != 0)
50                     {
51                             STORE(SEQ_START_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
52                             break;
53                     }
54                   msg[2] = 64;
55
56           case 0x80:
57                   STORE(SEQ_STOP_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
58                   break;
59
60           case 0xA0:
61                   STORE(SEQ_KEY_PRESSURE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
62                   break;
63
64           case 0xB0:
65                   STORE(SEQ_CONTROL(synthno, msg[0] & 0x0f,
66                                     msg[1], msg[2]));
67                   break;
68
69           case 0xC0:
70                   STORE(SEQ_SET_PATCH(synthno, msg[0] & 0x0f, msg[1]));
71                   break;
72
73           case 0xD0:
74                   STORE(SEQ_CHN_PRESSURE(synthno, msg[0] & 0x0f, msg[1]));
75                   break;
76
77           case 0xE0:
78                   STORE(SEQ_BENDER(synthno, msg[0] & 0x0f,
79                               (msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7)));
80                   break;
81
82           default:
83                   /* printk( "MPU: Unknown midi channel message %02x\n",  msg[0]); */
84                   ;
85           }
86 }
87 EXPORT_SYMBOL(do_midi_msg);
88
89 static void
90 midi_outc(int midi_dev, int data)
91 {
92         int             timeout;
93
94         for (timeout = 0; timeout < 3200; timeout++)
95                 if (midi_devs[midi_dev]->outputc(midi_dev, (unsigned char) (data & 0xff)))
96                   {
97                           if (data & 0x80)      /*
98                                                  * Status byte
99                                                  */
100                                   prev_out_status[midi_dev] =
101                                       (unsigned char) (data & 0xff);    /*
102                                                                          * Store for running status
103                                                                          */
104                           return;       /*
105                                          * Mission complete
106                                          */
107                   }
108         /*
109          * Sorry! No space on buffers.
110          */
111         printk("Midi send timed out\n");
112 }
113
114 static int
115 prefix_cmd(int midi_dev, unsigned char status)
116 {
117         if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
118                 return 1;
119
120         return midi_devs[midi_dev]->prefix_cmd(midi_dev, status);
121 }
122
123 static void
124 midi_synth_input(int orig_dev, unsigned char data)
125 {
126         int             dev;
127         struct midi_input_info *inc;
128
129         static unsigned char len_tab[] =        /* # of data bytes following a status
130                                                  */
131         {
132                 2,              /* 8x */
133                 2,              /* 9x */
134                 2,              /* Ax */
135                 2,              /* Bx */
136                 1,              /* Cx */
137                 1,              /* Dx */
138                 2,              /* Ex */
139                 0               /* Fx */
140         };
141
142         if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL)
143                 return;
144
145         if (data == 0xfe)       /* Ignore active sensing */
146                 return;
147
148         dev = midi2synth[orig_dev];
149         inc = &midi_devs[orig_dev]->in_info;
150
151         switch (inc->m_state)
152           {
153           case MST_INIT:
154                   if (data & 0x80)      /* MIDI status byte */
155                     {
156                             if ((data & 0xf0) == 0xf0)  /* Common message */
157                               {
158                                       switch (data)
159                                         {
160                                         case 0xf0:      /* Sysex */
161                                                 inc->m_state = MST_SYSEX;
162                                                 break;  /* Sysex */
163
164                                         case 0xf1:      /* MTC quarter frame */
165                                         case 0xf3:      /* Song select */
166                                                 inc->m_state = MST_DATA;
167                                                 inc->m_ptr = 1;
168                                                 inc->m_left = 1;
169                                                 inc->m_buf[0] = data;
170                                                 break;
171
172                                         case 0xf2:      /* Song position pointer */
173                                                 inc->m_state = MST_DATA;
174                                                 inc->m_ptr = 1;
175                                                 inc->m_left = 2;
176                                                 inc->m_buf[0] = data;
177                                                 break;
178
179                                         default:
180                                                 inc->m_buf[0] = data;
181                                                 inc->m_ptr = 1;
182                                                 do_midi_msg(dev, inc->m_buf, inc->m_ptr);
183                                                 inc->m_ptr = 0;
184                                                 inc->m_left = 0;
185                                         }
186                             } else
187                               {
188                                       inc->m_state = MST_DATA;
189                                       inc->m_ptr = 1;
190                                       inc->m_left = len_tab[(data >> 4) - 8];
191                                       inc->m_buf[0] = inc->m_prev_status = data;
192                               }
193                     } else if (inc->m_prev_status & 0x80) {
194                             /* Data byte (use running status) */
195                             inc->m_ptr = 2;
196                             inc->m_buf[1] = data;
197                             inc->m_buf[0] = inc->m_prev_status;
198                             inc->m_left = len_tab[(inc->m_buf[0] >> 4) - 8] - 1;
199                             if (inc->m_left > 0)
200                                     inc->m_state = MST_DATA; /* Not done yet */
201                             else {
202                                     inc->m_state = MST_INIT;
203                                     do_midi_msg(dev, inc->m_buf, inc->m_ptr);
204                                     inc->m_ptr = 0;
205                             }
206                     }
207                   break;        /* MST_INIT */
208
209           case MST_DATA:
210                   inc->m_buf[inc->m_ptr++] = data;
211                   if (--inc->m_left <= 0)
212                     {
213                             inc->m_state = MST_INIT;
214                             do_midi_msg(dev, inc->m_buf, inc->m_ptr);
215                             inc->m_ptr = 0;
216                     }
217                   break;        /* MST_DATA */
218
219           case MST_SYSEX:
220                   if (data == 0xf7)     /* Sysex end */
221                     {
222                             inc->m_state = MST_INIT;
223                             inc->m_left = 0;
224                             inc->m_ptr = 0;
225                     }
226                   break;        /* MST_SYSEX */
227
228           default:
229                   printk("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state, (int) data);
230                   inc->m_state = MST_INIT;
231           }
232 }
233
234 static void
235 leave_sysex(int dev)
236 {
237         int             orig_dev = synth_devs[dev]->midi_dev;
238         int             timeout = 0;
239
240         if (!sysex_state[dev])
241                 return;
242
243         sysex_state[dev] = 0;
244
245         while (!midi_devs[orig_dev]->outputc(orig_dev, 0xf7) &&
246                timeout < 1000)
247                 timeout++;
248
249         sysex_state[dev] = 0;
250 }
251
252 static void
253 midi_synth_output(int dev)
254 {
255         /*
256          * Currently NOP
257          */
258 }
259
260 int midi_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
261 {
262         /*
263          * int orig_dev = synth_devs[dev]->midi_dev;
264          */
265
266         switch (cmd) {
267
268         case SNDCTL_SYNTH_INFO:
269                 if (__copy_to_user(arg, synth_devs[dev]->info, sizeof(struct synth_info)))
270                         return -EFAULT;
271                 return 0;
272                 
273         case SNDCTL_SYNTH_MEMAVL:
274                 return 0x7fffffff;
275
276         default:
277                 return -EINVAL;
278         }
279 }
280 EXPORT_SYMBOL(midi_synth_ioctl);
281
282 int
283 midi_synth_kill_note(int dev, int channel, int note, int velocity)
284 {
285         int             orig_dev = synth_devs[dev]->midi_dev;
286         int             msg, chn;
287
288         if (note < 0 || note > 127)
289                 return 0;
290         if (channel < 0 || channel > 15)
291                 return 0;
292         if (velocity < 0)
293                 velocity = 0;
294         if (velocity > 127)
295                 velocity = 127;
296
297         leave_sysex(dev);
298
299         msg = prev_out_status[orig_dev] & 0xf0;
300         chn = prev_out_status[orig_dev] & 0x0f;
301
302         if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
303           {                     /*
304                                  * Use running status
305                                  */
306                   if (!prefix_cmd(orig_dev, note))
307                           return 0;
308
309                   midi_outc(orig_dev, note);
310
311                   if (msg == 0x90)      /*
312                                          * Running status = Note on
313                                          */
314                           midi_outc(orig_dev, 0);       /*
315                                                            * Note on with velocity 0 == note
316                                                            * off
317                                                          */
318                   else
319                           midi_outc(orig_dev, velocity);
320         } else
321           {
322                   if (velocity == 64)
323                     {
324                             if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
325                                     return 0;
326                             midi_outc(orig_dev, 0x90 | (channel & 0x0f));       /*
327                                                                                  * Note on
328                                                                                  */
329                             midi_outc(orig_dev, note);
330                             midi_outc(orig_dev, 0);     /*
331                                                          * Zero G
332                                                          */
333                   } else
334                     {
335                             if (!prefix_cmd(orig_dev, 0x80 | (channel & 0x0f)))
336                                     return 0;
337                             midi_outc(orig_dev, 0x80 | (channel & 0x0f));       /*
338                                                                                  * Note off
339                                                                                  */
340                             midi_outc(orig_dev, note);
341                             midi_outc(orig_dev, velocity);
342                     }
343           }
344
345         return 0;
346 }
347 EXPORT_SYMBOL(midi_synth_kill_note);
348
349 int
350 midi_synth_set_instr(int dev, int channel, int instr_no)
351 {
352         int             orig_dev = synth_devs[dev]->midi_dev;
353
354         if (instr_no < 0 || instr_no > 127)
355                 instr_no = 0;
356         if (channel < 0 || channel > 15)
357                 return 0;
358
359         leave_sysex(dev);
360
361         if (!prefix_cmd(orig_dev, 0xc0 | (channel & 0x0f)))
362                 return 0;
363         midi_outc(orig_dev, 0xc0 | (channel & 0x0f));   /*
364                                                          * Program change
365                                                          */
366         midi_outc(orig_dev, instr_no);
367
368         return 0;
369 }
370 EXPORT_SYMBOL(midi_synth_set_instr);
371
372 int
373 midi_synth_start_note(int dev, int channel, int note, int velocity)
374 {
375         int             orig_dev = synth_devs[dev]->midi_dev;
376         int             msg, chn;
377
378         if (note < 0 || note > 127)
379                 return 0;
380         if (channel < 0 || channel > 15)
381                 return 0;
382         if (velocity < 0)
383                 velocity = 0;
384         if (velocity > 127)
385                 velocity = 127;
386
387         leave_sysex(dev);
388
389         msg = prev_out_status[orig_dev] & 0xf0;
390         chn = prev_out_status[orig_dev] & 0x0f;
391
392         if (chn == channel && msg == 0x90)
393           {                     /*
394                                  * Use running status
395                                  */
396                   if (!prefix_cmd(orig_dev, note))
397                           return 0;
398                   midi_outc(orig_dev, note);
399                   midi_outc(orig_dev, velocity);
400         } else
401           {
402                   if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
403                           return 0;
404                   midi_outc(orig_dev, 0x90 | (channel & 0x0f));         /*
405                                                                          * Note on
406                                                                          */
407                   midi_outc(orig_dev, note);
408                   midi_outc(orig_dev, velocity);
409           }
410         return 0;
411 }
412 EXPORT_SYMBOL(midi_synth_start_note);
413
414 void
415 midi_synth_reset(int dev)
416 {
417
418         leave_sysex(dev);
419 }
420 EXPORT_SYMBOL(midi_synth_reset);
421
422 int
423 midi_synth_open(int dev, int mode)
424 {
425         int             orig_dev = synth_devs[dev]->midi_dev;
426         int             err;
427         struct midi_input_info *inc;
428
429         if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
430                 return -ENXIO;
431
432         midi2synth[orig_dev] = dev;
433         sysex_state[dev] = 0;
434         prev_out_status[orig_dev] = 0;
435
436         if ((err = midi_devs[orig_dev]->open(orig_dev, mode,
437                                midi_synth_input, midi_synth_output)) < 0)
438                 return err;
439         inc = &midi_devs[orig_dev]->in_info;
440
441         /* save_flags(flags);
442         cli(); 
443         don't know against what irqhandler to protect*/
444         inc->m_busy = 0;
445         inc->m_state = MST_INIT;
446         inc->m_ptr = 0;
447         inc->m_left = 0;
448         inc->m_prev_status = 0x00;
449         /* restore_flags(flags); */
450
451         return 1;
452 }
453 EXPORT_SYMBOL(midi_synth_open);
454
455 void
456 midi_synth_close(int dev)
457 {
458         int             orig_dev = synth_devs[dev]->midi_dev;
459
460         leave_sysex(dev);
461
462         /*
463          * Shut up the synths by sending just single active sensing message.
464          */
465         midi_devs[orig_dev]->outputc(orig_dev, 0xfe);
466
467         midi_devs[orig_dev]->close(orig_dev);
468 }
469 EXPORT_SYMBOL(midi_synth_close);
470
471 void
472 midi_synth_hw_control(int dev, unsigned char *event)
473 {
474 }
475 EXPORT_SYMBOL(midi_synth_hw_control);
476
477 int
478 midi_synth_load_patch(int dev, int format, const char __user *addr,
479                       int count, int pmgr_flag)
480 {
481         int             orig_dev = synth_devs[dev]->midi_dev;
482
483         struct sysex_info sysex;
484         int             i;
485         unsigned long   left, src_offs, eox_seen = 0;
486         int             first_byte = 1;
487         int             hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
488
489         leave_sysex(dev);
490
491         if (!prefix_cmd(orig_dev, 0xf0))
492                 return 0;
493
494         /* Invalid patch format */
495         if (format != SYSEX_PATCH)
496                   return -EINVAL;
497
498         /* Patch header too short */
499         if (count < hdr_size)
500                 return -EINVAL;
501
502         count -= hdr_size;
503
504         /*
505          * Copy the header from user space
506          */
507
508         if (copy_from_user(&sysex, addr, hdr_size))
509                 return -EFAULT;
510
511         /* Sysex record too short */
512         if ((unsigned)count < (unsigned)sysex.len)
513                 sysex.len = count;
514
515         left = sysex.len;
516         src_offs = 0;
517
518         for (i = 0; i < left && !signal_pending(current); i++)
519         {
520                 unsigned char   data;
521
522                 if (get_user(data,
523                     (unsigned char __user *)(addr + hdr_size + i)))
524                         return -EFAULT;
525
526                 eox_seen = (i > 0 && data & 0x80);      /* End of sysex */
527
528                 if (eox_seen && data != 0xf7)
529                         data = 0xf7;
530
531                 if (i == 0)
532                 {
533                         if (data != 0xf0)
534                         {
535                                 printk(KERN_WARNING "midi_synth: Sysex start missing\n");
536                                 return -EINVAL;
537                         }
538                 }
539                 while (!midi_devs[orig_dev]->outputc(orig_dev, (unsigned char) (data & 0xff)) &&
540                         !signal_pending(current))
541                         schedule();
542
543                 if (!first_byte && data & 0x80)
544                         return 0;
545                 first_byte = 0;
546         }
547
548         if (!eox_seen)
549                 midi_outc(orig_dev, 0xf7);
550         return 0;
551 }
552 EXPORT_SYMBOL(midi_synth_load_patch);
553
554 void midi_synth_panning(int dev, int channel, int pressure)
555 {
556 }
557 EXPORT_SYMBOL(midi_synth_panning);
558
559 void midi_synth_aftertouch(int dev, int channel, int pressure)
560 {
561         int             orig_dev = synth_devs[dev]->midi_dev;
562         int             msg, chn;
563
564         if (pressure < 0 || pressure > 127)
565                 return;
566         if (channel < 0 || channel > 15)
567                 return;
568
569         leave_sysex(dev);
570
571         msg = prev_out_status[orig_dev] & 0xf0;
572         chn = prev_out_status[orig_dev] & 0x0f;
573
574         if (msg != 0xd0 || chn != channel)      /*
575                                                  * Test for running status
576                                                  */
577           {
578                   if (!prefix_cmd(orig_dev, 0xd0 | (channel & 0x0f)))
579                           return;
580                   midi_outc(orig_dev, 0xd0 | (channel & 0x0f));         /*
581                                                                          * Channel pressure
582                                                                          */
583         } else if (!prefix_cmd(orig_dev, pressure))
584                 return;
585
586         midi_outc(orig_dev, pressure);
587 }
588 EXPORT_SYMBOL(midi_synth_aftertouch);
589
590 void
591 midi_synth_controller(int dev, int channel, int ctrl_num, int value)
592 {
593         int             orig_dev = synth_devs[dev]->midi_dev;
594         int             chn, msg;
595
596         if (ctrl_num < 0 || ctrl_num > 127)
597                 return;
598         if (channel < 0 || channel > 15)
599                 return;
600
601         leave_sysex(dev);
602
603         msg = prev_out_status[orig_dev] & 0xf0;
604         chn = prev_out_status[orig_dev] & 0x0f;
605
606         if (msg != 0xb0 || chn != channel)
607           {
608                   if (!prefix_cmd(orig_dev, 0xb0 | (channel & 0x0f)))
609                           return;
610                   midi_outc(orig_dev, 0xb0 | (channel & 0x0f));
611         } else if (!prefix_cmd(orig_dev, ctrl_num))
612                 return;
613
614         midi_outc(orig_dev, ctrl_num);
615         midi_outc(orig_dev, value & 0x7f);
616 }
617 EXPORT_SYMBOL(midi_synth_controller);
618
619 void
620 midi_synth_bender(int dev, int channel, int value)
621 {
622         int             orig_dev = synth_devs[dev]->midi_dev;
623         int             msg, prev_chn;
624
625         if (channel < 0 || channel > 15)
626                 return;
627
628         if (value < 0 || value > 16383)
629                 return;
630
631         leave_sysex(dev);
632
633         msg = prev_out_status[orig_dev] & 0xf0;
634         prev_chn = prev_out_status[orig_dev] & 0x0f;
635
636         if (msg != 0xd0 || prev_chn != channel)         /*
637                                                          * Test for running status
638                                                          */
639           {
640                   if (!prefix_cmd(orig_dev, 0xe0 | (channel & 0x0f)))
641                           return;
642                   midi_outc(orig_dev, 0xe0 | (channel & 0x0f));
643         } else if (!prefix_cmd(orig_dev, value & 0x7f))
644                 return;
645
646         midi_outc(orig_dev, value & 0x7f);
647         midi_outc(orig_dev, (value >> 7) & 0x7f);
648 }
649 EXPORT_SYMBOL(midi_synth_bender);
650
651 void
652 midi_synth_setup_voice(int dev, int voice, int channel)
653 {
654 }
655 EXPORT_SYMBOL(midi_synth_setup_voice);
656
657 int
658 midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
659 {
660         int             orig_dev = synth_devs[dev]->midi_dev;
661         int             i;
662
663         for (i = 0; i < len; i++)
664           {
665                   switch (bytes[i])
666                     {
667                     case 0xf0:  /* Start sysex */
668                             if (!prefix_cmd(orig_dev, 0xf0))
669                                     return 0;
670                             sysex_state[dev] = 1;
671                             break;
672
673                     case 0xf7:  /* End sysex */
674                             if (!sysex_state[dev])      /* Orphan sysex end */
675                                     return 0;
676                             sysex_state[dev] = 0;
677                             break;
678
679                     default:
680                             if (!sysex_state[dev])
681                                     return 0;
682
683                             if (bytes[i] & 0x80)        /* Error. Another message before sysex end */
684                               {
685                                       bytes[i] = 0xf7;  /* Sysex end */
686                                       sysex_state[dev] = 0;
687                               }
688                     }
689
690                   if (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]))
691                     {
692 /*
693  * Hardware level buffer is full. Abort the sysex message.
694  */
695
696                             int             timeout = 0;
697
698                             bytes[i] = 0xf7;
699                             sysex_state[dev] = 0;
700
701                             while (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]) &&
702                                    timeout < 1000)
703                                     timeout++;
704                     }
705                   if (!sysex_state[dev])
706                           return 0;
707           }
708
709         return 0;
710 }
711 EXPORT_SYMBOL(midi_synth_send_sysex);
712