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

« back to all changes in this revision

Viewing changes to kernel/drv/oss_ich/oss_ich.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 the Intel ICH AC97 audio controller
 
3
 *
 
4
 * The same design is also used in many PC chipsets by nVidia, AMD and SiS for
 
5
 * audio functionality.
 
6
 */
 
7
 
 
8
/*
 
9
 *
 
10
 * This file is part of Open Sound System.
 
11
 *
 
12
 * Copyright (C) 4Front Technologies 1996-2008.
 
13
 *
 
14
 * This this source file is released under GPL v2 license (no other versions).
 
15
 * See the COPYING file included in the main directory of this source
 
16
 * distribution for the license terms and conditions.
 
17
 *
 
18
 */
 
19
 
 
20
#include "oss_ich_cfg.h"
 
21
#include <oss_pci.h>
 
22
 
 
23
#include <ac97.h>
 
24
extern int intelpci_force_mmio;
 
25
 
 
26
#define INTEL_VENDOR_ID         0x8086
 
27
#define SIS_VENDOR_ID           0x1039
 
28
#define NVIDIA_VENDOR_ID        0x10de
 
29
#define AMD_VENDOR_ID           0x1022
 
30
#define SIS_DEVICE_7012         0x7012
 
31
#define INTEL_DEVICE_ICH1       0x2415
 
32
#define INTEL_DEVICE_ICH1R1     0x2425
 
33
#define INTEL_DEVICE_ICH1R2     0x7195
 
34
#define INTEL_DEVICE_ICH2       0x2445
 
35
#define INTEL_DEVICE_ICH3       0x2485
 
36
#define INTEL_DEVICE_ICH4       0x24c5
 
37
#define INTEL_DEVICE_ICH5       0x24d5
 
38
#define INTEL_DEVICE_ESB        0x25a6
 
39
#define INTEL_DEVICE_ICH6       0x266e
 
40
#define INTEL_DEVICE_ICH7       0x27de
 
41
#define NVIDIA_DEVICE_NFORCE    0x01b1
 
42
#define NVIDIA_DEVICE_MCP4      0x003a
 
43
#define NVIDIA_DEVICE_NFORCE2   0x006a
 
44
#define NVIDIA_DEVICE_CK8       0x008a
 
45
#define NVIDIA_DEVICE_NFORCE3   0x00da
 
46
#define NVIDIA_DEVICE_CK8S      0x00ea
 
47
#define NVIDIA_DEVICE_NFORCE4   0x0059
 
48
#define NVIDIA_DEVICE_MCP51     0x026b
 
49
#define AMD_DEVICE_768          0x7445
 
50
#define AMD_DEVICE_8111         0x746d
 
51
 
 
52
extern int intelpci_rate_tuning;
 
53
 
 
54
#define MAX_PORTC 3
 
55
#define BDL_SIZE        32
 
56
 
 
57
extern int ich_jacksense;
 
58
 
 
59
typedef struct
 
60
{
 
61
  int open_mode;
 
62
  int speed, bits, channels;
 
63
  int audio_enabled;
 
64
  int trigger_bits;
 
65
  int audiodev;
 
66
  int port_type;
 
67
#define DF_PCM 0
 
68
#define DF_SPDIF 1
 
69
}
 
70
ich_portc;
 
71
 
 
72
typedef struct
 
73
{
 
74
  unsigned int addr;
 
75
  unsigned short size;
 
76
  unsigned short flags;
 
77
}
 
78
bdl_t;
 
79
 
 
80
typedef struct ich_devc
 
81
{
 
82
  oss_device_t *osdev;
 
83
  oss_native_word base, ac97_base;
 
84
  oss_native_word membar_addr, ac97_membar_addr;
 
85
  char *membar_virt, *ac97_membar_virt;
 
86
#define CTL_BASE   0            /* addressing controller regs */
 
87
#define MIXER_BASE 1            /* addressing mixer regs */
 
88
  int mem_mode;
 
89
#define MMAP_MODE  0            /* ICH4/ICH5 uses MEM BARS */
 
90
#define IO_MODE    1            /* ICH1/2/3/4/5 uses IO BARS */
 
91
 
 
92
  int irq;
 
93
  oss_mutex_t mutex;
 
94
  oss_mutex_t low_mutex;
 
95
 
 
96
  /* Mixer */
 
97
  ac97_devc ac97devc;
 
98
  int mixer_dev;
 
99
  int inverted_amplifier;
 
100
 
 
101
  /* Audio parameters */
 
102
  int open_mode;
 
103
  int fifo_errors;
 
104
 
 
105
  /* Buffer Descriptor List */
 
106
  char *bdlBuffer;
 
107
  bdl_t *playBDL, *recBDL, *spdifBDL;
 
108
  oss_native_word playBDL_phys, recBDL_phys, spdifBDL_phys;
 
109
  oss_dma_handle_t bldbuf_dma_handle;
 
110
 
 
111
  int play_currbuf, play_currfrag;
 
112
  int spdif_currbuf, spdif_currfrag;
 
113
  int rec_currbuf, rec_currfrag;
 
114
#define INTEL_ICH1 0
 
115
#define INTEL_ICH3 1
 
116
#define INTEL_ICH4 2
 
117
#define SIS_7012   3
 
118
#define AMD_768    4
 
119
#define AMD_8111   5
 
120
#define NVIDIA_NFORCE  6
 
121
#define NVIDIA_NFORCE2 7
 
122
  int model;
 
123
  char *chip_name;
 
124
  ich_portc portc[MAX_PORTC];
 
125
  int play_frag_index[BDL_SIZE];
 
126
  int rec_frag_index[BDL_SIZE];
 
127
  int spdif_frag_index[BDL_SIZE];
 
128
}
 
129
ich_devc;
 
130
 
 
131
static unsigned int
 
132
ich_INL (ich_devc * devc, int base, unsigned int a)
 
133
{
 
134
  if (devc->mem_mode == MMAP_MODE)
 
135
    {
 
136
      if (base == CTL_BASE)
 
137
        return *(volatile unsigned int *) (devc->membar_virt + (a));
 
138
      else
 
139
        return *(volatile unsigned int *) (devc->ac97_membar_virt + (a));
 
140
    }
 
141
  else
 
142
    {
 
143
      if (base == CTL_BASE)
 
144
        return INL (devc->osdev, devc->base + a);
 
145
      else
 
146
        return INL (devc->osdev, devc->ac97_base + a);
 
147
    }
 
148
}
 
149
 
 
150
static unsigned short
 
151
ich_INW (ich_devc * devc, int base, unsigned short a)
 
152
{
 
153
  if (devc->mem_mode == MMAP_MODE)
 
154
    {
 
155
      if (base == CTL_BASE)
 
156
        return *(volatile unsigned short *) (devc->membar_virt + (a));
 
157
      else
 
158
        return *(volatile unsigned short *) (devc->ac97_membar_virt + (a));
 
159
    }
 
160
  else
 
161
    {
 
162
      if (base == CTL_BASE)
 
163
        return INW (devc->osdev, devc->base + a);
 
164
      else
 
165
        return INW (devc->osdev, devc->ac97_base + a);
 
166
    }
 
167
}
 
168
 
 
169
static unsigned char
 
170
ich_INB (ich_devc * devc, int base, unsigned char a)
 
171
{
 
172
  if (devc->mem_mode == MMAP_MODE)
 
173
    {
 
174
      if (base == CTL_BASE)
 
175
        return *(volatile unsigned char *) (devc->membar_virt + (a));
 
176
      else
 
177
        return *(volatile unsigned char *) (devc->ac97_membar_virt + (a));
 
178
    }
 
179
  else
 
180
    {
 
181
      if (base == CTL_BASE)
 
182
        return INB (devc->osdev, devc->base + a);
 
183
      else
 
184
        return INB (devc->osdev, devc->ac97_base + a);
 
185
    }
 
186
}
 
187
 
 
188
static void
 
189
ich_OUTL (ich_devc * devc, unsigned int d, int base, unsigned int a)
 
