~ubuntu-branches/ubuntu/oneiric/oss4/oneiric-proposed

« back to all changes in this revision

Viewing changes to attic/drv/oss_vortex/oss_vortex2.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Rivera
  • Date: 2011-06-16 20:37:48 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110616203748-jbrxik6ql33z54co
Tags: 4.2-build2004-1ubuntu1
* Merge from Debian unstable.
  - Supports our current kernel (LP: #746048)
  Remaining changes:
  - debian/oss4-dkms.dkms.in: s/source/build/ in Kernel headers paths.
* ld-as-needed.patch: Re-order CC arguments to enable building with ld
  --as-needed (LP: #770972)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: Driver for Aureal Semiconductor Vortex 2 PCI audio controller.
 
3
 */
 
4
/*
 
5
 *
 
6
 * This file is part of Open Sound System.
 
7
 *
 
8
 * Copyright (C) 4Front Technologies 1996-2008.
 
9
 *
 
10
 * This this source file is released under GPL v2 license (no other versions).
 
11
 * See the COPYING file included in the main directory of this source
 
12
 * distribution for the license terms and conditions.
 
13
 *
 
14
 */
 
15
 
 
16
#include "vortex.h"
 
17
 
 
18
#undef USE_SRC
 
19
#undef USE_SPDIF
 
20
 
 
21
#define AUREAL_VENDOR_ID        0x12eb
 
22
#define AUREAL_VORTEX2          0x0002
 
23
 
 
24
#       define                  ISR     (devc->global_base+0x0)
 
25
#               define                  CODIRQST        0x00008000
 
26
#               define                  MODIRQST        0x00004000
 
27
#               define                  MIDIRQST        0x00002000
 
28
#               define                  TIMIRQST        0x00001000
 
29
#               define                  COIRQLST        0x00000800
 
30
#               define                  COIRQPST        0x00000400
 
31
#               define                  FRCIRQST        0x00000200
 
32
#               define                  SBIRQST         0x00000100
 
33
#               define                  SBMIRQST        0x00000080
 
34
#               define                  FMIRQST         0x00000040
 
35
#               define                  DMAENDIRQST     0x00000020
 
36
#               define                  DMABERRST       0x00000010
 
37
#               define                  FIFOERRST       0x00000008
 
38
#               define                  REGERRST        0x00000004
 
39
#               define                  MPARERRST       0x00000002
 
40
#               define                  MFATERRST       0x00000001
 
41
#       define                  ICR             devc->global_base+0x4
 
42
#       define                  GSR             devc->global_base+0x8
 
43
#       define                  GCR             devc->global_base+0xc
 
44
#               define                  SFTRST          0x00800000
 
45
#               define                  ARBRST          0x00400000
 
46
#               define                  EXTRST          0x00200000
 
47
#               define                  RBTOEN          0x00100000
 
48
#               define                  AINCEN          0x00080000
 
49
#               define                  TTXFLUSH        0x00040000
 
50
#               define                  TRVFLUSH        0x00020000
 
51
#               define                  MFIFOFLUSH      0x00010000
 
52
#               define                  FRCIRQ          0x00008000
 
53
#               define                  GIRQEN          0x00004000
 
54
#       define                  MIDIDAT         devc->midi_base+0x0
 
55
#       define                  MIDICMD         devc->midi_base+0x4
 
56
#       define                  MIDISTAT        MIDICMD
 
57
#               define                  MIDIVAL         0x00000080
 
58
#               define                  CMDOK           0x00000040
 
59
#               define                  MPUMODE         0x00000001
 
60
#       define                  GAMECTL         devc->midi_base+0xc
 
61
#               define                  JOYMODE         0x00000040
 
62
#               define                  MIDITXFULL      0x00000008
 
63
#               define                  MIDIRXINIT      0x00000004
 
64
#               define                  MIDIRXOVFL      0x00000002
 
65
#               define                  MIDIDATVAL      0x00000001
 
66
 
 
67
#define adb_destinations                173
 
68
#       define                  CODSMPLTMR      (devc->serial_block_base+0x19c)
 
69
#define adbarb_base     devc->adbarb_block_base
 
70
#define adbarb_wtdram_base_addr         (devc->adbarb_block_base + 0x000)
 
71
#define adbarb_wtdram_srhdr_base_addr   (devc->adbarb_block_base + (adb_destinations * 4))
 
72
#define adbarb_sr_active_addr           (devc->adbarb_block_base + 0x400)
 
73
 
 
74
#define codec_control_reg_addr          (devc->serial_block_base + 0x184)
 
75
#define cmd_status_reg_addr             (devc->serial_block_base + 0x188)
 
76
#define channel_enable_reg_addr         (devc->serial_block_base + 0x190)
 
77
#define serial_ram_reg_addr             (devc->serial_block_base + 0x00)
 
78
 
 
79
#define         spdif_ctrl_reg  (devc->serial_block_base + 0x0194)      /* offset for spdif control register */
 
80
#define         codec_sample_counter (devc->serial_block_base + 0x0198) /* offset for spdif control register */
 
81
#define         spdif_cfg_dword         0x86    /* enable port, enable CRC, set clock toinput (48kHz) */
 
82
#define         spdif_ch_status_reg0    0x0     /* Set to consumer, digital audio, */
 
83
#define     spdif_ch_status_reg_base (devc->serial_block_base + 0x1D0)  /* Set to the first address location */
 
84
 
 
85
#define fifo_chan0_src_addr         0x00
 
86
#define fifo_chan1_src_addr         0x01
 
87
#define fifo_chan6_src_addr         0x06
 
88
#define fifo_chan7_src_addr         0x07
 
89
#define fifo_chan8_src_addr         0x08
 
90
#define fifo_chan9_src_addr         0x09
 
91
#define fifo_chan2_dst_addr         0x02
 
92
#define fifo_chan2a_dst_addr         0x022
 
93
#define fifo_chan3_dst_addr         0x03
 
94
#define fifo_chan3a_dst_addr         0x023
 
95
#define fifo_chan4_dst_addr         0x04
 
96
#define fifo_chan5_dst_addr         0x05
 
97
#define fifo_chan6_dst_addr         0x06
 
98
#define fifo_chan7_dst_addr         0x07
 
99
#define fifo_chan8_dst_addr         0x08
 
100
#define fifo_chan9_dst_addr         0x09
 
101
#define fifo_chana_dst_addr         0x0a
 
102
#define fifo_chanb_dst_addr         0x0b
 
103
 
 
104
#define codec_chan0_src_addr        0x70
 
105
#define codec_chan1_src_addr        0x71
 
106
#define codec_chan0_dst_addr        0x88
 
107
#define codec_chan1_dst_addr        0x89
 
108
#define codec_chan4_dst_addr        0x8c
 
109
#define codec_chan5_dst_addr        0x8d
 
110
 
 
111
#define spdif_chan0_dst_addr                0x92
 
112
#define spdif_chan1_dst_addr                0x93
 
113
 
 
114
#define src_chan0_dst_addr                  0x40
 
115
#define src_chan1_dst_addr                  0x41
 
116
#define src_chan0_src_addr                  0x20
 
117
#define src_chan1_src_addr                  0x21
 
118
 
 
119
#define src_base_offset                         (devc->src_base)
 
120
#define src_input_fifo_base                     (devc->src_base + 0x000)
 
121
#define src_output_fifo_base                    (devc->src_base + 0x800)
 
122
#define src_next_ch_base                        (devc->src_base + 0xc00)
 
123
#define src_sr_header_base                      (devc->src_base + 0xc40)
 
124
#define src_active_sample_rate                  (devc->src_base + 0xcc0)
 
125
#define src_throttle_source                     (devc->src_base + 0xcc4)
 
126
#define src_throttle_count_size                 (devc->src_base + 0xcc8)
 
127
#define src_ch_params_base                      (devc->src_base + 0xe00)
 
128
#define src_ch_param0                           (devc->src_base + 0xe00)
 
129
#define src_ch_param1                           (devc->src_base + 0xe40)
 
130
#define src_ch_param2                           (devc->src_base + 0xe80)
 
131
#define src_ch_param3                           (devc->src_base + 0xec0)
 
132
#define src_ch_param4                           (devc->src_base + 0xf00)
 
133
#define src_ch_param5                           (devc->src_base + 0xf40)
 
134
#define src_ch_param6                           (devc->src_base + 0xf80)
 
135
 
 
136
#define pif_gpio_control                        (devc->parallel_base + 0x05c)
 
137
 
 
138
/************************************************************
 
139
 *                          Vortex2 Routines                *
 
140
 ************************************************************/
 
141
 
 
142
 
 
143
static unsigned int
 
144
V2ReadReg (vortex_devc * devc, oss_native_word addr)
 
145
{
 
146
  return READL (addr);
 
147
}
 
148
 
 
149
static void
 
150
V2WriteReg (vortex_devc * devc, oss_native_word addr, oss_native_word data)
 
151
{
 
152
  WRITEL (addr, data);
 
153
}
 
154
 
 
155
static void
 
156
V2ReadCodecRegister (vortex_devc * devc, int cIndex, int *pdwData)
 
157
{
 
158
  int dwCmdStRegAddr;
 
159
  int dwCmdStRegData;
 
160
  int nCnt = 0;
 
161
 
 
162
  dwCmdStRegAddr = cIndex << 16;
 
163
  V2WriteReg (devc, cmd_status_reg_addr, dwCmdStRegAddr);
 
164
  do
 
165
    {
 
166
      dwCmdStRegData = V2ReadReg (devc, cmd_status_reg_addr);
 
167
      if (nCnt++ > 1)
 
168
        oss_udelay (10);
 
169
    }
 
170
  while ((dwCmdStRegData & 0x00FF0000) != ((1 << 23) | (dwCmdStRegAddr))
 
171
         && (nCnt < 10));
 
172
  if (nCnt >= 50)
 
173
    {
 
174
      *pdwData = -1;
 
175
      cmn_err (CE_WARN, "AC97 Timeout\n");
 
176
    }
 
177
  else
 
178
    *pdwData = dwCmdStRegData & 0x0000ffff;
 
179
}
 
180
 
 
181
static void
 
182
V2WriteCodecCommand (vortex_devc * devc, int cIndex, int wData)
 
183
{
 
184
  int dwData;
 
185
  int nCnt = 0;
 
186
 
 
187
 
 
188
  do
 
189
    {
 
190
      dwData = V2ReadReg (devc, codec_control_reg_addr);
 
191
      if (nCnt++ > 1)
 
192
        oss_udelay (10);
 
193
    }
 
194
  while (!(dwData & 0x0100) && (nCnt < 50));
 
195
  if (nCnt >= 10)
 
196
    cmn_err (CE_WARN, "AC97 write timeout.\n");
 
197
 
 
198
 
 
199
  do
 
200
    {
 
201
      dwData = V2ReadReg (devc, codec_control_reg_addr);
 
202
      if (nCnt++ > 1)
 
203
        oss_udelay (10);
 
204
    }
 
205
  while (!(dwData & 0x0100) && (nCnt < 100));
 
206
  if (nCnt >= 100)
 
207
    cmn_err (CE_WARN, "AC97 timeout(2)\n");
 
208
 
 
209
  dwData = (cIndex << 16) | (1 << 23) | wData;
 
210
  V2WriteReg (devc, cmd_status_reg_addr, dwData);
 
211
  oss_udelay (20);
 
212
  /* Read it back to make sure it got there */
 
213
  do
 
214
    {
 
215
      dwData = V2ReadReg (devc, codec_control_reg_addr);
 
216
      if (nCnt++ > 1)
 
217
        oss_udelay (10);
 
218
    }
 
219
  while (!(dwData & 0x0100) && (nCnt < 100));
 
220
  if (nCnt >= 100)
 
221
    cmn_err (CE_WARN, "AC97 timeout(3)\n");
 
222
  V2ReadCodecRegister (devc, cIndex, &dwData);
 
223
  if (dwData != (int) wData)
 
224
    {
 
225
      do
 
226
        {
 
227
          dwData = V2ReadReg (devc, codec_control_reg_addr);
 
228
          if (nCnt++ > 1)
 
229
            oss_udelay (10);
 
230
        }
 
231
      while (!(dwData & 0x0100) && (nCnt < 10));
 
232
      if (nCnt >= 10)
 
233
        cmn_err (CE_WARN, "AC97 Timeout(4).\n");
 
234
      dwData = (cIndex << 16) | (1 << 23) | wData;
 
235
      V2WriteReg (devc, cmd_status_reg_addr, dwData);
 
236
      do
 
237
        {
 
238
          dwData = V2ReadReg (devc, codec_control_reg_addr);
 
239
          if (nCnt++ > 1)
 
240
            oss_udelay (10);
 
241
        }
 
242
      while (!(dwData & 0x0100) && (nCnt < 100));
 
243
      if (nCnt >= 100)
 
244
        cmn_err (CE_WARN, "AC97 timeout(5).\n");
 
245
#if 0
 
246
      V2ReadCodecRegister (devc, cIndex, &dwData);
 
247
      if (dwData != (int) wData)
 
248
        {
 
249
          cmn_err (CE_WARN,
 
250
                   "Vortex ERROR: Write to index %x failed (exp %04x, got %04x)\n",
 
251
                   cIndex, wData, dwData);
 
252
        }
 
253
#endif
 
254
    }
 
255
}
 
256
 
 
257
static void
 
258
ClearDataFifo (vortex_devc * devc, int nChannel)
 
259
{
 
260
  int j;
 
261
 
 
262
  /* Clear out FIFO data */
 
263
  for (j = 0; j < 64; j++)
 
264
    V2WriteReg (devc,
 
265
                devc->fifo_base + 0x4000 + (0x100 * nChannel) + (0x4 * j),
 
266
                0x0);
 
267
}
 
268
 
 
269
static void
 
270
cold_reset (vortex_devc * devc)
 
271
{
 
272
  int i, reg;
 
273
  int bSigmatelCodec = 0;
 
274
 
 
275
  V2ReadCodecRegister (devc, 0x7c, &reg);
 
276
  if (reg == 0x8384)
 
277
    {
 
278
      DDB (cmn_err (CE_WARN, "Sigmatel codec detected\n"));
 
279
      bSigmatelCodec = 1;
 
280
    }
 
281
 
 
282
  for (i = 0; i < 32; i = i + 1)
 
283
    {
 
284
      V2WriteReg (devc, serial_ram_reg_addr + 0x80 + (i * 4), 0);
 
285
      oss_udelay (10);
 
286
    }
 
287
  if (bSigmatelCodec)
 
288
    {
 
289
      /* Disable clock */
 
290
      V2WriteReg (devc, codec_control_reg_addr, 0x00a8);
 
291
      oss_udelay (100);
 
292
      /* Set Sync High     */
 
293
      /*    V2WriteReg(devc, codec_control_reg_addr, 0x40a8); */
 
294
      /*    delay(100);    */
 
295
      /* Place CODEC into reset */
 
296
      V2WriteReg (devc, codec_control_reg_addr, 0x80a8);
 
297
      oss_udelay (100);
 
298
      /* Give CODEC some Clocks with reset asserted */
 
299
      V2WriteReg (devc, codec_control_reg_addr, 0x80e8);
 
300
      oss_udelay (100);
 
301
      /* Turn off clocks */
 
302
      V2WriteReg (devc, codec_control_reg_addr, 0x80a8);
 
303
      oss_udelay (100);
 
304
      /* Take out of reset */
 
305
      /*  V2WriteReg(devc, codec_control_reg_addr, 0x40a8); */
 
306
      /*  oss_udelay(100);    */
 
307
      /* Release reset     */
 
308
      V2WriteReg (devc, codec_control_reg_addr, 0x00a8);
 
309
      oss_udelay (100);
 
310
      /* Turn on clocks        */
 
311
      V2WriteReg (devc, codec_control_reg_addr, 0x00e8);
 
312
      oss_udelay (100);
 
313
    }
 
314
  else
 
315
    {
 
316
      V2WriteReg (devc, codec_control_reg_addr, 0x8068);
 
317
      oss_udelay (10);
 
318
      V2WriteReg (devc, codec_control_reg_addr, 0x00e8);
 
319
      oss_udelay (10);
 
320
    }
 
321
}
 
322
 
 
323
static void
 
324
V2InitCodec (vortex_devc * devc)
 
325
{
 
326
  int i;
 
327
  cold_reset (devc);
 
328
  for (i = 0; i < 32; i = i + 1)
 
329
    {
 
330
      V2WriteReg (devc, serial_ram_reg_addr + 0x80 + (i * 4), 0);
 
331
      oss_udelay (10);
 
332
    }
 
333
 
 
334
  /* Set up the codec in AC97 mode */
 
335
  V2WriteReg (devc, codec_control_reg_addr, 0x00e8);
 
336
  oss_udelay (10);
 
337
  /* Clear the channel enable register */
 
338
  V2WriteReg (devc, channel_enable_reg_addr, 0);
 
339
 
 
340
  /* Set up Sigmatel STAC9708 Codec with initialization routine  rev. 0.50 */
 
341
 
 
342
  V2WriteCodecCommand (devc, 0x26, 0x800f);     /* set EAPD to unmute */
 
343
  oss_udelay (10);
 
344
 
 
345
  V2WriteCodecCommand (devc, 0x76, 0xabba);
 
346
  oss_udelay (10);              /* Turn on secondary output DACs */
 
347
  V2WriteCodecCommand (devc, 0x78, 0x1000);
 
348
  oss_udelay (10);
 
349
 
 
350
  V2WriteCodecCommand (devc, 0x70, 0xabba);
 
351
  oss_udelay (10);              /* Turn on extra current to reduce THD */
 
352
  V2WriteCodecCommand (devc, 0x72, 0x07);
 
353
  oss_udelay (10);
 
354
}
 
355
 
 
356
static void
 
357
V2SetupCodec (vortex_devc * devc)
 
358
{
 
359
  int dwData;
 
360
  int count = 0;
 
361
  int dwBit28 = 1 << 28;
 
362
 
 
363
  /* do the following only for ac97 codecs */
 
364
  /* Wait for Codec Ready (bit 28) */
 
365
  do
 
366
    {
 
367
      dwData = V2ReadReg (devc, codec_control_reg_addr);
 
368
      if (count++ > 1)
 
369
        oss_udelay (10);
 
370
    }
 
371
  while ((count < 100) && !(dwData & dwBit28));
 
372
  if (count >= 100)
 
373
    {
 
374
#if 1
 
375
      cmn_err (CE_WARN, "Error: timeout waiting for Codec Ready bit.\n");
 
376
      cmn_err (CE_WARN, "Codec Interface Control Register is %08x\n", dwData);
 
377
#endif
 
378
    }
 
379
  /* Write interesting data to the Codec 97 Mixer registers */
 
380
  /* Master Volume 0dB Attunuation, Not muted. */
 
381
  V2WriteCodecCommand (devc, 0x02, 0x0a0a);
 
382
  oss_udelay (10);
 
383
  /* Master Volume mono muted. */
 
384
  V2WriteCodecCommand (devc, 0x06, 0x8000);
 
385
  oss_udelay (10);
 
386
  /* Mic Volume muted. */
 
387
  V2WriteCodecCommand (devc, 0x0e, 0x8000);
 
388
  oss_udelay (10);
 
389
  /* Line In Volume muted. */
 
390
  V2WriteCodecCommand (devc, 0x10, 0x8000);
 
391
  oss_udelay (10);
 
392
  /* CD Volume muted. */
 
393
  V2WriteCodecCommand (devc, 0x12, 0x8000);
 
394
  oss_udelay (10);
 
395
  /* Aux Volume muted. */
 
396
  V2WriteCodecCommand (devc, 0x16, 0x8000);
 
397
  oss_udelay (10);
 
398
  /* PCM out Volume 0 dB Gain, Not muted. */
 
399
  V2WriteCodecCommand (devc, 0x18, 0x0f0f);
 
400
  oss_udelay (10);
 
401
  /* Record select, select Mic for recording */
 
402
  V2WriteCodecCommand (devc, 0x1a, 0x0404);
 
403
  oss_udelay (10);
 
404
  /* Record Gain, 0dB */
 
405
  V2WriteCodecCommand (devc, 0x1c, 0x8000);
 
406
  oss_udelay (10);
 
407
 
 
408
  /* Poll the Section Ready bits in the Status Register (index 0x26) */
 
409
  count = 0;
 
410
  do
 
411
    {
 
412
      V2ReadCodecRegister (devc, 0x26, &dwData);
 
413
      if (count++ > 1)
 
414
        oss_udelay (10);
 
415
    }
 
416
  while (!(dwData & 0x02) && (count < 10));
 
417
  if (!(dwData & 0x02))
 
418
    cmn_err (CE_WARN, "DAC section ready bit is not set.\n");
 
419
 
 
420
  /* Read and confirm the data in the Codec 97 Mixer registers. */
 
421
  /* just the PCM reg, as a sanity check */
 
422
  V2ReadCodecRegister (devc, 0x18, &dwData);
 
423
  if ((dwData & 0x0000ffff) != 0xf0f)
 
424
    {
 
425
      cmn_err (CE_WARN, "PCM volume reg is %x, sb 0xf0f.\n", dwData);
 
426
    }
 
427
}
 
428
 
 
429
static void
 
430
V2InitAdb (vortex_devc * devc)
 
431
{
 
432
/*  parameter  values for write_op  */
 
433
#define none      0             /* dst_op = x */
 
434
#define tail      1             /* dst_op = x */
 
435
#define add       2             /* dst_op = dst_addr being added */
 
436
#define adds      3             /* dst_op = dst_addr being added */
 
437
#define del               4     /* dst_op = dst_addr being deleted */
 
438
#define dels      5             /* dst_op = dst_addr being deleted */
 
439
#define inval     6             /* dst_op = x */
 
440
 
 
441
  int i;
 
442
 
 
443
#if 0
 
444
  unsigned char /*reg   [3:0] */ write_op;
 
445
  unsigned char /*reg   [6:0] */ dst_op;
 
446
  unsigned char /*reg   [6:0] */ src_op;
 
447
  unsigned char /*reg   [SS:0] */ sr_op;
 
448
#endif
 
449
  /* misc */
 
450
 
 
451
  devc->sr_active = 0;
 
452
  /* the initial tail for each list is the header location */
 
453
  for (i = 0; i <= 31; i = i + 1)
 
454
    devc->tail_index[i] = adb_destinations + i;
 
455
  for (i = 0; i <= 127; i = i + 1)
 
456
    devc->dst_index[i] = 0x7f;  /*~('b0); */
 
457
  for (i = 0; i <= 127; i = i + 1)
 
458
    devc->sr_list[i] = 0x1f;    /*~('b0); */
 
459
 
 
460
#if 0
 
461
  write_op = none;
 
462
  dst_op = 0x7f;                /* ~('b0); */
 
463
  src_op = 0x7f;                /* ~('b0); */
 
464
  sr_op = 0x1f;                 /* ~('b0); */
 
465
#endif
 
466
  /* Disable any active sample rate */
 
467
  V2WriteReg (devc, adbarb_base + 0x400, 0);
 
468
  /* Null out all the linked lists */
 
469
  for (i = 0; i < 0x1f0; i = i + 4)
 
470
    {
 
471
      V2WriteReg (devc, adbarb_base + i, 0xffffffff);
 
472
    }
 
473
}
 
474
 
 
475
#ifdef USE_SRC
 
476
static void
 
477
V2DisableSrc (vortex_devc * devc)
 
478
{
 
479
  V2WriteReg (devc, (oss_native_word) (src_active_sample_rate), (oss_native_word) (0x0));       /* activate 0 and 1 */
 
480
  return;
 
481
}
 
482
 
 
483
 
 
484
static void
 
485
V2EnableSrc (vortex_devc * devc)
 
486
{
 
487
  int i, j;
 
488
 
 
489
  for (i = 0; i < 16; i++)
 
490
    {
 
491
      V2WriteReg (devc, (unsigned long) (src_next_ch_base + (0x4 * i)), (unsigned long) (0x0)); /* clear next ch list */
 
492
    }
 
493
 
 
494
  for (i = 0; i < 22; i++)
 
495
    {
 
496
      V2WriteReg (devc, (unsigned long) (src_sr_header_base + (0x4 * i)), (unsigned long) (0x0));       /* Clear header list */
 
497
    }
 
498
 
 
499
  for (i = 0; i < 16; i++)
 
500
    {
 
501
      for (j = 0; j < 32; j++)
 
502
        {
 
503
          V2WriteReg (devc, (unsigned long) (src_input_fifo_base + (0x4 * ((0x20 * i) + j))), (unsigned long) (0xdeadbabe));    /* clear input fifo */
 
504
        }
 
505
    }
 
506
 
 
507
  for (i = 0; i < 16; i++)
 
508
    {
 
509
      for (j = 0; j < 2; j++)
 
510
        {
 
511
          V2WriteReg (devc, (unsigned long) (src_output_fifo_base + (0x4 * ((0x2 * i) + j))), (unsigned long) (0x5555aaaa));    /* clear input fifo */
 
512
        }
 
513
    }
 
514
 
 
515
  for (i = 0; i < 16; i++)
 
516
    {
 
517
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * i)), (unsigned long) (0xc0));     /* samples per wing */
 
518
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x10 + i))), (unsigned long) (0x45a9));  /* conversion ratio */
 
