~ubuntu-branches/ubuntu/vivid/oss4/vivid-proposed

« back to all changes in this revision

Viewing changes to kernel/drv/oss_ymf7xx/oss_ymf7xx.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis, Samuel Thibault, Romain Beauxis, Sebastien NOEL
  • Date: 2011-06-14 10:06:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110614100656-cx4oc7u426zn812z
Tags: 4.2-build2004-1
[ Samuel Thibault ]
* debian/control: Add liboss4-salsa2, liboss4-salsa-dev and
  liboss4-salsa-asound2 packages, equivalent to (and will replace) those from
  the oss-libsalsa package (Closes: #589127).
* debian/patches/liboss4-salsa.patch: New patch to rename libsalsa into
  liboss4-salsa to avoid conflicts in the archive for no good reason.
* debian/rules: Make in libOSSlib and libsalsa.
* debian/liboss4-salsa-dev.install, debian/liboss4-salsa2.install,
  debian/liboss4-salsa-asound2.links, debian/liboss4-salsa-dev.links:
  Install liboss4-salsa libraries like was done in the oss-libsalsa package.
* include-alsa: Add a copy of ALSA 1.0.5 headers: Cf ALSA_1.0.* symbols in
  libsalsa, this is the roughly supported version.
* debian/copyright: Update for new include-alsa files.
* alsa.pc: New file for compatibility with libasound-dev.
* debian/control:
  - Add Vcs-Browser and Vcs-Svn fields.
  - Use linux-any instead of the list of Linux archs (Closes: #604679).
  - Make dkms dependency linux-any only.
* debian/patches/hurd_iot.patch: New patch to fix soundcard.h usage in
  libsalsa on hurd-i386.
* debian/patches/libsalsa_fixes.patch: New patch to fix some printf usages
  and ioctl declaration in libsalsa.
* debian/patches/no_EBADE.patch: New patch to cope with hurd-i386 not having
  EBADE.
* debian/patches/CFLAGS.patch: New patch to make oss4 take debian/rules
  CFLAGS into account.
* debian/patches/snd_asoundlib_version.patch: New patch to add
  snd_asoundlib_version().
* debian/patches/generic_srccconf.patch: New patch to fix source
  configuration on unknown archs.

[ Romain Beauxis ]
* Fixed README.Debian to only mention dkms' modules.
* Switch to dpkg-source 3.0 (quilt) format
* Added DM-Upload-Allowed: yes

[ Sebastien NOEL ]
* New upstream release (Closes: #595298, #619272).
* Fix typo in initscript (Closes: #627149).
* debian/control: adjust linux-headers dependencies (Closes: #628879).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: Driver for Yamaha YMF7xx 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 "oss_ymf7xx_cfg.h"
 
17
#include "ymf7xx.h"
 
18
#include "oss_pci.h"
 
19
#include "ac97.h"
 
20
#include "uart401.h"
 
21
 
 
22
#define YAMAHA_VENDOR_ID        0x1073
 
23
#define YAMAHA_YMF724_ID        0x0004
 
24
#define YAMAHA_YMF724F_ID       0x000d
 
25
#define YAMAHA_YMF734_ID        0x0005
 
26
#define YAMAHA_YMF740_ID        0x000a
 
27
#define YAMAHA_YMF740C_ID       0x000c
 
28
#define YAMAHA_YMF744_ID        0x0010
 
29
#define YAMAHA_YMF754_ID        0x0012
 
30
 
 
31
#define WRITEB(a,d) devc->bRegister[a] = d
 
32
#define READB(a) devc->bRegister[a]
 
33
#define WRITEW(a,d) devc->wRegister[a>>1] = d
 
34
#define READW(a) devc->wRegister[a>>1]
 
35
#define WRITEL(a,d) devc->dwRegister[a>>2] = d
 
36
#define READL(a) (devc->dwRegister[a>>2])
 
37
 
 
38
#ifdef OSS_BIG_ENDIAN
 
39
static __inline__ unsigned int
 
40
ymf_swap (unsigned int x)
 
41
{
 
42
  return ((x & 0x000000ff) << 24) |
 
43
    ((x & 0x0000ff00) << 8) |
 
44
    ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
 
45
}
 
46
 
 
47
#define LSWAP(x) ymf_swap(x)
 
48
#else
 
49
#define LSWAP(x)        x
 
50
#endif
 
51
 
 
52
#define MAX_PORTC 8
 
53
 
 
54
extern int yamaha_mpu_ioaddr;
 
55
extern int yamaha_mpu_irq;
 
56
extern int yamaha_fm_ioaddr;
 
57
 
 
58
 
 
59
typedef struct ymf7xx_portc
 
60
{
 
61
  int speed, bits, channels;
 
62
  int open_mode;
 
63
  int trigger_bits;
 
64
  int audio_enabled;
 
65
  int audiodev;
 
66
  int devs_opened;
 
67
  int devnum;
 
68
  PLAY_BANK *bank1, *bank2, *bank3, *bank4;
 
69
  EFFECT_CNTRL_SLOT effectslot;
 
70
  REC_CNTRL_SLOT recslot;
 
71
  int dacfmt;
 
72
}
 
73
ymf7xx_portc;
 
74
 
 
75
typedef struct ymf7xx_devc
 
76
{
 
77
  oss_device_t *osdev;
 
78
  char *chip_name;
 
79
  int deviceid;
 
80
  unsigned int base0addr;
 
81
  unsigned int *base0virt;
 
82
  volatile unsigned int *dwRegister;
 
83
  volatile unsigned short *wRegister;
 
84
  volatile unsigned char *bRegister;
 
85
  int irq;
 
86
  oss_mutex_t mutex;
 
87
  oss_mutex_t low_mutex;
 
88
 
 
89
  /* Legacy */
 
90
  int mpu_base, mpu_irq;
 
91
  int fm_base;
 
92
  int fm_attached, mpu_attached;
 
93
 
 
94
  /* Mixer parameters */
 
95
  ac97_devc ac97devc, ac97devc2;
 
96
  int mixer_dev;
 
97
  int mixlevels[10];
 
98
 
 
99
  /* Audio parameters */
 
100
  int audio_initialized;
 
101
  ymf7xx_portc portc[MAX_PORTC];
 
102
 
 
103
  /* Play Table */
 
104
  volatile oss_native_word slt;
 
105
  oss_native_word slt_phys;
 
106
  volatile unsigned int *tab;
 
107
  oss_native_word play_table;
 
108
  oss_native_word play_table_virt;
 
109
  unsigned char *dmabuf1;
 
110
  oss_dma_handle_t dmabuf1_dma_handle;
 
111
 
 
112
  /* Effect Table */
 
113
  volatile unsigned int *effecttab;
 
114
  oss_native_word effect_table;
 
115
  oss_native_word effect_table_virt, eff_buf_phys;
 
116
  unsigned char *dmabuf2, *eff_buf;
 
117
  oss_dma_handle_t dmabuf2_dma_handle;
 
118
  oss_dma_handle_t eff_buf_dma_handle;
 
119
 
 
120
  /* Recording Table */
 
121
  volatile unsigned int *rectab;
 
122
  oss_native_word rec_table;
 
123
  oss_native_word rec_table_virt;
 
124
  unsigned char *dmabuf3;
 
125
  oss_dma_handle_t dmabuf3_dma_handle;
 
126
  int spdif_in;
 
127
}
 
128
ymf7xx_devc;
 
129
 
 
130
int SetupPlaySlot (int dev, int slot);
 
131
int ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value);
 
132
 
 
133
static int
 
134
ac97_read (void *devc_, int addr)
 
135
{
 
136
  ymf7xx_devc *devc = devc_;
 
137
  int count;
 
138
  oss_native_word flags;
 
139
 
 
140
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
141
  WRITEW (AC97_CMD_ADDRESS, addr | 0x8000);
 
142
 
 
143
  for (count = 0; count < 1000; count++)
 
144
    if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
 
145
      {
 
146
        MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
147
        return READW (AC97_STATUS_DATA);
 
148
      }
 
149
  DDB (cmn_err (CE_WARN, "AC97 mixer read timed out\n"));
 
150
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
151
  return OSS_EIO;
 
152
}
 
153
 
 
154
static int
 
155
ac97_write (void *devc_, int addr, int data)
 
156
{
 
157
  ymf7xx_devc *devc = devc_;
 
158
  oss_native_word flags;
 
159
  int count;
 
160
 
 
161
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
162
  WRITEW (AC97_CMD_ADDRESS, addr);
 
163
  WRITEW (AC97_CMD_DATA, data);
 
164
 
 
165
  for (count = 0; count < 1000; count++)
 
166
    if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
 
167
      {
 
168
        MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
169
        return 1;
 
170
      }
 
171
  DDB (cmn_err (CE_WARN, "AC97 mixer write timed out\n"));
 
172
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
173
  return 0;
 
174
}
 
175
 
 
176
static void
 
177
install_ucode (ymf7xx_devc * devc, int addr, unsigned int *src, int len)
 
178
{
 
179
  int i;
 
180
 
 
181
  for (i = 0; i < len; i++)
 
182
    {
 
183
      WRITEL (addr, *src);
 
184
      addr += 4;
 
185
      src++;
 
186
    }
 
187
}
 
188
 
 
189
static int
 
190
ymf7xxintr (oss_device_t * osdev)
 
191
{
 
192
  ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
 
193
  ymf7xx_portc *portc;
 
194
  dmap_t *dmapin, *dmapout;
 
195
  unsigned int status;
 
196
  int i, n;
 
197
  int currdac = 0;
 
198
  int curradc = 0;
 
199
  int serviced = 0;
 
200
 
 
201
 
 
202
  status = READL (STATUS);
 
203
 
 
204
  if ((status & 0x80000000))
 
205
    {
 
206
      serviced = 1;
 
207
      for (i = 0; i < MAX_PORTC; i++)
 
208
        {
 
209
          portc = &devc->portc[i];
 
210
 
 
211
          if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
 
212
            {
 
213
              dmapout = audio_engines[portc->audiodev]->dmap_out;
 
214
              currdac = LSWAP (portc->bank1->PgStart);
 
215
              currdac /= dmapout->fragment_size / portc->dacfmt;
 
216
 
 
217
              if (currdac < 0 || currdac >= dmapout->nfrags)
 
218
                currdac = 0;
 
219
              n = 0;
 
220
              while (dmap_get_qhead (dmapout) != currdac
 
221
                     && n++ < dmapout->nfrags)
 
222
                oss_audio_outputintr (portc->audiodev, 1);
 
223
            }
 
224
          if (portc->trigger_bits & PCM_ENABLE_INPUT)
 
225
            {
 
226
              dmapin = audio_engines[portc->audiodev]->dmap_in;
 
227
 
 
228
              if (devc->spdif_in)
 
229
                curradc = LSWAP (portc->recslot.bank1->PgStartAdr);
 
230
              else
 
231
                curradc = LSWAP (portc->recslot.bank3->PgStartAdr);
 
232
 
 
233
              curradc /= dmapin->fragment_size;
 
234
 
 
235
              if (curradc < 0 || curradc >= dmapin->nfrags)
 
236
                curradc = 0;
 
237
              n = 0;
 
238
              while (dmap_get_qtail (dmapin) != curradc
 
239
                     && n++ < dmapin->nfrags)
 
240
                oss_audio_inputintr (portc->audiodev, 0);
 
241
            }
 
242
          WRITEL (STATUS, 0x80000000);
 
243
          WRITEL (MODE, READL (MODE) | 0x00000002);
 
244
        }
 
245
    }
 
246
 
 
247
  return serviced;
 
248
}
 
249
 
 
250
/*
 
251
 *****************************************************************************
 
252
 */
 
253
 
 
254
static int
 
255
ymf7xx_audio_set_rate (int dev, int arg)
 
256
{
 
257
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
258
 
 
259
  if (arg == 0)
 
260
    return portc->speed;
 
261
 
 
262
  if (arg > 48000)
 
263
    arg = 48000;
 
264
  if (arg < 5000)
 
265
    arg = 5000;
 
266
  portc->speed = arg;
 
267
  return portc->speed;
 
268
}
 
269
 
 
270
static short
 
271
ymf7xx_audio_set_channels (int dev, short arg)
 
272
{
 
273
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
274
 
 
275
  if ((arg != 1) && (arg != 2))
 
276
    return portc->channels;
 
277
  portc->channels = arg;
 
278
 
 
279
  return portc->channels;
 
280
}
 
281
 
 
282
static unsigned int
 
283
ymf7xx_audio_set_format (int dev, unsigned int arg)
 
284
{
 
285
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
286
 
 
287
  if (arg == 0)
 
288
    return portc->bits;
 
289
 
 
290
  if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
 
291
    return portc->bits;
 
292
  portc->bits = arg;
 
293
 
 
294
  return portc->bits;
 
295
}
 
296
 
 
297
/*ARGSUSED*/
 
298
static int
 
299
ymf7xx_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
 
300
{
 
301
  return OSS_EINVAL;
 
302
}
 
303
 
 
304
static void ymf7xx_audio_trigger (int dev, int state);
 
305
 
 
306
static void
 
307
ymf7xx_audio_reset (int dev)
 
308
{
 
309
  ymf7xx_audio_trigger (dev, 0);
 
310
}
 
311
 
 
312
static void
 
313
ymf7xx_audio_reset_input (int dev)
 
314
{
 
315
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
316
  ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
 
317
}
 
318
 
 
319
static void
 
320
ymf7xx_audio_reset_output (int dev)
 
321
{
 
322
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
323
  ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
 
324
}
 
325
 
 
326
/*ARGSUSED*/
 
327
static int
 
328
ymf7xx_audio_open (int dev, int mode, int open_flags)
 
329
{
 
330
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
331
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
332
  oss_native_word flags;
 
333
 
 
334
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
335
  if (portc->open_mode)
 
336
    {
 
337
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
338
      return OSS_EBUSY;
 
339
    }
 
340
 
 
341
  portc->open_mode = mode;
 
342
  portc->audio_enabled = ~mode;
 
343
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
344
 
 
345
  return 0;
 
346
}
 
347
 
 
348
static void
 
349
ymf7xx_audio_close (int dev, int mode)
 
350
{
 
351
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
352
 
 
353
  ymf7xx_audio_reset (dev);
 
354
  portc->open_mode = 0;
 
355
  portc->audio_enabled &= ~mode;
 
356
}
 
357
 
 
358
/*ARGSUSED*/
 
359
static void
 
360
ymf7xx_audio_output_block (int dev, oss_native_word buf, int count,
 
361
                           int fragsize, int intrflag)
 
362
{
 
363
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
364
 
 
365
  portc->audio_enabled |= PCM_ENABLE_OUTPUT;
 
366
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
367
}
 
368
 
 
369
/*ARGSUSED*/
 
370
static void
 
371
ymf7xx_audio_start_input (int dev, oss_native_word buf, int count,
 
372
                          int fragsize, int intrflag)
 
373
{
 
374
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
375
 
 
376
  portc->audio_enabled |= PCM_ENABLE_INPUT;
 
377
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
378
}
 
379
 
 
380
static void
 
381
ymf7xx_audio_trigger (int dev, int state)
 
382
{
 
383
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
384
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
385
  oss_native_word flags;
 
386
 
 
387
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
388
 
 
389
  if (portc->open_mode & OPEN_WRITE)
 
390
    {
 
391
      if (state & PCM_ENABLE_OUTPUT)
 
392
        {
 
393
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
394
              !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
395
            {
 
396
              portc->devs_opened = SetupPlaySlot (dev, portc->devnum);
 
397
 
 
398
              WRITEL (CONTROL_SELECT, 1);
 
399
              WRITEL (MODE, READL (MODE) | 0x00000003);
 
400
              portc->trigger_bits |= PCM_ENABLE_OUTPUT;
 
401
            }
 
402
        }
 
403
      else
 
404
        {
 
405
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
406
              (portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
407
            {
 
408
              portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
409
              portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
410
 
 
411
              devc->tab[portc->devs_opened] = 0;
 
412
              if (portc->channels > 1)
 
413
                devc->tab[portc->devs_opened - 1] = 0;
 
414
            }
 
415
        }
 
416
    }
 
417
 
 
418
  if ((portc->open_mode & OPEN_READ)
 
419
      && !(audio_engines[dev]->flags & ADEV_NOINPUT))
 
420
    {
 
421
      if (state & PCM_ENABLE_INPUT)
 
422
        {
 
423
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
424
              !(portc->trigger_bits & PCM_ENABLE_INPUT))
 
425
            {
 
426
              /* 0x01 = REC SLOT, 0x02 = ADC SLOT */
 
427
              if (devc->spdif_in)
 
428
                WRITEL (MAP_OF_REC, 0x1);
 
429
              else
 
430
                WRITEL (MAP_OF_REC, 0x2);
 
431
              WRITEL (CONTROL_SELECT, 0);
 
432
              WRITEL (MODE, READL (MODE) | 0x00000003);
 
433
              portc->trigger_bits |= PCM_ENABLE_INPUT;
 
434
            }
 
435
        }
 
436
      else
 
437
        {
 
438
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
439
              (portc->trigger_bits & PCM_ENABLE_INPUT))
 
440
            {
 
441
              portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
442
              portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
443
 
 
444
              /* set the map of  rec 0 */
 
445
              WRITEL (MAP_OF_REC, 0x0);
 
446
            }
 
447
        }
 
448
    }
 
449
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
450
}
 
451
 
 
452
static unsigned int
 
453
SetFormatField (ymf7xx_portc * portc)
 
454
{
 
455
  unsigned int val;
 
456
 
 
457
  val = 0x00000000;
 
458
  if (portc->bits == 8)
 
459
    val |= 0x80000000;
 
460
  if (portc->channels > 1)
 
461
    val |= 0x00010000;
 
462
  return val;
 
463
}
 
464
 
 
465
static unsigned int
 
466
SetPgDeltaField (ymf7xx_portc * portc)
 
467
{
 
468
  unsigned int val;
 
469
 
 
470
#if 0
 
471
  double x;
 
472
  x = (double) portc->speed / 48000.0;
 
473
  val = (int) (x * (1 << 28)) & 0x7FFFFF00;
 
474
#else
 
475
  oss_native_word x;
 
476
  x = (portc->speed * (1 << 15) + 187) / 375;
 
477
  val = (x * (1 << 6)) & 0x7FFFFF00;
 
478
#endif
 
479
  return val;
 
480
}
 
481
 
 
482
static unsigned int
 
483
SetLpfKField (ymf7xx_portc * portc)
 
484
{
 
485
  unsigned int i, val = 0, sr = portc->speed;
 
486
  int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
 
487
  int LpfK[8] =
 
488
    { 0x0057, 0x06aa, 0x18B2, 0x2093, 0x2b9a, 0x35a1, 0x3eaa, 0x4000 };
 
489
 
 
490
  if (sr == 44100)
 
491
    {
 
492
      val = 0x4646 << 16;
 
493
    }
 
494
  else
 
495
    {
 
496
      for (i = 0; i < 8; i++)
 
497
        {
 
498
          if (sr <= freq[i])
 
499
            {
 
500
              val = LpfK[i] << 16;
 
501
              break;
 
502
            }
 
503
        }
 
504
    }
 
505
  return val;
 
506
}
 
507
 
 
508
static unsigned int
 
509
SetLpfQField (ymf7xx_portc * portc)
 
510
{
 
511
  unsigned int i, val = 0, sr = portc->speed;
 
512
  int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
 
513
  int LpfQ[8] =
 
514
    { 0x3528, 0x34a7, 0x3202, 0x3177, 0x3139, 0x31c9, 0x33d0, 0x4000 };
 
515
 
 
516
  if (sr == 44100)
 
517
    {
 
518
      val = 0x370A << 16;
 
519
    }
 
520
  else
 
521
    {
 
522
      for (i = 0; i < 8; i++)
 
523
        {
 
524
          if (sr <= freq[i])
 
525
            {
 
526
              val = LpfQ[i] << 16;
 
527
              break;
 
528
            }
 
529
        }
 
530
    }
 
531
  return val;
 
532
}
 
533
 
 
534
void
 
535
SetupRecSlot (int dev)
 
536
{
 
537
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
538
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
539
  dmap_t *dmap = audio_engines[dev]->dmap_in;
 
540
  int banksize;
 
541
 
 
542
  banksize = READL (REC_CNTRL_SIZE);
 
543
  portc->recslot.base = (devc->rec_table_virt);
 
544
 
 
545
  /* banks 1 and 2 are for REC Slot and 3 and 4 are for ADC Slot */
 
546
  if (devc->spdif_in)
 
547
    {
 
548
      portc->recslot.bank1 =
 
549
        (REC_BANK *) (portc->recslot.base + (banksize * 0));
 
550
      portc->recslot.bank2 =
 
551
        (REC_BANK *) (portc->recslot.base + (banksize * 4));
 
552
 
 
553
      WRITEB (REC_FORMAT,
 
554
              (unsigned char) ((portc->channels & 0x02) +
 
555
                               ((portc->bits & 0x08) >> 3)));
 
556
      WRITEW (REC_SAMPLING_RATE,
 
557
              (unsigned short) (48000 * 4096 / portc->speed) - 1);
 
558
 
 
559
      portc->recslot.bank1->PgBase = portc->recslot.bank2->PgBase = LSWAP (dmap->dmabuf_phys);  /* use the REC slot */
 
560
 
 
561
      portc->recslot.bank1->PgLoopEndAdr = portc->recslot.bank2->PgLoopEndAdr = LSWAP (dmap->bytes_in_use);     /* use the REC slot */
 
562
    }
 
563
  else
 
564
    {
 
565
      portc->recslot.bank3 =
 
566
        (REC_BANK *) (portc->recslot.base + (banksize * 8));
 
567
      portc->recslot.bank4 =
 
568
        (REC_BANK *) (portc->recslot.base + (banksize * 12));
 
569
 
 
570
      WRITEB (ADC_FORMAT,
 
571
              (unsigned char) ((portc->channels & 0x02) +
 
572
                               ((portc->bits & 0x08) >> 3)));
 
573
      WRITEW (ADC_SAMPLING_RATE,
 
574
              (unsigned short) (48000 * 4096 / portc->speed) - 1);
 
575
 
 
576
      portc->recslot.bank3->PgBase = portc->recslot.bank4->PgBase = LSWAP (dmap->dmabuf_phys);  /* use the ADC slot */
 
577
 
 
578
      portc->recslot.bank3->PgLoopEndAdr = portc->recslot.bank4->PgLoopEndAdr = LSWAP (dmap->bytes_in_use);     /* use the ADC slot */
 
579
    }
 
580
 
 
581
}
 
582
 
 
583
/*ARGSUSED*/
 
584
static int
 
585
ymf7xx_audio_prepare_for_input (int dev, int bsize, int bcount)
 
586
{
 
587
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
588
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
589
  oss_native_word flags;
 
590
 
 
591
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
592
  SetupRecSlot (dev);
 
593
 
 
594
  /* set the input level to max and go! */
 
595
  WRITEL (NATIVE_REC_INPUT, 0xffffffff);
 
596
  WRITEL (NATIVE_ADC_INPUT, 0xffffffff);
 
597
  portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
598
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
599
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
600
  return 0;
 
601
}
 
602
 
 
603
void
 
604
SetupEffectSlot (int dev)
 
605
{
 
606
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
607
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
608
 
 
609
  int banksize;
 
610
 
 
611
  banksize = READL (EFF_CNTRL_SIZE);
 
612
  portc->effectslot.base = (devc->effect_table_virt);
 
613
 
 
614
  /* slots 1-5 each having 2 banks */
 
615
  portc->effectslot.bank1 =
 
616
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 0));
 
617
  portc->effectslot.bank2 =
 
618
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 4));
 
