gus_card.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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