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

« back to all changes in this revision

Viewing changes to attic/drv/oss_digi32/oss_digi32.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 RME Digi32 family
 
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 "oss_digi32_cfg.h"
 
17
#include "oss_pci.h"
 
18
 
 
19
#define RME_VENDOR_ID           0xea60
 
20
#define RME_DIGI32              0x9896
 
21
#define RME_DIGI32_PRO          0x9897
 
22
#define RME_DIGI32_8            0x9898
 
23
 
 
24
#define RME_VENDOR_ID2          0x10ee
 
25
#define RME_DIGI96_8_PRO        0x3fc2
 
26
 
 
27
#define MAX_AUDIO_CHANNEL       4
 
28
 
 
29
/*
 
30
 * Control register bits
 
31
 */
 
32
#define C_EMP           0x8000
 
33
#define C_PD            0x4000
 
34
#define C_AUTOSYNC      0x2000
 
35
#define C_ADAT          0x1000
 
36
#define C_DS            0x0800
 
37
#define C_BM            0x0800
 
38
#define C_PRO           0x0400
 
39
#define C_MUTE          0x0200
 
40
#define C_RESET         0x0100
 
41
#define C_INP_1         0x0080
 
42
#define C_INP_0         0x0040
 
43
#define C_FREQ_1        0x0020
 
44
#define C_FREQ_0        0x0010
 
45
#define C_SEL           0x0008
 
46
#define C_MODE24        0x0004
 
47
#define C_MONO          0x0002
 
48
#define C_START         0x0001
 
49
 
 
50
/*
 
51
 * Status register bits 
 
52
 */
 
53
#define S_INTR          0x80000000
 
54
#define S_KMODE         0x40000000      /* 0=Quartz mode, 1=PLL mode */
 
55
#define S_FBITS         0x38000000      /* F bits of CS8412/14 */
 
56
#define S_FSHIFT        27
 
57
#define S_ERF           0x04000000      /* ERF of the CS8412. 1=error */
 
58
#define S_REV           0x0x300000      /* Revision bits */
 
59
#define S_ADATLOCK      0x00080000      /* ADAT PLL locked */
 
60
 
 
61
typedef struct digi32_portc
 
62
{
 
63
  int open_mode;
 
64
  int audio_dev;
 
65
  int voice_chn;
 
66
  int type;
 
67
#define TY_IN   1
 
68
#define TY_OUT  2
 
69
#define TY_BOTH 3
 
70
 
 
71
  int active;
 
72
  int channels;
 
73
  int speed;
 
74
  int speedsel;
 
75
  int bits;
 
76
  int inptr, outptr;
 
77
  int tmp_autosync;
 
78
  int bytes_per_sample;
 
79
  int trigger_bits;
 
80
}
 
81
digi32_portc;
 
82
 
 
83
typedef struct digi32_devc
 
84
{
 
85
  oss_device_t *osdev;
 
86
  oss_mutex_t mutex;
 
87
  char *chip_name;
 
88
  int model;
 
89
#define MDL_BASIC               0
 
90
#define MDL_8                   1
 
91
#define MDL_PRO                 2
 
92
#define MDL_96_8_PRO            3
 
93
 
 
94
  int cs841x_part;
 
95
#define CS8412                  0
 
96
#define CS8414                  1
 
97
 
 
98
  unsigned int cmd;
 
99
 
 
100
  oss_native_word physaddr;
 
101
  char *linaddr;
 
102
  unsigned int *pFIFO;
 
103
  unsigned int *pCTRL;
 
104
 
 
105
  int irq;
 
106
 
 
107
  digi32_portc portc[MAX_AUDIO_CHANNEL];
 
108
  int open_count;
 
109
  int mixer_dev;
 
110
 
 
111
  int speed_locked;
 
112
  int active_device_count;
 
113
}
 
114
digi32_devc;
 
115
 
 
116
static int fbit_tab[2][8] = {
 
117
  {0, 48000, 44100, 32000, 48000, 44100, 44056, 32000},
 
118
  {0, 0, 0, 96000, 88200, 48000, 44100, 32000}
 
119
};
 
120
 
 
121
 
 
122
static void
 
123
write_command (digi32_devc * devc, unsigned int ctrl)
 
124
{
 
125
  devc->cmd = ctrl;
 
126
 
 
127
  PCI_WRITEL (devc->osdev, devc->pCTRL, ctrl);
 
128
}
 
129
 
 
130
/*ARGSUSED*/
 
131
static void
 
132
handle_recording (int dev)
 