619
  portc->effectslot.bank3 =
 
620
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 8));
 
621
  portc->effectslot.bank4 =
 
622
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 12));
 
623
  portc->effectslot.bank5 =
 
624
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 16));
 
625
  portc->effectslot.bank6 =
 
626
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 20));
 
627
  portc->effectslot.bank7 =
 
628
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 24));
 
629
  portc->effectslot.bank8 =
 
630
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 28));
 
631
  portc->effectslot.bank9 =
 
632
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 32));
 
633
  portc->effectslot.bank10 =
 
634
    (EFFECT_BANK *) (portc->effectslot.base + (banksize * 36));
 
635
 
 
636
#if 0
 
637
/* Dry Left Channel */
 
638
  portc->effectslot.bank1->PgBase = portc->effectslot.bank2->PgBase =
 
639
    LSWAP (devc->eff_buf_phys + 0 * 8192);
 
640
  portc->effectslot.bank1->PgLoopEnd = portc->effectslot.bank2->PgLoopEnd =
 
641
    LSWAP (4096);
 
642
  portc->effectslot.bank1->PgStart = portc->effectslot.bank2->PgStart = 0;
 
643
 
 
644
/* Dry Right Channel */
 
645
  portc->effectslot.bank3->PgBase = portc->effectslot.bank4->PgBase =
 
