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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * sound/sgalaxy.c
  3.  *
  4.  * Low level driver for Aztech Sound Galaxy cards.
  5.  * Copyright 1998 Artur Skawina <skawina@geocities.com>
  6.  *
  7.  * Supported cards:
  8.  *    Aztech Sound Galaxy Waverider Pro 32 - 3D
  9.  *    Aztech Sound Galaxy Washington 16
  10.  *
  11.  * Based on cs4232.c by Hannu Savolainen and Alan Cox.
  12.  *
  13.  *
  14.  * Copyright (C) by Hannu Savolainen 1993-1997
  15.  *
  16.  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  17.  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  18.  * for more info.
  19.  *
  20.  * Changes:
  21.  * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
  22.  * Added __init to sb_rst() and sb_cmd()
  23.  */
  24. #include <linux/init.h>
  25. #include <linux/module.h>
  26. #include "sound_config.h"
  27. #include "ad1848.h"
  28. static void sleep( unsigned howlong )
  29. {
  30. current->state   = TASK_INTERRUPTIBLE;
  31. schedule_timeout(howlong);
  32. }
  33. #define DPORT 0x80
  34. /* Sound Blaster regs */
  35. #define SBDSP_RESET      0x6
  36. #define SBDSP_READ       0xA
  37. #define SBDSP_COMMAND    0xC
  38. #define SBDSP_STATUS     SBDSP_COMMAND
  39. #define SBDSP_DATA_AVAIL 0xE
  40. static int __init sb_rst(int base)
  41. {
  42. int   i;
  43.    
  44. outb( 1, base+SBDSP_RESET );     /* reset the DSP */
  45. outb( 0, base+SBDSP_RESET );
  46.     
  47. for ( i=0; i<500; i++ )          /* delay */
  48. inb(DPORT);
  49.       
  50. for ( i=0; i<100000; i++ )
  51. {
  52. if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
  53. break;
  54. }
  55. if ( inb( base+SBDSP_READ )!=0xAA )
  56. return 0;
  57. return 1;
  58. }
  59. static int __init sb_cmd( int base, unsigned char val )
  60. {
  61. int  i;
  62. for ( i=100000; i; i-- )
  63. {
  64. if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
  65. {
  66.          outb( val, base+SBDSP_COMMAND );
  67.          break;
  68. }
  69. }
  70. return i;      /* i>0 == success */
  71. }
  72. #define ai_sgbase    driver_use_1
  73. static int __init probe_sgalaxy( struct address_info *ai )
  74. {
  75. if ( check_region( ai->io_base, 8 ) ) {
  76. printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not availablen", ai->io_base);
  77. return 0;
  78. }
  79.         
  80. if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
  81. return probe_ms_sound(ai);  /* The card is already active, check irq etc... */
  82. if ( check_region( ai->ai_sgbase, 0x10 ) ) {
  83. printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not availablen", ai->ai_sgbase);
  84. return 0;
  85. }
  86.         
  87. /* switch to MSS/WSS mode */
  88.    
  89. sb_rst( ai->ai_sgbase );
  90.    
  91. sb_cmd( ai->ai_sgbase, 9 );
  92. sb_cmd( ai->ai_sgbase, 0 );
  93. sleep( HZ/10 );
  94.        return probe_ms_sound(ai);
  95. }
  96. static void __init attach_sgalaxy( struct address_info *ai )
  97. {
  98. int n;
  99. request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB" );
  100.  
  101. attach_ms_sound(ai, THIS_MODULE);
  102. n=ai->slots[0];
  103. if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
  104. AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE );   /* Line-in */
  105. AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH );  /* FM+Wavetable*/
  106. AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD );     /* CD */
  107. }
  108. }
  109. static void __exit unload_sgalaxy( struct address_info *ai )
  110. {
  111. unload_ms_sound( ai );
  112. release_region( ai->ai_sgbase, 0x10 );
  113. }
  114. static struct address_info cfg;
  115. static int __initdata io = -1;
  116. static int __initdata irq = -1;
  117. static int __initdata dma = -1;
  118. static int __initdata dma2 = -1;
  119. static int __initdata sgbase = -1;
  120. MODULE_PARM(io,"i");
  121. MODULE_PARM(irq,"i");
  122. MODULE_PARM(dma,"i");
  123. MODULE_PARM(dma2,"i");
  124. MODULE_PARM(sgbase,"i");
  125. static int __init init_sgalaxy(void)
  126. {
  127. cfg.io_base   = io;
  128. cfg.irq       = irq;
  129. cfg.dma       = dma;
  130. cfg.dma2      = dma2;
  131. cfg.ai_sgbase = sgbase;
  132. if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
  133. printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.n");
  134. return -EINVAL;
  135. }
  136. if ( probe_sgalaxy(&cfg) == 0 )
  137. return -ENODEV;
  138. attach_sgalaxy(&cfg);
  139. return 0;
  140. }
  141. static void __exit cleanup_sgalaxy(void)
  142. {
  143. unload_sgalaxy(&cfg);
  144. }
  145. module_init(init_sgalaxy);
  146. module_exit(cleanup_sgalaxy);
  147. #ifndef MODULE
  148. static int __init setup_sgalaxy(char *str)
  149. {
  150. /* io, irq, dma, dma2, sgbase */
  151. int ints[6];
  152. str = get_options(str, ARRAY_SIZE(ints), ints);
  153. io = ints[1];
  154. irq = ints[2];
  155. dma = ints[3];
  156. dma2 = ints[4];
  157. sgbase = ints[5];
  158. return 1;
  159. }
  160. __setup("sgalaxy=", setup_sgalaxy);
  161. #endif
  162. MODULE_LICENSE("GPL");