519
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x20 + i))), (unsigned long) (0x0));     /* Drift error = 0 */
 
520
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x30 + i))), (unsigned long) (0x0));     /* Drift error = 0  */
 
521
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x40 + i))), (unsigned long) (0x0));     /* fraction = 0 */
 
522
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x50 + i))), (unsigned long) (0x1));     /* drift out count = 1 */
 
523
      V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * (0x60 + i))), (unsigned long) (0x30f00)); /* conversion ratio */
 
524
    }
 
525
 
 
526
 
 
527
  V2WriteReg (devc, (unsigned long) (src_next_ch_base), (unsigned long) (0x1)); /* point to SRC1 as last in list */
 
528
  V2WriteReg (devc, (unsigned long) (src_sr_header_base + (0x04 * 20)), (unsigned long) (0x10));        /* Using spdif sr (20) point to ch 0 */
 
529
  V2WriteReg (devc, (unsigned long) (src_ch_params_base), (unsigned long) (0xc0));      /* samples per wing */
 
530
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04)), (unsigned long) (0xc1));     /* samples per wing */
 
531
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x10)), (unsigned long) (0x45a9));    /* conversion ratio */
 
532
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x11)), (unsigned long) (0x45a9));    /* conversion ratio */
 
533
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x20)), (unsigned long) (0x0));       /* Drift error = 0 */
 