646
    LSWAP (devc->eff_buf_phys + 1 * 8192);
 
647
  portc->effectslot.bank3->PgLoopEnd = portc->effectslot.bank4->PgLoopEnd =
 
648
    LSWAP (4096);
 
649
  portc->effectslot.bank3->PgStart = portc->effectslot.bank4->PgStart = 0;
 
650
 
 
651
/* Effect 1 */
 
652
  portc->effectslot.bank5->PgBase = portc->effectslot.bank6->PgBase =
 
653
    LSWAP (devc->eff_buf_phys + 2 * 8192);
 
654
  portc->effectslot.bank5->PgLoopEnd = portc->effectslot.bank6->PgLoopEnd =
 
655
    LSWAP (4096);
 
656
  portc->effectslot.bank5->PgStart = portc->effectslot.bank6->PgStart = 0;
 
657
 
 
658
#endif
 
659
 
 
660
/* Effect 2 */
 
661
  portc->effectslot.bank7->PgBase = portc->effectslot.bank8->PgBase =
 
662
    LSWAP (devc->eff_buf_phys + 0 * 8192);
 
663
  portc->effectslot.bank7->PgLoopEnd = portc->effectslot.bank8->PgLoopEnd =
 
664
    LSWAP (4096);
 
665
  portc->effectslot.bank7->PgStart = portc->effectslot.bank8->PgStart = 0;
 
