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

« back to all changes in this revision

Viewing changes to kernel/drv/oss_envy24ht/envy24ht_aureon.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: Low level routines for Terrate Aureon 7.1 family
 
3
 */
 
4
/*
 
5
 *
 
6
 * This file is part of Open Sound System.
 
7
 *
 
8
 * Copyright (C) 4Front Technologies 1996-2008.
 
9
 *
 
10
 * This this source file is released under GPL v2 license (no other versions).
 
11
 * See the COPYING file included in the main directory of this source
 
12
 * distribution for the license terms and conditions.
 
13
 *
 
14
 */
 
15
 
 
16
#include "oss_envy24ht_cfg.h"
 
17
 
 
18
#define IN
 
19
#define OUT
 
20
#define UCHAR unsigned char
 
21
#define PUCHAR UCHAR*
 
22
#define BYTE unsigned char
 
23
#define PBYTE BYTE*
 
24
#define BOOLEAN unsigned char
 
25
#define ULONG unsigned int
 
26
#define PULONG ULONG*
 
27
#define USHORT unsigned short
 
28
#define PUSHORT USHORT*
 
29
 
 
30
#define WORD USHORT
 
31
#define PWORD PUSHORT
 
32
 
 
33
/*
 
34
 * Default levels 
 
35
 */
 
36
#define WM_OUT_DEFAULT          0x7F
 
37
#define WM_OUT_MAX              0x7F
 
38
#define WM_INP_DEFAULT          0x0C    /* for 0dB */
 
39
#define AC97_INP_DEFAULT        0x1f1f
 
40
#define AC97_INP_MAX        0x1f
 
41
 
 
42
#define REG_CCS         1
 
43
#define REG_MT          2
 
44
 
 
45
#define WM_MASTER_MODE_CNTRL 0
 
46
 
 
47
/* List of the WKN CCS Control Registers. */
 
48
#define WKN_CONTROL_REG         0x00
 
49
#define WKN_INT_MASK_REG        0x01
 
50
#define WKN_INT_STAT_REG        0x02
 
51
#define WKN_DMA_INT        0x10
 
52
#define WKN_UART_RECV      0x80
 
53
#define WKN_UART_TRAN      0x20
 
54
 
 
55
/* #define WKN_INDEX_REG           0x03 */
 
56
 
 
57
#define WKN_SYS_CONFIG          0x04
 
58
#define WKN_49MHZ           0x40
 
59
#define WKN_ACLINK_CONFIG       0x05
 
60
#define CODEC_AKM           0x80
 
61
 
 
62
#define WKN_I2S_CONFIG          0x06
 
63
#define WKN_SPDIF_CONFIG        0x07
 
64
 
 
65
#define SPDIF_ENABLE_MASK       0x00010000
 
66
 
 
67
/* #define WKN_AC97_INDEX          0x08 */
 
68
/* #define WKN_AC97_CMDSTAT        0x09 */
 
69
#define WKN_TX_QUE              0x0A
 
70
#define WKN_RX_QUE              0x0B
 
71
 
 
72
#define WKN_MIDI_PORT1_DATA_REG 0x0C
 
73
#define WKN_MIDI_PORT1_CMD_REG  0x0D
 
74
#define WKN_NMI_EXTSTAT_REG     0x0E
 
75
 
 
76
#define WKN_I2C_DEVADDR           0x10
 
77
#define WKN_I2C_AKM          0x20
 
78
#define WKN_I2C_WRITE          0x01
 
79
#define WKN_I2C_READ           0x00
 
80
#define WKN_I2C_BYTEADDR          0x11
 
81
#define WKN_I2C_DATA              0x12
 
82
#define WKN_I2C_STATUS            0x13
 
83
#define WKN_I2C_BUSY           0x01
 
84
#define WKN_GPIO_DATA0           0x14
 
85
#define WKN_GPIO_DATA1           0x15
 
86
#define WKN_GPIO_DATA2           0x1E
 
87
#define WKN_GPIO_WRT_MASK0       0x16
 
88
#define WKN_GPIO_WRT_MASK1       0x17
 
89
#define WKN_GPIO_WRT_MASK2       0x1F
 
90
#define WKN_GPIO_DIR0           0x18
 
91
#define WKN_GPIO_DIR1           0x19
 
92
#define WKN_GPIO_DIR2           0x1A
 
93
#define WKN_GPIO_DATA16         0x1E
 
94
#define WKN_GPIO_WRT_MASK16     0x1F
 
95
 
 
96
#define GPIO_DATA_ADR_MASK      0x000000FF
 
97
#define GPIO_LD_DATA_H_MASK     0x00000100
 
98
#define GPIO_LD_DATA_L_MASK     0x00000200
 
99
#define GPIO_LD_ADR_MASK        0x00000400
 
100
#define GPIO_GO_MASK            0x00000800
 
101
#define GPIO_WM8770_CS_MASK     0x00001000
 
102
#define GPIO_INT_REST_MASK      0x00002000
 
103
#define GPIO_REMOTE_MASK        0x00004000
 
104
#define GPIO_HEADPHONE_MASK     0x00004000
 
105
#define GPIO_DIGITAL_SEL        0x00008000
 
106
#define GPIO_AC97_RESET_MASK    0x00010000
 
107
#define GPIO_SDA_TX_MASK        0x00020000
 
108
#define GPIO_SDA_MASK           0x00040000
 
109
#define GPIO_SCL_MASK           0x00080000
 
110
#define GPIO_WM8770_RS_MASK     0x00100000
 
111
#define GPIO_CS8415_CDTO_MASK   0x00200000
 
112
#define GPIO_CS8415_CS_MASK     0x00400000
 
113
 
 
114
#define WM_DAC1_VOL_CNTRL           0x00
 
115
#define WM_DAC2_VOL_CNTRL           0x02
 
116
#define WM_DAC3_VOL_CNTRL           0x04
 
117
#define WM_DAC4_VOL_CNTRL           0x06
 
118
#define WM_MASTER_VOL_CNTRL         0x08
 
119
#define WM_POWER_CNTRL              0x18
 
120
#define WM_ADC_GAIN_CNTRL           0x19
 
121
#define WM_ADC_INPUT_MX             0x1B
 
122
#define WM_OUT12_SELECT             0x1C
 
123
#define WM_OUT34_SELECT             0x1D
 
124
 
 
125
#define CS_CONTROL_1                0x01
 
126
#define CS_CONTROL_2                0x02
 
127
#define CS_CLK_SRC_CNTRL            0x04
 
128
#define CS_SER_OUT_FORMAT           0x06
 
129
 
 
130
#define MT_SAMPLE_RATE_REG              0x01
 
131
#define MT_48KHZ                 0x0
 
132
#define MT_24KHZ                 0x01
 
133
#define MT_12KHZ                 0x02
 
134
#define MT_9p6KHZ               0x03
 
135
#define MT_32KHZ                 0x04
 
136
#define MT_16KHZ                 0x05
 
137
#define MT_8KHZ                 0x06
 
138
#define MT_96KHZ                 0x07
 
139
#define MT_192KHZ                0x0E
 
140
#define MT_64KHZ                 0x0F
 
141
#define MT_44p1KHZ               0x08
 
142
#define MT_22p05KHZ              0x09
 
143
#define MT_11p025KHZ             0x0A
 
144
#define MT_88p2KHZ               0x0B
 
145
#define MT_176p4KHZ              0x0C
 
146
 
 
147
#define MT_DATA_FORMAT_REG              0x02
 
148
#define MT_128X                  0x08
 
149
#define MT_INTR_MASK_REG         0x03
 
150
 
 
151
#define SRC_PDMA        0x00
 
152
#define SRC_PSDIN0_L    0x02
 
153
#define SRC_PSDIN0_R    0x03
 
154
#define SRC_SPDIN_L     0x06
 
155
#define SRC_SPDIN_R     0x07
 
156
#define SRC_MASK        0x07
 
157
 
 
158
static const UCHAR gWMRegister[] = { WM_DAC1_VOL_CNTRL,
 
159
  WM_DAC1_VOL_CNTRL + 1,
 
160
  WM_DAC2_VOL_CNTRL,
 
161
  WM_DAC2_VOL_CNTRL + 1,
 
162
  WM_DAC3_VOL_CNTRL,
 
163
  WM_DAC3_VOL_CNTRL + 1,
 
164
  WM_DAC4_VOL_CNTRL,
 
165
  WM_DAC4_VOL_CNTRL + 1,
 
166
  WM_MASTER_VOL_CNTRL,
 
167
  WM_MASTER_VOL_CNTRL + 1,
 
168
  WM_ADC_GAIN_CNTRL,
 
169
  WM_ADC_GAIN_CNTRL + 1
 
170
};
 
171
 
 
172
#define AC97_IDXREG_RESET           0x00
 
173
#define AC97_IDXREG_STEREO_OUT      0x02
 
174
#define AC97_IDXREG_MONO_OUT        0x06
 
175
#define AC97_IDXREG_PCBEEP          0x0A
 
176
#define AC97_IDXREG_PHONE           0x0C
 
177
#define AC97_IDXREG_MIC_IN          0x0E
 
178
#define AC97_IDXREG_LINE_IN         0x10
 
179
#define AC97_IDXREG_CD_IN           0x12
 
180
#define AC97_IDXREG_VIDEO_IN        0x14
 
181
#define AC97_IDXREG_AUX_IN          0x16
 
182
#define AC97_IDXREG_PCM_OUT         0x18
 
183
#define AC97_IDXREG_RECORD_SELECT   0x1A
 
184
#define AC97_IDXREG_RECORD_GAIN     0x1C
 
185
#define AC97_IDXREG_GEN_PURPOSE     0x20
 
186
#define AC97_IDXREG_POWER_DOWN      0x26
 
187
#define AC97_IDXREG_TEST_CONTROL    0x5A
 
188
#define AC97_IDXREG_VENDOR_RESV     0x7A
 
189
#define AC97_IDXREG_VENDOR_ID1      0x7C
 
190
#define AC97_IDXREG_VENDOR_ID2      0x7E
 
191
/* AC97 register - AC97_IDXREG_RECORD_SELECT */
 
192
#define AC97_REC_SELECT_MIC         0x0000
 
193
#define AC97_REC_SELECT_LINEIN      0x0404
 
194
#define AC97_REC_SELECT_ST_MIX      0x0505
 
195
 
 
196
/*                         
 
197
 * List of the Channel IDs
 
198
 */
 
199
#define CH_MASTER_LEFT            ((OUT_MASTER<<16)|CH_LEFT)
 
200
#define CH_MASTER_RIGHT           ((OUT_MASTER<<16)|CH_RIGHT)
 
201
#define CH_MASTER_BOTH            ((OUT_MASTER<<16)|CH_BOTH)
 
202
 
 
203
#define CH_OUT12_LEFT             ((OUT_12<<16)|CH_LEFT)
 
204
#define CH_OUT12_RIGHT            ((OUT_12<<16)|CH_RIGHT)
 
205
#define CH_OUT12_BOTH             ((OUT_12<<16)|CH_BOTH)
 
206
#define CH_OUT34_LEFT             ((OUT_34<<16)|CH_LEFT)
 
207
#define CH_OUT34_RIGHT            ((OUT_34<<16)|CH_RIGHT)
 
208
#define CH_OUT34_BOTH             ((OUT_34<<16)|CH_BOTH)
 
209
#define CH_OUT56_LEFT             ((OUT_56<<16)|CH_LEFT)
 
210
#define CH_OUT56_RIGHT            ((OUT_56<<16)|CH_RIGHT)
 
211
#define CH_OUT56_BOTH             ((OUT_56<<16)|CH_BOTH)
 
212
#define CH_OUT78_LEFT             ((OUT_78<<16)|CH_LEFT)
 
213
#define CH_OUT78_RIGHT            ((OUT_78<<16)|CH_RIGHT)
 
214
#define CH_OUT78_BOTH             ((OUT_78<<16)|CH_BOTH)
 
215
 
 
216
#define CH_IN12_LEFT              ((IN_12<<16)|CH_LEFT)
 
217
#define CH_IN12_RIGHT             ((IN_12<<16)|CH_RIGHT)
 
218
#define CH_IN12_BOTH              ((IN_12<<16)|CH_BOTH)
 
219
 
 
220
#define CH_FRONT_BOTH             CH_OUT12_BOTH
 
221
#define CH_REAR_BOTH              CH_OUT34_BOTH
 
222
#define CH_CENTER                 CH_OUT56_LEFT
 
223
#define CH_LFE                    CH_OUT56_RIGHT
 
224
#define CH_BS_BOTH                CH_OUT78_BOTH
 
225
 
 
226
#define MAX_VOLUME 0x7F
 
227
#define MIN_VOLUME 0x00
 
228
 
 
229
#define MAX_GAIN   0x1F
 
230
 
 
231
#define MT_PLAY_REC_UNDOVR         0x01A
 
232
#define MT_INTR_STATUS_REG         0x00
 
233
#define MT_INTR_MASK_REG           0x03
 
234
#define MT_SPDIF_REG                 0x3C
 
235
 
 
236
/* List of AC97 inputs */
 
237
#define AC97_CD         0
 
238
#define AC97_AUX        1
 
239
#define AC97_LINE       2
 
240
#define AC97_MIC        3
 
241
#define AC97_PHONO      4
 
242
#define AC97_LINE2      5
 
243
#define AC97_COUNT      6       /* Must match devc->m_AC97Volume definition in envy24ht.h */
 
244
 
 
245
/* Channel def */
 
246
#define CH_LEFT    0x00000001
 
247
#define CH_RIGHT   0x00000002
 
248
#define CH_BOTH    (CH_LEFT|CH_RIGHT)
 
249
#define CH_NOP     0xFFFFFFFF
 
250
 
 
251
/*
 
252
 *  List of inputs
 
253
 */
 
254
#define ADC_CD          0
 