534
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x21)), (unsigned long) (0x0));       /* Drift error = 0 */
 
535
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x30)), (unsigned long) (0x0));       /* Drift error = 0  */
 
536
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x31)), (unsigned long) (0x0));       /*  Drift error = 0 */
 
537
 
 
538
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x40)), (unsigned long) (0x0));       /* fraction = 0  */
 
539
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x41)), (unsigned long) (0x0));       /* fraction = 0 */
 
540
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x50)), (unsigned long) (0x1));       /* drift out count = 1  */
 
541
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x51)), (unsigned long) (0x1));       /* drift out count = 1 */
 
542
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x60)), (unsigned long) (0x30f00));   /* pointers, throttle in */
 
543
  V2WriteReg (devc, (unsigned long) (src_ch_params_base + (0x04 * 0x61)), (unsigned long) (0x30f00));   /* pointers, throttle in */
 
544
  V2WriteReg (devc, (unsigned long) (src_throttle_source), (unsigned long) (0x3));      /* choose counter for ch 0 & 1 */
 
545
  V2WriteReg (devc, (unsigned long) (src_throttle_count_size), (unsigned long) (0x1ff));        /* counter size = 511 */
 
546
  V2WriteReg (devc, (unsigned long) (src_active_sample_rate), (unsigned long) (0x100000));      /* activate sr 20 for codec */
 
547
 
 
548
}
 
549
#endif
 
550
 
 
551
static void
 
552
SetBit (unsigned int owData[], int nBit, unsigned char cVal)
 
553
{
 
554
  if (cVal)
 
555
    owData[nBit / 32] |= (1 << (nBit % 32));
 
556
  else
 
557
    owData[nBit / 32] &= ~(1 << (nBit % 32));
 
558
}
 
559
 
 
560
/*ARGSUSED*/
 
561
static int
 
562
add_route (vortex_devc * devc, unsigned int sr,
 
563
           unsigned int src_addr, unsigned int dst_addr, int verify)
 
564
{
 
565
 
 
566
  unsigned int ram_hdr_addr;
 
567
  unsigned int ram_dst_addr;
 
568
  unsigned int ram_tail_addr;
 
569
  unsigned int sr_ram_index;
 
570
 
 
571
  sr_ram_index = adb_destinations + sr;
 
572
  ram_hdr_addr = adbarb_wtdram_srhdr_base_addr + (sr * 4);      /* VHRDxx[sr] */
 
573
  ram_dst_addr = adbarb_wtdram_base_addr + (dst_addr * 4);      /* VDSTxx[dst_addr] */
 
574
  ram_tail_addr = adbarb_wtdram_base_addr + (devc->tail_index[sr] * 4);
 
575
 
 
576
  /* since always add to end of list, ram[dst_addr] will be the new tail. */
 
577
  /* and, since we could be adding to an active list, the tail needs */
 
578
  /* to be NULLed before the new link is inserted  */
 
579
  /* (since we need to check the current tail next, devc->tail_index is  */
 
580
  /* updated a bit later below.) */
 
581
  V2WriteReg (devc, ram_dst_addr, 0xffffffff);
 
582
 
 
583
  /* check if this sr has a list started yet */
 
584
  if (devc->tail_index[sr] == (adb_destinations + sr))
 
585
    {
 
586
      /* current tail for this sample rate indicates that list is empty, */
 
587
      /* thus this route will be head of list */
 
588
      V2WriteReg (devc, ram_hdr_addr, ((src_addr << 8) | dst_addr));
 
589
      devc->dst_index[dst_addr] = sr_ram_index;
 
590
    }
 
591
  else
 
592
    {
 
593
      /* add to end of list */
 
594
      V2WriteReg (devc, ram_tail_addr, ((src_addr << 8) | dst_addr));
 
595
      devc->dst_index[dst_addr] = devc->tail_index[sr];
 
596
    }
 
597
 
 
598
  /* keep track of the new tail */
 
599
  devc->tail_index[sr] = dst_addr;
 
600
 
 
601
  /* keep track of which sample rate list this dst_addr now belongs to */
 
602
  devc->sr_list[dst_addr] = sr;
 
603
 
 
604
  /* mark dst_addr as routed */
 
605
  /* devc->dst_routed[dst_addr] = 1; */
 
606
  SetBit ((unsigned int *) &devc->dst_routed, dst_addr, 1);
 
607
 
 
608
  return 0;
 
609
}
 
610
 
 
611
/*ARGSUSED*/
 
612
static void
 
613
del_route (vortex_devc * devc, unsigned char dst_addr, int verify)
 