666
 
 
667
/* Effect 3 */
 
668
  portc->effectslot.bank9->PgBase = portc->effectslot.bank10->PgBase =
 
669
    LSWAP (devc->eff_buf_phys + 1 * 8192);
 
670
  portc->effectslot.bank9->PgLoopEnd = portc->effectslot.bank10->PgLoopEnd =
 
671
    LSWAP (4096);
 
672
  portc->effectslot.bank9->PgStart = portc->effectslot.bank10->PgStart = 0;
 
673
 
 
674
  WRITEL (AC97_SEC_CONFIG, (READL (AC97_SEC_CONFIG) & ~0x0030) | 0x0010);
 
675
  WRITEL (MAP_OF_EFFECTS, 0x18);        /* effect 2,3 */
 
676
  WRITEL (MODE, READL (MODE) | (1 << 30));      /* AC3 Setup */
 
677
}
 
678
 
 
679
 
 
680
void
 
681
SetupPlayBank (int dev, int slot, oss_native_word sbase)
 
682
{
 
683
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
684
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
685
  dmap_t *dmap = audio_engines[dev]->dmap_out;
 
686
 
 
687
  PLAY_BANK *bank1;
 
688
  PLAY_BANK *bank2;
 
689
  bank1 = (PLAY_BANK *) sbase;
 
690
  bank2 =
 
691
    (PLAY_BANK *) (sbase + READL (PLAY_CNTRL_SIZE) * sizeof (unsigned int));
 
692
 
 
693
  memset ((void *) bank1, 0, sizeof (PLAY_BANK));
 
694
  memset ((void *) bank2, 0, sizeof (PLAY_BANK));
 
695
 
 
696
  if (slot == 2)
 
697
    {
 
698
      portc->bank3 = bank1;
 
699
      portc->bank4 = bank2;
 
700
    }
 
701
  else
 
702
    {
 
703
      portc->bank1 = bank1;
 
704
      portc->bank2 = bank2;
 
705
    }
 
706
 
 
707
  /* setup format field */
 
708
  bank1->Format = LSWAP (SetFormatField (portc));
 
709
  bank1->EgGain = bank1->EgGainEnd = LSWAP (0x40000000);
 
710
 
 
711
  if (portc->channels == 1)
 
712
    {
 
713
      /* Gain */
 
714
      bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
 
715
      bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
 
716
      bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
 
717
      bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
 
718
    }
 
719
  else
 
720
    {
 
721
      if (slot == 2)
 
722
        {
 
723
          bank1->Format = LSWAP (LSWAP (bank1->Format) + 1);
 
724
          bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
 
725
          bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
 
726
        }
 
727
      else
 
728
        {
 
729
          bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
 
730
          bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
 
731
        }
 
732
    }
 
733
 
 
734
  bank1->LoopDefault = 0;
 
735
  bank1->NumOfFrames = 0;
 
736
  bank1->LoopCount = 0;
 
737
  bank1->PgStart = 0;
 
738
  bank1->PgLoop = 0;
 
739
 
 
740
  /* PgBase */
 
741
  bank1->PgBase = LSWAP (dmap->dmabuf_phys);
 
742
 
 
743
  /* PgLoopEnd */
 
744
  bank1->PgLoopEnd = LSWAP (dmap->bytes_in_use / portc->dacfmt);
 
745
 
 
746
  /* PgDelta & PgDeltaEnd */
 
747
  bank1->PgDelta = bank1->PgDeltaEnd = LSWAP (SetPgDeltaField (portc));
 
748
 
 
749
  if (portc->channels == 4)
 
750
    bank1->PgDelta = bank1->PgDeltaEnd *= 2;
 
751
 
 
752
  /* LpfK & LpfKEnd */
 
753
  bank1->LpfK = bank1->LpfKEnd = LSWAP (SetLpfKField (portc));
 
754
 
 
755
  /* LpfQ */
 
756
  bank1->LpfQ = LSWAP (SetLpfQField (portc));
 
757
 
 
758
  memcpy (bank2, bank1, sizeof (PLAY_BANK));
 
759
}
 
760
 
 
761
int
 
762
SetupPlaySlot (int dev, int slot)
 
763
{
 
764
  int tmp;
 
765
  oss_native_word sltbase;
 
766
  oss_native_word physbase;
 
767
 
 
768
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
769
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
770
 
 
771
  tmp = slot * 2 + 1;
 
772
  sltbase = (oss_native_word) devc->slt + (tmp * 0x120);
 
773
  physbase = devc->slt_phys + (tmp * 0x120);
 
774
  SetupPlayBank (dev, 1, sltbase);
 
775
  devc->tab[tmp] = LSWAP (physbase);
 
776
 
 
777
  if (portc->channels > 1)
 
778
    {
 
779
      sltbase += 0x120;
 
780
      physbase += 0x120;
 
781
      SetupPlayBank (dev, 2, sltbase);
 
782
      tmp++;
 
783
      devc->tab[tmp] = LSWAP (physbase);
 
784
    }
 
785
  return tmp;
 
786
}
 
787
 
 
788
/*ARGSUSED*/
 
789
static int
 
790
ymf7xx_audio_prepare_for_output (int dev, int bsize, int bcount)
 
791
{
 
792
  ymf7xx_devc *devc = audio_engines[dev]->devc;
 
793
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
794
  oss_native_word flags;
 
795
 
 
796
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
797
 
 
798
  if (portc->bits == AFMT_AC3)
 
799
    {
 
800
      portc->channels = 2;
 
801
      portc->bits = 16;
 
802
      ymf7xx_spdif_control (devc->mixer_dev, 1, SNDCTL_MIX_WRITE, 1);   /* enable SPDIF */
 
803
      ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 1);   /* enable AC3 */
 
804
    }
 
805
  else
 
806
    ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 0);     /* enable AC3 */
 
807
 
 
808
 
 
809
  portc->dacfmt = portc->channels * (portc->bits / 8);
 
810
 
 
811
  if (portc->dacfmt > 4)
 
812
    portc->dacfmt = 4;
 
813
  /* portc->devs_opened = SetupPlaySlot (dev, portc->devnum); -> trigger */
 
814
  /* set effects slot */
 
815
  SetupEffectSlot (dev);
 
816
 
 
817
  if (portc->bits != AFMT_AC3)
 
818
    WRITEL (NATIVE_DAC, 0xFFFFFFFF);
 
819
  else
 
820
    WRITEL (NATIVE_DAC, 0x00000000);
 
821
 
 
822
  portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
823
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
824
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
825
  return 0;
 
826
}
 
827
 
 
828
/*ARGSUSED*/
 
829
static int
 
830
ymf7xx_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
 