133
{
 
134
  digi32_portc *portc = audio_engines[dev]->portc;
 
135
  digi32_devc *devc = audio_engines[dev]->devc;
 
136
 
 
137
  int i, p;
 
138
  unsigned int *buf;
 
139
 
 
140
  p = portc->inptr / 4;         /* Dword addressing */
 
141
  buf =
 
142
    (unsigned int *) &audio_engines[dev]->dmap_in->
 
143
    dmabuf[dmap_get_qtail (audio_engines[dev]->dmap_in) *
 
144
           audio_engines[dev]->dmap_in->fragment_size];
 
145
 
 
146
  /* Perform copy with channel swapping */
 
147
  if (portc->bytes_per_sample == 4)
 
148
    {
 
149
      /* 32 bit mode */
 
150
      for (i = 0; i < (8 * 1024) / 4; i += 2)
 
151
        {
 
152
          buf[i] = PCI_READL (devc->osdev, devc->pFIFO + i + 1 + p);
 
153
          buf[i + 1] = PCI_READL (devc->osdev, devc->pFIFO + i + p);
 
154
        }
 
155
    }
 
156
  else
 
157
    {
 
158
      /* 16 bit mode */
 
159
      unsigned int tmp;
 
160
 
 
161
      for (i = 0; i < (8 * 1024) / 4; i++)
 
162
        {
 
163
          tmp = PCI_READL (devc->osdev, devc->pFIFO + i + p);
 
164
          buf[i] = ((tmp >> 16) & 0xffff) | ((tmp & 0xffff) << 16);
 
165
        }
 
166
    }
 
167
 
 
168
  if (!(portc->trigger_bits & PCM_ENABLE_OUTPUT))       /* Clean the samples */
 
169
    for (i = 0; i < (8 * 1024) / 4; i++)
 
170
      {
 
171
        PCI_WRITEL (devc->osdev, devc->pFIFO + i + p, 0);
 
172
      }
 
173
 
 
174
  portc->inptr = (portc->inptr + (8 * 1024)) % (128 * 1024);    /* Increment the pointer */
 
175
}
 
176
 
 
177
static int
 
178
digi32intr (oss_device_t * osdev)
 
179
{
 
180
  unsigned int status;
 
181
  digi32_devc *devc = (digi32_devc *) osdev->devc;
 
182
  digi32_portc *portc;
 
183
  int i;
 
184
 
 
185
  status = PCI_READL (devc->osdev, devc->pCTRL);
 
186
  if (!(status & S_INTR))
 
187
    return 0;
 
188
 
 
189
  for (i = 0; i < 2; i++)
 
190
    {
 
191
      portc = &devc->portc[i];
 
192
 
 
193
      if (portc->trigger_bits & PCM_ENABLE_INPUT)
 
194
        {
 
195
          handle_recording (portc->audio_dev);
 
196
          if (status & S_ERF && !(devc->cmd & C_AUTOSYNC))
 
197
            {
 
198
              cmn_err (CE_WARN, "External sync dropped\n");
 
199
#if 0
 
200
              devc->cmd |= C_AUTOSYNC;
 
201
              write_command (devc, devc->cmd);
 
202
#endif
 
203
            }
 
204
          else
 
205
            oss_audio_inputintr (portc->audio_dev, 0);
 
206
        }
 
207
 
 
208
      if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
 
209
        {
 
210
          oss_audio_outputintr (portc->audio_dev, 1);
 
211
        }
 
212
    }
 
213
  write_command (devc, devc->cmd);      /* Interrupt acknowledge */
 
214
 
 
215
  return 1;
 
216
}
 
217
 
 
218
 
 
219
/***********************************
 
220
 * Audio routines 
 
221
 ***********************************/
 
222
 
 
223
static int
 
224
digi32_set_rate (int dev, int arg)
 
225
{
 
226
  digi32_devc *devc = audio_engines[dev]->devc;
 
227
  digi32_portc *portc = audio_engines[dev]->portc;
 
228
 
 
229
  static int speed_table[6] = { 32000, 44100, 48000, 64000, 88200, 96000 };
 
230
  int n, i, best = 2, dif, bestdif = 0x7fffffff;
 
231
 
 
232
  if (arg == 0 || devc->active_device_count > 0 || devc->speed_locked)
 
233
    arg = portc->speed;
 
234
 
 
235
  n = (devc->model == MDL_PRO) ? 6 : 3;
 
236
 
 
237
  for (i = 0; i < n; i++)
 
238
    {
 
239
      if (arg == speed_table[i])        /* Exact match */
 
240
        {
 
241
          portc->speed = arg;
 
242
          portc->speedsel = i;
 
243
          return portc->speed;
 
244
        }
 
245
 
 
246
      dif = arg - speed_table[i];
 
247
      if (dif < 0)
 
248
        dif *= -1;
 
249
      if (dif <= bestdif)
 
250
        {
 
251
          best = i;
 
252
          bestdif = dif;
 
253
        }
 
254
 
 
255
    }
 
256
 
 
257
  portc->speed = speed_table[best];
 
258
  portc->speedsel = best;
 
259
  return portc->speed;
 
260
}
 