255
#define ADC_AUX         1
 
256
#define ADC_LINE        2
 
257
#define ADC_MIC         3
 
258
#define ADC_PHONO       4
 
259
#define ADC_WTL         5
 
260
#define ADC_LINE_REAR   6
 
261
#define ADC_STEREO_MIX  7
 
262
#define ADC_COUNT       8       /* Must match the size of m_ADCVolume */
 
263
 
 
264
/*
 
265
 * List of Lines
 
266
 */
 
267
#define LINE_OUT_1L     0x00000000
 
268
#define LINE_OUT_1R     0x00000001
 
269
#define LINE_OUT_2L     0x00000002
 
270
#define LINE_OUT_2R     0x00000003
 
271
#define LINE_OUT_3L     0x00000004
 
272
#define LINE_OUT_3R     0x00000005
 
273
#define LINE_OUT_4L     0x00000006
 
274
#define LINE_OUT_4R     0x00000007
 
275
#define LINE_MASTER     0x00000008
 
276
#define LINE_MASTER_    0x00000009
 
277
#define LINE_GAIN_L     0x0000000a
 
278
#define LINE_GAIN_R     0x0000000b
 
279
#define LINE_S_NUM      0x0000000c      /* 12 - Should match devc->m_fDACMute size */
 
280
 
 
281
/*
 
282
 * List of Stereo Lines
 
283
 */
 
284
#define OUT_12          0x00000000
 
285
#define OUT_34          0x00000001
 
286
#define OUT_56          0x00000002
 
287
#define OUT_78          0x00000003
 
288
#define OUT_MASTER      0x00000004
 
289
#define IN_12           0x00000005
 
290
#define NUM_LINES       0x00000006
 
291
 
 
292
/*
 
293
 * SPDIF Out Source
 
294
 */
 
295
enum
 
296
{
 
297
  DIGOUT_DIG_IN = 0,
 
298
  DIGOUT_ANA_IN,
 
299
  DIGOUT_WAVE
 
300
};
 
301
/*
 
302
 * Digital IN Source
 
303
 */
 
304
enum
 
305
{
 
306
  DIGIN_OPTICAL = 0,
 
307
  DIGIN_COAX,
 
308
  DIGIN_CD_IN
 
309
};
 
310
/*
 
311
 * Out-0 Source
 
312
 */
 
313
enum
 
314
{
 
315
  SRC_DMA1 = 0,
 
316
  SRC_PSDIN0,
 
317
  SRC_SPDIN
 
318
};
 
319
 
 
320
/*
 
321
 * Line IN Source (Aureon 7.1 Universe only)
 
322
 */
 
323
#define SRC_AUX         0
 
324
#define SRC_WTL         1
 
325
#define SRC_LINE_REAR   2
 
326
#define SRC_GROUND      3
 
327
 
 
328
/*
 
329
 * Clock Source
 
330
 */
 
331
enum
 
332
{
 
333
  ICE_INTERNAL_CLOCK = 0,
 
334
  ICE_SPDIF_CLOCK
 
335
};
 
336
/*
 
337
 * Function of Frontjack
 
338
 */
 
339
enum
 
340
{
 
341
  FRONT_JACK_LINEIN = 0,
 
342
  FRONT_JACK_HEADPHONE
 
343
};
 
344
 
 
345
enum MUX_TP_PIN
 
346
{
 
347
  CD_IN_MUX_TP_PIN = 1,
 
348
  LINE_IN_MUX_TP_PIN,
 
349
  AUX_IN_MUX_TP_PIN,
 
350
  PHONO_IN_MUX_PIN,
 
351
  LINE2_IN_MUX_PIN,
 
352
  MIC_IN_MUX_TP_PIN,
 
353
  DIG_IN_MUX_TP_PIN,
 
354
  STEREO_MIX_MUX_TP_PIN
 
355
};
 
356
 
 
357
#define AUREON_REMOTE_CNTRL     0x32
 
358
/* #define AUREON_REMOTE_ID        0x0016 */
 
359
#define AUREON_REMOTE_ID        0x6B86
 
360
#define AUREON_PCA_BASEBOARD    0x40
 
361
 
 
362
#define MT_LOOPBK_CONTROL         0x02C
 
363
#define MT_LOOPBK_CONTROL_DAC_REG       0x030
 
364
#define MT_LOOPBK_CONTROL_SPDIF_OUT_REG 0x032
 
365
 
 
366
#define WIDTH_BYTE      1
 
367
#define WIDTH_WORD      2
 
368
#define WIDTH_DWORD     4
 
369
 
 
370
#define BITS_ON     0x10
 
371
#define BITS_OFF    0x00
 
372
#define TOGGLE_ON   0x20
 
373
 
 
374
#define CRITSEC_ON      0x00000001
 
375
 
 
376
#define WIDTH_MASK  0x0f
 
377
 
 
378
#include "spdif.h"
 
379
#include "envy24ht.h"
 
380
 
 
381
/*! \fn =======================================================================
 
382
  Function    : WritePort
 
383
-------------------------------------------------------------------------------
 
384
  Description : 
 
385
  Parameters  : dwRegType -> 
 
386
              : dwIndex -> 
 
387
              : dwValue -> 
 
388
              : dwWidth -> 
 
389
-------------------------------------------------------------------------------
 
390
  Notes       : 
 
391
=============================================================================*/
 
392
static void WritePort
 
393
  (envy24ht_devc * devc,
 
394
   IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwValue, IN ULONG dwWidth)
 
395
{
 
396
  oss_native_word pPort = devc->ccs_base;
 
397
 
 
398
  switch (dwRegType)
 
399
    {
 
400
    case REG_CCS:
 
401
      pPort = devc->ccs_base;
 
402
      break;
 
403
 
 
404
    case REG_MT:
 
405
      pPort = devc->mt_base;
 
406
      break;
 
407
    }
 
408
 
 
409
  /* registers are addressible in byte, word or dword */
 
410
  switch (dwWidth)
 
411
    {
 
412
    case WIDTH_BYTE:
 
413
      OUTB (devc->osdev, dwValue, pPort + dwIndex);
 
414
      break;
 
415
    case WIDTH_WORD:
 
416
      OUTW (devc->osdev, dwValue, pPort + dwIndex);
 
417
 
 
418
      break;
 
419
    case WIDTH_DWORD:
 
420
      OUTL (devc->osdev, dwValue, pPort + dwIndex);
 
421
      break;
 
422
    }
 
423
}
 
424
 
 
425
 
 
426
/*! \fn =======================================================================
 
427
  Function    : ReadPort
 
428
-------------------------------------------------------------------------------
 
429
  Description : 
 
430
  Returns     :  -> 
 
431
  Parameters  : IN ULONG     dwWidth -> 
 
432
                IN ULONG     dwWidth 
 
433
-------------------------------------------------------------------------------
 
434
  Notes       : 
 
435
=============================================================================*/
 
436
static ULONG ReadPort
 
437
  (envy24ht_devc * devc,
 
438
   IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwWidth)
 
439
{
 
440
  oss_native_word pPort = devc->ccs_base;
 
441
  ULONG dwData = 0;
 
442
 
 
443
  switch (dwRegType)
 
444
    {
 
445
    case REG_CCS:
 
446
      pPort = devc->ccs_base;
 
447
      break;
 
448
 
 
449
    case REG_MT:
 
450
      pPort = devc->mt_base;
 
451
      break;
 
452
    }
 
453
 
 
454
  /* all other registers are addressible in byte, word or dword */
 
455
  switch (dwWidth)
 
456
    {
 
457
    case WIDTH_BYTE:
 
458
      dwData = INB (devc->osdev, pPort + dwIndex);
 
459
      break;
 
460
    case WIDTH_WORD:
 
461
      dwData = INW (devc->osdev, pPort + dwIndex);
 
462
      break;
 
463
    case WIDTH_DWORD:
 
464
      dwData = INL (devc->osdev, pPort + dwIndex);
 
465
      break;
 
466
    }
 
467
 
 
468
 
 
469
  return dwData;
 
470
}
 
471
 
 
472
/*! \fn =======================================================================
 
473
  Function    : ReadModifyWritePort
 
474
-------------------------------------------------------------------------------
 
475
  Description : 
 
476
  Returns     : VOID  -> 
 
477
  Parameters  : wRegType -> 
 
478
              : dwMask -> 
 
479
              : dwControl ->
 
480
-------------------------------------------------------------------------------
 
481
  Notes       : 
 
482
=============================================================================*/
 
483
static void ReadModifyWritePort
 
484
  (envy24ht_devc * devc,
 
485
   IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwMask, IN ULONG dwControl
 
486
   /* dwControl: */
 
487
   /* bit[3:0] : data width, 1 => byte, 2 => word, 4 => dword */
 
488
   /* bit[4]   : 1 => turn on bit(s); 0 => turn off bit(s) */
 
489
   /* bit[5]   : 1 => toggle bit(s) */
 
490
   /* bit[6]   : 1 => turn on Hw access critical section */
 
491
  )
 
492
{
 
493
  ULONG dwValue;
 
494
  ULONG dwWidth;
 
495
  oss_native_word flags;
 
496
 
 
497
  dwWidth = dwControl & WIDTH_MASK;
 
498
 
 
499
  if (dwControl & CRITSEC_ON)
 
500
    {
 
501
      MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
502
    }
 
503
 
 
504
  dwValue = ReadPort (devc, dwRegType, dwIndex, dwWidth);
 
505
 
 
506
  /* see whether we should turn on or off the bit(s) */
 
507
  if (dwControl & BITS_ON)
 
508
    dwValue |= dwMask;
 
509
  else
 
510
    dwValue &= ~dwMask;
 
511
 
 
512
  WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth);
 
513
 
 
514
  /* see if we need to toggle the bit(s) */
 
515
  if (dwControl & TOGGLE_ON)
 
516
    {
 
517
      dwValue ^= dwMask;
 
518
      WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth);
 
519
    }
 
520
 
 
521
  if (dwControl & CRITSEC_ON)
 
522
    {
 
523
      MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
 
524
    }
 
525
 
 
526
}
 
527
 
 
528
/*! \fn =======================================================================
 
529
 Function    : WriteGPIO
 
530
-------------------------------------------------------------------------------
 
531
 Description : Writes masked Data to GPIO Port
 
532
 Parameters  : IN ULONG Data -> 
 
533
             : IN ULONG Mask -> 
 
534
-------------------------------------------------------------------------------
 
535
 Notes       : 
 
536
=============================================================================*/
 
537
static void
 
538
WriteGPIO (envy24ht_devc * devc, IN ULONG Data, IN ULONG Mask)
 
539
{
 
540
  USHORT MaskL;
 
541
  UCHAR MaskH;
 
542
  USHORT DataL;
 
543
  UCHAR DataH;
 
544
 
 
545
  /* Do the masking. */
 
546
  MaskL = (USHORT) Mask;
 
547
  MaskH = (UCHAR) (Mask >> 16);
 
548
  DataL = (USHORT) Data;
 
549
  DataH = (UCHAR) (Data >> 16);
 
550
  devc->gpio_shadow_L &= ~MaskL;
 
551
  devc->gpio_shadow_H &= ~MaskH;
 
552
  devc->gpio_shadow_L |= (MaskL & DataL);
 
553
  devc->gpio_shadow_H |= (MaskH & DataH);
 
554
 
 
555
  /* Write Data */
 
556
  WritePort (devc, REG_CCS, WKN_GPIO_DATA0, devc->gpio_shadow_L, WIDTH_WORD);
 
557
  WritePort (devc, REG_CCS, WKN_GPIO_DATA2, devc->gpio_shadow_H, WIDTH_BYTE);
 
558
}
 
559
 
 
560
/*! \fn =======================================================================
 
561
 Function    : SetSDADir
 
562
-------------------------------------------------------------------------------
 
563
 Description : 
 
564
 Returns     : void  -> 
 
565
 Parameters  : IN BOOLEAN fOut -> 
 
566
-------------------------------------------------------------------------------
 
567
 Notes       : 
 
568
=============================================================================*/
 
569
static void
 
570
SetSDADir (envy24ht_devc * devc, IN BOOLEAN fOut)
 
571
{
 
572
  if (fOut)
 
573
    {
 
574
      /* Set GPIO 18 direction to output */
 
575
      WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE);
 
576
      /* Turn IIC logic to SDA write */
 
577
      WriteGPIO (devc, GPIO_SDA_TX_MASK, GPIO_SDA_TX_MASK);
 
578
    }
 
579
  else
 
580
    {
 
581
      WriteGPIO (devc, 0, GPIO_SDA_TX_MASK);
 
582
      /* Direction "Read" for GPIO 18 (SDA) */
 
583
      WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDB, WIDTH_BYTE);
 
584
    }
 
585
}
 
586
 
 
587
/*! \fn =======================================================================
 
588
 Function    : SetSDA
 
589
-------------------------------------------------------------------------------
 
590
 Description : 
 
591
 Parameters  : BOOLEAN fSet
 
592
-------------------------------------------------------------------------------
 
593
 Notes       : 
 
594
=============================================================================*/
 
595
static void
 
596
SetSDA (envy24ht_devc * devc, BOOLEAN fSet)
 
597
{
 
598
  /* Set GPIO 18 direction to output */
 
599
  SetSDADir (devc, 1);
 
600
  /* Write SDA */
 
601
  WriteGPIO (devc, fSet ? GPIO_SDA_MASK : 0, GPIO_SDA_MASK);
 
602
}
 
603
 
 
604
/*! \fn =======================================================================
 
605
 Function    : GetSDA
 
606
-------------------------------------------------------------------------------
 
607
 Description : 
 
608
 Returns     : 
 
609
UCHAR  -> 
 
610
-------------------------------------------------------------------------------
 
611
 Notes       : 
 
612
=============================================================================*/
 
613
static UCHAR
 
614
GetSDA (envy24ht_devc * devc)
 