831
{
 
832
  ymf7xx_portc *portc = audio_engines[dev]->portc;
 
833
 
 
834
  unsigned int ptr = 0;
 
835
 
 
836
  if (direction == PCM_ENABLE_OUTPUT)
 
837
    {
 
838
      ptr = LSWAP (portc->bank1->PgStart);
 
839
      ptr *= portc->dacfmt;
 
840
    }
 
841
  if (direction == PCM_ENABLE_INPUT)
 
842
    {
 
843
      ptr = LSWAP (portc->recslot.bank3->PgStartAdr);
 
844
    }
 
845
  return ptr;
 
846
}
 
847
 
 
848
static audiodrv_t ymf7xx_audio_driver = {
 
849
  ymf7xx_audio_open,
 
850
  ymf7xx_audio_close,
 
851
  ymf7xx_audio_output_block,
 
852
  ymf7xx_audio_start_input,
 
853
  ymf7xx_audio_ioctl,
 
854
  ymf7xx_audio_prepare_for_input,
 
855
  ymf7xx_audio_prepare_for_output,
 
856
  ymf7xx_audio_reset,
 
857
  NULL,
 
858
  NULL,
 
859
  ymf7xx_audio_reset_input,
 
860
  ymf7xx_audio_reset_output,
 
861
  ymf7xx_audio_trigger,
 
862
  ymf7xx_audio_set_rate,
 
863
  ymf7xx_audio_set_format,
 
864
  ymf7xx_audio_set_channels,
 
865
  NULL,
 
866
  NULL,
 
867
  NULL,
 
868
  NULL,
 
869
  NULL,                         /* ymf7xx_alloc_buffer */
 
870
  NULL,                         /* ymf7xx_free_buffer */
 
871
  NULL,
 
872
  NULL,
 
873
  ymf7xx_get_buffer_pointer
 
874
};
 
875
 
 
876
#if 0
 
877
static void
 
878
init_audio (ymf7xx_devc * devc)
 
879
{
 
880
  devc->audio_initialized = 1;
 
881
}
 
882
 
 
883
uninit_audio (ymf7xx_devc * devc)
 
884
{
 
885
  devc->audio_initialized = 0;
 
886
  WRITEL (CONFIG, 0);
 
887
  WRITEL (MODE, 0);
 
888
}
 
889
#endif
 
890
 
 
891
#ifdef OBSOLETED_STUFF
 
892
/*
 
893
 * This device has "ISA style" MIDI and FM subsystems. Such devices don't
 
894
 * use PCI config space for the I/O ports and interrupts. Instead the driver
 
895
 * needs to allocate proper resources itself. This functionality is no longer
 
896
 * possible. For this reason the MIDI and FM parts are not accessible.
 
897
 */
 
898
static void
 
899
attach_fm (ymf7xx_devc * devc)
 
900
{
 
901
  devc->fm_attached = 0;
 
902
  if (!opl3_detect (0x388, devc->osdev))
 
903
    {
 
904
      cmn_err (CE_WARN, "OPL3 not detected\n");
 
905
      return;
 
906
    }
 
907
  opl3_init (0x388, devc->osdev);
 
908
  devc->fm_attached = 1;
 
909
}
 
910
 
 
911
 
 
912
static void
 
913
attach_mpu (ymf7xx_devc * devc)
 
914
{
 
915
  struct address_info hw_config;
 
916
 
 
917
  hw_config.io_base = devc->mpu_base;
 
918
  hw_config.irq = devc->mpu_irq;
 
919
  hw_config.dma = -1;
 
920
  hw_config.dma2 = -1;
 
921
  hw_config.always_detect = 0;
 
922
  hw_config.name = "Yamaha DS-XG MPU401";
 
923
  hw_config.driver_use_1 = 0;
 
924
  hw_config.driver_use_2 = 0;
 
925
  hw_config.osdev = devc->osdev;
 
926
#ifdef CREATE_OSP
 
927
  CREATE_OSP (hw_config.osdev);
 
928
#endif
 
929
  hw_config.card_subtype = 0;
 
930
 
 
931
  if (!probe_uart401 (&hw_config))
 
932
    {
 
933
      cmn_err (CE_WARN, "MPU-401 was not detected\n");
 
934
      return;
 
935
    }
 
936
  DDB (cmn_err (CE_WARN, "MPU-401 detected - Good\n"));
 
937
  devc->mpu_attached = 1;
 
938
  attach_uart401 (&hw_config);
 
939
}
 
940
 
 
941
static void
 
942
unload_mpu (ymf7xx_devc * devc)
 
943
{
 
944
  struct address_info hw_config;
 
945
 
 
946
  hw_config.io_base = devc->mpu_base;
 
947
  hw_config.irq = devc->mpu_irq;
 
948
  hw_config.dma = -1;
 
949
  hw_config.dma2 = -1;
 
950
  hw_config.always_detect = 0;
 
951
  hw_config.name = "Yahama DS-XG MPU401";
 
952
  hw_config.driver_use_1 = 0;
 
953
  hw_config.driver_use_2 = 0;
 
954
  hw_config.osdev = devc->osdev;
 
955
#ifdef CREATE_OSP
 
956
  CREATE_OSP (hw_config.osdev);
 
957
#endif
 
958
  hw_config.card_subtype = 0;
 
959
 
 
960
  devc->mpu_attached = 0;
 
961
  unload_uart401 (&hw_config);
 
962
}
 
963
#endif
 
964
 
 
965
int
 
966
ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value)
 
967
{
 
968
  ymf7xx_devc *devc = mixer_devs[dev]->hw_devc;
 
969
/*  int left, right; */
 
970
 
 
971
  if (cmd == SNDCTL_MIX_READ)
 
972
    {
 
973
      value = 0;
 
974
      switch (ctrl)
 
975
        {
 
976
        case 1:         /* S/PDIF Enable/Disable */
 
977
          value = READL (SPDIFOUT_CONTROL) & 0x1;
 
978
          break;
 
979
 
 
980
        case 2:         /* S/PDIF Record Enable */
 
981
          value = devc->spdif_in;
 
982
          break;
 
983
 
 
984
        case 3:         /* S/PDIF Loopback */
 
985
          value = READL (SPDIFIN_CONTROL) & (1 << 4);
 
986
          break;
 
987
 
 
988
        case 4:         /* AC3 Output */
 
989
          value = READL (SPDIFOUT_CONTROL) & (1 << 1);
 
990
          break;
 
991
#if 0
 
992
        case 5:         /* CopyProtection Bit */
 
993
          value = READL (SPDIFOUT_STATUS) & (1 << 2);
 
994
          break;
 
995
        case 6:         /* SPDIF OUTVOL */
 
996
          value = devc->mixlevels[0];
 
997
          break;
 
998
        case 7:         /* SPDIF LOOPVOL */
 
999
          value = devc->mixlevels[1];
 
1000
          break;
 
1001
        case 8:         /* SPDIF AC3VOL */
 
1002
          value = devc->mixlevels[2];
 
1003
          break;
 
1004
#endif
 
1005
        }
 
1006
    }
 
1007
  if (cmd == SNDCTL_MIX_WRITE)
 
1008
    {
 
1009
      switch (ctrl)
 
1010
        {
 
1011
        case 1:         /* S/PDIF OUTPUT ENABLE/DISABLE */
 
1012
          if (value)
 
1013
            WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | 0x1);
 
1014
          else
 
1015
            WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~0x1);
 
1016
          break;
 
1017
 
 
1018
        case 2:         /* Record S/PDIF IN ENABLE DISABLE */
 
1019
          if (value)
 
1020
            {
 
1021
              WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | 0x1);
 
1022
              devc->spdif_in = 1;
 
1023
            }
 
1024
          else
 
1025
            {
 
1026
              WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~0x1);
 
1027
              devc->spdif_in = 0;
 
1028
            }
 
1029
          break;
 
1030
 
 
1031
        case 3:         /* S/PDIF Loopback Mode */
 
1032
          if (value)
 
1033
            WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | (1 << 4));
 
1034
          else
 
1035
            WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~(1 << 4));
 
1036
          break;
 
1037
 
 
1038
        case 4:         /* AC3 Output Mode */
 
1039
          if (value)
 
1040
            WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | (1 << 1));
 
1041
          else
 
1042
            WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~(1 << 1));
 
1043
          break;
 
1044
 
 
1045
#if 0
 
1046
        case 5:         /* Copy Protect Mode */
 