261
 
 
262
static short
 
263
digi32_set_channels (int dev, short arg)
 
264
{
 
265
  digi32_portc *portc = audio_engines[dev]->portc;
 
266
 
 
267
  if ((arg == 0))
 
268
    return portc->channels;
 
269
  arg = 2;
 
270
  portc->channels = arg;
 
271
 
 
272
  return portc->channels;
 
273
}
 
274
 
 
275
static unsigned int
 
276
digi32_set_format (int dev, unsigned int arg)
 
277
{
 
278
  digi32_devc *devc = audio_engines[dev]->devc;
 
279
  digi32_portc *portc = audio_engines[dev]->portc;
 
280
 
 
281
  if (arg == 0 || devc->active_device_count > 0)
 
282
    return portc->bits;
 
283
 
 
284
  if (arg != AFMT_S16_NE && arg != AFMT_S32_NE && arg != AFMT_AC3)
 
285
    arg = AFMT_S16_NE;
 
286
 
 
287
  portc->bytes_per_sample = (arg & (AFMT_S32_LE | AFMT_S32_BE)) ? 4 : 2;
 
288
  portc->bits = arg;
 
289
 
 
290
  return portc->bits;
 
291
}
 
292
 
 
293
/*ARGSUSED*/
 
294
static int
 
295
digi32_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
 
296
{
 
297
  return OSS_EINVAL;
 
298
}
 
299
 
 
300
static void digi32_trigger (int dev, int state);
 
301
 
 
302
static void
 
303
digi32_reset (int dev)
 
304
{
 
305
  digi32_trigger (dev, 0);
 
306
}
 
307
 
 
308
static void
 
309
digi32_reset_input (int dev)
 
310
{
 
311
  digi32_portc *portc = audio_engines[dev]->portc;
 
312
  digi32_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
 
313
}
 
314
 
 
315
static void
 
316
digi32_reset_output (int dev)
 
317
{
 
318
  digi32_portc *portc = audio_engines[dev]->portc;
 
319
  digi32_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
 
320
}
 
321
 
 
322
static void digi32_close (int dev, int mode);
 
323
 
 
324
/*ARGSUSED*/
 
325
static int
 
326
digi32_open (int dev, int mode, int open_flags)
 
327
{
 
328
  digi32_portc *portc = audio_engines[dev]->portc;
 
329
  digi32_devc *devc = audio_engines[dev]->devc;
 
330
  int i;
 
331
  oss_native_word flags;
 
332
 
 
333
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
334
  if (portc->open_mode != 0)
 
335
    {
 
336
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
337
      return OSS_EBUSY;
 
338
    }
 
339
 
 
340
  portc->open_mode = mode;
 
341
  portc->audio_dev = dev;
 
342
  devc->speed_locked = 0;
 
343
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
344
 
 
345
  for (i = 0; i < 32 * 1024; i++)
 
346
    PCI_WRITEL (devc->osdev, devc->pFIFO + i, 0);       /* Clean the buffer */
 
347
  return 0;
 
348
}
 
349
 
 
350
/*ARGSUSED*/
 
351
static void
 
352
digi32_close (int dev, int mode)
 
353
{
 
354
  digi32_portc *portc = audio_engines[dev]->portc;
 
355
  digi32_devc *devc = audio_engines[dev]->devc;
 
356
  oss_native_word flags;
 
357
 
 
358
  digi32_reset (dev);
 
359
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
360
  portc->open_mode = 0;
 
361
  portc->active = 0;
 
362
  if (portc->tmp_autosync)
 
363
    {
 
364
      portc->tmp_autosync = 0;
 
365
      devc->cmd |= C_AUTOSYNC;
 
366
      write_command (devc, devc->cmd);
 
367
    }
 
368
 
 
369
/*
 
370
 * Inactivate all auxiliary channels allocated for this device
 
371
 */
 
372
 
 
373
  if (--devc->open_count <= 0)
 
374
    {
 
375
      devc->open_count = 0;
 
376
    }
 
377
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
378
}
 
379
 
 
380
/*ARGSUSED*/
 
381
static void
 
382
digi32_output_block (int dev, oss_native_word ptr, int count, int fragsize,
 
383
                     int intrflag)
 
