Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/ice1712/prodigy_hifi.c
10817 views
1
/*
2
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
3
*
4
* Lowlevel functions for Audiotrak Prodigy 7.1 Hifi
5
* based on pontis.c
6
*
7
* Copyright (c) 2007 Julian Scheel <[email protected]>
8
* Copyright (c) 2007 allank
9
* Copyright (c) 2004 Takashi Iwai <[email protected]>
10
*
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
15
*
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
20
*
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
*
25
*/
26
27
28
#include <asm/io.h>
29
#include <linux/delay.h>
30
#include <linux/interrupt.h>
31
#include <linux/init.h>
32
#include <linux/slab.h>
33
#include <linux/mutex.h>
34
35
#include <sound/core.h>
36
#include <sound/info.h>
37
#include <sound/tlv.h>
38
39
#include "ice1712.h"
40
#include "envy24ht.h"
41
#include "prodigy_hifi.h"
42
43
struct prodigy_hifi_spec {
44
unsigned short master[2];
45
unsigned short vol[8];
46
};
47
48
/* I2C addresses */
49
#define WM_DEV 0x34
50
51
/* WM8776 registers */
52
#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
53
#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
54
#define WM_HP_MASTER 0x02 /* headphone master (both channels),
55
override LLR */
56
#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
57
#define WM_DAC_ATTEN_R 0x04
58
#define WM_DAC_MASTER 0x05
59
#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
60
#define WM_DAC_CTRL1 0x07
61
#define WM_DAC_MUTE 0x08
62
#define WM_DAC_CTRL2 0x09
63
#define WM_DAC_INT 0x0a
64
#define WM_ADC_INT 0x0b
65
#define WM_MASTER_CTRL 0x0c
66
#define WM_POWERDOWN 0x0d
67
#define WM_ADC_ATTEN_L 0x0e
68
#define WM_ADC_ATTEN_R 0x0f
69
#define WM_ALC_CTRL1 0x10
70
#define WM_ALC_CTRL2 0x11
71
#define WM_ALC_CTRL3 0x12
72
#define WM_NOISE_GATE 0x13
73
#define WM_LIMITER 0x14
74
#define WM_ADC_MUX 0x15
75
#define WM_OUT_MUX 0x16
76
#define WM_RESET 0x17
77
78
/* Analog Recording Source :- Mic, LineIn, CD/Video, */
79
80
/* implement capture source select control for WM8776 */
81
82
#define WM_AIN1 "AIN1"
83
#define WM_AIN2 "AIN2"
84
#define WM_AIN3 "AIN3"
85
#define WM_AIN4 "AIN4"
86
#define WM_AIN5 "AIN5"
87
88
/* GPIO pins of envy24ht connected to wm8766 */
89
#define WM8766_SPI_CLK (1<<17) /* CLK, Pin97 on ICE1724 */
90
#define WM8766_SPI_MD (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
91
#define WM8766_SPI_ML (1<<18) /* Latch, Pin98 */
92
93
/* WM8766 registers */
94
#define WM8766_DAC_CTRL 0x02 /* DAC Control */
95
#define WM8766_INT_CTRL 0x03 /* Interface Control */
96
#define WM8766_DAC_CTRL2 0x09
97
#define WM8766_DAC_CTRL3 0x0a
98
#define WM8766_RESET 0x1f
99
#define WM8766_LDA1 0x00
100
#define WM8766_LDA2 0x04
101
#define WM8766_LDA3 0x06
102
#define WM8766_RDA1 0x01
103
#define WM8766_RDA2 0x05
104
#define WM8766_RDA3 0x07
105
#define WM8766_MUTE1 0x0C
106
#define WM8766_MUTE2 0x0F
107
108
109
/*
110
* Prodigy HD2
111
*/
112
#define AK4396_ADDR 0x00
113
#define AK4396_CSN (1 << 8) /* CSN->GPIO8, pin 75 */
114
#define AK4396_CCLK (1 << 9) /* CCLK->GPIO9, pin 76 */
115
#define AK4396_CDTI (1 << 10) /* CDTI->GPIO10, pin 77 */
116
117
/* ak4396 registers */
118
#define AK4396_CTRL1 0x00
119
#define AK4396_CTRL2 0x01
120
#define AK4396_CTRL3 0x02
121
#define AK4396_LCH_ATT 0x03
122
#define AK4396_RCH_ATT 0x04
123
124
125
/*
126
* get the current register value of WM codec
127
*/
128
static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
129
{
130
reg <<= 1;
131
return ((unsigned short)ice->akm[0].images[reg] << 8) |
132
ice->akm[0].images[reg + 1];
133
}
134
135
/*
136
* set the register value of WM codec and remember it
137
*/
138
static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
139
{
140
unsigned short cval;
141
cval = (reg << 9) | val;
142
snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
143
}
144
145
static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
146
{
147
wm_put_nocache(ice, reg, val);
148
reg <<= 1;
149
ice->akm[0].images[reg] = val >> 8;
150
ice->akm[0].images[reg + 1] = val;
151
}
152
153
/*
154
* write data in the SPI mode
155
*/
156
157
static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
158
{
159
unsigned int tmp = snd_ice1712_gpio_read(ice);
160
if (val)
161
tmp |= bit;
162
else
163
tmp &= ~bit;
164
snd_ice1712_gpio_write(ice, tmp);
165
}
166
167
/*
168
* SPI implementation for WM8766 codec - only writing supported, no readback
169
*/
170
171
static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
172
{
173
int i;
174
for (i = 0; i < 16; i++) {
175
set_gpio_bit(ice, WM8766_SPI_CLK, 0);
176
udelay(1);
177
set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
178
udelay(1);
179
set_gpio_bit(ice, WM8766_SPI_CLK, 1);
180
udelay(1);
181
data <<= 1;
182
}
183
}
184
185
static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
186
unsigned int data)
187
{
188
unsigned int block;
189
190
snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
191
WM8766_SPI_CLK|WM8766_SPI_ML);
192
snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
193
WM8766_SPI_CLK|WM8766_SPI_ML));
194
/* latch must be low when writing */
195
set_gpio_bit(ice, WM8766_SPI_ML, 0);
196
block = (reg << 9) | (data & 0x1ff);
197
wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
198
/* release latch */
199
set_gpio_bit(ice, WM8766_SPI_ML, 1);
200
udelay(1);
201
/* restore */
202
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
203
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
204
}
205
206
207
/*
208
* serial interface for ak4396 - only writing supported, no readback
209
*/
210
211
static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
212
{
213
int i;
214
for (i = 0; i < 16; i++) {
215
set_gpio_bit(ice, AK4396_CCLK, 0);
216
udelay(1);
217
set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
218
udelay(1);
219
set_gpio_bit(ice, AK4396_CCLK, 1);
220
udelay(1);
221
data <<= 1;
222
}
223
}
224
225
static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
226
unsigned int data)
227
{
228
unsigned int block;
229
230
snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
231
snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
232
/* latch must be low when writing */
233
set_gpio_bit(ice, AK4396_CSN, 0);
234
block = ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
235
((reg & 0x1f) << 8) | (data & 0xff);
236
ak4396_send_word(ice, block); /* REGISTER ADDRESS */
237
/* release latch */
238
set_gpio_bit(ice, AK4396_CSN, 1);
239
udelay(1);
240
/* restore */
241
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
242
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
243
}
244
245
246
/*
247
* ak4396 mixers
248
*/
249
250
251
252
/*
253
* DAC volume attenuation mixer control (-64dB to 0dB)
254
*/
255
256
static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
257
struct snd_ctl_elem_info *uinfo)
258
{
259
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
260
uinfo->count = 2;
261
uinfo->value.integer.min = 0; /* mute */
262
uinfo->value.integer.max = 0xFF; /* linear */
263
return 0;
264
}
265
266
static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
267
struct snd_ctl_elem_value *ucontrol)
268
{
269
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
270
struct prodigy_hifi_spec *spec = ice->spec;
271
int i;
272
273
for (i = 0; i < 2; i++)
274
ucontrol->value.integer.value[i] = spec->vol[i];
275
276
return 0;
277
}
278
279
static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
280
{
281
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
282
struct prodigy_hifi_spec *spec = ice->spec;
283
int i;
284
int change = 0;
285
286
mutex_lock(&ice->gpio_mutex);
287
for (i = 0; i < 2; i++) {
288
if (ucontrol->value.integer.value[i] != spec->vol[i]) {
289
spec->vol[i] = ucontrol->value.integer.value[i];
290
ak4396_write(ice, AK4396_LCH_ATT + i,
291
spec->vol[i] & 0xff);
292
change = 1;
293
}
294
}
295
mutex_unlock(&ice->gpio_mutex);
296
return change;
297
}
298
299
static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
300
301
static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
302
{
303
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
304
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
305
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
306
.name = "Front Playback Volume",
307
.info = ak4396_dac_vol_info,
308
.get = ak4396_dac_vol_get,
309
.put = ak4396_dac_vol_put,
310
.tlv = { .p = db_scale_wm_dac },
311
},
312
};
313
314
315
/* --------------- */
316
317
/*
318
* Logarithmic volume values for WM87*6
319
* Computed as 20 * Log10(255 / x)
320
*/
321
static const unsigned char wm_vol[256] = {
322
127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
323
23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
324
17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
325
13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
326
11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
327
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
328
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
329
5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
330
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
331
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
332
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333
0, 0
334
};
335
336
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
337
#define WM_VOL_MUTE 0x8000
338
339
340
#define DAC_0dB 0xff
341
#define DAC_RES 128
342
#define DAC_MIN (DAC_0dB - DAC_RES)
343
344
345
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
346
unsigned short vol, unsigned short master)
347
{
348
unsigned char nvol;
349
350
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
351
nvol = 0;
352
else {
353
nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
354
& WM_VOL_MAX;
355
nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
356
}
357
358
wm_put(ice, index, nvol);
359
wm_put_nocache(ice, index, 0x100 | nvol);
360
}
361
362
static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
363
unsigned short vol, unsigned short master)
364
{
365
unsigned char nvol;
366
367
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
368
nvol = 0;
369
else {
370
nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
371
& WM_VOL_MAX;
372
nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
373
}
374
375
wm8766_spi_write(ice, index, (0x0100 | nvol));
376
}
377
378
379
/*
380
* DAC volume attenuation mixer control (-64dB to 0dB)
381
*/
382
383
static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
384
struct snd_ctl_elem_info *uinfo)
385
{
386
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
387
uinfo->count = 2;
388
uinfo->value.integer.min = 0; /* mute */
389
uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
390
return 0;
391
}
392
393
static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
394
struct snd_ctl_elem_value *ucontrol)
395
{
396
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
397
struct prodigy_hifi_spec *spec = ice->spec;
398
int i;
399
400
for (i = 0; i < 2; i++)
401
ucontrol->value.integer.value[i] =
402
spec->vol[2 + i] & ~WM_VOL_MUTE;
403
return 0;
404
}
405
406
static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
407
{
408
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
409
struct prodigy_hifi_spec *spec = ice->spec;
410
int i, idx, change = 0;
411
412
mutex_lock(&ice->gpio_mutex);
413
for (i = 0; i < 2; i++) {
414
if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
415
idx = WM_DAC_ATTEN_L + i;
416
spec->vol[2 + i] &= WM_VOL_MUTE;
417
spec->vol[2 + i] |= ucontrol->value.integer.value[i];
418
wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
419
change = 1;
420
}
421
}
422
mutex_unlock(&ice->gpio_mutex);
423
return change;
424
}
425
426
427
/*
428
* WM8766 DAC volume attenuation mixer control
429
*/
430
static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
431
struct snd_ctl_elem_info *uinfo)
432
{
433
int voices = kcontrol->private_value >> 8;
434
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
435
uinfo->count = voices;
436
uinfo->value.integer.min = 0; /* mute */
437
uinfo->value.integer.max = DAC_RES; /* 0dB */
438
return 0;
439
}
440
441
static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
442
struct snd_ctl_elem_value *ucontrol)
443
{
444
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
445
struct prodigy_hifi_spec *spec = ice->spec;
446
int i, ofs, voices;
447
448
voices = kcontrol->private_value >> 8;
449
ofs = kcontrol->private_value & 0xff;
450
for (i = 0; i < voices; i++)
451
ucontrol->value.integer.value[i] = spec->vol[ofs + i];
452
return 0;
453
}
454
455
static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
456
{
457
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
458
struct prodigy_hifi_spec *spec = ice->spec;
459
int i, idx, ofs, voices;
460
int change = 0;
461
462
voices = kcontrol->private_value >> 8;
463
ofs = kcontrol->private_value & 0xff;
464
mutex_lock(&ice->gpio_mutex);
465
for (i = 0; i < voices; i++) {
466
if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
467
idx = WM8766_LDA1 + ofs + i;
468
spec->vol[ofs + i] &= WM_VOL_MUTE;
469
spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
470
wm8766_set_vol(ice, idx,
471
spec->vol[ofs + i], spec->master[i]);
472
change = 1;
473
}
474
}
475
mutex_unlock(&ice->gpio_mutex);
476
return change;
477
}
478
479
/*
480
* Master volume attenuation mixer control / applied to WM8776+WM8766
481
*/
482
static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
483
struct snd_ctl_elem_info *uinfo)
484
{
485
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
486
uinfo->count = 2;
487
uinfo->value.integer.min = 0;
488
uinfo->value.integer.max = DAC_RES;
489
return 0;
490
}
491
492
static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
493
struct snd_ctl_elem_value *ucontrol)
494
{
495
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
496
struct prodigy_hifi_spec *spec = ice->spec;
497
int i;
498
for (i = 0; i < 2; i++)
499
ucontrol->value.integer.value[i] = spec->master[i];
500
return 0;
501
}
502
503
static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
504
struct snd_ctl_elem_value *ucontrol)
505
{
506
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
507
struct prodigy_hifi_spec *spec = ice->spec;
508
int ch, change = 0;
509
510
mutex_lock(&ice->gpio_mutex);
511
for (ch = 0; ch < 2; ch++) {
512
if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
513
spec->master[ch] = ucontrol->value.integer.value[ch];
514
515
/* Apply to front DAC */
516
wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
517
spec->vol[2 + ch], spec->master[ch]);
518
519
wm8766_set_vol(ice, WM8766_LDA1 + ch,
520
spec->vol[0 + ch], spec->master[ch]);
521
522
wm8766_set_vol(ice, WM8766_LDA2 + ch,
523
spec->vol[4 + ch], spec->master[ch]);
524
525
wm8766_set_vol(ice, WM8766_LDA3 + ch,
526
spec->vol[6 + ch], spec->master[ch]);
527
change = 1;
528
}
529
}
530
mutex_unlock(&ice->gpio_mutex);
531
return change;
532
}
533
534
535
/* KONSTI */
536
537
static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
538
struct snd_ctl_elem_info *uinfo)
539
{
540
static char* texts[32] = {
541
"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
542
WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
543
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
544
WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
545
WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
546
WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
547
WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
548
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
549
WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
550
WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
551
WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
552
WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
553
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
554
WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
555
WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
556
WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
557
WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
558
WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
559
WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
560
WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
561
};
562
563
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
564
uinfo->count = 1;
565
uinfo->value.enumerated.items = 32;
566
if (uinfo->value.enumerated.item > 31)
567
uinfo->value.enumerated.item = 31;
568
strcpy(uinfo->value.enumerated.name,
569
texts[uinfo->value.enumerated.item]);
570
return 0;
571
}
572
573
static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
574
struct snd_ctl_elem_value *ucontrol)
575
{
576
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
577
578
mutex_lock(&ice->gpio_mutex);
579
ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
580
mutex_unlock(&ice->gpio_mutex);
581
return 0;
582
}
583
584
static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
585
struct snd_ctl_elem_value *ucontrol)
586
{
587
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
588
unsigned short oval, nval;
589
int change = 0;
590
591
mutex_lock(&ice->gpio_mutex);
592
oval = wm_get(ice, WM_ADC_MUX);
593
nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
594
if (nval != oval) {
595
wm_put(ice, WM_ADC_MUX, nval);
596
change = 1;
597
}
598
mutex_unlock(&ice->gpio_mutex);
599
return change;
600
}
601
602
/* KONSTI */
603
604
/*
605
* ADC gain mixer control (-64dB to 0dB)
606
*/
607
608
#define ADC_0dB 0xcf
609
#define ADC_RES 128
610
#define ADC_MIN (ADC_0dB - ADC_RES)
611
612
static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
613
struct snd_ctl_elem_info *uinfo)
614
{
615
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
616
uinfo->count = 2;
617
uinfo->value.integer.min = 0; /* mute (-64dB) */
618
uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
619
return 0;
620
}
621
622
static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
623
struct snd_ctl_elem_value *ucontrol)
624
{
625
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
626
unsigned short val;
627
int i;
628
629
mutex_lock(&ice->gpio_mutex);
630
for (i = 0; i < 2; i++) {
631
val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
632
val = val > ADC_MIN ? (val - ADC_MIN) : 0;
633
ucontrol->value.integer.value[i] = val;
634
}
635
mutex_unlock(&ice->gpio_mutex);
636
return 0;
637
}
638
639
static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
640
struct snd_ctl_elem_value *ucontrol)
641
{
642
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
643
unsigned short ovol, nvol;
644
int i, idx, change = 0;
645
646
mutex_lock(&ice->gpio_mutex);
647
for (i = 0; i < 2; i++) {
648
nvol = ucontrol->value.integer.value[i];
649
nvol = nvol ? (nvol + ADC_MIN) : 0;
650
idx = WM_ADC_ATTEN_L + i;
651
ovol = wm_get(ice, idx) & 0xff;
652
if (ovol != nvol) {
653
wm_put(ice, idx, nvol);
654
change = 1;
655
}
656
}
657
mutex_unlock(&ice->gpio_mutex);
658
return change;
659
}
660
661
/*
662
* ADC input mux mixer control
663
*/
664
#define wm_adc_mux_info snd_ctl_boolean_mono_info
665
666
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
667
struct snd_ctl_elem_value *ucontrol)
668
{
669
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
670
int bit = kcontrol->private_value;
671
672
mutex_lock(&ice->gpio_mutex);
673
ucontrol->value.integer.value[0] =
674
(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
675
mutex_unlock(&ice->gpio_mutex);
676
return 0;
677
}
678
679
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
680
struct snd_ctl_elem_value *ucontrol)
681
{
682
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
683
int bit = kcontrol->private_value;
684
unsigned short oval, nval;
685
int change;
686
687
mutex_lock(&ice->gpio_mutex);
688
nval = oval = wm_get(ice, WM_ADC_MUX);
689
if (ucontrol->value.integer.value[0])
690
nval |= (1 << bit);
691
else
692
nval &= ~(1 << bit);
693
change = nval != oval;
694
if (change) {
695
wm_put(ice, WM_ADC_MUX, nval);
696
}
697
mutex_unlock(&ice->gpio_mutex);
698
return 0;
699
}
700
701
/*
702
* Analog bypass (In -> Out)
703
*/
704
#define wm_bypass_info snd_ctl_boolean_mono_info
705
706
static int wm_bypass_get(struct snd_kcontrol *kcontrol,
707
struct snd_ctl_elem_value *ucontrol)
708
{
709
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
710
711
mutex_lock(&ice->gpio_mutex);
712
ucontrol->value.integer.value[0] =
713
(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
714
mutex_unlock(&ice->gpio_mutex);
715
return 0;
716
}
717
718
static int wm_bypass_put(struct snd_kcontrol *kcontrol,
719
struct snd_ctl_elem_value *ucontrol)
720
{
721
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
722
unsigned short val, oval;
723
int change = 0;
724
725
mutex_lock(&ice->gpio_mutex);
726
val = oval = wm_get(ice, WM_OUT_MUX);
727
if (ucontrol->value.integer.value[0])
728
val |= 0x04;
729
else
730
val &= ~0x04;
731
if (val != oval) {
732
wm_put(ice, WM_OUT_MUX, val);
733
change = 1;
734
}
735
mutex_unlock(&ice->gpio_mutex);
736
return change;
737
}
738
739
/*
740
* Left/Right swap
741
*/
742
#define wm_chswap_info snd_ctl_boolean_mono_info
743
744
static int wm_chswap_get(struct snd_kcontrol *kcontrol,
745
struct snd_ctl_elem_value *ucontrol)
746
{
747
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
748
749
mutex_lock(&ice->gpio_mutex);
750
ucontrol->value.integer.value[0] =
751
(wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
752
mutex_unlock(&ice->gpio_mutex);
753
return 0;
754
}
755
756
static int wm_chswap_put(struct snd_kcontrol *kcontrol,
757
struct snd_ctl_elem_value *ucontrol)
758
{
759
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
760
unsigned short val, oval;
761
int change = 0;
762
763
mutex_lock(&ice->gpio_mutex);
764
oval = wm_get(ice, WM_DAC_CTRL1);
765
val = oval & 0x0f;
766
if (ucontrol->value.integer.value[0])
767
val |= 0x60;
768
else
769
val |= 0x90;
770
if (val != oval) {
771
wm_put(ice, WM_DAC_CTRL1, val);
772
wm_put_nocache(ice, WM_DAC_CTRL1, val);
773
change = 1;
774
}
775
mutex_unlock(&ice->gpio_mutex);
776
return change;
777
}
778
779
780
/*
781
* mixers
782
*/
783
784
static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
785
{
786
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
787
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
788
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
789
.name = "Master Playback Volume",
790
.info = wm_master_vol_info,
791
.get = wm_master_vol_get,
792
.put = wm_master_vol_put,
793
.tlv = { .p = db_scale_wm_dac }
794
},
795
{
796
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
797
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
798
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
799
.name = "Front Playback Volume",
800
.info = wm_dac_vol_info,
801
.get = wm_dac_vol_get,
802
.put = wm_dac_vol_put,
803
.tlv = { .p = db_scale_wm_dac },
804
},
805
{
806
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
808
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
809
.name = "Rear Playback Volume",
810
.info = wm8766_vol_info,
811
.get = wm8766_vol_get,
812
.put = wm8766_vol_put,
813
.private_value = (2 << 8) | 0,
814
.tlv = { .p = db_scale_wm_dac },
815
},
816
{
817
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
819
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
820
.name = "Center Playback Volume",
821
.info = wm8766_vol_info,
822
.get = wm8766_vol_get,
823
.put = wm8766_vol_put,
824
.private_value = (1 << 8) | 4,
825
.tlv = { .p = db_scale_wm_dac }
826
},
827
{
828
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
829
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
830
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
831
.name = "LFE Playback Volume",
832
.info = wm8766_vol_info,
833
.get = wm8766_vol_get,
834
.put = wm8766_vol_put,
835
.private_value = (1 << 8) | 5,
836
.tlv = { .p = db_scale_wm_dac }
837
},
838
{
839
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
840
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
841
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
842
.name = "Side Playback Volume",
843
.info = wm8766_vol_info,
844
.get = wm8766_vol_get,
845
.put = wm8766_vol_put,
846
.private_value = (2 << 8) | 6,
847
.tlv = { .p = db_scale_wm_dac },
848
},
849
{
850
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
851
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
852
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
853
.name = "Capture Volume",
854
.info = wm_adc_vol_info,
855
.get = wm_adc_vol_get,
856
.put = wm_adc_vol_put,
857
.tlv = { .p = db_scale_wm_dac },
858
},
859
{
860
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
861
.name = "CD Capture Switch",
862
.info = wm_adc_mux_info,
863
.get = wm_adc_mux_get,
864
.put = wm_adc_mux_put,
865
.private_value = 0,
866
},
867
{
868
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
869
.name = "Line Capture Switch",
870
.info = wm_adc_mux_info,
871
.get = wm_adc_mux_get,
872
.put = wm_adc_mux_put,
873
.private_value = 1,
874
},
875
{
876
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877
.name = "Analog Bypass Switch",
878
.info = wm_bypass_info,
879
.get = wm_bypass_get,
880
.put = wm_bypass_put,
881
},
882
{
883
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
884
.name = "Swap Output Channels",
885
.info = wm_chswap_info,
886
.get = wm_chswap_get,
887
.put = wm_chswap_put,
888
},
889
{
890
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
891
.name = "Analog Capture Source",
892
.info = wm_adc_mux_enum_info,
893
.get = wm_adc_mux_enum_get,
894
.put = wm_adc_mux_enum_put,
895
},
896
};
897
898
/*
899
* WM codec registers
900
*/
901
static void wm_proc_regs_write(struct snd_info_entry *entry,
902
struct snd_info_buffer *buffer)
903
{
904
struct snd_ice1712 *ice = entry->private_data;
905
char line[64];
906
unsigned int reg, val;
907
mutex_lock(&ice->gpio_mutex);
908
while (!snd_info_get_line(buffer, line, sizeof(line))) {
909
if (sscanf(line, "%x %x", &reg, &val) != 2)
910
continue;
911
if (reg <= 0x17 && val <= 0xffff)
912
wm_put(ice, reg, val);
913
}
914
mutex_unlock(&ice->gpio_mutex);
915
}
916
917
static void wm_proc_regs_read(struct snd_info_entry *entry,
918
struct snd_info_buffer *buffer)
919
{
920
struct snd_ice1712 *ice = entry->private_data;
921
int reg, val;
922
923
mutex_lock(&ice->gpio_mutex);
924
for (reg = 0; reg <= 0x17; reg++) {
925
val = wm_get(ice, reg);
926
snd_iprintf(buffer, "%02x = %04x\n", reg, val);
927
}
928
mutex_unlock(&ice->gpio_mutex);
929
}
930
931
static void wm_proc_init(struct snd_ice1712 *ice)
932
{
933
struct snd_info_entry *entry;
934
if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
935
snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
936
entry->mode |= S_IWUSR;
937
entry->c.text.write = wm_proc_regs_write;
938
}
939
}
940
941
static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
942
{
943
unsigned int i;
944
int err;
945
946
for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
947
err = snd_ctl_add(ice->card,
948
snd_ctl_new1(&prodigy_hifi_controls[i], ice));
949
if (err < 0)
950
return err;
951
}
952
953
wm_proc_init(ice);
954
955
return 0;
956
}
957
958
static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
959
{
960
unsigned int i;
961
int err;
962
963
for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
964
err = snd_ctl_add(ice->card,
965
snd_ctl_new1(&prodigy_hd2_controls[i], ice));
966
if (err < 0)
967
return err;
968
}
969
970
wm_proc_init(ice);
971
972
return 0;
973
}
974
975
976
/*
977
* initialize the chip
978
*/
979
static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
980
{
981
static unsigned short wm_inits[] = {
982
/* These come first to reduce init pop noise */
983
WM_ADC_MUX, 0x0003, /* ADC mute */
984
/* 0x00c0 replaced by 0x0003 */
985
986
WM_DAC_MUTE, 0x0001, /* DAC softmute */
987
WM_DAC_CTRL1, 0x0000, /* DAC mute */
988
989
WM_POWERDOWN, 0x0008, /* All power-up except HP */
990
WM_RESET, 0x0000, /* reset */
991
};
992
static unsigned short wm_inits2[] = {
993
WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
994
WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
995
WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
996
WM_DAC_CTRL1, 0x0090, /* DAC L/R */
997
WM_OUT_MUX, 0x0001, /* OUT DAC */
998
WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
999
WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
1000
WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
1001
WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
1002
WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
1003
WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
1004
WM_PHASE_SWAP, 0x0000, /* phase normal */
1005
#if 0
1006
WM_DAC_MASTER, 0x0100, /* DAC master muted */
1007
#endif
1008
WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
1009
WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
1010
WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
1011
#if 1
1012
WM_ALC_CTRL1, 0x007b, /* */
1013
WM_ALC_CTRL2, 0x0000, /* */
1014
WM_ALC_CTRL3, 0x0000, /* */
1015
WM_NOISE_GATE, 0x0000, /* */
1016
#endif
1017
WM_DAC_MUTE, 0x0000, /* DAC unmute */
1018
WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
1019
};
1020
static unsigned short wm8766_inits[] = {
1021
WM8766_RESET, 0x0000,
1022
WM8766_DAC_CTRL, 0x0120,
1023
WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */
1024
WM8766_DAC_CTRL2, 0x0001,
1025
WM8766_DAC_CTRL3, 0x0080,
1026
WM8766_LDA1, 0x0100,
1027
WM8766_LDA2, 0x0100,
1028
WM8766_LDA3, 0x0100,
1029
WM8766_RDA1, 0x0100,
1030
WM8766_RDA2, 0x0100,
1031
WM8766_RDA3, 0x0100,
1032
WM8766_MUTE1, 0x0000,
1033
WM8766_MUTE2, 0x0000,
1034
};
1035
1036
struct prodigy_hifi_spec *spec;
1037
unsigned int i;
1038
1039
ice->vt1720 = 0;
1040
ice->vt1724 = 1;
1041
1042
ice->num_total_dacs = 8;
1043
ice->num_total_adcs = 1;
1044
1045
/* HACK - use this as the SPDIF source.
1046
* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1047
*/
1048
ice->gpio.saved[0] = 0;
1049
/* to remember the register values */
1050
1051
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1052
if (! ice->akm)
1053
return -ENOMEM;
1054
ice->akm_codecs = 1;
1055
1056
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1057
if (!spec)
1058
return -ENOMEM;
1059
ice->spec = spec;
1060
1061
/* initialize WM8776 codec */
1062
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
1063
wm_put(ice, wm_inits[i], wm_inits[i+1]);
1064
schedule_timeout_uninterruptible(1);
1065
for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
1066
wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
1067
1068
/* initialize WM8766 codec */
1069
for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
1070
wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
1071
1072
1073
return 0;
1074
}
1075
1076
1077
/*
1078
* initialize the chip
1079
*/
1080
static void ak4396_init(struct snd_ice1712 *ice)
1081
{
1082
static unsigned short ak4396_inits[] = {
1083
AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */
1084
AK4396_CTRL2, 0x02,
1085
AK4396_CTRL3, 0x00,
1086
AK4396_LCH_ATT, 0x00,
1087
AK4396_RCH_ATT, 0x00,
1088
};
1089
1090
unsigned int i;
1091
1092
/* initialize ak4396 codec */
1093
/* reset codec */
1094
ak4396_write(ice, AK4396_CTRL1, 0x86);
1095
msleep(100);
1096
ak4396_write(ice, AK4396_CTRL1, 0x87);
1097
1098
for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1099
ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1100
}
1101
1102
#ifdef CONFIG_PM
1103
static int prodigy_hd2_resume(struct snd_ice1712 *ice)
1104
{
1105
/* initialize ak4396 codec and restore previous mixer volumes */
1106
struct prodigy_hifi_spec *spec = ice->spec;
1107
int i;
1108
mutex_lock(&ice->gpio_mutex);
1109
ak4396_init(ice);
1110
for (i = 0; i < 2; i++)
1111
ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
1112
mutex_unlock(&ice->gpio_mutex);
1113
return 0;
1114
}
1115
#endif
1116
1117
static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1118
{
1119
struct prodigy_hifi_spec *spec;
1120
1121
ice->vt1720 = 0;
1122
ice->vt1724 = 1;
1123
1124
ice->num_total_dacs = 1;
1125
ice->num_total_adcs = 1;
1126
1127
/* HACK - use this as the SPDIF source.
1128
* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1129
*/
1130
ice->gpio.saved[0] = 0;
1131
/* to remember the register values */
1132
1133
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1134
if (! ice->akm)
1135
return -ENOMEM;
1136
ice->akm_codecs = 1;
1137
1138
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1139
if (!spec)
1140
return -ENOMEM;
1141
ice->spec = spec;
1142
1143
#ifdef CONFIG_PM
1144
ice->pm_resume = &prodigy_hd2_resume;
1145
ice->pm_suspend_enabled = 1;
1146
#endif
1147
1148
ak4396_init(ice);
1149
1150
return 0;
1151
}
1152
1153
1154
static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
1155
0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1156
0x80, /* ACLINK: I2S */
1157
0xfc, /* I2S: vol, 96k, 24bit, 192k */
1158
0xc3, /* SPDIF: out-en, out-int, spdif-in */
1159
0xff, /* GPIO_DIR */
1160
0xff, /* GPIO_DIR1 */
1161
0x5f, /* GPIO_DIR2 */
1162
0x00, /* GPIO_MASK */
1163
0x00, /* GPIO_MASK1 */
1164
0x00, /* GPIO_MASK2 */
1165
0x00, /* GPIO_STATE */
1166
0x00, /* GPIO_STATE1 */
1167
0x00, /* GPIO_STATE2 */
1168
};
1169
1170
static unsigned char prodigyhd2_eeprom[] __devinitdata = {
1171
0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1172
0x80, /* ACLINK: I2S */
1173
0xfc, /* I2S: vol, 96k, 24bit, 192k */
1174
0xc3, /* SPDIF: out-en, out-int, spdif-in */
1175
0xff, /* GPIO_DIR */
1176
0xff, /* GPIO_DIR1 */
1177
0x5f, /* GPIO_DIR2 */
1178
0x00, /* GPIO_MASK */
1179
0x00, /* GPIO_MASK1 */
1180
0x00, /* GPIO_MASK2 */
1181
0x00, /* GPIO_STATE */
1182
0x00, /* GPIO_STATE1 */
1183
0x00, /* GPIO_STATE2 */
1184
};
1185
1186
static unsigned char fortissimo4_eeprom[] __devinitdata = {
1187
0x43, /* SYSCONF: clock 512, ADC, 4DACs */
1188
0x80, /* ACLINK: I2S */
1189
0xfc, /* I2S: vol, 96k, 24bit, 192k */
1190
0xc1, /* SPDIF: out-en, out-int */
1191
0xff, /* GPIO_DIR */
1192
0xff, /* GPIO_DIR1 */
1193
0x5f, /* GPIO_DIR2 */
1194
0x00, /* GPIO_MASK */
1195
0x00, /* GPIO_MASK1 */
1196
0x00, /* GPIO_MASK2 */
1197
0x00, /* GPIO_STATE */
1198
0x00, /* GPIO_STATE1 */
1199
0x00, /* GPIO_STATE2 */
1200
};
1201
1202
/* entry point */
1203
struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
1204
{
1205
.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
1206
.name = "Audiotrak Prodigy 7.1 HiFi",
1207
.model = "prodigy71hifi",
1208
.chip_init = prodigy_hifi_init,
1209
.build_controls = prodigy_hifi_add_controls,
1210
.eeprom_size = sizeof(prodigy71hifi_eeprom),
1211
.eeprom_data = prodigy71hifi_eeprom,
1212
.driver = "Prodigy71HIFI",
1213
},
1214
{
1215
.subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
1216
.name = "Audiotrak Prodigy HD2",
1217
.model = "prodigyhd2",
1218
.chip_init = prodigy_hd2_init,
1219
.build_controls = prodigy_hd2_add_controls,
1220
.eeprom_size = sizeof(prodigyhd2_eeprom),
1221
.eeprom_data = prodigyhd2_eeprom,
1222
.driver = "Prodigy71HD2",
1223
},
1224
{
1225
.subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
1226
.name = "Hercules Fortissimo IV",
1227
.model = "fortissimo4",
1228
.chip_init = prodigy_hifi_init,
1229
.build_controls = prodigy_hifi_add_controls,
1230
.eeprom_size = sizeof(fortissimo4_eeprom),
1231
.eeprom_data = fortissimo4_eeprom,
1232
.driver = "Fortissimo4",
1233
},
1234
{ } /* terminator */
1235
};
1236
1237
1238