OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [sound/] [trix.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * sound/trix.c
3
 *
4
 * Low level driver for the MediaTrix AudioTrix Pro
5
 * (MT-0002-PC Control Chip)
6
 */
7
/*
8
 * Copyright (C) by Hannu Savolainen 1993-1996
9
 *
10
 * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12
 * for more info.
13
 */
14
#include <linux/config.h>
15
 
16
 
17
#include "sound_config.h"
18
#include "sb.h"
19
 
20
#if defined(CONFIG_TRIX)
21
 
22
#ifdef INCLUDE_TRIX_BOOT
23
#include "trix_boot.h"
24
#else
25
static unsigned char *trix_boot = NULL;
26
static int      trix_boot_len = 0;
27
 
28
#endif
29
 
30
 
31
static int      kilroy_was_here = 0;     /* Don't detect twice */
32
static int      sb_initialized = 0;
33
static int      mpu_initialized = 0;
34
 
35
static int     *trix_osp = NULL;
36
 
37
static unsigned char
38
trix_read (int addr)
39
{
40
  outb ((unsigned char) addr, 0x390);   /* MT-0002-PC ASIC address */
41
  return inb (0x391);           /* MT-0002-PC ASIC data */
42
}
43
 
44
static void
45
trix_write (int addr, int data)
46
{
47
  outb ((unsigned char) addr, 0x390);   /* MT-0002-PC ASIC address */
48
  outb ((unsigned char) data, 0x391);   /* MT-0002-PC ASIC data */
49
}
50
 
51
static void
52
download_boot (int base)
53
{
54
  int             i = 0, n = trix_boot_len;
55
 
56
  if (trix_boot_len == 0)
57
    return;
58
 
59
  trix_write (0xf8, 0x00);      /* ??????? */
60
  outb (0x01, base + 6);        /* Clear the internal data pointer */
61
  outb (0x00, base + 6);        /* Restart */
62
 
63
  /*
64
     *  Write the boot code to the RAM upload/download register.
65
     *  Each write increments the internal data pointer.
66
   */
67
  outb (0x01, base + 6);        /* Clear the internal data pointer */
68
  outb (0x1A, 0x390);           /* Select RAM download/upload port */
69
 
70
  for (i = 0; i < n; i++)
71
    outb (trix_boot[i], 0x391);
72
  for (i = n; i < 10016; i++)   /* Clear up to first 16 bytes of data RAM */
73
    outb (0x00, 0x391);
74
  outb (0x00, base + 6);        /* Reset */
75
  outb (0x50, 0x390);           /* ?????? */
76
 
77
}
78
 
79
static int
80
trix_set_wss_port (struct address_info *hw_config)
81
{
82
  unsigned char   addr_bits;
83
 
84
  if (check_region (0x390, 2))
85
    {
86
      printk ("AudioTrix: Config port I/O conflict\n");
87
      return 0;
88
    }
89
 
90
  if (kilroy_was_here)          /* Already initialized */
91
    return 0;
92
 
93
  if (trix_read (0x15) != 0x71) /* No ASIC signature */
94
    {
95
      DDB (printk ("No AudioTrix ASIC signature found\n"));
96
      return 0;
97
    }
98
 
99
  kilroy_was_here = 1;
100
 
101
  /*
102
   * Reset some registers.
103
   */
104
 
105
  trix_write (0x13, 0);
106
  trix_write (0x14, 0);
107
 
108
  /*
109
     * Configure the ASIC to place the codec to the proper I/O location
110
   */
111
 
112
  switch (hw_config->io_base)
113
    {
114
    case 0x530:
115
      addr_bits = 0;
116
      break;
117
    case 0x604:
118
      addr_bits = 1;
119
      break;
120
    case 0xE80:
121
      addr_bits = 2;
122
      break;
123
    case 0xF40:
124
      addr_bits = 3;
125
      break;
126
    default:
127
      return 0;
128
    }
129
 
130
  trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits);
131
  return 1;
132
}
133
 
134
/*
135
 *    Probe and attach routines for the Windows Sound System mode of
136
 *      AudioTrix Pro
137
 */
138
 