615
{
 
616
  UCHAR ulData;
 
617
 
 
618
  /* Turn IIC logic to SDA read */
 
619
  SetSDADir (devc, 0);
 
620
  ulData =
 
621
    ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x04) == 0x04);
 
622
  return ulData;
 
623
}
 
624
 
 
625
/*! \fn =======================================================================
 
626
 Function    : SetIIC
 
627
-------------------------------------------------------------------------------
 
628
 Description : 
 
629
 Parameters  : IN BOOLEAN fSDA -> 
 
630
             : IN BOOLEAN fCLK -> 
 
631
             : IN ULONG ulSleep -> 
 
632
-------------------------------------------------------------------------------
 
633
 Notes       : 
 
634
=============================================================================*/
 
635
static void SetIIC
 
636
  (envy24ht_devc * devc, IN BOOLEAN fSDA, IN BOOLEAN fCLK, IN ULONG ulSleep)
 
637
{
 
638
  SetSDA (devc, fSDA);
 
639
  if (fCLK)
 
640
    WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
 
641
  else
 
642
    WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
643
  if (ulSleep)
 
644
    oss_udelay (ulSleep);
 
645
}
 
646
 
 
647
/*! \fn =======================================================================
 
648
 Function    : IICStart
 
649
-------------------------------------------------------------------------------
 
650
 Description : 
 
651
 Parameters  : ULONG ulSleep -> 
 
652
-------------------------------------------------------------------------------
 
653
 Notes       : 
 
654
=============================================================================*/
 
655
static void
 
656
IICStart (envy24ht_devc * devc, ULONG ulSleep)
 
657
{
 
658
  /* falling edge of SDA while SCL is HIGH */
 
659
  SetIIC (devc, 1, 1, ulSleep);
 
660
  SetIIC (devc, 0, 1, ulSleep);
 
661
}
 
662
 
 
663
/*! \fn =======================================================================
 
664
 Function    : IICStop
 
665
-------------------------------------------------------------------------------
 
666
 Description : 
 
667
 Parameters  : ULONG ulSleep -> 
 
668
-------------------------------------------------------------------------------
 
669
 Notes       : 
 
670
=============================================================================*/
 
671
static void
 
672
IICStop (envy24ht_devc * devc, ULONG ulSleep)
 
673
{
 
674
  /* rising edge of SDA while SCL is HIGH */
 
675
  SetIIC (devc, 0, 1, ulSleep);
 
676
  SetIIC (devc, 1, 1, ulSleep);
 
677
  /* Reset Lines (No IIC requirement, but for prevent conflicts with SPI) */
 
678
  /*SetIIC(0,0,ulSleep); */
 
679
}
 
680
 
 
681
/*! \fn =======================================================================
 
682
 Function    : IICSendByte
 
683
-------------------------------------------------------------------------------
 
684
 Description : 
 
685
 Returns     : UCHAR  -> 
 
686
 Parameters  : CHAR bByte -> 
 
687
             : ULONG ulSleep -> 
 
688
-------------------------------------------------------------------------------
 
689
 Notes       : 
 
690
=============================================================================*/
 
691
static UCHAR IICSendByte
 
692
  (envy24ht_devc * devc, IN UCHAR bByte, IN ULONG ulSleep)
 
693
{
 
694
  UCHAR bDataBit, bAck;
 
695
  int i;
 
696
  for (i = 7; i >= 0; i--)      /* send byte (MSB first) */
 
697
    {
 
698
      bDataBit = (bByte >> i) & 0x01;
 
699
 
 
700
      SetIIC (devc, bDataBit, 0, ulSleep);
 
701
      SetIIC (devc, bDataBit, 1, ulSleep);
 
702
      SetIIC (devc, bDataBit, 0, ulSleep);
 
703
    }                           /* end for i */
 
704
 
 
705
  SetIIC (devc, 1, 0, ulSleep);
 
706
 
 
707
  /* This is neccesary for PLC */
 
708
  SetSDADir (devc, 0);
 
709
  /* Get acknowledge */
 
710
  SetIIC (devc, 1, 1, ulSleep);
 
711
  bAck = GetSDA (devc);
 
712
  /*if (fAddress) */
 
713
  /*    SetIIC(devc, 1,0,ulSleep); */
 
714
  /* else */
 
715
  /* this is a start condition but never mind */
 
716
  SetIIC (devc, 0, 0, ulSleep);
 
717
  return (!bAck);               /* bAck = 0 --> success */
 
718
}
 
719
 
 
720
#if 0
 
721
/*! \fn =======================================================================
 
722
 Function    : IICReceiveByte
 
723
-------------------------------------------------------------------------------
 
724
 Description : 
 
725
 Returns     : UCHAR  -> 
 
726
 Parameters  : CHAR fLastByte -> 
 
727
             : ULONG ulSleep -> 
 
728
-------------------------------------------------------------------------------
 
729
 Notes       : 
 
730
=============================================================================*/
 
731
static UCHAR IICReceiveByte
 
732
  (envy24ht_devc * devc, UCHAR fLastByte, ULONG ulSleep)
 
733
{
 
734
  UCHAR bRead = 0;
 
735
  int i;
 
736
 
 
737
  for (i = 7; i >= 0; i--)
 
738
    {
 
739
      SetIIC (devc, 1, 0, ulSleep);
 
740
      SetIIC (devc, 1, 1, ulSleep);
 
741
      bRead <<= 1;
 
742
      bRead += GetSDA (devc);
 
743
    }
 
744
 
 
745
  /* -> no acknowledge for last received byte */
 
746
  SetIIC (devc, fLastByte, 0, ulSleep); /* SDA = HIGH for last byte */
 
747
  SetIIC (devc, fLastByte, 1, ulSleep);
 
748
  SetIIC (devc, fLastByte, 0, ulSleep); /* clock -> LOW */
 
749
 
 
750
  return bRead;
 
751
}
 
752
#endif
 
753
 
 
754
/*! \fn =======================================================================
 
755
 Function    : IICWriteBuffer
 
756
-------------------------------------------------------------------------------
 
757
 Description : 
 
758
 Returns     : UCHAR  -> 
 
759
 Parameters  : CHAR bIicAddress -> 
 
760
             : PUCHAR pbByte -> 
 
761
             : USHORT nNoBytes -> 
 
762
             : ULONG ulSleep -> 
 
763
-------------------------------------------------------------------------------
 
764
 Notes       : 
 
765
=============================================================================*/
 
766
static UCHAR IICWriteBuffer
 
767
  (envy24ht_devc * devc,
 
768
   UCHAR bIicAddress, PUCHAR pbByte, USHORT nNoBytes, ULONG ulSleep)
 
769
{
 
770
  IICStart (devc, ulSleep);
 
771
 
 
772
  /* send IIC address and data byte */
 
773
  if (!IICSendByte (devc, bIicAddress, ulSleep))
 
774
    goto FAILED;
 
775
  /* send buffer */
 
776
  do
 
777
    {
 
778
      if (!IICSendByte (devc, *pbByte, ulSleep))
 
779
        goto FAILED;            /* got no acknowledge */
 
780
      pbByte++;
 
781
      nNoBytes--;
 
782
    }
 
783
  while (nNoBytes);
 
784
 
 
785
  IICStop (devc, ulSleep);
 
786
  return 1;
 
787
 
 
788
FAILED:
 
789
  IICStop (devc, ulSleep);
 
790
  return 0;
 
791
}
 
792
 
 
793
/*! \fn =======================================================================
 
794
 Function    : WriteCS8415
 
795
-------------------------------------------------------------------------------
 
796
 Description : 
 
797
 Parameters  : IN UCHAR Register -> 
 
798
             : IN UCHAR Value -> 
 
799
-------------------------------------------------------------------------------
 
800
 Notes       : 
 
801
=============================================================================*/
 
802
static void WriteCS8415
 
803
  (envy24ht_devc * devc, IN UCHAR Register, IN UCHAR Value)
 
804
{
 
805
  ULONG i;
 
806
  BOOLEAN fData;
 
807
  ULONG ulCmd;
 
808
  ULONG ulCount;
 
809
 
 
810
  /* m_pAdapter->HwEnter(); *//* TODO */
 
811
 
 
812
  /* Clock low to prevent IIC Startcondition */
 
813
  WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
814
 
 
815
  SetSDA (devc, 0);
 
816
  /* Chip select (CS low) */
 
817
  WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
 
818
 
 
819
  /* format buffer */
 
820
  ulCmd = 0x200000 +            /* chip address + R/W */
 
821
    (((ULONG) Register) << 8) + /* register address */
 
822
    Value;                      /* Value */
 
823
  ulCmd <<= 8;
 
824
  ulCount = 24;                 /* (AddressOnly) ? 16:24; */
 
825
  for (i = 0; i < ulCount; i++)
 
826
    {
 
827
      fData = (ulCmd & 0x80000000) ? 1 : 0;
 
828
      /* CCLK -> low */
 
829
      WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
830
      oss_udelay (3);
 
831
      /* CDTI -> Set data */
 
832
      SetSDA (devc, fData);
 
833
      oss_udelay (3);
 
834
      /* CCLK -> high */
 
835
      WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
 
836
      ulCmd <<= 1;
 
837
    }
 
838
  WriteGPIO (devc, 0, GPIO_SCL_MASK);   /* CCLK -> low */
 
839
 
 
840
  /* Chip deselect (CS high) */
 
841
  WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
 
842
  /* m_pAdapter->HwLeave(); *//* TODO */
 
843
}
 
844
 
 
845
#if 0
 
846
/*! \fn =======================================================================
 
847
 Function    : ReadCS8415
 
848
-------------------------------------------------------------------------------
 
849
 Description : 
 
850
 Returns     : UCHAR  -> 
 
851
 Parameters  : IN UCHAR Register -> 
 
852
-------------------------------------------------------------------------------
 
853
 Notes       : 
 
854
=============================================================================*/
 
855
 /*ARGSUSED*/ static UCHAR
 
856
ReadCS8415 (envy24ht_devc * devc, IN UCHAR Register)
 
857
{
 
858
  ULONG i;
 
859
  BOOLEAN fData;
 
860
  UCHAR cValue = 0;
 
861
  USHORT wCmd;
 
862
 
 
863
  /* m_pAdapter->HwEnter(); *//* TODO */
 
864
 
 
865
  /* Clock low to prevent IIC Startcondition */
 
866
  WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
867
 
 
868
  SetSDA (devc, 0);
 
869
 
 
870
  /* Chip select (CS low) */
 
871
  WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
 
872
  /* Set GPIO21 to read direction */
 
873
  WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE);
 
874
 
 
875
  wCmd = 0x2100;                /* +  *//* chip address + R/W */
 
876
  /*(((USHORT)Register) << 8); *//* register address */
 
877
  for (i = 0; i < 16; i++)
 
878
    {
 
879
      fData = (wCmd & 0x8000) ? 1 : 0;
 
880
      /* CCLK -> low */
 
881
      WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
882
      /* CDTI -> Set data */
 
883
      SetSDA (devc, fData);
 
884
      oss_udelay (3);
 
885
      /* CCLK -> high */
 
886
      WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
 
887
      wCmd <<= 1;
 
888
      if (i > 7)
 
889
        {
 
890
          /* Read CDTO */
 
891
          cValue <<= 1;
 
892
          cValue +=
 
893
            ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x20) ==
 
894
             0x20);
 
895
        }
 
896
    }
 
897
 
 
898
  WriteGPIO (devc, 0, GPIO_SCL_MASK);   /* CCLK -> low */
 
899
 
 
900
  /* Chip deselect (CS high) */
 
901
  WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
 
902
 
 
903
  /* m_pAdapter->HwLeave(); *//* TODO */
 
904
  return cValue;
 
905
}
 
906
#endif
 
907
 
 
908
/*
 
909
 * Definition of PCA I/Os
 
910
 */
 
911
typedef union tagPCA_CFG
 
912
{
 
913
  unsigned char cReg;
 
914
  struct
 
915
  {
 
916
    unsigned char P00_SourceSel:2;      /* LineIN Selector */
 
917
    /* 00 -> Aux */
 
918
    /* 01 -> Wavetable */
 
919
    /* 11 -> LineIN Rear */
 
920
    unsigned char P02_DigSel:1; /* DigitalIN Selector */
 
921
    /* 0  -> Coax */
 
922
    /* 1  -> Optical */
 
923
 
 
924
    unsigned char P03_LineLED:1;        /* LineLED */
 
925
    /* 0 -> Off */
 
926
    /* 1 -> On */
 
927
    unsigned char P04_unused:4; /* unused */
 
928
  } Bits;
 
929
} PCA_CFG;
 
930
 
 
931
/*! \fn =======================================================================
 
932
 Function    : WritePCA
 
933
-------------------------------------------------------------------------------
 
934
 Description : 
 
935
 Returns     : NTSTATUS  -> 
 
936
-------------------------------------------------------------------------------
 
937
 Notes       : 
 
938
=============================================================================*/
 
939
static void
 
940
WritePCA (envy24ht_devc * devc)
 
941
{
 
942
  PCA_CFG tCFG;
 
943
  BYTE bByte[2];
 
944
 
 
945
  tCFG.cReg = 0;
 
946
 
 
947
  switch (devc->m_LineInSource)
 
948
    {
 
949
    case SRC_AUX:
 
950
      tCFG.Bits.P00_SourceSel = 0;
 
951
      break;
 
952
    case SRC_WTL:
 
953
      tCFG.Bits.P00_SourceSel = 1;
 
954
      break;
 
955
    case SRC_LINE_REAR:
 
956
      tCFG.Bits.P00_SourceSel = 2;
 
957
      break;
 
958
    case SRC_GROUND:
 
959
      tCFG.Bits.P00_SourceSel = 3;
 
960
      break;
 
961
 
 
962
    }
 
963
 
 
964
  /* Switch LineLED when Line is selected for record */
 
965
  if (devc->m_ADCIndex == ADC_LINE)
 
966
    tCFG.Bits.P03_LineLED = 1;
 
967
  if (devc->m_DigInSource == DIGIN_OPTICAL)
 
968
    tCFG.Bits.P02_DigSel = 1;
 
969
  /* Set all I/Os to Output */
 
970
  bByte[0] = 3;
 
971
  bByte[1] = 0;
 
972
  IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30);
 