190
{
 
191
  if (devc->mem_mode == MMAP_MODE)
 
192
    {
 
193
      if (base == CTL_BASE)
 
194
        *(volatile unsigned int *) (devc->membar_virt + (a)) = d;
 
195
      else
 
196
        *(volatile unsigned int *) (devc->ac97_membar_virt + (a)) = d;
 
197
    }
 
198
  else
 
199
    {
 
200
      if (base == CTL_BASE)
 
201
        OUTL (devc->osdev, d, devc->base + a);
 
202
      else
 
203
        OUTL (devc->osdev, d, devc->ac97_base + a);
 
204
    }
 
205
}
 
206
 
 
207
static void
 
208
ich_OUTW (ich_devc * devc, unsigned short d, int base, unsigned short a)
 
209
{
 
210
  if (devc->mem_mode == MMAP_MODE)
 
211
    {
 
212
      if (base == CTL_BASE)
 
213
        *(volatile unsigned short *) (devc->membar_virt + (a)) = d;
 
214
      else
 
215
        *(volatile unsigned short *) (devc->ac97_membar_virt + (a)) = d;
 
216
    }
 
217
  else
 
218
    {
 
219
      if (base == CTL_BASE)
 
220
        OUTW (devc->osdev, d, devc->base + a);
 
221
      else
 
222
        OUTW (devc->osdev, d, devc->ac97_base + a);
 
223
    }
 
224
}
 
225
 
 
226
static void
 
227
ich_OUTB (ich_devc * devc, unsigned char d, int base, unsigned char a)
 
228
{
 
229
  if (devc->mem_mode == MMAP_MODE)
 
230
    {
 
231
      if (base == CTL_BASE)
 
232
        *(volatile unsigned char *) (devc->membar_virt + (a)) = d;
 
233
      else
 
234
        *(volatile unsigned char *) (devc->ac97_membar_virt + (a)) = d;
 
235
    }
 
236
  else
 
237
    {
 
238
      if (base == CTL_BASE)
 
239
        OUTB (devc->osdev, d, devc->base + a);
 
240
      else
 
241
        OUTB (devc->osdev, d, devc->ac97_base + a);
 
242
    }
 
243
}
 
244
 
 
245
static int
 
246
ac97_read (void *devc_, int reg)
 
247
{
 
248
  ich_devc *devc = devc_;
 
249
  int i = 100, status;
 
250
  oss_native_word flags;
 
251
 
 
252
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
253
  status = ich_INB (devc, CTL_BASE, 0x34);
 
254
 
 
255
  while (status & 0x01 && i-- > 0)
 
256
    {
 
257
      MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
258
      oss_udelay (10);
 
259
      MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
260
      status = ich_INB (devc, CTL_BASE, 0x34);
 
261
    }
 
262
 
 
263
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
264
  return ich_INW (devc, MIXER_BASE, reg);
 
265
}
 
266
 
 
267
static int
 
268
ac97_write (void *devc_, int reg, int data)
 
269
{
 
270
  ich_devc *devc = devc_;
 
271
  int i = 100, status;
 
272
  oss_native_word flags;
 
273
 
 
274
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
275
  status = ich_INB (devc, CTL_BASE, 0x34);
 
276
 
 
277
  while (status & 0x01 && i-- > 0)
 
278
    {
 
279
      MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
280
      oss_udelay (10);
 
281
      MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
282
      status = ich_INB (devc, CTL_BASE, 0x34);
 
283
    }
 
284
 
 
285
  ich_OUTW (devc, data, MIXER_BASE, reg);
 
286
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
287
  return 1;
 
288
}
 
289
 
 
290
/*
 
291
 * The top half interrupt handler
 
292
 */
 
293
static int
 
294
ichintr (oss_device_t * osdev)
 
295
{
 
296
  int serviced = 0;
 
297
  ich_devc *devc = osdev->devc;
 
298
  ich_portc *portc;
 
299
  unsigned int glob_status, status, p, f;
 
300
  oss_native_word flags;
 
301
  int i;
 
302
 
 
303
  flags = 0;                    /* To prevent compiler warnings */
 
304
  MUTEX_ENTER (devc->mutex, flags);
 
305
  /* Get pending interrupts and acknowledge them */
 
306
  glob_status = ich_INL (devc, CTL_BASE, 0x30);
 
307
  ich_OUTL (devc, glob_status, CTL_BASE, 0x30);
 
308
 
 
309
  /*
 
310
   * Check the interrupt bits of the status register
 
311
   */
 
312
  if (!(glob_status & 0x0cf7))
 
313
    {
 
314
      /* Not for me */
 
315
      MUTEX_EXIT (devc->mutex, flags);
 
316
      return 0;
 
317
    }
 
318
 
 
319
  /*-------------------- Handle PCM -------------------*/
 
320
  if (devc->model == SIS_7012)
 
321
    status = ich_INB (devc, CTL_BASE, 0x18);
 
322
  else
 
323
    status = ich_INB (devc, CTL_BASE, 0x16);
 
324
 
 
325
  if (status & 0x10)            /* FIFO error */
 
326
    devc->fifo_errors++;
 
327
 
 
328
  if (status & 0x08)
 
329
    {
 
330
      for (i = 0; i < MAX_PORTC - 1; i++)
 
331
        {
 
332
          portc = &devc->portc[i];
 
333
          serviced = 1;
 
334
          if ((portc->trigger_bits & PCM_ENABLE_OUTPUT))        /* IOC interrupt */
 
335
            {
 
336
              dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
 
337
              p = ich_INB (devc, CTL_BASE, 0x14);
 
338
 
 
339
              if (p != devc->play_currbuf)
 
340
                {
 
341
                  p = devc->play_currbuf;
 
342
                  f = devc->play_currfrag;
 
343
                  devc->playBDL[p].addr =
 
344
                    dmap->dmabuf_phys + (f * dmap->fragment_size);
 
345
 
 
346
                  /* SIS uses bytes, intelpci uses samples */
 
347
                  if (devc->model == SIS_7012)
 
348
                    devc->playBDL[p].size = (dmap->fragment_size);
 
349
                  else
 
350
                    devc->playBDL[p].size = (dmap->fragment_size / 2);
 
351
                  devc->playBDL[p].flags = 0xc000;      /* IOC interrupts */
 
352
 
 
353
                  ich_OUTB (devc, p, CTL_BASE, 0x15);   /* Set LVD */
 
354
                  devc->play_frag_index[p] = f;
 
355
                  devc->play_currbuf = (p + 1) % BDL_SIZE;
 
356
                  devc->play_currfrag = (f + 1) % dmap->nfrags;
 
357
                }
 
358
              oss_audio_outputintr (portc->audiodev, 1);
 
359
            }
 
360
        }
 
361
      if (devc->model == SIS_7012)
 
362
        ich_OUTB (devc, status, CTL_BASE, 0x18);        /* Clear interrupts */
 
363
      else
 
364
        ich_OUTB (devc, status, CTL_BASE, 0x16);        /* Clear interrupts */
 
365
    }
 
366
 
 
367
  /*------------------- handle SPDIF interrupts -------------------------*/
 
368
 
 
369
  if (devc->model == NVIDIA_NFORCE2)
 
370
    {
 
371
      status = ich_INB (devc, CTL_BASE, 0x76);
 
372
      if (status & 0x08)
 
373
        {
 
374
          portc = &devc->portc[2];
 
375
          serviced = 1;
 
376
          if ((portc->trigger_bits & PCM_ENABLE_OUTPUT))        /* IOC interrupt */
 
377
            {
 
378
              dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
 
379
              p = ich_INB (devc, CTL_BASE, 0x74);
 
380
 
 
381
              if (p != devc->spdif_currbuf)
 
382
                {
 
383
                  p = devc->spdif_currbuf;
 
384
                  f = devc->spdif_currfrag;
 
385
                  devc->spdifBDL[p].addr =
 
386
                    dmap->dmabuf_phys + (f * dmap->fragment_size);
 
387
                  /* SIS uses bytes, intelpci uses samples */
 
388
                  devc->spdifBDL[p].size = (dmap->fragment_size / 2);
 
389
                  devc->spdifBDL[p].flags = 0xc000;     /* IOC interrupts */
 
390
 
 
391
                  ich_OUTB (devc, p, CTL_BASE, 0x75);   /* Set LVD */
 
392
                  devc->spdif_frag_index[p] = f;
 
393
                  devc->spdif_currbuf = (p + 1) % BDL_SIZE;
 
394
                  devc->spdif_currfrag = (f + 1) % dmap->nfrags;
 
395
                }
 
396
              oss_audio_outputintr (portc->audiodev, 1);
 
397
            }
 
398
          ich_OUTB (devc, status, CTL_BASE, 0x76);      /* Clear interrupts */
 
399
        }
 
400
    }
 
401
 
 
402
  /*----------------------- Handle Recording Interrupts --------------------*/
 
403
 
 
404
  if (devc->model == SIS_7012)
 
405
    status = ich_INB (devc, CTL_BASE, 0x08);
 
406
  else
 
407
    status = ich_INB (devc, CTL_BASE, 0x06);
 
408
 
 
409
  if (status & 0x08)
 
410
    {
 
411
      for (i = 0; i < MAX_PORTC - 1; i++)
 
412
        {
 
413
          portc = &devc->portc[i];
 
414
          serviced = 1;
 
415
          if ((portc->trigger_bits & PCM_ENABLE_INPUT)) /* IOC interrupt */
 
416
            {
 
417
              dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
 
418
              p = ich_INB (devc, CTL_BASE, 0x04);
 
419
 
 
420
              if (p != devc->rec_currbuf)
 
421
                {
 
422
                  p = devc->rec_currbuf;
 
423
                  f = devc->rec_currfrag;
 
424
                  devc->recBDL[p].addr =
 
425
                    dmap->dmabuf_phys + (f * dmap->fragment_size);
 
426
 
 
427
                  /* SIS uses bytes, intelpci uses samples */
 
428
                  if (devc->model == SIS_7012)
 
429
                    devc->recBDL[p].size = (dmap->fragment_size);
 
430
                  else
 
431
                    devc->recBDL[p].size = (dmap->fragment_size / 2);
 
432
 
 
433
                  devc->recBDL[p].flags = 0xc000;       /* IOC interrupts */
 
434
 
 
435
                  ich_OUTB (devc, p, CTL_BASE, 0x05);   /* Set LVD */
 
436
                  devc->rec_frag_index[p] = f;
 
437
                  devc->rec_currbuf = (p + 1) % BDL_SIZE;
 
438
                  devc->rec_currfrag = (f + 1) % dmap->nfrags;
 
439
                }
 
440
              oss_audio_inputintr (portc->audiodev, 0);
 
441
            }
 
442
        }
 
443
      if (devc->model == SIS_7012)
 
444
        ich_OUTB (devc, status, CTL_BASE, 0x08);        /* Clear int */
 
445
      else
 
446
        ich_OUTB (devc, status, CTL_BASE, 0x06);        /* Clear int */
 
447
    }
 
448
  MUTEX_EXIT (devc->mutex, flags);
 
449
  return serviced;
 
450
}
 
