Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/ice1712/aureon.c
10818 views
1
/*
2
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
3
*
4
* Lowlevel functions for Terratec Aureon cards
5
*
6
* Copyright (c) 2003 Takashi Iwai <[email protected]>
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*
22
*
23
* NOTES:
24
*
25
* - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
26
* both wm and akm codecs are pretty similar, so we can integrate
27
* both controls in the future, once if wm codecs are reused in
28
* many boards.
29
*
30
* - DAC digital volumes are not implemented in the mixer.
31
* if they show better response than DAC analog volumes, we can use them
32
* instead.
33
*
34
* Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35
* Copyright (c) 2003 Dimitromanolakis Apostolos <[email protected]>
36
*
37
* version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
38
* added 64x/128x oversampling switch (should be 64x only for 96khz)
39
* fixed some recording labels (still need to check the rest)
40
* recording is working probably thanks to correct wm8770 initialization
41
*
42
* version 0.5: Initial release:
43
* working: analog output, mixer, headphone amplifier switch
44
* not working: prety much everything else, at least i could verify that
45
* we have no digital output, no capture, pretty bad clicks and poops
46
* on mixer switch and other coll stuff.
47
*/
48
49
#include <linux/io.h>
50
#include <linux/delay.h>
51
#include <linux/interrupt.h>
52
#include <linux/init.h>
53
#include <linux/slab.h>
54
#include <linux/mutex.h>
55
56
#include <sound/core.h>
57
58
#include "ice1712.h"
59
#include "envy24ht.h"
60
#include "aureon.h"
61
#include <sound/tlv.h>
62
63
/* AC97 register cache for Aureon */
64
struct aureon_spec {
65
unsigned short stac9744[64];
66
unsigned int cs8415_mux;
67
unsigned short master[2];
68
unsigned short vol[8];
69
unsigned char pca9554_out;
70
};
71
72
/* WM8770 registers */
73
#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
74
#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
75
#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
76
#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
77
#define WM_PHASE_SWAP 0x12 /* DAC phase */
78
#define WM_DAC_CTRL1 0x13 /* DAC control bits */
79
#define WM_MUTE 0x14 /* mute controls */
80
#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
81
#define WM_INT_CTRL 0x16 /* interface control */
82
#define WM_MASTER 0x17 /* master clock and mode */
83
#define WM_POWERDOWN 0x18 /* power-down controls */
84
#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
85
#define WM_ADC_MUX 0x1b /* input MUX */
86
#define WM_OUT_MUX1 0x1c /* output MUX */
87
#define WM_OUT_MUX2 0x1e /* output MUX */
88
#define WM_RESET 0x1f /* software reset */
89
90
/* CS8415A registers */
91
#define CS8415_CTRL1 0x01
92
#define CS8415_CTRL2 0x02
93
#define CS8415_QSUB 0x14
94
#define CS8415_RATIO 0x1E
95
#define CS8415_C_BUFFER 0x20
96
#define CS8415_ID 0x7F
97
98
/* PCA9554 registers */
99
#define PCA9554_DEV 0x40 /* I2C device address */
100
#define PCA9554_IN 0x00 /* input port */
101
#define PCA9554_OUT 0x01 /* output port */
102
#define PCA9554_INVERT 0x02 /* input invert */
103
#define PCA9554_DIR 0x03 /* port directions */
104
105
/*
106
* Aureon Universe additional controls using PCA9554
107
*/
108
109
/*
110
* Send data to pca9554
111
*/
112
static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
113
unsigned char data)
114
{
115
unsigned int tmp;
116
int i, j;
117
unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
118
unsigned char val = 0;
119
120
tmp = snd_ice1712_gpio_read(ice);
121
122
snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
123
AUREON_WM_RW|AUREON_WM_CS|
124
AUREON_CS8415_CS));
125
tmp |= AUREON_WM_RW;
126
tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
127
128
tmp &= ~AUREON_SPI_MOSI;
129
tmp &= ~AUREON_SPI_CLK;
130
snd_ice1712_gpio_write(ice, tmp);
131
udelay(50);
132
133
/*
134
* send i2c stop condition and start condition
135
* to obtain sane state
136
*/
137
tmp |= AUREON_SPI_CLK;
138
snd_ice1712_gpio_write(ice, tmp);
139
udelay(50);
140
tmp |= AUREON_SPI_MOSI;
141
snd_ice1712_gpio_write(ice, tmp);
142
udelay(100);
143
tmp &= ~AUREON_SPI_MOSI;
144
snd_ice1712_gpio_write(ice, tmp);
145
udelay(50);
146
tmp &= ~AUREON_SPI_CLK;
147
snd_ice1712_gpio_write(ice, tmp);
148
udelay(100);
149
/*
150
* send device address, command and value,
151
* skipping ack cycles in between
152
*/
153
for (j = 0; j < 3; j++) {
154
switch (j) {
155
case 0:
156
val = dev;
157
break;
158
case 1:
159
val = reg;
160
break;
161
case 2:
162
val = data;
163
break;
164
}
165
for (i = 7; i >= 0; i--) {
166
tmp &= ~AUREON_SPI_CLK;
167
snd_ice1712_gpio_write(ice, tmp);
168
udelay(40);
169
if (val & (1 << i))
170
tmp |= AUREON_SPI_MOSI;
171
else
172
tmp &= ~AUREON_SPI_MOSI;
173
snd_ice1712_gpio_write(ice, tmp);
174
udelay(40);
175
tmp |= AUREON_SPI_CLK;
176
snd_ice1712_gpio_write(ice, tmp);
177
udelay(40);
178
}
179
tmp &= ~AUREON_SPI_CLK;
180
snd_ice1712_gpio_write(ice, tmp);
181
udelay(40);
182
tmp |= AUREON_SPI_CLK;
183
snd_ice1712_gpio_write(ice, tmp);
184
udelay(40);
185
tmp &= ~AUREON_SPI_CLK;
186
snd_ice1712_gpio_write(ice, tmp);
187
udelay(40);
188
}
189
tmp &= ~AUREON_SPI_CLK;
190
snd_ice1712_gpio_write(ice, tmp);
191
udelay(40);
192
tmp &= ~AUREON_SPI_MOSI;
193
snd_ice1712_gpio_write(ice, tmp);
194
udelay(40);
195
tmp |= AUREON_SPI_CLK;
196
snd_ice1712_gpio_write(ice, tmp);
197
udelay(50);
198
tmp |= AUREON_SPI_MOSI;
199
snd_ice1712_gpio_write(ice, tmp);
200
udelay(100);
201
}
202
203
static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
204
struct snd_ctl_elem_info *uinfo)
205
{
206
char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
207
208
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
209
uinfo->count = 1;
210
uinfo->value.enumerated.items = 3;
211
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
212
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
213
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
214
return 0;
215
}
216
217
static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
218
struct snd_ctl_elem_value *ucontrol)
219
{
220
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
221
struct aureon_spec *spec = ice->spec;
222
ucontrol->value.enumerated.item[0] = spec->pca9554_out;
223
return 0;
224
}
225
226
static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
227
struct snd_ctl_elem_value *ucontrol)
228
{
229
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
230
struct aureon_spec *spec = ice->spec;
231
unsigned char oval, nval;
232
int change;
233
234
nval = ucontrol->value.enumerated.item[0];
235
if (nval >= 3)
236
return -EINVAL;
237
snd_ice1712_save_gpio_status(ice);
238
oval = spec->pca9554_out;
239
change = (oval != nval);
240
if (change) {
241
aureon_pca9554_write(ice, PCA9554_OUT, nval);
242
spec->pca9554_out = nval;
243
}
244
snd_ice1712_restore_gpio_status(ice);
245
return change;
246
}
247
248
249
static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
250
unsigned short val)
251
{
252
struct aureon_spec *spec = ice->spec;
253
unsigned int tmp;
254
255
/* Send address to XILINX chip */
256
tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
257
snd_ice1712_gpio_write(ice, tmp);
258
udelay(10);
259
tmp |= AUREON_AC97_ADDR;
260
snd_ice1712_gpio_write(ice, tmp);
261
udelay(10);
262
tmp &= ~AUREON_AC97_ADDR;
263
snd_ice1712_gpio_write(ice, tmp);
264
udelay(10);
265
266
/* Send low-order byte to XILINX chip */
267
tmp &= ~AUREON_AC97_DATA_MASK;
268
tmp |= val & AUREON_AC97_DATA_MASK;
269
snd_ice1712_gpio_write(ice, tmp);
270
udelay(10);
271
tmp |= AUREON_AC97_DATA_LOW;
272
snd_ice1712_gpio_write(ice, tmp);
273
udelay(10);
274
tmp &= ~AUREON_AC97_DATA_LOW;
275
snd_ice1712_gpio_write(ice, tmp);
276
udelay(10);
277
278
/* Send high-order byte to XILINX chip */
279
tmp &= ~AUREON_AC97_DATA_MASK;
280
tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
281
282
snd_ice1712_gpio_write(ice, tmp);
283
udelay(10);
284
tmp |= AUREON_AC97_DATA_HIGH;
285
snd_ice1712_gpio_write(ice, tmp);
286
udelay(10);
287
tmp &= ~AUREON_AC97_DATA_HIGH;
288
snd_ice1712_gpio_write(ice, tmp);
289
udelay(10);
290
291
/* Instruct XILINX chip to parse the data to the STAC9744 chip */
292
tmp |= AUREON_AC97_COMMIT;
293
snd_ice1712_gpio_write(ice, tmp);
294
udelay(10);
295
tmp &= ~AUREON_AC97_COMMIT;
296
snd_ice1712_gpio_write(ice, tmp);
297
udelay(10);
298
299
/* Store the data in out private buffer */
300
spec->stac9744[(reg & 0x7F) >> 1] = val;
301
}
302
303
static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
304
{
305
struct aureon_spec *spec = ice->spec;
306
return spec->stac9744[(reg & 0x7F) >> 1];
307
}
308
309
/*
310
* Initialize STAC9744 chip
311
*/
312
static int aureon_ac97_init(struct snd_ice1712 *ice)
313
{
314
struct aureon_spec *spec = ice->spec;
315
int i;
316
static const unsigned short ac97_defaults[] = {
317
0x00, 0x9640,
318
0x02, 0x8000,
319
0x04, 0x8000,
320
0x06, 0x8000,
321
0x0C, 0x8008,
322
0x0E, 0x8008,
323
0x10, 0x8808,
324
0x12, 0x8808,
325
0x14, 0x8808,
326
0x16, 0x8808,
327
0x18, 0x8808,
328
0x1C, 0x8000,
329
0x26, 0x000F,
330
0x28, 0x0201,
331
0x2C, 0xBB80,
332
0x32, 0xBB80,
333
0x7C, 0x8384,
334
0x7E, 0x7644,
335
(unsigned short)-1
336
};
337
unsigned int tmp;
338
339
/* Cold reset */
340
tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
341
snd_ice1712_gpio_write(ice, tmp);
342
udelay(3);
343
344
tmp &= ~AUREON_AC97_RESET;
345
snd_ice1712_gpio_write(ice, tmp);
346
udelay(3);
347
348
tmp |= AUREON_AC97_RESET;
349
snd_ice1712_gpio_write(ice, tmp);
350
udelay(3);
351
352
memset(&spec->stac9744, 0, sizeof(spec->stac9744));
353
for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
354
spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
355
356
/* Unmute AC'97 master volume permanently - muting is done by WM8770 */
357
aureon_ac97_write(ice, AC97_MASTER, 0x0000);
358
359
return 0;
360
}
361
362
#define AUREON_AC97_STEREO 0x80
363
364
/*
365
* AC'97 volume controls
366
*/
367
static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
368
{
369
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
370
uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
371
uinfo->value.integer.min = 0;
372
uinfo->value.integer.max = 31;
373
return 0;
374
}
375
376
static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
377
{
378
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
379
unsigned short vol;
380
381
mutex_lock(&ice->gpio_mutex);
382
383
vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
384
ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
385
if (kcontrol->private_value & AUREON_AC97_STEREO)
386
ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
387
388
mutex_unlock(&ice->gpio_mutex);
389
return 0;
390
}
391
392
static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
393
{
394
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
395
unsigned short ovol, nvol;
396
int change;
397
398
snd_ice1712_save_gpio_status(ice);
399
400
ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
401
nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
402
if (kcontrol->private_value & AUREON_AC97_STEREO)
403
nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
404
nvol |= ovol & ~0x1F1F;
405
406
change = (ovol != nvol);
407
if (change)
408
aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
409
410
snd_ice1712_restore_gpio_status(ice);
411
412
return change;
413
}
414
415
/*
416
* AC'97 mute controls
417
*/
418
#define aureon_ac97_mute_info snd_ctl_boolean_mono_info
419
420
static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
421
{
422
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
423
424
mutex_lock(&ice->gpio_mutex);
425
426
ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
427
kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
428
429
mutex_unlock(&ice->gpio_mutex);
430
return 0;
431
}
432
433
static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
434
{
435
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
436
unsigned short ovol, nvol;
437
int change;
438
439
snd_ice1712_save_gpio_status(ice);
440
441
ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
442
nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
443
444
change = (ovol != nvol);
445
if (change)
446
aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
447
448
snd_ice1712_restore_gpio_status(ice);
449
450
return change;
451
}
452
453
/*
454
* AC'97 mute controls
455
*/
456
#define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
457
458
static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
459
{
460
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
461
462
mutex_lock(&ice->gpio_mutex);
463
464
ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
465
466
mutex_unlock(&ice->gpio_mutex);
467
return 0;
468
}
469
470
static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
471
{
472
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
473
unsigned short ovol, nvol;
474
int change;
475
476
snd_ice1712_save_gpio_status(ice);
477
478
ovol = aureon_ac97_read(ice, AC97_MIC);
479
nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
480
481
change = (ovol != nvol);
482
if (change)
483
aureon_ac97_write(ice, AC97_MIC, nvol);
484
485
snd_ice1712_restore_gpio_status(ice);
486
487
return change;
488
}
489
490
/*
491
* write data in the SPI mode
492
*/
493
static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
494
{
495
unsigned int tmp;
496
int i;
497
unsigned int mosi, clk;
498
499
tmp = snd_ice1712_gpio_read(ice);
500
501
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
502
ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
503
snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
504
mosi = PRODIGY_SPI_MOSI;
505
clk = PRODIGY_SPI_CLK;
506
} else {
507
snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
508
AUREON_WM_CS|AUREON_CS8415_CS));
509
mosi = AUREON_SPI_MOSI;
510
clk = AUREON_SPI_CLK;
511
512
tmp |= AUREON_WM_RW;
513
}
514
515
tmp &= ~cs;
516
snd_ice1712_gpio_write(ice, tmp);
517
udelay(1);
518
519
for (i = bits - 1; i >= 0; i--) {
520
tmp &= ~clk;
521
snd_ice1712_gpio_write(ice, tmp);
522
udelay(1);
523
if (data & (1 << i))
524
tmp |= mosi;
525
else
526
tmp &= ~mosi;
527
snd_ice1712_gpio_write(ice, tmp);
528
udelay(1);
529
tmp |= clk;
530
snd_ice1712_gpio_write(ice, tmp);
531
udelay(1);
532
}
533
534
tmp &= ~clk;
535
tmp |= cs;
536
snd_ice1712_gpio_write(ice, tmp);
537
udelay(1);
538
tmp |= clk;
539
snd_ice1712_gpio_write(ice, tmp);
540
udelay(1);
541
}
542
543
/*
544
* Read data in SPI mode
545
*/
546
static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
547
unsigned int data, int bits, unsigned char *buffer, int size)
548
{
549
int i, j;
550
unsigned int tmp;
551
552
tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
553
snd_ice1712_gpio_write(ice, tmp);
554
tmp &= ~cs;
555
snd_ice1712_gpio_write(ice, tmp);
556
udelay(1);
557
558
for (i = bits-1; i >= 0; i--) {
559
if (data & (1 << i))
560
tmp |= AUREON_SPI_MOSI;
561
else
562
tmp &= ~AUREON_SPI_MOSI;
563
snd_ice1712_gpio_write(ice, tmp);
564
udelay(1);
565
566
tmp |= AUREON_SPI_CLK;
567
snd_ice1712_gpio_write(ice, tmp);
568
udelay(1);
569
570
tmp &= ~AUREON_SPI_CLK;
571
snd_ice1712_gpio_write(ice, tmp);
572
udelay(1);
573
}
574
575
for (j = 0; j < size; j++) {
576
unsigned char outdata = 0;
577
for (i = 7; i >= 0; i--) {
578
tmp = snd_ice1712_gpio_read(ice);
579
outdata <<= 1;
580
outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
581
udelay(1);
582
583
tmp |= AUREON_SPI_CLK;
584
snd_ice1712_gpio_write(ice, tmp);
585
udelay(1);
586
587
tmp &= ~AUREON_SPI_CLK;
588
snd_ice1712_gpio_write(ice, tmp);
589
udelay(1);
590
}
591
buffer[j] = outdata;
592
}
593
594
tmp |= cs;
595
snd_ice1712_gpio_write(ice, tmp);
596
}
597
598
static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
599
{
600
unsigned char val;
601
aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
602
aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
603
return val;
604
}
605
606
static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
607
unsigned char *buffer, int size)
608
{
609
aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
610
aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
611
}
612
613
static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
614
unsigned char val)
615
{
616
aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
617
}
618
619
/*
620
* get the current register value of WM codec
621
*/
622
static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
623
{
624
reg <<= 1;
625
return ((unsigned short)ice->akm[0].images[reg] << 8) |
626
ice->akm[0].images[reg + 1];
627
}
628
629
/*
630
* set the register value of WM codec
631
*/
632
static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
633
{
634
aureon_spi_write(ice,
635
((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
636
ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
637
PRODIGY_WM_CS : AUREON_WM_CS),
638
(reg << 9) | (val & 0x1ff), 16);
639
}
640
641
/*
642
* set the register value of WM codec and remember it
643
*/
644
static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
645
{
646
wm_put_nocache(ice, reg, val);
647
reg <<= 1;
648
ice->akm[0].images[reg] = val >> 8;
649
ice->akm[0].images[reg + 1] = val;
650
}
651
652
/*
653
*/
654
#define aureon_mono_bool_info snd_ctl_boolean_mono_info
655
656
/*
657
* AC'97 master playback mute controls (Mute on WM8770 chip)
658
*/
659
#define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
660
661
static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
662
{
663
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
664
665
mutex_lock(&ice->gpio_mutex);
666
667
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
668
669
mutex_unlock(&ice->gpio_mutex);
670
return 0;
671
}
672
673
static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
674
{
675
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
676
unsigned short ovol, nvol;
677
int change;
678
679
snd_ice1712_save_gpio_status(ice);
680
681
ovol = wm_get(ice, WM_OUT_MUX1);
682
nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
683
change = (ovol != nvol);
684
if (change)
685
wm_put(ice, WM_OUT_MUX1, nvol);
686
687
snd_ice1712_restore_gpio_status(ice);
688
689
return change;
690
}
691
692
static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
693
static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
694
static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
695
static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
696
static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
697
698
#define WM_VOL_MAX 100
699
#define WM_VOL_CNT 101 /* 0dB .. -100dB */
700
#define WM_VOL_MUTE 0x8000
701
702
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
703
{
704
unsigned char nvol;
705
706
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
707
nvol = 0;
708
} else {
709
nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
710
WM_VOL_MAX;
711
nvol += 0x1b;
712
}
713
714
wm_put(ice, index, nvol);
715
wm_put_nocache(ice, index, 0x180 | nvol);
716
}
717
718
/*
719
* DAC mute control
720
*/
721
#define wm_pcm_mute_info snd_ctl_boolean_mono_info
722
723
static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
724
{
725
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
726
727
mutex_lock(&ice->gpio_mutex);
728
ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
729
mutex_unlock(&ice->gpio_mutex);
730
return 0;
731
}
732
733
static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
734
{
735
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
736
unsigned short nval, oval;
737
int change;
738
739
snd_ice1712_save_gpio_status(ice);
740
oval = wm_get(ice, WM_MUTE);
741
nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
742
change = (oval != nval);
743
if (change)
744
wm_put(ice, WM_MUTE, nval);
745
snd_ice1712_restore_gpio_status(ice);
746
747
return change;
748
}
749
750
/*
751
* Master volume attenuation mixer control
752
*/
753
static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
754
{
755
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
756
uinfo->count = 2;
757
uinfo->value.integer.min = 0;
758
uinfo->value.integer.max = WM_VOL_MAX;
759
return 0;
760
}
761
762
static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
763
{
764
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
765
struct aureon_spec *spec = ice->spec;
766
int i;
767
for (i = 0; i < 2; i++)
768
ucontrol->value.integer.value[i] =
769
spec->master[i] & ~WM_VOL_MUTE;
770
return 0;
771
}
772
773
static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
774
{
775
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
776
struct aureon_spec *spec = ice->spec;
777
int ch, change = 0;
778
779
snd_ice1712_save_gpio_status(ice);
780
for (ch = 0; ch < 2; ch++) {
781
unsigned int vol = ucontrol->value.integer.value[ch];
782
if (vol > WM_VOL_MAX)
783
vol = WM_VOL_MAX;
784
vol |= spec->master[ch] & WM_VOL_MUTE;
785
if (vol != spec->master[ch]) {
786
int dac;
787
spec->master[ch] = vol;
788
for (dac = 0; dac < ice->num_total_dacs; dac += 2)
789
wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
790
spec->vol[dac + ch],
791
spec->master[ch]);
792
change = 1;
793
}
794
}
795
snd_ice1712_restore_gpio_status(ice);
796
return change;
797
}
798
799
/*
800
* DAC volume attenuation mixer control
801
*/
802
static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
803
{
804
int voices = kcontrol->private_value >> 8;
805
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
806
uinfo->count = voices;
807
uinfo->value.integer.min = 0; /* mute (-101dB) */
808
uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
809
return 0;
810
}
811
812
static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
813
{
814
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
815
struct aureon_spec *spec = ice->spec;
816
int i, ofs, voices;
817
818
voices = kcontrol->private_value >> 8;
819
ofs = kcontrol->private_value & 0xff;
820
for (i = 0; i < voices; i++)
821
ucontrol->value.integer.value[i] =
822
spec->vol[ofs+i] & ~WM_VOL_MUTE;
823
return 0;
824
}
825
826
static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
827
{
828
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
829
struct aureon_spec *spec = ice->spec;
830
int i, idx, ofs, voices;
831
int change = 0;
832
833
voices = kcontrol->private_value >> 8;
834
ofs = kcontrol->private_value & 0xff;
835
snd_ice1712_save_gpio_status(ice);
836
for (i = 0; i < voices; i++) {
837
unsigned int vol = ucontrol->value.integer.value[i];
838
if (vol > WM_VOL_MAX)
839
vol = WM_VOL_MAX;
840
vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
841
if (vol != spec->vol[ofs+i]) {
842
spec->vol[ofs+i] = vol;
843
idx = WM_DAC_ATTEN + ofs + i;
844
wm_set_vol(ice, idx, spec->vol[ofs + i],
845
spec->master[i]);
846
change = 1;
847
}
848
}
849
snd_ice1712_restore_gpio_status(ice);
850
return change;
851
}
852
853
/*
854
* WM8770 mute control
855
*/
856
static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
857
{
858
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
859
uinfo->count = kcontrol->private_value >> 8;
860
uinfo->value.integer.min = 0;
861
uinfo->value.integer.max = 1;
862
return 0;
863
}
864
865
static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
866
{
867
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
868
struct aureon_spec *spec = ice->spec;
869
int voices, ofs, i;
870
871
voices = kcontrol->private_value >> 8;
872
ofs = kcontrol->private_value & 0xFF;
873
874
for (i = 0; i < voices; i++)
875
ucontrol->value.integer.value[i] =
876
(spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
877
return 0;
878
}
879
880
static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
881
{
882
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
883
struct aureon_spec *spec = ice->spec;
884
int change = 0, voices, ofs, i;
885
886
voices = kcontrol->private_value >> 8;
887
ofs = kcontrol->private_value & 0xFF;
888
889
snd_ice1712_save_gpio_status(ice);
890
for (i = 0; i < voices; i++) {
891
int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
892
if (ucontrol->value.integer.value[i] != val) {
893
spec->vol[ofs + i] &= ~WM_VOL_MUTE;
894
spec->vol[ofs + i] |=
895
ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
896
wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
897
spec->master[i]);
898
change = 1;
899
}
900
}
901
snd_ice1712_restore_gpio_status(ice);
902
903
return change;
904
}
905
906
/*
907
* WM8770 master mute control
908
*/
909
#define wm_master_mute_info snd_ctl_boolean_stereo_info
910
911
static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
912
{
913
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
914
struct aureon_spec *spec = ice->spec;
915
916
ucontrol->value.integer.value[0] =
917
(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
918
ucontrol->value.integer.value[1] =
919
(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
920
return 0;
921
}
922
923
static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
924
{
925
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
926
struct aureon_spec *spec = ice->spec;
927
int change = 0, i;
928
929
snd_ice1712_save_gpio_status(ice);
930
for (i = 0; i < 2; i++) {
931
int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
932
if (ucontrol->value.integer.value[i] != val) {
933
int dac;
934
spec->master[i] &= ~WM_VOL_MUTE;
935
spec->master[i] |=
936
ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
937
for (dac = 0; dac < ice->num_total_dacs; dac += 2)
938
wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
939
spec->vol[dac + i],
940
spec->master[i]);
941
change = 1;
942
}
943
}
944
snd_ice1712_restore_gpio_status(ice);
945
946
return change;
947
}
948
949
/* digital master volume */
950
#define PCM_0dB 0xff
951
#define PCM_RES 128 /* -64dB */
952
#define PCM_MIN (PCM_0dB - PCM_RES)
953
static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
954
{
955
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
956
uinfo->count = 1;
957
uinfo->value.integer.min = 0; /* mute (-64dB) */
958
uinfo->value.integer.max = PCM_RES; /* 0dB */
959
return 0;
960
}
961
962
static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
963
{
964
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
965
unsigned short val;
966
967
mutex_lock(&ice->gpio_mutex);
968
val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
969
val = val > PCM_MIN ? (val - PCM_MIN) : 0;
970
ucontrol->value.integer.value[0] = val;
971
mutex_unlock(&ice->gpio_mutex);
972
return 0;
973
}
974
975
static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
976
{
977
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
978
unsigned short ovol, nvol;
979
int change = 0;
980
981
nvol = ucontrol->value.integer.value[0];
982
if (nvol > PCM_RES)
983
return -EINVAL;
984
snd_ice1712_save_gpio_status(ice);
985
nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
986
ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
987
if (ovol != nvol) {
988
wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
989
wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
990
change = 1;
991
}
992
snd_ice1712_restore_gpio_status(ice);
993
return change;
994
}
995
996
/*
997
* ADC mute control
998
*/
999
#define wm_adc_mute_info snd_ctl_boolean_stereo_info
1000
1001
static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1002
{
1003
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1004
unsigned short val;
1005
int i;
1006
1007
mutex_lock(&ice->gpio_mutex);
1008
for (i = 0; i < 2; i++) {
1009
val = wm_get(ice, WM_ADC_GAIN + i);
1010
ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
1011
}
1012
mutex_unlock(&ice->gpio_mutex);
1013
return 0;
1014
}
1015
1016
static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1017
{
1018
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1019
unsigned short new, old;
1020
int i, change = 0;
1021
1022
snd_ice1712_save_gpio_status(ice);
1023
for (i = 0; i < 2; i++) {
1024
old = wm_get(ice, WM_ADC_GAIN + i);
1025
new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1026
if (new != old) {
1027
wm_put(ice, WM_ADC_GAIN + i, new);
1028
change = 1;
1029
}
1030
}
1031
snd_ice1712_restore_gpio_status(ice);
1032
1033
return change;
1034
}
1035
1036
/*
1037
* ADC gain mixer control
1038
*/
1039
static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1040
{
1041
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1042
uinfo->count = 2;
1043
uinfo->value.integer.min = 0; /* -12dB */
1044
uinfo->value.integer.max = 0x1f; /* 19dB */
1045
return 0;
1046
}
1047
1048
static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1049
{
1050
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1051
int i, idx;
1052
unsigned short vol;
1053
1054
mutex_lock(&ice->gpio_mutex);
1055
for (i = 0; i < 2; i++) {
1056
idx = WM_ADC_GAIN + i;
1057
vol = wm_get(ice, idx) & 0x1f;
1058
ucontrol->value.integer.value[i] = vol;
1059
}
1060
mutex_unlock(&ice->gpio_mutex);
1061
return 0;
1062
}
1063
1064
static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1065
{
1066
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1067
int i, idx;
1068
unsigned short ovol, nvol;
1069
int change = 0;
1070
1071
snd_ice1712_save_gpio_status(ice);
1072
for (i = 0; i < 2; i++) {
1073
idx = WM_ADC_GAIN + i;
1074
nvol = ucontrol->value.integer.value[i] & 0x1f;
1075
ovol = wm_get(ice, idx);
1076
if ((ovol & 0x1f) != nvol) {
1077
wm_put(ice, idx, nvol | (ovol & ~0x1f));
1078
change = 1;
1079
}
1080
}
1081
snd_ice1712_restore_gpio_status(ice);
1082
return change;
1083
}
1084
1085
/*
1086
* ADC input mux mixer control
1087
*/
1088
static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1089
{
1090
static const char * const texts[] = {
1091
"CD", /* AIN1 */
1092
"Aux", /* AIN2 */
1093
"Line", /* AIN3 */
1094
"Mic", /* AIN4 */
1095
"AC97" /* AIN5 */
1096
};
1097
static const char * const universe_texts[] = {
1098
"Aux1", /* AIN1 */
1099
"CD", /* AIN2 */
1100
"Phono", /* AIN3 */
1101
"Line", /* AIN4 */
1102
"Aux2", /* AIN5 */
1103
"Mic", /* AIN6 */
1104
"Aux3", /* AIN7 */
1105
"AC97" /* AIN8 */
1106
};
1107
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1108
1109
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1110
uinfo->count = 2;
1111
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1112
uinfo->value.enumerated.items = 8;
1113
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1114
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1115
strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1116
} else {
1117
uinfo->value.enumerated.items = 5;
1118
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1119
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1120
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1121
}
1122
return 0;
1123
}
1124
1125
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1126
{
1127
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1128
unsigned short val;
1129
1130
mutex_lock(&ice->gpio_mutex);
1131
val = wm_get(ice, WM_ADC_MUX);
1132
ucontrol->value.enumerated.item[0] = val & 7;
1133
ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1134
mutex_unlock(&ice->gpio_mutex);
1135
return 0;
1136
}
1137
1138
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1139
{
1140
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1141
unsigned short oval, nval;
1142
int change;
1143
1144
snd_ice1712_save_gpio_status(ice);
1145
oval = wm_get(ice, WM_ADC_MUX);
1146
nval = oval & ~0x77;
1147
nval |= ucontrol->value.enumerated.item[0] & 7;
1148
nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1149
change = (oval != nval);
1150
if (change)
1151
wm_put(ice, WM_ADC_MUX, nval);
1152
snd_ice1712_restore_gpio_status(ice);
1153
return change;
1154
}
1155
1156
/*
1157
* CS8415 Input mux
1158
*/
1159
static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1160
{
1161
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1162
static const char * const aureon_texts[] = {
1163
"CD", /* RXP0 */
1164
"Optical" /* RXP1 */
1165
};
1166
static const char * const prodigy_texts[] = {
1167
"CD",
1168
"Coax"
1169
};
1170
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1171
uinfo->count = 1;
1172
uinfo->value.enumerated.items = 2;
1173
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1174
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1175
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1176
strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1177
else
1178
strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1179
return 0;
1180
}
1181
1182
static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1183
{
1184
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1185
struct aureon_spec *spec = ice->spec;
1186
1187
/* snd_ice1712_save_gpio_status(ice); */
1188
/* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1189
ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1190
/* snd_ice1712_restore_gpio_status(ice); */
1191
return 0;
1192
}
1193
1194
static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1195
{
1196
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1197
struct aureon_spec *spec = ice->spec;
1198
unsigned short oval, nval;
1199
int change;
1200
1201
snd_ice1712_save_gpio_status(ice);
1202
oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1203
nval = oval & ~0x07;
1204
nval |= ucontrol->value.enumerated.item[0] & 7;
1205
change = (oval != nval);
1206
if (change)
1207
aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1208
snd_ice1712_restore_gpio_status(ice);
1209
spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1210
return change;
1211
}
1212
1213
static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1214
{
1215
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1216
uinfo->count = 1;
1217
uinfo->value.integer.min = 0;
1218
uinfo->value.integer.max = 192000;
1219
return 0;
1220
}
1221
1222
static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1223
{
1224
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1225
unsigned char ratio;
1226
ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1227
ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1228
return 0;
1229
}
1230
1231
/*
1232
* CS8415A Mute
1233
*/
1234
#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
1235
1236
static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1237
{
1238
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1239
snd_ice1712_save_gpio_status(ice);
1240
ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1241
snd_ice1712_restore_gpio_status(ice);
1242
return 0;
1243
}
1244
1245
static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1246
{
1247
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1248
unsigned char oval, nval;
1249
int change;
1250
snd_ice1712_save_gpio_status(ice);
1251
oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1252
if (ucontrol->value.integer.value[0])
1253
nval = oval & ~0x20;
1254
else
1255
nval = oval | 0x20;
1256
change = (oval != nval);
1257
if (change)
1258
aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1259
snd_ice1712_restore_gpio_status(ice);
1260
return change;
1261
}
1262
1263
/*
1264
* CS8415A Q-Sub info
1265
*/
1266
static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1267
{
1268
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1269
uinfo->count = 10;
1270
return 0;
1271
}
1272
1273
static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1274
{
1275
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1276
1277
snd_ice1712_save_gpio_status(ice);
1278
aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1279
snd_ice1712_restore_gpio_status(ice);
1280
1281
return 0;
1282
}
1283
1284
static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1285
{
1286
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1287
uinfo->count = 1;
1288
return 0;
1289
}
1290
1291
static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1292
{
1293
memset(ucontrol->value.iec958.status, 0xFF, 24);
1294
return 0;
1295
}
1296
1297
static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1298
{
1299
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1300
1301
snd_ice1712_save_gpio_status(ice);
1302
aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1303
snd_ice1712_restore_gpio_status(ice);
1304
return 0;
1305
}
1306
1307
/*
1308
* Headphone Amplifier
1309
*/
1310
static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1311
{
1312
unsigned int tmp, tmp2;
1313
1314
tmp2 = tmp = snd_ice1712_gpio_read(ice);
1315
if (enable)
1316
if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1317
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1318
tmp |= AUREON_HP_SEL;
1319
else
1320
tmp |= PRODIGY_HP_SEL;
1321
else
1322
if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1323
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1324
tmp &= ~AUREON_HP_SEL;
1325
else
1326
tmp &= ~PRODIGY_HP_SEL;
1327
if (tmp != tmp2) {
1328
snd_ice1712_gpio_write(ice, tmp);
1329
return 1;
1330
}
1331
return 0;
1332
}
1333
1334
static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1335
{
1336
unsigned int tmp = snd_ice1712_gpio_read(ice);
1337
1338
return (tmp & AUREON_HP_SEL) != 0;
1339
}
1340
1341
#define aureon_hpamp_info snd_ctl_boolean_mono_info
1342
1343
static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1344
{
1345
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1346
1347
ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1348
return 0;
1349
}
1350
1351
1352
static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1353
{
1354
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1355
1356
return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1357
}
1358
1359
/*
1360
* Deemphasis
1361
*/
1362
1363
#define aureon_deemp_info snd_ctl_boolean_mono_info
1364
1365
static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1366
{
1367
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1368
ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1369
return 0;
1370
}
1371
1372
static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1373
{
1374
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1375
int temp, temp2;
1376
temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1377
if (ucontrol->value.integer.value[0])
1378
temp |= 0xf;
1379
else
1380
temp &= ~0xf;
1381
if (temp != temp2) {
1382
wm_put(ice, WM_DAC_CTRL2, temp);
1383
return 1;
1384
}
1385
return 0;
1386
}
1387
1388
/*
1389
* ADC Oversampling
1390
*/
1391
static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1392
{
1393
static const char * const texts[2] = { "128x", "64x" };
1394
1395
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1396
uinfo->count = 1;
1397
uinfo->value.enumerated.items = 2;
1398
1399
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1400
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1401
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1402
1403
return 0;
1404
}
1405
1406
static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1407
{
1408
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1409
ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1410
return 0;
1411
}
1412
1413
static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1414
{
1415
int temp, temp2;
1416
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1417
1418
temp2 = temp = wm_get(ice, WM_MASTER);
1419
1420
if (ucontrol->value.enumerated.item[0])
1421
temp |= 0x8;
1422
else
1423
temp &= ~0x8;
1424
1425
if (temp != temp2) {
1426
wm_put(ice, WM_MASTER, temp);
1427
return 1;
1428
}
1429
return 0;
1430
}
1431
1432
/*
1433
* mixers
1434
*/
1435
1436
static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1437
{
1438
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439
.name = "Master Playback Switch",
1440
.info = wm_master_mute_info,
1441
.get = wm_master_mute_get,
1442
.put = wm_master_mute_put
1443
},
1444
{
1445
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1446
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1447
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1448
.name = "Master Playback Volume",
1449
.info = wm_master_vol_info,
1450
.get = wm_master_vol_get,
1451
.put = wm_master_vol_put,
1452
.tlv = { .p = db_scale_wm_dac }
1453
},
1454
{
1455
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1456
.name = "Front Playback Switch",
1457
.info = wm_mute_info,
1458
.get = wm_mute_get,
1459
.put = wm_mute_put,
1460
.private_value = (2 << 8) | 0
1461
},
1462
{
1463
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1464
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1465
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1466
.name = "Front Playback Volume",
1467
.info = wm_vol_info,
1468
.get = wm_vol_get,
1469
.put = wm_vol_put,
1470
.private_value = (2 << 8) | 0,
1471
.tlv = { .p = db_scale_wm_dac }
1472
},
1473
{
1474
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1475
.name = "Rear Playback Switch",
1476
.info = wm_mute_info,
1477
.get = wm_mute_get,
1478
.put = wm_mute_put,
1479
.private_value = (2 << 8) | 2
1480
},
1481
{
1482
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1483
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1484
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1485
.name = "Rear Playback Volume",
1486
.info = wm_vol_info,
1487
.get = wm_vol_get,
1488
.put = wm_vol_put,
1489
.private_value = (2 << 8) | 2,
1490
.tlv = { .p = db_scale_wm_dac }
1491
},
1492
{
1493
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1494
.name = "Center Playback Switch",
1495
.info = wm_mute_info,
1496
.get = wm_mute_get,
1497
.put = wm_mute_put,
1498
.private_value = (1 << 8) | 4
1499
},
1500
{
1501
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1503
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1504
.name = "Center Playback Volume",
1505
.info = wm_vol_info,
1506
.get = wm_vol_get,
1507
.put = wm_vol_put,
1508
.private_value = (1 << 8) | 4,
1509
.tlv = { .p = db_scale_wm_dac }
1510
},
1511
{
1512
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1513
.name = "LFE Playback Switch",
1514
.info = wm_mute_info,
1515
.get = wm_mute_get,
1516
.put = wm_mute_put,
1517
.private_value = (1 << 8) | 5
1518
},
1519
{
1520
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1521
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1522
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1523
.name = "LFE Playback Volume",
1524
.info = wm_vol_info,
1525
.get = wm_vol_get,
1526
.put = wm_vol_put,
1527
.private_value = (1 << 8) | 5,
1528
.tlv = { .p = db_scale_wm_dac }
1529
},
1530
{
1531
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1532
.name = "Side Playback Switch",
1533
.info = wm_mute_info,
1534
.get = wm_mute_get,
1535
.put = wm_mute_put,
1536
.private_value = (2 << 8) | 6
1537
},
1538
{
1539
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1540
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1541
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1542
.name = "Side Playback Volume",
1543
.info = wm_vol_info,
1544
.get = wm_vol_get,
1545
.put = wm_vol_put,
1546
.private_value = (2 << 8) | 6,
1547
.tlv = { .p = db_scale_wm_dac }
1548
}
1549
};
1550
1551
static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1552
{
1553
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1554
.name = "PCM Playback Switch",
1555
.info = wm_pcm_mute_info,
1556
.get = wm_pcm_mute_get,
1557
.put = wm_pcm_mute_put
1558
},
1559
{
1560
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1561
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1562
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1563
.name = "PCM Playback Volume",
1564
.info = wm_pcm_vol_info,
1565
.get = wm_pcm_vol_get,
1566
.put = wm_pcm_vol_put,
1567
.tlv = { .p = db_scale_wm_pcm }
1568
},
1569
{
1570
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1571
.name = "Capture Switch",
1572
.info = wm_adc_mute_info,
1573
.get = wm_adc_mute_get,
1574
.put = wm_adc_mute_put,
1575
},
1576
{
1577
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1578
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1579
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1580
.name = "Capture Volume",
1581
.info = wm_adc_vol_info,
1582
.get = wm_adc_vol_get,
1583
.put = wm_adc_vol_put,
1584
.tlv = { .p = db_scale_wm_adc }
1585
},
1586
{
1587
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1588
.name = "Capture Source",
1589
.info = wm_adc_mux_info,
1590
.get = wm_adc_mux_get,
1591
.put = wm_adc_mux_put,
1592
.private_value = 5
1593
},
1594
{
1595
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1596
.name = "External Amplifier",
1597
.info = aureon_hpamp_info,
1598
.get = aureon_hpamp_get,
1599
.put = aureon_hpamp_put
1600
},
1601
{
1602
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1603
.name = "DAC Deemphasis Switch",
1604
.info = aureon_deemp_info,
1605
.get = aureon_deemp_get,
1606
.put = aureon_deemp_put
1607
},
1608
{
1609
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1610
.name = "ADC Oversampling",
1611
.info = aureon_oversampling_info,
1612
.get = aureon_oversampling_get,
1613
.put = aureon_oversampling_put
1614
}
1615
};
1616
1617
static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1618
{
1619
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1620
.name = "AC97 Playback Switch",
1621
.info = aureon_ac97_mmute_info,
1622
.get = aureon_ac97_mmute_get,
1623
.put = aureon_ac97_mmute_put,
1624
.private_value = AC97_MASTER
1625
},
1626
{
1627
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1628
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1629
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1630
.name = "AC97 Playback Volume",
1631
.info = aureon_ac97_vol_info,
1632
.get = aureon_ac97_vol_get,
1633
.put = aureon_ac97_vol_put,
1634
.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1635
.tlv = { .p = db_scale_ac97_master }
1636
},
1637
{
1638
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1639
.name = "CD Playback Switch",
1640
.info = aureon_ac97_mute_info,
1641
.get = aureon_ac97_mute_get,
1642
.put = aureon_ac97_mute_put,
1643
.private_value = AC97_CD
1644
},
1645
{
1646
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1647
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1648
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1649
.name = "CD Playback Volume",
1650
.info = aureon_ac97_vol_info,
1651
.get = aureon_ac97_vol_get,
1652
.put = aureon_ac97_vol_put,
1653
.private_value = AC97_CD|AUREON_AC97_STEREO,
1654
.tlv = { .p = db_scale_ac97_gain }
1655
},
1656
{
1657
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1658
.name = "Aux Playback Switch",
1659
.info = aureon_ac97_mute_info,
1660
.get = aureon_ac97_mute_get,
1661
.put = aureon_ac97_mute_put,
1662
.private_value = AC97_AUX,
1663
},
1664
{
1665
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1666
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1667
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1668
.name = "Aux Playback Volume",
1669
.info = aureon_ac97_vol_info,
1670
.get = aureon_ac97_vol_get,
1671
.put = aureon_ac97_vol_put,
1672
.private_value = AC97_AUX|AUREON_AC97_STEREO,
1673
.tlv = { .p = db_scale_ac97_gain }
1674
},
1675
{
1676
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1677
.name = "Line Playback Switch",
1678
.info = aureon_ac97_mute_info,
1679
.get = aureon_ac97_mute_get,
1680
.put = aureon_ac97_mute_put,
1681
.private_value = AC97_LINE
1682
},
1683
{
1684
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1685
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1686
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1687
.name = "Line Playback Volume",
1688
.info = aureon_ac97_vol_info,
1689
.get = aureon_ac97_vol_get,
1690
.put = aureon_ac97_vol_put,
1691
.private_value = AC97_LINE|AUREON_AC97_STEREO,
1692
.tlv = { .p = db_scale_ac97_gain }
1693
},
1694
{
1695
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1696
.name = "Mic Playback Switch",
1697
.info = aureon_ac97_mute_info,
1698
.get = aureon_ac97_mute_get,
1699
.put = aureon_ac97_mute_put,
1700
.private_value = AC97_MIC
1701
},
1702
{
1703
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1704
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1705
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1706
.name = "Mic Playback Volume",
1707
.info = aureon_ac97_vol_info,
1708
.get = aureon_ac97_vol_get,
1709
.put = aureon_ac97_vol_put,
1710
.private_value = AC97_MIC,
1711
.tlv = { .p = db_scale_ac97_gain }
1712
},
1713
{
1714
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1715
.name = "Mic Boost (+20dB)",
1716
.info = aureon_ac97_micboost_info,
1717
.get = aureon_ac97_micboost_get,
1718
.put = aureon_ac97_micboost_put
1719
}
1720
};
1721
1722
static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1723
{
1724
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1725
.name = "AC97 Playback Switch",
1726
.info = aureon_ac97_mmute_info,
1727
.get = aureon_ac97_mmute_get,
1728
.put = aureon_ac97_mmute_put,
1729
.private_value = AC97_MASTER
1730
},
1731
{
1732
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1733
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1734
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1735
.name = "AC97 Playback Volume",
1736
.info = aureon_ac97_vol_info,
1737
.get = aureon_ac97_vol_get,
1738
.put = aureon_ac97_vol_put,
1739
.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1740
.tlv = { .p = db_scale_ac97_master }
1741
},
1742
{
1743
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1744
.name = "CD Playback Switch",
1745
.info = aureon_ac97_mute_info,
1746
.get = aureon_ac97_mute_get,
1747
.put = aureon_ac97_mute_put,
1748
.private_value = AC97_AUX
1749
},
1750
{
1751
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1752
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1753
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1754
.name = "CD Playback Volume",
1755
.info = aureon_ac97_vol_info,
1756
.get = aureon_ac97_vol_get,
1757
.put = aureon_ac97_vol_put,
1758
.private_value = AC97_AUX|AUREON_AC97_STEREO,
1759
.tlv = { .p = db_scale_ac97_gain }
1760
},
1761
{
1762
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1763
.name = "Phono Playback Switch",
1764
.info = aureon_ac97_mute_info,
1765
.get = aureon_ac97_mute_get,
1766
.put = aureon_ac97_mute_put,
1767
.private_value = AC97_CD
1768
},
1769
{
1770
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1771
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1772
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1773
.name = "Phono Playback Volume",
1774
.info = aureon_ac97_vol_info,
1775
.get = aureon_ac97_vol_get,
1776
.put = aureon_ac97_vol_put,
1777
.private_value = AC97_CD|AUREON_AC97_STEREO,
1778
.tlv = { .p = db_scale_ac97_gain }
1779
},
1780
{
1781
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1782
.name = "Line Playback Switch",
1783
.info = aureon_ac97_mute_info,
1784
.get = aureon_ac97_mute_get,
1785
.put = aureon_ac97_mute_put,
1786
.private_value = AC97_LINE
1787
},
1788
{
1789
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1790
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1791
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1792
.name = "Line Playback Volume",
1793
.info = aureon_ac97_vol_info,
1794
.get = aureon_ac97_vol_get,
1795
.put = aureon_ac97_vol_put,
1796
.private_value = AC97_LINE|AUREON_AC97_STEREO,
1797
.tlv = { .p = db_scale_ac97_gain }
1798
},
1799
{
1800
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1801
.name = "Mic Playback Switch",
1802
.info = aureon_ac97_mute_info,
1803
.get = aureon_ac97_mute_get,
1804
.put = aureon_ac97_mute_put,
1805
.private_value = AC97_MIC
1806
},
1807
{
1808
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1809
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1810
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1811
.name = "Mic Playback Volume",
1812
.info = aureon_ac97_vol_info,
1813
.get = aureon_ac97_vol_get,
1814
.put = aureon_ac97_vol_put,
1815
.private_value = AC97_MIC,
1816
.tlv = { .p = db_scale_ac97_gain }
1817
},
1818
{
1819
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1820
.name = "Mic Boost (+20dB)",
1821
.info = aureon_ac97_micboost_info,
1822
.get = aureon_ac97_micboost_get,
1823
.put = aureon_ac97_micboost_put
1824
},
1825
{
1826
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1827
.name = "Aux Playback Switch",
1828
.info = aureon_ac97_mute_info,
1829
.get = aureon_ac97_mute_get,
1830
.put = aureon_ac97_mute_put,
1831
.private_value = AC97_VIDEO,
1832
},
1833
{
1834
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1835
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1836
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1837
.name = "Aux Playback Volume",
1838
.info = aureon_ac97_vol_info,
1839
.get = aureon_ac97_vol_get,
1840
.put = aureon_ac97_vol_put,
1841
.private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1842
.tlv = { .p = db_scale_ac97_gain }
1843
},
1844
{
1845
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1846
.name = "Aux Source",
1847
.info = aureon_universe_inmux_info,
1848
.get = aureon_universe_inmux_get,
1849
.put = aureon_universe_inmux_put
1850
}
1851
1852
};
1853
1854
static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1855
{
1856
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1857
.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1858
.info = aureon_cs8415_mute_info,
1859
.get = aureon_cs8415_mute_get,
1860
.put = aureon_cs8415_mute_put
1861
},
1862
{
1863
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1864
.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1865
.info = aureon_cs8415_mux_info,
1866
.get = aureon_cs8415_mux_get,
1867
.put = aureon_cs8415_mux_put,
1868
},
1869
{
1870
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1871
.name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1872
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1873
.info = aureon_cs8415_qsub_info,
1874
.get = aureon_cs8415_qsub_get,
1875
},
1876
{
1877
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1878
.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1879
.access = SNDRV_CTL_ELEM_ACCESS_READ,
1880
.info = aureon_cs8415_spdif_info,
1881
.get = aureon_cs8415_mask_get
1882
},
1883
{
1884
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1885
.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1886
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1887
.info = aureon_cs8415_spdif_info,
1888
.get = aureon_cs8415_spdif_get
1889
},
1890
{
1891
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1892
.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1893
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1894
.info = aureon_cs8415_rate_info,
1895
.get = aureon_cs8415_rate_get
1896
}
1897
};
1898
1899
static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1900
{
1901
unsigned int i, counts;
1902
int err;
1903
1904
counts = ARRAY_SIZE(aureon_dac_controls);
1905
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1906
counts -= 2; /* no side */
1907
for (i = 0; i < counts; i++) {
1908
err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1909
if (err < 0)
1910
return err;
1911
}
1912
1913
for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1914
err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1915
if (err < 0)
1916
return err;
1917
}
1918
1919
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1920
for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1921
err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1922
if (err < 0)
1923
return err;
1924
}
1925
} else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1926
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1927
for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1928
err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1929
if (err < 0)
1930
return err;
1931
}
1932
}
1933
1934
if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1935
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1936
unsigned char id;
1937
snd_ice1712_save_gpio_status(ice);
1938
id = aureon_cs8415_get(ice, CS8415_ID);
1939
if (id != 0x41)
1940
snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1941
else if ((id & 0x0F) != 0x01)
1942
snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1943
else {
1944
for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1945
struct snd_kcontrol *kctl;
1946
err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1947
if (err < 0)
1948
return err;
1949
if (i > 1)
1950
kctl->id.device = ice->pcm->device;
1951
}
1952
}
1953
snd_ice1712_restore_gpio_status(ice);
1954
}
1955
1956
return 0;
1957
}
1958
1959
/*
1960
* reset the chip
1961
*/
1962
static int aureon_reset(struct snd_ice1712 *ice)
1963
{
1964
static const unsigned short wm_inits_aureon[] = {
1965
/* These come first to reduce init pop noise */
1966
0x1b, 0x044, /* ADC Mux (AC'97 source) */
1967
0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1968
0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1969
1970
0x18, 0x000, /* All power-up */
1971
1972
0x16, 0x122, /* I2S, normal polarity, 24bit */
1973
0x17, 0x022, /* 256fs, slave mode */
1974
0x00, 0, /* DAC1 analog mute */
1975
0x01, 0, /* DAC2 analog mute */
1976
0x02, 0, /* DAC3 analog mute */
1977
0x03, 0, /* DAC4 analog mute */
1978
0x04, 0, /* DAC5 analog mute */
1979
0x05, 0, /* DAC6 analog mute */
1980
0x06, 0, /* DAC7 analog mute */
1981
0x07, 0, /* DAC8 analog mute */
1982
0x08, 0x100, /* master analog mute */
1983
0x09, 0xff, /* DAC1 digital full */
1984
0x0a, 0xff, /* DAC2 digital full */
1985
0x0b, 0xff, /* DAC3 digital full */
1986
0x0c, 0xff, /* DAC4 digital full */
1987
0x0d, 0xff, /* DAC5 digital full */
1988
0x0e, 0xff, /* DAC6 digital full */
1989
0x0f, 0xff, /* DAC7 digital full */
1990
0x10, 0xff, /* DAC8 digital full */
1991
0x11, 0x1ff, /* master digital full */
1992
0x12, 0x000, /* phase normal */
1993
0x13, 0x090, /* unmute DAC L/R */
1994
0x14, 0x000, /* all unmute */
1995
0x15, 0x000, /* no deemphasis, no ZFLG */
1996
0x19, 0x000, /* -12dB ADC/L */
1997
0x1a, 0x000, /* -12dB ADC/R */
1998
(unsigned short)-1
1999
};
2000
static const unsigned short wm_inits_prodigy[] = {
2001
2002
/* These come first to reduce init pop noise */
2003
0x1b, 0x000, /* ADC Mux */
2004
0x1c, 0x009, /* Out Mux1 */
2005
0x1d, 0x009, /* Out Mux2 */
2006
2007
0x18, 0x000, /* All power-up */
2008
2009
0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
2010
0x17, 0x006, /* 128fs, slave mode */
2011
2012
0x00, 0, /* DAC1 analog mute */
2013
0x01, 0, /* DAC2 analog mute */
2014
0x02, 0, /* DAC3 analog mute */
2015
0x03, 0, /* DAC4 analog mute */
2016
0x04, 0, /* DAC5 analog mute */
2017
0x05, 0, /* DAC6 analog mute */
2018
0x06, 0, /* DAC7 analog mute */
2019
0x07, 0, /* DAC8 analog mute */
2020
0x08, 0x100, /* master analog mute */
2021
2022
0x09, 0x7f, /* DAC1 digital full */
2023
0x0a, 0x7f, /* DAC2 digital full */
2024
0x0b, 0x7f, /* DAC3 digital full */
2025
0x0c, 0x7f, /* DAC4 digital full */
2026
0x0d, 0x7f, /* DAC5 digital full */
2027
0x0e, 0x7f, /* DAC6 digital full */
2028
0x0f, 0x7f, /* DAC7 digital full */
2029
0x10, 0x7f, /* DAC8 digital full */
2030
0x11, 0x1FF, /* master digital full */
2031
2032
0x12, 0x000, /* phase normal */
2033
0x13, 0x090, /* unmute DAC L/R */
2034
0x14, 0x000, /* all unmute */
2035
0x15, 0x000, /* no deemphasis, no ZFLG */
2036
2037
0x19, 0x000, /* -12dB ADC/L */
2038
0x1a, 0x000, /* -12dB ADC/R */
2039
(unsigned short)-1
2040
2041
};
2042
static const unsigned short cs_inits[] = {
2043
0x0441, /* RUN */
2044
0x0180, /* no mute, OMCK output on RMCK pin */
2045
0x0201, /* S/PDIF source on RXP1 */
2046
0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2047
(unsigned short)-1
2048
};
2049
unsigned int tmp;
2050
const unsigned short *p;
2051
int err;
2052
struct aureon_spec *spec = ice->spec;
2053
2054
err = aureon_ac97_init(ice);
2055
if (err != 0)
2056
return err;
2057
2058
snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2059
2060
/* reset the wm codec as the SPI mode */
2061
snd_ice1712_save_gpio_status(ice);
2062
snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2063
2064
tmp = snd_ice1712_gpio_read(ice);
2065
tmp &= ~AUREON_WM_RESET;
2066
snd_ice1712_gpio_write(ice, tmp);
2067
udelay(1);
2068
tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2069
snd_ice1712_gpio_write(ice, tmp);
2070
udelay(1);
2071
tmp |= AUREON_WM_RESET;
2072
snd_ice1712_gpio_write(ice, tmp);
2073
udelay(1);
2074
2075
/* initialize WM8770 codec */
2076
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2077
ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2078
ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2079
p = wm_inits_prodigy;
2080
else
2081
p = wm_inits_aureon;
2082
for (; *p != (unsigned short)-1; p += 2)
2083
wm_put(ice, p[0], p[1]);
2084
2085
/* initialize CS8415A codec */
2086
if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2087
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2088
for (p = cs_inits; *p != (unsigned short)-1; p++)
2089
aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2090
spec->cs8415_mux = 1;
2091
2092
aureon_set_headphone_amp(ice, 1);
2093
}
2094
2095
snd_ice1712_restore_gpio_status(ice);
2096
2097
/* initialize PCA9554 pin directions & set default input */
2098
aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2099
aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2100
return 0;
2101
}
2102
2103
/*
2104
* suspend/resume
2105
*/
2106
#ifdef CONFIG_PM
2107
static int aureon_resume(struct snd_ice1712 *ice)
2108
{
2109
struct aureon_spec *spec = ice->spec;
2110
int err, i;
2111
2112
err = aureon_reset(ice);
2113
if (err != 0)
2114
return err;
2115
2116
/* workaround for poking volume with alsamixer after resume:
2117
* just set stored volume again */
2118
for (i = 0; i < ice->num_total_dacs; i++)
2119
wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2120
return 0;
2121
}
2122
#endif
2123
2124
/*
2125
* initialize the chip
2126
*/
2127
static int __devinit aureon_init(struct snd_ice1712 *ice)
2128
{
2129
struct aureon_spec *spec;
2130
int i, err;
2131
2132
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2133
if (!spec)
2134
return -ENOMEM;
2135
ice->spec = spec;
2136
2137
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2138
ice->num_total_dacs = 6;
2139
ice->num_total_adcs = 2;
2140
} else {
2141
/* aureon 7.1 and prodigy 7.1 */
2142
ice->num_total_dacs = 8;
2143
ice->num_total_adcs = 2;
2144
}
2145
2146
/* to remember the register values of CS8415 */
2147
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2148
if (!ice->akm)
2149
return -ENOMEM;
2150
ice->akm_codecs = 1;
2151
2152
err = aureon_reset(ice);
2153
if (err != 0)
2154
return err;
2155
2156
spec->master[0] = WM_VOL_MUTE;
2157
spec->master[1] = WM_VOL_MUTE;
2158
for (i = 0; i < ice->num_total_dacs; i++) {
2159
spec->vol[i] = WM_VOL_MUTE;
2160
wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2161
}
2162
2163
#ifdef CONFIG_PM
2164
ice->pm_resume = aureon_resume;
2165
ice->pm_suspend_enabled = 1;
2166
#endif
2167
2168
return 0;
2169
}
2170
2171
2172
/*
2173
* Aureon boards don't provide the EEPROM data except for the vendor IDs.
2174
* hence the driver needs to sets up it properly.
2175
*/
2176
2177
static unsigned char aureon51_eeprom[] __devinitdata = {
2178
[ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2179
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
2180
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2181
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2182
[ICE_EEP2_GPIO_DIR] = 0xff,
2183
[ICE_EEP2_GPIO_DIR1] = 0xff,
2184
[ICE_EEP2_GPIO_DIR2] = 0x5f,
2185
[ICE_EEP2_GPIO_MASK] = 0x00,
2186
[ICE_EEP2_GPIO_MASK1] = 0x00,
2187
[ICE_EEP2_GPIO_MASK2] = 0x00,
2188
[ICE_EEP2_GPIO_STATE] = 0x00,
2189
[ICE_EEP2_GPIO_STATE1] = 0x00,
2190
[ICE_EEP2_GPIO_STATE2] = 0x00,
2191
};
2192
2193
static unsigned char aureon71_eeprom[] __devinitdata = {
2194
[ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2195
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
2196
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2197
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2198
[ICE_EEP2_GPIO_DIR] = 0xff,
2199
[ICE_EEP2_GPIO_DIR1] = 0xff,
2200
[ICE_EEP2_GPIO_DIR2] = 0x5f,
2201
[ICE_EEP2_GPIO_MASK] = 0x00,
2202
[ICE_EEP2_GPIO_MASK1] = 0x00,
2203
[ICE_EEP2_GPIO_MASK2] = 0x00,
2204
[ICE_EEP2_GPIO_STATE] = 0x00,
2205
[ICE_EEP2_GPIO_STATE1] = 0x00,
2206
[ICE_EEP2_GPIO_STATE2] = 0x00,
2207
};
2208
#define prodigy71_eeprom aureon71_eeprom
2209
2210
static unsigned char aureon71_universe_eeprom[] __devinitdata = {
2211
[ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
2212
* 4DACs
2213
*/
2214
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
2215
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2216
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2217
[ICE_EEP2_GPIO_DIR] = 0xff,
2218
[ICE_EEP2_GPIO_DIR1] = 0xff,
2219
[ICE_EEP2_GPIO_DIR2] = 0x5f,
2220
[ICE_EEP2_GPIO_MASK] = 0x00,
2221
[ICE_EEP2_GPIO_MASK1] = 0x00,
2222
[ICE_EEP2_GPIO_MASK2] = 0x00,
2223
[ICE_EEP2_GPIO_STATE] = 0x00,
2224
[ICE_EEP2_GPIO_STATE1] = 0x00,
2225
[ICE_EEP2_GPIO_STATE2] = 0x00,
2226
};
2227
2228
static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2229
[ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2230
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
2231
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2232
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2233
[ICE_EEP2_GPIO_DIR] = 0xff,
2234
[ICE_EEP2_GPIO_DIR1] = 0xff,
2235
[ICE_EEP2_GPIO_DIR2] = 0x5f,
2236
[ICE_EEP2_GPIO_MASK] = 0x00,
2237
[ICE_EEP2_GPIO_MASK1] = 0x00,
2238
[ICE_EEP2_GPIO_MASK2] = 0x00,
2239
[ICE_EEP2_GPIO_STATE] = 0x00,
2240
[ICE_EEP2_GPIO_STATE1] = 0x00,
2241
[ICE_EEP2_GPIO_STATE2] = 0x00,
2242
};
2243
#define prodigy71xt_eeprom prodigy71lt_eeprom
2244
2245
/* entry point */
2246
struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2247
{
2248
.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2249
.name = "Terratec Aureon 5.1-Sky",
2250
.model = "aureon51",
2251
.chip_init = aureon_init,
2252
.build_controls = aureon_add_controls,
2253
.eeprom_size = sizeof(aureon51_eeprom),
2254
.eeprom_data = aureon51_eeprom,
2255
.driver = "Aureon51",
2256
},
2257
{
2258
.subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2259
.name = "Terratec Aureon 7.1-Space",
2260
.model = "aureon71",
2261
.chip_init = aureon_init,
2262
.build_controls = aureon_add_controls,
2263
.eeprom_size = sizeof(aureon71_eeprom),
2264
.eeprom_data = aureon71_eeprom,
2265
.driver = "Aureon71",
2266
},
2267
{
2268
.subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2269
.name = "Terratec Aureon 7.1-Universe",
2270
.model = "universe",
2271
.chip_init = aureon_init,
2272
.build_controls = aureon_add_controls,
2273
.eeprom_size = sizeof(aureon71_universe_eeprom),
2274
.eeprom_data = aureon71_universe_eeprom,
2275
.driver = "Aureon71Univ", /* keep in 15 letters */
2276
},
2277
{
2278
.subvendor = VT1724_SUBDEVICE_PRODIGY71,
2279
.name = "Audiotrak Prodigy 7.1",
2280
.model = "prodigy71",
2281
.chip_init = aureon_init,
2282
.build_controls = aureon_add_controls,
2283
.eeprom_size = sizeof(prodigy71_eeprom),
2284
.eeprom_data = prodigy71_eeprom,
2285
.driver = "Prodigy71", /* should be identical with Aureon71 */
2286
},
2287
{
2288
.subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2289
.name = "Audiotrak Prodigy 7.1 LT",
2290
.model = "prodigy71lt",
2291
.chip_init = aureon_init,
2292
.build_controls = aureon_add_controls,
2293
.eeprom_size = sizeof(prodigy71lt_eeprom),
2294
.eeprom_data = prodigy71lt_eeprom,
2295
.driver = "Prodigy71LT",
2296
},
2297
{
2298
.subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2299
.name = "Audiotrak Prodigy 7.1 XT",
2300
.model = "prodigy71xt",
2301
.chip_init = aureon_init,
2302
.build_controls = aureon_add_controls,
2303
.eeprom_size = sizeof(prodigy71xt_eeprom),
2304
.eeprom_data = prodigy71xt_eeprom,
2305
.driver = "Prodigy71LT",
2306
},
2307
{ } /* terminator */
2308
};
2309
2310