973
  /* Write config */
 
974
  bByte[0] = 0x01;
 
975
  bByte[1] = tCFG.cReg;
 
976
  IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30);
 
977
}
 
978
 
 
979
/*! \fn =======================================================================
 
980
 Function    : SetDigInSource
 
981
-------------------------------------------------------------------------------
 
982
 Description : 
 
983
 Returns     : void  -> 
 
984
 Parameters  : IN ULONG Source -> 
 
985
-------------------------------------------------------------------------------
 
986
 Notes       : 
 
987
=============================================================================*/
 
988
static void
 
989
SetDigInSource (envy24ht_devc * devc, IN ULONG Source)
 
990
{
 
991
  switch (Source)
 
992
    {
 
993
    case DIGIN_OPTICAL:
 
994
    case DIGIN_COAX:
 
995
      WriteCS8415 (devc, CS_CONTROL_2, 0x01);
 
996
      break;
 
997
    case DIGIN_CD_IN:
 
998
      WriteCS8415 (devc, CS_CONTROL_2, 0x00);
 
999
      break;
 
1000
    }
 
1001
  devc->m_DigInSource = Source;
 
1002
  WritePCA (devc);
 
1003
}
 
1004
 
 
1005
/*! \fn =======================================================================
 
1006
 Function    : SetOUT0Source
 
1007
-------------------------------------------------------------------------------
 
1008
 Description : 
 
1009
 Returns     : void  -> 
 
1010
 Parameters  : IN ULONG Source -> 
 
1011
-------------------------------------------------------------------------------
 
1012
 Notes       : 
 
1013
=============================================================================*/
 
1014
static void
 
1015
SetOUT0Source (envy24ht_devc * devc, IN ULONG Source)
 
1016
{
 
1017
  ULONG ulShiftL, ulShiftR;
 
1018
  ULONG aulShiftL[] = { 0, 8, 11, 14, 17 };
 
1019
  ULONG aulShiftR[] = { 3, 20, 23, 26, 29 };
 
1020
  ULONG ulSourceL, ulSourceR;
 
1021
  int i;
 
1022
 
 
1023
  /* No DigMonitor when Clock is internal */
 
1024
  if ((devc->m_ClockSource == ICE_INTERNAL_CLOCK) && (Source == SRC_SPDIN))
 
1025
    return;
 
1026
  for (i = 0; i < 5; i++)
 
1027
    {
 
1028
      ulShiftL = aulShiftL[i];
 
1029
      ulShiftR = aulShiftR[i];
 
1030
      switch (Source)
 
1031
        {
 
1032
        case SRC_DMA1:
 
1033
          ulSourceL = SRC_PDMA;
 
1034
          ulSourceR = SRC_PDMA;
 
1035
          break;
 
1036
        case SRC_PSDIN0:
 
1037
          ulSourceL = SRC_PSDIN0_L;
 
1038
          ulSourceR = SRC_PSDIN0_R;
 
1039
          break;
 
1040
        case SRC_SPDIN:
 
1041
          ulSourceL = SRC_SPDIN_L;
 
1042
          ulSourceR = SRC_SPDIN_R;
 
1043
          break;
 
1044
        default:                /* Do nothing */
 
1045
          return;
 
1046
        }
 
1047
      /* First reset all relevant bits */
 
1048
      ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
 
1049
                           SRC_MASK << ulShiftL, WIDTH_DWORD | BITS_OFF);
 
1050
      ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
 
1051
                           SRC_MASK << ulShiftR, WIDTH_DWORD | BITS_OFF);
 
1052
      /* ..and set routing mask */
 
1053
      ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
 
1054
                           ulSourceL << ulShiftL, WIDTH_DWORD | BITS_ON);
 
1055
      ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
 
1056
                           ulSourceR << ulShiftR, WIDTH_DWORD | BITS_ON);
 
1057
    }
 
1058
  devc->m_Out0Source = Source;
 
1059
}
 
1060
static void SetADCMux (envy24ht_devc * devc, IN ULONG Value);
 
1061
 
 
1062
/*! \fn =======================================================================
 
1063
 Function    : SetLineSource
 
1064
-------------------------------------------------------------------------------
 
1065
 Description : 
 
1066
 Parameters  : IN ULONG Source -> 
 
1067
-------------------------------------------------------------------------------
 
1068
 Notes       : 
 
1069
=============================================================================*/
 
1070
static void
 
1071
SetLineSource (envy24ht_devc * devc, IN ULONG Source)
 
1072
{
 
1073
  switch (Source)
 
1074
    {
 
1075
    case SRC_AUX:
 
1076
      devc->m_AuxMux = 0x00;
 
1077
      break;
 
1078
    case SRC_WTL:
 
1079
      devc->m_AuxMux = 0x44;
 
1080
      break;
 
1081
    case SRC_LINE_REAR:
 
1082
      devc->m_AuxMux = 0x66;
 
1083
      break;
 
1084
 
 
1085
    }
 
1086
  /* Update ADCMux */
 
1087
  SetADCMux (devc, devc->m_ADCMux);
 
1088
  devc->m_LineInSource = Source;
 
1089
  WritePCA (devc);
 
1090
}
 
1091
 
 
1092
/*! \fn =======================================================================
 
1093
 Function    : SetClockSource
 
1094
-------------------------------------------------------------------------------
 
1095
 Description : 
 
1096
 Parameters  : IN ULONG ClockSource -> 
 
1097
-------------------------------------------------------------------------------
 
1098
 Notes       : 
 
1099
=============================================================================*/
 
1100
static void
 
1101
SetClockSource (envy24ht_devc * devc, IN ULONG ClockSource)
 
1102
{
 
1103
 
 
1104
  if (ClockSource == ICE_INTERNAL_CLOCK)
 
1105
    {
 
1106
      ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10,
 
1107
                           WIDTH_BYTE | BITS_OFF);
 
1108
      /* Disable DigMonitor to avoid noisy output */
 
1109
      if (devc->m_Out0Source == SRC_SPDIN)
 
1110
        SetOUT0Source (devc, SRC_DMA1);
 
1111
    }
 
1112
  else
 
1113
    {
 
1114
      ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10,
 
1115
                           WIDTH_BYTE | BITS_ON);
 
1116
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
1117
                           WIDTH_BYTE | BITS_OFF);
 
1118
    }
 
1119
  devc->m_ClockSource = ClockSource;
 
1120
}
 
1121
 
 
1122
/*! \fn =======================================================================
 
1123
  Function    : ResetGPIO
 
1124
-------------------------------------------------------------------------------
 
1125
  Description : 
 
1126
  Returns     : void  -> 
 
1127
-------------------------------------------------------------------------------
 
1128
  Notes       : 
 
1129
=============================================================================*/
 
1130
static void
 
1131
ResetGPIO (envy24ht_devc * devc)
 
1132
{
 
1133
 
 
1134
  /* Enable all lower GPIOs */
 
1135
  WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK0, 0x0, WIDTH_WORD);
 
1136
  /* Enable all upper GPIOs */
 
1137
  WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK2, 0x0, WIDTH_BYTE);
 
1138
  /* Set GPIO direction  */
 
1139
  if (devc->subvendor == SSID_AUREON_UNIVERSE)
 
1140
    {
 
1141
      /* -> all output except GPIO_CS8415_CDTO_MASK  */
 
1142
      /* and GPIO_REMOTE_MASK */
 
1143
      WritePort (devc, REG_CCS, WKN_GPIO_DIR0,
 
1144
                 ~(GPIO_CS8415_CDTO_MASK | GPIO_REMOTE_MASK), WIDTH_DWORD);
 
1145
    }
 
1146
  else
 
1147
    {
 
1148
      /* All output except GPIO_CS8415_CDTO_MASK */
 
1149
      WritePort (devc, REG_CCS, WKN_GPIO_DIR0, ~GPIO_CS8415_CDTO_MASK,
 
1150
                 WIDTH_DWORD);
 
1151
    }
 
1152
 
 
1153
  oss_udelay (100);
 
1154
 
 
1155
    /*----------------------------------------------------------------------------
 
1156
        Reset AC97 Interface  
 
1157
    -----------------------------------------------------------------------------*/
 
1158
 
 
1159
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
1160
  oss_udelay (3);
 
1161
  WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
 
1162
  oss_udelay (3);
 
1163
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
1164
 
 
1165
    /*----------------------------------------------------------------------------
 
1166
        Enable Remote-Control Interrupts  
 
1167
    -----------------------------------------------------------------------------*/
 
1168
  WriteGPIO (devc, GPIO_INT_REST_MASK, GPIO_INT_REST_MASK);
 
1169
 
 
1170
  /* Select optical input */
 
1171
  /* WriteGPIO(devc, GPIO_DIGITAL_SEL, 0); */
 
1172
}
 
1173
 
 
1174
/*! \fn =======================================================================
 
1175
 Function    : SetSPDIFConfig
 
1176
-------------------------------------------------------------------------------
 
1177
 Description : 
 
1178
 Returns     : void  -> 
 
1179
 Parameters  : IN ULONG Config  -> 
 
1180
-------------------------------------------------------------------------------
 
1181
 Notes       : 
 
1182
=============================================================================*/
 
1183
static void
 
1184
SetSPDIFConfig (envy24ht_devc * devc, IN ULONG Config)
 
1185
{
 
1186
  ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80,
 
1187
                       WIDTH_BYTE | BITS_OFF);
 
1188
  if (Config & SPDIF_ENABLE_MASK)
 
1189
    {
 
1190
      devc->m_f1724SPDIF = 1;
 
1191
    }
 
1192
  else
 
1193
    {
 
1194
      devc->m_f1724SPDIF = 0;
 
1195
    }
 
1196
  /* Reset SPDIF Config */
 
1197
  ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, 0x000F,
 
1198
                       WIDTH_WORD | BITS_OFF);
 
1199
  /* Set new Config */
 
1200
  ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, Config & 0xFFFF,
 
1201
                       WIDTH_WORD | BITS_ON);
 
1202
  devc->m_SPDIFConfig = Config;
 
1203
  if (devc->m_f1724SPDIF)
 
1204
    ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80,
 
1205
                         WIDTH_BYTE | BITS_ON);
 
1206
  /* Force saving of registers */
 
1207
  /* devc->m_pAdapter->SetDirty(); *//* TODO */
 
1208
}
 
1209
 
 
1210
/*! \fn =======================================================================
 
1211
 Function    : SetFrontjack
 
1212
-------------------------------------------------------------------------------
 
1213
 Description : 
 
1214
 Parameters  : IN ULONG Frontjack -> 
 
1215
-------------------------------------------------------------------------------
 
1216
 Notes       : 
 
1217
=============================================================================*/
 
1218
static void
 
1219
SetFrontjack (envy24ht_devc * devc, IN ULONG Frontjack)
 
1220
{
 
1221
 
 
1222
  switch (Frontjack)
 
1223
    {
 
1224
    case FRONT_JACK_LINEIN:
 
1225
      WriteGPIO (devc, 0, GPIO_HEADPHONE_MASK);
 
1226
      break;
 
1227
    case FRONT_JACK_HEADPHONE:
 
1228
      WriteGPIO (devc, GPIO_HEADPHONE_MASK, GPIO_HEADPHONE_MASK);
 
1229
      break;
 
1230
    }
 
1231
  devc->m_Frontjack = Frontjack;
 
1232
  /* Force saving of registers */
 
1233
  /* devc->m_pAdapter->SetDirty(); *//* TODO */
 
1234
 
 
1235
}
 
1236
 
 
1237
/*! \fn =======================================================================
 
1238
 Function    : Init1724
 
1239
-------------------------------------------------------------------------------
 
1240
 Description : 
 
1241
 Returns     : void  -> 
 
1242
-------------------------------------------------------------------------------
 
1243
 Notes       : 
 
1244
=============================================================================*/
 
1245
static void
 
1246
Init1724 (envy24ht_devc * devc)
 
1247
{
 
1248
  /* System Config: 4 DACs, one ADC & SPDIF, MPU enabled, 24,576Mhz crystal */
 
1249
  /* WritePort(REG_CCS, WKN_SYS_CONFIG, 0x2B, WIDTH_BYTE); */
 
1250
  /* CL_NOTE: New Setings */
 
1251
  /* System Config: 4 DACs, one ADC & SPDIF, MPU disabled, 24,576Mhz crystal */
 
1252
  WritePort (devc, REG_CCS, WKN_SYS_CONFIG, 0x0B, WIDTH_BYTE);
 
1253
 
 
1254
  /* Config I2S Interface */
 
1255
  WritePort (devc, REG_CCS, WKN_ACLINK_CONFIG, 0x80, WIDTH_BYTE);
 
1256
  WritePort (devc, REG_CCS, WKN_I2S_CONFIG, 0xF9, WIDTH_BYTE);
 
1257
  WritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x83, WIDTH_BYTE);
 
1258
 
 
1259
  /* Config Interrupt behaviour */
 
1260
  WritePort (devc, REG_MT, MT_PLAY_REC_UNDOVR, 0, WIDTH_BYTE);
 
1261
  WritePort (devc, REG_MT, MT_INTR_STATUS_REG, 0, WIDTH_BYTE);
 
1262
  WritePort (devc, REG_MT, MT_INTR_MASK_REG, 0xFF, WIDTH_BYTE);
 
1263
  WritePort (devc, REG_CCS, WKN_INT_STAT_REG, 0, WIDTH_BYTE);
 