451
 
 
452
 
 
453
/*
 
454
 * Audio routines
 
455
 */
 
456
 
 
457
static int
 
458
ich_audio_set_rate (int dev, int arg)
 
459
{
 
460
  ich_portc *portc = audio_engines[dev]->portc;
 
461
 
 
462
  if (arg == 0)
 
463
    return portc->speed;
 
464
 
 
465
  if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
 
466
    arg = 48000;
 
467
 
 
468
  if (arg > 48000)
 
469
    arg = 48000;
 
470
  if (arg < 5000)
 
471
    arg = 5000;
 
472
  portc->speed = arg;
 
473
  return portc->speed;
 
474
}
 
475
 
 
476
static short
 
477
ich_audio_set_channels (int dev, short arg)
 
478
{
 
479
  ich_portc *portc = audio_engines[dev]->portc;
 
480
 
 
481
  if ((arg == 1) || (arg == 2))
 
482
    {
 
483
      audio_engines[dev]->flags |= ADEV_STEREOONLY;
 
484
      arg = 2;
 
485
    }
 
486
  else
 
487
    audio_engines[dev]->flags &= ~ADEV_STEREOONLY;
 
488
 
 
489
  if (arg>6)
 
490
     arg=6;
 
491
 
 
492
  if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
 
493
    return portc->channels;
 
494
  portc->channels = arg;
 
495
 
 
496
  return portc->channels;
 
497
}
 
498
 
 
499
static unsigned int
 
500
ich_audio_set_format (int dev, unsigned int arg)
 
501
{
 
502
  ich_portc *portc = audio_engines[dev]->portc;
 
503
 
 
504
  if (arg == 0)
 
505
    return portc->bits;
 
506
 
 
507
#if 1
 
508
  if (portc->open_mode & OPEN_READ)
 
509
    return portc->bits = AFMT_S16_LE;
 
510
#endif
 
511
  if (!(arg & (AFMT_S16_LE | AFMT_AC3)))
 
512
    return portc->bits;
 
513
  portc->bits = arg;
 
514
 
 
515
  return portc->bits;
 
516
}
 
517
 
 
518
/*ARGSUSED*/
 
519
static int
 
520
ich_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
 
521
{
 
522
  return OSS_EINVAL;
 
523
}
 
524
 
 
525
static void ich_audio_trigger (int dev, int state);
 
526
 
 
527
static void
 
528
ich_audio_reset (int dev)
 
529
{
 
530
  ich_audio_trigger (dev, 0);
 
531
}
 
532
 
 
533
static void
 
534
ich_audio_reset_input (int dev)
 
535
{
 
536
  ich_portc *portc = audio_engines[dev]->portc;
 
537
  ich_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
 
538
}
 
539
 
 
540
static void
 
541
ich_audio_reset_output (int dev)
 
542
{
 
543
  ich_portc *portc = audio_engines[dev]->portc;
 
544
  ich_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
 
545
}
 
546
 
 
547
/*ARGSUSED*/
 
548
static int
 
549
ich_audio_open (int dev, int mode, int openflags)
 
550
{
 
551
  ich_portc *portc = audio_engines[dev]->portc;
 
552
  ich_devc *devc = audio_engines[dev]->devc;
 
553
  oss_native_word flags;
 
554
 
 
555
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
556
  if (portc->open_mode)
 
557
    {
 
558
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
559
      return OSS_EBUSY;
 
560
    }
 
561
  if (portc->port_type == DF_SPDIF)
 
562
    {
 
563
      if (mode & OPEN_READ)
 
564
        {
 
565
          cmn_err (CE_NOTE, "The S/PDIF device supports only playback\n");
 
566
          MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
567
          return OSS_EIO;
 
568
        }
 
569
    }
 
570
  else
 
571
    {
 
572
      if (devc->open_mode & mode)
 
573
        {
 
574
          MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
575
          return OSS_EBUSY;
 
576
        }
 
577
      devc->open_mode |= mode;
 
578
    }
 
579
 
 
580
  portc->open_mode = mode;
 
581
  portc->audio_enabled &= ~mode;
 
582
  devc->fifo_errors = 0;
 
583
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
584
 
 
585
  return 0;
 
586
}
 
587
 
 
588
static void
 
589
ich_audio_close (int dev, int mode)
 
590
{
 
591
  ich_portc *portc = audio_engines[dev]->portc;
 
592
  ich_devc *devc = audio_engines[dev]->devc;
 
593
 
 
594
  ich_audio_reset (dev);
 
595
  portc->open_mode = 0;
 
596
 
 
597
  if (devc->fifo_errors > 0)
 
598
    cmn_err (CE_CONT, "%d fifo errors were detected\n", devc->fifo_errors);
 
599
 
 
600
  if (portc->port_type != DF_SPDIF)
 
601
    devc->open_mode &= ~mode;
 
602
  portc->audio_enabled &= ~mode;
 
603
}
 
604
 
 
605
/*ARGSUSED*/
 
606
static void
 
607
ich_audio_output_block (int dev, oss_native_word buf, int count,
 
608
                        int fragsize, int intrflag)
 