1047
          {
 
1048
            int ac3_mode;
 
1049
 
 
1050
            ac3_mode = READL (SPDIFOUT_CONTROL) & (1 << 1);
 
1051
 
 
1052
            if (value)
 
1053
              {
 
1054
                if (ac3_mode)
 
1055
                  WRITEL (SPDIFOUT_STATUS,
 
1056
                          READL (SPDIFOUT_STATUS) | (1 << 1));
 
1057
                else
 
1058
                  WRITEL (SPDIFOUT_STATUS, READL (SPDIFOUT_STATUS) & ~0x3E);
 
1059
              }
 
1060
            else
 
1061
              {
 
1062
                if (ac3_mode)
 
1063
                  WRITEL (SPDIFOUT_STATUS,
 
1064
                          READL (SPDIFOUT_STATUS) | (3 << 1));
 
1065
                else
 
1066
 
 
1067
                  WRITEL (SPDIFOUT_STATUS,
 
1068
                          READL (SPDIFOUT_STATUS) | (1 << 2));
 
1069
              }
 
1070
          }
 
1071
          break;
 
1072
 
 
1073
        case 6:
 
1074
          left = value & 0xff;
 
1075
          right = (value >> 8) & 0xff;
 
1076
          if (left > 100)
 
1077
            left = 100;
 
1078
          if (right > 100)
 
1079
            right = 100;
 
1080
          value = left | (right << 8);
 
1081
          left = left * 0xFFFF / 100;
 
1082
          right = right * 0xFFFF / 100;
 
1083
          WRITEL (SPDIFOUTVOL, left << 16 | right);
 
1084
          devc->mixlevels[0] = value;
 
1085
          break;
 
1086
        case 7:
 
1087
          left = value & 0xff;
 
1088
          right = (value >> 8) & 0xff;
 
1089
          if (left > 100)
 
1090
            left = 100;
 
1091
          if (right > 100)
 
1092
            right = 100;
 
1093
          value = left | (right << 8);
 
1094
          left = left * 0xFFFF / 100;
 
1095
          right = right * 0xFFFF / 100;
 
1096
          WRITEL (SPDIFLOOPVOL, left << 16 | right);
 
1097
          devc->mixlevels[1] = value;
 
1098
          break;
 
1099
        case 8:
 
1100
          left = value & 0xff;
 
1101
          right = (value >> 8) & 0xff;
 
1102
          if (left > 100)
 
1103
            left = 100;
 
1104
          if (right > 100)
 
1105
            right = 100;
 
1106
          value = left | (right << 8);
 
1107
          left = left * 0xFFFF / 100;
 
1108
          right = right * 0xFFFF / 100;
 
1109
          WRITEL (AC3_OUTPUT, left << 16 | right);
 
1110
          devc->mixlevels[2] = value;
 
1111
          break;
 
1112
#endif
 
1113
        }
 
1114
    }
 
1115
  return value;
 
1116
}
 
1117
 
 
1118
static int
 
1119
ymf7xx_mix_init (int dev)
 