1264
  WritePort (devc, REG_CCS, WKN_INT_MASK_REG, 0xFE, WIDTH_BYTE);
 
1265
 
 
1266
  SetSPDIFConfig (devc, 0);
 
1267
  /* SetSDPIFSource(devc, DIGOUT_WAVE); */
 
1268
  SetDigInSource (devc, DIGIN_OPTICAL);
 
1269
  SetFrontjack (devc, FRONT_JACK_LINEIN);
 
1270
}
 
1271
 
 
1272
/*! \fn =======================================================================
 
1273
 Function    : WriteWM8770
 
1274
-------------------------------------------------------------------------------
 
1275
 Description : 
 
1276
 Parameters  : IN UCHAR Register -> 
 
1277
             : IN UCHAR Value -> 
 
1278
-------------------------------------------------------------------------------
 
1279
 Notes       : 
 
1280
=============================================================================*/
 
1281
void
 
1282
WriteWM8770 (envy24ht_devc * devc, IN UCHAR Register, IN USHORT Value)
 
1283
{
 
1284
  int i;
 
1285
  BOOLEAN fData;
 
1286
  USHORT wCmd;
 
1287
/*    KIRQL       OldIrql; */
 
1288
 
 
1289
  /* m_pAdapter->HwEnter(); */
 
1290
 
 
1291
  /* KeAcquireSpinLock (&m_SPILock,&OldIrql); */
 
1292
 
 
1293
 
 
1294
  /* Clock low to prevent IIC Startcondition */
 
1295
  WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
1296
 
 
1297
  SetSDA (devc, 0);
 
1298
 
 
1299
  /* Chip select (CS low) */
 
1300
  WriteGPIO (devc, 0, GPIO_WM8770_CS_MASK);
 
1301
 
 
1302
  /* format buffer */
 
1303
  wCmd = (((USHORT) Register) << 9) + Value;
 
1304
 
 
1305
 
 
1306
  for (i = 0; i < 16; i++)
 
1307
    {
 
1308
      fData = (wCmd & 0x8000) ? 1 : 0;
 
1309
      /* CCLK -> low */
 
1310
      WriteGPIO (devc, 0, GPIO_SCL_MASK);
 
1311
      oss_udelay (3);
 
1312
      /* CDTI -> Set data */
 
1313
      SetSDA (devc, fData);
 
1314
      oss_udelay (3);
 
1315
      /* CCLK -> high */
 
1316
      WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
 
1317
      wCmd <<= 1;
 
1318
    }
 
1319
  WriteGPIO (devc, 0, GPIO_SCL_MASK);   /* CCLK -> low */
 
1320
 
 
1321
  /* Chip deselect */
 
1322
  WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK);
 
1323
}
 
1324
 
 
1325
/*! \fn =======================================================================
 
1326
 Function    : SetVolReg
 
1327
-------------------------------------------------------------------------------
 
1328
 Description : 
 
1329
 Parameters  : IN ULONG LineIdx -> 
 
1330
-------------------------------------------------------------------------------
 
1331
 Notes       : 
 
1332
=============================================================================*/
 
1333
static void
 
1334
SetVolReg (envy24ht_devc * devc, IN ULONG LineIdx)
 
1335
{
 
1336
  int iVol, ChnlVol;
 
1337
 
 
1338
  ChnlVol = devc->m_DACVolume[LineIdx];
 
1339
 
 
1340
  /* See if we want to mute anything */
 
1341
  if (devc->m_fDACMute[LineIdx] || devc->m_fDACMute[LINE_MASTER])
 
1342
    {
 
1343
      WriteWM8770 (devc, gWMRegister[LineIdx], 0x100);
 
1344
      return;
 
1345
    }
 
1346
 
 
1347
  /* Since master volume is virtualized, we add the attenuations for both */
 
1348
  /* master volume and channel volume to obtain the overall attenuation */
 
1349
 
 
1350
  /* Get total attenuation */
 
1351
  iVol = ChnlVol + devc->m_DACVolume[LINE_MASTER] - MAX_VOLUME;
 
1352
  /* Check against bounds */
 
1353
  iVol = (iVol < MAX_VOLUME) ? iVol : MAX_VOLUME;
 
1354
  if (iVol < MIN_VOLUME)
 
1355
    iVol = MIN_VOLUME;
 
1356
  WriteWM8770 (devc, gWMRegister[LineIdx], iVol | 0x180);
 
1357
}
 
1358
 
 
1359
 
 
1360
/*! \fn =======================================================================
 
1361
 Function    : SetMute
 
1362
-------------------------------------------------------------------------------
 
1363
 Description : 
 
1364
 Returns     : VOID  -> 
 
1365
 Parameters  : IN ULONG ChannelID -> 
 
1366
             : IN BOOLEAN Mute -> 
 
1367
-------------------------------------------------------------------------------
 
1368
 Notes       : 
 
1369
=============================================================================*/
 
1370
static void SetDACMute
 
1371
  (envy24ht_devc * devc, IN ULONG ChannelID, IN BOOLEAN Mute)
 
1372
{
 
1373
  ULONG LineIndex;
 
1374
 
 
1375
  /* Convert ChannelID to line index */
 
1376
  /* If it is for left channel, we will need to add one */
 
1377
  LineIndex = ChannelID >> 15;
 
1378
 
 
1379
  /* See if this is for master volume */
 
1380
  if (LineIndex == LINE_MASTER)
 
1381
    {
 
1382
      /* if current setting is not the same as previous setting */
 
1383
      if (devc->m_fDACMute[LINE_MASTER] != Mute)
 
1384
        {
 
1385
          int i;
 
1386
 
 
1387
          devc->m_fDACMute[LINE_MASTER] = Mute;
 
1388
 
 
1389
          /* Need to do it for every single line (excluding Master and Gain) */
 
1390
          for (i = 0; i <= LINE_OUT_4R; i++)
 
1391
            {
 
1392
              SetVolReg (devc, i);
 
1393
            }
 
1394
          return;
 
1395
        }
 
1396
    }
 
1397
 
 
1398
  /* See if this is for left channel */
 
1399
  if (ChannelID & CH_LEFT)
 
1400
    {
 
1401
      /* if current setting is not the same as previous setting */
 
1402
      if (devc->m_fDACMute[LineIndex] != Mute)
 
1403
        {
 
1404
          devc->m_fDACMute[LineIndex] = Mute;
 
1405
          if (LineIndex == LINE_GAIN_L)
 
1406
            {
 
1407
              WriteWM8770 (devc, gWMRegister[LINE_GAIN_L],
 
1408
                           devc->
 
1409
                           m_DACVolume[LINE_GAIN_L] | ((Mute) ? 0x20 : 0x00));
 
1410
            }
 
1411
          else
 
1412
            {
 
1413
              SetVolReg (devc, LineIndex);
 
1414
            }
 
1415
        }
 
1416
    }
 
1417
 
 
1418
  /* See if this is for right channel */
 
1419
  if (ChannelID & CH_RIGHT)
 
1420
    {
 
1421
      LineIndex++;
 
1422
      /* if current setting is not the same as previous setting */
 
1423
      if (devc->m_fDACMute[LineIndex] != Mute)
 
1424
        {
 
1425
          devc->m_fDACMute[LineIndex] = Mute;
 
1426
          if (LineIndex == LINE_GAIN_R)
 
1427
            {
 
1428
              WriteWM8770 (devc, gWMRegister[LINE_GAIN_R],
 
1429
                           devc->
 
1430
                           m_DACVolume[LINE_GAIN_R] | ((Mute) ? 0x20 : 0x00));
 
1431
            }
 
1432
          else
 
1433
            {
 
1434
              SetVolReg (devc, LineIndex);
 
1435
            }
 
1436
        }
 
1437
    }
 
1438
  /* m_pAdapter->SetDirty(); *//* TODO */
 
1439
}
 
1440
 
 
1441
 
 
1442
 
 
1443
/*=============================================================================
 
1444
  Function    : SetVolume
 
1445
-------------------------------------------------------------------------------
 
1446
  Description : 
 
1447
  Returns     : VOID  -> 
 
1448
  Parameters  : IN  ICE_HW_PARAM*   HwParm -> 
 
1449
-------------------------------------------------------------------------------
 
1450
  Notes       : 
 
1451
=============================================================================*/
 
1452
static void SetDACVolume
 
1453
  (envy24ht_devc * devc, IN ULONG ChannelID, IN UCHAR Volume)
 
1454
{
 
1455
  ULONG LineIndex;
 
1456
  WORD LeftRight;
 
1457
  BOOLEAN VolChnged = 0;
 
1458
 
 
1459
  /* Convert ChannelID to line index */
 
1460
  LineIndex = ChannelID >> 15;
 
1461
  /* Get the left/right side */
 
1462
  LeftRight = (WORD) (ChannelID & 0xffff);
 
1463
 
 
1464
  /* Check if left volume is changed */
 
1465
  if (LeftRight & CH_LEFT)
 
1466
    {
 
1467
      if (devc->m_DACVolume[LineIndex] != Volume)
 
1468
        {
 
1469
          devc->m_DACVolume[LineIndex] = Volume;
 
1470
          VolChnged = 1;
 
1471
        }
 
1472
    }
 
1473
 
 
1474
  /* Check if right volume is changed */
 
1475
  if (LeftRight & CH_RIGHT)
 
1476
    {
 
1477
      if (devc->m_DACVolume[LineIndex + 1] != Volume)
 
1478
        {
 
1479
          devc->m_DACVolume[LineIndex + 1] = Volume;
 
1480
          VolChnged = 1;
 
1481
        }
 
1482
    }
 
1483
 
 
1484
  /* If any volume is changed, need to touch hardware */
 
1485
  if (VolChnged)
 
1486
    {
 
1487
      /* check if this is for input gain */
 
1488
      if ((ChannelID >> 16) == IN_12)
 
1489
        {
 
1490
          USHORT WMValue = (USHORT) Volume;
 
1491
#ifdef NULL_DB
 
1492
          WMValue = 0x0C;
 
1493
#endif
 
1494
          if (LeftRight & CH_LEFT)
 
1495
            WriteWM8770 (devc, gWMRegister[LineIndex], WMValue);
 
1496
          if (LeftRight & CH_RIGHT)
 
1497
            WriteWM8770 (devc, gWMRegister[LineIndex + 1], WMValue);
 
1498
        }
 
1499
      else
 
1500
        /* Yap, now check if this is for master volume */
 
1501
      if ((ChannelID >> 16) == OUT_MASTER)
 
1502
        {
 
1503
          int i;
 
1504
          /* Need to do it for every single line (excluding Master and Gain) */
 
1505
          for (i = 0; i <= LINE_OUT_4R; i++)
 
1506
            {
 
1507
              SetVolReg (devc, i);
 
1508
            }
 
1509
        }
 
1510
      else
 
1511
        {
 
1512
          if (LeftRight & CH_LEFT)
 
1513
            SetVolReg (devc, LineIndex);
 
1514
          if (LeftRight & CH_RIGHT)
 
1515
            SetVolReg (devc, LineIndex + 1);
 
1516
        }
 
1517
    }
 
1518
  /* m_pAdapter->SetDirty(); TODO */
 
1519
}
 
1520
 
 
1521
 
 
1522
/*! \fn =======================================================================
 
1523
 Function    : GetVolume
 
1524
-------------------------------------------------------------------------------
 
1525
 Description : 
 
1526
 Returns     : UCHAR  -> 
 
1527
 Parameters  : IN ULONG    ChannelID -> 
 
1528
-------------------------------------------------------------------------------
 
1529
 Notes       : 
 
1530
=============================================================================*/
 
1531
static UCHAR
 
1532
GetDACVolume (envy24ht_devc * devc, IN ULONG ChannelID)
 
1533
{
 
1534
  UCHAR Value;
 
1535
  USHORT LeftRight;
 
1536
  ULONG LineIndex;
 
1537
 
 
1538
  /* Convert ChannelID to line index */
 
1539
  LineIndex = ChannelID >> 15;
 
1540
  /* Get the left/right side */
 
1541
  LeftRight = (USHORT) (ChannelID & 0xffff);
 
1542
 
 
1543
  if (LeftRight == CH_LEFT)
 
1544
    {
 
1545
      Value = devc->m_DACVolume[LineIndex];
 
1546
    }
 
1547
  else
 
1548
    {
 
1549
      Value = devc->m_DACVolume[LineIndex + 1];
 
1550
    }
 
1551
  return Value;
 
1552
}
 
1553
 
 
1554
 
 
1555
#if 0
 
1556
/*! \fn =======================================================================
 
1557
 Function    : GetMute
 
1558
-------------------------------------------------------------------------------
 
1559
 Description : 
 
1560
 Returns     : BOOLEAN  -> 
 
1561
 Parameters  : IN ULONG    ChannelID -> 
 
1562
-------------------------------------------------------------------------------
 
1563
 Notes       : 
 
1564
=============================================================================*/
 
1565
static BOOLEAN
 
1566
GetDACMute (envy24ht_devc * devc, IN ULONG ChannelID)
 
1567
{
 
1568
  BOOLEAN Value;
 
1569
  USHORT LeftRight;
 
1570
  ULONG LineIndex;
 
1571
 
 
1572
  /* Convert ChannelID to line index */
 
1573
  LineIndex = ChannelID >> 15;
 
1574
  /* Get the left/right side */
 
1575
  LeftRight = (USHORT) (ChannelID & 0xffff);
 
1576
 
 
1577
  if (LeftRight == CH_LEFT)
 
1578
    {
 
1579
      Value = devc->m_fDACMute[LineIndex];
 
1580
    }
 
1581
  else
 
1582
    {
 
1583
      Value = devc->m_fDACMute[LineIndex + 1];
 
1584
    }
 
1585
  return Value;
 
1586
}
 
1587
#endif
 
