1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
5 * Lowlevel functions for AudioTrak Prodigy 192 cards
6 * Supported IEC958 input from optional MI/ODI/O add-on card.
11 * * SPDIF-OUT on the card:
12 * - coax (through isolation transformer)/toslink supplied by
13 * 74HC04 gates - 3 in parallel
14 * - output switched between on-board CD drive dig-out connector
15 * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
16 * by GPIO20 (0 = CD dig-out, 1 = SPDTX)
17 * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
19 * * MI/ODI/O card: AK4114 based, used for iec958 input only
20 * - toslink input -> RX0
24 * ------------------------------
25 * CDTO (pin 32) -- GPIO11 pin 86
26 * CDTI (pin 33) -- GPIO10 pin 77
27 * CCLK (pin 34) -- GPIO9 pin 76
28 * CSN (pin 35) -- GPIO8 pin 75
29 * - output data Mode 7 (24bit, I2S, slave)
30 * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
31 * outputs master clock to SPMCLKIN of ice1724.
32 * Experimentally I found out that only a combination of
33 * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
34 * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
35 * sampling rate. That means that the FPGA doubles the
38 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
39 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
40 * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
43 #include <linux/delay.h>
44 #include <linux/interrupt.h>
45 #include <linux/init.h>
46 #include <linux/slab.h>
47 #include <sound/core.h>
51 #include "prodigy192.h"
53 #include <sound/tlv.h>
55 struct prodigy192_spec
{
56 struct ak4114
*ak4114
;
57 /* rate change needs atomic mute/unmute of all dacs*/
58 struct mutex mute_mutex
;
61 static inline void stac9460_put(struct snd_ice1712
*ice
, int reg
, unsigned char val
)
63 snd_vt1724_write_i2c(ice
, PRODIGY192_STAC9460_ADDR
, reg
, val
);
66 static inline unsigned char stac9460_get(struct snd_ice1712
*ice
, int reg
)
68 return snd_vt1724_read_i2c(ice
, PRODIGY192_STAC9460_ADDR
, reg
);
76 * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
78 static int stac9460_dac_mute(struct snd_ice1712
*ice
, int idx
,
81 unsigned char new, old
;
83 old
= stac9460_get(ice
, idx
);
84 new = (~mute
<< 7 & 0x80) | (old
& ~0x80);
85 change
= (new != old
);
87 /* dev_dbg(ice->card->dev, "Volume register 0x%02x: 0x%02x\n", idx, new);*/
88 stac9460_put(ice
, idx
, new);
92 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
94 static int stac9460_dac_mute_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
96 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
100 if (kcontrol
->private_value
)
101 idx
= STAC946X_MASTER_VOLUME
;
103 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
104 val
= stac9460_get(ice
, idx
);
105 ucontrol
->value
.integer
.value
[0] = (~val
>> 7) & 0x1;
109 static int stac9460_dac_mute_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
111 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
112 struct prodigy192_spec
*spec
= ice
->spec
;
115 if (kcontrol
->private_value
)
116 idx
= STAC946X_MASTER_VOLUME
;
118 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
119 /* due to possible conflicts with stac9460_set_rate_val, mutexing */
120 mutex_lock(&spec
->mute_mutex
);
122 dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
123 ucontrol->value.integer.value[0]);
125 change
= stac9460_dac_mute(ice
, idx
, ucontrol
->value
.integer
.value
[0]);
126 mutex_unlock(&spec
->mute_mutex
);
131 * DAC volume attenuation mixer control
133 static int stac9460_dac_vol_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
135 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
137 uinfo
->value
.integer
.min
= 0; /* mute */
138 uinfo
->value
.integer
.max
= 0x7f; /* 0dB */
142 static int stac9460_dac_vol_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
144 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
148 if (kcontrol
->private_value
)
149 idx
= STAC946X_MASTER_VOLUME
;
151 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
152 vol
= stac9460_get(ice
, idx
) & 0x7f;
153 ucontrol
->value
.integer
.value
[0] = 0x7f - vol
;
158 static int stac9460_dac_vol_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
160 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
162 unsigned char tmp
, ovol
, nvol
;
165 if (kcontrol
->private_value
)
166 idx
= STAC946X_MASTER_VOLUME
;
168 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
169 nvol
= ucontrol
->value
.integer
.value
[0];
170 tmp
= stac9460_get(ice
, idx
);
171 ovol
= 0x7f - (tmp
& 0x7f);
172 change
= (ovol
!= nvol
);
174 ovol
= (0x7f - nvol
) | (tmp
& 0x80);
176 dev_dbg(ice->card->dev, "DAC Volume: reg 0x%02x: 0x%02x\n",
179 stac9460_put(ice
, idx
, (0x7f - nvol
) | (tmp
& 0x80));
187 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
189 static int stac9460_adc_mute_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
191 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
195 for (i
= 0; i
< 2; ++i
) {
196 val
= stac9460_get(ice
, STAC946X_MIC_L_VOLUME
+ i
);
197 ucontrol
->value
.integer
.value
[i
] = ~val
>>7 & 0x1;
203 static int stac9460_adc_mute_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
205 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
206 unsigned char new, old
;
210 for (i
= 0; i
< 2; ++i
) {
211 reg
= STAC946X_MIC_L_VOLUME
+ i
;
212 old
= stac9460_get(ice
, reg
);
213 new = (~ucontrol
->value
.integer
.value
[i
]<<7&0x80) | (old
&~0x80);
214 change
= (new != old
);
216 stac9460_put(ice
, reg
, new);
223 * ADC gain mixer control
225 static int stac9460_adc_vol_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
227 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
229 uinfo
->value
.integer
.min
= 0; /* 0dB */
230 uinfo
->value
.integer
.max
= 0x0f; /* 22.5dB */
234 static int stac9460_adc_vol_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
236 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
240 for (i
= 0; i
< 2; ++i
) {
241 reg
= STAC946X_MIC_L_VOLUME
+ i
;
242 vol
= stac9460_get(ice
, reg
) & 0x0f;
243 ucontrol
->value
.integer
.value
[i
] = 0x0f - vol
;
249 static int stac9460_adc_vol_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
251 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
253 unsigned char ovol
, nvol
;
256 for (i
= 0; i
< 2; ++i
) {
257 reg
= STAC946X_MIC_L_VOLUME
+ i
;
258 nvol
= ucontrol
->value
.integer
.value
[i
] & 0x0f;
259 ovol
= 0x0f - stac9460_get(ice
, reg
);
260 change
= ((ovol
& 0x0f) != nvol
);
262 stac9460_put(ice
, reg
, (0x0f - nvol
) | (ovol
& ~0x0f));
268 static int stac9460_mic_sw_info(struct snd_kcontrol
*kcontrol
,
269 struct snd_ctl_elem_info
*uinfo
)
271 static const char * const texts
[2] = { "Line In", "Mic" };
273 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
277 static int stac9460_mic_sw_get(struct snd_kcontrol
*kcontrol
,
278 struct snd_ctl_elem_value
*ucontrol
)
280 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
283 val
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
284 ucontrol
->value
.enumerated
.item
[0] = (val
>> 7) & 0x1;
288 static int stac9460_mic_sw_put(struct snd_kcontrol
*kcontrol
,
289 struct snd_ctl_elem_value
*ucontrol
)
291 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
292 unsigned char new, old
;
294 old
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
295 new = (ucontrol
->value
.enumerated
.item
[0] << 7 & 0x80) | (old
& ~0x80);
296 change
= (new != old
);
298 stac9460_put(ice
, STAC946X_GENERAL_PURPOSE
, new);
302 * Handler for setting correct codec rate - called when rate change is detected
304 static void stac9460_set_rate_val(struct snd_ice1712
*ice
, unsigned int rate
)
306 unsigned char old
, new;
308 unsigned char changed
[7];
309 struct prodigy192_spec
*spec
= ice
->spec
;
311 if (rate
== 0) /* no hint - S/PDIF input is master, simply return */
313 else if (rate
<= 48000)
314 new = 0x08; /* 256x, base rate mode */
315 else if (rate
<= 96000)
316 new = 0x11; /* 256x, mid rate mode */
318 new = 0x12; /* 128x, high rate mode */
319 old
= stac9460_get(ice
, STAC946X_MASTER_CLOCKING
);
322 /* change detected, setting master clock, muting first */
323 /* due to possible conflicts with mute controls - mutexing */
324 mutex_lock(&spec
->mute_mutex
);
325 /* we have to remember current mute status for each DAC */
326 for (idx
= 0; idx
< 7 ; ++idx
)
327 changed
[idx
] = stac9460_dac_mute(ice
,
328 STAC946X_MASTER_VOLUME
+ idx
, 0);
329 /*dev_dbg(ice->card->dev, "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
330 stac9460_put(ice
, STAC946X_MASTER_CLOCKING
, new);
332 /* unmuting - only originally unmuted dacs -
333 * i.e. those changed when muting */
334 for (idx
= 0; idx
< 7 ; ++idx
) {
336 stac9460_dac_mute(ice
, STAC946X_MASTER_VOLUME
+ idx
, 1);
338 mutex_unlock(&spec
->mute_mutex
);
342 static const DECLARE_TLV_DB_SCALE(db_scale_dac
, -19125, 75, 0);
343 static const DECLARE_TLV_DB_SCALE(db_scale_adc
, 0, 150, 0);
349 static const struct snd_kcontrol_new stac_controls
[] = {
351 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
352 .name
= "Master Playback Switch",
353 .info
= stac9460_dac_mute_info
,
354 .get
= stac9460_dac_mute_get
,
355 .put
= stac9460_dac_mute_put
,
357 .tlv
= { .p
= db_scale_dac
}
360 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
361 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
362 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
363 .name
= "Master Playback Volume",
364 .info
= stac9460_dac_vol_info
,
365 .get
= stac9460_dac_vol_get
,
366 .put
= stac9460_dac_vol_put
,
368 .tlv
= { .p
= db_scale_dac
}
371 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
372 .name
= "DAC Switch",
374 .info
= stac9460_dac_mute_info
,
375 .get
= stac9460_dac_mute_get
,
376 .put
= stac9460_dac_mute_put
,
379 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
380 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
381 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
382 .name
= "DAC Volume",
384 .info
= stac9460_dac_vol_info
,
385 .get
= stac9460_dac_vol_get
,
386 .put
= stac9460_dac_vol_put
,
387 .tlv
= { .p
= db_scale_dac
}
390 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
391 .name
= "ADC Capture Switch",
393 .info
= stac9460_adc_mute_info
,
394 .get
= stac9460_adc_mute_get
,
395 .put
= stac9460_adc_mute_put
,
399 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
400 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
401 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
402 .name
= "ADC Capture Volume",
404 .info
= stac9460_adc_vol_info
,
405 .get
= stac9460_adc_vol_get
,
406 .put
= stac9460_adc_vol_put
,
407 .tlv
= { .p
= db_scale_adc
}
410 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
411 .name
= "Analog Capture Input",
412 .info
= stac9460_mic_sw_info
,
413 .get
= stac9460_mic_sw_get
,
414 .put
= stac9460_mic_sw_put
,
419 /* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
420 /* CDTO (pin 32) -- GPIO11 pin 86
421 * CDTI (pin 33) -- GPIO10 pin 77
422 * CCLK (pin 34) -- GPIO9 pin 76
423 * CSN (pin 35) -- GPIO8 pin 75
425 #define AK4114_ADDR 0x00 /* C1-C0: Chip Address
426 * (According to datasheet fixed to “00”)
430 * 4wire ak4114 protocol - writing data
432 static void write_data(struct snd_ice1712
*ice
, unsigned int gpio
,
433 unsigned int data
, int idx
)
435 for (; idx
>= 0; idx
--) {
437 gpio
&= ~VT1724_PRODIGY192_CCLK
;
438 snd_ice1712_gpio_write(ice
, gpio
);
441 if (data
& (1 << idx
))
442 gpio
|= VT1724_PRODIGY192_CDOUT
;
444 gpio
&= ~VT1724_PRODIGY192_CDOUT
;
445 snd_ice1712_gpio_write(ice
, gpio
);
448 gpio
|= VT1724_PRODIGY192_CCLK
;
449 snd_ice1712_gpio_write(ice
, gpio
);
455 * 4wire ak4114 protocol - reading data
457 static unsigned char read_data(struct snd_ice1712
*ice
, unsigned int gpio
,
460 unsigned char data
= 0;
462 for (; idx
>= 0; idx
--) {
464 gpio
&= ~VT1724_PRODIGY192_CCLK
;
465 snd_ice1712_gpio_write(ice
, gpio
);
468 if (snd_ice1712_gpio_read(ice
) & VT1724_PRODIGY192_CDIN
)
472 gpio
|= VT1724_PRODIGY192_CCLK
;
473 snd_ice1712_gpio_write(ice
, gpio
);
479 * 4wire ak4114 protocol - starting sequence
481 static unsigned int prodigy192_4wire_start(struct snd_ice1712
*ice
)
485 snd_ice1712_save_gpio_status(ice
);
486 tmp
= snd_ice1712_gpio_read(ice
);
488 tmp
|= VT1724_PRODIGY192_CCLK
; /* high at init */
489 tmp
&= ~VT1724_PRODIGY192_CS
; /* drop chip select */
490 snd_ice1712_gpio_write(ice
, tmp
);
496 * 4wire ak4114 protocol - final sequence
498 static void prodigy192_4wire_finish(struct snd_ice1712
*ice
, unsigned int tmp
)
500 tmp
|= VT1724_PRODIGY192_CS
; /* raise chip select */
501 snd_ice1712_gpio_write(ice
, tmp
);
503 snd_ice1712_restore_gpio_status(ice
);
507 * Write data to addr register of ak4114
509 static void prodigy192_ak4114_write(void *private_data
, unsigned char addr
,
512 struct snd_ice1712
*ice
= private_data
;
513 unsigned int tmp
, addrdata
;
514 tmp
= prodigy192_4wire_start(ice
);
515 addrdata
= (AK4114_ADDR
<< 6) | 0x20 | (addr
& 0x1f);
516 addrdata
= (addrdata
<< 8) | data
;
517 write_data(ice
, tmp
, addrdata
, 15);
518 prodigy192_4wire_finish(ice
, tmp
);
522 * Read data from addr register of ak4114
524 static unsigned char prodigy192_ak4114_read(void *private_data
,
527 struct snd_ice1712
*ice
= private_data
;
531 tmp
= prodigy192_4wire_start(ice
);
532 write_data(ice
, tmp
, (AK4114_ADDR
<< 6) | (addr
& 0x1f), 7);
533 data
= read_data(ice
, tmp
, 7);
534 prodigy192_4wire_finish(ice
, tmp
);
539 static int ak4114_input_sw_info(struct snd_kcontrol
*kcontrol
,
540 struct snd_ctl_elem_info
*uinfo
)
542 static const char * const texts
[2] = { "Toslink", "Coax" };
544 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
548 static int ak4114_input_sw_get(struct snd_kcontrol
*kcontrol
,
549 struct snd_ctl_elem_value
*ucontrol
)
551 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
554 val
= prodigy192_ak4114_read(ice
, AK4114_REG_IO1
);
555 /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
556 * AK4114_IPS0 bit = 1 -> RX1 = Coax
558 ucontrol
->value
.enumerated
.item
[0] = (val
& AK4114_IPS0
) ? 1 : 0;
562 static int ak4114_input_sw_put(struct snd_kcontrol
*kcontrol
,
563 struct snd_ctl_elem_value
*ucontrol
)
565 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
566 unsigned char new, old
, itemvalue
;
569 old
= prodigy192_ak4114_read(ice
, AK4114_REG_IO1
);
570 /* AK4114_IPS0 could be any bit */
571 itemvalue
= (ucontrol
->value
.enumerated
.item
[0]) ? 0xff : 0x00;
573 new = (itemvalue
& AK4114_IPS0
) | (old
& ~AK4114_IPS0
);
574 change
= (new != old
);
576 prodigy192_ak4114_write(ice
, AK4114_REG_IO1
, new);
581 static const struct snd_kcontrol_new ak4114_controls
[] = {
583 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
584 .name
= "MIODIO IEC958 Capture Input",
585 .info
= ak4114_input_sw_info
,
586 .get
= ak4114_input_sw_get
,
587 .put
= ak4114_input_sw_put
,
593 static int prodigy192_ak4114_init(struct snd_ice1712
*ice
)
595 static const unsigned char ak4114_init_vals
[] = {
596 AK4114_RST
| AK4114_PWN
| AK4114_OCKS0
| AK4114_OCKS1
,
597 /* ice1724 expects I2S and provides clock,
598 * DEM0 disables the deemphasis filter
600 AK4114_DIF_I24I2S
| AK4114_DEM0
,
602 AK4114_EFH_1024
| AK4114_DIT
, /* default input RX0 */
606 static const unsigned char ak4114_init_txcsb
[] = {
607 0x41, 0x02, 0x2c, 0x00, 0x00
609 struct prodigy192_spec
*spec
= ice
->spec
;
612 err
= snd_ak4114_create(ice
->card
,
613 prodigy192_ak4114_read
,
614 prodigy192_ak4114_write
,
615 ak4114_init_vals
, ak4114_init_txcsb
,
619 /* AK4114 in Prodigy192 cannot detect external rate correctly.
620 * No reason to stop capture stream due to incorrect checks */
621 spec
->ak4114
->check_flags
= AK4114_CHECK_NO_RATE
;
625 static void stac9460_proc_regs_read(struct snd_info_entry
*entry
,
626 struct snd_info_buffer
*buffer
)
628 struct snd_ice1712
*ice
= entry
->private_data
;
630 /* registers 0x0 - 0x14 */
631 for (reg
= 0; reg
<= 0x15; reg
++) {
632 val
= stac9460_get(ice
, reg
);
633 snd_iprintf(buffer
, "0x%02x = 0x%02x\n", reg
, val
);
638 static void stac9460_proc_init(struct snd_ice1712
*ice
)
640 snd_card_ro_proc_new(ice
->card
, "stac9460_codec", ice
,
641 stac9460_proc_regs_read
);
645 static int prodigy192_add_controls(struct snd_ice1712
*ice
)
647 struct prodigy192_spec
*spec
= ice
->spec
;
651 for (i
= 0; i
< ARRAY_SIZE(stac_controls
); i
++) {
652 err
= snd_ctl_add(ice
->card
,
653 snd_ctl_new1(&stac_controls
[i
], ice
));
658 /* ak4114 is connected */
659 for (i
= 0; i
< ARRAY_SIZE(ak4114_controls
); i
++) {
660 err
= snd_ctl_add(ice
->card
,
661 snd_ctl_new1(&ak4114_controls
[i
],
666 err
= snd_ak4114_build(spec
->ak4114
,
667 NULL
, /* ak4114 in MIO/DI/O handles no IEC958 output */
668 ice
->pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
);
672 stac9460_proc_init(ice
);
677 * check for presence of MI/ODI/O add-on card with digital inputs
679 static int prodigy192_miodio_exists(struct snd_ice1712
*ice
)
682 unsigned char orig_value
;
683 const unsigned char test_data
= 0xd1; /* random value */
684 unsigned char addr
= AK4114_REG_INT0_MASK
; /* random SAFE address */
687 orig_value
= prodigy192_ak4114_read(ice
, addr
);
688 prodigy192_ak4114_write(ice
, addr
, test_data
);
689 if (prodigy192_ak4114_read(ice
, addr
) == test_data
) {
690 /* ak4114 seems to communicate, apparently exists */
691 /* writing back original value */
692 prodigy192_ak4114_write(ice
, addr
, orig_value
);
699 * initialize the chip
701 static int prodigy192_init(struct snd_ice1712
*ice
)
703 static const unsigned short stac_inits_prodigy
[] = {
705 STAC946X_MASTER_CLOCKING
, 0x11,
706 /* STAC946X_MASTER_VOLUME, 0,
707 STAC946X_LF_VOLUME, 0,
708 STAC946X_RF_VOLUME, 0,
709 STAC946X_LR_VOLUME, 0,
710 STAC946X_RR_VOLUME, 0,
711 STAC946X_CENTER_VOLUME, 0,
712 STAC946X_LFE_VOLUME, 0,*/
715 const unsigned short *p
;
717 struct prodigy192_spec
*spec
;
720 ice
->num_total_dacs
= 6;
721 ice
->num_total_adcs
= 2;
722 ice
->vt1720
= 0; /* ice1724, e.g. 23 GPIOs */
724 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
728 mutex_init(&spec
->mute_mutex
);
730 /* initialize codec */
731 p
= stac_inits_prodigy
;
732 for (; *p
!= (unsigned short)-1; p
+= 2)
733 stac9460_put(ice
, p
[0], p
[1]);
734 ice
->gpio
.set_pro_rate
= stac9460_set_rate_val
;
736 /* MI/ODI/O add on card with AK4114 */
737 if (prodigy192_miodio_exists(ice
)) {
738 err
= prodigy192_ak4114_init(ice
);
739 /* from this moment if err = 0 then
740 * spec->ak4114 should not be null
742 dev_dbg(ice
->card
->dev
,
743 "AK4114 initialized with status %d\n", err
);
745 dev_dbg(ice
->card
->dev
, "AK4114 not found\n");
752 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
753 * hence the driver needs to sets up it properly.
756 static const unsigned char prodigy71_eeprom
[] = {
757 [ICE_EEP2_SYSCONF
] = 0x6a, /* 49MHz crystal, mpu401,
758 * spdif-in+ 1 stereo ADC,
761 [ICE_EEP2_ACLINK
] = 0x80, /* I2S */
762 [ICE_EEP2_I2S
] = 0xf8, /* vol, 96k, 24bit, 192k */
763 [ICE_EEP2_SPDIF
] = 0xc3, /* out-en, out-int, spdif-in */
764 [ICE_EEP2_GPIO_DIR
] = 0xff,
765 [ICE_EEP2_GPIO_DIR1
] = ~(VT1724_PRODIGY192_CDIN
>> 8) ,
766 [ICE_EEP2_GPIO_DIR2
] = 0xbf,
767 [ICE_EEP2_GPIO_MASK
] = 0x00,
768 [ICE_EEP2_GPIO_MASK1
] = 0x00,
769 [ICE_EEP2_GPIO_MASK2
] = 0x00,
770 [ICE_EEP2_GPIO_STATE
] = 0x00,
771 [ICE_EEP2_GPIO_STATE1
] = 0x00,
772 [ICE_EEP2_GPIO_STATE2
] = 0x10, /* GPIO20: 0 = CD drive dig. input
774 * 1 = SPDIF-OUT from ice1724
780 struct snd_ice1712_card_info snd_vt1724_prodigy192_cards
[] = {
782 .subvendor
= VT1724_SUBDEVICE_PRODIGY192VE
,
783 .name
= "Audiotrak Prodigy 192",
784 .model
= "prodigy192",
785 .chip_init
= prodigy192_init
,
786 .build_controls
= prodigy192_add_controls
,
787 .eeprom_size
= sizeof(prodigy71_eeprom
),
788 .eeprom_data
= prodigy71_eeprom
,