]>
Commit | Line | Data |
---|---|---|
961b7146 AM |
1 | 30_btaudio |
2 | diff -u linux-2.4.23-pre7/drivers/sound/btaudio.c linux/drivers/sound/btaudio.c | |
3 | --- linux-2.4.23-pre7/drivers/sound/btaudio.c 2003-10-10 13:36:01.413814360 +0200 | |
4 | +++ linux/drivers/sound/btaudio.c 2003-10-10 15:04:24.120070522 +0200 | |
5 | @@ -1,7 +1,7 @@ | |
6 | /* | |
7 | - btaudio - bt878 audio dma driver for linux 2.4.x | |
8 | + btaudio - bt878 audio dma driver for linux 2.4 / 2.5 | |
9 | ||
10 | - (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org> | |
11 | + (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org> | |
12 | ||
13 | This program is free software; you can redistribute it and/or modify | |
14 | it under the terms of the GNU General Public License as published by | |
15 | @@ -19,14 +19,12 @@ | |
16 | ||
17 | */ | |
18 | ||
19 | -#include <linux/version.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/errno.h> | |
22 | #include <linux/pci.h> | |
23 | #include <linux/sched.h> | |
24 | #include <linux/signal.h> | |
25 | #include <linux/types.h> | |
26 | -#include <linux/wrapper.h> | |
27 | #include <linux/interrupt.h> | |
28 | #include <linux/init.h> | |
29 | #include <linux/poll.h> | |
30 | @@ -37,6 +35,8 @@ | |
31 | #include <asm/uaccess.h> | |
32 | #include <asm/io.h> | |
33 | ||
34 | +# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) | |
35 | +# define iminor(inode) minor(inode->i_rdev) | |
36 | ||
37 | /* mmio access */ | |
38 | #define btwrite(dat,adr) writel((dat), (bta->mmio+(adr))) | |
39 | @@ -152,15 +152,30 @@ | |
40 | int rate; | |
41 | }; | |
42 | ||
43 | -static struct btaudio *btaudios = NULL; | |
44 | -static unsigned int debug = 0; | |
45 | -static unsigned int irq_debug = 0; | |
46 | +static struct btaudio *btaudios = NULL; | |
47 | +static unsigned int btcount = 0; | |
48 | +static unsigned int debug = 0; | |
49 | +static unsigned int irq_debug = 0; | |
50 | ||
51 | /* -------------------------------------------------------------- */ | |
52 | ||
53 | #define BUF_DEFAULT 128*1024 | |
54 | #define BUF_MIN 8192 | |
55 | ||
56 | +static void free_buffer(struct btaudio *bta) | |
57 | +{ | |
58 | + if (NULL != bta->buf_cpu) { | |
59 | + pci_free_consistent(bta->pci, bta->buf_size, | |
60 | + bta->buf_cpu, bta->buf_dma); | |
61 | + bta->buf_cpu = NULL; | |
62 | + } | |
63 | + if (NULL != bta->risc_cpu) { | |
64 | + pci_free_consistent(bta->pci, bta->risc_size, | |
65 | + bta->risc_cpu, bta->risc_dma); | |
66 | + bta->risc_cpu = NULL; | |
67 | + } | |
68 | +} | |
69 | + | |
70 | static int alloc_buffer(struct btaudio *bta) | |
71 | { | |
72 | if (NULL == bta->buf_cpu) { | |
73 | @@ -172,7 +187,7 @@ | |
74 | break; | |
75 | } | |
76 | if (NULL == bta->buf_cpu) | |
77 | - return -ENOMEM; | |
78 | + goto err; | |
79 | memset(bta->buf_cpu,0,bta->buf_size); | |
80 | } | |
81 | if (NULL == bta->risc_cpu) { | |
82 | @@ -180,23 +195,13 @@ | |
83 | bta->risc_cpu = pci_alloc_consistent | |
84 | (bta->pci, bta->risc_size, &bta->risc_dma); | |
85 | if (NULL == bta->risc_cpu) | |
86 | - return -ENOMEM; | |
87 | + goto err; | |
88 | } | |
89 | return 0; | |
90 | -} | |
91 | ||
92 | -static void free_buffer(struct btaudio *bta) | |
93 | -{ | |
94 | - if (NULL != bta->buf_cpu) { | |
95 | - pci_free_consistent(bta->pci, bta->buf_size, | |
96 | - bta->buf_cpu, bta->buf_dma); | |
97 | - bta->buf_cpu = NULL; | |
98 | - } | |
99 | - if (NULL != bta->risc_cpu) { | |
100 | - pci_free_consistent(bta->pci, bta->risc_size, | |
101 | - bta->risc_cpu, bta->risc_dma); | |
102 | - bta->risc_cpu = NULL; | |
103 | - } | |
104 | + err: | |
105 | + free_buffer(bta); | |
106 | + return -ENOMEM; | |
107 | } | |
108 | ||
109 | static int make_risc(struct btaudio *bta) | |
110 | @@ -301,7 +306,7 @@ | |
111 | ||
112 | static int btaudio_mixer_open(struct inode *inode, struct file *file) | |
113 | { | |
114 | - int minor = minor(inode->i_rdev); | |
115 | + int minor = iminor(inode); | |
116 | struct btaudio *bta; | |
117 | ||
118 | for (bta = btaudios; bta != NULL; bta = bta->next) | |
119 | @@ -330,8 +335,8 @@ | |
120 | if (cmd == SOUND_MIXER_INFO) { | |
121 | mixer_info info; | |
122 | memset(&info,0,sizeof(info)); | |
123 | - strncpy(info.id,"bt878",sizeof(info.id)-1); | |
124 | - strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1); | |
125 | + strlcpy(info.id,"bt878",sizeof(info.id)); | |
126 | + strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); | |
127 | info.modify_counter = bta->mixcount; | |
128 | if (copy_to_user((void *)arg, &info, sizeof(info))) | |
129 | return -EFAULT; | |
130 | @@ -340,8 +345,8 @@ | |
131 | if (cmd == SOUND_OLD_MIXER_INFO) { | |
132 | _old_mixer_info info; | |
133 | memset(&info,0,sizeof(info)); | |
134 | - strncpy(info.id,"bt878",sizeof(info.id)-1); | |
135 | - strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1); | |
136 | + strlcpy(info.id,"bt878",sizeof(info.id)); | |
137 | + strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); | |
138 | if (copy_to_user((void *)arg, &info, sizeof(info))) | |
139 | return -EFAULT; | |
140 | return 0; | |
141 | @@ -426,11 +431,11 @@ | |
142 | } | |
143 | ||
144 | static struct file_operations btaudio_mixer_fops = { | |
145 | - owner: THIS_MODULE, | |
146 | - llseek: no_llseek, | |
147 | - open: btaudio_mixer_open, | |
148 | - release: btaudio_mixer_release, | |
149 | - ioctl: btaudio_mixer_ioctl, | |
150 | + .owner = THIS_MODULE, | |
151 | + .llseek = no_llseek, | |
152 | + .open = btaudio_mixer_open, | |
153 | + .release = btaudio_mixer_release, | |
154 | + .ioctl = btaudio_mixer_ioctl, | |
155 | }; | |
156 | ||
157 | /* -------------------------------------------------------------- */ | |
158 | @@ -460,7 +465,7 @@ | |
159 | ||
160 | static int btaudio_dsp_open_digital(struct inode *inode, struct file *file) | |
161 | { | |
162 | - int minor = minor(inode->i_rdev); | |
163 | + int minor = iminor(inode); | |
164 | struct btaudio *bta; | |
165 | ||
166 | for (bta = btaudios; bta != NULL; bta = bta->next) | |
167 | @@ -476,7 +481,7 @@ | |
168 | ||
169 | static int btaudio_dsp_open_analog(struct inode *inode, struct file *file) | |
170 | { | |
171 | - int minor = minor(inode->i_rdev); | |
172 | + int minor = iminor(inode); | |
173 | struct btaudio *bta; | |
174 | ||
175 | for (bta = btaudios; bta != NULL; bta = bta->next) | |
176 | @@ -791,25 +796,25 @@ | |
177 | } | |
178 | ||
179 | static struct file_operations btaudio_digital_dsp_fops = { | |
180 | - owner: THIS_MODULE, | |
181 | - llseek: no_llseek, | |
182 | - open: btaudio_dsp_open_digital, | |
183 | - release: btaudio_dsp_release, | |
184 | - read: btaudio_dsp_read, | |
185 | - write: btaudio_dsp_write, | |
186 | - ioctl: btaudio_dsp_ioctl, | |
187 | - poll: btaudio_dsp_poll, | |
188 | + .owner = THIS_MODULE, | |
189 | + .llseek = no_llseek, | |
190 | + .open = btaudio_dsp_open_digital, | |
191 | + .release = btaudio_dsp_release, | |
192 | + .read = btaudio_dsp_read, | |
193 | + .write = btaudio_dsp_write, | |
194 | + .ioctl = btaudio_dsp_ioctl, | |
195 | + .poll = btaudio_dsp_poll, | |
196 | }; | |
197 | ||
198 | static struct file_operations btaudio_analog_dsp_fops = { | |
199 | - owner: THIS_MODULE, | |
200 | - llseek: no_llseek, | |
201 | - open: btaudio_dsp_open_analog, | |
202 | - release: btaudio_dsp_release, | |
203 | - read: btaudio_dsp_read, | |
204 | - write: btaudio_dsp_write, | |
205 | - ioctl: btaudio_dsp_ioctl, | |
206 | - poll: btaudio_dsp_poll, | |
207 | + .owner = THIS_MODULE, | |
208 | + .llseek = no_llseek, | |
209 | + .open = btaudio_dsp_open_analog, | |
210 | + .release = btaudio_dsp_release, | |
211 | + .read = btaudio_dsp_read, | |
212 | + .write = btaudio_dsp_write, | |
213 | + .ioctl = btaudio_dsp_ioctl, | |
214 | + .poll = btaudio_dsp_poll, | |
215 | }; | |
216 | ||
217 | /* -------------------------------------------------------------- */ | |
218 | @@ -818,18 +823,20 @@ | |
219 | "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR", | |
220 | "RIPERR", "PABORT", "OCERR", "SCERR" }; | |
221 | ||
222 | -static void btaudio_irq(int irq, void *dev_id, struct pt_regs * regs) | |
223 | +static irqreturn_t btaudio_irq(int irq, void *dev_id, struct pt_regs * regs) | |
224 | { | |
225 | int count = 0; | |
226 | u32 stat,astat; | |
227 | struct btaudio *bta = dev_id; | |
228 | + int handled = 0; | |
229 | ||
230 | for (;;) { | |
231 | count++; | |
232 | stat = btread(REG_INT_STAT); | |
233 | astat = stat & btread(REG_INT_MASK); | |
234 | if (!astat) | |
235 | - return; | |
236 | + break; | |
237 | + handled = 1; | |
238 | btwrite(astat,REG_INT_STAT); | |
239 | ||
240 | if (irq_debug) { | |
241 | @@ -865,29 +872,31 @@ | |
242 | btwrite(0, REG_INT_MASK); | |
243 | } | |
244 | } | |
245 | - return; | |
246 | + return IRQ_RETVAL(handled); | |
247 | } | |
248 | ||
249 | /* -------------------------------------------------------------- */ | |
250 | ||
251 | -static unsigned int dsp1 = -1; | |
252 | -static unsigned int dsp2 = -1; | |
253 | -static unsigned int mixer = -1; | |
254 | +#define BTAUDIO_MAX 16 | |
255 | + | |
256 | +static unsigned int dsp1[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; | |
257 | +static unsigned int dsp2[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; | |
258 | +static unsigned int mixer[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; | |
259 | +static int digital[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 1 }; | |
260 | +static int analog[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 1 }; | |
261 | +static int rate[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 0 }; | |
262 | static int latency = -1; | |
263 | -static int digital = 1; | |
264 | -static int analog = 1; | |
265 | -static int rate = 0; | |
266 | ||
267 | #define BTA_OSPREY200 1 | |
268 | ||
269 | static struct cardinfo cards[] = { | |
270 | [0] = { | |
271 | - name: "default", | |
272 | - rate: 32000, | |
273 | + .name = "default", | |
274 | + .rate = 32000, | |
275 | }, | |
276 | [BTA_OSPREY200] = { | |
277 | - name: "Osprey 200", | |
278 | - rate: 44100, | |
279 | + .name = "Osprey 200", | |
280 | + .rate = 44100, | |
281 | }, | |
282 | }; | |
283 | ||
284 | @@ -899,6 +908,9 @@ | |
285 | unsigned char revision,lat; | |
286 | int rc = -EBUSY; | |
287 | ||
288 | + if (BTAUDIO_MAX == btcount) | |
289 | + return -EBUSY; | |
290 | + | |
291 | if (pci_enable_device(pci_dev)) | |
292 | return -EIO; | |
293 | if (!request_mem_region(pci_resource_start(pci_dev,0), | |
294 | @@ -932,8 +944,8 @@ | |
295 | ||
296 | /* sample rate */ | |
297 | bta->rate = card->rate; | |
298 | - if (rate) | |
299 | - bta->rate = rate; | |
300 | + if (rate[btcount]) | |
301 | + bta->rate = rate[btcount]; | |
302 | ||
303 | init_MUTEX(&bta->lock); | |
304 | init_waitqueue_head(&bta->readq); | |
305 | @@ -955,7 +967,7 @@ | |
306 | /* init hw */ | |
307 | btwrite(0, REG_GPIO_DMA_CTL); | |
308 | btwrite(0, REG_INT_MASK); | |
309 | - btwrite(~0x0UL, REG_INT_STAT); | |
310 | + btwrite(~(u32)0, REG_INT_STAT); | |
311 | pci_set_master(pci_dev); | |
312 | ||
313 | if ((rc = request_irq(bta->irq, btaudio_irq, SA_SHIRQ|SA_INTERRUPT, | |
314 | @@ -966,9 +978,9 @@ | |
315 | } | |
316 | ||
317 | /* register devices */ | |
318 | - if (digital) { | |
319 | + if (digital[btcount]) { | |
320 | rc = bta->dsp_digital = | |
321 | - register_sound_dsp(&btaudio_digital_dsp_fops,dsp1); | |
322 | + register_sound_dsp(&btaudio_digital_dsp_fops,dsp1[btcount]); | |
323 | if (rc < 0) { | |
324 | printk(KERN_WARNING | |
325 | "btaudio: can't register digital dsp (rc=%d)\n",rc); | |
326 | @@ -977,9 +989,9 @@ | |
327 | printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n", | |
328 | bta->dsp_digital >> 4); | |
329 | } | |
330 | - if (analog) { | |
331 | + if (analog[btcount]) { | |
332 | rc = bta->dsp_analog = | |
333 | - register_sound_dsp(&btaudio_analog_dsp_fops,dsp2); | |
334 | + register_sound_dsp(&btaudio_analog_dsp_fops,dsp2[btcount]); | |
335 | if (rc < 0) { | |
336 | printk(KERN_WARNING | |
337 | "btaudio: can't register analog dsp (rc=%d)\n",rc); | |
338 | @@ -987,7 +999,8 @@ | |
339 | } | |
340 | printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n", | |
341 | bta->dsp_analog >> 4); | |
342 | - rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer); | |
343 | + rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops, | |
344 | + mixer[btcount]); | |
345 | if (rc < 0) { | |
346 | printk(KERN_WARNING | |
347 | "btaudio: can't register mixer (rc=%d)\n",rc); | |
348 | @@ -1000,6 +1013,7 @@ | |
349 | /* hook into linked list */ | |
350 | bta->next = btaudios; | |
351 | btaudios = bta; | |
352 | + btcount++; | |
353 | ||
354 | pci_set_drvdata(pci_dev,bta); | |
355 | return 0; | |
356 | @@ -1027,7 +1041,7 @@ | |
357 | /* turn off all DMA / IRQs */ | |
358 | btand(~15, REG_GPIO_DMA_CTL); | |
359 | btwrite(0, REG_INT_MASK); | |
360 | - btwrite(~0x0UL, REG_INT_STAT); | |
361 | + btwrite(~(u32)0, REG_INT_STAT); | |
362 | ||
363 | /* unregister devices */ | |
364 | if (digital) { | |
365 | @@ -1052,6 +1066,7 @@ | |
366 | ; /* if (NULL == walk->next) BUG(); */ | |
367 | walk->next = bta->next; | |
368 | } | |
369 | + btcount--; | |
370 | ||
371 | pci_set_drvdata(pci_dev, NULL); | |
372 | kfree(bta); | |
373 | @@ -1060,33 +1075,33 @@ | |
374 | ||
375 | /* -------------------------------------------------------------- */ | |
376 | ||
377 | -static struct pci_device_id btaudio_pci_tbl[] __devinitdata = { | |
378 | +static struct pci_device_id btaudio_pci_tbl[] = { | |
379 | { | |
380 | - vendor: PCI_VENDOR_ID_BROOKTREE, | |
381 | - device: 0x0878, | |
382 | - subvendor: 0x0070, | |
383 | - subdevice: 0xff01, | |
384 | - driver_data: BTA_OSPREY200, | |
385 | + .vendor = PCI_VENDOR_ID_BROOKTREE, | |
386 | + .device = 0x0878, | |
387 | + .subvendor = 0x0070, | |
388 | + .subdevice = 0xff01, | |
389 | + .driver_data = BTA_OSPREY200, | |
390 | },{ | |
391 | - vendor: PCI_VENDOR_ID_BROOKTREE, | |
392 | - device: 0x0878, | |
393 | - subvendor: PCI_ANY_ID, | |
394 | - subdevice: PCI_ANY_ID, | |
395 | + .vendor = PCI_VENDOR_ID_BROOKTREE, | |
396 | + .device = 0x0878, | |
397 | + .subvendor = PCI_ANY_ID, | |
398 | + .subdevice = PCI_ANY_ID, | |
399 | },{ | |
400 | - vendor: PCI_VENDOR_ID_BROOKTREE, | |
401 | - device: 0x0878, | |
402 | - subvendor: PCI_ANY_ID, | |
403 | - subdevice: PCI_ANY_ID, | |
404 | + .vendor = PCI_VENDOR_ID_BROOKTREE, | |
405 | + .device = 0x0879, | |
406 | + .subvendor = PCI_ANY_ID, | |
407 | + .subdevice = PCI_ANY_ID, | |
408 | },{ | |
409 | /* --- end of list --- */ | |
410 | } | |
411 | }; | |
412 | ||
413 | static struct pci_driver btaudio_pci_driver = { | |
414 | - name: "btaudio", | |
415 | - id_table: btaudio_pci_tbl, | |
416 | - probe: btaudio_probe, | |
417 | - remove: __devexit_p(btaudio_remove), | |
418 | + .name = "btaudio", | |
419 | + .id_table = btaudio_pci_tbl, | |
420 | + .probe = btaudio_probe, | |
421 | + .remove = __devexit_p(btaudio_remove), | |
422 | }; | |
423 | ||
424 | static int btaudio_init_module(void) | |
425 | @@ -1107,15 +1122,21 @@ | |
426 | module_init(btaudio_init_module); | |
427 | module_exit(btaudio_cleanup_module); | |
428 | ||
429 | -MODULE_PARM(dsp1,"i"); | |
430 | -MODULE_PARM(dsp2,"i"); | |
431 | -MODULE_PARM(mixer,"i"); | |
432 | -MODULE_PARM(debug,"i"); | |
433 | -MODULE_PARM(irq_debug,"i"); | |
434 | -MODULE_PARM(digital,"i"); | |
435 | -MODULE_PARM(analog,"i"); | |
436 | -MODULE_PARM(rate,"i"); | |
437 | -MODULE_PARM(latency,"i"); | |
438 | +MODULE_PARM(dsp1, "1-" __stringify(BTAUDIO_MAX) "i"); | |
439 | +MODULE_PARM_DESC(dsp1,"digital dsp nr"); | |
440 | +MODULE_PARM(dsp2, "1-" __stringify(BTAUDIO_MAX) "i"); | |
441 | +MODULE_PARM_DESC(dsp2,"analog dsp nr"); | |
442 | +MODULE_PARM(mixer, "1-" __stringify(BTAUDIO_MAX) "i"); | |
443 | +MODULE_PARM_DESC(mixer,"mixer nr"); | |
444 | +MODULE_PARM(debug, "i"); | |
445 | +MODULE_PARM(irq_debug, "i"); | |
446 | +MODULE_PARM(digital, "1-" __stringify(BTAUDIO_MAX) "i"); | |
447 | +MODULE_PARM_DESC(digital,"register digital dsp device"); | |
448 | +MODULE_PARM(analog, "1-" __stringify(BTAUDIO_MAX) "i"); | |
449 | +MODULE_PARM_DESC(analog,"register analog dsp device (and mixer)"); | |
450 | +MODULE_PARM(rate, "1-" __stringify(BTAUDIO_MAX) "i"); | |
451 | +MODULE_PARM_DESC(rate,"sample rate supported by the hardware"); | |
452 | +MODULE_PARM(latency, "i"); | |
453 | MODULE_PARM_DESC(latency,"pci latency timer"); | |
454 | ||
455 | MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl); |