1588
 
 
1589
/*! \fn =======================================================================
 
1590
 Function    : SetADCGain
 
1591
-------------------------------------------------------------------------------
 
1592
 Description : 
 
1593
 Parameters  : IN ULONG Index -> 
 
1594
             : IN ULONG Value -> 
 
1595
             : IN ULONG Channel -> 
 
1596
-------------------------------------------------------------------------------
 
1597
 Notes       : 
 
1598
=============================================================================*/
 
1599
static void SetADCGain
 
1600
  (envy24ht_devc * devc, IN ULONG Index, IN USHORT Value, IN ULONG Channel)
 
1601
{
 
1602
  UCHAR WMReg = 0x19;
 
1603
  USHORT WMValue;
 
1604
 
 
1605
  /* Set only selected Line */
 
1606
  if (Index != devc->m_ADCIndex)
 
1607
    return;
 
1608
 
 
1609
  switch (Channel)
 
1610
    {
 
1611
    case CH_LEFT:
 
1612
      devc->m_ADCVolume[Index] =
 
1613
        (Value << 8) | (devc->m_ADCVolume[Index] & 0x00FF);
 
1614
      break;
 
1615
    case CH_BOTH:
 
1616
      devc->m_ADCVolume[Index] = (Value << 8) | Value;
 
1617
      break;
 
1618
    case CH_NOP:
 
1619
      /* Hold Value */
 
1620
      break;
 
1621
    case CH_RIGHT:
 
1622
    default:
 
1623
      devc->m_ADCVolume[Index] = Value | (devc->m_ADCVolume[Index] & 0xFF00);
 
1624
 
 
1625
    }
 
1626
  WMValue =
 
1627
    ((devc->m_ADCVolume[Index] & 0x00FF) <
 
1628
     0x1F) ? (devc->m_ADCVolume[Index] & 0x00FF) : 0x1F;
 
1629
#ifdef NULL_DB
 
1630
  WMValue = 0x0C;
 
1631
#endif
 
1632
  WriteWM8770 (devc, WMReg, WMValue);
 
1633
  WMValue = (((devc->m_ADCVolume[Index] >> 8) & 0x00FF) < 0x1F) ?
 
1634
    ((devc->m_ADCVolume[Index] >> 8) & 0x00FF) : 0x1F;
 
1635
#ifdef NULL_DB
 
1636
  WMValue = 0x0C;
 
1637
#endif
 
1638
  WriteWM8770 (devc, WMReg + 1, WMValue);
 
1639
  /* Force saving of registers */
 
1640
  /* devc->m_pAdapter->SetDirty(); TODO */
 
1641
}
 
1642
 
 
1643
#if 0
 
1644
/*! \fn =======================================================================
 
1645
 Function    : GetADCGain
 
1646
-------------------------------------------------------------------------------
 
1647
 Description : 
 
1648
 Returns     : UCHAR  -> 
 
1649
 Parameters  : IN ULONG    Index -> 
 
1650
             : IN ULONG    Channel -> 
 
1651
-------------------------------------------------------------------------------
 
1652
 Notes       : 
 
1653
=============================================================================*/
 
1654
static UCHAR GetADCGain
 
1655
  (envy24ht_devc * devc, IN ULONG Index, IN ULONG Channel)
 
1656
{
 
1657
  UCHAR Value;
 
1658
 
 
1659
  if (Channel == CH_LEFT)
 
1660
    {
 
1661
      Value = (UCHAR) ((devc->m_ADCVolume[Index] >> 8) & 0xFF);
 
1662
    }
 
1663
  else
 
1664
    {
 
1665
      Value = (UCHAR) (devc->m_ADCVolume[Index] & 0xFF);
 
1666
    }
 
1667
  return Value;
 
1668
}
 
1669
#endif
 
1670
 
 
1671
/*! \fn =======================================================================
 
1672
 Function    : SetADCMux
 
1673
-------------------------------------------------------------------------------
 
1674
 Description : 
 
1675
 Parameters  : IN Value -> 
 
1676
-------------------------------------------------------------------------------
 
1677
 Notes       : 
 
1678
=============================================================================*/
 
1679
static void
 
1680
SetADCMux (envy24ht_devc * devc, IN ULONG Value)
 
1681
{
 
1682
  UCHAR MuxVal = 0;
 
1683
  BOOLEAN fAU;
 
1684
 
 
1685
  /* Store to shadow register */
 
1686
  devc->m_ADCMux = Value;
 
1687
  devc->m_fSPDIFRecord = 0;
 
1688
  fAU = (devc->subvendor == SSID_AUREON_UNIVERSE);
 
1689
  switch (Value)
 
1690
    {
 
1691
    case CD_IN_MUX_TP_PIN:
 
1692
      devc->m_ADCIndex = ADC_CD;
 
1693
      MuxVal = (fAU) ? 0x11 : 0x00;
 
1694
      break;
 
1695
    case LINE_IN_MUX_TP_PIN:
 
1696
      devc->m_ADCIndex = ADC_LINE;
 
1697
      MuxVal = (fAU) ? 0x33 : 0x22;
 
1698
      break;
 
1699
    case AUX_IN_MUX_TP_PIN:
 
1700
      devc->m_ADCIndex = ADC_AUX;
 
1701
      MuxVal = (fAU) ? devc->m_AuxMux : 0x11;
 
1702
      break;
 
1703
    case MIC_IN_MUX_TP_PIN:
 
1704
      devc->m_ADCIndex = ADC_MIC;
 
1705
      MuxVal = (fAU) ? 0x55 : 0x33;
 
1706
      break;
 
1707
    case DIG_IN_MUX_TP_PIN:
 
1708
      /* Use SPDIF DMA channel */
 
1709
      devc->m_fSPDIFRecord = 1;
 
1710
      break;
 
1711
    case PHONO_IN_MUX_PIN:
 
1712
      devc->m_ADCIndex = ADC_PHONO;
 
1713
      MuxVal = 0x22;
 
1714
      break;
 
1715
    case STEREO_MIX_MUX_TP_PIN:
 
1716
      devc->m_ADCIndex = ADC_STEREO_MIX;
 
1717
      MuxVal = (fAU) ? 0x77 : 0x44;
 
1718
      break;
 
1719
 
 
1720
    default:
 
1721
      devc->m_ADCIndex = ADC_LINE;
 
1722
      MuxVal = 0x22;
 
1723
 
 
1724
    }
 
1725
  WriteWM8770 (devc, WM_ADC_INPUT_MX, (UCHAR) MuxVal);
 
1726
  /* Reset GAIN */
 
1727
  SetADCGain (devc, devc->m_ADCIndex, 0, CH_NOP);
 
1728
  /* Update PCA config */
 
1729
  WritePCA (devc);
 
1730
  /* Force saving of registers */
 
1731
  /*devc->m_pAdapter->SetDirty(); TODO */
 
1732
}
 
1733
 
 
1734
/*! \fn =======================================================================
 
1735
 Function    : InitWM8770
 
1736
-------------------------------------------------------------------------------
 
1737
 Description : 
 
1738
-------------------------------------------------------------------------------
 
1739
 Notes       : Call before Registry Read
 
1740
=============================================================================*/
 
1741
static void
 
1742
InitWM8770 (envy24ht_devc * devc)
 
1743
{
 
1744
    /*----------------------------------------------------------------------------
 
1745
        Reset WM8770   
 
1746
    -----------------------------------------------------------------------------*/
 
1747
  /* Set SPI Mode */
 
1748
  WriteGPIO (devc, 0, GPIO_WM8770_RS_MASK);
 
1749
  oss_udelay (3);
 
1750
  WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK);
 
1751
  oss_udelay (3);
 
1752
  WriteGPIO (devc, GPIO_WM8770_RS_MASK, GPIO_WM8770_RS_MASK);
 
1753
  oss_udelay (100);
 
1754
 
 
1755
    /*----------------------------------------------------------------------------
 
1756
        Set defaults   
 
1757
    -----------------------------------------------------------------------------*/
 
1758
 
 
1759
  /* Output defaults */
 
1760
  SetDACVolume (devc, CH_MASTER_BOTH, WM_OUT_DEFAULT);
 
1761
  SetDACVolume (devc, CH_FRONT_BOTH, WM_OUT_DEFAULT);
 
1762
  SetDACVolume (devc, CH_REAR_BOTH, WM_OUT_DEFAULT);
 
1763
  SetDACVolume (devc, CH_CENTER, WM_OUT_DEFAULT);
 
1764
  SetDACVolume (devc, CH_LFE, WM_OUT_DEFAULT);
 
1765
  SetDACVolume (devc, CH_BS_BOTH, WM_OUT_DEFAULT);
 
1766
  SetDACMute (devc, CH_MASTER_BOTH, 0);
 
1767
  SetDACMute (devc, CH_FRONT_BOTH, 0);
 
1768
  SetDACMute (devc, CH_REAR_BOTH, 0);
 
1769
  SetDACMute (devc, CH_CENTER, 0);
 
1770
  SetDACMute (devc, CH_LFE, 0);
 
1771
  SetDACMute (devc, CH_BS_BOTH, 0);
 
1772
  /* Input */
 
1773
  SetADCGain (devc, ADC_CD, WM_INP_DEFAULT, CH_BOTH);
 
1774
  SetADCGain (devc, ADC_AUX, WM_INP_DEFAULT, CH_BOTH);
 
1775
  SetADCGain (devc, ADC_LINE, WM_INP_DEFAULT, CH_BOTH);
 
1776
  SetADCGain (devc, ADC_MIC, WM_INP_DEFAULT, CH_BOTH);
 
1777
  /* Mux */
 
1778
  SetADCMux (devc, STEREO_MIX_MUX_TP_PIN);
 
1779
 
 
1780
  /* At least Power DAC & ADC */
 
1781
  WriteWM8770 (devc, WM_POWER_CNTRL, 0x0000);
 
1782
  /* Power ADC Input Mux */
 
1783
  WriteWM8770 (devc, WM_ADC_INPUT_MX, 0x0000);
 
1784
  /* Enable Aux-Output */
 
1785
 
 
1786
  if (devc->subvendor == SSID_PHASE28)
 
1787
    {
 
1788
      WriteWM8770 (devc, WM_OUT12_SELECT, 0x0009);
 
1789
      WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009);
 
1790
    }
 
1791
  else
 
1792
    {
 
1793
      WriteWM8770 (devc, WM_OUT12_SELECT, 0x000b);
 
1794
      WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009);
 
1795
    }
 
1796
  /* Init Master Mode Register */
 
1797
  WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012);
 
1798
 
 
1799
}
 
1800
 
 
1801
/*! \fn =======================================================================
 
1802
 Function    : InitCS8415
 
1803
-------------------------------------------------------------------------------
 
1804
 Description : 
 
1805
 Returns     : void  -> 
 
1806
-------------------------------------------------------------------------------
 
1807
 Notes       : Has to be called after InitWM8770 since RST must be "high"
 
1808
=============================================================================*/
 
1809
static void
 
1810
InitCS8415 (envy24ht_devc * devc)
 
1811
{
 
1812
 
 
1813
  /* Init Remote-Controller */
 
1814
  if (devc->subvendor == SSID_AUREON_UNIVERSE)
 
1815
    {
 
1816
      UCHAR bByte[2];
 
1817
      bByte[0] = (UCHAR) ((AUREON_REMOTE_ID >> 8) & 0xFF);
 
1818
      bByte[1] = (UCHAR) AUREON_REMOTE_ID;
 
1819
      IICWriteBuffer (devc, AUREON_REMOTE_CNTRL, bByte, 2, 200);
 
1820
    }
 
1821
    /*----------------------------------------------------------------------------
 
1822
        Reset CS8415   
 
1823
    -----------------------------------------------------------------------------*/
 
1824
  /* Set SPI Mode */
 
1825
  WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
 
1826
  oss_udelay (3);
 
1827
  WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
 
1828
  oss_udelay (100);
 
1829
 
 
1830
  /* Set defaults */
 
1831
  WriteCS8415 (devc, CS_CONTROL_1, 0x80);
 
1832
  /* SPDIF mux to RXP1 */
 
1833
  WriteCS8415 (devc, CS_CONTROL_2, 0x01);
 
1834
  WriteCS8415 (devc, CS_CLK_SRC_CNTRL, 0x41);
 
1835
  WriteCS8415 (devc, CS_SER_OUT_FORMAT, 0x05);
 
1836
 
 
1837
  /* all other register remain to their defaults */
 
1838
 
 
1839
}
 
1840
 
 
1841
#define GPIO_WAIT 10
 
1842
 
 
1843
/*! \fn =======================================================================
 
1844
 Function    : WriteAC97Codec
 
1845
-------------------------------------------------------------------------------
 
1846
 Description : Writes to TT-AC97 Interface
 
1847
 Parameters  : IN  ULONG       Register -> 
 
1848
             : IN  ULONG      Data -> 
 
1849
-------------------------------------------------------------------------------
 
1850
 Notes       : 
 
1851
=============================================================================*/
 
1852
static void WriteAC97Codec
 
1853
  (envy24ht_devc * devc, IN ULONG Register, IN ULONG Data)
 