614
{
 
615
 
 
616
  unsigned int data, ram_dst_addr, ram_rtd_addr;
 
617
  unsigned char sr;
 
618
 
 
619
 
 
620
  ram_dst_addr = adbarb_wtdram_base_addr + (dst_addr * 4);
 
621
  ram_rtd_addr = adbarb_wtdram_base_addr + (devc->dst_index[dst_addr] * 4);
 
622
 
 
623
  /* get the sr list that this dst_addr belongs to */
 
624
  sr = devc->sr_list[dst_addr];
 
625
 
 
626
  /* mark dst as no longer routed  */
 
627
  SetBit ((unsigned int *) &devc->dst_routed, dst_addr, 0);
 
628
 
 
629
  /* remove the dst from the sr_list then check to see if this was the */
 
630
  /* last route in the list.  if so, disable wtd for this sample rate */
 
631
  devc->sr_list[dst_addr] = 0x1f;       /*~('b0); */
 
632
 
 
633
  /* find out what's linked to us so we can reroute it.  if we are the  */
 
634
  /* tail, this will be NULL and will get relinked as such */
 
635
  data = V2ReadReg (devc, ram_dst_addr);
 
636
 
 
637
  /* now update the list by writing what was linked to us to where we  */
 
638
  /* were once at in the list  */
 
639
  V2WriteReg (devc, ram_rtd_addr, data);
 
640
 
 
641
  /* update the devc->dst_index for this reroute */
 
642
  /* devc->dst_index[data[6:0]] = devc->dst_index[dst_addr]; */
 
643
  devc->dst_index[data & 0x7f] = devc->dst_index[dst_addr];
 
644
 
 
645
  /* Invalidate the now deleted route.  Data for dst_addr = 7e; */
 
646
  /* NOTE: the adbarb_monitor needs this write to track properly! */
 
647
  V2WriteReg (devc, ram_dst_addr, 0xfffffffe);
 
648
 
 
649
  /* if we are removing the tail, reset the tail pointer */
 
650
  if (devc->tail_index[sr] == dst_addr)
 
651
    {
 
652
      devc->tail_index[sr] = devc->dst_index[dst_addr];
 
653
    }
 
654
 
 
655
  /* clean up all data elements used to track this dst_addr */
 
656
  /* XXX check field size below */
 
657
  devc->dst_index[dst_addr] = 0x7f;     /* ~('b0); */
 
658
}
 
659
 
 
660
static void
 
661
EnableCodecChannel (vortex_devc * devc, unsigned char channel)
 
662
{
 
663
  unsigned int data;
 
664
 
 
665
  data = V2ReadReg (devc, channel_enable_reg_addr);
 
666
  data = data | (1 << (8 + channel));   /*(1'b1 << (8+channel)); */
 
667
  V2WriteReg (devc, channel_enable_reg_addr, data);
 
668
}
 
669
 
 
670
static void
 
671
DisableCodecChannel (vortex_devc * devc, unsigned char channel)
 
672
{
 
673
  unsigned int data;
 
674
 
 
675
  data = V2ReadReg (devc, channel_enable_reg_addr);
 
676
  data = data & ~(1 << (8 + channel));  /*~(1'b1 << (8+channel)); */
 
677
  V2WriteReg (devc, channel_enable_reg_addr, data);
 
678
}
 
679
 
 
680
static void
 
681
EnableAdbWtd (vortex_devc * devc, int sr)
 
682
{
 
683
  unsigned int dwData;
 
684
 
 
685
  dwData = V2ReadReg (devc, adbarb_sr_active_addr);
 
686
  dwData |= (1 << sr);
 
687
  V2WriteReg (devc, adbarb_sr_active_addr, dwData);
 
688
  devc->sr_active |= (1 << sr);
 
689
}
 
690
 
 
691
static void
 
692
DisableAdbWtd (vortex_devc * devc, int sr)
 
693
{
 
694
  unsigned int dwData;
 
695
 
 
696
  dwData = V2ReadReg (devc, adbarb_sr_active_addr);
 
697
  dwData &= ~(1 << sr);
 
698
  V2WriteReg (devc, adbarb_sr_active_addr, dwData);
 
699
  devc->sr_active &= ~(1 << sr);
 
700
}
 
701
 
 
702
static void
 
703
V2SetupRoutes (vortex_devc * devc)
 
704
{
 
705
 
 
706
  /* Add the record routes */
 
707
  add_route (devc, 17, codec_chan0_src_addr, fifo_chan2_dst_addr, 0);
 
708
  add_route (devc, 17, codec_chan1_src_addr, fifo_chan3_dst_addr, 0);
 
709
  add_route (devc, 17, codec_chan0_src_addr, fifo_chan2a_dst_addr, 0);
 
710
  add_route (devc, 17, codec_chan1_src_addr, fifo_chan3a_dst_addr, 0);
 
711
 
 
712
  /* Add the playback routes */
 
713
  add_route (devc, 17, fifo_chan0_src_addr, codec_chan0_dst_addr, 0);
 
714
  add_route (devc, 17, fifo_chan0_src_addr, codec_chan1_dst_addr, 0);
 
715
}
 
716
 
 
717
static void
 
718
init_fifos (vortex_devc * devc)
 
719
/* */
 
720
/* Frequency to use.  1..256 which translates to nFreq/48000 */
 
721
/* if 0 then use 12 for left and 24 for right. */
 
722
/*  */
 
723
/* inputs: */
 
724
/*    nFreq -- frequency to use. */
 
725
/* outputs: */
 
726
/*    none. */
 
727
{
 
728
  int i;
 
729
 
 
730
  /* Zero Out all the FIFO Pointers, WT(64) & VDB(32) */
 
731
  for (i = 0; i < 96; i++)
 
732
    {
 
733
      V2WriteReg (devc, devc->fifo_base + 0x6000 + (4 * i), 0x00000020);
 
734
    }
 
735
  /* Program Channels 2,3,4,5 as record channels */
 
736
  for (i = 2; i < 6; i++)
 
737
    {
 
738
      V2WriteReg (devc, devc->fifo_base + 0x6100 + (4 * i), 0x00000000);
 
739
    }
 
740
  /* Set Trigger Levels */
 
741
  V2WriteReg (devc, devc->fifo_base + 0x7008, 0x00000843);
 
742
 
 
743
 
 
744
  /* Clear out FIFO data for channels 0-9 */
 
745
  for (i = 0; i < 10; i++)
 
746
    ClearDataFifo (devc, i);
 
747
 
 
748
  /* Set up the DMA engine to grab DMA memory */
 
749
  V2WriteReg (devc, devc->dma_base + 0xa80, 0); /* Clear Dma Status0 */
 
750
  V2WriteReg (devc, devc->dma_base + 0xa84, 0); /* Clear Dma Status1 */
 
751
  V2WriteReg (devc, devc->dma_base + 0xa88, 0); /* Clear Dma Status2 */
 
752
  V2WriteReg (devc, devc->dma_base + 0xa8c, 0); /* Clear Dma Status3 */
 
753
  V2WriteReg (devc, devc->dma_base + 0xa90, 0); /* Clear Dma Status4 */
 
754
  V2WriteReg (devc, devc->dma_base + 0xa94, 0); /* Clear Dma Status5 */
 
755
}
 
756
 
 
757
#ifdef USE_SRC
 
758
static void
 
759
v2setup_src (int dev)
 
760
{
 
761
  vortex_portc *portc = audio_engines[dev]->portc;
 
762
  vortex_devc *devc = audio_engines[dev]->devc;
 
763
 
 
764
  int i, j, chn;
 
765
 
 
766
  for (j = 0; j < 2; j++)
 
767
    {
 
768
      unsigned int tmp, ratio, link;
 
769
      chn = portc->voice_chn + j;
 
770
 
 
771
      for (i = 0; i < 128; i += 4)
 
772
        V2WriteReg (devc, src_input_fifo_base + (128 * chn) + i, 0);
 
773
      for (i = 0; i < 8; i += 4)
 
774
        V2WriteReg (devc, src_output_fifo_base + (chn * 8) + i, 0);
 
775
 
 
776
      ratio = 48000 / portc->speed;
 
777
      tmp = 0;
 
778
      tmp |= chn & 0xf;         /* Correlated channel */
 
779
      if (ratio > 4)
 
780
        tmp |= ((17 - ratio - 1) << 4);
 
781
      else
 
782
        tmp |= (12 << 4);       /* Zero crossing */
 
783
      V2WriteReg (devc, src_ch_params_base + 0xe00 + 4 * chn, tmp);     /* [0] */
 
784
 
 
785
      ratio = (48000 << 14) / portc->speed;
 
786
      V2WriteReg (devc, src_ch_params_base + 0xe40 * 4 * chn, ratio);   /* [1] */
 
787
 
 
788
      V2WriteReg (devc, src_ch_params_base + 0xe80 + 4 * chn, 0);       /* [2] */
 
789
      V2WriteReg (devc, src_ch_params_base + 0xec0 + 4 * chn, 0);       /* [3] */
 
790
      V2WriteReg (devc, src_ch_params_base + 0xf00 + 4 * chn, 0);       /* [4] */
 
791
      V2WriteReg (devc, src_ch_params_base + 0xf40 + 4 * chn, 1);       /* [5] */
 
792
 
 
793
      ratio = 48000 / portc->speed;
 
794
      tmp = 0x3000f;            /* Throttle in, FIFO depth=15 */
 
795
      V2WriteReg (devc, src_ch_params_base + 0xf80 + 4 * chn, tmp);     /* [6] */
 
796
 
 
797
      link = V2ReadReg (devc, src_sr_header_base + 0);
 
798
      V2WriteReg (devc, src_next_ch_base + chn * 4, link);
 
799
      V2WriteReg (devc, src_sr_header_base + 0, 0x10 | chn);
 
800
 
 
801
      link = V2ReadReg (devc, src_throttle_source);
 
802
      link |= (1 << chn);
 
803
      V2WriteReg (devc, src_throttle_source, link);
 
804
 
 
805
      link = V2ReadReg (devc, src_active_sample_rate);
 
806
      link |= (1 << 0);
 
807
      V2WriteReg (devc, src_active_sample_rate, link);
 
808
 
 
809
    }
 
810
}
 
811
 
 
812
static void
 
813
v2cleanup_src (int dev)
 
