Root/
1 | /* |
2 | * sound/oss/sb_common.c |
3 | * |
4 | * Common routines for Sound Blaster compatible cards. |
5 | * |
6 | * |
7 | * Copyright (C) by Hannu Savolainen 1993-1997 |
8 | * |
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) |
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software |
11 | * for more info. |
12 | * |
13 | * |
14 | * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts |
15 | * for full duplex support ( only sb16 by now ) |
16 | * Rolf Fokkens: Added (BETA?) support for ES1887 chips. |
17 | * (fokkensr@vertis.nl) Which means: You can adjust the recording levels. |
18 | * |
19 | * 2000/01/18 - separated sb_card and sb_common - |
20 | * Jeff Garzik <jgarzik@pobox.com> |
21 | * |
22 | * 2000/09/18 - got rid of attach_uart401 |
23 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
24 | * |
25 | * 2001/01/26 - replaced CLI/STI with spinlocks |
26 | * Chris Rankin <rankinc@zipworld.com.au> |
27 | */ |
28 | |
29 | #include <linux/init.h> |
30 | #include <linux/interrupt.h> |
31 | #include <linux/module.h> |
32 | #include <linux/delay.h> |
33 | #include <linux/spinlock.h> |
34 | #include <linux/slab.h> |
35 | |
36 | #include "sound_config.h" |
37 | #include "sound_firmware.h" |
38 | |
39 | #include "mpu401.h" |
40 | |
41 | #include "sb_mixer.h" |
42 | #include "sb.h" |
43 | #include "sb_ess.h" |
44 | |
45 | /* |
46 | * global module flag |
47 | */ |
48 | |
49 | int sb_be_quiet; |
50 | |
51 | static sb_devc *detected_devc; /* For communication from probe to init */ |
52 | static sb_devc *last_devc; /* For MPU401 initialization */ |
53 | |
54 | static unsigned char jazz_irq_bits[] = { |
55 | 0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6 |
56 | }; |
57 | |
58 | static unsigned char jazz_dma_bits[] = { |
59 | 0, 1, 0, 2, 0, 3, 0, 4 |
60 | }; |
61 | |
62 | void *smw_free; |
63 | |
64 | /* |
65 | * Jazz16 chipset specific control variables |
66 | */ |
67 | |
68 | static int jazz16_base; /* Not detected */ |
69 | static unsigned char jazz16_bits; /* I/O relocation bits */ |
70 | static DEFINE_SPINLOCK(jazz16_lock); |
71 | |
72 | /* |
73 | * Logitech Soundman Wave specific initialization code |
74 | */ |
75 | |
76 | #ifdef SMW_MIDI0001_INCLUDED |
77 | #include "smw-midi0001.h" |
78 | #else |
79 | static unsigned char *smw_ucode; |
80 | static int smw_ucodeLen; |
81 | |
82 | #endif |
83 | |
84 | static sb_devc *last_sb; /* Last sb loaded */ |
85 | |
86 | int sb_dsp_command(sb_devc * devc, unsigned char val) |
87 | { |
88 | int i; |
89 | unsigned long limit; |
90 | |
91 | limit = jiffies + HZ / 10; /* Timeout */ |
92 | |
93 | /* |
94 | * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes |
95 | * called while interrupts are disabled. This means that the timer is |
96 | * disabled also. However the timeout situation is a abnormal condition. |
97 | * Normally the DSP should be ready to accept commands after just couple of |
98 | * loops. |
99 | */ |
100 | |
101 | for (i = 0; i < 500000 && (limit-jiffies)>0; i++) |
102 | { |
103 | if ((inb(DSP_STATUS) & 0x80) == 0) |
104 | { |
105 | outb((val), DSP_COMMAND); |
106 | return 1; |
107 | } |
108 | } |
109 | printk(KERN_WARNING "Sound Blaster: DSP command(%x) timeout.\n", val); |
110 | return 0; |
111 | } |
112 | |
113 | int sb_dsp_get_byte(sb_devc * devc) |
114 | { |
115 | int i; |
116 | |
117 | for (i = 1000; i; i--) |
118 | { |
119 | if (inb(DSP_DATA_AVAIL) & 0x80) |
120 | return inb(DSP_READ); |
121 | } |
122 | return 0xffff; |
123 | } |
124 | |
125 | static void sb_intr (sb_devc *devc) |
126 | { |
127 | int status; |
128 | unsigned char src = 0xff; |
129 | |
130 | if (devc->model == MDL_SB16) |
131 | { |
132 | src = sb_getmixer(devc, IRQ_STAT); /* Interrupt source register */ |
133 | |
134 | if (src & 4) /* MPU401 interrupt */ |
135 | if(devc->midi_irq_cookie) |
136 | uart401intr(devc->irq, devc->midi_irq_cookie); |
137 | |
138 | if (!(src & 3)) |
139 | return; /* Not a DSP interrupt */ |
140 | } |
141 | if (devc->intr_active && (!devc->fullduplex || (src & 0x01))) |
142 | { |
143 | switch (devc->irq_mode) |
144 | { |
145 | case IMODE_OUTPUT: |
146 | DMAbuf_outputintr(devc->dev, 1); |
147 | break; |
148 | |
149 | case IMODE_INPUT: |
150 | DMAbuf_inputintr(devc->dev); |
151 | break; |
152 | |
153 | case IMODE_INIT: |
154 | break; |
155 | |
156 | case IMODE_MIDI: |
157 | sb_midi_interrupt(devc); |
158 | break; |
159 | |
160 | default: |
161 | /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */ |
162 | ; |
163 | } |
164 | } |
165 | else if (devc->intr_active_16 && (src & 0x02)) |
166 | { |
167 | switch (devc->irq_mode_16) |
168 | { |
169 | case IMODE_OUTPUT: |
170 | DMAbuf_outputintr(devc->dev, 1); |
171 | break; |
172 | |
173 | case IMODE_INPUT: |
174 | DMAbuf_inputintr(devc->dev); |
175 | break; |
176 | |
177 | case IMODE_INIT: |
178 | break; |
179 | |
180 | default: |
181 | /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */ |
182 | ; |
183 | } |
184 | } |
185 | /* |
186 | * Acknowledge interrupts |
187 | */ |
188 | |
189 | if (src & 0x01) |
190 | status = inb(DSP_DATA_AVAIL); |
191 | |
192 | if (devc->model == MDL_SB16 && src & 0x02) |
193 | status = inb(DSP_DATA_AVL16); |
194 | } |
195 | |
196 | static void pci_intr(sb_devc *devc) |
197 | { |
198 | int src = inb(devc->pcibase+0x1A); |
199 | src&=3; |
200 | if(src) |
201 | sb_intr(devc); |
202 | } |
203 | |
204 | static irqreturn_t sbintr(int irq, void *dev_id) |
205 | { |
206 | sb_devc *devc = dev_id; |
207 | |
208 | devc->irq_ok = 1; |
209 | |
210 | switch (devc->model) { |
211 | case MDL_ESSPCI: |
212 | pci_intr (devc); |
213 | break; |
214 | |
215 | case MDL_ESS: |
216 | ess_intr (devc); |
217 | break; |
218 | default: |
219 | sb_intr (devc); |
220 | break; |
221 | } |
222 | return IRQ_HANDLED; |
223 | } |
224 | |
225 | int sb_dsp_reset(sb_devc * devc) |
226 | { |
227 | int loopc; |
228 | |
229 | DEB(printk("Entered sb_dsp_reset()\n")); |
230 | |
231 | if (devc->model == MDL_ESS) return ess_dsp_reset (devc); |
232 | |
233 | /* This is only for non-ESS chips */ |
234 | |
235 | outb(1, DSP_RESET); |
236 | |
237 | udelay(10); |
238 | outb(0, DSP_RESET); |
239 | udelay(30); |
240 | |
241 | for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++); |
242 | |
243 | if (inb(DSP_READ) != 0xAA) |
244 | { |
245 | DDB(printk("sb: No response to RESET\n")); |
246 | return 0; /* Sorry */ |
247 | } |
248 | |
249 | DEB(printk("sb_dsp_reset() OK\n")); |
250 | |
251 | return 1; |
252 | } |
253 | |
254 | static void dsp_get_vers(sb_devc * devc) |
255 | { |
256 | int i; |
257 | |
258 | unsigned long flags; |
259 | |
260 | DDB(printk("Entered dsp_get_vers()\n")); |
261 | spin_lock_irqsave(&devc->lock, flags); |
262 | devc->major = devc->minor = 0; |
263 | sb_dsp_command(devc, 0xe1); /* Get version */ |
264 | |
265 | for (i = 100000; i; i--) |
266 | { |
267 | if (inb(DSP_DATA_AVAIL) & 0x80) |
268 | { |
269 | if (devc->major == 0) |
270 | devc->major = inb(DSP_READ); |
271 | else |
272 | { |
273 | devc->minor = inb(DSP_READ); |
274 | break; |
275 | } |
276 | } |
277 | } |
278 | spin_unlock_irqrestore(&devc->lock, flags); |
279 | DDB(printk("DSP version %d.%02d\n", devc->major, devc->minor)); |
280 | } |
281 | |
282 | static int sb16_set_dma_hw(sb_devc * devc) |
283 | { |
284 | int bits; |
285 | |
286 | if (devc->dma8 != 0 && devc->dma8 != 1 && devc->dma8 != 3) |
287 | { |
288 | printk(KERN_ERR "SB16: Invalid 8 bit DMA (%d)\n", devc->dma8); |
289 | return 0; |
290 | } |
291 | bits = (1 << devc->dma8); |
292 | |
293 | if (devc->dma16 >= 5 && devc->dma16 <= 7) |
294 | bits |= (1 << devc->dma16); |
295 | |
296 | sb_setmixer(devc, DMA_NR, bits); |
297 | return 1; |
298 | } |
299 | |
300 | static void sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config) |
301 | { |
302 | /* |
303 | * This routine initializes new MIDI port setup register of SB Vibra (CT2502). |
304 | */ |
305 | unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06; |
306 | |
307 | switch (hw_config->io_base) |
308 | { |
309 | case 0x300: |
310 | sb_setmixer(devc, 0x84, bits | 0x04); |
311 | break; |
312 | |
313 | case 0x330: |
314 | sb_setmixer(devc, 0x84, bits | 0x00); |
315 | break; |
316 | |
317 | default: |
318 | sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */ |
319 | printk(KERN_ERR "SB16: Invalid MIDI I/O port %x\n", hw_config->io_base); |
320 | } |
321 | } |
322 | |
323 | static int sb16_set_irq_hw(sb_devc * devc, int level) |
324 | { |
325 | int ival; |
326 | |
327 | switch (level) |
328 | { |
329 | case 5: |
330 | ival = 2; |
331 | break; |
332 | case 7: |
333 | ival = 4; |
334 | break; |
335 | case 9: |
336 | ival = 1; |
337 | break; |
338 | case 10: |
339 | ival = 8; |
340 | break; |
341 | default: |
342 | printk(KERN_ERR "SB16: Invalid IRQ%d\n", level); |
343 | return 0; |
344 | } |
345 | sb_setmixer(devc, IRQ_NR, ival); |
346 | return 1; |
347 | } |
348 | |
349 | static void relocate_Jazz16(sb_devc * devc, struct address_info *hw_config) |
350 | { |
351 | unsigned char bits = 0; |
352 | unsigned long flags; |
353 | |
354 | if (jazz16_base != 0 && jazz16_base != hw_config->io_base) |
355 | return; |
356 | |
357 | switch (hw_config->io_base) |
358 | { |
359 | case 0x220: |
360 | bits = 1; |
361 | break; |
362 | case 0x240: |
363 | bits = 2; |
364 | break; |
365 | case 0x260: |
366 | bits = 3; |
367 | break; |
368 | default: |
369 | return; |
370 | } |
371 | bits = jazz16_bits = bits << 5; |
372 | jazz16_base = hw_config->io_base; |
373 | |
374 | /* |
375 | * Magic wake up sequence by writing to 0x201 (aka Joystick port) |
376 | */ |
377 | spin_lock_irqsave(&jazz16_lock, flags); |
378 | outb((0xAF), 0x201); |
379 | outb((0x50), 0x201); |
380 | outb((bits), 0x201); |
381 | spin_unlock_irqrestore(&jazz16_lock, flags); |
382 | } |
383 | |
384 | static int init_Jazz16(sb_devc * devc, struct address_info *hw_config) |
385 | { |
386 | char name[100]; |
387 | /* |
388 | * First try to check that the card has Jazz16 chip. It identifies itself |
389 | * by returning 0x12 as response to DSP command 0xfa. |
390 | */ |
391 | |
392 | if (!sb_dsp_command(devc, 0xfa)) |
393 | return 0; |
394 | |
395 | if (sb_dsp_get_byte(devc) != 0x12) |
396 | return 0; |
397 | |
398 | /* |
399 | * OK so far. Now configure the IRQ and DMA channel used by the card. |
400 | */ |
401 | if (hw_config->irq < 1 || hw_config->irq > 15 || jazz_irq_bits[hw_config->irq] == 0) |
402 | { |
403 | printk(KERN_ERR "Jazz16: Invalid interrupt (IRQ%d)\n", hw_config->irq); |
404 | return 0; |
405 | } |
406 | if (hw_config->dma < 0 || hw_config->dma > 3 || jazz_dma_bits[hw_config->dma] == 0) |
407 | { |
408 | printk(KERN_ERR "Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma); |
409 | return 0; |
410 | } |
411 | if (hw_config->dma2 < 0) |
412 | { |
413 | printk(KERN_ERR "Jazz16: No 16 bit DMA channel defined\n"); |
414 | return 0; |
415 | } |
416 | if (hw_config->dma2 < 5 || hw_config->dma2 > 7 || jazz_dma_bits[hw_config->dma2] == 0) |
417 | { |
418 | printk(KERN_ERR "Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2); |
419 | return 0; |
420 | } |
421 | devc->dma16 = hw_config->dma2; |
422 | |
423 | if (!sb_dsp_command(devc, 0xfb)) |
424 | return 0; |
425 | |
426 | if (!sb_dsp_command(devc, jazz_dma_bits[hw_config->dma] | |
427 | (jazz_dma_bits[hw_config->dma2] << 4))) |
428 | return 0; |
429 | |
430 | if (!sb_dsp_command(devc, jazz_irq_bits[hw_config->irq])) |
431 | return 0; |
432 | |
433 | /* |
434 | * Now we have configured a standard Jazz16 device. |
435 | */ |
436 | devc->model = MDL_JAZZ; |
437 | strcpy(name, "Jazz16"); |
438 | |
439 | hw_config->name = "Jazz16"; |
440 | devc->caps |= SB_NO_MIDI; |
441 | return 1; |
442 | } |
443 | |
444 | static void relocate_ess1688(sb_devc * devc) |
445 | { |
446 | unsigned char bits; |
447 | |
448 | switch (devc->base) |
449 | { |
450 | case 0x220: |
451 | bits = 0x04; |
452 | break; |
453 | case 0x230: |
454 | bits = 0x05; |
455 | break; |
456 | case 0x240: |
457 | bits = 0x06; |
458 | break; |
459 | case 0x250: |
460 | bits = 0x07; |
461 | break; |
462 | default: |
463 | return; /* Wrong port */ |
464 | } |
465 | |
466 | DDB(printk("Doing ESS1688 address selection\n")); |
467 | |
468 | /* |
469 | * ES1688 supports two alternative ways for software address config. |
470 | * First try the so called Read-Sequence-Key method. |
471 | */ |
472 | |
473 | /* Reset the sequence logic */ |
474 | inb(0x229); |
475 | inb(0x229); |
476 | inb(0x229); |
477 | |
478 | /* Perform the read sequence */ |
479 | inb(0x22b); |
480 | inb(0x229); |
481 | inb(0x22b); |
482 | inb(0x229); |
483 | inb(0x229); |
484 | inb(0x22b); |
485 | inb(0x229); |
486 | |
487 | /* Select the base address by reading from it. Then probe using the port. */ |
488 | inb(devc->base); |
489 | if (sb_dsp_reset(devc)) /* Bingo */ |
490 | return; |
491 | |
492 | #if 0 /* This causes system lockups (Nokia 386/25 at least) */ |
493 | /* |
494 | * The last resort is the system control register method. |
495 | */ |
496 | |
497 | outb((0x00), 0xfb); /* 0xFB is the unlock register */ |
498 | outb((0x00), 0xe0); /* Select index 0 */ |
499 | outb((bits), 0xe1); /* Write the config bits */ |
500 | outb((0x00), 0xf9); /* 0xFB is the lock register */ |
501 | #endif |
502 | } |
503 | |
504 | int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_module_options *sbmo) |
505 | { |
506 | sb_devc sb_info; |
507 | sb_devc *devc = &sb_info; |
508 | |
509 | memset((char *) &sb_info, 0, sizeof(sb_info)); /* Zero everything */ |
510 | |
511 | /* Copy module options in place */ |
512 | if(sbmo) memcpy(&devc->sbmo, sbmo, sizeof(struct sb_module_options)); |
513 | |
514 | sb_info.my_mididev = -1; |
515 | sb_info.my_mixerdev = -1; |
516 | sb_info.dev = -1; |
517 | |
518 | /* |
519 | * Initialize variables |
520 | */ |
521 | |
522 | DDB(printk("sb_dsp_detect(%x) entered\n", hw_config->io_base)); |
523 | |
524 | spin_lock_init(&devc->lock); |
525 | devc->type = hw_config->card_subtype; |
526 | |
527 | devc->base = hw_config->io_base; |
528 | devc->irq = hw_config->irq; |
529 | devc->dma8 = hw_config->dma; |
530 | |
531 | devc->dma16 = -1; |
532 | devc->pcibase = pciio; |
533 | |
534 | if(pci == SB_PCI_ESSMAESTRO) |
535 | { |
536 | devc->model = MDL_ESSPCI; |
537 | devc->caps |= SB_PCI_IRQ; |
538 | hw_config->driver_use_1 |= SB_PCI_IRQ; |
539 | hw_config->card_subtype = MDL_ESSPCI; |
540 | } |
541 | |
542 | if(pci == SB_PCI_YAMAHA) |
543 | { |
544 | devc->model = MDL_YMPCI; |
545 | devc->caps |= SB_PCI_IRQ; |
546 | hw_config->driver_use_1 |= SB_PCI_IRQ; |
547 | hw_config->card_subtype = MDL_YMPCI; |
548 | |
549 | printk("Yamaha PCI mode.\n"); |
550 | } |
551 | |
552 | if (devc->sbmo.acer) |
553 | { |
554 | unsigned long flags; |
555 | |
556 | spin_lock_irqsave(&devc->lock, flags); |
557 | inb(devc->base + 0x09); |
558 | inb(devc->base + 0x09); |
559 | inb(devc->base + 0x09); |
560 | inb(devc->base + 0x0b); |
561 | inb(devc->base + 0x09); |
562 | inb(devc->base + 0x0b); |
563 | inb(devc->base + 0x09); |
564 | inb(devc->base + 0x09); |
565 | inb(devc->base + 0x0b); |
566 | inb(devc->base + 0x09); |
567 | inb(devc->base + 0x00); |
568 | spin_unlock_irqrestore(&devc->lock, flags); |
569 | } |
570 | /* |
571 | * Detect the device |
572 | */ |
573 | |
574 | if (sb_dsp_reset(devc)) |
575 | dsp_get_vers(devc); |
576 | else |
577 | devc->major = 0; |
578 | |
579 | if (devc->type == 0 || devc->type == MDL_JAZZ || devc->type == MDL_SMW) |
580 | if (devc->major == 0 || (devc->major == 3 && devc->minor == 1)) |
581 | relocate_Jazz16(devc, hw_config); |
582 | |
583 | if (devc->major == 0 && (devc->type == MDL_ESS || devc->type == 0)) |
584 | relocate_ess1688(devc); |
585 | |
586 | if (!sb_dsp_reset(devc)) |
587 | { |
588 | DDB(printk("SB reset failed\n")); |
589 | #ifdef MODULE |
590 | printk(KERN_INFO "sb: dsp reset failed.\n"); |
591 | #endif |
592 | return 0; |
593 | } |
594 | if (devc->major == 0) |
595 | dsp_get_vers(devc); |
596 | |
597 | if (devc->major == 3 && devc->minor == 1) |
598 | { |
599 | if (devc->type == MDL_AZTECH) /* SG Washington? */ |
600 | { |
601 | if (sb_dsp_command(devc, 0x09)) |
602 | if (sb_dsp_command(devc, 0x00)) /* Enter WSS mode */ |
603 | { |
604 | int i; |
605 | |
606 | /* Have some delay */ |
607 | for (i = 0; i < 10000; i++) |
608 | inb(DSP_DATA_AVAIL); |
609 | devc->caps = SB_NO_AUDIO | SB_NO_MIDI; /* Mixer only */ |
610 | devc->model = MDL_AZTECH; |
611 | } |
612 | } |
613 | } |
614 | |
615 | if(devc->type == MDL_ESSPCI) |
616 | devc->model = MDL_ESSPCI; |
617 | |
618 | if(devc->type == MDL_YMPCI) |
619 | { |
620 | printk("YMPCI selected\n"); |
621 | devc->model = MDL_YMPCI; |
622 | } |
623 | |
624 | /* |
625 | * Save device information for sb_dsp_init() |
626 | */ |
627 | |
628 | |
629 | detected_devc = kmalloc(sizeof(sb_devc), GFP_KERNEL); |
630 | if (detected_devc == NULL) |
631 | { |
632 | printk(KERN_ERR "sb: Can't allocate memory for device information\n"); |
633 | return 0; |
634 | } |
635 | memcpy(detected_devc, devc, sizeof(sb_devc)); |
636 | MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base)); |
637 | return 1; |
638 | } |
639 | |
640 | int sb_dsp_init(struct address_info *hw_config, struct module *owner) |
641 | { |
642 | sb_devc *devc; |
643 | char name[100]; |
644 | extern int sb_be_quiet; |
645 | int mixer22, mixer30; |
646 | |
647 | /* |
648 | * Check if we had detected a SB device earlier |
649 | */ |
650 | DDB(printk("sb_dsp_init(%x) entered\n", hw_config->io_base)); |
651 | name[0] = 0; |
652 | |
653 | if (detected_devc == NULL) |
654 | { |
655 | MDB(printk("No detected device\n")); |
656 | return 0; |
657 | } |
658 | devc = detected_devc; |
659 | detected_devc = NULL; |
660 | |
661 | if (devc->base != hw_config->io_base) |
662 | { |
663 | DDB(printk("I/O port mismatch\n")); |
664 | release_region(devc->base, 16); |
665 | return 0; |
666 | } |
667 | /* |
668 | * Now continue initialization of the device |
669 | */ |
670 | |
671 | devc->caps = hw_config->driver_use_1; |
672 | |
673 | if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0) |
674 | { /* IRQ setup */ |
675 | |
676 | /* |
677 | * ESS PCI cards do shared PCI IRQ stuff. Since they |
678 | * will get shared PCI irq lines we must cope. |
679 | */ |
680 | |
681 | int i=(devc->caps&SB_PCI_IRQ)?IRQF_SHARED:0; |
682 | |
683 | if (request_irq(hw_config->irq, sbintr, i, "soundblaster", devc) < 0) |
684 | { |
685 | printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq); |
686 | release_region(devc->base, 16); |
687 | return 0; |
688 | } |
689 | devc->irq_ok = 0; |
690 | |
691 | if (devc->major == 4) |
692 | if (!sb16_set_irq_hw(devc, devc->irq)) /* Unsupported IRQ */ |
693 | { |
694 | free_irq(devc->irq, devc); |
695 | release_region(devc->base, 16); |
696 | return 0; |
697 | } |
698 | if ((devc->type == 0 || devc->type == MDL_ESS) && |
699 | devc->major == 3 && devc->minor == 1) |
700 | { /* Handle various chipsets which claim they are SB Pro compatible */ |
701 | if ((devc->type != 0 && devc->type != MDL_ESS) || |
702 | !ess_init(devc, hw_config)) |
703 | { |
704 | if ((devc->type != 0 && devc->type != MDL_JAZZ && |
705 | devc->type != MDL_SMW) || !init_Jazz16(devc, hw_config)) |
706 | { |
707 | DDB(printk("This is a genuine SB Pro\n")); |
708 | } |
709 | } |
710 | } |
711 | if (devc->major == 4 && devc->minor <= 11 ) /* Won't work */ |
712 | devc->irq_ok = 1; |
713 | else |
714 | { |
715 | int n; |
716 | |
717 | for (n = 0; n < 3 && devc->irq_ok == 0; n++) |
718 | { |
719 | if (sb_dsp_command(devc, 0xf2)) /* Cause interrupt immediately */ |
720 | { |
721 | int i; |
722 | |
723 | for (i = 0; !devc->irq_ok && i < 10000; i++); |
724 | } |
725 | } |
726 | if (!devc->irq_ok) |
727 | printk(KERN_WARNING "sb: Interrupt test on IRQ%d failed - Probable IRQ conflict\n", devc->irq); |
728 | else |
729 | { |
730 | DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq)); |
731 | } |
732 | } |
733 | } /* IRQ setup */ |
734 | |
735 | last_sb = devc; |
736 | |
737 | switch (devc->major) |
738 | { |
739 | case 1: /* SB 1.0 or 1.5 */ |
740 | devc->model = hw_config->card_subtype = MDL_SB1; |
741 | break; |
742 | |
743 | case 2: /* SB 2.x */ |
744 | if (devc->minor == 0) |
745 | devc->model = hw_config->card_subtype = MDL_SB2; |
746 | else |
747 | devc->model = hw_config->card_subtype = MDL_SB201; |
748 | break; |
749 | |
750 | case 3: /* SB Pro and most clones */ |
751 | switch (devc->model) { |
752 | case 0: |
753 | devc->model = hw_config->card_subtype = MDL_SBPRO; |
754 | if (hw_config->name == NULL) |
755 | hw_config->name = "Sound Blaster Pro (8 BIT ONLY)"; |
756 | break; |
757 | case MDL_ESS: |
758 | ess_dsp_init(devc, hw_config); |
759 | break; |
760 | } |
761 | break; |
762 | |
763 | case 4: |
764 | devc->model = hw_config->card_subtype = MDL_SB16; |
765 | /* |
766 | * ALS007 and ALS100 return DSP version 4.2 and have 2 post-reset !=0 |
767 | * registers at 0x3c and 0x4c (output ctrl registers on ALS007) whereas |
768 | * a "standard" SB16 doesn't have a register at 0x4c. ALS100 actively |
769 | * updates register 0x22 whenever 0x30 changes, as per the SB16 spec. |
770 | * Since ALS007 doesn't, this can be used to differentiate the 2 cards. |
771 | */ |
772 | if ((devc->minor == 2) && sb_getmixer(devc,0x3c) && sb_getmixer(devc,0x4c)) |
773 | { |
774 | mixer30 = sb_getmixer(devc,0x30); |
775 | sb_setmixer(devc,0x22,(mixer22=sb_getmixer(devc,0x22)) & 0x0f); |
776 | sb_setmixer(devc,0x30,0xff); |
777 | /* ALS100 will force 0x30 to 0xf8 like SB16; ALS007 will allow 0xff. */ |
778 | /* Register 0x22 & 0xf0 on ALS100 == 0xf0; on ALS007 it == 0x10. */ |
779 | if ((sb_getmixer(devc,0x30) != 0xff) || ((sb_getmixer(devc,0x22) & 0xf0) != 0x10)) |
780 | { |
781 | devc->submodel = SUBMDL_ALS100; |
782 | if (hw_config->name == NULL) |
783 | hw_config->name = "Sound Blaster 16 (ALS-100)"; |
784 | } |
785 | else |
786 | { |
787 | sb_setmixer(devc,0x3c,0x1f); /* Enable all inputs */ |
788 | sb_setmixer(devc,0x4c,0x1f); |
789 | sb_setmixer(devc,0x22,mixer22); /* Restore 0x22 to original value */ |
790 | devc->submodel = SUBMDL_ALS007; |
791 | if (hw_config->name == NULL) |
792 | hw_config->name = "Sound Blaster 16 (ALS-007)"; |
793 | } |
794 | sb_setmixer(devc,0x30,mixer30); |
795 | } |
796 | else if (hw_config->name == NULL) |
797 | hw_config->name = "Sound Blaster 16"; |
798 | |
799 | if (hw_config->dma2 == -1) |
800 | devc->dma16 = devc->dma8; |
801 | else if (hw_config->dma2 < 5 || hw_config->dma2 > 7) |
802 | { |
803 | printk(KERN_WARNING "SB16: Bad or missing 16 bit DMA channel\n"); |
804 | devc->dma16 = devc->dma8; |
805 | } |
806 | else |
807 | devc->dma16 = hw_config->dma2; |
808 | |
809 | if(!sb16_set_dma_hw(devc)) { |
810 | free_irq(devc->irq, devc); |
811 | release_region(hw_config->io_base, 16); |
812 | return 0; |
813 | } |
814 | |
815 | devc->caps |= SB_NO_MIDI; |
816 | } |
817 | |
818 | if (!(devc->caps & SB_NO_MIXER)) |
819 | if (devc->major == 3 || devc->major == 4) |
820 | sb_mixer_init(devc, owner); |
821 | |
822 | if (!(devc->caps & SB_NO_MIDI)) |
823 | sb_dsp_midi_init(devc, owner); |
824 | |
825 | if (hw_config->name == NULL) |
826 | hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)"; |
827 | |
828 | sprintf(name, "%s (%d.%02d)", hw_config->name, devc->major, devc->minor); |
829 | conf_printf(name, hw_config); |
830 | |
831 | /* |
832 | * Assuming that a sound card is Sound Blaster (compatible) is the most common |
833 | * configuration error and the mother of all problems. Usually sound cards |
834 | * emulate SB Pro but in addition they have a 16 bit native mode which should be |
835 | * used in Unix. See Readme.cards for more information about configuring OSS/Free |
836 | * properly. |
837 | */ |
838 | if (devc->model <= MDL_SBPRO) |
839 | { |
840 | if (devc->major == 3 && devc->minor != 1) /* "True" SB Pro should have v3.1 (rare ones may have 3.2). */ |
841 | { |
842 | printk(KERN_INFO "This sound card may not be fully Sound Blaster Pro compatible.\n"); |
843 | printk(KERN_INFO "In many cases there is another way to configure OSS so that\n"); |
844 | printk(KERN_INFO "it works properly with OSS (for example in 16 bit mode).\n"); |
845 | printk(KERN_INFO "Please ignore this message if you _really_ have a SB Pro.\n"); |
846 | } |
847 | else if (!sb_be_quiet && devc->model == MDL_SBPRO) |
848 | { |
849 | printk(KERN_INFO "SB DSP version is just %d.%02d which means that your card is\n", devc->major, devc->minor); |
850 | printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n"); |
851 | printk(KERN_INFO "is incorrectly configured.\n"); |
852 | } |
853 | } |
854 | hw_config->card_subtype = devc->model; |
855 | hw_config->slots[0]=devc->dev; |
856 | last_devc = devc; /* For SB MPU detection */ |
857 | |
858 | if (!(devc->caps & SB_NO_AUDIO) && devc->dma8 >= 0) |
859 | { |
860 | if (sound_alloc_dma(devc->dma8, "SoundBlaster8")) |
861 | { |
862 | printk(KERN_WARNING "Sound Blaster: Can't allocate 8 bit DMA channel %d\n", devc->dma8); |
863 | } |
864 | if (devc->dma16 >= 0 && devc->dma16 != devc->dma8) |
865 | { |
866 | if (sound_alloc_dma(devc->dma16, "SoundBlaster16")) |
867 | printk(KERN_WARNING "Sound Blaster: can't allocate 16 bit DMA channel %d.\n", devc->dma16); |
868 | } |
869 | sb_audio_init(devc, name, owner); |
870 | hw_config->slots[0]=devc->dev; |
871 | } |
872 | else |
873 | { |
874 | MDB(printk("Sound Blaster: no audio devices found.\n")); |
875 | } |
876 | return 1; |
877 | } |
878 | |
879 | /* if (sbmpu) below we allow mpu401 to manage the midi devs |
880 | otherwise we have to unload them. (Andrzej Krzysztofowicz) */ |
881 | |
882 | void sb_dsp_unload(struct address_info *hw_config, int sbmpu) |
883 | { |
884 | sb_devc *devc; |
885 | |
886 | devc = audio_devs[hw_config->slots[0]]->devc; |
887 | |
888 | if (devc && devc->base == hw_config->io_base) |
889 | { |
890 | if ((devc->model & MDL_ESS) && devc->pcibase) |
891 | release_region(devc->pcibase, 8); |
892 | |
893 | release_region(devc->base, 16); |
894 | |
895 | if (!(devc->caps & SB_NO_AUDIO)) |
896 | { |
897 | sound_free_dma(devc->dma8); |
898 | if (devc->dma16 >= 0) |
899 | sound_free_dma(devc->dma16); |
900 | } |
901 | if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI)) |
902 | { |
903 | if (devc->irq > 0) |
904 | free_irq(devc->irq, devc); |
905 | |
906 | sb_mixer_unload(devc); |
907 | /* We don't have to do this bit any more the UART401 is its own |
908 | master -- Krzysztof Halasa */ |
909 | /* But we have to do it, if UART401 is not detected */ |
910 | if (!sbmpu) |
911 | sound_unload_mididev(devc->my_mididev); |
912 | sound_unload_audiodev(devc->dev); |
913 | } |
914 | kfree(devc); |
915 | } |
916 | else |
917 | release_region(hw_config->io_base, 16); |
918 | |
919 | kfree(detected_devc); |
920 | } |
921 | |
922 | /* |
923 | * Mixer access routines |
924 | * |
925 | * ES1887 modifications: some mixer registers reside in the |
926 | * range above 0xa0. These must be accessed in another way. |
927 | */ |
928 | |
929 | void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value) |
930 | { |
931 | unsigned long flags; |
932 | |
933 | if (devc->model == MDL_ESS) { |
934 | ess_setmixer (devc, port, value); |
935 | return; |
936 | } |
937 | |
938 | spin_lock_irqsave(&devc->lock, flags); |
939 | |
940 | outb(((unsigned char) (port & 0xff)), MIXER_ADDR); |
941 | udelay(20); |
942 | outb(((unsigned char) (value & 0xff)), MIXER_DATA); |
943 | udelay(20); |
944 | |
945 | spin_unlock_irqrestore(&devc->lock, flags); |
946 | } |
947 | |
948 | unsigned int sb_getmixer(sb_devc * devc, unsigned int port) |
949 | { |
950 | unsigned int val; |
951 | unsigned long flags; |
952 | |
953 | if (devc->model == MDL_ESS) return ess_getmixer (devc, port); |
954 | |
955 | spin_lock_irqsave(&devc->lock, flags); |
956 | |
957 | outb(((unsigned char) (port & 0xff)), MIXER_ADDR); |
958 | udelay(20); |
959 | val = inb(MIXER_DATA); |
960 | udelay(20); |
961 | |
962 | spin_unlock_irqrestore(&devc->lock, flags); |
963 | |
964 | return val; |
965 | } |
966 | |
967 | void sb_chgmixer |
968 | (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val) |
969 | { |
970 | int value; |
971 | |
972 | value = sb_getmixer(devc, reg); |
973 | value = (value & ~mask) | (val & mask); |
974 | sb_setmixer(devc, reg, value); |
975 | } |
976 | |
977 | /* |
978 | * MPU401 MIDI initialization. |
979 | */ |
980 | |
981 | static void smw_putmem(sb_devc * devc, int base, int addr, unsigned char val) |
982 | { |
983 | unsigned long flags; |
984 | |
985 | spin_lock_irqsave(&jazz16_lock, flags); /* NOT the SB card? */ |
986 | |
987 | outb((addr & 0xff), base + 1); /* Low address bits */ |
988 | outb((addr >> 8), base + 2); /* High address bits */ |
989 | outb((val), base); /* Data */ |
990 | |
991 | spin_unlock_irqrestore(&jazz16_lock, flags); |
992 | } |
993 | |
994 | static unsigned char smw_getmem(sb_devc * devc, int base, int addr) |
995 | { |
996 | unsigned long flags; |
997 | unsigned char val; |
998 | |
999 | spin_lock_irqsave(&jazz16_lock, flags); /* NOT the SB card? */ |
1000 | |
1001 | outb((addr & 0xff), base + 1); /* Low address bits */ |
1002 | outb((addr >> 8), base + 2); /* High address bits */ |
1003 | val = inb(base); /* Data */ |
1004 | |
1005 | spin_unlock_irqrestore(&jazz16_lock, flags); |
1006 | return val; |
1007 | } |
1008 | |
1009 | static int smw_midi_init(sb_devc * devc, struct address_info *hw_config) |
1010 | { |
1011 | int mpu_base = hw_config->io_base; |
1012 | int mp_base = mpu_base + 4; /* Microcontroller base */ |
1013 | int i; |
1014 | unsigned char control; |
1015 | |
1016 | |
1017 | /* |
1018 | * Reset the microcontroller so that the RAM can be accessed |
1019 | */ |
1020 | |
1021 | control = inb(mpu_base + 7); |
1022 | outb((control | 3), mpu_base + 7); /* Set last two bits to 1 (?) */ |
1023 | outb(((control & 0xfe) | 2), mpu_base + 7); /* xxxxxxx0 resets the mc */ |
1024 | |
1025 | mdelay(3); /* Wait at least 1ms */ |
1026 | |
1027 | outb((control & 0xfc), mpu_base + 7); /* xxxxxx00 enables RAM */ |
1028 | |
1029 | /* |
1030 | * Detect microcontroller by probing the 8k RAM area |
1031 | */ |
1032 | smw_putmem(devc, mp_base, 0, 0x00); |
1033 | smw_putmem(devc, mp_base, 1, 0xff); |
1034 | udelay(10); |
1035 | |
1036 | if (smw_getmem(devc, mp_base, 0) != 0x00 || smw_getmem(devc, mp_base, 1) != 0xff) |
1037 | { |
1038 | DDB(printk("SM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(devc, mp_base, 0), smw_getmem(devc, mp_base, 1))); |
1039 | return 0; /* No RAM */ |
1040 | } |
1041 | /* |
1042 | * There is RAM so assume it's really a SM Wave |
1043 | */ |
1044 | |
1045 | devc->model = MDL_SMW; |
1046 | smw_mixer_init(devc); |
1047 | |
1048 | #ifdef MODULE |
1049 | if (!smw_ucode) |
1050 | { |
1051 | smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode); |
1052 | smw_free = smw_ucode; |
1053 | } |
1054 | #endif |
1055 | if (smw_ucodeLen > 0) |
1056 | { |
1057 | if (smw_ucodeLen != 8192) |
1058 | { |
1059 | printk(KERN_ERR "SM Wave: Invalid microcode (MIDI0001.BIN) length\n"); |
1060 | return 1; |
1061 | } |
1062 | /* |
1063 | * Download microcode |
1064 | */ |
1065 | |
1066 | for (i = 0; i < 8192; i++) |
1067 | smw_putmem(devc, mp_base, i, smw_ucode[i]); |
1068 | |
1069 | /* |
1070 | * Verify microcode |
1071 | */ |
1072 | |
1073 | for (i = 0; i < 8192; i++) |
1074 | if (smw_getmem(devc, mp_base, i) != smw_ucode[i]) |
1075 | { |
1076 | printk(KERN_ERR "SM Wave: Microcode verification failed\n"); |
1077 | return 0; |
1078 | } |
1079 | } |
1080 | control = 0; |
1081 | #ifdef SMW_SCSI_IRQ |
1082 | /* |
1083 | * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt |
1084 | * is disabled by default. |
1085 | * |
1086 | * FIXME - make this a module option |
1087 | * |
1088 | * BTW the Zilog 5380 SCSI controller is located at MPU base + 0x10. |
1089 | */ |
1090 | { |
1091 | static unsigned char scsi_irq_bits[] = { |
1092 | 0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0 |
1093 | }; |
1094 | control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6; |
1095 | } |
1096 | #endif |
1097 | |
1098 | #ifdef SMW_OPL4_ENABLE |
1099 | /* |
1100 | * Make the OPL4 chip visible on the PC bus at 0x380. |
1101 | * |
1102 | * There is no need to enable this feature since this driver |
1103 | * doesn't support OPL4 yet. Also there is no RAM in SM Wave so |
1104 | * enabling OPL4 is pretty useless. |
1105 | */ |
1106 | control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */ |
1107 | /* control |= 0x20; Uncomment this if you want to use IRQ7 */ |
1108 | #endif |
1109 | outb((control | 0x03), mpu_base + 7); /* xxxxxx11 restarts */ |
1110 | hw_config->name = "SoundMan Wave"; |
1111 | return 1; |
1112 | } |
1113 | |
1114 | static int init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config) |
1115 | { |
1116 | int mpu_base = hw_config->io_base; |
1117 | int sb_base = devc->base; |
1118 | int irq = hw_config->irq; |
1119 | |
1120 | unsigned char bits = 0; |
1121 | unsigned long flags; |
1122 | |
1123 | if (irq < 0) |
1124 | irq *= -1; |
1125 | |
1126 | if (irq < 1 || irq > 15 || |
1127 | jazz_irq_bits[irq] == 0) |
1128 | { |
1129 | printk(KERN_ERR "Jazz16: Invalid MIDI interrupt (IRQ%d)\n", irq); |
1130 | return 0; |
1131 | } |
1132 | switch (sb_base) |
1133 | { |
1134 | case 0x220: |
1135 | bits = 1; |
1136 | break; |
1137 | case 0x240: |
1138 | bits = 2; |
1139 | break; |
1140 | case 0x260: |
1141 | bits = 3; |
1142 | break; |
1143 | default: |
1144 | return 0; |
1145 | } |
1146 | bits = jazz16_bits = bits << 5; |
1147 | switch (mpu_base) |
1148 | { |
1149 | case 0x310: |
1150 | bits |= 1; |
1151 | break; |
1152 | case 0x320: |
1153 | bits |= 2; |
1154 | break; |
1155 | case 0x330: |
1156 | bits |= 3; |
1157 | break; |
1158 | default: |
1159 | printk(KERN_ERR "Jazz16: Invalid MIDI I/O port %x\n", mpu_base); |
1160 | return 0; |
1161 | } |
1162 | /* |
1163 | * Magic wake up sequence by writing to 0x201 (aka Joystick port) |
1164 | */ |
1165 | spin_lock_irqsave(&jazz16_lock, flags); |
1166 | outb(0xAF, 0x201); |
1167 | outb(0x50, 0x201); |
1168 | outb(bits, 0x201); |
1169 | spin_unlock_irqrestore(&jazz16_lock, flags); |
1170 | |
1171 | hw_config->name = "Jazz16"; |
1172 | smw_midi_init(devc, hw_config); |
1173 | |
1174 | if (!sb_dsp_command(devc, 0xfb)) |
1175 | return 0; |
1176 | |
1177 | if (!sb_dsp_command(devc, jazz_dma_bits[devc->dma8] | |
1178 | (jazz_dma_bits[devc->dma16] << 4))) |
1179 | return 0; |
1180 | |
1181 | if (!sb_dsp_command(devc, jazz_irq_bits[devc->irq] | |
1182 | (jazz_irq_bits[irq] << 4))) |
1183 | return 0; |
1184 | |
1185 | return 1; |
1186 | } |
1187 | |
1188 | int probe_sbmpu(struct address_info *hw_config, struct module *owner) |
1189 | { |
1190 | sb_devc *devc = last_devc; |
1191 | int ret; |
1192 | |
1193 | if (last_devc == NULL) |
1194 | return 0; |
1195 | |
1196 | last_devc = NULL; |
1197 | |
1198 | if (hw_config->io_base <= 0) |
1199 | { |
1200 | /* The real vibra16 is fine about this, but we have to go |
1201 | wipe up after Cyrix again */ |
1202 | |
1203 | if(devc->model == MDL_SB16 && devc->minor >= 12) |
1204 | { |
1205 | unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06; |
1206 | sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */ |
1207 | } |
1208 | return 0; |
1209 | } |
1210 | |
1211 | #if defined(CONFIG_SOUND_MPU401) |
1212 | if (devc->model == MDL_ESS) |
1213 | { |
1214 | struct resource *ports; |
1215 | ports = request_region(hw_config->io_base, 2, "mpu401"); |
1216 | if (!ports) { |
1217 | printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base); |
1218 | return 0; |
1219 | } |
1220 | if (!ess_midi_init(devc, hw_config)) { |
1221 | release_region(hw_config->io_base, 2); |
1222 | return 0; |
1223 | } |
1224 | hw_config->name = "ESS1xxx MPU"; |
1225 | devc->midi_irq_cookie = NULL; |
1226 | if (!probe_mpu401(hw_config, ports)) { |
1227 | release_region(hw_config->io_base, 2); |
1228 | return 0; |
1229 | } |
1230 | attach_mpu401(hw_config, owner); |
1231 | if (last_sb->irq == -hw_config->irq) |
1232 | last_sb->midi_irq_cookie = |
1233 | (void *)(long) hw_config->slots[1]; |
1234 | return 1; |
1235 | } |
1236 | #endif |
1237 | |
1238 | switch (devc->model) |
1239 | { |
1240 | case MDL_SB16: |
1241 | if (hw_config->io_base != 0x300 && hw_config->io_base != 0x330) |
1242 | { |
1243 | printk(KERN_ERR "SB16: Invalid MIDI port %x\n", hw_config->io_base); |
1244 | return 0; |
1245 | } |
1246 | hw_config->name = "Sound Blaster 16"; |
1247 | if (hw_config->irq < 3 || hw_config->irq == devc->irq) |
1248 | hw_config->irq = -devc->irq; |
1249 | if (devc->minor > 12) /* What is Vibra's version??? */ |
1250 | sb16_set_mpu_port(devc, hw_config); |
1251 | break; |
1252 | |
1253 | case MDL_JAZZ: |
1254 | if (hw_config->irq < 3 || hw_config->irq == devc->irq) |
1255 | hw_config->irq = -devc->irq; |
1256 | if (!init_Jazz16_midi(devc, hw_config)) |
1257 | return 0; |
1258 | break; |
1259 | |
1260 | case MDL_YMPCI: |
1261 | hw_config->name = "Yamaha PCI Legacy"; |
1262 | printk("Yamaha PCI legacy UART401 check.\n"); |
1263 | break; |
1264 | default: |
1265 | return 0; |
1266 | } |
1267 | |
1268 | ret = probe_uart401(hw_config, owner); |
1269 | if (ret) |
1270 | last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc; |
1271 | return ret; |
1272 | } |
1273 | |
1274 | void unload_sbmpu(struct address_info *hw_config) |
1275 | { |
1276 | #if defined(CONFIG_SOUND_MPU401) |
1277 | if (!strcmp (hw_config->name, "ESS1xxx MPU")) { |
1278 | unload_mpu401(hw_config); |
1279 | return; |
1280 | } |
1281 | #endif |
1282 | unload_uart401(hw_config); |
1283 | } |
1284 | |
1285 | EXPORT_SYMBOL(sb_dsp_init); |
1286 | EXPORT_SYMBOL(sb_dsp_detect); |
1287 | EXPORT_SYMBOL(sb_dsp_unload); |
1288 | EXPORT_SYMBOL(sb_be_quiet); |
1289 | EXPORT_SYMBOL(probe_sbmpu); |
1290 | EXPORT_SYMBOL(unload_sbmpu); |
1291 | EXPORT_SYMBOL(smw_free); |
1292 | MODULE_LICENSE("GPL"); |
1293 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9