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 
mycard_install(struct pci_dev * pcidev)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 
init_mycard(void)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 
init_module(void)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 
cleanup_module(void)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