609
{
 
610
  ich_portc *portc = audio_engines[dev]->portc;
 
611
 
 
612
  portc->audio_enabled |= PCM_ENABLE_OUTPUT;
 
613
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
614
}
 
615
 
 
616
/*ARGSUSED*/
 
617
static void
 
618
ich_audio_start_input (int dev, oss_native_word buf, int count,
 
619
                       int fragsize, int intrflag)
 
620
{
 
621
  ich_portc *portc = audio_engines[dev]->portc;
 
622
 
 
623
  portc->audio_enabled |= PCM_ENABLE_INPUT;
 
624
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
625
}
 
626
 
 
627
static void
 
628
ich_audio_trigger (int dev, int state)
 
629
{
 
630
  ich_devc *devc = audio_engines[dev]->devc;
 
631
  ich_portc *portc = audio_engines[dev]->portc;
 
632
  oss_native_word flags;
 
633
 
 
634
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
635
  if (portc->open_mode & OPEN_WRITE)
 
636
    {
 
637
      if (state & PCM_ENABLE_OUTPUT)
 
638
        {
 
639
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
640
              !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
641
            {
 
642
              if (portc->port_type == DF_SPDIF)
 
643
                ich_OUTB (devc, 0x1d, CTL_BASE, 0x7b);  /* Kickstart */
 
644
              else
 
645
                ich_OUTB (devc, 0x1d, CTL_BASE, 0x1b);  /* Kickstart */
 
646
              portc->trigger_bits |= PCM_ENABLE_OUTPUT;
 
647
            }
 
648
        }
 
649
      else
 
650
        {
 
651
          if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
 
652
              (portc->trigger_bits & PCM_ENABLE_OUTPUT))
 
653
            {
 
654
              portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
655
              portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
656
              if (portc->port_type == DF_SPDIF)
 
657
                ich_OUTB (devc, 0x00, CTL_BASE, 0x7b);  /* reset */
 
658
              else
 
659
                ich_OUTB (devc, 0x00, CTL_BASE, 0x1b);  /* reset */
 
660
            }
 
661
        }
 
662
    }
 
663
  if (portc->open_mode & OPEN_READ)
 
664
    {
 
665
      if (state & PCM_ENABLE_INPUT)
 
666
        {
 
667
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
668
              !(portc->trigger_bits & PCM_ENABLE_INPUT))
 
669
            {
 
670
              ich_OUTB (devc, 0x1d, CTL_BASE, 0x0b);    /* Kickstart */
 
671
              portc->trigger_bits |= PCM_ENABLE_INPUT;
 
672
            }
 
673
        }
 
674
      else
 
675
        {
 
676
          if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
 
677
              (portc->trigger_bits & PCM_ENABLE_INPUT))
 
678
            {
 
679
              portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
680
              portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
681
              ich_OUTB (devc, 0x00, CTL_BASE, 0x0b);    /* reset */
 
682
            }
 
683
        }
 
684
    }
 
685
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
686
}
 
687
 
 
688
/*ARGSUSED*/
 
689
static int
 
690
ich_audio_prepare_for_input (int dev, int bsize, int bcount)
 
691
{
 
692
  ich_devc *devc = audio_engines[dev]->devc;
 
693
  ich_portc *portc = audio_engines[dev]->portc;
 
694
  dmap_t *dmap = audio_engines[dev]->dmap_in;
 
695
  int i, n, speed;
 
696
  oss_native_word flags;
 
697
 
 
698
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
699
  ich_OUTB (devc, 0x02, CTL_BASE, 0x0b);        /* Reset */
 
700
  ich_OUTL (devc, devc->recBDL_phys, CTL_BASE, 0x00);   /* BDL base */
 
701
 
 
702
  speed = portc->speed;
 
703
  speed = (speed * 240) / intelpci_rate_tuning;
 
704
  ac97_recrate (&devc->ac97devc, speed);
 
705
 
 
706
  n = bcount;
 
707
  if (n > BDL_SIZE)
 
708
    n = BDL_SIZE;
 
709
 
 
710
  for (i = 0; i < n; i++)
 
711
    {
 
712
      devc->recBDL[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
 
713
 
 
714
      /* SiS7012 uses bytes, ICH uses samples */
 
715
      if (devc->model == SIS_7012)
 
716
        devc->recBDL[i].size = (dmap->fragment_size);
 
717
      else
 
718
        devc->recBDL[i].size = (dmap->fragment_size / 2);
 
719
 
 
720
      devc->recBDL[i].flags = 0xc000;   /* IOC interrupts */
 
721
      devc->rec_frag_index[i] = i;
 
722
    }
 
723
  ich_OUTB (devc, n - 1, CTL_BASE, 0x05);       /* Set last valid descriptor */
 
724
 
 
725
  devc->rec_currbuf = n % BDL_SIZE;
 
726
  devc->rec_currfrag = n;
 
727
  if (devc->rec_currfrag >= dmap->nfrags)
 
728
    devc->rec_currfrag = 0;
 
729
 
 
730
  portc->audio_enabled &= ~PCM_ENABLE_INPUT;
 
731
  portc->trigger_bits &= ~PCM_ENABLE_INPUT;
 
732
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
733
  return 0;
 
734
}
 
735
 
 
736
/*ARGSUSED*/
 
737
static int
 
738
ich_audio_prepare_for_output (int dev, int bsize, int bcount)
 
739
{
 
740
  ich_devc *devc = audio_engines[dev]->devc;
 
741
  ich_portc *portc = audio_engines[dev]->portc;
 
742
  dmap_t *dmap = audio_engines[dev]->dmap_out;
 
743
  int i, n, speed;
 
744
  unsigned int tmp;
 
745
  oss_native_word flags;
 
746
 
 
747
  MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
748
 
 
749
  /* We need to add ac3 pass through support */
 
750
  if (devc->model == SIS_7012)
 
751
    {
 
752
      if (portc->bits == AFMT_AC3)
 
753
        ich_OUTB (devc, 0, CTL_BASE, 0x4c);
 
754
      else
 
755
        ich_OUTB (devc, 1, CTL_BASE, 0x4c);
 
756
    }
 
757
 
 
758
  ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
 
759
 
 
760
  if (portc->bits == AFMT_AC3)
 
761
    {
 
762
      portc->channels = 2;
 
763
      portc->bits = 16;
 
764
    }
 
765
 
 
766
  /* do SPDIF out */
 
767
  if ((portc->port_type == DF_SPDIF) && (devc->model == NVIDIA_NFORCE2))
 
768
    {
 
769
      ich_OUTB (devc, 0x02, CTL_BASE, 0x7b);    /* Reset */
 
770
      ich_OUTL (devc, devc->spdifBDL_phys, CTL_BASE, 0x70);     /* BDL base */
 
771
      n = bcount;
 
772
      if (n > BDL_SIZE)
 
773
        n = BDL_SIZE;
 
774
 
 
775
      for (i = 0; i < n; i++)
 
776
        {
 
777
          devc->spdifBDL[i].addr =
 
778
            dmap->dmabuf_phys + (i * dmap->fragment_size);
 
779
          devc->spdifBDL[i].size = (dmap->fragment_size / 2);
 
780
          devc->spdifBDL[i].flags = 0xc000;     /* IOC interrupts */
 
781
          devc->spdif_frag_index[i] = i;
 
782
        }
 
783
      ich_OUTB (devc, n - 1, CTL_BASE, 0x75);   /* Set last valid
 
784
                                                 * descriptor */
 
785
      devc->spdif_currbuf = n % BDL_SIZE;
 
786
      devc->spdif_currfrag = n;
 
787
      if (devc->spdif_currfrag >= dmap->nfrags)
 
788
        devc->spdif_currfrag = 0;
 
789
 
 
790
      portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
791
      portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
792
 
 
793
      MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
794
 
 
795
      return 0;
 
796
    }
 
797
  /* else do PCM */
 
798
  ich_OUTB (devc, 0x02, CTL_BASE, 0x1b);        /* Reset */
 
799
  ich_OUTL (devc, devc->playBDL_phys, CTL_BASE, 0x10);  /* BDL base */
 
800
 
 
801
  speed = portc->speed;
 
802
  speed = (speed * 240) / intelpci_rate_tuning;
 
803
  ac97_playrate (&devc->ac97devc, speed);
 
804
 
 
805
  /* Handle 4/6 channel output on 7012 */
 
806
  if (devc->model == SIS_7012)
 
807
    {
 
808
      tmp = ich_INL (devc, CTL_BASE, 0x30);
 
809
 
 
810
      /* set default to 2 channel mode */
 
811
      ich_OUTB (devc, ich_INB (devc, CTL_BASE, 0x2c) & 0x3f, CTL_BASE, 0x2c);
 
812
 
 
813
      if ((portc->channels == 4) && (tmp & (1 << 20)))
 
814
        ich_OUTB (devc, (ich_INB (devc, CTL_BASE, 0x2c) & 0x3f) | 0x40,
 
815
                  CTL_BASE, 0x2c);
 
816
 
 
817
      if ((portc->channels == 6) && (tmp & (1 << 21)))
 
818
        ich_OUTB (devc, (ich_INB (devc, CTL_BASE, 0x2c) & 0x3f) | 0x80,
 
819
                  CTL_BASE, 0x2c);
 
820
    }
 
821
  /* Handle 4/6 channel output on evrything other than ICH1 and SIS7012 */
 
822
  if ((devc->model != INTEL_ICH1) && (devc->model != SIS_7012))
 
823
    {
 
824
      tmp = ich_INL (devc, CTL_BASE, 0x30);
 
825
 
 
826
      /* set default to 2 channel mode */
 
827
      ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x2c) & 0x0cfffff, CTL_BASE,
 
828
                0x2c);
 
829
 
 
830
      if ((portc->channels == 4) && (tmp & (1 << 20)))
 
831
        ich_OUTL (devc,
 
832
                  (ich_INL (devc, CTL_BASE, 0x2c) & 0x00fffff) | 0x0100000,
 
833
                  CTL_BASE, 0x2c);
 
834
 
 
835
      if ((portc->channels == 6) && (tmp & (1 << 21)))
 
836
        ich_OUTL (devc,
 
837
                  (ich_INL (devc, CTL_BASE, 0x2c) & 0x00fffff) | 0x0200000,
 
838
                  CTL_BASE, 0x2c);
 
839
    }
 