139
int
140
probe_trix_wss (struct address_info *hw_config)
141
{
142
  int             ret;
143
 
144
  /*
145
     * Check if the IO port returns valid signature. The original MS Sound
146
     * system returns 0x04 while some cards (AudioTrix Pro for example)
147
     * return 0x00.
148
   */
149
  if (check_region (hw_config->io_base, 8))
150
    {
151
      printk ("AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
152
      return 0;
153
    }
154
 
155
  trix_osp = hw_config->osp;
156
 
157
  if (!trix_set_wss_port (hw_config))
158
    return 0;
159
 
160
  if ((inb (hw_config->io_base + 3) & 0x3f) != 0x00)
161
    {
162
      DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config->io_base));
163
      return 0;
164
    }
165
 
166
  if (hw_config->irq > 11)
167
    {
168
      printk ("AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
169
      return 0;
170
    }
171
 
172
  if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
173
    {
174
      printk ("AudioTrix: Bad WSS DMA %d\n", hw_config->dma);
175
      return 0;
176
    }
177
 
178
  if (hw_config->dma2 != -1)
179
    if (hw_config->dma2 != 0 && hw_config->dma2 != 1 && hw_config->dma2 != 3)
180
      {
181
        printk ("AudioTrix: Bad capture DMA %d\n", hw_config->dma2);
182
        return 0;
183
      }
184
 
185
  /*
186
     * Check that DMA0 is not in use with a 8 bit board.
187
   */
188
 
189
  if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
190
    {
191
      printk ("AudioTrix: Can't use DMA0 with a 8 bit card\n");
192
      return 0;
193
    }
194
 
195
  if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
196
    {
197
      printk ("AudioTrix: Can't use IRQ%d with a 8 bit card\n", hw_config->irq);
198
      return 0;
199
    }
200
 
201
  ret = ad1848_detect (hw_config->io_base + 4, NULL, hw_config->osp);
202
 
203
  if (ret)
204
    request_region (0x390, 2, "AudioTrix");
205
 
206
  return ret;
207
}
208
 
209
void
210
attach_trix_wss (struct address_info *hw_config)
211
{
212
  static unsigned char interrupt_bits[12] =
213
  {0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x10, 0x18, 0x20};
214
  char            bits;
215
 
216
  static unsigned char dma_bits[4] =
217
  {1, 2, 0, 3};
218
 
219
  int             config_port = hw_config->io_base + 0;
220
  int             dma1 = hw_config->dma, dma2 = hw_config->dma2;
221
 
222
  trix_osp = hw_config->osp;
223
 
224
  if (!kilroy_was_here)
225
    {
226
      DDB (printk ("AudioTrix: Attach called but not probed yet???\n"));
227
      return;
228
    }
229
 
230
  /*
231
     * Set the IRQ and DMA addresses.
232
   */
233
 
234
  bits = interrupt_bits[hw_config->irq];
235
  if (bits == 0)
236
    {
237
      printk ("AudioTrix: Bad IRQ (%d)\n", hw_config->irq);
238
      return;
239
    }
240
 
241
  outb (bits | 0x40, config_port);
242
 
243
  if (hw_config->dma2 == -1 || hw_config->dma2 == hw_config->dma)
244
    {
245
      bits |= dma_bits[dma1];
246
      dma2 = dma1;
247
    }
248
  else
249
    {
250
      unsigned char   tmp;
251
 
252
      tmp = trix_read (0x13) & ~30;
253
      trix_write (0x13, tmp | 0x80 | (dma1 << 4));
254
 
255
      tmp = trix_read (0x14) & ~30;
256
      trix_write (0x14, tmp | 0x80 | (dma2 << 4));
257
    }
258
 
259
  outb (bits, config_port);     /* Write IRQ+DMA setup */
260
 
261
  ad1848_init ("AudioTrix Pro", hw_config->io_base + 4,
262
               hw_config->irq,
263
               dma1,
264
               dma2,
265
               0,
266
               hw_config->osp);
267
  request_region (hw_config->io_base, 4, "MSS config");
268
}
269
 