814
{
 
815
  vortex_portc *portc = audio_engines[dev]->portc;
 
816
  vortex_devc *devc = audio_engines[dev]->devc;
 
817
 
 
818
  int i, j, chn;
 
819
 
 
820
  for (j = 0; j < 2; j++)
 
821
    {
 
822
      unsigned int link;
 
823
 
 
824
      chn = portc->voice_chn + j;
 
825
 
 
826
      for (i = 0; i < 128; i += 4)
 
827
        V2WriteReg (devc, src_input_fifo_base + (128 * chn) + i, 0);
 
828
      for (i = 0; i < 8; i += 4)
 
829
        V2WriteReg (devc, src_output_fifo_base + (chn * 8) + i, 0);
 
830
      V2WriteReg (devc, src_next_ch_base + chn * 4, 0);
 
831
      V2WriteReg (devc, src_sr_header_base + 0, 0);
 
832
 
 
833
      link = V2ReadReg (devc, src_active_sample_rate);
 
834
      link &= ~(1 << chn);
 
835
      V2WriteReg (devc, src_active_sample_rate, link);
 
836
 
 
837
    }
 
838
}
 
839
#endif
 
840
 
 
841
/********************************************************
 
842
 *      Vortex2 MIDI Routines                           *
 
843
 ********************************************************/
 
844
/*ARGSUSED*/
 
845
static int
 
846
vortex2_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
 
847
                   oss_midi_inputbuf_t inputbuf,
 
848
                   oss_midi_outputintr_t outputintr)
 
849
{
 
850
  vortex_devc *devc = (vortex_devc *) midi_devs[dev]->devc;
 
851
 
 
852
  if (devc->midi_opened)
 
853
    {
 
854
      return OSS_EBUSY;
 
855
    }
 
856
 
 
857
  devc->midi_input_intr = inputbyte;
 
858
  devc->midi_opened = mode;
 
859
 
 
860
  if (mode & OPEN_READ)
 
861
    {
 
862
      int tmp = V2ReadReg (devc, ICR);
 
863
      V2WriteReg (devc, ICR, tmp | MIDIRQST);   /* Enable MIDI interrupts */
 
864
      tmp = V2ReadReg (devc, ICR);
 
865
    }
 
866
 
 
867
  V2WriteReg (devc, MIDICMD, 0x000000ff);       /* Reset MIDI */
 
868
  V2WriteReg (devc, MIDICMD, 0x0000003f);       /* Enter UART mode */
 
869
  if ((V2ReadReg (devc, MIDIDAT) & 0xff) != 0xfe)
 
870
    cmn_err (CE_NOTE, "MIDI init not acknowledged\n");
 
871
  return 0;
 
872
}
 
873
 
 
874
/*ARGSUSED*/
 
875
static void
 
876
vortex2_midi_close (int dev, int mode)
 
877
{
 
878
  vortex_devc *devc = (vortex_devc *) midi_devs[dev]->devc;
 
879
 
 
880
  int tmp = V2ReadReg (devc, ICR);
 
881
  V2WriteReg (devc, ICR, tmp & ~MIDIRQST);      /* Disable MIDI interrupts */
 
882
  V2WriteReg (devc, MIDICMD, 0x000000ff);       /* Reset MIDI */
 
883
 
 
884
  devc->midi_opened = 0;
 
885
}
 
886
 
 
887
static int
 
888
vortex2_midi_out (int dev, unsigned char midi_byte)
 
889
{
 
890
  int n = 10;
 
891
  vortex_devc *devc = (vortex_devc *) midi_devs[dev]->devc;
 
892
 
 
893
  while ((V2ReadReg (devc, MIDISTAT) & CMDOK) && n--);
 
894
  if (V2ReadReg (devc, MIDISTAT) & CMDOK)
 
895
    return 0;
 
896
  V2WriteReg (devc, MIDIDAT, midi_byte);
 
897
  return 1;
 
898
}
 
899
 
 
900
/*ARGSUSED*/
 
901
static int
 
902
vortex2_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
 
903
{
 
904
  return OSS_EINVAL;
 
905
}
 
906
 
 
907
static midi_driver_t vortex2_midi_driver = {
 
908
  vortex2_midi_open,
 
909
  vortex2_midi_close,
 
910
  vortex2_midi_ioctl,
 
911
  vortex2_midi_out
 
912
};
 
913
 
 
914
static void
 
915
vortex2_midi_init (vortex_devc * devc)
 
916
{
 
917
  /* Derive the MIDI baud rate from 49.152 MHz clock */
 
918
  V2WriteReg (devc, GAMECTL, 0x00006100);
 
919
  V2WriteReg (devc, MIDICMD, 0x000000ff);       /* Reset MIDI */
 
920
  V2WriteReg (devc, MIDICMD, 0x0000003f);       /* Enter UART mode */
 
921
 
 
922
  /* All commands should return 0xfe as an acknowledgement */
 
923
  if ((V2ReadReg (devc, MIDIDAT) & 0xff) != 0xfe)
 
924
    cmn_err (CE_NOTE, "MIDI init not acknowledged\n");
 
925
  V2WriteReg (devc, MIDICMD, 0x000000ff);       /* Reset MIDI */
 
926
}
 
927
 
 
928
/****************************************************
 
929
 *                              OSS Audio routines                                      *
 
930
 ****************************************************/
 
931
 
 
932
static int
 
933
ac97_read (void *devc_, int addr)
 
934
{
 
935
  vortex_devc *devc = devc_;
 
936
  int data;
 
937
  oss_native_word flags;
 
938
 
 
939
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
940
  V2ReadCodecRegister (devc, addr, &data);
 
941
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
942
  return data & 0xffff;
 
943
}
 
944
 
 
945
static int
 
946
ac97_write (void *devc_, int addr, int data)
 
947
{
 
948
  vortex_devc *devc = devc_;
 
949
  oss_native_word flags;
 
950
 
 
951
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
952
  V2WriteCodecCommand (devc, addr, data);
 
953
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
954
  return 0;
 
955
}
 
956
 
 
957
int
 
958
vortex2intr (oss_device_t * osdev)
 
959
{
 
960
  vortex_devc *devc = (vortex_devc *) osdev->devc;
 
961
  int status;
 
962
  int i;
 
963
  int serviced = 0;
 
964
 
 
965
  /*
 
966
   * TODO: Fix mutexes and move the inputintr/outputintr calls outside the
 
967
   * mutex block.
 
968
   */
 
969
  /* MUTEX_ENTER (devc->mutex, flags); */
 
970
  status = V2ReadReg (devc, ISR);
 
971
 
 
972
  if (status & MFATERRST)
 
973
    cmn_err (CE_WARN, "Aureal Master fatal error interrupt\n");
 
974
 
 
975
  if (status & MPARERRST)
 
976
    cmn_err (CE_WARN, "Aureal Master parity error interrupt\n");
 
977
 
 
978
  if (status & TIMIRQST)        /* Timer interrupt */
 
979
    {
 
980
      V2ReadReg (devc, CODSMPLTMR);     /* Clear the interrupt */
 
981
      V2WriteReg (devc, CODSMPLTMR, 0x1000);
 
982
      serviced = 1;
 
983
    }
 
984
 
 
985
  if (status & (DMAENDIRQST | DMABERRST))       /* DMA end interrupt */
 
986
    {
 
987
      for (i = 0; i < MAX_PORTC; i++)
 
988
        {
 
989
          vortex_portc *portc = &devc->portc[i];
 
990
 
 
991
          if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
 
992
            {
 
993
              dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
 
994
 
 
995
              int pos = 0, n;
 
996
              unsigned int dmastat;
 
997
 
 
998
              dmastat = V2ReadReg (devc, devc->dma_base + 0xd00 + (64 * 4));
 
999
              pos = ((dmastat >> 12) & 0x03) * 4096 + (dmastat & 4095);
 
1000
              pos /= dmap->fragment_size;
 
1001
              if (pos < 0 || pos >= dmap->nfrags)
 
1002
                pos = 0;
 
1003
 
 
1004
              n = 0;
 
1005
              while (dmap_get_qhead (dmap) != pos && n++ < dmap->nfrags)
 
1006
                oss_audio_outputintr (portc->audiodev, 0);
 
1007
            }
 
1008
 
 
1009
          if (portc->trigger_bits & PCM_ENABLE_INPUT)
 
1010
            {
 
1011
              dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
 
1012
 
 
1013
              int pos = 0, n;
 
1014
              unsigned int dmastat;
 
1015
 
 
1016
              dmastat = V2ReadReg (devc, devc->dma_base + 0xd08 + (64 * 4));
 
1017
 
 
1018
              pos = ((dmastat >> 12) & 0x03) * 4096 + (dmastat & 4095);
 
1019
              pos /= dmap->fragment_size;
 
1020
              if (pos < 0 || pos >= dmap->nfrags)
 
1021
                pos = 0;
 
1022
 
 
1023
              n = 0;
 
1024
              while (dmap_get_qtail (dmap) != pos && n++ < dmap->nfrags)
 
1025
                oss_audio_inputintr (portc->audiodev, 0);
 
1026
            }
 
1027
          V2ReadReg (devc, devc->dma_base + 0xa80);     /* Read Dma Status0 */
 
1028
          V2ReadReg (devc, devc->dma_base + 0xa84);     /* Read Dma Status1 */
 
1029
          V2ReadReg (devc, devc->dma_base + 0xa88);     /* Read Dma Status2 */
 
1030
          V2ReadReg (devc, devc->dma_base + 0xa8c);     /* Read Dma Status3 */
 
1031
          V2ReadReg (devc, devc->dma_base + 0xa90);     /* Read Dma Status4 */
 
1032
          V2ReadReg (devc, devc->dma_base + 0xa94);     /* Read Dma Status5 */
 
1033
          serviced = 1;
 
1034
        }
 
1035
    }
 
1036
 
 
1037
  if (status & MIDIRQST)        /* MIDI interrupt */
 
1038
    {
 
1039
      int uart_stat = V2ReadReg (devc, MIDISTAT);
 
1040
      int n = 10;
 
1041
 
 
1042
      while (!(uart_stat & MIDIVAL) && n--)
 
1043
        {
 
1044
          int d;
 
1045
          d = V2ReadReg (devc, MIDIDAT) & 0xff;
 
1046
 
 
1047
          if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
 
1048
            devc->midi_input_intr (devc->midi_dev, d);
 
1049
          uart_stat = V2ReadReg (devc, MIDISTAT);
 
1050
        }
 
1051
      serviced = 1;
 
1052
    }
 
1053
 
 
1054
  if (status != 0)
 
1055
    {
 
1056
      V2WriteReg (devc, ISR, status & 0x7ff);   /* Ack pulse interrupts */
 
1057
      status = V2ReadReg (devc, ISR);
 
1058
      serviced = 1;
 
1059
    }
 
1060
  /* MUTEX_EXIT (devc->mutex, flags); */
 
1061
  return serviced;
 
1062
}
 
1063
 
 
1064
 
 
1065
static int
 