1854
{
 
1855
  UCHAR TTData;
 
1856
 
 
1857
#ifdef TTTT
 
1858
  /* CL_TEST */
 
1859
  /* Reset AC97 */
 
1860
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
1861
  oss_udelay (3);
 
1862
  WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
 
1863
  oss_udelay (3);
 
1864
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
1865
  oss_udelay (3);
 
1866
  /* Unmute Master */
 
1867
  WriteAC97Codec (devc, 0x02, 0x00);
 
1868
#endif
 
1869
 
 
1870
  /* m_pAdapter->HwEnter(); TODO */
 
1871
 
 
1872
  oss_udelay (GPIO_WAIT);
 
1873
 
 
1874
  /* Reset all LD Pins and GO Pin */
 
1875
  WriteGPIO (devc, 0,
 
1876
             GPIO_LD_DATA_H_MASK | GPIO_LD_DATA_L_MASK | GPIO_LD_ADR_MASK |
 
1877
             GPIO_GO_MASK);
 
1878
 
 
1879
 
 
1880
  /* apply address to TT-AC97 Interface */
 
1881
  WriteGPIO (devc, Register, GPIO_DATA_ADR_MASK);
 
1882
 
 
1883
  /* Set "Load Address" Pin */
 
1884
  oss_udelay (GPIO_WAIT);
 
1885
  WriteGPIO (devc, GPIO_LD_ADR_MASK, GPIO_LD_ADR_MASK);
 
1886
 
 
1887
  /* Reset "Load Address" Pin */
 
1888
  oss_udelay (GPIO_WAIT);
 
1889
  WriteGPIO (devc, 0, GPIO_LD_ADR_MASK);
 
1890
 
 
1891
  /* apply data low to TT-AC97 Interface */
 
1892
  oss_udelay (GPIO_WAIT);
 
1893
  TTData = (UCHAR) (Data & 0x000000FF);
 
1894
  WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK);
 
1895
 
 
1896
  /* Set "Load Data low" Pin */
 
1897
  oss_udelay (GPIO_WAIT);
 
1898
  WriteGPIO (devc, GPIO_LD_DATA_L_MASK, GPIO_LD_DATA_L_MASK);
 
1899
 
 
1900
  /* Reset "Load Data low" Pin */
 
1901
  oss_udelay (GPIO_WAIT);
 
1902
  WriteGPIO (devc, 0, GPIO_LD_DATA_L_MASK);
 
1903
 
 
1904
  /* apply data high to TT-AC97 Interface */
 
1905
  oss_udelay (GPIO_WAIT);
 
1906
  TTData = (UCHAR) ((Data >> 8) & 0x000000FF);
 
1907
  WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK);
 
1908
 
 
1909
  /* Set "Load Data high" Pin */
 
1910
  oss_udelay (GPIO_WAIT);
 
1911
  WriteGPIO (devc, GPIO_LD_DATA_H_MASK, GPIO_LD_DATA_H_MASK);
 
1912
 
 
1913
  /* Reset "Load Data high" Pin */
 
1914
  oss_udelay (GPIO_WAIT);
 
1915
  WriteGPIO (devc, 0, GPIO_LD_DATA_H_MASK);
 
1916
 
 
1917
  /* Set and immediately reset "GO" Pin */
 
1918
  oss_udelay (GPIO_WAIT);
 
1919
  WriteGPIO (devc, GPIO_GO_MASK, GPIO_GO_MASK);
 
1920
  WriteGPIO (devc, 0, GPIO_GO_MASK);
 
1921
  /* m_pAdapter->HwLeave(); *//* TODO */
 
1922
 
 
1923
}
 
1924
 
 
1925
/*! \fn =======================================================================
 
1926
 Function    : SetAC97Volume
 
1927
-------------------------------------------------------------------------------
 
1928
 Description : 
 
1929
 Parameters  : IN ULONG    Index -> 
 
1930
             : IN UHSORT   Value -> 
 
1931
-------------------------------------------------------------------------------
 
1932
 Notes       : 
 
1933
=============================================================================*/
 
1934
static void SetAC97Volume
 
1935
  (envy24ht_devc * devc, IN ULONG Index, IN USHORT left, IN USHORT right)
 
1936
{
 
1937
  int AC97Reg = 0, value;
 
1938
 
 
1939
  devc->m_AC97Volume[Index] = left | (right << 8);
 
1940
 
 
1941
  left = AC97_INP_MAX - left;
 
1942
  right = AC97_INP_MAX - right;
 
1943
 
 
1944
  value = (left << 8) | right;
 
1945
 
 
1946
  switch (devc->subvendor)
 
1947
    {
 
1948
    case SSID_AUREON_SKY:
 
1949
    case SSID_PRODIGY71:
 
1950
    case SSID_AUREON_SPACE:
 
1951
      switch (Index)
 
1952
        {
 
1953
        case AC97_MIC:
 
1954
          AC97Reg = AC97_IDXREG_MIC_IN;
 
1955
          break;
 
1956
        case AC97_LINE:
 
1957
          AC97Reg = AC97_IDXREG_LINE_IN;
 
1958
          break;
 
1959
        case AC97_CD:
 
1960
          AC97Reg = AC97_IDXREG_CD_IN;
 
1961
          break;
 
1962
        case AC97_AUX:
 
1963
          AC97Reg = AC97_IDXREG_AUX_IN;
 
1964
          break;
 
1965
        default:
 
1966
          cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
 
1967
          return;
 
1968
        }
 
1969
      break;
 
1970
    case SSID_AUREON_UNIVERSE:
 
1971
      switch (Index)
 
1972
        {
 
1973
        case AC97_MIC:
 
1974
          AC97Reg = AC97_IDXREG_MIC_IN;
 
1975
          break;
 
1976
        case AC97_LINE:
 
1977
          AC97Reg = AC97_IDXREG_LINE_IN;
 
1978
          break;
 
1979
        case AC97_CD:
 
1980
          AC97Reg = AC97_IDXREG_AUX_IN;
 
1981
          break;
 
1982
        case AC97_PHONO:
 
1983
          AC97Reg = AC97_IDXREG_CD_IN;
 
1984
          break;
 
1985
        case AC97_AUX:
 
1986
        case AC97_LINE2:
 
1987
          AC97Reg = AC97_IDXREG_VIDEO_IN;
 
1988
          break;
 
1989
        default:
 
1990
          cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
 
1991
          return;
 
1992
 
 
1993
        }
 
1994
      break;
 
1995
    }
 
1996
  if (!devc->m_fAC97Mute[Index])
 
1997
    {
 
1998
      WriteAC97Codec (devc, AC97Reg, value);
 
1999
    }
 
2000
  /* Force saving of registers */
 
2001
  /* m_pAdapter->SetDirty(); TODO */
 
2002
}
 
2003
 
 
2004
 
 
2005
/*! \fn =======================================================================
 
2006
 Function    : GetAC97Volume
 
2007
-------------------------------------------------------------------------------
 
2008
 Description : 
 
2009
 Returns     : UCHAR  -> 
 
2010
 Parameters  : IN ULONG    Index -> 
 
2011
             : IN ULONG    Channel -> 
 
2012
-------------------------------------------------------------------------------
 
2013
 Notes       : 
 
2014
=============================================================================*/
 
2015
static USHORT
 
2016
GetAC97Volume (envy24ht_devc * devc, IN ULONG Index)
 
2017
{
 
2018
  return devc->m_AC97Volume[Index];
 
2019
}
 
2020
 
 
2021
/*! \fn =======================================================================
 
2022
 Function    : SetAC97Mute
 
2023
-------------------------------------------------------------------------------
 
2024
 Description : 
 
2025
 Returns     : void  -> 
 
2026
 Parameters  : IN ULONG    Index -> 
 
2027
-------------------------------------------------------------------------------
 
2028
 Notes       : 
 
2029
=============================================================================*/
 
2030
static void
 
2031
SetAC97Mute (envy24ht_devc * devc, IN ULONG Index, BOOLEAN OnOff)
 
2032
{
 
2033
  UCHAR AC97Reg = 0;
 
2034
  devc->m_fAC97Mute[Index] = OnOff;
 
2035
  switch (devc->subvendor)
 
2036
    {
 
2037
    case SSID_AUREON_SKY:
 
2038
    case SSID_PRODIGY71:
 
2039
    case SSID_AUREON_SPACE:
 
2040
      switch (Index)
 
2041
        {
 
2042
        case AC97_MIC:
 
2043
          AC97Reg = AC97_IDXREG_MIC_IN;
 
2044
          break;
 
2045
        case AC97_LINE:
 
2046
          AC97Reg = AC97_IDXREG_LINE_IN;
 
2047
          break;
 
2048
        case AC97_CD:
 
2049
          AC97Reg = AC97_IDXREG_CD_IN;
 
2050
          break;
 
2051
        case AC97_AUX:
 
2052
          AC97Reg = AC97_IDXREG_AUX_IN;
 
2053
          break;
 
2054
        default:
 
2055
          cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
 
2056
          return;
 
2057
        }
 
2058
      break;
 
2059
    case SSID_AUREON_UNIVERSE:
 
2060
      switch (Index)
 
2061
        {
 
2062
        case AC97_MIC:
 
2063
          AC97Reg = AC97_IDXREG_MIC_IN;
 
2064
          break;
 
2065
        case AC97_LINE:
 
2066
          AC97Reg = AC97_IDXREG_LINE_IN;
 
2067
          break;
 
2068
        case AC97_CD:
 
2069
          AC97Reg = AC97_IDXREG_AUX_IN;
 
2070
          break;
 
2071
        case AC97_PHONO:
 
2072
          AC97Reg = AC97_IDXREG_CD_IN;
 
2073
          break;
 
2074
        case AC97_AUX:
 
2075
        case AC97_LINE2:
 
2076
          AC97Reg = AC97_IDXREG_VIDEO_IN;
 
2077
          break;
 
2078
        default:
 
2079
          cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
 
2080
          return;
 
2081
        }
 
2082
      break;
 
2083
    }
 
2084
#ifdef AC97_MUTE
 
2085
  WriteAC97Codec (devc, AC97Reg, 0x8000);
 
2086
#else
 
2087
  WriteAC97Codec (devc, AC97Reg,
 
2088
                  (OnOff) ? 0x8000 : devc->m_AC97Volume[Index]);
 
2089
#endif
 
2090
 
 
2091
  /* Force saving of registers */
 
2092
  /* m_pAdapter->SetDirty(); *//* TODO */
 
2093
}
 
2094
 
 
2095
/*! \fn =======================================================================
 
2096
 Function    : InitAC97
 
2097
-------------------------------------------------------------------------------
 
2098
 Description : 
 
2099
 Returns     : void  -> 
 
2100
-------------------------------------------------------------------------------
 
2101
 Notes       : Call before Registry Read
 
2102
=============================================================================*/
 
2103
static void
 
2104
InitAC97 (envy24ht_devc * devc)
 
2105
{
 
2106
  /* Reset AC97 */
 
2107
  oss_udelay (30);
 
2108
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
2109
  oss_udelay (3);
 
2110
  WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
 
2111
  oss_udelay (3);
 
2112
  WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
 
2113
  oss_udelay (3);
 
2114
 
 
2115
  /* Unmute Master */
 
2116
  WriteAC97Codec (devc, 0x02, 0x00);
 
2117
 
 
2118
    /*----------------------------------------------------------------------------
 
2119
        Set defaults   
 
2120
    -----------------------------------------------------------------------------*/
 
2121
  /* Volume */
 
2122
  SetAC97Volume (devc, AC97_MIC, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
 
2123
  SetAC97Volume (devc, AC97_LINE, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
 
2124
  SetAC97Volume (devc, AC97_AUX, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
 
2125
  SetAC97Volume (devc, AC97_CD, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
 
2126
  /* Mute */
 
2127
  SetAC97Mute (devc, AC97_MIC, 0);
 
2128
  SetAC97Mute (devc, AC97_LINE, 0);
 
2129
  SetAC97Mute (devc, AC97_AUX, 0);
 
2130
  SetAC97Mute (devc, AC97_CD, 0);
 
2131
}
 
2132
 
 
2133
/*! \fn =======================================================================
 
2134
 Function    : SetSampleRate
 
2135
-------------------------------------------------------------------------------
 
2136
 Description : 
 
2137
 Returns     : NTSTATUS  -> 
 
2138
 Parameters  : IN ULONG SampleRate -> 
 
2139
-------------------------------------------------------------------------------
 
2140
 Notes       : 
 
2141
=============================================================================*/
 
2142
static void
 
2143
SetSampleRate (envy24ht_devc * devc, IN ULONG SampleRate)
 
2144
{
 
2145
  WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012);
 
2146
 
 
2147
  switch (SampleRate)
 
2148
    {
 
2149
    case 48000:
 
2150
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_48KHZ, WIDTH_BYTE);
 
2151
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2152
                           WIDTH_BYTE | BITS_OFF);
 
2153
      /* WRITE_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG,(~MT_128X)&READ_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG)); */
 
2154
      break;
 
2155
    case 24000:
 
2156
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_24KHZ, WIDTH_BYTE);
 
2157
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2158
                           WIDTH_BYTE | BITS_OFF);
 
2159
      break;
 
2160
    case 12000:
 
2161
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_12KHZ, WIDTH_BYTE);
 
2162
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2163
                           WIDTH_BYTE | BITS_OFF);
 
2164
      break;
 
2165
    case 9600:
 
2166
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_9p6KHZ, WIDTH_BYTE);
 
2167
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2168
                           WIDTH_BYTE | BITS_OFF);
 
2169
      break;
 
2170
    case 32000:
 
2171
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_32KHZ, WIDTH_BYTE);
 
2172
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2173
                           WIDTH_BYTE | BITS_OFF);
 
2174
      break;
 
2175
    case 16000:
 
2176
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_16KHZ, WIDTH_BYTE);
 
2177
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2178
                           WIDTH_BYTE | BITS_OFF);
 
2179
      break;
 
2180
    case 8000:
 
2181
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_8KHZ, WIDTH_BYTE);
 
2182
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2183
                           WIDTH_BYTE | BITS_OFF);
 
2184
      break;
 
2185
    case 96000:
 
2186
      WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
 
2187
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_96KHZ, WIDTH_BYTE);
 
2188
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2189
                           WIDTH_BYTE | BITS_OFF);
 
2190
      break;
 
2191
    case 192000:
 
2192
      WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
 
2193
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_192KHZ, WIDTH_BYTE);
 
2194
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2195
                           WIDTH_BYTE | BITS_ON);
 
2196
      break;
 
2197
    case 64000:
 
2198
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_64KHZ, WIDTH_BYTE);
 
