4 * Low level driver for the MediaTriX AudioTriX Pro
5 * (MT-0002-PC Control Chip)
7 * Copyright by Hannu Savolainen 1995
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met: 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 2.
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include "sound_config.h"
33 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_TRIX)
35 #ifdef INCLUDE_TRIX_BOOT
36 #include "trix_boot.h"
39 static int kilroy_was_here
= 0; /* Don't detect twice */
40 static int sb_initialized
= 0;
41 static int mpu_initialized
= 0;
43 static sound_os_info
*trix_osp
= NULL
;
48 outb ((unsigned char) addr
, 0x390); /* MT-0002-PC ASIC address */
49 return inb (0x391); /* MT-0002-PC ASIC data */
53 trix_write (int addr
, int data
)
55 outb ((unsigned char) addr
, 0x390); /* MT-0002-PC ASIC address */
56 outb ((unsigned char) data
, 0x391); /* MT-0002-PC ASIC data */
60 download_boot (int base
)
62 #ifdef INCLUDE_TRIX_BOOT
63 int i
= 0, n
= sizeof (trix_boot
);
65 trix_write (0xf8, 0x00); /* ??????? */
66 outb (0x01, base
+ 6); /* Clear the internal data pointer */
67 outb (0x00, base
+ 6); /* Restart */
70 * Write the boot code to the RAM upload/download register.
71 * Each write increments the internal data pointer.
73 outb (0x01, base
+ 6); /* Clear the internal data pointer */
74 outb (0x1A, 0x390); /* Select RAM download/upload port */
76 for (i
= 0; i
< n
; i
++)
77 outb (trix_boot
[i
], 0x391);
78 for (i
= n
; i
< 10016; i
++) /* Clear up to first 16 bytes of data RAM */
80 outb (0x00, base
+ 6); /* Reset */
81 outb (0x50, 0x390); /* ?????? */
86 trix_set_wss_port (struct address_info
*hw_config
)
88 unsigned char addr_bits
;
90 if (check_region (0x390, 2))
92 printk ("AudioTriX: Config port I/O conflict\n");
96 if (kilroy_was_here
) /* Already initialized */
99 if (trix_read (0x15) != 0x71) /* No asic signature */
101 DDB (printk ("No AudioTriX ASIC signature found\n"));
105 request_region (0x390, 2, "AudioTriX");
110 * Reset some registers.
113 trix_write (0x13, 0);
114 trix_write (0x14, 0);
117 * Configure the ASIC to place the codec to the proper I/O location
120 switch (hw_config
->io_base
)
138 trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits
);
143 * Probe and attach routines for the Windows Sound System mode of
148 probe_trix_wss (struct address_info
*hw_config
)
151 * Check if the IO port returns valid signature. The original MS Sound
152 * system returns 0x04 while some cards (AudioTriX Pro for example)
155 if (check_region (hw_config
->io_base
, 8))
157 printk ("AudioTriX: MSS I/O port conflict\n");
161 trix_osp
= hw_config
->osp
;
163 if (!trix_set_wss_port (hw_config
))
166 if ((inb (hw_config
->io_base
+ 3) & 0x3f) != 0x00)
168 DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config
->io_base
));
172 if (hw_config
->irq
> 11)
174 printk ("AudioTriX: Bad WSS IRQ %d\n", hw_config
->irq
);
178 if (hw_config
->dma
!= 0 && hw_config
->dma
!= 1 && hw_config
->dma
!= 3)
180 printk ("AudioTriX: Bad WSS DMA %d\n", hw_config
->dma
);
184 if (hw_config
->dma2
!= -1)
185 if (hw_config
->dma2
!= 0 && hw_config
->dma2
!= 1 && hw_config
->dma2
!= 3)
187 printk ("AudioTriX: Bad capture DMA %d\n", hw_config
->dma2
);
192 * Check that DMA0 is not in use with a 8 bit board.
195 if (hw_config
->dma
== 0 && inb (hw_config
->io_base
+ 3) & 0x80)
197 printk ("AudioTriX: Can't use DMA0 with a 8 bit card\n");
201 if (hw_config
->irq
> 7 && hw_config
->irq
!= 9 && inb (hw_config
->io_base
+ 3) & 0x80)
203 printk ("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config
->irq
);
207 return ad1848_detect (hw_config
->io_base
+ 4, NULL
, hw_config
->osp
);
211 attach_trix_wss (long mem_start
, struct address_info
*hw_config
)
213 static unsigned char interrupt_bits
[12] =
214 {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20};
217 static unsigned char dma_bits
[4] =
220 int config_port
= hw_config
->io_base
+ 0, version_port
= hw_config
->io_base
+ 3;
221 int dma1
= hw_config
->dma
, dma2
= hw_config
->dma2
;
223 trix_osp
= hw_config
->osp
;
225 if (!kilroy_was_here
)
227 DDB (printk ("AudioTriX: Attach called but not probed yet???\n"));
232 * Set the IRQ and DMA addresses.
235 bits
= interrupt_bits
[hw_config
->irq
];
238 printk ("AudioTriX: Bad IRQ (%d)\n", hw_config
->irq
);
242 outb (bits
| 0x40, config_port
);
243 if ((inb (version_port
) & 0x40) == 0)
244 printk ("[IRQ Conflict?]");
246 if (hw_config
->dma2
== -1) /* Single DMA mode */
248 bits
|= dma_bits
[dma1
];
255 tmp
= trix_read (0x13) & ~30;
256 trix_write (0x13, tmp
| 0x80 | (dma1
<< 4));
258 tmp
= trix_read (0x14) & ~30;
259 trix_write (0x14, tmp
| 0x80 | (dma2
<< 4));
262 outb (bits
, config_port
); /* Write IRQ+DMA setup */
264 ad1848_init ("AudioTriX Pro", hw_config
->io_base
+ 4,
270 request_region (hw_config
->io_base
, 4, "MSS config");
275 probe_trix_sb (struct address_info
*hw_config
)
280 static char irq_translate
[] =
281 {-1, -1, -1, 0, 1, 2, -1, 3};
283 #ifndef INCLUDE_TRIX_BOOT
284 return 0; /* No boot code -> no fun */
286 if (!kilroy_was_here
)
287 return 0; /* AudioTriX Pro has not been detected earlier */
292 if (check_region (hw_config
->io_base
, 16))
294 printk ("AudioTriX: SB I/O port conflict\n");
298 if (hw_config
->io_base
& 0xffffff8f != 0x200)
301 tmp
= hw_config
->irq
;
304 if (irq_translate
[tmp
] == -1)
307 tmp
= hw_config
->dma
;
308 if (tmp
!= 1 && tmp
!= 3)
311 conf
= 0x84; /* DMA and IRQ enable */
312 conf
|= hw_config
->io_base
& 0x70; /* I/O address bits */
313 conf
|= irq_translate
[hw_config
->irq
];
314 if (hw_config
->dma
== 3)
316 trix_write (0x1b, conf
);
318 download_boot (hw_config
->io_base
);
325 attach_trix_sb (long mem_start
, struct address_info
*hw_config
)
328 extern int sb_no_recording
;
330 sb_dsp_disable_midi ();
333 printk (" <AudioTriX (SB)>");
338 attach_trix_mpu (long mem_start
, struct address_info
*hw_config
)
340 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
341 return attach_mpu401 (mem_start
, hw_config
);
348 probe_trix_mpu (struct address_info
*hw_config
)
350 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
352 static char irq_bits
[] =
353 {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
355 if (!kilroy_was_here
)
357 DDB (printk ("Trix: WSS and SB modes must be initialized before MPU\n"));
358 return 0; /* AudioTriX Pro has not been detected earlier */
363 DDB (printk ("Trix: SB mode must be initialized before MPU\n"));
369 DDB (printk ("Trix: MPU mode already initialized\n"));
373 if (check_region (hw_config
->io_base
, 4))
375 printk ("AudioTriX: MPU I/O port conflict\n");
379 if (hw_config
->irq
> 9)
381 printk ("AudioTriX: Bad MPU IRQ %d\n", hw_config
->irq
);
385 if (irq_bits
[hw_config
->irq
] == -1)
387 printk ("AudioTriX: Bad MPU IRQ %d\n", hw_config
->irq
);
391 switch (hw_config
->io_base
)
406 return 0; /* Invalid port */
409 conf
|= irq_bits
[hw_config
->irq
] << 4;
411 trix_write (0x19, (trix_read (0x19) & 0x83) | conf
);
415 return probe_mpu401 (hw_config
);
422 unload_trix_wss (struct address_info
*hw_config
)
424 int dma2
= hw_config
->dma2
;
427 dma2
= hw_config
->dma
;
429 release_region (0x390, 2);
430 release_region (hw_config
->io_base
, 4);
432 ad1848_unload (hw_config
->io_base
+ 4,
440 unload_trix_mpu (struct address_info
*hw_config
)
442 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
443 unload_mpu401 (hw_config
);
447 unload_trix_sb (struct address_info
*hw_config
)