840
  n = bcount;
 
841
  if (n > BDL_SIZE)
 
842
    n = BDL_SIZE;
 
843
 
 
844
  for (i = 0; i < n; i++)
 
845
    {
 
846
      devc->playBDL[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
 
847
 
 
848
      /* SiS7012 uses bytes, ICH uses samples */
 
849
      if (devc->model == SIS_7012)
 
850
        devc->playBDL[i].size = (dmap->fragment_size);
 
851
      else
 
852
        devc->playBDL[i].size = (dmap->fragment_size / 2);
 
853
 
 
854
      devc->playBDL[i].flags = 0xc000;  /* IOC interrupts */
 
855
      devc->play_frag_index[i] = i;
 
856
    }
 
857
  ich_OUTB (devc, n - 1, CTL_BASE, 0x15);       /* Set last valid descriptor */
 
858
 
 
859
 
 
860
  devc->play_currbuf = n % BDL_SIZE;
 
861
  devc->play_currfrag = n;
 
862
  if (devc->play_currfrag >= dmap->nfrags)
 
863
    devc->play_currfrag = 0;
 
864
 
 
865
  portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
 
866
  portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
 
867
  MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
 
868
  return 0;
 
869
}
 
870
 
 
871
static int
 
872
ich_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
 
873
{
 
874
  ich_devc *devc = audio_engines[dev]->devc;
 
875
  ich_portc *portc = audio_engines[dev]->portc;
 
876
  int p = 0, f = 0, c = 0;
 
877
  oss_native_word flags;
 
878
 
 
879
  MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
880
  if (direction == PCM_ENABLE_OUTPUT)
 
881
    {
 
882
      if (portc->port_type == DF_PCM)
 
883
        {
 
884
          f = ich_INB (devc, CTL_BASE, 0x14);   /* Current buffer */
 
885
 
 
886
          if (devc->model == SIS_7012)
 
887
            p = ich_INW (devc, CTL_BASE, 0x16); /* Position in current
 
888
                                                 * buffer */
 
889
          else
 
890
            p = ich_INW (devc, CTL_BASE, 0x18); /* Position in current
 
891
                                                 * buffer */
 
892
          c = devc->play_frag_index[f]; /* Current fragment */
 
893
 
 
894
          if (devc->model == SIS_7012)
 
895
            p = dmap->fragment_size - (p);      /* Remaining bytes */
 
896
          else
 
897
            p = dmap->fragment_size - (p * 2);  /* Remaining bytes */
 
898
        }
 
899
      if ((portc->port_type == DF_SPDIF) && (devc->model == NVIDIA_NFORCE2))
 
900
        {
 
901
          f = ich_INB (devc, CTL_BASE, 0x74);   /* Current buffer */
 
902
          p = ich_INW (devc, CTL_BASE, 0x78);   /* Position in current
 
903
                                                 * buffer */
 
904
          c = devc->play_frag_index[f]; /* Current fragment */
 
905
          p = dmap->fragment_size - (p * 2);    /* Remaining bytes */
 
906
        }
 
907
    }
 
908
  /*
 
909
   * Handle input
 
910
   */
 
911
  if (direction == PCM_ENABLE_INPUT)
 
912
    {
 
913
 
 
914
      f = ich_INB (devc, CTL_BASE, 0x04);       /* Current buffer */
 
915
 
 
916
      if (devc->model == SIS_7012)
 
917
        p = ich_INW (devc, CTL_BASE, 0x06);     /* Position in current
 
918
                                                 * buffer */
 
919
      else
 
920
        p = ich_INW (devc, CTL_BASE, 0x08);     /* Position in current
 
921
                                                 * buffer */
 
922
      c = devc->rec_frag_index[f];      /* Current fragment */
 
923
 
 
924
      if (devc->model == SIS_7012)
 
925
        p = dmap->fragment_size - (p);  /* Remaining bytes */
 
926
      else
 
927
        p = dmap->fragment_size - (p * 2);      /* Remaining bytes */
 
928
    }
 
929
  MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
930
  return p + c * dmap->fragment_size;
 
931
}
 
932
 
 
933
#if 0
 
934
static int
 
935
ich_calibrate_speed (int dev, int nominal_speed, int true_speed)
 
936
{
 
937
  unsigned int fix;
 
938
  DDB (smn_err (CE_CONT,
 
939
                "ich_calibrate_speed(%d, %d, %d)\n", dev, nominal_speed,
 
940
                true_speed));
 
941
 
 
942
  fix = ((240 * true_speed) + nominal_speed / 2) / nominal_speed;
 
943
  DDB (cmn_err (CE_NOTE, "intelpci_rate_tuning = %d\n", fix));
 
944
  if (fix > 1)
 
945
    intelpci_rate_tuning = fix;
 
946
 
 
947
  return 0;
 
948
}
 
949
#endif
 
950
 
 
951
static const audiodrv_t ich_audio_driver = {
 
952
  ich_audio_open,
 
953
  ich_audio_close,
 
954
  ich_audio_output_block,
 
955
  ich_audio_start_input,
 
956
  ich_audio_ioctl,
 
957
  ich_audio_prepare_for_input,
 
958
  ich_audio_prepare_for_output,
 
959
  ich_audio_reset,
 
960
  NULL,
 
961
  NULL,
 
962
  ich_audio_reset_input,
 
963
  ich_audio_reset_output,
 
964
  ich_audio_trigger,
 
965
  ich_audio_set_rate,
 
966
  ich_audio_set_format,
 
967
  ich_audio_set_channels,
 
968
  NULL,
 
969
  NULL,
 
970
  NULL,                         /* ich_check_input, */
 
971
  NULL,                         /* ich_check_output, */
 
972
  NULL,                         /* ich_alloc_buffer, */
 
973
  NULL,                         /* ich_free_buffer, */
 
974
  NULL,
 
975
  NULL,
 
976
  ich_get_buffer_pointer,
 
977
  NULL                          /* ich_calibrate_speed */
 
978
};
 
