2
* Purpose: Driver for RME Digi96 family
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
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.
16
#include "oss_digi96_cfg.h"
19
#define RME_VENDOR_ID2 0x10ee
20
#define RME_DIGI96 0x3fc0
21
#define RME_DIGI96_8 0x3fc1
22
#define RME_DIGI96_PRO 0x3fc2
23
#define RME_DIGI96_PAD 0x3fc3
25
#define MAX_AUDIO_CHANNEL 2
28
* Control register pCTRL1
30
#define CTRL1_STARTPLAY 0x00000001
31
#define CTRL1_STARTREC 0x00000002
32
#define CTRL1_GAIN 0x0000000c
33
#define CTRL1_MODE24_PLAY 0x00000010
34
#define CTRL1_MODE24_REC 0x00000020
35
#define CTRL1_PLAYBM 0x00000040
36
#define CTRL1_RECBM 0x00000080
37
#define CTRL1_ADAT 0x00000100
38
#define CTRL1_FREQ 0x00000600
39
#define CTRL1_FREQ32 0x00000200
40
#define CTRL1_FREQ44 0x00000400
41
#define CTRL1_FREQ48 0x00000600
42
#define CTRL1_DS 0x00000800
43
#define CTRL1_PRO 0x00001000
44
#define CTRL1_EMP 0x00002000
45
#define CTRL1_SEL 0x00004000
46
#define CTRL1_MASTER 0x00008000
47
#define CTRL1_PD 0x00010000
48
#define CTRL1_INPUTSEL 0x00060000
49
#define CTRL1_INPUTSHIFT 17
50
#define CTRL1_THRU 0x07f80000
51
#define CTRL1_AC3 0x08000000
52
#define CTRL1_MONITOR 0x30000000
53
#define CTRL1_ISEL 0x40000000
54
#define CTRL1_IDIS 0x80000000
57
* Control register pCTRL2
59
#define CTRL2_WSEL 0x00000001
60
#define CTRL2_ANALOG 0x00000002 /* PAD only */
61
#define CTRL2_FREQAD 0x0000001c /* PAD */
62
#define CTRL2_PD2 0x00000020
64
/* Next ones are only for new Digi96/8Pro (blue board) and PAD */
65
#define CTRL2_DAC_EN 0x00000040
66
#define CTRL2_CLATCH 0x00000080
67
#define CTRL2_CCLK 0x00000100
68
#define CTRL2_CDATA 0x00000200
70
* For reads from the pPLAYPOS and pRECPOS registers
73
#define POS_PLAYIRQ 0x80000000
74
#define POS_AUTOSYNC 0x40000000
75
#define POS_FBITS 0x38000000
77
#define POS_ERF 0x04000000
78
#define POS_CONSTANT11 0x03000000
79
#define POS_LOCK 0x00800000
80
#define POS_DEVID 0x00600000
81
#define POS_CONSTANT000 0x008c0000
82
#define POS_TOUT 0x00020000
83
#define POS_RECIRQ 0x00010000
84
#define POS_ADDR 0x000fffff
86
typedef struct digi96_portc
96
typedef struct digi96_devc
109
oss_native_word physaddr;
111
unsigned int *pPLAYBUF;
112
unsigned int *pRECBUF;
113
unsigned int *pCTRL1, ctrl1_bits;
114
unsigned int *pCTRL2, ctrl2_bits;
115
unsigned int *pPLAYACK;
116
unsigned int *pRECACK;
117
unsigned int *pPLAYPOS;
118
unsigned int *pRECPOS;
119
unsigned int *pRESETPLAY;
120
unsigned int *pRESETREC;
124
digi96_portc portc[MAX_AUDIO_CHANNEL];
139
static int fbit_tab[8] = {
140
0, 0, 0, 96000, 88200, 48000, 44100, 32000
145
write_ctrl1 (digi96_devc * devc, unsigned int ctrl)
147
devc->ctrl1_bits = ctrl;
149
PCI_WRITEL (devc->osdev, devc->pCTRL1, ctrl);
153
write_ctrl2 (digi96_devc * devc, unsigned int ctrl)
155
devc->ctrl2_bits = ctrl;
157
PCI_WRITEL (devc->osdev, devc->pCTRL2, ctrl);
161
digi96intr (oss_device_t * osdev)
164
unsigned int playstat, recstat;
165
digi96_devc *devc = (digi96_devc *) osdev->devc;
168
playstat = PCI_READL (devc->osdev, devc->pPLAYPOS);
169
recstat = PCI_READL (devc->osdev, devc->pRECPOS);
171
for (i = 0; i < 2; i++)
173
portc = &devc->portc[i];
175
if (playstat & POS_PLAYIRQ)
178
PCI_WRITEL (devc->osdev, devc->pPLAYACK, 0);
179
oss_audio_outputintr (portc->audio_dev, 0);
182
if (recstat & POS_RECIRQ)
185
PCI_WRITEL (devc->osdev, devc->pRECACK, 0);
186
oss_audio_inputintr (portc->audio_dev, 0);
193
/***********************************
195
***********************************/
198
digi96_set_rate (int dev, int arg)
200
digi96_devc *devc = audio_engines[dev]->devc;
201
digi96_portc *portc = audio_engines[dev]->portc;
203
static int speed_table[6] = { 32000, 44100, 48000, 64000, 88200, 96000 };
204
int i, best = 2, dif, bestdif = 0x7fffffff;
208
if (devc->external_locked || (portc->open_mode & OPEN_READ))
209
arg = portc->speed; /* Speed locked to input */
211
for (i = 0; i < 6; i++)
213
if (arg == speed_table[i]) /* Exact match */
220
dif = arg - speed_table[i];
231
portc->speed = speed_table[best];
232
portc->speedsel = best;
239
digi96_set_channels (int dev, short arg)
241
digi96_portc *portc = audio_engines[dev]->portc;
242
digi96_devc *devc = audio_engines[dev]->devc;
245
return portc->channels;
247
if (devc->mode == MD_ADAT)
251
return portc->channels = arg;
255
digi96_set_format (int dev, unsigned int arg)
257
digi96_portc *portc = audio_engines[dev]->portc;
259
if (arg != AFMT_S16_LE && arg != AFMT_AC3 && arg != AFMT_S32_LE)
262
return portc->bits = arg;
267
digi96_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
272
static void digi96_trigger (int dev, int state);
275
digi96_reset (int dev)
277
digi96_trigger (dev, 0);
281
digi96_reset_input (int dev)
283
digi96_portc *portc = audio_engines[dev]->portc;
284
digi96_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
288
digi96_reset_output (int dev)
290
digi96_portc *portc = audio_engines[dev]->portc;
291
digi96_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
295
verify_input (digi96_devc * devc, digi96_portc * portc)
297
int i, status, savedstatus;
299
oss_native_word flags;
301
tmp = devc->ctrl1_bits & ~CTRL1_INPUTSEL;
302
tmp |= (devc->input_source & 0x3) << CTRL1_INPUTSHIFT;
303
write_ctrl1 (devc, tmp);
305
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
308
status = PCI_READL (devc->osdev, devc->pRECPOS);
310
if (status & POS_LOCK) /* ADAT input */
312
devc->mode = MD_ADAT;
315
switch (devc->adatrate)
317
case 0: /* Autodetect */
318
if (status & POS_AUTOSYNC)
319
portc->speed = 48000;
321
portc->speed = 44100;
323
(CE_WARN, "ADAT input detected, sr=%d Hz\n", portc->speed));
327
portc->speed = 44100;
331
portc->speed = 48000;
334
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
338
while (i++ < 100 && status & POS_ERF)
341
status = PCI_READL (devc->osdev, devc->pRECPOS);
344
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
345
savedstatus = status;
350
cmn_err (CE_WARN, "Cannot sync with the input signal\n");
353
int fbits = (savedstatus & POS_FBITS) >> POS_FSHIFT;
354
portc->speed = fbit_tab[fbits];
356
(CE_WARN, "digi96: Measured input sampling rate is %d\n",
359
return devc->external_locked = !status;
364
digi96_open (int dev, int mode, int open_flags)
367
digi96_portc *portc = audio_engines[dev]->portc;
368
digi96_devc *devc = audio_engines[dev]->devc;
369
oss_native_word flags;
371
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
372
if (portc->open_mode != 0 || (devc->open_mode & mode)) /* Busy? */
374
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
378
portc->open_mode = mode;
379
devc->open_mode |= mode;
380
portc->audio_dev = dev;
381
portc->trigger_bits = 0;
383
tmp = devc->ctrl1_bits;
384
devc->external_locked = 0;
389
tmp &= ~CTRL1_MASTER;
390
devc->external_locked = 1;
392
write_ctrl1 (devc, tmp);
393
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
395
if (devc->external_locked || (portc->open_mode & OPEN_READ))
396
verify_input (devc, portc);
398
if (devc->mode == MD_ADAT)
400
audio_engines[dev]->min_block = 8 * 1024;
401
audio_engines[dev]->max_block = 8 * 1024;
402
audio_engines[dev]->caps &= ~DSP_CH_MASK;
403
audio_engines[dev]->caps |= DSP_CH_MULTI;
404
audio_engines[dev]->min_channels = 8;
405
audio_engines[dev]->max_channels = 8;
406
write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_ISEL);
410
audio_engines[dev]->min_block = 2 * 1024;
411
audio_engines[dev]->max_block = 2 * 1024;
412
audio_engines[dev]->caps &= ~DSP_CH_MASK;
413
audio_engines[dev]->caps |= DSP_CH_STEREO;
414
audio_engines[dev]->min_channels = 2;
415
audio_engines[dev]->max_channels = 2;
416
write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_ISEL);
423
digi96_close (int dev, int mode)
425
digi96_devc *devc = audio_engines[dev]->devc;
426
digi96_portc *portc = audio_engines[dev]->portc;
427
oss_native_word flags;
430
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
431
portc->open_mode = 0;
432
devc->open_mode &= ~mode;
433
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
438
digi96_output_block (int dev, oss_native_word ptr, int count, int fragsize,
445
digi96_start_input (int dev, oss_native_word ptr, int count, int fragsize,
451
digi96_trigger (int dev, int state)
453
digi96_devc *devc = audio_engines[dev]->devc;
454
digi96_portc *portc = audio_engines[dev]->portc;
455
unsigned int tmp = devc->ctrl1_bits;
457
state &= portc->open_mode;
459
if (portc->open_mode & OPEN_WRITE)
461
if (state & PCM_ENABLE_OUTPUT)
462
tmp |= CTRL1_STARTPLAY;
464
tmp &= ~CTRL1_STARTPLAY;
467
if (portc->open_mode & OPEN_READ)
469
if (state & PCM_ENABLE_INPUT)
470
tmp |= CTRL1_STARTREC;
472
tmp &= ~CTRL1_STARTREC;
475
portc->trigger_bits = state;
476
write_ctrl1 (devc, tmp);
481
digi96_prepare_for_output (int dev, int bsize, int bcount)
483
digi96_devc *devc = audio_engines[dev]->devc;
484
digi96_portc *portc = audio_engines[dev]->portc;
486
int cmd = devc->ctrl1_bits;
489
PCI_WRITEL (devc->osdev, devc->pRESETPLAY, 0);
493
cmd &= ~CTRL1_MASTER;
494
if (portc->channels == 8)
498
write_ctrl1 (devc, cmd);
502
if (!verify_input (devc, portc))
506
cmd = devc->ctrl1_bits;
507
doublespeed = (portc->speedsel > 3);
509
cmd &= ~(CTRL1_DS | CTRL1_FREQ);
513
cmd |= ((portc->speedsel % 3) + 1) << 9;
514
write_ctrl1 (devc, cmd);
516
if (doublespeed != devc->doublespeed)
518
devc->doublespeed = doublespeed;
519
write_ctrl1 (devc, cmd | CTRL1_PD); /* Reset the DAC */
522
if (portc->bits == AFMT_AC3)
523
write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_AC3 | CTRL1_PD);
526
if (portc->bits == AFMT_S32_LE)
528
write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_MODE24_PLAY);
531
write_ctrl1 (devc, devc->ctrl1_bits & ~(CTRL1_MODE24_PLAY));
533
write_ctrl1 (devc, devc->ctrl1_bits & ~(CTRL1_AC3 | CTRL1_PD)); /* Unmute DAC */
540
digi96_prepare_for_input (int dev, int bsize, int bcount)
542
digi96_devc *devc = audio_engines[dev]->devc;
543
digi96_portc *portc = audio_engines[dev]->portc;
545
int cmd = devc->ctrl1_bits;
547
if (portc->channels == 8)
552
if (portc->bits == AFMT_S32_LE)
553
cmd |= CTRL1_MODE24_REC;
555
cmd &= ~CTRL1_MODE24_REC;
556
write_ctrl1 (devc, cmd);
558
if (!verify_input (devc, portc))
560
PCI_WRITEL (devc->osdev, devc->pRESETREC, 0);
566
digi96_alloc_buffer (int dev, dmap_t * dmap, int direction)
568
digi96_devc *devc = audio_engines[dev]->devc;
570
if (direction == OPEN_WRITE)
572
dmap->dmabuf = (void *) devc->pPLAYBUF;
573
dmap->dmabuf_phys = (oss_native_word) devc->pPLAYBUF;
577
dmap->dmabuf = (void *) devc->pRECBUF;
578
dmap->dmabuf_phys = (oss_native_word) devc->pRECBUF;
580
dmap->buffsize = 64 * 1024;
587
digi96_free_buffer (int dev, dmap_t * dmap, int direction)
590
dmap->dmabuf_phys = 0;
596
digi96_setup_fragments (int dev, dmap_p dmap, int direction)
598
/* Make sure the whole sample RAM is covered by the buffer */
599
dmap->nfrags = dmap->buffsize / dmap->fragment_size;
602
static audiodrv_t digi96_driver = {
608
digi96_prepare_for_input,
609
digi96_prepare_for_output,
627
NULL, /* digi96_get_buffer_pointer */
634
digi96_setup_fragments
639
digi96_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
641
if (cmd == SOUND_MIXER_PRIVATE1) /* Bogus testing */
648
if (cmd == SOUND_MIXER_READ_DEVMASK ||
649
cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC)
652
if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM)
653
return *arg = 100 | (100 << 8);
654
if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM)
655
return *arg = 100 | (100 << 8);
659
static mixer_driver_t digi96_mixer_driver = {
664
digi96_set_control (int dev, int ctrl, unsigned int cmd, int value)
666
digi96_devc *devc = mixer_devs[dev]->devc;
672
if (cmd == SNDCTL_MIX_READ)
677
return !!devc->master;
681
return devc->input_source;
685
return !!(devc->ctrl1_bits & CTRL1_SEL);
693
return !!(devc->ctrl2_bits & CTRL2_WSEL);
697
return !!(devc->ctrl1_bits & CTRL1_EMP);
701
return !!(devc->ctrl1_bits & CTRL1_AC3);
705
return devc->adatrate;
712
if (cmd == SNDCTL_MIX_WRITE)
717
devc->master = !!value;
722
if (value < 0 || value > 3)
725
devc->input_source = value;
730
tmp = devc->ctrl1_bits;
735
tmp &= ~(CTRL1_SEL | CTRL1_MASTER);
738
write_ctrl1 (devc, tmp);
743
if (value > 2 || (!devc->have_adat && value > 1))
753
write_ctrl2 (devc, devc->ctrl2_bits | CTRL2_WSEL);
757
write_ctrl2 (devc, devc->ctrl2_bits & ~CTRL2_WSEL);
764
write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_EMP);
768
write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_EMP);
775
write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_AC3);
779
write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_AC3);
789
return devc->adatrate = value;
801
digi96_mix_init (int dev)
803
/* digi96_devc *devc = mixer_devs[dev]->devc; */
806
if ((group = mixer_ext_create_group (dev, 0, "DIGI96")) < 0)
809
if ((err = mixer_ext_create_control (dev, group,
810
4, digi96_set_control,
813
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
816
if ((err = mixer_ext_create_control (dev, group,
817
1, digi96_set_control,
820
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
823
if ((err = mixer_ext_create_control (dev, group,
824
2, digi96_set_control,
827
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
830
if ((err = mixer_ext_create_control (dev, group,
831
3, digi96_set_control,
834
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
837
if ((err = mixer_ext_create_control (dev, group,
838
5, digi96_set_control,
840
"DIGI96_WORLDCLK", 1,
841
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
844
if ((err = mixer_ext_create_control (dev, group,
845
6, digi96_set_control,
848
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
852
if ((err = mixer_ext_create_control (dev, group,
853
7, digi96_set_control,
856
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
860
if ((err = mixer_ext_create_control (dev, group,
861
8, digi96_set_control,
863
"DIGI96_ADATRATE", 3,
864
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
866
mixer_ext_set_strings (dev, err, "AUTO 44100 48000", 0);
872
attach_channel (digi96_devc * devc, int chnum, char *name,
873
audiodrv_t * drv, int type)
877
int opts = ADEV_DUPLEX | ADEV_COLD | ADEV_AUTOMODE | ADEV_NOVIRTUAL;
879
if (chnum < 0 || chnum >= MAX_AUDIO_CHANNEL)
885
portc = &devc->portc[chnum];
888
devc->input_source = 0;
889
devc->doublespeed = 0;
890
devc->external_locked = 0;
892
if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
899
AFMT_AC3 | AFMT_S16_LE | AFMT_S32_LE,
905
audio_engines[adev]->mixer_dev = devc->mixer_dev;
906
audio_engines[adev]->portc = portc;
907
audio_engines[adev]->caps |= DSP_CH_STEREO;
908
audio_engines[adev]->min_block = 2 * 1024;
909
audio_engines[adev]->max_block = 2 * 1024;
910
audio_engines[adev]->min_rate = 32000;
911
audio_engines[adev]->max_rate = 96000;
912
portc->open_mode = 0;
914
portc->audio_dev = adev;
916
portc->speed = 48000;
918
portc->bits = AFMT_S16_LE;
924
init_digi96 (digi96_devc * devc)
929
if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
932
"RME Digi96 Control panel",
933
&digi96_mixer_driver,
934
sizeof (mixer_driver_t), devc)) < 0)
937
devc->mixer_dev = -1;
943
mixer_devs[my_mixer]->priority = -1; /* Don't use as the default mixer */
944
devc->mixer_dev = my_mixer;
945
mixer_ext_set_init_fn (my_mixer, digi96_mix_init, 20);
948
ret = attach_channel (devc, 0, devc->chip_name, &digi96_driver, 0);
952
attach_channel (devc, 1, devc->chip_name, &digi96_driver, TY_BOTH);
958
write_ctrl2 (devc, 0);
959
write_ctrl1 (devc, CTRL1_ISEL | CTRL1_FREQ48 | CTRL1_PD); /* Reset DAC */
960
write_ctrl1 (devc, CTRL1_ISEL | CTRL1_FREQ48 | CTRL1_MASTER | CTRL1_SEL);
961
write_ctrl2 (devc, CTRL2_DAC_EN); /* Soft unmute the DAC (blue PRO boards) */
967
oss_digi96_attach (oss_device_t * osdev)
970
unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
971
unsigned short pci_command, vendor, device;
972
unsigned int pci_ioaddr;
975
DDB (cmn_err (CE_WARN, "Entered Digi96 detect routine\n"));
977
pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
978
pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
979
if (vendor != RME_VENDOR_ID2 ||
980
(device != RME_DIGI96_PRO &&
981
device != RME_DIGI96_PAD &&
982
device != RME_DIGI96 && device != RME_DIGI96_8))
986
pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
987
pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
988
pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
989
pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
991
pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
992
pci_write_config_word (osdev, PCI_COMMAND, pci_command);
996
cmn_err (CE_WARN, "BAR0 not initialized by BIOS\n");
1000
if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
1002
cmn_err (CE_WARN, "Out of memory\n");
1006
devc->osdev = osdev;
1008
devc->physaddr = pci_ioaddr;
1010
devc->have_adat = 0;
1011
devc->have_analog = 0;
1012
devc->mode = MD_SPDIF;
1017
devc->chip_name = "RME Digi96";
1021
devc->chip_name = "RME Digi96/8";
1022
devc->have_adat = 1;
1025
case RME_DIGI96_PRO:
1026
devc->have_adat = 1;
1027
if (pci_revision < 2)
1029
devc->chip_name = "RME Digi96/8 PRO (green)";
1033
devc->chip_name = "RME Digi96/8 PRO (blue)";
1037
case RME_DIGI96_PAD:
1038
devc->have_adat = 1;
1039
devc->have_analog = 1;
1040
devc->chip_name = "RME Digi96/8 PAD";
1044
MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
1046
oss_register_device (osdev, devc->chip_name);
1049
(char *) MAP_PCI_MEM (devc->osdev, 0, devc->physaddr, 0x60000);
1050
if (devc->linaddr == NULL)
1052
cmn_err (CE_WARN, "Can't map PCI registers (0x%08lx)\n",
1057
if ((err = oss_register_interrupts (devc->osdev, 0, digi96intr, NULL)) < 0)
1059
cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
1063
devc->pPLAYBUF = (unsigned int *) devc->linaddr;
1064
devc->pRECBUF = (unsigned int *) (devc->linaddr + 0x10000);
1065
devc->pCTRL1 = (unsigned int *) (devc->linaddr + 0x20000);
1066
devc->pCTRL2 = (unsigned int *) (devc->linaddr + 0x20004);
1067
devc->pPLAYACK = (unsigned int *) (devc->linaddr + 0x20008);
1068
devc->pRECACK = (unsigned int *) (devc->linaddr + 0x2000c);
1069
devc->pPLAYPOS = (unsigned int *) (devc->linaddr + 0x20000);
1070
devc->pRECPOS = (unsigned int *) (devc->linaddr + 0x30000);
1071
devc->pRESETPLAY = (unsigned int *) (devc->linaddr + 0x4fffc);
1072
devc->pRESETREC = (unsigned int *) (devc->linaddr + 0x5fffc);
1074
return init_digi96 (devc); /* Detected */
1078
oss_digi96_detach (oss_device_t * osdev)
1080
digi96_devc *devc = (digi96_devc *) osdev->devc;
1082
if (oss_disable_device (osdev) < 0)
1085
write_ctrl2 (devc, 0); /* Soft mute */
1087
oss_unregister_interrupts (devc->osdev);
1089
MUTEX_CLEANUP (devc->mutex);
1091
UNMAP_PCI_MEM (devc->osdev, 0, devc->physaddr, devc->linaddr, 0x60000);
1093
oss_unregister_device (devc->osdev);