sb_midi.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * sound/oss/sb_midi.c
  3. *
  4. * The low level driver for the Sound Blaster DS chips.
  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. #include <linux/spinlock.h>
  14. #include "sound_config.h"
  15. #include "sb.h"
  16. #undef SB_TEST_IRQ
  17. /*
  18. * The DSP channel can be used either for input or output. Variable
  19. * 'sb_irq_mode' will be set when the program calls read or write first time
  20. * after open. Current version doesn't support mode changes without closing
  21. * and reopening the device. Support for this feature may be implemented in a
  22. * future version of this driver.
  23. */
  24. static int sb_midi_open(int dev, int mode,
  25. void (*input) (int dev, unsigned char data),
  26. void (*output) (int dev)
  27. )
  28. {
  29. sb_devc *devc = midi_devs[dev]->devc;
  30. unsigned long flags;
  31. if (devc == NULL)
  32. return -ENXIO;
  33. spin_lock_irqsave(&devc->lock, flags);
  34. if (devc->opened)
  35. {
  36. spin_unlock_irqrestore(&devc->lock, flags);
  37. return -EBUSY;
  38. }
  39. devc->opened = 1;
  40. spin_unlock_irqrestore(&devc->lock, flags);
  41. devc->irq_mode = IMODE_MIDI;
  42. devc->midi_broken = 0;
  43. sb_dsp_reset(devc);
  44. if (!sb_dsp_command(devc, 0x35)) /* Start MIDI UART mode */
  45. {
  46. devc->opened = 0;
  47. return -EIO;
  48. }
  49. devc->intr_active = 1;
  50. if (mode & OPEN_READ)
  51. {
  52. devc->input_opened = 1;
  53. devc->midi_input_intr = input;
  54. }
  55. return 0;
  56. }
  57. static void sb_midi_close(int dev)
  58. {
  59. sb_devc *devc = midi_devs[dev]->devc;
  60. unsigned long flags;
  61. if (devc == NULL)
  62. return;
  63. spin_lock_irqsave(&devc->lock, flags);
  64. sb_dsp_reset(devc);
  65. devc->intr_active = 0;
  66. devc->input_opened = 0;
  67. devc->opened = 0;
  68. spin_unlock_irqrestore(&devc->lock, flags);
  69. }
  70. static int sb_midi_out(int dev, unsigned char midi_byte)
  71. {
  72. sb_devc *devc = midi_devs[dev]->devc;
  73. if (devc == NULL)
  74. return 1;
  75. if (devc->midi_broken)
  76. return 1;
  77. if (!sb_dsp_command(devc, midi_byte))
  78. {
  79. devc->midi_broken = 1;
  80. return 1;
  81. }
  82. return 1;
  83. }
  84. static int sb_midi_start_read(int dev)
  85. {
  86. return 0;
  87. }
  88. static int sb_midi_end_read(int dev)
  89. {
  90. sb_devc *devc = midi_devs[dev]->devc;
  91. if (devc == NULL)
  92. return -ENXIO;
  93. sb_dsp_reset(devc);
  94. devc->intr_active = 0;
  95. return 0;
  96. }
  97. static int sb_midi_ioctl(int dev, unsigned cmd, void __user *arg)
  98. {
  99. return -EINVAL;
  100. }
  101. void sb_midi_interrupt(sb_devc * devc)
  102. {
  103. unsigned long flags;
  104. unsigned char data;
  105. if (devc == NULL)
  106. return;
  107. spin_lock_irqsave(&devc->lock, flags);
  108. data = inb(DSP_READ);
  109. if (devc->input_opened)
  110. devc->midi_input_intr(devc->my_mididev, data);
  111. spin_unlock_irqrestore(&devc->lock, flags);
  112. }
  113. #define MIDI_SYNTH_NAME "Sound Blaster Midi"
  114. #define MIDI_SYNTH_CAPS 0
  115. #include "midi_synth.h"
  116. static struct midi_operations sb_midi_operations =
  117. {
  118. .owner = THIS_MODULE,
  119. .info = {"Sound Blaster", 0, 0, SNDCARD_SB},
  120. .converter = &std_midi_synth,
  121. .in_info = {0},
  122. .open = sb_midi_open,
  123. .close = sb_midi_close,
  124. .ioctl = sb_midi_ioctl,
  125. .outputc = sb_midi_out,
  126. .start_read = sb_midi_start_read,
  127. .end_read = sb_midi_end_read,
  128. };
  129. void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
  130. {
  131. int dev;
  132. if (devc->model < 2) /* No MIDI support for SB 1.x */
  133. return;
  134. dev = sound_alloc_mididev();
  135. if (dev == -1)
  136. {
  137. printk(KERN_ERR "sb_midi: too many MIDI devices detected\n");
  138. return;
  139. }
  140. std_midi_synth.midi_dev = devc->my_mididev = dev;
  141. midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
  142. if (midi_devs[dev] == NULL)
  143. {
  144. printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
  145. sound_unload_mididev(dev);
  146. return;
  147. }
  148. memcpy((char *) midi_devs[dev], (char *) &sb_midi_operations,
  149. sizeof(struct midi_operations));
  150. if (owner)
  151. midi_devs[dev]->owner = owner;
  152. midi_devs[dev]->devc = devc;
  153. midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
  154. if (midi_devs[dev]->converter == NULL)
  155. {
  156. printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
  157. kfree(midi_devs[dev]);
  158. sound_unload_mididev(dev);
  159. return;
  160. }
  161. memcpy((char *) midi_devs[dev]->converter, (char *) &std_midi_synth,
  162. sizeof(struct synth_operations));
  163. midi_devs[dev]->converter->id = "SBMIDI";
  164. sequencer_init();
  165. }