• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <linux/delay.h>
29 #include <linux/interrupt.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/mutex.h>
33 
34 #include <sound/core.h>
35 #include <sound/info.h>
36 #include <sound/tlv.h>
37 
38 #include "ice1712.h"
39 #include "envy24ht.h"
40 #include "prodigy_hifi.h"
41 
42 struct prodigy_hifi_spec {
43 	unsigned short master[2];
44 	unsigned short vol[8];
45 };
46 
47 /* I2C addresses */
48 #define WM_DEV		0x34
49 
50 /* WM8776 registers */
51 #define WM_HP_ATTEN_L		0x00	/* headphone left attenuation */
52 #define WM_HP_ATTEN_R		0x01	/* headphone left attenuation */
53 #define WM_HP_MASTER		0x02	/* headphone master (both channels),
54 						override LLR */
55 #define WM_DAC_ATTEN_L		0x03	/* digital left attenuation */
56 #define WM_DAC_ATTEN_R		0x04
57 #define WM_DAC_MASTER		0x05
58 #define WM_PHASE_SWAP		0x06	/* DAC phase swap */
59 #define WM_DAC_CTRL1		0x07
60 #define WM_DAC_MUTE		0x08
61 #define WM_DAC_CTRL2		0x09
62 #define WM_DAC_INT		0x0a
63 #define WM_ADC_INT		0x0b
64 #define WM_MASTER_CTRL		0x0c
65 #define WM_POWERDOWN		0x0d
66 #define WM_ADC_ATTEN_L		0x0e
67 #define WM_ADC_ATTEN_R		0x0f
68 #define WM_ALC_CTRL1		0x10
69 #define WM_ALC_CTRL2		0x11
70 #define WM_ALC_CTRL3		0x12
71 #define WM_NOISE_GATE		0x13
72 #define WM_LIMITER		0x14
73 #define WM_ADC_MUX		0x15
74 #define WM_OUT_MUX		0x16
75 #define WM_RESET		0x17
76 
77 /* Analog Recording Source :- Mic, LineIn, CD/Video, */
78 
79 /* implement capture source select control for WM8776 */
80 
81 #define WM_AIN1 "AIN1"
82 #define WM_AIN2 "AIN2"
83 #define WM_AIN3 "AIN3"
84 #define WM_AIN4 "AIN4"
85 #define WM_AIN5 "AIN5"
86 
87 /* GPIO pins of envy24ht connected to wm8766 */
88 #define WM8766_SPI_CLK	 (1<<17) /* CLK, Pin97 on ICE1724 */
89 #define WM8766_SPI_MD	  (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
90 #define WM8766_SPI_ML	  (1<<18) /* Latch, Pin98 */
91 
92 /* WM8766 registers */
93 #define WM8766_DAC_CTRL	 0x02   /* DAC Control */
94 #define WM8766_INT_CTRL	 0x03   /* Interface Control */
95 #define WM8766_DAC_CTRL2	0x09
96 #define WM8766_DAC_CTRL3	0x0a
97 #define WM8766_RESET	    0x1f
98 #define WM8766_LDA1	     0x00
99 #define WM8766_LDA2	     0x04
100 #define WM8766_LDA3	     0x06
101 #define WM8766_RDA1	     0x01
102 #define WM8766_RDA2	     0x05
103 #define WM8766_RDA3	     0x07
104 #define WM8766_MUTE1	    0x0C
105 #define WM8766_MUTE2	    0x0F
106 
107 
108 /*
109  * Prodigy HD2
110  */
111 #define AK4396_ADDR    0x00
112 #define AK4396_CSN    (1 << 8)    /* CSN->GPIO8, pin 75 */
113 #define AK4396_CCLK   (1 << 9)    /* CCLK->GPIO9, pin 76 */
114 #define AK4396_CDTI   (1 << 10)   /* CDTI->GPIO10, pin 77 */
115 
116 /* ak4396 registers */
117 #define AK4396_CTRL1	    0x00
118 #define AK4396_CTRL2	    0x01
119 #define AK4396_CTRL3	    0x02
120 #define AK4396_LCH_ATT	  0x03
121 #define AK4396_RCH_ATT	  0x04
122 
123 
124 /*
125  * get the current register value of WM codec
126  */
wm_get(struct snd_ice1712 * ice,int reg)127 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
128 {
129 	reg <<= 1;
130 	return ((unsigned short)ice->akm[0].images[reg] << 8) |
131 		ice->akm[0].images[reg + 1];
132 }
133 
134 /*
135  * set the register value of WM codec and remember it
136  */
wm_put_nocache(struct snd_ice1712 * ice,int reg,unsigned short val)137 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
138 {
139 	unsigned short cval;
140 	cval = (reg << 9) | val;
141 	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
142 }
143 
wm_put(struct snd_ice1712 * ice,int reg,unsigned short val)144 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
145 {
146 	wm_put_nocache(ice, reg, val);
147 	reg <<= 1;
148 	ice->akm[0].images[reg] = val >> 8;
149 	ice->akm[0].images[reg + 1] = val;
150 }
151 
152 /*
153  * write data in the SPI mode
154  */
155 
set_gpio_bit(struct snd_ice1712 * ice,unsigned int bit,int val)156 static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
157 {
158 	unsigned int tmp = snd_ice1712_gpio_read(ice);
159 	if (val)
160 		tmp |= bit;
161 	else
162 		tmp &= ~bit;
163 	snd_ice1712_gpio_write(ice, tmp);
164 }
165 
166 /*
167  * SPI implementation for WM8766 codec - only writing supported, no readback
168  */
169 
wm8766_spi_send_word(struct snd_ice1712 * ice,unsigned int data)170 static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
171 {
172 	int i;
173 	for (i = 0; i < 16; i++) {
174 		set_gpio_bit(ice, WM8766_SPI_CLK, 0);
175 		udelay(1);
176 		set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
177 		udelay(1);
178 		set_gpio_bit(ice, WM8766_SPI_CLK, 1);
179 		udelay(1);
180 		data <<= 1;
181 	}
182 }
183 
wm8766_spi_write(struct snd_ice1712 * ice,unsigned int reg,unsigned int data)184 static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
185 			     unsigned int data)
186 {
187 	unsigned int block;
188 
189 	snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
190 					WM8766_SPI_CLK|WM8766_SPI_ML);
191 	snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
192 					WM8766_SPI_CLK|WM8766_SPI_ML));
193 	/* latch must be low when writing */
194 	set_gpio_bit(ice, WM8766_SPI_ML, 0);
195 	block = (reg << 9) | (data & 0x1ff);
196 	wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
197 	/* release latch */
198 	set_gpio_bit(ice, WM8766_SPI_ML, 1);
199 	udelay(1);
200 	/* restore */
201 	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
202 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
203 }
204 
205 
206 /*
207  * serial interface for ak4396 - only writing supported, no readback
208  */
209 
ak4396_send_word(struct snd_ice1712 * ice,unsigned int data)210 static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
211 {
212 	int i;
213 	for (i = 0; i < 16; i++) {
214 		set_gpio_bit(ice, AK4396_CCLK, 0);
215 		udelay(1);
216 		set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
217 		udelay(1);
218 		set_gpio_bit(ice, AK4396_CCLK, 1);
219 		udelay(1);
220 		data <<= 1;
221 	}
222 }
223 
ak4396_write(struct snd_ice1712 * ice,unsigned int reg,unsigned int data)224 static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
225 			 unsigned int data)
226 {
227 	unsigned int block;
228 
229 	snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
230 	snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
231 	/* latch must be low when writing */
232 	set_gpio_bit(ice, AK4396_CSN, 0);
233 	block =  ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
234 			((reg & 0x1f) << 8) | (data & 0xff);
235 	ak4396_send_word(ice, block); /* REGISTER ADDRESS */
236 	/* release latch */
237 	set_gpio_bit(ice, AK4396_CSN, 1);
238 	udelay(1);
239 	/* restore */
240 	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
241 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
242 }
243 
244 
245 /*
246  * ak4396 mixers
247  */
248 
249 
250 
251 /*
252  * DAC volume attenuation mixer control (-64dB to 0dB)
253  */
254 
ak4396_dac_vol_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)255 static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
256 			       struct snd_ctl_elem_info *uinfo)
257 {
258 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
259 	uinfo->count = 2;
260 	uinfo->value.integer.min = 0;   /* mute */
261 	uinfo->value.integer.max = 0xFF; /* linear */
262 	return 0;
263 }
264 
ak4396_dac_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)265 static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
266 			      struct snd_ctl_elem_value *ucontrol)
267 {
268 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
269 	struct prodigy_hifi_spec *spec = ice->spec;
270 	int i;
271 
272 	for (i = 0; i < 2; i++)
273 		ucontrol->value.integer.value[i] = spec->vol[i];
274 
275 	return 0;
276 }
277 
ak4396_dac_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)278 static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
279 {
280 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
281 	struct prodigy_hifi_spec *spec = ice->spec;
282 	int i;
283 	int change = 0;
284 
285 	mutex_lock(&ice->gpio_mutex);
286 	for (i = 0; i < 2; i++) {
287 		if (ucontrol->value.integer.value[i] != spec->vol[i]) {
288 			spec->vol[i] = ucontrol->value.integer.value[i];
289 			ak4396_write(ice, AK4396_LCH_ATT + i,
290 				     spec->vol[i] & 0xff);
291 			change = 1;
292 		}
293 	}
294 	mutex_unlock(&ice->gpio_mutex);
295 	return change;
296 }
297 
298 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
299 static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
300 
301 static struct snd_kcontrol_new prodigy_hd2_controls[] = {
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 = ak4396_db_scale },
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 
wm_set_vol(struct snd_ice1712 * ice,unsigned int index,unsigned short vol,unsigned short master)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 
wm8766_set_vol(struct snd_ice1712 * ice,unsigned int index,unsigned short vol,unsigned short master)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 
wm_dac_vol_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)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 
wm_dac_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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 
wm_dac_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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  */
wm8766_vol_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)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 
wm8766_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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 
wm8766_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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  */
wm_master_vol_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)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 
wm_master_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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 
wm_master_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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 
wm_adc_mux_enum_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)537 static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
538 				struct snd_ctl_elem_info *uinfo)
539 {
540 	static const char * const 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 	return snd_ctl_enum_info(uinfo, 1, 32, texts);
564 }
565 
wm_adc_mux_enum_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)566 static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
567 			       struct snd_ctl_elem_value *ucontrol)
568 {
569 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
570 
571 	mutex_lock(&ice->gpio_mutex);
572 	ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
573 	mutex_unlock(&ice->gpio_mutex);
574 	return 0;
575 }
576 
wm_adc_mux_enum_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)577 static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
578 			       struct snd_ctl_elem_value *ucontrol)
579 {
580 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
581 	unsigned short oval, nval;
582 	int change = 0;
583 
584 	mutex_lock(&ice->gpio_mutex);
585 	oval = wm_get(ice, WM_ADC_MUX);
586 	nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
587 	if (nval != oval) {
588 		wm_put(ice, WM_ADC_MUX, nval);
589 		change = 1;
590 	}
591 	mutex_unlock(&ice->gpio_mutex);
592 	return change;
593 }
594 
595 /* KONSTI */
596 
597 /*
598  * ADC gain mixer control (-64dB to 0dB)
599  */
600 
601 #define ADC_0dB	0xcf
602 #define ADC_RES	128
603 #define ADC_MIN	(ADC_0dB - ADC_RES)
604 
wm_adc_vol_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)605 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
606 			   struct snd_ctl_elem_info *uinfo)
607 {
608 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
609 	uinfo->count = 2;
610 	uinfo->value.integer.min = 0;	/* mute (-64dB) */
611 	uinfo->value.integer.max = ADC_RES;	/* 0dB, 0.5dB step */
612 	return 0;
613 }
614 
wm_adc_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)615 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
616 			  struct snd_ctl_elem_value *ucontrol)
617 {
618 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
619 	unsigned short val;
620 	int i;
621 
622 	mutex_lock(&ice->gpio_mutex);
623 	for (i = 0; i < 2; i++) {
624 		val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
625 		val = val > ADC_MIN ? (val - ADC_MIN) : 0;
626 		ucontrol->value.integer.value[i] = val;
627 	}
628 	mutex_unlock(&ice->gpio_mutex);
629 	return 0;
630 }
631 
wm_adc_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)632 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
633 			  struct snd_ctl_elem_value *ucontrol)
634 {
635 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
636 	unsigned short ovol, nvol;
637 	int i, idx, change = 0;
638 
639 	mutex_lock(&ice->gpio_mutex);
640 	for (i = 0; i < 2; i++) {
641 		nvol = ucontrol->value.integer.value[i];
642 		nvol = nvol ? (nvol + ADC_MIN) : 0;
643 		idx  = WM_ADC_ATTEN_L + i;
644 		ovol = wm_get(ice, idx) & 0xff;
645 		if (ovol != nvol) {
646 			wm_put(ice, idx, nvol);
647 			change = 1;
648 		}
649 	}
650 	mutex_unlock(&ice->gpio_mutex);
651 	return change;
652 }
653 
654 /*
655  * ADC input mux mixer control
656  */
657 #define wm_adc_mux_info		snd_ctl_boolean_mono_info
658 
wm_adc_mux_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)659 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
660 			  struct snd_ctl_elem_value *ucontrol)
661 {
662 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
663 	int bit = kcontrol->private_value;
664 
665 	mutex_lock(&ice->gpio_mutex);
666 	ucontrol->value.integer.value[0] =
667 		(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
668 	mutex_unlock(&ice->gpio_mutex);
669 	return 0;
670 }
671 
wm_adc_mux_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)672 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
673 			  struct snd_ctl_elem_value *ucontrol)
674 {
675 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
676 	int bit = kcontrol->private_value;
677 	unsigned short oval, nval;
678 	int change;
679 
680 	mutex_lock(&ice->gpio_mutex);
681 	nval = oval = wm_get(ice, WM_ADC_MUX);
682 	if (ucontrol->value.integer.value[0])
683 		nval |= (1 << bit);
684 	else
685 		nval &= ~(1 << bit);
686 	change = nval != oval;
687 	if (change) {
688 		wm_put(ice, WM_ADC_MUX, nval);
689 	}
690 	mutex_unlock(&ice->gpio_mutex);
691 	return 0;
692 }
693 
694 /*
695  * Analog bypass (In -> Out)
696  */
697 #define wm_bypass_info		snd_ctl_boolean_mono_info
698 
wm_bypass_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)699 static int wm_bypass_get(struct snd_kcontrol *kcontrol,
700 			 struct snd_ctl_elem_value *ucontrol)
701 {
702 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
703 
704 	mutex_lock(&ice->gpio_mutex);
705 	ucontrol->value.integer.value[0] =
706 		(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
707 	mutex_unlock(&ice->gpio_mutex);
708 	return 0;
709 }
710 
wm_bypass_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)711 static int wm_bypass_put(struct snd_kcontrol *kcontrol,
712 			 struct snd_ctl_elem_value *ucontrol)
713 {
714 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
715 	unsigned short val, oval;
716 	int change = 0;
717 
718 	mutex_lock(&ice->gpio_mutex);
719 	val = oval = wm_get(ice, WM_OUT_MUX);
720 	if (ucontrol->value.integer.value[0])
721 		val |= 0x04;
722 	else
723 		val &= ~0x04;
724 	if (val != oval) {
725 		wm_put(ice, WM_OUT_MUX, val);
726 		change = 1;
727 	}
728 	mutex_unlock(&ice->gpio_mutex);
729 	return change;
730 }
731 
732 /*
733  * Left/Right swap
734  */
735 #define wm_chswap_info		snd_ctl_boolean_mono_info
736 
wm_chswap_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)737 static int wm_chswap_get(struct snd_kcontrol *kcontrol,
738 			 struct snd_ctl_elem_value *ucontrol)
739 {
740 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
741 
742 	mutex_lock(&ice->gpio_mutex);
743 	ucontrol->value.integer.value[0] =
744 			(wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
745 	mutex_unlock(&ice->gpio_mutex);
746 	return 0;
747 }
748 
wm_chswap_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)749 static int wm_chswap_put(struct snd_kcontrol *kcontrol,
750 			 struct snd_ctl_elem_value *ucontrol)
751 {
752 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
753 	unsigned short val, oval;
754 	int change = 0;
755 
756 	mutex_lock(&ice->gpio_mutex);
757 	oval = wm_get(ice, WM_DAC_CTRL1);
758 	val = oval & 0x0f;
759 	if (ucontrol->value.integer.value[0])
760 		val |= 0x60;
761 	else
762 		val |= 0x90;
763 	if (val != oval) {
764 		wm_put(ice, WM_DAC_CTRL1, val);
765 		wm_put_nocache(ice, WM_DAC_CTRL1, val);
766 		change = 1;
767 	}
768 	mutex_unlock(&ice->gpio_mutex);
769 	return change;
770 }
771 
772 
773 /*
774  * mixers
775  */
776 
777 static struct snd_kcontrol_new prodigy_hifi_controls[] = {
778 	{
779 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
780 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
781 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
782 		.name = "Master Playback Volume",
783 		.info = wm_master_vol_info,
784 		.get = wm_master_vol_get,
785 		.put = wm_master_vol_put,
786 		.tlv = { .p = db_scale_wm_dac }
787 	},
788 	{
789 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
790 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
791 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
792 		.name = "Front Playback Volume",
793 		.info = wm_dac_vol_info,
794 		.get = wm_dac_vol_get,
795 		.put = wm_dac_vol_put,
796 		.tlv = { .p = db_scale_wm_dac },
797 	},
798 	{
799 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
800 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
801 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
802 		.name = "Rear Playback Volume",
803 		.info = wm8766_vol_info,
804 		.get = wm8766_vol_get,
805 		.put = wm8766_vol_put,
806 		.private_value = (2 << 8) | 0,
807 		.tlv = { .p = db_scale_wm_dac },
808 	},
809 	{
810 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
811 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
812 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
813 		.name = "Center Playback Volume",
814 		.info = wm8766_vol_info,
815 		.get = wm8766_vol_get,
816 		.put = wm8766_vol_put,
817 		.private_value = (1 << 8) | 4,
818 		.tlv = { .p = db_scale_wm_dac }
819 	},
820 	{
821 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
822 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
823 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
824 		.name = "LFE Playback Volume",
825 		.info = wm8766_vol_info,
826 		.get = wm8766_vol_get,
827 		.put = wm8766_vol_put,
828 		.private_value = (1 << 8) | 5,
829 		.tlv = { .p = db_scale_wm_dac }
830 	},
831 	{
832 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
833 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
834 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
835 		.name = "Side Playback Volume",
836 		.info = wm8766_vol_info,
837 		.get = wm8766_vol_get,
838 		.put = wm8766_vol_put,
839 		.private_value = (2 << 8) | 6,
840 		.tlv = { .p = db_scale_wm_dac },
841 	},
842 	{
843 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
845 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
846 		.name = "Capture Volume",
847 		.info = wm_adc_vol_info,
848 		.get = wm_adc_vol_get,
849 		.put = wm_adc_vol_put,
850 		.tlv = { .p = db_scale_wm_dac },
851 	},
852 	{
853 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
854 		.name = "CD Capture Switch",
855 		.info = wm_adc_mux_info,
856 		.get = wm_adc_mux_get,
857 		.put = wm_adc_mux_put,
858 		.private_value = 0,
859 	},
860 	{
861 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
862 		.name = "Line Capture Switch",
863 		.info = wm_adc_mux_info,
864 		.get = wm_adc_mux_get,
865 		.put = wm_adc_mux_put,
866 		.private_value = 1,
867 	},
868 	{
869 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
870 		.name = "Analog Bypass Switch",
871 		.info = wm_bypass_info,
872 		.get = wm_bypass_get,
873 		.put = wm_bypass_put,
874 	},
875 	{
876 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 		.name = "Swap Output Channels",
878 		.info = wm_chswap_info,
879 		.get = wm_chswap_get,
880 		.put = wm_chswap_put,
881 	},
882 	{
883 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
884 		.name = "Analog Capture Source",
885 		.info = wm_adc_mux_enum_info,
886 		.get = wm_adc_mux_enum_get,
887 		.put = wm_adc_mux_enum_put,
888 	},
889 };
890 
891 /*
892  * WM codec registers
893  */
wm_proc_regs_write(struct snd_info_entry * entry,struct snd_info_buffer * buffer)894 static void wm_proc_regs_write(struct snd_info_entry *entry,
895 			       struct snd_info_buffer *buffer)
896 {
897 	struct snd_ice1712 *ice = entry->private_data;
898 	char line[64];
899 	unsigned int reg, val;
900 	mutex_lock(&ice->gpio_mutex);
901 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
902 		if (sscanf(line, "%x %x", &reg, &val) != 2)
903 			continue;
904 		if (reg <= 0x17 && val <= 0xffff)
905 			wm_put(ice, reg, val);
906 	}
907 	mutex_unlock(&ice->gpio_mutex);
908 }
909 
wm_proc_regs_read(struct snd_info_entry * entry,struct snd_info_buffer * buffer)910 static void wm_proc_regs_read(struct snd_info_entry *entry,
911 			      struct snd_info_buffer *buffer)
912 {
913 	struct snd_ice1712 *ice = entry->private_data;
914 	int reg, val;
915 
916 	mutex_lock(&ice->gpio_mutex);
917 	for (reg = 0; reg <= 0x17; reg++) {
918 		val = wm_get(ice, reg);
919 		snd_iprintf(buffer, "%02x = %04x\n", reg, val);
920 	}
921 	mutex_unlock(&ice->gpio_mutex);
922 }
923 
wm_proc_init(struct snd_ice1712 * ice)924 static void wm_proc_init(struct snd_ice1712 *ice)
925 {
926 	struct snd_info_entry *entry;
927 	if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
928 		snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
929 		entry->mode |= S_IWUSR;
930 		entry->c.text.write = wm_proc_regs_write;
931 	}
932 }
933 
prodigy_hifi_add_controls(struct snd_ice1712 * ice)934 static int prodigy_hifi_add_controls(struct snd_ice1712 *ice)
935 {
936 	unsigned int i;
937 	int err;
938 
939 	for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
940 		err = snd_ctl_add(ice->card,
941 				  snd_ctl_new1(&prodigy_hifi_controls[i], ice));
942 		if (err < 0)
943 			return err;
944 	}
945 
946 	wm_proc_init(ice);
947 
948 	return 0;
949 }
950 
prodigy_hd2_add_controls(struct snd_ice1712 * ice)951 static int prodigy_hd2_add_controls(struct snd_ice1712 *ice)
952 {
953 	unsigned int i;
954 	int err;
955 
956 	for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
957 		err = snd_ctl_add(ice->card,
958 				  snd_ctl_new1(&prodigy_hd2_controls[i], ice));
959 		if (err < 0)
960 			return err;
961 	}
962 
963 	wm_proc_init(ice);
964 
965 	return 0;
966 }
967 
968 
969 /*
970  * initialize the chip
971  */
prodigy_hifi_init(struct snd_ice1712 * ice)972 static int prodigy_hifi_init(struct snd_ice1712 *ice)
973 {
974 	static unsigned short wm_inits[] = {
975 		/* These come first to reduce init pop noise */
976 		WM_ADC_MUX,	0x0003,	/* ADC mute */
977 		/* 0x00c0 replaced by 0x0003 */
978 
979 		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
980 		WM_DAC_CTRL1,	0x0000,	/* DAC mute */
981 
982 		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
983 		WM_RESET,	0x0000,	/* reset */
984 	};
985 	static unsigned short wm_inits2[] = {
986 		WM_MASTER_CTRL,  0x0022, /* 256fs, slave mode */
987 		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
988 		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
989 		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
990 		WM_OUT_MUX,	0x0001,	/* OUT DAC */
991 		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
992 		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
993 		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
994 		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
995 		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
996 		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
997 		WM_PHASE_SWAP,	0x0000,	/* phase normal */
998 #if 0
999 		WM_DAC_MASTER,	0x0100,	/* DAC master muted */
1000 #endif
1001 		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
1002 		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
1003 		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
1004 #if 1
1005 		WM_ALC_CTRL1,	0x007b,	/* */
1006 		WM_ALC_CTRL2,	0x0000,	/* */
1007 		WM_ALC_CTRL3,	0x0000,	/* */
1008 		WM_NOISE_GATE,	0x0000,	/* */
1009 #endif
1010 		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
1011 		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
1012 	};
1013 	static unsigned short wm8766_inits[] = {
1014 		WM8766_RESET,	   0x0000,
1015 		WM8766_DAC_CTRL,	0x0120,
1016 		WM8766_INT_CTRL,	0x0022, /* I2S Normal Mode, 24 bit */
1017 		WM8766_DAC_CTRL2,       0x0001,
1018 		WM8766_DAC_CTRL3,       0x0080,
1019 		WM8766_LDA1,	    0x0100,
1020 		WM8766_LDA2,	    0x0100,
1021 		WM8766_LDA3,	    0x0100,
1022 		WM8766_RDA1,	    0x0100,
1023 		WM8766_RDA2,	    0x0100,
1024 		WM8766_RDA3,	    0x0100,
1025 		WM8766_MUTE1,	   0x0000,
1026 		WM8766_MUTE2,	   0x0000,
1027 	};
1028 
1029 	struct prodigy_hifi_spec *spec;
1030 	unsigned int i;
1031 
1032 	ice->vt1720 = 0;
1033 	ice->vt1724 = 1;
1034 
1035 	ice->num_total_dacs = 8;
1036 	ice->num_total_adcs = 1;
1037 
1038 	/* HACK - use this as the SPDIF source.
1039 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1040 	*/
1041 	ice->gpio.saved[0] = 0;
1042 	/* to remember the register values */
1043 
1044 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1045 	if (! ice->akm)
1046 		return -ENOMEM;
1047 	ice->akm_codecs = 1;
1048 
1049 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1050 	if (!spec)
1051 		return -ENOMEM;
1052 	ice->spec = spec;
1053 
1054 	/* initialize WM8776 codec */
1055 	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
1056 		wm_put(ice, wm_inits[i], wm_inits[i+1]);
1057 	schedule_timeout_uninterruptible(1);
1058 	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
1059 		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
1060 
1061 	/* initialize WM8766 codec */
1062 	for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
1063 		wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
1064 
1065 
1066 	return 0;
1067 }
1068 
1069 
1070 /*
1071  * initialize the chip
1072  */
ak4396_init(struct snd_ice1712 * ice)1073 static void ak4396_init(struct snd_ice1712 *ice)
1074 {
1075 	static unsigned short ak4396_inits[] = {
1076 		AK4396_CTRL1,	   0x87,   /* I2S Normal Mode, 24 bit */
1077 		AK4396_CTRL2,	   0x02,
1078 		AK4396_CTRL3,	   0x00,
1079 		AK4396_LCH_ATT,	 0x00,
1080 		AK4396_RCH_ATT,	 0x00,
1081 	};
1082 
1083 	unsigned int i;
1084 
1085 	/* initialize ak4396 codec */
1086 	/* reset codec */
1087 	ak4396_write(ice, AK4396_CTRL1, 0x86);
1088 	msleep(100);
1089 	ak4396_write(ice, AK4396_CTRL1, 0x87);
1090 
1091 	for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1092 		ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1093 }
1094 
1095 #ifdef CONFIG_PM_SLEEP
prodigy_hd2_resume(struct snd_ice1712 * ice)1096 static int prodigy_hd2_resume(struct snd_ice1712 *ice)
1097 {
1098 	/* initialize ak4396 codec and restore previous mixer volumes */
1099 	struct prodigy_hifi_spec *spec = ice->spec;
1100 	int i;
1101 	mutex_lock(&ice->gpio_mutex);
1102 	ak4396_init(ice);
1103 	for (i = 0; i < 2; i++)
1104 		ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
1105 	mutex_unlock(&ice->gpio_mutex);
1106 	return 0;
1107 }
1108 #endif
1109 
prodigy_hd2_init(struct snd_ice1712 * ice)1110 static int prodigy_hd2_init(struct snd_ice1712 *ice)
1111 {
1112 	struct prodigy_hifi_spec *spec;
1113 
1114 	ice->vt1720 = 0;
1115 	ice->vt1724 = 1;
1116 
1117 	ice->num_total_dacs = 1;
1118 	ice->num_total_adcs = 1;
1119 
1120 	/* HACK - use this as the SPDIF source.
1121 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1122 	*/
1123 	ice->gpio.saved[0] = 0;
1124 	/* to remember the register values */
1125 
1126 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1127 	if (! ice->akm)
1128 		return -ENOMEM;
1129 	ice->akm_codecs = 1;
1130 
1131 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1132 	if (!spec)
1133 		return -ENOMEM;
1134 	ice->spec = spec;
1135 
1136 #ifdef CONFIG_PM_SLEEP
1137 	ice->pm_resume = &prodigy_hd2_resume;
1138 	ice->pm_suspend_enabled = 1;
1139 #endif
1140 
1141 	ak4396_init(ice);
1142 
1143 	return 0;
1144 }
1145 
1146 
1147 static unsigned char prodigy71hifi_eeprom[] = {
1148 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1149 	0x80,   /* ACLINK: I2S */
1150 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1151 	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1152 	0xff,   /* GPIO_DIR */
1153 	0xff,   /* GPIO_DIR1 */
1154 	0x5f,   /* GPIO_DIR2 */
1155 	0x00,   /* GPIO_MASK */
1156 	0x00,   /* GPIO_MASK1 */
1157 	0x00,   /* GPIO_MASK2 */
1158 	0x00,   /* GPIO_STATE */
1159 	0x00,   /* GPIO_STATE1 */
1160 	0x00,   /* GPIO_STATE2 */
1161 };
1162 
1163 static unsigned char prodigyhd2_eeprom[] = {
1164 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1165 	0x80,   /* ACLINK: I2S */
1166 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1167 	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1168 	0xff,   /* GPIO_DIR */
1169 	0xff,   /* GPIO_DIR1 */
1170 	0x5f,   /* GPIO_DIR2 */
1171 	0x00,   /* GPIO_MASK */
1172 	0x00,   /* GPIO_MASK1 */
1173 	0x00,   /* GPIO_MASK2 */
1174 	0x00,   /* GPIO_STATE */
1175 	0x00,   /* GPIO_STATE1 */
1176 	0x00,   /* GPIO_STATE2 */
1177 };
1178 
1179 static unsigned char fortissimo4_eeprom[] = {
1180 	0x43,   /* SYSCONF: clock 512, ADC, 4DACs */
1181 	0x80,   /* ACLINK: I2S */
1182 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1183 	0xc1,   /* SPDIF: out-en, out-int */
1184 	0xff,   /* GPIO_DIR */
1185 	0xff,   /* GPIO_DIR1 */
1186 	0x5f,   /* GPIO_DIR2 */
1187 	0x00,   /* GPIO_MASK */
1188 	0x00,   /* GPIO_MASK1 */
1189 	0x00,   /* GPIO_MASK2 */
1190 	0x00,   /* GPIO_STATE */
1191 	0x00,   /* GPIO_STATE1 */
1192 	0x00,   /* GPIO_STATE2 */
1193 };
1194 
1195 /* entry point */
1196 struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] = {
1197 	{
1198 		.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
1199 		.name = "Audiotrak Prodigy 7.1 HiFi",
1200 		.model = "prodigy71hifi",
1201 		.chip_init = prodigy_hifi_init,
1202 		.build_controls = prodigy_hifi_add_controls,
1203 		.eeprom_size = sizeof(prodigy71hifi_eeprom),
1204 		.eeprom_data = prodigy71hifi_eeprom,
1205 		.driver = "Prodigy71HIFI",
1206 	},
1207 	{
1208 	.subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
1209 	.name = "Audiotrak Prodigy HD2",
1210 	.model = "prodigyhd2",
1211 	.chip_init = prodigy_hd2_init,
1212 	.build_controls = prodigy_hd2_add_controls,
1213 	.eeprom_size = sizeof(prodigyhd2_eeprom),
1214 	.eeprom_data = prodigyhd2_eeprom,
1215 	.driver = "Prodigy71HD2",
1216 	},
1217 	{
1218 		.subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
1219 		.name = "Hercules Fortissimo IV",
1220 		.model = "fortissimo4",
1221 		.chip_init = prodigy_hifi_init,
1222 		.build_controls = prodigy_hifi_add_controls,
1223 		.eeprom_size = sizeof(fortissimo4_eeprom),
1224 		.eeprom_data = fortissimo4_eeprom,
1225 		.driver = "Fortissimo4",
1226 	},
1227 	{ } /* terminator */
1228 };
1229 
1230