979
 
 
980
static int
 
981
ich_init (ich_devc * devc)
 
982
{
 
983
  int my_mixer, adev, opts;
 
984
  int i, max_port;
 
985
  unsigned int reg;
 
986
  int first_dev = 0;
 
987
  oss_native_word phaddr;
 
988
 
 
989
  /* ACLink on, warm reset */
 
990
  reg = ich_INL (devc, CTL_BASE, 0x2c);
 
991
  if ((reg & 0x02) == 0)
 
992
    reg |= 2;
 
993
  else
 
994
    reg |= 4;
 
995
  reg &= ~8;
 
996
  ich_OUTL (devc, reg, CTL_BASE, 0x2c);
 
997
  oss_udelay (500);
 
998
  if (devc->model == SIS_7012)
 
999
    {
 
1000
      reg |= 0x10;
 
1001
      ich_OUTL (devc, reg, CTL_BASE, 0x2c);
 
1002
      oss_udelay (500);
 
1003
    }
 
1004
  /* disable interrupts */
 
1005
  ich_OUTB (devc, 0x00, CTL_BASE, 0x0b);
 
1006
  ich_OUTB (devc, 0x00, CTL_BASE, 0x1b);
 
1007
  ich_OUTB (devc, 0x00, CTL_BASE, 0x2b);
 
1008
  ich_OUTB (devc, 0x00, CTL_BASE, 0x7b);
 
1009
 
 
1010
  devc->bdlBuffer =
 
1011
    CONTIG_MALLOC (devc->osdev, 4 * 32 * 32, MEMLIMIT_32BITS, &phaddr, devc->bldbuf_dma_handle);
 
1012
  if (devc->bdlBuffer == NULL)
 
1013
    {
 
1014
      cmn_err (CE_WARN, "Failed to allocate BDL\n");
 
1015
      return 0;
 
1016
    }
 
1017
  devc->playBDL = (bdl_t *) devc->bdlBuffer;
 
1018
  devc->playBDL_phys = phaddr;
 
1019
  devc->recBDL = (bdl_t *) (devc->bdlBuffer + (32 * 32));
 
1020
  devc->recBDL_phys = phaddr + 32 * 32;
 
1021
  devc->spdifBDL = (bdl_t *) (devc->bdlBuffer + (2 * 32 * 32));
 
1022
  devc->spdifBDL_phys = phaddr + 2 * 32 * 32;
 
1023
 
 
1024
  /*
 
1025
   * Init mixer
 
1026
   */
 
1027
  my_mixer =
 
1028
    ac97_install_full (&devc->ac97devc, "ICH AC97 Mixer", ac97_read, ac97_write,
 
1029
                       devc, devc->osdev, devc->inverted_amplifier |
 
1030
                       (ich_jacksense?AC97_FORCE_SENSE:0));
 
1031
  if (my_mixer == -1)
 
1032
    {
 
1033
      cmn_err (CE_WARN, "AC97 mixer installation failed\n");
 
1034
      return 0;                 /* No mixer */
 
1035
    }
 
1036
 
 
1037
  devc->mixer_dev = my_mixer;
 
1038
  mixer_devs[my_mixer]->priority = 10;  /* Known motherboard device */
 
1039
 
 
1040
  /* enable S/PDIF */
 
1041
  devc->ac97devc.spdif_slot = SPDIF_SLOT34;
 
1042
  ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 1);
 
1043
 
 
1044
  /* enable variable rate mode */
 
1045
  ac97_write (devc, 0x2a, ac97_read (devc, 0x2a) | 9);
 
1046
  if (!(ac97_read (devc, 0x2a) & 1))
 
1047
    DDB (cmn_err (CE_NOTE, "VRA not supported...using GRC\n"));
 
1048
 
 
1049
  /* Enable SPDIF for SiS 7012 */
 
1050
  if (devc->model == SIS_7012)
 
1051
    {
 
1052
      ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x2c) | (1 << 10), CTL_BASE,
 
1053
                0x2c);
 
1054
      ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x4c) | 1, CTL_BASE, 0x4c);
 
1055
    }
 
1056
  if (devc->model == NVIDIA_NFORCE2)
 
1057
    max_port = 3;
 
1058
  else
 
1059
    max_port = 2;
 
1060
 
 
1061
  for (i = 0; i < max_port; i++)
 
1062
    {
 
1063
      ich_portc *portc = &devc->portc[i];
 
1064
      char tmp_name[100];
 
1065
      int port_fmt = DF_PCM;
 
1066
      int formats = AFMT_S16_LE | AFMT_AC3;
 
1067
      char *devfile_name = "";
 
1068
 
 
1069
      strcpy (tmp_name, devc->chip_name);
 
1070
      opts = ADEV_AUTOMODE | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_COLD;
 
1071
 
 
1072
      if (!ac97_varrate (&devc->ac97devc))
 
1073
        {
 
1074
          opts |= ADEV_FIXEDRATE;
 
1075
        }
 
1076
      if (i == 0)
 
1077
        {
 
1078
          strcpy (tmp_name, devc->chip_name);
 
1079
          opts |= ADEV_DUPLEX;
 
1080
        }
 
1081
      if (i == 1)
 
1082
        {
 
1083
          strcpy (tmp_name, devc->chip_name);
 
1084
          opts |= ADEV_DUPLEX | ADEV_SHADOW;
 
1085
        }
 
1086
      if (i == 2)
 
1087
        {
 
1088
          sprintf (tmp_name, "%s S/PDIF out", devc->chip_name);
 
1089
          opts |= ADEV_NOINPUT | ADEV_SPECIAL | ADEV_FIXEDRATE;
 
1090
          port_fmt = DF_SPDIF;
 
1091
          devfile_name = "spdout";
 
1092
        }
 
1093
      if ((adev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
 
1094
                                        devc->osdev,
 
1095
                                        devc->osdev,
 
1096
                                        tmp_name,
 
1097
                                        &ich_audio_driver,
 
1098
                                        sizeof (audiodrv_t),
 
1099
                                        opts, formats, devc, -1,
 
1100
                                        devfile_name)) < 0)
 
1101
        {
 
1102
          adev = -1;
 
1103
          return 0;
 
1104
        }
 
1105
      else
 
1106
        {
 
1107
          if (i == 0)
 
1108
            first_dev = adev;
 
1109
          audio_engines[adev]->portc = portc;
 
1110
          audio_engines[adev]->rate_source = first_dev;
 
1111
          audio_engines[adev]->mixer_dev = my_mixer;
 
1112
          audio_engines[adev]->max_block = 64 * 1024;
 
1113
 
 
1114
          /* fix a timeout bug with Nforce2 */
 
1115
          if ((devc->model == NVIDIA_NFORCE) ||
 
1116
              (devc->model == NVIDIA_NFORCE2))
 
1117
            {
 
1118
              audio_engines[adev]->min_block = 4096;
 
1119
              audio_engines[adev]->max_block = 4096;
 
1120
            }
 
1121
 
 
1122
          audio_engines[adev]->min_rate =
 
1123
            (opts & ADEV_FIXEDRATE) ? 48000 : 5000;
 
1124
          audio_engines[adev]->max_rate = 48000;
 
1125
          audio_engines[adev]->caps |= PCM_CAP_FREERATE;
 
1126
          audio_engines[adev]->min_channels = 2;
 
1127
          audio_engines[adev]->max_channels = 6;
 
1128
          portc->open_mode = 0;
 
1129
          portc->audio_enabled = 0;
 
1130
          portc->audiodev = adev;
 
1131
          portc->port_type = port_fmt;
 
1132
          if (audio_engines[adev]->flags & ADEV_FIXEDRATE)
 
1133
            audio_engines[adev]->fixed_rate = 48000;
 
1134
#ifdef CONFIG_OSS_VMIX
 
1135
          if (i == 0)
 
1136
             vmix_attach_audiodev(devc->osdev, adev, -1, 0);
 
1137
#endif
 
1138
        }
 
1139
    }
 
1140
  return 1;
 
1141
}
 
1142
 
 
1143
int
 