384
{
 
385
  digi32_portc *portc = audio_engines[dev]->portc;
 
386
  digi32_devc *devc = audio_engines[dev]->devc;
 
387
 
 
388
  int i, p;
 
389
  unsigned int *buf;
 
390
 
 
391
  p = portc->outptr / 4;        /* Dword addressing */
 
392
  buf = (unsigned int *) &audio_engines[dev]->dmap_out->dmabuf[ptr];
 
393
 
 
394
 
 
395
  /* Perform copy with channel swapping */
 
396
  if (portc->bytes_per_sample == 4)
 
397
    {
 
398
      /* 32 bit mode */
 
399
      for (i = 0; i < (8 * 1024) / 4; i += 2)
 
400
        {
 
401
          PCI_WRITEL (devc->osdev, devc->pFIFO + i + p, buf[i + 1]);
 
402
          PCI_WRITEL (devc->osdev, devc->pFIFO + i + 1 + p, buf[i]);
 
403
        }
 
404
    }
 
405
  else
 
406
    {
 
407
      /* 16 bit mode */
 
408
      for (i = 0; i < (8 * 1024) / 4; i++)
 
409
        {
 
410
          unsigned int tmp = buf[i];
 
411
          tmp = ((tmp >> 16) & 0xffff) | ((tmp & 0xffff) << 16);
 
412
          PCI_WRITEL (devc->osdev, devc->pFIFO + i + p, tmp);
 
413
        }
 
414
    }
 
415
 
 
416
  PCI_READL (devc->osdev, devc->pFIFO); /* Dummy read to flust cache on some archs */
 
417
 
 
418
  portc->outptr = (portc->outptr + (8 * 1024)) % (128 * 1024);  /* Increment the pointer */
 
419
 
 
420
#if 1
 
421
  if (!intrflag)
 
422
    oss_audio_outputintr (dev, 0);
 
423
#endif
 
424
}
 
425
 
 
426
/*ARGSUSED*/
 
427
static void
 
428
digi32_start_input (int dev, oss_native_word ptr, int count, int fragsize,
 
429
                    int intrflag)
 
430
{
 
431
}
 
432
 
 
433
static void
 
434
digi32_trigger (int dev, int state)
 
435
{
 
436
  digi32_portc *portc = audio_engines[dev]->portc;
 
437
  digi32_devc *devc = audio_engines[dev]->devc;
 
438
  int cmd = devc->cmd;
 
439
  oss_native_word flags;
 
440
 
 
441
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
442
  state &= portc->open_mode;
 
443
 
 
444
  if (portc->active != state)
 
445
    {
 
446
      if (state)
 
447
        {
 
448
          if (devc->active_device_count == 0)
 
449
            {
 
450
              cmd |= C_START;
 
451
              cmd &= ~C_RESET;
 
452
              write_command (devc, cmd | C_SEL);
 
453
              if ((state & OPEN_WRITE) && (portc->open_mode & OPEN_WRITE))
 
454
                portc->trigger_bits |= PCM_ENABLE_OUTPUT;
 
455
              if ((state & OPEN_READ) && (portc->open_mode & OPEN_READ))
 
456
                portc->trigger_bits |= PCM_ENABLE_INPUT;
 
457
              devc->active_device_count = 1;
 
458
            }
 
459
        }
 
460
      else
 
461
        {
 
462
          if (devc->active_device_count != 0)
 
463
            {
 
464
              cmd &= ~C_START;
 
465
              write_command (devc, cmd);
 
466
              if (!(state & OPEN_WRITE) && (portc->open_mode & OPEN_WRITE))
 
467
                portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
468
              if (!(state & OPEN_READ) && (portc->open_mode & OPEN_READ))
 
469
                portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
470
              devc->active_device_count = 0;
 
471
            }
 
472
        }
 
473
    }
 
474
 
 
475
  portc->active = state;
 
476
 
 
477
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
478
}
 
479
 
 
480
/*ARGSUSED*/
 
481
static int
 
482
digi32_prepare_for_output (int dev, int bsize, int bcount)
 
483
{
 
484
/* NOTE! This routine is used for input too */
 
485
 
 
486
  digi32_devc *devc = audio_engines[dev]->devc;
 
487
  digi32_portc *portc = audio_engines[dev]->portc;
 
488
 
 
489
  int cmd = devc->cmd;
 
490
  int dblbit = 0, prev_dblbit, speedsel;
 
491
 
 
492
  if (devc->active_device_count > 0)
 
493
    return 0;
 
494
 
 
495
  if (bsize != 8 * 1024)
 
496
    {
 
497
      cmn_err (CE_CONT, "Illegal fragment size %d\n", bsize);
 
498
      return OSS_EIO;
 
499
    }
 
500
 
 
501
  prev_dblbit = cmd & C_DS;
 
502
  cmd &= C_EMP | C_PRO | C_SEL | C_MUTE | C_INP_0 | C_INP_1 | C_AUTOSYNC;
 
503
  cmd |= C_RESET;
 
504
 
 
505
  if (portc->bits & (AFMT_S32_BE | AFMT_S32_LE))
 
506
    cmd |= C_MODE24;
 
507
 
 
508
  if (portc->speedsel > 2)
 
509
    dblbit = C_DS;
 
510
 
 
511
  speedsel = (portc->speedsel % 3) + 1;
 
512
  cmd |= (speedsel << 4) | dblbit;
 
513
 
 
514
  if (dblbit != prev_dblbit)
 
515
    {
 
516
      write_command (devc, cmd | C_PD);
 
517
      oss_udelay (10);
 
518
    }
 
519
  write_command (devc, cmd);
 
520
  portc->outptr = 0;
 
521
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
522
  return 0;
 
523
}
 
