~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/sound/skeleton.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.