1144
oss_ich_attach (oss_device_t * osdev)
 
1145
{
 
1146
  unsigned char pci_irq_line, pci_revision /* , pci_latency */ ;
 
1147
  unsigned short pci_command, vendor, device, sub_vendor, sub_id;
 
1148
  unsigned int pci_ioaddr0, pci_ioaddr1;
 
1149
  unsigned int dw;
 
1150
 
 
1151
  ich_devc *devc;
 
1152
 
 
1153
  if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
 
1154
    {
 
1155
      cmn_err (CE_WARN, "Out of memory\n");
 
1156
      return 0;
 
1157
    }
 
1158
 
 
1159
  devc->osdev = osdev;
 
1160
  osdev->devc = devc;
 
1161
  devc->open_mode = 0;
 
1162
 
 
1163
  pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
 
1164
  pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
 
1165
 
 
1166
  DDB (cmn_err
 
1167
       (CE_CONT, "oss_ich_attach(Vendor %x, device %x)\n", vendor, device));
 
1168
 
 
1169
#if 0
 
1170
  // This check is not necessary because the kernel has already checked
 
1171
  // the vendor&device ID
 
1172
 
 
1173
  if ((vendor != INTEL_VENDOR_ID && vendor != SIS_VENDOR_ID &&
 
1174
       vendor != NVIDIA_VENDOR_ID && vendor != AMD_VENDOR_ID) ||
 
1175
      (device != INTEL_DEVICE_ICH1 && device != INTEL_DEVICE_ICH1R1 &&
 
1176
       device != INTEL_DEVICE_ICH1R2 && device != INTEL_DEVICE_ICH2 &&
 
1177
       device != INTEL_DEVICE_ICH3 && device != INTEL_DEVICE_ICH4 &&
 
1178
       device != INTEL_DEVICE_ICH5 && device != INTEL_DEVICE_ESB &&
 
1179
       device != INTEL_DEVICE_ICH6 && device != INTEL_DEVICE_ICH7 &&
 
1180
       device != SIS_DEVICE_7012 &&
 
1181
       device != AMD_DEVICE_768 && device != AMD_DEVICE_8111 &&
 
1182
       device != NVIDIA_DEVICE_NFORCE && device != NVIDIA_DEVICE_NFORCE2 &&
 
1183
       device != NVIDIA_DEVICE_NFORCE3 && device != NVIDIA_DEVICE_CK8S &&
 
1184
       device != NVIDIA_DEVICE_NFORCE4 && device != NVIDIA_DEVICE_CK8 &&
 
1185
       device != NVIDIA_DEVICE_MCP51 && device != NVIDIA_DEVICE_MCP4
 
1186
       ))
 
1187
    {
 
1188
      cmn_err (CE_WARN, "Hardware not recognized (vendor=%x, dev=%x)\n",
 
1189
               vendor, device);
 
1190
      return 0;
 
1191
    }
 
1192
#endif
 
1193
 
 
1194
  pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor);
 
1195
  pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &sub_id);
 
1196
  dw = (sub_id << 16) | sub_vendor;
 
1197
 
 
1198
  switch (dw)
 
1199
    {
 
1200
       case 0x202f161f: /* Gateway 7326GZ */
 
1201
       case 0x203a161f: /* Gateway 4028GZ or 4542GZ */
 
1202
       case 0x203e161f: /* Gateway 3520GZ/M210 */
 
1203
       case 0x204c161f: /* Kvazar-Micro Senator 3592XT */
 
1204
       case 0x8144104d: /* Sony VAIO PCG-TR* */
 
1205
       case 0x8197104d: /* Sony S1XP */
 
1206
       case 0x81c0104d: /* Sony VAIO type T */
 
1207
       case 0x81c5104d: /* Sony VAIO VGN B1VP/B1XP */
 
1208
       case 0x3089103c: /* Compaq Presario B3800 */
 
1209
       case 0x309a103c: /* HP Compaq nx4300 */
 
1210
       case 0x82131033: /* NEC VersaPro VJ10F/BH */
 
1211
       case 0x82be1033: /* NEC VersaPro VJ12F/CH */
 
1212
         devc->inverted_amplifier = AC97_INVERTED;
 
1213
         cmn_err (CE_CONT, "An inverted amplifier has been autodetected\n");
 
1214
         break;
 
1215
       default:
 
1216
         devc->inverted_amplifier = 0;
 
1217
         break;
 
1218
    }
 
1219
 
 
1220
  pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
 
1221
  pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
 
1222
  pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
 
1223
  pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr0);
 
1224
  pci_read_config_dword (osdev, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
 
1225
 
 
1226
  switch (device)
 
1227
    {
 
1228
    case INTEL_DEVICE_ICH1:
 
1229
      devc->model = INTEL_ICH1;
 
1230
      devc->chip_name = "Intel ICH (2415)";
 
1231
      break;
 
1232
    case INTEL_DEVICE_ICH1R1:
 
1233
      devc->model = INTEL_ICH1;
 
1234
      devc->chip_name = "Intel ICHR1(2425)";
 
1235
      break;
 
1236
    case INTEL_DEVICE_ICH1R2:
 
1237
      devc->model = INTEL_ICH1;
 
1238
      devc->chip_name = "Intel ICHR2 (7195)";
 
1239
      break;
 
1240
    case INTEL_DEVICE_ICH2:
 
1241
      devc->model = INTEL_ICH1;
 
1242
      devc->chip_name = "Intel ICH2 (2445)";
 
1243
      break;
 
1244
    case INTEL_DEVICE_ICH3:
 
1245
      devc->model = INTEL_ICH3;
 
1246
      devc->chip_name = "Intel ICH3 (2485)";
 
1247
      break;
 
1248
    case INTEL_DEVICE_ICH4:
 
1249
      devc->model = INTEL_ICH4;
 
1250
      devc->chip_name = "Intel ICH4 (24C5)";
 
1251
      break;
 
1252
    case INTEL_DEVICE_ICH5:
 
1253
      devc->model = INTEL_ICH4;
 
1254
      devc->chip_name = "Intel ICH5 (24D5)";
 
1255
      break;
 
1256
    case INTEL_DEVICE_ICH6:
 
1257
      devc->model = INTEL_ICH4;
 
1258
      devc->chip_name = "Intel ICH6 (266E)";
 
1259
      break;
 
1260
    case INTEL_DEVICE_ICH7:
 
1261
      devc->model = INTEL_ICH4;
 
1262
      devc->chip_name = "Intel ICH7 (27DE)";
 
1263
      break;
 
1264
    case INTEL_DEVICE_ESB:
 
1265
      devc->model = INTEL_ICH4;
 
1266
      devc->chip_name = "Intel ICH5 (25a6)";
 
1267
      break;
 
1268
    case SIS_DEVICE_7012:
 
1269
      devc->model = SIS_7012;
 
1270
      devc->chip_name = "SiS 7012";
 
1271
      break;
 
1272
    case NVIDIA_DEVICE_NFORCE:
 
1273
      devc->model = NVIDIA_NFORCE;
 
1274
      devc->chip_name = "Nvidia nForce";
 
1275
      break;
 
1276
    case NVIDIA_DEVICE_NFORCE2:
 
1277
      devc->model = NVIDIA_NFORCE2;
 
1278
      devc->chip_name = "Nvidia nForce2";
 
1279
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1280
      dw |= 0x1000000;
 
1281
      pci_write_config_dword (osdev, 0x4c, dw);
 
1282
      break;
 
1283
    case NVIDIA_DEVICE_NFORCE3:
 
1284
      devc->model = NVIDIA_NFORCE2;
 
1285
      devc->chip_name = "Nvidia nForce3";
 
1286
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1287
      dw |= 0x1000000;
 
1288
      pci_write_config_dword (osdev, 0x4c, dw);
 
1289
      break;
 
1290
    case NVIDIA_DEVICE_CK8S:
 
1291
      devc->model = NVIDIA_NFORCE2;
 
1292
      devc->chip_name = "Nvidia CK8S";
 
1293
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1294
      dw |= 0x1000000;
 
1295
      pci_write_config_dword (osdev, 0x4c, dw);
 
1296
      break;
 
1297
    case NVIDIA_DEVICE_NFORCE4:
 
1298
      devc->model = NVIDIA_NFORCE2;
 
1299
      devc->chip_name = "Nvidia nForce4";
 
1300
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1301
      dw |= 0x1000000;
 
1302
      pci_write_config_dword (osdev, 0x4c, dw);
 
1303
      break;
 
1304
    case NVIDIA_DEVICE_CK8:
 
1305
      devc->model = NVIDIA_NFORCE2;
 
1306
      devc->chip_name = "Nvidia CK8";
 
1307
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1308
      dw |= 0x1000000;
 
1309
      pci_write_config_dword (osdev, 0x4c, dw);
 
1310
      break;
 
1311
    case NVIDIA_DEVICE_MCP51:
 
1312
      devc->model = NVIDIA_NFORCE2;
 
1313
      devc->chip_name = "Nvidia MCP51";
 
1314
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1315
      dw |= 0x1000000;
 
1316
      pci_write_config_dword (osdev, 0x4c, dw);
 
1317
      break;
 
1318
    case NVIDIA_DEVICE_MCP4:
 
1319
      devc->model = NVIDIA_NFORCE2;
 
1320
      devc->chip_name = "Nvidia MCP4";
 
1321
      pci_read_config_dword (osdev, 0x4c, &dw);
 
1322
      dw |= 0x1000000;
 
1323
      pci_write_config_dword (osdev, 0x4c, dw);
 
1324
      break;
 
1325
    case AMD_DEVICE_768:
 
1326
      devc->model = AMD_768;
 
1327
      devc->chip_name = "AMD 768";
 
1328
      break;
 
1329
    case AMD_DEVICE_8111:
 
1330
      devc->model = AMD_8111;
 
1331
      devc->chip_name = "AMD 8111";
 
1332
      break;
 
1333
    default:
 
1334
      devc->chip_name = "Unknown ICH chip";
 
1335
    }
 
1336
 
 
1337
  if (((pci_ioaddr1 == 0) || (intelpci_force_mmio)) &&
 
1338
      (devc->model == INTEL_ICH4))
 
1339
    {
 
1340
      unsigned int ioaddr;
 
1341
 
 
1342
      /* read bar2 and bar3 for getting mmap address */
 
1343
      pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_2, &ioaddr);
 
1344
      devc->ac97_membar_addr = ioaddr;
 
1345
      pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_3, &ioaddr);
 