524
 
 
525
/*ARGSUSED*/
 
526
static int
 
527
digi32_prepare_for_input (int dev, int bsize, int bcount)
 
528
{
 
529
  int i, status, fbits;
 
530
  digi32_devc *devc = audio_engines[dev]->devc;
 
531
  digi32_portc *portc = audio_engines[dev]->portc;
 
532
  int cmd = devc->cmd;
 
533
  int dblbit = 0, prev_dblbit, speedsel;
 
534
 
 
535
  if (devc->cmd & C_AUTOSYNC)
 
536
    {
 
537
      devc->cmd &= ~C_AUTOSYNC; /* Autosync must be used for input */
 
538
      portc->tmp_autosync = 1;
 
539
    }
 
540
 
 
541
  write_command (devc, devc->cmd);
 
542
  oss_udelay (100);
 
543
 
 
544
  for (i = 0; i < 1000; i++)
 
545
    {
 
546
      oss_udelay (10);
 
547
      status = PCI_READL (devc->osdev, devc->pCTRL);
 
548
 
 
549
      if (!(status & S_ERF))
 
550
        break;
 
551
    }
 
552
 
 
553
  if (i >= 1000)
 
554
    {
 
555
      cmn_err (CE_WARN, "No input signal detected\n");
 
556
      return OSS_EIO;
 
557
    }
 
558
 
 
559
  devc->speed_locked = 1;
 
560
  fbits = (status & S_FBITS) >> S_FSHIFT;
 
561
  portc->speed = fbit_tab[devc->cs841x_part][fbits];
 
562
  DDB (cmn_err
 
563
       (CE_WARN, "digi32: Measured input sampling rate is %d\n",
 
564
        portc->speed));
 
565
 
 
566
  if (devc->active_device_count > 0)
 
567
    return 0;
 
568
 
 
569
  if (bsize != 8 * 1024)
 
570
    {
 
571
      cmn_err (CE_CONT, "Illegal fragment size %d\n", bsize);
 
572
      return OSS_EIO;
 
573
    }
 
574
 
 
575
  prev_dblbit = cmd & C_DS;
 
576
  cmd &= C_EMP | C_PRO | C_SEL | C_MUTE | C_INP_0 | C_INP_1 | C_AUTOSYNC;
 
577
  cmd |= C_RESET;
 
578
 
 
579
  if (portc->bits & (AFMT_S32_BE | AFMT_S32_LE))
 
580
    cmd |= C_MODE24;
 
581
 
 
582
  if (portc->speedsel > 2)
 
583
    dblbit = C_DS;
 
584
 
 
585
  speedsel = (portc->speedsel % 3) + 1;
 
586
  cmd |= (speedsel << 4) | dblbit;
 
587
 
 
588
  if (dblbit != prev_dblbit)
 
589
    {
 
590
      write_command (devc, cmd | C_PD);
 
591
      oss_udelay (10);
 
592
    }
 
593
  write_command (devc, cmd);
 
594
  portc->inptr = 0;
 
595
 
 
596
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
597
  return 0;
 
598
}
 
599
 
 
600
/*ARGSUSED*/
 
601
static int
 
602
digi32_alloc_buffer (int dev, dmap_t * dmap, int direction)
 
603
{
 
604
  extern int digi32_buffsize;
 
605
 
 
606
  if (digi32_buffsize < 512)    /* Given in kilobytes */
 
607
    digi32_buffsize *= 1024;
 
608
 
 
609
  if (digi32_buffsize < 4096)   /* Smaller ones not acceptable */
 
610
    digi32_buffsize = 64 * 1024;
 
611
 
 
612
  if (dmap->dmabuf != NULL)
 
613
    return 0;
 
614
  dmap->dmabuf_phys = 0;        /* Not mmap() capable */
 
615
  dmap->dmabuf = KERNEL_MALLOC (digi32_buffsize);
 
616
  if (dmap->dmabuf == NULL)
 
617
    return OSS_ENOSPC;
 
618
  dmap->buffsize = digi32_buffsize;
 
619
 
 
620
  return 0;
 
621
}
 
622
 
 
623
/*ARGSUSED*/
 
624
static int
 
