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