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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * PCI sound skeleton example
  3.  *
  4.  * (c) 1998 Red Hat Software
  5.  *
  6.  * This software may be used and distributed according to the 
  7.  * terms of the GNU General Public License, incorporated herein by 
  8.  * reference.
  9.  *
  10.  * This example is designed to be built in the linux/drivers/sound
  11.  * directory as part of a kernel build. The example is modular only
  12.  * drop me a note once you have a working modular driver and want
  13.  * to integrate it with the main code.
  14.  * -- Alan <alan@redhat.com>
  15.  *
  16.  * This is a first draft. Please report any errors, corrections or
  17.  * improvements to me.
  18.  */
  19. #include <linux/module.h>
  20. #include <linux/delay.h>
  21. #include <linux/errno.h>
  22. #include <linux/fs.h>
  23. #include <linux/kernel.h>
  24. #include <linux/pci.h>
  25. #include <asm/io.h>
  26. #include "sound_config.h"
  27. /*
  28.  * Define our PCI vendor ID here
  29.  */
  30.  
  31. #ifndef PCI_VENDOR_MYIDENT
  32. #define PCI_VENDOR_MYIDENT 0x125D
  33. /*
  34.  * PCI identity for the card.
  35.  */
  36.  
  37. #define PCI_DEVICE_ID_MYIDENT_MYCARD1 0x1969
  38. #endif
  39. #define CARD_NAME "ExampleWave 3D Pro Ultra ThingyWotsit"
  40. #define MAX_CARDS 8
  41. /*
  42.  * Each address_info object holds the information about one of
  43.  * our card resources. In this case the MSS emulation of our
  44.  * ficticious card. Its used to manage and attach things.
  45.  */
  46.  
  47. static struct address_info mss_data[MAX_CARDS];
  48. static int  cards = 0;
  49. /*
  50.  * Install the actual card. This is an example
  51.  */
  52. static int mycard_install(struct pci_dev *pcidev)
  53. {
  54. int iobase;
  55. int mssbase;
  56. int mpubase;
  57. u8 x;
  58. u16 w;
  59. u32 v;
  60. int i;
  61. int dma;
  62. /*
  63.  * Our imaginary code has its I/O on PCI address 0, a
  64.  * MSS on PCI address 1 and an MPU on address 2
  65.  *
  66.  * For the example we will only initialise the MSS
  67.  */
  68.  
  69. iobase = pci_resource_start(pcidev, 0);
  70. mssbase = pci_resource_start(pcidev, 1);
  71. mpubase = pci_resource_start(pcidev, 2);
  72. /*
  73.  * Reset the board
  74.  */
  75.  
  76. /*
  77.  * Wait for completion. udelay() waits in microseconds
  78.  */
  79.  
  80. udelay(100);
  81. /*
  82.  * Ok card ready. Begin setup proper. You might for example
  83.  * load the firmware here
  84.  */
  85. dma = card_specific_magic(ioaddr);
  86. /*
  87.  * Turn on legacy mode (example), There are also byte and
  88.  * dword (32bit) PCI configuration function calls
  89.  */
  90. pci_read_config_word(pcidev, 0x40, &w);
  91. w&=~(1<<15); /* legacy decode on */
  92. w|=(1<<14); /* Reserved write as 1 in this case */
  93. w|=(1<<3)|(1<<1)|(1<<0); /* SB on , FM on, MPU on */
  94. pci_write_config_word(pcidev, 0x40, w);
  95. /*
  96.  * Let the user know we found his toy.
  97.  */
  98.  
  99. printk(KERN_INFO "Programmed "CARD_NAME" at 0x%X to legacy mode.n",
  100. iobase);
  101. /*
  102.  * Now set it up the description of the card
  103.  */
  104.  
  105. mss_data[cards].io_base = mssbase;
  106. mss_data[cards].irq = pcidev->irq;
  107. mss_data[cards].dma = dma;
  108. /*
  109.  * Check there is an MSS present
  110.  */
  111. if(ad1848_detect(mssbase, NULL, mss_data[cards].osp)==0)
  112. return 0;
  113. /*
  114.  * Initialize it
  115.  */
  116.  
  117. mss_data[cards].slots[3] = ad1848_init("MyCard MSS 16bit", 
  118. mssbase,
  119. mss_data[cards].irq,
  120. mss_data[cards].dma,
  121. mss_data[cards].dma,
  122. 0,
  123. 0,
  124. THIS_MODULE);
  125. cards++;
  126. return 1;
  127. }
  128. /*
  129.  *  This loop walks the PCI configuration database and finds where
  130.  * the sound cards are.
  131.  */
  132.  
  133. int init_mycard(void)
  134. {
  135. struct pci_dev *pcidev=NULL;
  136. int count=0;
  137. if(!pci_present())
  138. return -ENODEV;
  139. while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
  140. {
  141. if (pci_enable_device(pcidev))
  142. continue;
  143. count+=mycard_install(pcidev);
  144. if(count)
  145. return 0;
  146. if(count==MAX_CARDS)
  147. break;
  148. }
  149. if(count==0)
  150. return -ENODEV;
  151. return 0;
  152. }
  153. /*
  154.  * This function is called when the user or kernel loads the 
  155.  * module into memory.
  156.  */
  157. int init_module(void)
  158. {
  159. if(init_mycard()<0)
  160. {
  161. printk(KERN_ERR "No "CARD_NAME" cards found.n");
  162. return -ENODEV;
  163. }
  164. return 0;
  165. }
  166. /*
  167.  * This is called when it is removed. It will only be removed 
  168.  * when its use count is 0.
  169.  */
  170.  
  171. void cleanup_module(void)
  172. {
  173. for(i=0;i< cards; i++)
  174. {
  175. /*
  176.  * Free attached resources
  177.  */
  178.  
  179. ad1848_unload(mss_data[i].io_base,
  180.       mss_data[i].irq,
  181.       mss_data[i].dma,
  182.       mss_data[i].dma,
  183.       0);
  184. /*
  185.  * And disconnect the device from the kernel
  186.  */
  187. sound_unload_audiodevice(mss_data[i].slots[3]);
  188. }
  189. }