270
int
271
probe_trix_sb (struct address_info *hw_config)
272
{
273
 
274
  int             tmp;
275
  unsigned char   conf;
276
  static char     irq_translate[] =
277
  {-1, -1, -1, 0, 1, 2, -1, 3};
278
 
279
  if (trix_boot_len == 0)
280
    return 0;                    /* No boot code -> no fun */
281
 
282
  if (!kilroy_was_here)
283
    return 0;                    /* AudioTrix Pro has not been detected earlier */
284
 
285
  if (sb_initialized)
286
    return 0;
287
 
288
  if (check_region (hw_config->io_base, 16))
289
    {
290
      printk ("AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
291
      return 0;
292
    }
293
 
294
  if ((hw_config->io_base & 0xffffff8f) != 0x200)
295
    return 0;
296
 
297
  tmp = hw_config->irq;
298
  if (tmp > 7)
299
    return 0;
300
  if (irq_translate[tmp] == -1)
301
    return 0;
302
 
303
  tmp = hw_config->dma;
304
  if (tmp != 1 && tmp != 3)
305
    return 0;
306
 
307
  conf = 0x84;                  /* DMA and IRQ enable */
308
  conf |= hw_config->io_base & 0x70;    /* I/O address bits */
309
  conf |= irq_translate[hw_config->irq];
310
  if (hw_config->dma == 3)
311
    conf |= 0x08;
312
  trix_write (0x1b, conf);
313
 
314
  download_boot (hw_config->io_base);
315
  sb_initialized = 1;
316
 
317
  hw_config->name = "AudioTrix SB";
318
#ifdef CONFIG_SBDSP
319
  return probe_sb (hw_config);
320
#else
321
  return 0;
322
#endif
323
}
324
 
325
void
326
attach_trix_sb (struct address_info *hw_config)
327
{
328
#ifdef CONFIG_SBDSP
329
  hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;
330
  attach_sb_card (hw_config);
331
#endif
332
}
333
 
334
void
335
attach_trix_mpu (struct address_info *hw_config)
336
{
337
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
338
  hw_config->name = "AudioTrix Pro";
339
  attach_uart401 (hw_config);
340
#endif
341
}
342
 
343
int
344
probe_trix_mpu (struct address_info *hw_config)
345
{
346
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
347
  unsigned char   conf;
348
  static char     irq_bits[] =
349
  {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
350
 
351
  if (!kilroy_was_here)
352
    {
353
      DDB (printk ("Trix: WSS and SB modes must be initialized before MPU\n"));
354
      return 0;                  /* AudioTrix Pro has not been detected earlier */
355
    }
356
 
357
  if (!sb_initialized)
358
    {
359
      DDB (printk ("Trix: SB mode must be initialized before MPU\n"));
360
      return 0;
361
    }
362
 
363
  if (mpu_initialized)
364
    {
365
      DDB (printk ("Trix: MPU mode already initialized\n"));
366
      return 0;
367
    }
368
 
369
  if (check_region (hw_config->io_base, 4))
370
    {
371
      printk ("AudioTrix: MPU I/O port conflict (%x)\n", hw_config->io_base);
372
      return 0;
373
    }
374
 
375
  if (hw_config->irq > 9)
376
    {
377
      printk ("AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
378
      return 0;
379
    }
380
 
381
  if (irq_bits[hw_config->irq] == -1)
382
    {
383
      printk ("AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
384
      return 0;
385
    }
386
 
387
  switch (hw_config->io_base)
388
    {
389
    case 0x330:
390
      conf = 0x00;
391
      break;
392
    case 0x370:
393
      conf = 0x04;
394
      break;
395
    case 0x3b0:
396
      conf = 0x08;
397
      break;
398
    case 0x3f0:
399
      conf = 0x0c;
400
      break;
401
    default:
402
      return 0;                  /* Invalid port */
403
    }
404
 
405
  conf |= irq_bits[hw_config->irq] << 4;
406
 
407
  trix_write (0x19, (trix_read (0x19) & 0x83) | conf);
408
 
409
  mpu_initialized = 1;
410
 
411
  return probe_uart401 (hw_config);
412
#else
413
  return 0;
414
#endif
415
}
416
 
417
void
418
unload_trix_wss (struct address_info *hw_config)
419
{
420
  int             dma2 = hw_config->dma2;
421
 
422
  if (dma2 == -1)
423
    dma2 = hw_config->dma;
424
 
425
  release_region (0x390, 2);
426
  release_region (hw_config->io_base, 4);
427
 
428
  ad1848_unload (hw_config->io_base + 4,
429
                 hw_config->irq,
430
                 hw_config->dma,
431
                 dma2,
432
                 0);
433
}
434
 
435
void
436
unload_trix_mpu (struct address_info *hw_config)
437
{
438
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
439
  unload_uart401 (hw_config);
440
#endif
441
}
442
void
443
unload_trix_sb (struct address_info *hw_config)
444
{
445
#ifdef CONFIG_SBDSP
446
  unload_sb (hw_config);
447
#endif
448
}
449
 
450
 
451
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.