1066
vortex2_set_rate (int dev, int arg)
 
1067
{
 
1068
  vortex_portc *portc = audio_engines[dev]->portc;
 
1069
 
 
1070
  if (arg == 0)
 
1071
    return portc->speed;
 
1072
 
 
1073
  if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
 
1074
    arg = 48000;
 
1075
 
 
1076
  if (arg > 48000)
 
1077
    arg = 48000;
 
1078
  if (arg < 5000)
 
1079
    arg = 5000;
 
1080
  portc->speed = arg;
 
1081
  return portc->speed;
 
1082
}
 
1083
 
 
1084
static short
 
1085
vortex2_set_channels (int dev, short arg)
 
1086
{
 
1087
  vortex_portc *portc = audio_engines[dev]->portc;
 
1088
 
 
1089
  if (audio_engines[dev]->flags & ADEV_STEREOONLY)
 
1090
    arg = 2;
 
1091
 
 
1092
  if ((arg != 1) && (arg != 2))
 
1093
    return portc->channels;
 
1094
  portc->channels = arg;
 
1095
 
 
1096
  return portc->channels;
 
1097
}
 
1098
 
 
1099
static unsigned int
 
1100
vortex2_set_format (int dev, unsigned int arg)
 
1101
{
 
1102
  vortex_portc *portc = audio_engines[dev]->portc;
 
1103
 
 
1104
  if (audio_engines[dev]->flags & ADEV_16BITONLY)
 
1105
    arg = 16;
 
1106
 
 
1107
  if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
 
1108
    return portc->bits;
 
1109
  portc->bits = arg;
 
1110
 
 
1111
  return portc->bits;
 
1112
}
 
1113
 
 
1114
/*ARGSUSED*/
 
1115
static int
 
1116
vortex2_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
 
1117
{
 
1118
  return OSS_EINVAL;
 
1119
}
 
1120
 
 
1121
static void vortex2_trigger (int dev, int state);
 
1122
 
 
1123
static void
 
1124
vortex2_reset (int dev)
 
1125
{
 
1126
  vortex2_trigger (dev, 0);
 
1127
 
 
1128
#ifdef USE_SRC
 
1129
  v2cleanup_src (dev);
 
1130
  del_route (devc, src_chan0_src_addr, 0);
 
1131
  del_route (devc, src_chan1_src_addr, 0);
 
1132
  del_route (devc, src_chan0_dst_addr, 0);
 
1133
  del_route (devc, src_chan1_dst_addr, 0);
 
1134
#endif
 
1135
 
 
1136
#ifdef USE_SPDIF
 
1137
  del_route (devc, spdif_chan0_dst_addr, 0);
 
1138
  del_route (devc, spdif_chan1_dst_addr, 0);
 
1139
#endif
 
1140
}
 
1141
 
 
1142
static void
 
1143
vortex2_reset_input (int dev)
 
1144
{
 
1145
  vortex_portc *portc = audio_engines[dev]->portc;
 
1146
  vortex2_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
 
1147
}
 
1148
 
 
1149
static void
 
1150
vortex2_reset_output (int dev)
 
1151
{
 
1152
  vortex_portc *portc = audio_engines[dev]->portc;
 
1153
  vortex2_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
 
1154
}
 
1155
 
 
1156
/*ARGSUSED*/
 
1157
static int
 
1158
vortex2_open (int dev, int mode, int open_flags)
 
1159
{
 
1160
  oss_native_word flags;
 
1161
  vortex_portc *portc = audio_engines[dev]->portc;
 
1162
  vortex_devc *devc = audio_engines[dev]->devc;
 
1163
 
 
1164
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
1165
  if (portc->open_mode)
 
1166
    {
 
1167
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1168
      return OSS_EBUSY;
 
1169
    }
 
1170
 
 
1171
  if (devc->open_mode & mode)
 
1172
    {
 
1173
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1174
      return OSS_EBUSY;
 
1175
    }
 
1176
 
 
1177
  devc->open_mode |= mode;
 
1178
 
 
1179
  portc->open_mode = mode;
 
1180
  portc->audio_enabled &= ~mode;
 
1181
 
 
1182
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1183
  return 0;
 
1184
}
 
1185
 
 
1186
static void
 
1187
vortex2_close (int dev, int mode)
 
1188
{
 
1189
  vortex_portc *portc = audio_engines[dev]->portc;
 
1190
  vortex_devc *devc = audio_engines[dev]->devc;
 
1191
 
 
1192
  vortex2_reset (dev);
 
1193
  portc->open_mode = 0;
 
1194
  devc->open_mode &= ~mode;
 
1195
  portc->audio_enabled = ~mode;
 
1196
}
 
1197
 
 
1198
/*ARGSUSED*/
 
1199
static void
 
1200
vortex2_output_block (int dev, oss_native_word buf, int count, int fragsize,
 
1201
                      int intrflag)
 
1202
{
 
1203
  vortex_portc *portc = audio_engines[dev]->portc;
 
1204
 
 
1205
  portc->audio_enabled |= PCM_ENABLE_OUTPUT;
 
1206
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
1207
}
 
1208
 
 
1209
/*ARGSUSED*/
 
1210
static void
 
1211
vortex2_start_input (int dev, oss_native_word buf, int count, int fragsize,
 
1212
                     int intrflag)
 
1213
{
 
1214
  vortex_portc *portc = audio_engines[dev]->portc;
 
1215
 
 
1216
  portc->audio_enabled |= PCM_ENABLE_INPUT;
 
1217
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
1218
}
 
1219
 
 
1220
static void
 
1221
vortex2_trigger (int dev, int state)
 
1222
{
 
1223
  vortex_devc *devc = audio_engines[dev]->devc;
 
1224
  vortex_portc *portc = audio_engines[dev]->portc;
 
1225
  unsigned int fifo_mode;
 
1226
  oss_native_word flags;
 
1227
 
 
1228
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
1229
 
 
1230
  if (portc->open_mode & OPEN_WRITE)
 
1231
    {
 
1232
      if (state & PCM_ENABLE_OUTPUT)
 
1233
        {
 
1234
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
1235
              !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
1236
            {
 
1237
              /* Start the fifos */
 
1238
              fifo_mode = 0xc0030;
 
1239
              if (portc->channels == 2)
 
1240
                {
 
1241
                  fifo_mode |= 0x2;
 
1242
                  V2WriteReg (devc, devc->fifo_base + 0x6100, fifo_mode);
 
1243
                }
 
1244
              else
 
1245
                {
 
1246
                  V2WriteReg (devc, devc->fifo_base + 0x6100, fifo_mode);
 
1247
                  V2WriteReg (devc, devc->fifo_base + 0x6104, fifo_mode);
 
1248
                }
 
1249
              V2WriteReg (devc, CODSMPLTMR, 0x1000);    /* start timer */
 
1250
              portc->trigger_bits |= PCM_ENABLE_OUTPUT;
 
1251
            }
 
1252
        }
 
1253
      else
 
1254
        {
 
1255
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
1256
              (portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
1257
            {
 
1258
              portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
1259
              portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
1260
 
 
1261
              V2WriteReg (devc, CODSMPLTMR, 0x0);       /* stop timer */
 
1262
 
 
1263
              V2WriteReg (devc, devc->fifo_base + 0x6100, 0);   /* Left Play */
 
1264
              V2WriteReg (devc, devc->fifo_base + 0x6104, 0);   /* Right Play */
 
1265
 
 
1266
              ClearDataFifo (devc, 0);
 
1267
              ClearDataFifo (devc, 1);
 
1268
            }
 
1269
        }
 
1270
    }
 
1271
 
 
1272
  if (portc->open_mode & OPEN_READ)
 
1273
    {
 
1274
      if (state & PCM_ENABLE_INPUT)
 
1275
        {
 
1276
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
1277
              !(portc->trigger_bits & PCM_ENABLE_INPUT))
 
1278
            {
 
1279
              /* Start the fifos */
 
1280
              fifo_mode = 0xc0010;
 
1281
              if (portc->channels == 2)
 
1282
                fifo_mode |= 2;
 
1283
              V2WriteReg (devc, devc->fifo_base + 0x6108, fifo_mode);   /* LRecord  */
 
1284
              V2WriteReg (devc, devc->fifo_base + 0x610c, fifo_mode);   /* RRecord */
 
1285
              V2WriteReg (devc, CODSMPLTMR, 0x1000);    /* start timer */
 
1286
              portc->trigger_bits |= PCM_ENABLE_INPUT;
 
1287
            }
 
1288
        }
 
1289
      else
 
1290
        {
 
1291
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
1292
              (portc->trigger_bits & PCM_ENABLE_INPUT))
 
1293
            {
 
1294
              portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
1295
              portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
1296
 
 
1297
              V2WriteReg (devc, CODSMPLTMR, 0x0);       /* stop timer */
 
1298
 
 
1299
              V2WriteReg (devc, devc->fifo_base + 0x6108, 0);   /* LRecord */
 
1300
              V2WriteReg (devc, devc->fifo_base + 0x610c, 0);   /* RRecord */
 
1301
 
 
1302
              ClearDataFifo (devc, 2);
 
1303
              ClearDataFifo (devc, 3);
 
1304
            }
 
1305
        }
 
1306
    }
 
1307
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1308
}
 
1309
 
 
1310
/*ARGSUSED*/
 
1311
static int
 
1312
vortex2_prepare_for_input (int dev, int bsize, int bcount)
 