625
digi32_free_buffer (int dev, dmap_t * dmap, int direction)
 
626
{
 
627
  if (dmap->dmabuf == NULL)
 
628
    return 0;
 
629
  KERNEL_FREE (dmap->dmabuf);
 
630
 
 
631
  dmap->dmabuf = NULL;
 
632
  return 0;
 
633
}
 
634
 
 
635
#if 0
 
636
static int
 
637
digi32_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
 
638
{
 
639
}
 
640
#endif
 
641
 
 
642
/*ARGSUSED*/
 
643
static void
 
644
digi32_setup_fragments (int dev, dmap_p dmap, int direction)
 
645
{
 
646
  /* Make sure the whole sample RAM is covered by the buffer */
 
647
  dmap->nfrags = dmap->buffsize / dmap->fragment_size;
 
648
}
 
649
 
 
650
static audiodrv_t digi32_output_driver = {
 
651
  digi32_open,
 
652
  digi32_close,
 
653
  digi32_output_block,
 
654
  digi32_start_input,
 
655
  digi32_ioctl,
 
656
  digi32_prepare_for_input,
 
657
  digi32_prepare_for_output,
 
658
  digi32_reset,
 
659
  NULL,
 
660
  NULL,
 
661
  digi32_reset_input,
 
662
  digi32_reset_output,
 
663
  digi32_trigger,
 
664
  digi32_set_rate,
 
665
  digi32_set_format,
 
666
  digi32_set_channels,
 
667
  NULL,
 
668
  NULL,
 
669
  NULL,
 
670
  NULL,
 
671
  digi32_alloc_buffer,
 
672
  digi32_free_buffer,
 
673
  NULL,
 
674
  NULL,
 
675
  NULL,                         /* digi32_get_buffer_pointer */
 
676
  NULL,
 
677
  NULL,
 
678
  NULL,
 
679
  NULL,
 
680
  NULL,
 
681
  NULL,
 
682
  digi32_setup_fragments
 
683
};
 
684
 
 
685
static int
 
686
attach_channel (digi32_devc * devc, int chnum, char *name,
 
687
                audiodrv_t * drv, int type)
 
688
{
 
689
  int adev, opts;
 
690
  digi32_portc *portc;
 
691
 
 
692
  if (chnum < 0 || chnum >= MAX_AUDIO_CHANNEL)
 
693
    return 0;
 
694
 
 
695
  portc = &devc->portc[chnum];
 
696
  opts =
 
697
    ADEV_DUPLEX | ADEV_STEREOONLY | ADEV_COLD | ADEV_NOMMAP | ADEV_NOVIRTUAL;
 
698
 
 
699
  if (chnum != 0)
 
700
     opts |= ADEV_SHADOW;
 
701
 
 
702
  if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
 
703
                                    devc->osdev,
 
704
                                    devc->osdev,
 
705
                                    name, drv, sizeof (audiodrv_t),
 
706
                                    opts,
 
707
                                    AFMT_S16_NE | AFMT_S32_NE | AFMT_AC3,
 
708
                                    devc, -1)) < 0)
 
709
    {
 
710
      return 0;
 
711
    }
 
712
 
 
713
  audio_engines[adev]->mixer_dev = devc->mixer_dev;
 
714
  audio_engines[adev]->portc = portc;
 
715
  audio_engines[adev]->caps |= DSP_CH_STEREO;
 
716
  audio_engines[adev]->min_block = 8 * 1024;
 
717
  audio_engines[adev]->max_block = 8 * 1024;
 
718
  audio_engines[adev]->min_rate = 32000;
 
719
  audio_engines[adev]->max_rate = (devc->model == MDL_PRO) ? 96000 : 48000;
 
720
  portc->open_mode = 0;
 
721
  portc->voice_chn = chnum;
 
722
  portc->speed = 48000;
 
723
  portc->bits = AFMT_S16_NE;
 
724
  portc->bytes_per_sample = 2;
 
725
  portc->type = type;
 
726
  return 1;
 
727
}
 
728
 
 
729
/*ARGSUSED*/
 
730
static int
 
731
digi32_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
 
732
{
 
733
  if (cmd == SOUND_MIXER_READ_DEVMASK ||
 
734
      cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC)
 
735
    return *arg = 0;
 
736
 
 
737
  if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM)
 
738
    return *arg = 100 | (100 << 8);
 
739
  if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM)
 
740
    return *arg = 100 | (100 << 8);
 
741
  return OSS_EINVAL;
 
742
}
 
743
 
 
744
static mixer_driver_t digi32_mixer_driver = {
 
745
  digi32_mixer_ioctl
 
746
};
 
747
 
 
748
static int
 
749
digi32_set_control (int dev, int ctrl, unsigned int cmd, int value)
 
