gus_card.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * sound/gus_card.c
  3. *
  4. * Detection routine for the Gravis Ultrasound.
  5. *
  6. * Copyright (C) by Hannu Savolainen 1993-1997
  7. *
  8. *
  9. * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
  10. * usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
  11. * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
  12. *
  13. * Status:
  14. * Tested...
  15. */
  16. #include <linux/config.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/module.h>
  20. #include "sound_config.h"
  21. #include "gus.h"
  22. #include "gus_hw.h"
  23. irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy);
  24. int gus_base = 0, gus_irq = 0, gus_dma = 0;
  25. int gus_no_wave_dma = 0;
  26. extern int gus_wave_volume;
  27. extern int gus_pcm_volume;
  28. extern int have_gus_max;
  29. int gus_pnp_flag = 0;
  30. #ifdef CONFIG_SOUND_GUS16
  31. static int db16; /* Has a Gus16 AD1848 on it */
  32. #endif
  33. static void __init attach_gus(struct address_info *hw_config)
  34. {
  35. gus_wave_init(hw_config);
  36. if (sound_alloc_dma(hw_config->dma, "GUS"))
  37. printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
  38. if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
  39. if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
  40. printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
  41. gus_midi_init(hw_config);
  42. if(request_irq(hw_config->irq, gusintr, 0, "Gravis Ultrasound", hw_config)<0)
  43. printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
  44. return;
  45. }
  46. static int __init probe_gus(struct address_info *hw_config)
  47. {
  48. int irq;
  49. int io_addr;
  50. if (hw_config->card_subtype == 1)
  51. gus_pnp_flag = 1;
  52. irq = hw_config->irq;
  53. if (hw_config->card_subtype == 0) /* GUS/MAX/ACE */
  54. if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
  55. irq != 11 && irq != 12 && irq != 15)
  56. {
  57. printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
  58. return 0;
  59. }
  60. if (gus_wave_detect(hw_config->io_base))
  61. return 1;
  62. #ifndef EXCLUDE_GUS_IODETECT
  63. /*
  64. * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
  65. */
  66. for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) {
  67. if (io_addr == hw_config->io_base) /* Already tested */
  68. continue;
  69. if (gus_wave_detect(io_addr)) {
  70. hw_config->io_base = io_addr;
  71. return 1;
  72. }
  73. }
  74. #endif
  75. printk("NO GUS card found !\n");
  76. return 0;
  77. }
  78. static void __exit unload_gus(struct address_info *hw_config)
  79. {
  80. DDB(printk("unload_gus(%x)\n", hw_config->io_base));
  81. gus_wave_unload(hw_config);
  82. release_region(hw_config->io_base, 16);
  83. release_region(hw_config->io_base + 0x100, 12); /* 0x10c-> is MAX */
  84. free_irq(hw_config->irq, hw_config);
  85. sound_free_dma(hw_config->dma);
  86. if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
  87. sound_free_dma(hw_config->dma2);
  88. }
  89. irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy)
  90. {
  91. unsigned char src;
  92. extern int gus_timer_enabled;
  93. int handled = 0;
  94. #ifdef CONFIG_SOUND_GUSMAX
  95. if (have_gus_max) {
  96. struct address_info *hw_config = dev_id;
  97. adintr(irq, (void *)hw_config->slots[1], NULL);
  98. }
  99. #endif
  100. #ifdef CONFIG_SOUND_GUS16
  101. if (db16) {
  102. struct address_info *hw_config = dev_id;
  103. adintr(irq, (void *)hw_config->slots[3], NULL);
  104. }
  105. #endif
  106. while (1)
  107. {
  108. if (!(src = inb(u_IrqStatus)))
  109. break;
  110. handled = 1;
  111. if (src & DMA_TC_IRQ)
  112. {
  113. guswave_dma_irq();
  114. }
  115. if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
  116. {
  117. gus_midi_interrupt(0);
  118. }
  119. if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
  120. {
  121. if (gus_timer_enabled)
  122. sound_timer_interrupt();
  123. gus_write8(0x45, 0); /* Ack IRQ */
  124. gus_timer_command(4, 0x80); /* Reset IRQ flags */
  125. }
  126. if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
  127. gus_voice_irq();
  128. }
  129. return IRQ_RETVAL(handled);
  130. }
  131. /*
  132. * Some extra code for the 16 bit sampling option
  133. */
  134. #ifdef CONFIG_SOUND_GUS16
  135. static int __init init_gus_db16(struct address_info *hw_config)
  136. {
  137. struct resource *ports;
  138. ports = request_region(hw_config->io_base, 4, "ad1848");
  139. if (!ports)
  140. return 0;
  141. if (!ad1848_detect(ports, NULL, hw_config->osp)) {
  142. release_region(hw_config->io_base, 4);
  143. return 0;
  144. }
  145. gus_pcm_volume = 100;
  146. gus_wave_volume = 90;
  147. hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports,
  148. hw_config->irq,
  149. hw_config->dma,
  150. hw_config->dma, 0,
  151. hw_config->osp,
  152. THIS_MODULE);
  153. return 1;
  154. }
  155. static void __exit unload_gus_db16(struct address_info *hw_config)
  156. {
  157. ad1848_unload(hw_config->io_base,
  158. hw_config->irq,
  159. hw_config->dma,
  160. hw_config->dma, 0);
  161. sound_unload_audiodev(hw_config->slots[3]);
  162. }
  163. #endif
  164. #ifdef CONFIG_SOUND_GUS16
  165. static int gus16;
  166. #endif
  167. #ifdef CONFIG_SOUND_GUSMAX
  168. static int no_wave_dma; /* Set if no dma is to be used for the
  169. wave table (GF1 chip) */
  170. #endif
  171. /*
  172. * Note DMA2 of -1 has the right meaning in the GUS driver as well
  173. * as here.
  174. */
  175. static struct address_info cfg;
  176. static int __initdata io = -1;
  177. static int __initdata irq = -1;
  178. static int __initdata dma = -1;
  179. static int __initdata dma16 = -1; /* Set this for modules that need it */
  180. static int __initdata type = 0; /* 1 for PnP */
  181. module_param(io, int, 0);
  182. module_param(irq, int, 0);
  183. module_param(dma, int, 0);
  184. module_param(dma16, int, 0);
  185. module_param(type, int, 0);
  186. #ifdef CONFIG_SOUND_GUSMAX
  187. module_param(no_wave_dma, int, 0);
  188. #endif
  189. #ifdef CONFIG_SOUND_GUS16
  190. module_param(db16, int, 0);
  191. module_param(gus16, int, 0);
  192. #endif
  193. MODULE_LICENSE("GPL");
  194. static int __init init_gus(void)
  195. {
  196. printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
  197. cfg.io_base = io;
  198. cfg.irq = irq;
  199. cfg.dma = dma;
  200. cfg.dma2 = dma16;
  201. cfg.card_subtype = type;
  202. #ifdef CONFIG_SOUND_GUSMAX
  203. gus_no_wave_dma = no_wave_dma;
  204. #endif
  205. if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
  206. printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
  207. return -EINVAL;
  208. }
  209. #ifdef CONFIG_SOUND_GUS16
  210. if (gus16 && init_gus_db16(&cfg))
  211. db16 = 1;
  212. #endif
  213. if (!probe_gus(&cfg))
  214. return -ENODEV;
  215. attach_gus(&cfg);
  216. return 0;
  217. }
  218. static void __exit cleanup_gus(void)
  219. {
  220. #ifdef CONFIG_SOUND_GUS16
  221. if (db16)
  222. unload_gus_db16(&cfg);
  223. #endif
  224. unload_gus(&cfg);
  225. }
  226. module_init(init_gus);
  227. module_exit(cleanup_gus);
  228. #ifndef MODULE
  229. static int __init setup_gus(char *str)
  230. {
  231. /* io, irq, dma, dma2 */
  232. int ints[5];
  233. str = get_options(str, ARRAY_SIZE(ints), ints);
  234. io = ints[1];
  235. irq = ints[2];
  236. dma = ints[3];
  237. dma16 = ints[4];
  238. return 1;
  239. }
  240. __setup("gus=", setup_gus);
  241. #endif