File: /usr/src/linux/drivers/sound/skeleton.c

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     
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