750
{
 
751
  digi32_devc *devc = mixer_devs[dev]->devc;
 
752
  int offs, nbits;
 
753
  unsigned int data;
 
754
 
 
755
  if (ctrl < 0)
 
756
    return OSS_EINVAL;
 
757
 
 
758
  offs = (ctrl >> 4) & 0x0f;    /* # of bits in the field */
 
759
  nbits = ctrl & 0x0f;          /* Shift amount */
 
760
 
 
761
  if (cmd == SNDCTL_MIX_READ)
 
762
    {
 
763
      data = devc->cmd;
 
764
      return (data >> offs) & ((1 << nbits) - 1);
 
765
    }
 
766
 
 
767
  if (cmd == SNDCTL_MIX_WRITE)
 
768
    {
 
769
      if (value < 0 || value >= (1 << nbits))
 
770
        return OSS_EINVAL;
 
771
      data = devc->cmd & ~(((1 << nbits) - 1) << offs);
 
772
      data |= (value & ((1 << nbits) - 1)) << offs;
 
773
      devc->cmd = data;
 
774
      return value;
 
775
    }
 
776
 
 
777
  return OSS_EINVAL;
 
778
}
 
779
 
 
780
static int
 
781
digi32_mix_init (int dev)
 
782
{
 
783
  digi32_devc *devc = mixer_devs[dev]->devc;
 
784
  int group, err;
 
785
 
 
786
  if ((group = mixer_ext_create_group (dev, 0, "DIGI32")) < 0)
 
787
    return group;
 
788
 
 
789
  if (devc->model == MDL_PRO)
 
790
    if ((err = mixer_ext_create_control (dev, group,
 
791
                                         0xf1, digi32_set_control,
 
792
                                         MIXT_ONOFF,
 
793
                                         "DIGI32_DEEMPH", 1,
 
794
                                         MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
795
      return err;
 
796
 
 
797
  if ((err = mixer_ext_create_control (dev, group,
 
798
                                       0xd1, digi32_set_control,
 
799
                                       MIXT_ENUM,
 
800
                                       "DIGI32_SYNC", 2,
 
801
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
802
    return err;
 
803
 
 
804
  if (devc->model != MDL_8)
 
805
    if ((err = mixer_ext_create_control (dev, group,
 
806
                                         0xa1, digi32_set_control,
 
807
                                         MIXT_ENUM,
 
808
                                         "DIGI32_AESMODE", 2,
 
809
                                         MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
810
      return err;
 
811
 
 
812
  if ((err = mixer_ext_create_control (dev, group,
 
813
                                       0x91, digi32_set_control,
 
814
                                       MIXT_ONOFF,
 
815
                                       "DIGI32_MUTE", 1,
 
816
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
817
    return err;
 
818
 
 
819
  if ((err = mixer_ext_create_control (dev, group,
 
820
                                       0x62, digi32_set_control,
 
821
                                       MIXT_ENUM,
 
822
                                       "DIGI32_INPUT", 3,
 
823
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
824
    return err;
 
825
 
 
826
 
 
827
  return 0;
 
828
}
 
829
 
 
830
int
 
831
init_digi32 (digi32_devc * devc)
 
832
{
 
833
  int my_mixer;
 
834
  char tmp[128];
 
835
  int ret;
 
836
 
 
837
  devc->mixer_dev = 0;
 
838
 
 
839
  if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
 
840
                                     devc->osdev,
 
841
                                     devc->osdev,
 
842
                                     "RME Digi32 Control panel",
 
843
                                     &digi32_mixer_driver,
 
844
                                     sizeof (mixer_driver_t), devc)) < 0)
 
845
    {
 
846
 
 
847
      devc->mixer_dev = -1;
 
848
      return 0;
 
849
    }
 
850
  else
 
851
    {
 
852
      devc->mixer_dev = my_mixer;
 
853
      mixer_devs[my_mixer]->priority = -1;      /* Don't use as the default mixer */
 
854
      mixer_ext_set_init_fn (my_mixer, digi32_mix_init, 20);
 
855
    }
 
856
 
 
857
  ret =
 
858
    attach_channel (devc, 0, devc->chip_name, &digi32_output_driver, TY_BOTH);
 
859
  if (ret > 0)
 
860
    {
 
861
      sprintf (tmp, "%s (shadow)", devc->chip_name);
 
862
      ret = attach_channel (devc, 1, tmp, &digi32_output_driver, TY_BOTH);
 
863
    }
 
864
  /*setup the command */
 
865
  if (devc->model == MDL_PRO)
 
866
    write_command (devc, C_PD); /* Reset DAC */
 
867
 
 
868
  write_command (devc, C_AUTOSYNC);
 
869
  return ret;
 
870
}
 
871
 
 
872
 
 
873
int
 
874
oss_digi32_attach (oss_device_t * osdev)
 
875
{
 
876
  digi32_devc *devc;
 
877
  unsigned char pci_irq_line, pci_revision;
 
878
  unsigned short pci_command, vendor, device;
 
879
  unsigned int pci_ioaddr;
 
880
  int err;
 
881
 
 
882
  DDB (cmn_err (CE_WARN, "Entered Digi32 detect routine\n"));
 
883
 
 
884
  pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
 
885
  pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
 
886
 
 
887
  if ((vendor != RME_VENDOR_ID && vendor != RME_VENDOR_ID2) ||
 
888
      (device != RME_DIGI32_PRO &&
 
889
       device != RME_DIGI32 && device != RME_DIGI32_8))
 
890
 
 
891
    return 0;
 
892
 
 
893
  pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
 
894
  pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
 
895
  pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
 
896
  pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
 
897
 
 
898
  if (pci_ioaddr == 0)
 
899
    {
 
900
      cmn_err (CE_WARN, "BAR0 not initialized by BIOS\n");
 
901
      return 0;
 
902
    }
 
903
 
 
904
 
 
905
  if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
 
906
    {
 
907
      cmn_err (CE_WARN, "Out of memory\n");
 
908
      return 0;
 
909
    }
 
910
 
 
911
  devc->osdev = osdev;
 
912
  osdev->devc = devc;
 
913
  devc->physaddr = pci_ioaddr;
 
914
 
 
915
  switch (device)
 
916
    {
 
917
    case RME_DIGI32_PRO:
 
918
      devc->model = MDL_PRO;
 
919
      if (pci_revision == 150)
 
920
        {
 
921
          devc->chip_name = "RME Digi 32 Pro (CS8414)";
 
922
          devc->cs841x_part = CS8414;
 
923
        }
 
924
      else
 
925
        {
 
926
          devc->chip_name = "RME Digi 32 Pro (CS8412)";
 
927
          devc->cs841x_part = CS8412;
 
928
        }
 
929
      break;
 
930
 
 
931
    case RME_DIGI32_8:
 
932
      devc->chip_name = "RME Digi 32/8";
 
933
      devc->model = MDL_8;
 
934
      devc->cs841x_part = CS8412;
 
935
      break;
 
936
 
 
937
    case RME_DIGI32:
 
938
      devc->chip_name = "RME Digi32";
 
939
      devc->model = MDL_BASIC;
 
940
      devc->cs841x_part = CS8412;
 
941
      break;
 
942
 
 
943
    case RME_DIGI96_8_PRO:
 
944
      devc->chip_name = "RME Digi 96/8 Pro";
 
945
      devc->model = MDL_96_8_PRO;
 
946
      devc->cs841x_part = CS8414;
 
947
      break;
 
948
    }
 
949
 
 
950
  DDB (cmn_err (CE_WARN, "Found Digi32 at 0x%x\n", pci_ioaddr));
 
951
 
 
952
  pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
 
953
  pci_write_config_word (osdev, PCI_COMMAND, pci_command);
 
954
 
 
955
  MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
 
956
 
 
957
  oss_register_device (osdev, devc->chip_name);
 
958
 
 
959
  if ((err = oss_register_interrupts (devc->osdev, 0, digi32intr, NULL)) < 0)
 
960
    {
 
961
      cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
 
962
      return 0;
 
963
    }
 
964
 
 
965
  devc->linaddr = (char *) MAP_PCI_MEM (devc->osdev, 0, devc->physaddr,
 
966
                                        128 * 1024 + 4);
 
967
  if (devc->linaddr == NULL)
 
968
    {
 
969
      cmn_err (CE_WARN, "Can't ioremap PCI registers\n");
 
970
      return 0;
 
971
    }
 
972
 
 
973
  devc->pFIFO = (unsigned int *) devc->linaddr;
 
974
  devc->pCTRL = (unsigned int *) (devc->linaddr + 0x20000);
 
975
 
 
976
  return init_digi32 (devc);    /* Detected */
 
977
}
 
978
 
 
979
int
 
980
oss_digi32_detach (oss_device_t * osdev)
 
981
{
 
982
  digi32_devc *devc = (digi32_devc *) osdev->devc;
 
983
 
 
984
  if (oss_disable_device (osdev) < 0)
 
985
    return 0;
 
986
 
 
987
  oss_unregister_interrupts (devc->osdev);
 
988
 
 
989
  MUTEX_CLEANUP (devc->mutex);
 
990
 
 
991
  UNMAP_PCI_MEM (devc->osdev, 0, devc->physaddr, devc->linaddr,
 
992
                 128 * 1024 + 4);
 
993
 
 
994
  oss_unregister_device (devc->osdev);
 
995
 
 
996
  return 1;
 
997
}