1313
{
 
1314
  unsigned int nBufSize, ChSizeGotoReg0, ChSizeGotoReg1;
 
1315
  unsigned int ch_mode, dma_base, dma_base4, dma_base8;
 
1316
 
 
1317
  dmap_t *dmap = audio_engines[dev]->dmap_in;
 
1318
  vortex_devc *devc = audio_engines[dev]->devc;
 
1319
  vortex_portc *portc = audio_engines[dev]->portc;
 
1320
  unsigned int SAMPLES = 1024;
 
1321
  oss_native_word flags;
 
1322
 
 
1323
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
1324
#ifdef USE_SRC
 
1325
  v2setup_src (dev);
 
1326
#endif
 
1327
 
 
1328
#ifdef USE_SRC
 
1329
  /* Add the routes */
 
1330
  add_route (devc, 17, codec_chan0_src_addr, src_chan0_dst_addr, 0);
 
1331
  add_route (devc, 17, codec_chan1_src_addr, src_chan1_dst_addr, 0);
 
1332
  add_route (devc, 1, src_chan0_src_addr, fifo_chan2_dst_addr, 0);
 
1333
  add_route (devc, 1, src_chan1_src_addr, fifo_chan3_dst_addr, 0);
 
1334
#endif
 
1335
 
 
1336
  nBufSize = (SAMPLES * 2 * 2) - 1;
 
1337
 
 
1338
  ch_mode = 0x00001000;
 
1339
  switch (portc->bits)
 
1340
    {
 
1341
    case AFMT_U8:
 
1342
      ch_mode |= 0x00004000;
 
1343
      break;
 
1344
    case AFMT_S16_LE:
 
1345
      ch_mode |= 0x00020000;
 
1346
      break;
 
1347
    }
 
1348
 
 
1349
  dma_base = devc->dma_base + 16 * portc->voice_chn;
 
1350
  dma_base8 = devc->dma_base + 8 * portc->voice_chn;
 
1351
  dma_base4 = devc->dma_base + 4 * portc->voice_chn;
 
1352
 
 
1353
  /* Left Record Channel VDB ch2 */
 
1354
  V2WriteReg (devc, dma_base + 0x420, dmap->dmabuf_phys);
 
1355
  V2WriteReg (devc, dma_base + 0x424, dmap->dmabuf_phys + 4096);
 
1356
  V2WriteReg (devc, dma_base + 0x428, dmap->dmabuf_phys + 2 * 4096);
 
1357
  V2WriteReg (devc, dma_base + 0x42c, dmap->dmabuf_phys + 3 * 4096);
 
1358
 
 
1359
  ChSizeGotoReg0 = (0xde000000) | (nBufSize << 12) | (nBufSize);
 
1360
  ChSizeGotoReg1 = (0xfc000000) | (nBufSize << 12) | (nBufSize);
 
1361
 
 
1362
  V2WriteReg (devc, dma_base8 + 0x810, ChSizeGotoReg0);
 
1363
  V2WriteReg (devc, dma_base8 + 0x814, ChSizeGotoReg1);
 
1364
  V2WriteReg (devc, dma_base4 + 0xa08, ch_mode);
 
1365
 
 
1366
  /* Right Record Channel VDB ch3 */
 
1367
  V2WriteReg (devc, dma_base + 0x430, dmap->dmabuf_phys);
 
1368
  V2WriteReg (devc, dma_base + 0x434, dmap->dmabuf_phys + 4096);
 
1369
  V2WriteReg (devc, dma_base + 0x438, dmap->dmabuf_phys + 2 * 4096);
 
1370
  V2WriteReg (devc, dma_base + 0x43c, dmap->dmabuf_phys + 3 * 4096);
 
1371
 
 
1372
  ChSizeGotoReg0 = (0x56000000) | (nBufSize << 12) | (nBufSize);
 
1373
  ChSizeGotoReg0 = (0x74000000) | (nBufSize << 12) | (nBufSize);
 
1374
  V2WriteReg (devc, dma_base8 + 0x818, ChSizeGotoReg0);
 
1375
  V2WriteReg (devc, dma_base8 + 0x81c, ChSizeGotoReg1);
 
1376
  V2WriteReg (devc, dma_base4 + 0xa0c, ch_mode);
 
1377
 
 
1378
  portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
1379
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
1380
 
 
1381
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1382
  return 0;
 
1383
}
 
1384
 
 
1385
/*ARGSUSED*/
 
1386
static int
 
1387
vortex2_prepare_for_output (int dev, int bsize, int bcount)
 
1388
{
 
1389
  unsigned int nBufSize, ChSizeGotoReg0, ChSizeGotoReg1;
 
1390
  unsigned int ch_mode, dma_base, dma_base4, dma_base8;
 
1391
 
 
1392
  dmap_t *dmap = audio_engines[dev]->dmap_out;
 
1393
  vortex_devc *devc = audio_engines[dev]->devc;
 
1394
  vortex_portc *portc = audio_engines[dev]->portc;
 
1395
  unsigned int SAMPLES = 1024;
 
1396
  oss_native_word flags;
 
1397
 
 
1398
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
1399
#ifdef USE_SRC
 
1400
  v2setup_src (dev);
 
1401
  add_route (devc, 17, fifo_chan0_src_addr, src_chan0_dst_addr, 0);
 
1402
  add_route (devc, 17, fifo_chan1_src_addr, src_chan1_dst_addr, 0);
 
1403
  add_route (devc, 1, src_chan0_src_addr, codec_chan0_dst_addr, 0);
 
1404
  add_route (devc, 1, src_chan1_src_addr, codec_chan1_dst_addr, 0);
 
1405
#endif
 
1406
 
 
1407
  nBufSize = (SAMPLES * 2 * 2) - 1;
 
1408
 
 
1409
  ch_mode = 0x00003000;
 
1410
  switch (portc->bits)
 
1411
    {
 
1412
    case AFMT_U8:
 
1413
      ch_mode |= 0x00004000;
 
1414
      break;
 
1415
 
 
1416
    case AFMT_S16_LE:
 
1417
      ch_mode |= 0x00020000;
 
1418
      break;
 
1419
    }
 
1420
 
 
1421
  dma_base = devc->dma_base + 16 * portc->voice_chn;
 
1422
  dma_base8 = devc->dma_base + 8 * portc->voice_chn;
 
1423
  dma_base4 = devc->dma_base + 4 * portc->voice_chn;
 
1424
 
 
1425
  /* Left Playback Channel #0 */
 
1426
  V2WriteReg (devc, dma_base + 0x400, dmap->dmabuf_phys);
 
1427
  V2WriteReg (devc, dma_base + 0x404, dmap->dmabuf_phys + 4096);
 
1428
  V2WriteReg (devc, dma_base + 0x408, dmap->dmabuf_phys + 2 * 4096);
 
1429
  V2WriteReg (devc, dma_base + 0x40c, dmap->dmabuf_phys + 3 * 4096);
 
1430
 
 
1431
  ChSizeGotoReg0 = (0xde000000) | (nBufSize << 12) | (nBufSize);
 
1432
  ChSizeGotoReg1 = (0xfc000000) | (nBufSize << 12) | (nBufSize);
 
1433
  V2WriteReg (devc, dma_base8 + 0x800, ChSizeGotoReg0);
 
1434
  V2WriteReg (devc, dma_base8 + 0x804, ChSizeGotoReg1);
 
1435
  V2WriteReg (devc, dma_base4 + 0xa00, ch_mode);        /* Set Chan0 Mode */
 
1436
 
 
1437
  /* Right Playback Channel #1 */
 
1438
  V2WriteReg (devc, dma_base + 0x410, dmap->dmabuf_phys);
 
1439
  V2WriteReg (devc, dma_base + 0x414, dmap->dmabuf_phys + 4096);
 
1440
  V2WriteReg (devc, dma_base + 0x418, dmap->dmabuf_phys + 2 * 4096);
 
1441
  V2WriteReg (devc, dma_base + 0x41c, dmap->dmabuf_phys + 3 * 4096);
 
1442
  ChSizeGotoReg0 = (0x56000000) | (nBufSize << 12) | (nBufSize);
 
1443
  ChSizeGotoReg1 = (0x74000000) | (nBufSize << 12) | (nBufSize);
 
1444
  V2WriteReg (devc, dma_base8 + 0x808, ChSizeGotoReg0);
 
1445
  V2WriteReg (devc, dma_base8 + 0x80c, ChSizeGotoReg1);
 
1446
  V2WriteReg (devc, dma_base4 + 0xa04, ch_mode);        /* Set Chan1 Mode */
 
1447
 
 
1448
  portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
1449
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
1450
 
 
1451
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
1452
  return 0;
 
1453
}
 
1454
 
 
1455
/*ARGSUSED*/
 
1456
static int
 
1457
vortex2_free_buffer (int dev, dmap_t * dmap, int direction)
 
1458
{
 
1459
  vortex_devc *devc = audio_engines[dev]->devc;
 
1460
 
 
1461
  if (dmap->dmabuf == NULL)
 
1462
    return 0;
 
1463
#if 1
 
1464
  CONTIG_FREE (devc->osdev, dmap->dmabuf, dmap->buffsize, TODO);
 
1465
#ifdef linux
 
1466
  oss_unreserve_pages ((oss_native_word) dmap->dmabuf,
 
1467
                       (oss_native_word) dmap->dmabuf + 4 * 4096 - 1);
 
1468
#endif
 
1469
 
 
1470
#else
 
1471
  dmap->buffsize = devc->origbufsize;
 
1472
  oss_free_dmabuf (dev, dmap);
 
1473
#endif
 
1474
 
 
1475
  dmap->dmabuf = NULL;
 
1476
  return 0;
 
1477
}
 
1478
 
 
1479
/*ARGSUSED*/
 
1480
static int
 
1481
vortex2_alloc_buffer (int dev, dmap_t * dmap, int direction)
 
1482
{
 
1483
  vortex_devc *devc = audio_engines[dev]->devc;
 
1484
  oss_native_word phaddr;
 
1485
  /*int err; */
 
1486
 
 
1487
  if (dmap->dmabuf != NULL)
 
1488
    return 0;
 
1489
#if 1
 
1490
  dmap->buffsize = 4 * 4096;    /* 4 subbuffers */
 
1491
  dmap->dmabuf =
 
1492
    CONTIG_MALLOC (devc->osdev, dmap->buffsize, MEMLIMIT_32BITS, &phaddr, TODO);
 
1493
  dmap->dmabuf_phys = phaddr;
 
1494
#ifdef linux
 
1495
  oss_reserve_pages ((oss_native_word) dmap->dmabuf,
 
1496
                     (oss_native_word) dmap->dmabuf + 4 * 4096 - 1);
 
1497
#endif
 
1498
#else
 
1499
  if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
 
1500
    return err;
 
1501
  devc->origbufsize = dmap->buffsize;
 
1502
  dmap->buffsize = 4 * 4096;
 
1503
#endif
 
1504
 
 
1505
  return 0;
 
1506
}
 
1507
 
 
1508
/*ARGSUSED*/
 
1509
static int
 
1510
vortex2_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
 
1511
{
 
1512
  vortex_devc *devc = audio_engines[dev]->devc;
 
1513
  oss_native_word flags, dmastat = 0;
 
1514
  int ptr = 0;
 
1515
 
 
1516
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
1517
  if (direction == PCM_ENABLE_OUTPUT)
 
1518
    {
 
1519
      dmastat = V2ReadReg (devc, devc->dma_base + 0xd00 + (64 * 4));
 
1520
    }
 
1521
  if (direction == PCM_ENABLE_INPUT)
 
1522
    {
 
1523
      dmastat = V2ReadReg (devc, devc->dma_base + 0xd08 + (64 * 4));
 
1524
    }
 
1525
  ptr = ((dmastat >> 12) & 0x03) * 4096 + (dmastat & 4095);
 
1526
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
1527
  return ptr;
 
1528
}
 
