• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/sound/pci/ice1712/
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 <julian@jusst.de>
8 *      Copyright (c) 2007 allank
9 *      Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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
43struct 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 */
128static 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 */
138static 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
145static 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
157static 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
171static 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
185static 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
211static 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
225static 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
256static 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
266static 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
279static 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
299static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
300
301static 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 */
321static 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
345static 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
362static 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
383static 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
393static 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
406static 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 */
430static 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
441static 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
455static 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 */
482static 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
492static 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
503static 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
537static 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
573static 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
584static 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
612static 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
622static 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
639static 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
666static 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
679static 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
706static 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
718static 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
744static 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
756static 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
784static 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 */
901static 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
917static 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
931static 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
941static 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
958static 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 */
979static 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		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
1006		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
1007		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
1008		WM_ALC_CTRL1,	0x007b,	/* */
1009		WM_ALC_CTRL2,	0x0000,	/* */
1010		WM_ALC_CTRL3,	0x0000,	/* */
1011		WM_NOISE_GATE,	0x0000,	/* */
1012		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
1013		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
1014	};
1015	static unsigned short wm8766_inits[] = {
1016		WM8766_RESET,	   0x0000,
1017		WM8766_DAC_CTRL,	0x0120,
1018		WM8766_INT_CTRL,	0x0022, /* I2S Normal Mode, 24 bit */
1019		WM8766_DAC_CTRL2,       0x0001,
1020		WM8766_DAC_CTRL3,       0x0080,
1021		WM8766_LDA1,	    0x0100,
1022		WM8766_LDA2,	    0x0100,
1023		WM8766_LDA3,	    0x0100,
1024		WM8766_RDA1,	    0x0100,
1025		WM8766_RDA2,	    0x0100,
1026		WM8766_RDA3,	    0x0100,
1027		WM8766_MUTE1,	   0x0000,
1028		WM8766_MUTE2,	   0x0000,
1029	};
1030
1031	struct prodigy_hifi_spec *spec;
1032	unsigned int i;
1033
1034	ice->vt1720 = 0;
1035	ice->vt1724 = 1;
1036
1037	ice->num_total_dacs = 8;
1038	ice->num_total_adcs = 1;
1039
1040	/* HACK - use this as the SPDIF source.
1041	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1042	*/
1043	ice->gpio.saved[0] = 0;
1044	/* to remeber the register values */
1045
1046	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1047	if (! ice->akm)
1048		return -ENOMEM;
1049	ice->akm_codecs = 1;
1050
1051	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1052	if (!spec)
1053		return -ENOMEM;
1054	ice->spec = spec;
1055
1056	/* initialize WM8776 codec */
1057	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
1058		wm_put(ice, wm_inits[i], wm_inits[i+1]);
1059	schedule_timeout_uninterruptible(1);
1060	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
1061		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
1062
1063	/* initialize WM8766 codec */
1064	for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
1065		wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
1066
1067
1068	return 0;
1069}
1070
1071
1072/*
1073 * initialize the chip
1074 */
1075static void ak4396_init(struct snd_ice1712 *ice)
1076{
1077	static unsigned short ak4396_inits[] = {
1078		AK4396_CTRL1,	   0x87,   /* I2S Normal Mode, 24 bit */
1079		AK4396_CTRL2,	   0x02,
1080		AK4396_CTRL3,	   0x00,
1081		AK4396_LCH_ATT,	 0x00,
1082		AK4396_RCH_ATT,	 0x00,
1083	};
1084
1085	unsigned int i;
1086
1087	/* initialize ak4396 codec */
1088	/* reset codec */
1089	ak4396_write(ice, AK4396_CTRL1, 0x86);
1090	msleep(100);
1091	ak4396_write(ice, AK4396_CTRL1, 0x87);
1092
1093	for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1094		ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1095}
1096
1097#ifdef CONFIG_PM
1098static int prodigy_hd2_resume(struct snd_ice1712 *ice)
1099{
1100	/* initialize ak4396 codec and restore previous mixer volumes */
1101	struct prodigy_hifi_spec *spec = ice->spec;
1102	int i;
1103	mutex_lock(&ice->gpio_mutex);
1104	ak4396_init(ice);
1105	for (i = 0; i < 2; i++)
1106		ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
1107	mutex_unlock(&ice->gpio_mutex);
1108	return 0;
1109}
1110#endif
1111
1112static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1113{
1114	struct prodigy_hifi_spec *spec;
1115
1116	ice->vt1720 = 0;
1117	ice->vt1724 = 1;
1118
1119	ice->num_total_dacs = 1;
1120	ice->num_total_adcs = 1;
1121
1122	/* HACK - use this as the SPDIF source.
1123	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1124	*/
1125	ice->gpio.saved[0] = 0;
1126	/* to remeber the register values */
1127
1128	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1129	if (! ice->akm)
1130		return -ENOMEM;
1131	ice->akm_codecs = 1;
1132
1133	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1134	if (!spec)
1135		return -ENOMEM;
1136	ice->spec = spec;
1137
1138#ifdef CONFIG_PM
1139	ice->pm_resume = &prodigy_hd2_resume;
1140	ice->pm_suspend_enabled = 1;
1141#endif
1142
1143	ak4396_init(ice);
1144
1145	return 0;
1146}
1147
1148
1149static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
1150	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1151	0x80,   /* ACLINK: I2S */
1152	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1153	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1154	0xff,   /* GPIO_DIR */
1155	0xff,   /* GPIO_DIR1 */
1156	0x5f,   /* GPIO_DIR2 */
1157	0x00,   /* GPIO_MASK */
1158	0x00,   /* GPIO_MASK1 */
1159	0x00,   /* GPIO_MASK2 */
1160	0x00,   /* GPIO_STATE */
1161	0x00,   /* GPIO_STATE1 */
1162	0x00,   /* GPIO_STATE2 */
1163};
1164
1165static unsigned char prodigyhd2_eeprom[] __devinitdata = {
1166	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1167	0x80,   /* ACLINK: I2S */
1168	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1169	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1170	0xff,   /* GPIO_DIR */
1171	0xff,   /* GPIO_DIR1 */
1172	0x5f,   /* GPIO_DIR2 */
1173	0x00,   /* GPIO_MASK */
1174	0x00,   /* GPIO_MASK1 */
1175	0x00,   /* GPIO_MASK2 */
1176	0x00,   /* GPIO_STATE */
1177	0x00,   /* GPIO_STATE1 */
1178	0x00,   /* GPIO_STATE2 */
1179};
1180
1181static unsigned char fortissimo4_eeprom[] __devinitdata = {
1182	0x43,   /* SYSCONF: clock 512, ADC, 4DACs */
1183	0x80,   /* ACLINK: I2S */
1184	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1185	0xc1,   /* SPDIF: out-en, out-int */
1186	0xff,   /* GPIO_DIR */
1187	0xff,   /* GPIO_DIR1 */
1188	0x5f,   /* GPIO_DIR2 */
1189	0x00,   /* GPIO_MASK */
1190	0x00,   /* GPIO_MASK1 */
1191	0x00,   /* GPIO_MASK2 */
1192	0x00,   /* GPIO_STATE */
1193	0x00,   /* GPIO_STATE1 */
1194	0x00,   /* GPIO_STATE2 */
1195};
1196
1197/* entry point */
1198struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
1199	{
1200		.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
1201		.name = "Audiotrak Prodigy 7.1 HiFi",
1202		.model = "prodigy71hifi",
1203		.chip_init = prodigy_hifi_init,
1204		.build_controls = prodigy_hifi_add_controls,
1205		.eeprom_size = sizeof(prodigy71hifi_eeprom),
1206		.eeprom_data = prodigy71hifi_eeprom,
1207		.driver = "Prodigy71HIFI",
1208	},
1209	{
1210	.subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
1211	.name = "Audiotrak Prodigy HD2",
1212	.model = "prodigyhd2",
1213	.chip_init = prodigy_hd2_init,
1214	.build_controls = prodigy_hd2_add_controls,
1215	.eeprom_size = sizeof(prodigyhd2_eeprom),
1216	.eeprom_data = prodigyhd2_eeprom,
1217	.driver = "Prodigy71HD2",
1218	},
1219	{
1220		.subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
1221		.name = "Hercules Fortissimo IV",
1222		.model = "fortissimo4",
1223		.chip_init = prodigy_hifi_init,
1224		.build_controls = prodigy_hifi_add_controls,
1225		.eeprom_size = sizeof(fortissimo4_eeprom),
1226		.eeprom_data = fortissimo4_eeprom,
1227		.driver = "Fortissimo4",
1228	},
1229	{ } /* terminator */
1230};
1231