2199
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2200
                           WIDTH_BYTE | BITS_OFF);
 
2201
      break;
 
2202
    case 44100:
 
2203
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_44p1KHZ, WIDTH_BYTE);
 
2204
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2205
                           WIDTH_BYTE | BITS_OFF);
 
2206
      break;
 
2207
    case 22050:
 
2208
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_22p05KHZ, WIDTH_BYTE);
 
2209
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2210
                           WIDTH_BYTE | BITS_OFF);
 
2211
      break;
 
2212
    case 11025:
 
2213
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_11p025KHZ, WIDTH_BYTE);
 
2214
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2215
                           WIDTH_BYTE | BITS_OFF);
 
2216
      break;
 
2217
    case 88200:
 
2218
      WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
 
2219
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_88p2KHZ, WIDTH_BYTE);
 
2220
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2221
                           WIDTH_BYTE | BITS_OFF);
 
2222
      break;
 
2223
    case 176400:
 
2224
      WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
 
2225
      WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_176p4KHZ, WIDTH_BYTE);
 
2226
      ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
 
2227
                           WIDTH_BYTE | BITS_OFF);
 
2228
      break;
 
2229
    default:
 
2230
      break;
 
2231
 
 
2232
    }
 
2233
}
 
2234
 
 
2235
static void
 
2236
aureon_card_init (envy24ht_devc * devc)
 
2237
{
 
2238
 
 
2239
/* Do not change the order of the following lines */
 
2240
  Init1724 (devc);
 
2241
  ResetGPIO (devc);
 
2242
 
 
2243
  if (devc->subvendor != SSID_PHASE28)
 
2244
    InitAC97 (devc);
 
2245
  InitWM8770 (devc);
 
2246
  InitCS8415 (devc);
 
2247
/* Do not change the order of the above lines */
 
2248
 
 
2249
  SetSPDIFConfig (devc, 0);
 
2250
  /* SetSDPIFSource(devc, DIGOUT_WAVE); */
 
2251
  SetDigInSource (devc, DIGIN_COAX);
 
2252
  SetFrontjack (devc, FRONT_JACK_HEADPHONE);
 
2253
  SetLineSource (devc, SRC_LINE_REAR);
 
2254
  SetClockSource (devc, ICE_INTERNAL_CLOCK);
 
2255
 
 
2256
}
 
2257
 
 
2258
static void
 
2259
aureon_set_rate (envy24ht_devc * devc)
 
2260
{
 
2261
  SetSampleRate (devc, devc->speed);
 
2262
}
 
2263
 
 
2264
static int
 
2265
aureon_set_ctl (int dev, int ctl, unsigned int cmd, int value)
 
2266
{
 
2267
  envy24ht_devc *devc = mixer_devs[dev]->devc;
 
2268
 
 
2269
  if (cmd == SNDCTL_MIX_READ)
 
2270
    {
 
2271
      switch (ctl)
 
2272
        {
 
2273
        case 1:
 
2274
          return devc->m_LineInSource;
 
2275
        case 3:
 
2276
          return devc->m_DigInSource;
 
2277
        case 4:
 
2278
          return devc->m_Frontjack;
 
2279
        }
 
2280
    }
 
2281
 
 
2282
  if (cmd == SNDCTL_MIX_WRITE)
 
2283
    {
 
2284
      switch (ctl)
 
2285
        {
 
2286
        case 1:
 
2287
          SetLineSource (devc, value);
 
2288
          return devc->m_LineInSource;
 
2289
        case 3:
 
2290
          SetDigInSource (devc, value);
 
2291
          return devc->m_DigInSource;
 
2292
        case 4:
 
2293
          SetFrontjack (devc, value);
 
2294
          return devc->m_Frontjack;
 
2295
        }
 
2296
    }
 
2297
 
 
2298
  return OSS_EINVAL;
 
2299
}
 
2300
 
 
2301
static int
 
2302
aureon_set_vol (int dev, int ChannelID, unsigned int cmd, int value)
 
2303
{
 
2304
  envy24ht_devc *devc = mixer_devs[dev]->devc;
 
2305
  ULONG LineIndex;
 
2306
  WORD LeftRight;
 
2307
  int left, right;
 
2308
 
 
2309
  /* Convert ChannelID to line index */
 
2310
  LineIndex = ChannelID >> 15;
 
2311
  /* Get the left/right side */
 
2312
  LeftRight = (WORD) (ChannelID & 0xffff);
 
2313
 
 
2314
  if (cmd == SNDCTL_MIX_READ)
 
2315
    {
 
2316
      left = right = 0;
 
2317
      if (LeftRight & CH_LEFT)
 
2318
        left = GetDACVolume (devc, (LineIndex << 15) | CH_LEFT);
 
2319
      if (LeftRight & CH_RIGHT)
 
2320
        right = GetDACVolume (devc, (LineIndex << 15) | CH_RIGHT);
 
2321
 
 
2322
      if (left == 0)
 
2323
        left = right;
 
2324
      else if (right == 0)
 
2325
        right = left;
 
2326
 
 
2327
      return left | (right << 8);
 
2328
    }
 
2329
 
 
2330
  if (cmd == SNDCTL_MIX_WRITE)
 
2331
    {
 
2332
      left = (value & 0xff);
 
2333
      right = ((value >> 8) & 0xff);
 
2334
 
 
2335
      if (LeftRight != CH_BOTH)
 
2336
        right = left;
 
2337
 
 
2338
      if (LeftRight & CH_LEFT)
 
2339
        SetDACVolume (devc, (LineIndex << 15) | CH_LEFT, left);
 
2340
 
 
2341
      if (LeftRight & CH_RIGHT)
 
2342
        SetDACVolume (devc, (LineIndex << 15) | CH_RIGHT, right);
 
2343
 
 
2344
      return left | (right << 8);
 
2345
    }
 
2346
 
 
2347
  return OSS_EINVAL;
 
2348
}
 
2349
 
 
2350
static int
 
2351
aureon_set_ac97 (int dev, int Index, unsigned int cmd, int value)
 
2352
{
 
2353
  envy24ht_devc *devc = mixer_devs[dev]->devc;
 
2354
  int left, right;
 
2355
 
 
2356
  if (cmd == SNDCTL_MIX_READ)
 
2357
    {
 
2358
      return GetAC97Volume (devc, Index);
 
2359
    }
 
2360
 
 
2361
  if (cmd == SNDCTL_MIX_WRITE)
 
2362
    {
 
2363
      left = (value & 0xff);
 
2364
      right = ((value >> 8) & 0xff);
 
2365
 
 
2366
      SetAC97Volume (devc, Index, left, right);
 
2367
 
 
2368
      return left | (right << 8);
 
2369
    }
 
2370
 
 
2371
  return OSS_EINVAL;
 
2372
}
 
2373
 
 
2374
 /*ARGSUSED*/ static int
 
2375
aureon_mixer_init_common (envy24ht_devc * devc, int dev, int root)
 
2376
{
 
2377
  int ctl, group;
 
2378
 
 
2379
  if ((group = mixer_ext_create_group (dev, root, "VOL")) < 0)
 
2380
    return group;
 
2381
 
 
2382
  if ((ctl = mixer_ext_create_control (dev, group,
 
2383
                                       CH_MASTER_BOTH,
 
2384
                                       aureon_set_vol,
 
2385
                                       MIXT_STEREOSLIDER, "MASTER",
 
2386
                                       WM_OUT_MAX,
 
2387
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2388
    return ctl;
 
2389
 
 
2390
  if ((ctl = mixer_ext_create_control (dev, group,
 
2391
                                       CH_FRONT_BOTH,
 
2392
                                       aureon_set_vol,
 
2393
                                       MIXT_STEREOSLIDER, "FRONT", WM_OUT_MAX,
 
2394
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2395
    return ctl;
 
2396
 
 
2397
  if ((ctl = mixer_ext_create_control (dev, group,
 
2398
                                       CH_REAR_BOTH,
 
2399
                                       aureon_set_vol,
 
2400
                                       MIXT_STEREOSLIDER, "SURROUND",
 
2401
                                       WM_OUT_MAX,
 
2402
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2403
    return ctl;
 
2404
 
 
2405
  if ((ctl = mixer_ext_create_control (dev, group,
 
2406
                                       CH_CENTER,
 
2407
                                       aureon_set_vol,
 
2408
                                       MIXT_MONOSLIDER, "CENTER", WM_OUT_MAX,
 
2409
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2410
    return ctl;
 
2411
 
 
2412
  if ((ctl = mixer_ext_create_control (dev, group,
 
2413
                                       CH_LFE,
 
2414
                                       aureon_set_vol,
 
2415
                                       MIXT_MONOSLIDER, "LFE", WM_OUT_MAX,
 
2416
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2417
    return ctl;
 
2418
 
 
2419
  if ((ctl = mixer_ext_create_control (dev, group,
 
2420
                                       CH_BS_BOTH,
 
2421
                                       aureon_set_vol,
 
2422
                                       MIXT_STEREOSLIDER, "REAR", WM_OUT_MAX,
 
2423
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2424
    return ctl;
 
2425
 
 
2426
  if ((group =
 
2427
       mixer_ext_create_group_flags (dev, root, "TERRATEC", MIXF_FLAT)) < 0)
 
2428
    return group;
 
2429
 
 
2430
  if ((ctl = mixer_ext_create_control (dev, group,
 
2431
                                       1,
 
2432
                                       aureon_set_ctl,
 
2433
                                       MIXT_ENUM, "LINESRC", 4,
 
2434
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2435
    return ctl;
 
2436
  mixer_ext_set_strings (dev, ctl, "AUX WTL REAR GROUND", 0);
 
2437
 
 
2438
  if ((ctl = mixer_ext_create_control (dev, group,
 
2439
                                       3,
 
2440
                                       aureon_set_ctl,
 
2441
                                       MIXT_ENUM, "DIGIN", 3,
 
2442
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2443
    return ctl;
 
2444
  mixer_ext_set_strings (dev, ctl, "OPTICAL COAX CD", 0);
 
2445
 
 
2446
  return 0;
 
2447
}
 
2448
 
 
2449
 /*ARGSUSED*/ static int
 
2450
aureon_mixer_init_universe (envy24ht_devc * devc, int dev, int group)
 
2451
{
 
2452
  int ctl;
 
2453
 
 
2454
  if ((group = mixer_ext_create_group (dev, group, "ENVY24_UNIVERSE")) < 0)
 
2455
    return group;
 
2456
 
 
2457
  if ((ctl = mixer_ext_create_control (dev, group,
 
2458
                                       4,
 
2459
                                       aureon_set_ctl,
 
2460
                                       MIXT_ENUM, "FRONTJACK", 3,
 
2461
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2462
    return ctl;
 
2463
  mixer_ext_set_strings (dev, ctl, "LINEIN HEADPH", 0);
 
2464
 
 
2465
  return 0;
 
2466
}
 
2467
 
 
2468
 /*ARGSUSED*/ static int
 
2469
aureon_mixer_init_ac97 (envy24ht_devc * devc, int dev, int group)
 
2470
{
 
2471
  int ctl;
 
2472
 
 
2473
  if ((group = mixer_ext_create_group (dev, group, "ENVY24_AC97")) < 0)
 
2474
    return group;
 
2475
 
 
2476
  if ((ctl = mixer_ext_create_control (dev, group,
 
2477
                                       AC97_MIC,
 
2478
                                       aureon_set_ac97,
 
2479
                                       MIXT_STEREOSLIDER, "MIC", AC97_INP_MAX,
 
2480
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2481
    return ctl;
 
2482
 
 
2483
  if ((ctl = mixer_ext_create_control (dev, group,
 
2484
                                       AC97_LINE,
 
2485
                                       aureon_set_ac97,
 
2486
                                       MIXT_STEREOSLIDER, "LINE",
 
2487
                                       AC97_INP_MAX,
 
2488
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2489
    return ctl;
 
2490
 
 
2491
  if ((ctl = mixer_ext_create_control (dev, group,
 
2492
                                       AC97_CD,
 
2493
                                       aureon_set_ac97,
 
2494
                                       MIXT_STEREOSLIDER, "CD", AC97_INP_MAX,
 
2495
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2496
    return ctl;
 
2497
 
 
2498
  if ((ctl = mixer_ext_create_control (dev, group,
 
2499
                                       AC97_PHONO,
 
2500
                                       aureon_set_ac97,
 
2501
                                       MIXT_STEREOSLIDER, "PHONO",
 
2502
                                       AC97_INP_MAX,
 
2503
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2504
    return ctl;
 
2505
 
 
2506
  if ((ctl = mixer_ext_create_control (dev, group,
 
2507
                                       AC97_AUX,
 
2508
                                       aureon_set_ac97,
 
2509
                                       MIXT_STEREOSLIDER, "AUX", AC97_INP_MAX,
 
2510
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
2511
    return ctl;
 
2512
 
 
2513
  return 0;
 
2514
}
 
2515
 
 
2516
static int
 
2517
aureon_mixer_init (envy24ht_devc * devc, int dev, int root)
 
2518
{
 
2519
  aureon_mixer_init_common (devc, dev, root);
 
2520
 
 
2521
  if (devc->subvendor == SSID_AUREON_UNIVERSE)
 
2522
    aureon_mixer_init_universe (devc, dev, root);
 
2523
 
 
2524
  if (devc->subvendor != SSID_PHASE28)
 
2525
    aureon_mixer_init_ac97 (devc, dev, root);
 
2526
  return 0;
 
2527
}
 
2528
 
 
2529
envy24ht_auxdrv_t envy24ht_aureon_auxdrv = {
 
2530
  aureon_card_init,
 
2531
  aureon_mixer_init,
 
2532
  aureon_set_rate,
 
2533
  NULL,
 
2534
  NULL,
 
2535
  NULL,                         /* aureon_private1 */
 
2536
};