1346
      devc->membar_addr = ioaddr;
 
1347
 
 
1348
      /* get virtual address */
 
1349
      devc->ac97_membar_virt =
 
1350
        (char *) MAP_PCI_MEM (devc->osdev, 2, devc->ac97_membar_addr, 512);
 
1351
      devc->membar_virt =
 
1352
        (char *) MAP_PCI_MEM (devc->osdev, 3, devc->membar_addr, 256);
 
1353
      devc->mem_mode = MMAP_MODE;
 
1354
    }
 
1355
  else
 
1356
    devc->mem_mode = IO_MODE;
 
1357
 
 
1358
  if (devc->mem_mode == IO_MODE)
 
1359
    {
 
1360
      if (devc->model == INTEL_ICH4)
 
1361
        {
 
1362
          /*
 
1363
           * enable the IOSE bit in 0x41 for legacy
 
1364
           * mode for ICH4/ICH5
 
1365
           */
 
1366
          pci_write_config_byte (osdev, 0x41, 1);
 
1367
 
 
1368
          /* Set the secondary codec ID */
 
1369
          pci_write_config_byte (osdev, 0x40, 0x39);
 
1370
        }
 
1371
      /* Remove I/O space marker in bit 0. */
 
1372
      devc->ac97_base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr0);
 
1373
      devc->base = MAP_PCI_IOADDR (devc->osdev, 1, pci_ioaddr1);
 
1374
      devc->ac97_base &= ~0xF;
 
1375
      devc->base &= ~0xF;
 
1376
    }
 
1377
  pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
 
1378
  pci_write_config_word (osdev, PCI_COMMAND, pci_command);
 
1379
 
 
1380
  devc->irq = pci_irq_line;
 
1381
 
 
1382
  if (devc->mem_mode != IO_MODE)
 
1383
    {
 
1384
      devc->base = devc->membar_addr;
 
1385
    }
 
1386
 
 
1387
  MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
 
1388
  MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
 
1389
 
 
1390
  oss_register_device (osdev, devc->chip_name);
 
1391
 
 
1392
  if (oss_register_interrupts (devc->osdev, 0, ichintr, NULL) < 0)
 
1393
    {
 
1394
      cmn_err (CE_WARN, "Unable to install interrupt handler\n");
 
1395
      return 0;
 
1396
    }
 
1397
 
 
1398
  return ich_init (devc);       /* Detected */
 
1399
}
 
1400
 
 
1401
int
 
1402
oss_ich_detach (oss_device_t * osdev)
 
1403
{
 
1404
  ich_devc *devc = (ich_devc *) osdev->devc;
 
1405
 
 
1406
  if (oss_disable_device (osdev) < 0)
 
1407
    return 0;
 
1408
 
 
1409
  /* disable interrupts */
 
1410
  ich_OUTB (devc, 0x00, CTL_BASE, 0x0b);
 
1411
  ich_OUTB (devc, 0x00, CTL_BASE, 0x1b);
 
1412
  ich_OUTB (devc, 0x00, CTL_BASE, 0x2b);
 
1413
  ich_OUTB (devc, 0x00, CTL_BASE, 0x7b);
 
1414
  oss_unregister_interrupts (devc->osdev);
 
1415
 
 
1416
  /* disable S/PDIF */
 
1417
  if (devc->mixer_dev)
 
1418
    ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 0);
 
1419
 
 
1420
  if (devc->bdlBuffer)
 
1421
    CONTIG_FREE (devc->osdev, devc->bdlBuffer, 4 * 32 * 32, devc->bldbuf_dma_handle);
 
1422
  devc->bdlBuffer = NULL;
 
1423
 
 
1424
  MUTEX_CLEANUP (devc->mutex);
 
1425
  MUTEX_CLEANUP (devc->low_mutex);
 
1426
 
 
1427
  if ((devc->mem_mode == MMAP_MODE) && (devc->membar_addr != 0))
 
1428
    {
 
1429
      UNMAP_PCI_MEM (devc->osdev, 2, devc->ac97_membar_addr,
 
1430
                     devc->ac97_membar_virt, 512);
 
1431
      UNMAP_PCI_MEM (devc->osdev, 3, devc->membar_addr, devc->membar_virt,
 
1432
                     256);
 
1433
      devc->membar_addr = 0;
 
1434
      devc->ac97_membar_addr = 0;
 
1435
    }
 
1436
  else
 
1437
    {
 
1438
      UNMAP_PCI_IOADDR (devc->osdev, 0);
 
1439
      UNMAP_PCI_IOADDR (devc->osdev, 1);
 
1440
    }
 
1441
  oss_unregister_device (osdev);
 
1442
  return 1;
 
1443
}
 
1444
 
 
1445
#ifdef OSS_POWER_MANAGE
 
1446
/* Not activated in .config at this moment */
 
1447
int
 
1448
oss_ich_power (oss_device_t *osdev, int component, int level)
 
1449
{
 
1450
// cmn_err(CE_CONT, "oss_ich_power(%d, %d)\n", component, level);
 
1451
 
 
1452
        return 0; /* Failed */
 
1453
}
 
1454
#endif
 
1455
 
 
1456
#ifdef OSS_SUSPEND_RESUME
 
1457
int
 
1458
oss_ich_suspend(oss_device_t *osdev)
 
1459
{
 
1460
//cmn_err(CE_CONT, "oss_ich_suspend()\n");
 
1461
        return 0; /* Failed */
 
1462
}
 
1463
 
 
1464
int
 
1465
oss_ich_resume(oss_device_t *osdev)
 
1466
{
 
1467
//cmn_err(CE_CONT, "oss_ich_resume()\n");
 
1468
        return 0; /* Failed */
 
1469
}
 
1470
#endif