1529
 
 
1530
static audiodrv_t vortex2_driver = {
 
1531
  vortex2_open,
 
1532
  vortex2_close,
 
1533
  vortex2_output_block,
 
1534
  vortex2_start_input,
 
1535
  vortex2_ioctl,
 
1536
  vortex2_prepare_for_input,
 
1537
  vortex2_prepare_for_output,
 
1538
  vortex2_reset,
 
1539
  NULL,
 
1540
  NULL,
 
1541
  vortex2_reset_input,
 
1542
  vortex2_reset_output,
 
1543
  vortex2_trigger,
 
1544
  vortex2_set_rate,
 
1545
  vortex2_set_format,
 
1546
  vortex2_set_channels,
 
1547
  NULL,
 
1548
  NULL,
 
1549
  NULL,                         /* vortex2_check_input, */
 
1550
  NULL,                         /* vortex2_check_output, */
 
1551
  vortex2_alloc_buffer,
 
1552
  vortex2_free_buffer,
 
1553
  NULL,
 
1554
  NULL,
 
1555
  vortex2_get_buffer_pointer
 
1556
};
 
1557
 
 
1558
#ifdef USE_SPDIF
 
1559
static void
 
1560
V2EnableSpdif (vortex_devc * devc)
 
1561
{
 
1562
  unsigned short data;
 
1563
  long n;
 
1564
 
 
1565
  for (n = 0; n <= 11; n++)
 
1566
    {
 
1567
      V2WriteReg (devc, spdif_ch_status_reg_base + (0x0004 * n), 0x0);
 
1568
    }
 
1569
 
 
1570
  V2WriteReg (devc, spdif_ch_status_reg_base, spdif_ch_status_reg0);    /* first 4 bytes of channel status word */
 
1571
 
 
1572
  V2WriteReg (devc, spdif_ctrl_reg, spdif_cfg_dword);   /* set port to enable crc, input clock */
 
1573
 
 
1574
  data = V2ReadReg (devc, channel_enable_reg_addr);
 
1575
  data = data | (1 << (18));    /*              set bits 18 and 19 to enable S/PDIF; */
 
1576
  data = data | (1 << (19));    /*              set bits 18 and 19 to enable S/PDIF; */
 
1577
  V2WriteReg (devc, channel_enable_reg_addr, data);
 
1578
}
 
1579
#endif
 
1580
 
 
1581
static void
 
1582
attach_channel_vortex2 (vortex_devc * devc, int my_mixer)
 
1583
{
 
1584
  int adev;
 
1585
  int i;
 
1586
  int first_dev = 0;
 
1587
 
 
1588
  for (i = 0; i < MAX_PORTC; i++)
 
1589
    {
 
1590
      char tmp_name[100];
 
1591
      vortex_portc *portc = &devc->portc[i];
 
1592
      int caps =
 
1593
        ADEV_FIXEDRATE | ADEV_AUTOMODE | ADEV_STEREOONLY | ADEV_16BITONLY;
 
1594
 
 
1595
      sprintf (tmp_name, "Aureal Vortex 2 (%s)", devc->name);
 
1596
      if (i == 0)
 
1597
        {
 
1598
          strcpy (tmp_name, devc->name);
 
1599
          caps |= ADEV_DUPLEX;
 
1600
        }
 
1601
      else
 
1602
        {
 
1603
          sprintf (tmp_name, "%s (shadow)", devc->name);
 
1604
          caps |= ADEV_DUPLEX | ADEV_SHADOW;
 
1605
        }
 
1606
 
 
1607
      if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
 
1608
                                        devc->osdev,
 
1609
                                        devc->osdev,
 
1610
                                        tmp_name,
 
1611
                                        &vortex2_driver,
 
1612
                                        sizeof (audiodrv_t),
 
1613
                                        caps,
 
1614
                                        AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
 
1615
        {
 
1616
          adev = -1;
 
1617
          return;
 
1618
        }
 
1619
      else
 
1620
        {
 
1621
          if (i == 0)
 
1622
            first_dev = adev;
 
1623
          audio_engines[adev]->portc = portc;
 
1624
          audio_engines[adev]->rate_source = first_dev;
 
1625
          audio_engines[adev]->fixed_rate = 48000;
 
1626
          audio_engines[adev]->min_rate = 48000;
 
1627
          audio_engines[adev]->max_rate = 48000;
 
1628
          audio_engines[adev]->vmix_flags = VMIX_MULTIFRAG;
 
1629
#if 0
 
1630
          audio_engines[adev]->min_block = 4096;
 
1631
          audio_engines[adev]->max_block = 4096;
 
1632
#endif
 
1633
          audio_engines[adev]->mixer_dev = my_mixer;
 
1634
          portc->voice_chn = 0;
 
1635
          portc->open_mode = 0;
 
1636
          portc->audiodev = adev;
 
1637
          portc->audio_enabled = 0;
 
1638
#ifdef CONFIG_OSS_VMIX
 
1639
          if (i == 0)
 
1640
             vmix_attach_audiodev(devc->osdev, adev, -1, 0);
 
1641
#endif
 
1642
        }
 
1643
    }
 
1644
  return;
 
1645
}
 
1646
 
 
1647
int
 
1648
init_vortex2 (vortex_devc * devc, int is_mx300)
 
1649
{
 
1650
  int my_mixer;
 
1651
  int i;
 
1652
 
 
1653
  devc->global_base = (0x2a000);
 
1654
  devc->dma_base = (0x27000);
 
1655
  devc->midi_base = (0x28800);
 
1656
  devc->fifo_base = (0x10000);
 
1657
  devc->adbarb_block_base = (0x28000);
 
1658
  devc->serial_block_base = (0x29000);
 
1659
  devc->parallel_base = (0x22000);
 
1660
  devc->src_base = (0x26000);
 
1661
 
 
1662
/*
 
1663
 * Reset Vortex
 
1664
 */
 
1665
  V2WriteReg (devc, GCR, 0xffffffff);
 
1666
  oss_udelay (1000);
 
1667
 
 
1668
  V2WriteReg (devc, GCR, V2ReadReg (devc, GCR) | GIRQEN);       /* Enable IRQ */
 
1669
  V2WriteReg (devc, CODSMPLTMR, 0x0);
 
1670
  V2WriteReg (devc, ICR, DMAENDIRQST | DMABERRST | TIMIRQST);
 
1671
  oss_udelay (100);
 
1672
 
 
1673
  if (is_mx300)
 
1674
    {
 
1675
      unsigned int temp;
 
1676
 
 
1677
      temp = V2ReadReg (devc, pif_gpio_control);
 
1678
      temp = 0x0c0 | temp;      /* set GPIO3 to stereo 2x mode */
 
1679
      temp = 0x080 | temp;      /* enable GPIO3 */
 
1680
      temp = 0xffffffbf & temp; /* set GPIO3 to low quad mode */
 
1681
      V2WriteReg (devc, pif_gpio_control, temp);
 
1682
    }
 
1683
 
 
1684
  V2InitCodec (devc);
 
1685
  V2SetupCodec (devc);
 
1686
  V2InitAdb (devc);
 
1687
  EnableCodecChannel (devc, 0);
 
1688
  EnableCodecChannel (devc, 1);
 
1689
  init_fifos (devc);
 
1690
  EnableAdbWtd (devc, 17);
 
1691
  V2SetupRoutes (devc);
 
1692
#ifdef USE_SRC
 
1693
  V2EnableSrc (devc);
 
1694
#endif
 
1695
#ifdef USE_SPDIF
 
1696
  V2EnableSpdif
 
1697
#endif
 
1698
    /*
 
1699
     * DMA controller memory is supposed to contain 0xdeadbeef after
 
1700
     * reset.
 
1701
     */
 
1702
    if (V2ReadReg (devc, devc->dma_base + 0xcfc) != 0xdeadbeef)
 
1703
    cmn_err (CE_WARN,
 
1704
             "DMA memory check returned unexpected result %08x\n",
 
1705
             V2ReadReg (devc, devc->dma_base + 0xcfc));
 
1706
 
 
1707
  my_mixer =
 
1708
    ac97_install (&devc->ac97devc, "Vortex2 AC97 Mixer", ac97_read,
 
1709
                  ac97_write, devc, devc->osdev);
 
1710
  if (my_mixer >= 0)
 
1711
    {
 
1712
      devc->mixer_dev = my_mixer;
 
1713
    }
 
1714
  else
 
1715
    return 0;
 
1716
 
 
1717
 
 
1718
  for (i = 0; i < 2; i++)
 
1719
    devc->dst_routed[i] = 0;
 
1720
 
 
1721
  attach_channel_vortex2 (devc, my_mixer);
 
1722
 
 
1723
  devc->midi_dev =
 
1724
    oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "VORTEX",
 
1725
                         "Aureal Vortex2 UART", &vortex2_midi_driver,
 
1726
                         sizeof (midi_driver_t),
 
1727
                         /*&std_midi_synth, */ NULL,
 
1728
                         0, devc, devc->osdev);
 
1729
  vortex2_midi_init (devc);
 
1730
  devc->midi_opened = 0;
 
1731
  return 1;
 
1732
}
 
1733
 
 
1734
void
 
1735
unload_vortex2 (oss_device_t * osdev)
 
1736
{
 
1737
  vortex_devc *devc = (vortex_devc *) osdev->devc;
 
1738
 
 
1739
#ifdef USE_SRC
 
1740
  V2DisableSrc (devc);
 
1741
#endif
 
1742
  DisableCodecChannel (devc, 0);
 
1743
  DisableCodecChannel (devc, 1);
 
1744
  DisableAdbWtd (devc, 17);
 
1745
 
 
1746
  /* Disable routes */
 
1747
  del_route (devc, codec_chan0_dst_addr, 0);
 
1748
  del_route (devc, codec_chan1_dst_addr, 0);
 
1749
  del_route (devc, fifo_chan2_dst_addr, 0);
 
1750
  del_route (devc, fifo_chan3_dst_addr, 0);
 
1751
  del_route (devc, fifo_chan2a_dst_addr, 0);
 
1752
  del_route (devc, fifo_chan3a_dst_addr, 0);
 
1753
 
 
1754
  /* Disable all interrupts */
 
1755
  V2WriteReg (devc, ICR, 0x00000000);
 
1756
}