1120
{
 
1121
  int group, err;
 
1122
 
 
1123
  if ((group = mixer_ext_create_group (dev, 0, "SPDIF")) < 0)
 
1124
    return group;
 
1125
 
 
1126
  if ((err = mixer_ext_create_control (dev, group, 1, ymf7xx_spdif_control,
 
1127
                                       MIXT_ONOFF, "ENABLE", 1,
 
1128
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1129
    return err;
 
1130
 
 
1131
  if ((err = mixer_ext_create_control (dev, group, 2, ymf7xx_spdif_control,
 
1132
                                       MIXT_ONOFF, "RECORD", 1,
 
1133
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1134
    return err;
 
1135
 
 
1136
  if ((err = mixer_ext_create_control (dev, group, 3, ymf7xx_spdif_control,
 
1137
                                       MIXT_ONOFF, "LOOP", 1,
 
1138
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1139
    return err;
 
1140
 
 
1141
#if 0
 
1142
  if ((err = mixer_ext_create_control (dev, group, 4, ymf7xx_spdif_control,
 
1143
                                       MIXT_ONOFF, "AC3", 1,
 
1144
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1145
    return err;
 
1146
  if ((err = mixer_ext_create_control (dev, group, 5, ymf7xx_spdif_control,
 
1147
                                       MIXT_ONOFF, "COPYPROT", 1,
 
1148
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1149
    return err;
 
1150
 
 
1151
  if ((err = mixer_ext_create_control (dev, group, 6, ymf7xx_spdif_control,
 
1152
                                       MIXT_STEREOSLIDER, "OUTVOL", 100,
 
1153
                                       MIXF_MAINVOL | MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1154
    return err;
 
1155
  if ((err = mixer_ext_create_control (dev, group, 7, ymf7xx_spdif_control,
 
1156
                                       MIXT_STEREOSLIDER, "LOOPVOL", 100,
 
1157
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1158
    return err;
 
1159
  if ((err = mixer_ext_create_control (dev, group, 8, ymf7xx_spdif_control,
 
1160
                                       MIXT_STEREOSLIDER, "AC3VOL", 100,
 
1161
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1162
    return err;
 
1163
#endif
 
1164
 
 
1165
  return 0;
 
1166
}
 
1167
 
 
1168
static int
 
1169
init_ymf7xx (ymf7xx_devc * devc)
 
1170
{
 
1171
 
 
1172
  int my_mixer, i;
 
1173
  int first_dev = 0;
 
1174
 
 
1175
  WRITEL (NATIVE_DAC, 0x00000000);
 
1176
  WRITEL (MODE, 0x00010000);
 
1177
  WRITEL (MODE, 0x00000000);
 
1178
  WRITEL (MAP_OF_REC, 0x00000000);
 
1179
  WRITEL (MAP_OF_EFFECTS, 0x00000000);
 
1180
  WRITEL (PLAY_CNTRL_BASE, 0x00000000);
 
1181
  WRITEL (REC_CNTRL_BASE, 0x00000000);
 
1182
  WRITEL (EFF_CNTRL_BASE, 0x00000000);
 
1183
  WRITEL (CONTROL_SELECT, 1);
 
1184
  WRITEL (GLOBAL_CONTROL, READL (GLOBAL_CONTROL) & ~0x0007);
 
1185
  WRITEL (ZVOUTVOL, 0xFFFFFFFF);
 
1186
  WRITEL (ZVLOOPVOL, 0xFFFFFFFF);
 
1187
  WRITEL (SPDIFOUTVOL, 0xFFFFFFFF);
 
1188
  WRITEL (SPDIFLOOPVOL, 0x3FFF3FFF);
 
1189
  devc->spdif_in = 0;
 
1190
 
 
1191
  if (ac97_read (devc, 0x02) == 0xFFFF)
 
1192
    {
 
1193
      for (i = 0; i < 100; i++)
 
1194
        if (ac97_read (devc, 0x02) != 0xFFFF)
 
1195
          {
 
1196
            break;
 
1197
          }
 
1198
    }
 
1199
 
 
1200
  install_ucode (devc, 0x1000, dsp, dsp_size);
 
1201
  switch (devc->deviceid)
 
1202
    {
 
1203
    case YAMAHA_YMF724F_ID:
 
1204
    case YAMAHA_YMF740C_ID:
 
1205
    case YAMAHA_YMF744_ID:
 
1206
    case YAMAHA_YMF754_ID:
 
1207
      install_ucode (devc, 0x4000, cntrl1E, cntrl1E_size);
 
1208
      break;
 
1209
    default:
 
1210
      install_ucode (devc, 0x4000, cntrl, cntrl_size);
 
1211
    }
 
1212
  WRITEL (CONFIG, 1);
 
1213
 
 
1214
/* add an extra reset to init the mixers */
 
1215
  ac97_write (devc, 0x02, 0x0000);
 
1216
  ac97_write (devc, 0x18, 0x0808);
 
1217
 
 
1218
/* Now check to see if the DSP is started or not */
 
1219
  {
 
1220
    int fEnd;
 
1221
    i = 10000;
 
1222
    do
 
1223
      {
 
1224
        if (i-- <= 0)
 
1225
          {
 
1226
            cmn_err (CE_WARN, "CTR/DSP Init/ TimeOut\n");
 
1227
            return 0;
 
1228
          }
 
1229
        fEnd = READL (CONTROL_SELECT) & 0x1;
 
1230
      }
 
1231
    while (fEnd == 0x1);
 
1232
  }
 
1233
 
 
1234
  my_mixer =
 
1235
    ac97_install (&devc->ac97devc, "Yamaha DS-XG", ac97_read, ac97_write,
 
1236
                  devc, devc->osdev);
 
1237
  if (my_mixer >= 0)
 
1238
    {
 
1239
      devc->mixer_dev = my_mixer;
 
1240
      mixer_ext_set_init_fn (my_mixer, ymf7xx_mix_init, 20);
 
1241
    }
 
1242
  else
 
1243
    return 0;
 
1244
 
 
1245
#ifdef OBSOLETED_STUFF
 
1246
  if (devc->fm_base > 0)
 
1247
    attach_fm (devc);
 
1248
  if (devc->mpu_base > 0)
 
1249
    attach_mpu (devc);
 
1250
#endif
 
1251
 
 
1252
  if (devc->play_table_virt == 0)
 
1253
    {
 
1254
      /* Allocate the Play Table */
 
1255
      oss_native_word phaddr;
 
1256
      devc->dmabuf1 =
 
1257
        CONTIG_MALLOC (devc->osdev, 0x1000, MEMLIMIT_32BITS, &phaddr, devc->dmabuf1_dma_handle);
 
1258
      devc->play_table_virt = (oss_native_word) devc->dmabuf1;
 
1259
      devc->play_table = phaddr;
 
1260
 
 
1261
      /* Allocate Effect Table */
 
1262
      devc->dmabuf2 =
 
1263
        CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf2_dma_handle);
 
1264
      devc->effect_table_virt = (oss_native_word) devc->dmabuf2;
 
1265
      devc->effect_table = phaddr;
 
1266
 
 
1267
      /* Allocate Effect Scratch Buffer */
 
1268
      devc->eff_buf =
 
1269
        CONTIG_MALLOC (devc->osdev, 2 * 8192, MEMLIMIT_32BITS, &phaddr, devc->eff_buf_dma_handle);
 
1270
      devc->eff_buf_phys = phaddr;
 
1271
 
 
1272
      /* Allocate the Record Table */
 
1273
      devc->dmabuf3 =
 
1274
        CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf3_dma_handle);
 
1275
      devc->rec_table_virt = (oss_native_word) devc->dmabuf3;
 
1276
      devc->rec_table = phaddr;
 
1277
 
 
1278
      /* Setup Play Table */
 
1279
      devc->tab = (unsigned int *) devc->play_table_virt;
 
1280
      devc->slt = (oss_native_word) (devc->play_table_virt + 0x100);
 
1281
      devc->slt_phys = (devc->play_table + 0x100);
 
1282
      memset ((void *) devc->tab, 0, 0x1000);
 
1283
      WRITEL (PLAY_CNTRL_BASE, (unsigned int) devc->play_table);
 
1284
      devc->tab[0] = LSWAP (20);        /* setup 20 slots for 8 playback devices */
 
1285
      /* Setup Effect Table and init Effect Slots */
 
1286
      devc->effecttab = (unsigned int *) devc->effect_table_virt;
 
1287
      memset ((void *) devc->effecttab, 0, 1024);
 
1288
      WRITEL (EFF_CNTRL_BASE, (unsigned int) devc->effect_table);
 
1289
 
 
1290
      //SetupEffectSlot (dev);
 
1291
 
 
1292
      /* Setup Record Table */
 
1293
      devc->rectab = (unsigned int *) devc->rec_table_virt;
 
1294
      memset ((void *) devc->rectab, 0, 1024);
 
1295
      WRITEL (REC_CNTRL_BASE, (unsigned int) devc->rec_table);
 
1296
    }
 
1297
 
 
1298
  for (i = 0; i < MAX_PORTC; i++)
 
1299
    {
 
1300
      int adev;
 
1301
      char tmp_name[100];
 
1302
      ymf7xx_portc *portc = &devc->portc[i];
 
1303
      int caps = ADEV_AUTOMODE | ADEV_NOVIRTUAL;
 
1304
 
 
1305
      if (i == 0)
 
1306
        {
 
1307
          strcpy (tmp_name, devc->chip_name);
 
1308
          caps |= ADEV_DUPLEX;
 
1309
        }
 
1310
      else
 
1311
        {
 
1312
          strcpy (tmp_name, devc->chip_name);
 
1313
          caps |= ADEV_NOINPUT;
 
1314
          if (i > 1)
 
1315
            caps |= ADEV_SHADOW;
 
1316
        }
 
1317
 
 
1318
 
 
1319
      if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
 
1320
                                        devc->osdev,
 
1321
                                        devc->osdev,
 
1322
                                        tmp_name,
 
1323
                                        &ymf7xx_audio_driver,
 
1324
                                        sizeof (audiodrv_t),
 
1325
                                        caps,
 
1326
                                        AFMT_U8 | AFMT_S16_LE | AFMT_AC3,
 
1327
                                        devc, -1)) < 0)
 
1328
        {
 
1329
          adev = -1;
 
1330
          return 0;
 
1331
        }
 
1332
      else
 
1333
        {
 
1334
          if (i == 0)
 
1335
            first_dev = adev;
 
1336
          audio_engines[adev]->mixer_dev = my_mixer;
 
1337
          audio_engines[adev]->portc = portc;
 
1338
          audio_engines[adev]->rate_source = first_dev;
 
1339
          audio_engines[adev]->min_block = 64;
 
1340
          audio_engines[adev]->min_rate = 5000;
 
1341
          audio_engines[adev]->max_rate = 48000;
 
1342
          audio_engines[adev]->vmix_flags |= VMIX_MULTIFRAG;
 
1343
          audio_engines[adev]->caps |= PCM_CAP_FREERATE;
 
1344
          audio_engines[adev]->min_channels = 2;
 
1345
          audio_engines[adev]->max_channels = 4;
 
1346
          portc->open_mode = 0;
 
1347
          portc->audiodev = adev;
 
1348
          portc->devnum = i;
 
1349
#ifdef CONFIG_OSS_VMIX
 
1350
          if (i == 0)
 
1351
             vmix_attach_audiodev(devc->osdev, adev, -1, 0);
 
1352
#endif
 
1353
        }
 
1354
    }
 
1355
  return 1;
 
1356
}
 
1357
 
 
1358
int
 
1359
oss_ymf7xx_attach (oss_device_t * osdev)
 
1360
{
 
1361
 
 
1362
 
 
1363
  unsigned char pci_irq_line, pci_revision;
 
1364
  unsigned short pci_command, vendor, device;
 
1365
  unsigned char pci_reset;
 
1366
  unsigned short pci_legacy;
 
1367
  ymf7xx_devc *devc;
 
1368
 
 
1369
  DDB (cmn_err (CE_WARN, "Entered DS-XG attach routine\n"));
 
1370
 
 
1371
  pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
 
1372
  pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
 
1373
 
 
1374
  if (((vendor != YAMAHA_VENDOR_ID)) ||
 
1375
      (device != YAMAHA_YMF740_ID &&
 
1376
       device != YAMAHA_YMF744_ID &&
 
1377
       device != YAMAHA_YMF754_ID &&
 
1378
       device != YAMAHA_YMF740C_ID &&
 
1379
       device != YAMAHA_YMF724_ID &&
 
1380
       device != YAMAHA_YMF734_ID && device != YAMAHA_YMF724F_ID))
 
1381
    return 0;
 
1382
 
 
1383
  oss_pci_byteswap (osdev, 1);
 
1384
 
 
1385
  if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
 
1386
    {
 
1387
      cmn_err (CE_WARN, "Out of memory\n");
 
1388
      return 0;
 
1389
    }
 
1390
 
 
1391
  devc->osdev = osdev;
 
1392
  osdev->devc = devc;
 
1393
 
 
1394
  pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
 
1395
  pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
 
1396
  pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
 
1397
  pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &devc->base0addr);
 
1398
 
 
1399
  if (devc->base0addr == 0)
 
1400
    {
 
1401
      cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
 
1402
      return 0;
 
1403
    }
 
1404
 
 
1405
  if (pci_irq_line == 0)
 
1406
    {
 
1407
      cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
 
1408
      return 0;
 
1409
    }
 
1410
 
 
1411
  DDB (cmn_err
 
1412
       (CE_WARN, "rev %x I/O base %04x\n", pci_revision, devc->base0addr));
 
1413
 
 
1414
  devc->deviceid = device;
 
1415
  switch (device)
 
1416
    {
 
1417
    case YAMAHA_YMF724_ID:
 
1418
      devc->chip_name = "Yamaha YMF724";
 
1419
      break;
 
1420
 
 
1421
    case YAMAHA_YMF724F_ID:
 
1422
      devc->chip_name = "Yamaha YMF724F";
 
1423
      break;
 
1424
 
 
1425
    case YAMAHA_YMF734_ID:
 
1426
      devc->chip_name = "Yamaha YMF734";
 
1427
      break;
 
1428
 
 
1429
    case YAMAHA_YMF740_ID:
 
1430
      devc->chip_name = "Yamaha YMF740";
 
1431
      break;
 
1432
 
 
1433
    case YAMAHA_YMF740C_ID:
 
1434
      devc->chip_name = "Yamaha YMF740C";
 
1435
      break;
 
1436
 
 
1437
    case YAMAHA_YMF744_ID:
 
1438
      devc->chip_name = "Yamaha YMF744";
 
1439
      break;
 
1440
 
 
1441
    case YAMAHA_YMF754_ID:
 
1442
      devc->chip_name = "Yamaha YMF754";
 
1443
      break;
 
1444
 
 
1445
    default:
 
1446
      devc->chip_name = "Yamaha DS-XG";
 
1447
    }
 
1448
 
 
1449
  devc->fm_base = yamaha_fm_ioaddr;
 
1450
  devc->mpu_base = yamaha_mpu_ioaddr;
 
1451
  devc->mpu_irq = yamaha_mpu_irq;
 
1452
 
 
1453
  /* reset the device */
 
1454
  pci_read_config_byte (osdev, 0x48, &pci_reset);
 
1455
 
 
1456
  if (pci_reset & 0x03)
 
1457
    {
 
1458
      pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
 
1459
      pci_write_config_byte (osdev, 0x48, pci_reset | 0x03);
 
1460
      pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
 
1461
    }
 
1462
 
 
1463
/*  Legacy I/O setup - setup MPU and FM io/irq values */
 
1464
  devc->fm_attached = 0;
 
1465
  devc->mpu_attached = 0;
 
1466
  /*pcipci_legacy = 0x0020|0x00C0|0x0004; // 10 bit address decode and Joystick */
 
1467
  pci_legacy = 0x4;
 
1468
  if (devc->fm_base)
 
1469
    pci_legacy |= 0x0002;       /* FM enable */
 
1470
 
 
1471
  if (devc->mpu_base)
 
1472
    {
 
1473
      pci_legacy |= 0x0008;     /* MPU I/O enable */
 
1474
 
 
1475
      switch (devc->mpu_irq)
 
1476
        {
 
1477
        case 5:
 
1478
          pci_legacy |= 0x0010;
 
1479
          break;
 
1480
        case 7:
 
1481
          pci_legacy |= 0x0810;
 
1482
          break;
 
1483
        case 9:
 
1484
          pci_legacy |= 0x1010;
 
1485
          break;
 
1486
        case 10:
 
1487
          pci_legacy |= 0x1810;
 
1488
          break;
 
1489
        case 11:
 
1490
          pci_legacy |= 0x2010;
 
1491
          break;
 
1492
        default:
 
1493
          devc->mpu_irq = 0;
 
1494
        }
 
1495
    }
 
1496
 
 
1497
  pci_write_config_word (osdev, 0x40, pci_legacy);
 
1498
 
 
1499
  pci_legacy = 0x0000;
 
1500
 
 
1501
  switch (devc->fm_base)
 
1502
    {
 
1503
    case 0x388:
 
1504
      pci_legacy |= 0x0000;
 
1505
      break;
 
1506
    case 0x398:
 
1507
      pci_legacy |= 0x0001;
 
1508
      break;
 
1509
    case 0x3a0:
 
1510
      pci_legacy |= 0x0002;
 
1511
      break;
 
1512
    case 0x3a8:
 
1513
      pci_legacy |= 0x0003;
 
1514
      break;
 
1515
    default:
 
1516
      devc->fm_base = 0;
 
1517
    }
 
1518
 
 
1519
  switch (devc->mpu_base)
 
1520
    {
 
1521
    case 0x330:
 
1522
      pci_legacy |= 0x0000;
 
1523
      break;
 
1524
    case 0x300:
 
1525
      pci_legacy |= 0x0010;
 
1526
      break;
 
1527
    case 0x332:
 
1528
      pci_legacy |= 0x0020;
 
1529
      break;
 
1530
    case 0x334:
 
1531
      pci_legacy |= 0x0020;
 
1532
      break;
 
1533
    default:
 
1534
      devc->mpu_base = 0;
 
1535
    }
 
1536
  pci_write_config_word (osdev, 0x42, pci_legacy);
 
1537
 
 
1538
  /* activate the device */
 
1539
  pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
 
1540
  pci_write_config_word (osdev, PCI_COMMAND, pci_command);
 
1541
 
 
1542
  /* Map the shared memory area */
 
1543
  devc->base0virt =
 
1544
    (unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->base0addr, 32 * 1024);
 
1545
  devc->dwRegister = (unsigned int *) devc->base0virt;
 
1546
  devc->wRegister = (unsigned short *) devc->base0virt;
 
1547
  devc->bRegister = (unsigned char *) devc->base0virt;
 
1548
 
 
1549
 
 
1550
  MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
 
1551
  MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
 
1552
 
 
1553
  oss_register_device (osdev, devc->chip_name);
 
1554
 
 
1555
  if (oss_register_interrupts (devc->osdev, 0, ymf7xxintr, NULL) < 0)
 
1556
    {
 
1557
      cmn_err (CE_WARN, "Can't allocate IRQ%d\n", pci_irq_line);
 
1558
      return 0;
 
1559
    }
 
1560
 
 
1561
  return init_ymf7xx (devc);    /* Detected */
 
1562
}
 
1563
 
 
1564
 
 
1565
int
 
1566
oss_ymf7xx_detach (oss_device_t * osdev)
 
1567
{
 
1568
  ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
 
1569
 
 
1570
  if (oss_disable_device (osdev) < 0)
 
1571
    return 0;
 
1572
 
 
1573
  WRITEL (CONFIG, 0);
 
1574
  WRITEL (MODE, 0);
 
1575
 
 
1576
  if (devc->dmabuf1)
 
1577
    {
 
1578
      CONTIG_FREE (devc->osdev, devc->dmabuf1, 0x1000, devc->dmabuf1_dma_handle);
 
1579
      devc->dmabuf1 = 0;
 
1580
    }
 
1581
 
 
1582
  if (devc->dmabuf2)
 
1583
    {
 
1584
      CONTIG_FREE (devc->osdev, devc->dmabuf2, 1024, devc->dmabuf2_dma_handle);
 
1585
      devc->dmabuf2 = 0;
 
1586
    }
 
1587
 
 
1588
  if (devc->eff_buf)
 
1589
    {
 
1590
      CONTIG_FREE (devc->osdev, devc->eff_buf, 16 * 1024, devc->eff_buf_dma_handle);
 
1591
      devc->eff_buf = 0;
 
1592
    }
 
1593
 
 
1594
  if (devc->dmabuf3)
 
1595
    {
 
1596
      CONTIG_FREE (devc->osdev, devc->dmabuf3, 1024, devc->dmabuf3_dma_handle);
 
1597
      devc->dmabuf3 = 0;
 
1598
    }
 
1599
 
 
1600
  devc->play_table_virt = 0;
 
1601
  devc->effect_table_virt = 0;
 
1602
  devc->rec_table_virt = 0;
 
1603
 
 
1604
#ifdef OBSOLETED_STUFF
 
1605
  if (devc->mpu_attached)
 
1606
    {
 
1607
      unload_mpu (devc);
 
1608
      devc->mpu_attached = 0;
 
1609
    }
 
1610
#endif
 
1611
 
 
1612
  oss_unregister_interrupts (devc->osdev);
 
1613
 
 
1614
  MUTEX_CLEANUP (devc->mutex);
 
1615
  MUTEX_CLEANUP (devc->low_mutex);
 
1616
 
 
1617
  if (devc->base0addr != 0)
 
1618
    {
 
1619
      UNMAP_PCI_MEM (devc->osdev, 0, devc->base0addr, devc->base0virt,
 
1620
                     32 * 1024);
 
1621
      devc->base0addr = 0;
 
1622
    }
 
1623
  oss_unregister_device (devc->osdev);
 
1624
  return 1;
 
1625
}