2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 * Lowlevel functions for AudioTrak Prodigy 192 cards
5 * Supported IEC958 input from optional MI/ODI/O add-on card.
10 * * SPDIF-OUT on the card:
11 * - coax (through isolation transformer)/toslink supplied by
12 * 74HC04 gates - 3 in parallel
13 * - output switched between on-board CD drive dig-out connector
14 * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
15 * by GPIO20 (0 = CD dig-out, 1 = SPDTX)
16 * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
18 * * MI/ODI/O card: AK4114 based, used for iec958 input only
19 * - toslink input -> RX0
23 * ------------------------------
24 * CDTO (pin 32) -- GPIO11 pin 86
25 * CDTI (pin 33) -- GPIO10 pin 77
26 * CCLK (pin 34) -- GPIO9 pin 76
27 * CSN (pin 35) -- GPIO8 pin 75
28 * - output data Mode 7 (24bit, I2S, slave)
29 * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
30 * outputs master clock to SPMCLKIN of ice1724.
31 * Experimentally I found out that only a combination of
32 * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
33 * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
34 * sampling rate. That means the the FPGA doubles the
37 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
38 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
39 * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
41 * This program is free software; you can redistribute it and/or modify
42 * it under the terms of the GNU General Public License as published by
43 * the Free Software Foundation; either version 2 of the License, or
44 * (at your option) any later version.
46 * This program is distributed in the hope that it will be useful,
47 * but WITHOUT ANY WARRANTY; without even the implied warranty of
48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 * GNU General Public License for more details.
51 * You should have received a copy of the GNU General Public License
52 * along with this program; if not, write to the Free Software
53 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58 #include <linux/delay.h>
59 #include <linux/interrupt.h>
60 #include <linux/init.h>
61 #include <linux/slab.h>
62 #include <sound/core.h>
66 #include "prodigy192.h"
68 #include <sound/tlv.h>
70 struct prodigy192_spec
{
71 struct ak4114
*ak4114
;
72 /* rate change needs atomic mute/unmute of all dacs*/
73 struct mutex mute_mutex
;
76 static inline void stac9460_put(struct snd_ice1712
*ice
, int reg
, unsigned char val
)
78 snd_vt1724_write_i2c(ice
, PRODIGY192_STAC9460_ADDR
, reg
, val
);
81 static inline unsigned char stac9460_get(struct snd_ice1712
*ice
, int reg
)
83 return snd_vt1724_read_i2c(ice
, PRODIGY192_STAC9460_ADDR
, reg
);
91 * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
93 static int stac9460_dac_mute(struct snd_ice1712
*ice
, int idx
,
96 unsigned char new, old
;
98 old
= stac9460_get(ice
, idx
);
99 new = (~mute
<< 7 & 0x80) | (old
& ~0x80);
100 change
= (new != old
);
102 /*printk ("Volume register 0x%02x: 0x%02x\n", idx, new);*/
103 stac9460_put(ice
, idx
, new);
107 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
109 static int stac9460_dac_mute_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
111 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
115 if (kcontrol
->private_value
)
116 idx
= STAC946X_MASTER_VOLUME
;
118 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
119 val
= stac9460_get(ice
, idx
);
120 ucontrol
->value
.integer
.value
[0] = (~val
>> 7) & 0x1;
124 static int stac9460_dac_mute_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
126 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
127 struct prodigy192_spec
*spec
= ice
->spec
;
130 if (kcontrol
->private_value
)
131 idx
= STAC946X_MASTER_VOLUME
;
133 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
134 /* due to possible conflicts with stac9460_set_rate_val, mutexing */
135 mutex_lock(&spec
->mute_mutex
);
136 /*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
137 ucontrol->value.integer.value[0]);*/
138 change
= stac9460_dac_mute(ice
, idx
, ucontrol
->value
.integer
.value
[0]);
139 mutex_unlock(&spec
->mute_mutex
);
144 * DAC volume attenuation mixer control
146 static int stac9460_dac_vol_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
148 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
150 uinfo
->value
.integer
.min
= 0; /* mute */
151 uinfo
->value
.integer
.max
= 0x7f; /* 0dB */
155 static int stac9460_dac_vol_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
157 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
161 if (kcontrol
->private_value
)
162 idx
= STAC946X_MASTER_VOLUME
;
164 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
165 vol
= stac9460_get(ice
, idx
) & 0x7f;
166 ucontrol
->value
.integer
.value
[0] = 0x7f - vol
;
171 static int stac9460_dac_vol_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
173 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
175 unsigned char tmp
, ovol
, nvol
;
178 if (kcontrol
->private_value
)
179 idx
= STAC946X_MASTER_VOLUME
;
181 idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + STAC946X_LF_VOLUME
;
182 nvol
= ucontrol
->value
.integer
.value
[0];
183 tmp
= stac9460_get(ice
, idx
);
184 ovol
= 0x7f - (tmp
& 0x7f);
185 change
= (ovol
!= nvol
);
187 ovol
= (0x7f - nvol
) | (tmp
& 0x80);
188 /*printk("DAC Volume: reg 0x%02x: 0x%02x\n", idx, ovol);*/
189 stac9460_put(ice
, idx
, (0x7f - nvol
) | (tmp
& 0x80));
197 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
199 static int stac9460_adc_mute_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
201 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
205 for (i
= 0; i
< 2; ++i
) {
206 val
= stac9460_get(ice
, STAC946X_MIC_L_VOLUME
+ i
);
207 ucontrol
->value
.integer
.value
[i
] = ~val
>>7 & 0x1;
213 static int stac9460_adc_mute_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
215 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
216 unsigned char new, old
;
220 for (i
= 0; i
< 2; ++i
) {
221 reg
= STAC946X_MIC_L_VOLUME
+ i
;
222 old
= stac9460_get(ice
, reg
);
223 new = (~ucontrol
->value
.integer
.value
[i
]<<7&0x80) | (old
&~0x80);
224 change
= (new != old
);
226 stac9460_put(ice
, reg
, new);
233 * ADC gain mixer control
235 static int stac9460_adc_vol_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
237 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
239 uinfo
->value
.integer
.min
= 0; /* 0dB */
240 uinfo
->value
.integer
.max
= 0x0f; /* 22.5dB */
244 static int stac9460_adc_vol_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
246 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
250 for (i
= 0; i
< 2; ++i
) {
251 reg
= STAC946X_MIC_L_VOLUME
+ i
;
252 vol
= stac9460_get(ice
, reg
) & 0x0f;
253 ucontrol
->value
.integer
.value
[i
] = 0x0f - vol
;
259 static int stac9460_adc_vol_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
261 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
263 unsigned char ovol
, nvol
;
266 for (i
= 0; i
< 2; ++i
) {
267 reg
= STAC946X_MIC_L_VOLUME
+ i
;
268 nvol
= ucontrol
->value
.integer
.value
[i
] & 0x0f;
269 ovol
= 0x0f - stac9460_get(ice
, reg
);
270 change
= ((ovol
& 0x0f) != nvol
);
272 stac9460_put(ice
, reg
, (0x0f - nvol
) | (ovol
& ~0x0f));
278 static int stac9460_mic_sw_info(struct snd_kcontrol
*kcontrol
,
279 struct snd_ctl_elem_info
*uinfo
)
281 static char *texts
[2] = { "Line In", "Mic" };
283 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
285 uinfo
->value
.enumerated
.items
= 2;
287 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
288 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
289 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
295 static int stac9460_mic_sw_get(struct snd_kcontrol
*kcontrol
,
296 struct snd_ctl_elem_value
*ucontrol
)
298 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
301 val
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
302 ucontrol
->value
.enumerated
.item
[0] = (val
>> 7) & 0x1;
306 static int stac9460_mic_sw_put(struct snd_kcontrol
*kcontrol
,
307 struct snd_ctl_elem_value
*ucontrol
)
309 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
310 unsigned char new, old
;
312 old
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
313 new = (ucontrol
->value
.enumerated
.item
[0] << 7 & 0x80) | (old
& ~0x80);
314 change
= (new != old
);
316 stac9460_put(ice
, STAC946X_GENERAL_PURPOSE
, new);
320 * Handler for setting correct codec rate - called when rate change is detected
322 static void stac9460_set_rate_val(struct snd_akm4xxx
*ak
, unsigned int rate
)
324 unsigned char old
, new;
326 unsigned char changed
[7];
327 struct snd_ice1712
*ice
= ak
->private_data
[0];
328 struct prodigy192_spec
*spec
= ice
->spec
;
330 if (rate
== 0) /* no hint - S/PDIF input is master, simply return */
332 else if (rate
<= 48000)
333 new = 0x08; /* 256x, base rate mode */
334 else if (rate
<= 96000)
335 new = 0x11; /* 256x, mid rate mode */
337 new = 0x12; /* 128x, high rate mode */
338 old
= stac9460_get(ice
, STAC946X_MASTER_CLOCKING
);
341 /* change detected, setting master clock, muting first */
342 /* due to possible conflicts with mute controls - mutexing */
343 mutex_lock(&spec
->mute_mutex
);
344 /* we have to remember current mute status for each DAC */
345 for (idx
= 0; idx
< 7 ; ++idx
)
346 changed
[idx
] = stac9460_dac_mute(ice
,
347 STAC946X_MASTER_VOLUME
+ idx
, 0);
348 /*printk("Rate change: %d, new MC: 0x%02x\n", rate, new);*/
349 stac9460_put(ice
, STAC946X_MASTER_CLOCKING
, new);
351 /* unmuting - only originally unmuted dacs -
352 * i.e. those changed when muting */
353 for (idx
= 0; idx
< 7 ; ++idx
) {
355 stac9460_dac_mute(ice
, STAC946X_MASTER_VOLUME
+ idx
, 1);
357 mutex_unlock(&spec
->mute_mutex
);
360 /* using akm infrastructure for setting rate of the codec */
361 static struct snd_akm4xxx akmlike_stac9460 __devinitdata
= {
362 .type
= NON_AKM
, /* special value */
363 .num_adcs
= 6, /* not used in any way, just for completeness */
366 .set_rate_val
= stac9460_set_rate_val
371 static const DECLARE_TLV_DB_SCALE(db_scale_dac
, -19125, 75, 0);
372 static const DECLARE_TLV_DB_SCALE(db_scale_adc
, 0, 150, 0);
378 static struct snd_kcontrol_new stac_controls
[] __devinitdata
= {
380 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
381 .name
= "Master Playback Switch",
382 .info
= stac9460_dac_mute_info
,
383 .get
= stac9460_dac_mute_get
,
384 .put
= stac9460_dac_mute_put
,
386 .tlv
= { .p
= db_scale_dac
}
389 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
390 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
391 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
392 .name
= "Master Playback Volume",
393 .info
= stac9460_dac_vol_info
,
394 .get
= stac9460_dac_vol_get
,
395 .put
= stac9460_dac_vol_put
,
397 .tlv
= { .p
= db_scale_dac
}
400 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
401 .name
= "DAC Switch",
403 .info
= stac9460_dac_mute_info
,
404 .get
= stac9460_dac_mute_get
,
405 .put
= stac9460_dac_mute_put
,
408 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
409 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
410 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
411 .name
= "DAC Volume",
413 .info
= stac9460_dac_vol_info
,
414 .get
= stac9460_dac_vol_get
,
415 .put
= stac9460_dac_vol_put
,
416 .tlv
= { .p
= db_scale_dac
}
419 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
420 .name
= "ADC Capture Switch",
422 .info
= stac9460_adc_mute_info
,
423 .get
= stac9460_adc_mute_get
,
424 .put
= stac9460_adc_mute_put
,
428 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
429 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
430 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
431 .name
= "ADC Capture Volume",
433 .info
= stac9460_adc_vol_info
,
434 .get
= stac9460_adc_vol_get
,
435 .put
= stac9460_adc_vol_put
,
436 .tlv
= { .p
= db_scale_adc
}
439 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
440 .name
= "Analog Capture Input",
441 .info
= stac9460_mic_sw_info
,
442 .get
= stac9460_mic_sw_get
,
443 .put
= stac9460_mic_sw_put
,
448 /* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
449 /* CDTO (pin 32) -- GPIO11 pin 86
450 * CDTI (pin 33) -- GPIO10 pin 77
451 * CCLK (pin 34) -- GPIO9 pin 76
452 * CSN (pin 35) -- GPIO8 pin 75
454 #define AK4114_ADDR 0x00 /* C1-C0: Chip Address
455 * (According to datasheet fixed to “00”)
459 * 4wire ak4114 protocol - writing data
461 static void write_data(struct snd_ice1712
*ice
, unsigned int gpio
,
462 unsigned int data
, int idx
)
464 for (; idx
>= 0; idx
--) {
466 gpio
&= ~VT1724_PRODIGY192_CCLK
;
467 snd_ice1712_gpio_write(ice
, gpio
);
470 if (data
& (1 << idx
))
471 gpio
|= VT1724_PRODIGY192_CDOUT
;
473 gpio
&= ~VT1724_PRODIGY192_CDOUT
;
474 snd_ice1712_gpio_write(ice
, gpio
);
477 gpio
|= VT1724_PRODIGY192_CCLK
;
478 snd_ice1712_gpio_write(ice
, gpio
);
484 * 4wire ak4114 protocol - reading data
486 static unsigned char read_data(struct snd_ice1712
*ice
, unsigned int gpio
,
489 unsigned char data
= 0;
491 for (; idx
>= 0; idx
--) {
493 gpio
&= ~VT1724_PRODIGY192_CCLK
;
494 snd_ice1712_gpio_write(ice
, gpio
);
497 if (snd_ice1712_gpio_read(ice
) & VT1724_PRODIGY192_CDIN
)
501 gpio
|= VT1724_PRODIGY192_CCLK
;
502 snd_ice1712_gpio_write(ice
, gpio
);
508 * 4wire ak4114 protocol - starting sequence
510 static unsigned int prodigy192_4wire_start(struct snd_ice1712
*ice
)
514 snd_ice1712_save_gpio_status(ice
);
515 tmp
= snd_ice1712_gpio_read(ice
);
517 tmp
|= VT1724_PRODIGY192_CCLK
; /* high at init */
518 tmp
&= ~VT1724_PRODIGY192_CS
; /* drop chip select */
519 snd_ice1712_gpio_write(ice
, tmp
);
525 * 4wire ak4114 protocol - final sequence
527 static void prodigy192_4wire_finish(struct snd_ice1712
*ice
, unsigned int tmp
)
529 tmp
|= VT1724_PRODIGY192_CS
; /* raise chip select */
530 snd_ice1712_gpio_write(ice
, tmp
);
532 snd_ice1712_restore_gpio_status(ice
);
536 * Write data to addr register of ak4114
538 static void prodigy192_ak4114_write(void *private_data
, unsigned char addr
,
541 struct snd_ice1712
*ice
= private_data
;
542 unsigned int tmp
, addrdata
;
543 tmp
= prodigy192_4wire_start(ice
);
544 addrdata
= (AK4114_ADDR
<< 6) | 0x20 | (addr
& 0x1f);
545 addrdata
= (addrdata
<< 8) | data
;
546 write_data(ice
, tmp
, addrdata
, 15);
547 prodigy192_4wire_finish(ice
, tmp
);
551 * Read data from addr register of ak4114
553 static unsigned char prodigy192_ak4114_read(void *private_data
,
556 struct snd_ice1712
*ice
= private_data
;
560 tmp
= prodigy192_4wire_start(ice
);
561 write_data(ice
, tmp
, (AK4114_ADDR
<< 6) | (addr
& 0x1f), 7);
562 data
= read_data(ice
, tmp
, 7);
563 prodigy192_4wire_finish(ice
, tmp
);
568 static int ak4114_input_sw_info(struct snd_kcontrol
*kcontrol
,
569 struct snd_ctl_elem_info
*uinfo
)
571 static char *texts
[2] = { "Toslink", "Coax" };
573 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
575 uinfo
->value
.enumerated
.items
= 2;
576 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
577 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
578 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
583 static int ak4114_input_sw_get(struct snd_kcontrol
*kcontrol
,
584 struct snd_ctl_elem_value
*ucontrol
)
586 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
589 val
= prodigy192_ak4114_read(ice
, AK4114_REG_IO1
);
590 /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
591 * AK4114_IPS0 bit = 1 -> RX1 = Coax
593 ucontrol
->value
.enumerated
.item
[0] = (val
& AK4114_IPS0
) ? 1 : 0;
597 static int ak4114_input_sw_put(struct snd_kcontrol
*kcontrol
,
598 struct snd_ctl_elem_value
*ucontrol
)
600 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
601 unsigned char new, old
, itemvalue
;
604 old
= prodigy192_ak4114_read(ice
, AK4114_REG_IO1
);
605 /* AK4114_IPS0 could be any bit */
606 itemvalue
= (ucontrol
->value
.enumerated
.item
[0]) ? 0xff : 0x00;
608 new = (itemvalue
& AK4114_IPS0
) | (old
& ~AK4114_IPS0
);
609 change
= (new != old
);
611 prodigy192_ak4114_write(ice
, AK4114_REG_IO1
, new);
616 static struct snd_kcontrol_new ak4114_controls
[] __devinitdata
= {
618 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
619 .name
= "MIODIO IEC958 Capture Input",
620 .info
= ak4114_input_sw_info
,
621 .get
= ak4114_input_sw_get
,
622 .put
= ak4114_input_sw_put
,
628 static int prodigy192_ak4114_init(struct snd_ice1712
*ice
)
630 static const unsigned char ak4114_init_vals
[] = {
631 AK4114_RST
| AK4114_PWN
| AK4114_OCKS0
| AK4114_OCKS1
,
632 /* ice1724 expects I2S and provides clock,
633 * DEM0 disables the deemphasis filter
635 AK4114_DIF_I24I2S
| AK4114_DEM0
,
637 AK4114_EFH_1024
| AK4114_DIT
, /* default input RX0 */
641 static const unsigned char ak4114_init_txcsb
[] = {
642 0x41, 0x02, 0x2c, 0x00, 0x00
644 struct prodigy192_spec
*spec
= ice
->spec
;
646 return snd_ak4114_create(ice
->card
,
647 prodigy192_ak4114_read
,
648 prodigy192_ak4114_write
,
649 ak4114_init_vals
, ak4114_init_txcsb
,
653 static void stac9460_proc_regs_read(struct snd_info_entry
*entry
,
654 struct snd_info_buffer
*buffer
)
656 struct snd_ice1712
*ice
= (struct snd_ice1712
*)entry
->private_data
;
658 /* registers 0x0 - 0x14 */
659 for (reg
= 0; reg
<= 0x15; reg
++) {
660 val
= stac9460_get(ice
, reg
);
661 snd_iprintf(buffer
, "0x%02x = 0x%02x\n", reg
, val
);
666 static void stac9460_proc_init(struct snd_ice1712
*ice
)
668 struct snd_info_entry
*entry
;
669 if (!snd_card_proc_new(ice
->card
, "stac9460_codec", &entry
))
670 snd_info_set_text_ops(entry
, ice
, stac9460_proc_regs_read
);
674 static int __devinit
prodigy192_add_controls(struct snd_ice1712
*ice
)
676 struct prodigy192_spec
*spec
= ice
->spec
;
680 for (i
= 0; i
< ARRAY_SIZE(stac_controls
); i
++) {
681 err
= snd_ctl_add(ice
->card
,
682 snd_ctl_new1(&stac_controls
[i
], ice
));
687 /* ak4114 is connected */
688 for (i
= 0; i
< ARRAY_SIZE(ak4114_controls
); i
++) {
689 err
= snd_ctl_add(ice
->card
,
690 snd_ctl_new1(&ak4114_controls
[i
],
695 err
= snd_ak4114_build(spec
->ak4114
,
696 NULL
, /* ak4114 in MIO/DI/O handles no IEC958 output */
697 ice
->pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
);
701 stac9460_proc_init(ice
);
706 * check for presence of MI/ODI/O add-on card with digital inputs
708 static int prodigy192_miodio_exists(struct snd_ice1712
*ice
)
711 unsigned char orig_value
;
712 const unsigned char test_data
= 0xd1; /* random value */
713 unsigned char addr
= AK4114_REG_INT0_MASK
; /* random SAFE address */
716 orig_value
= prodigy192_ak4114_read(ice
, addr
);
717 prodigy192_ak4114_write(ice
, addr
, test_data
);
718 if (prodigy192_ak4114_read(ice
, addr
) == test_data
) {
719 /* ak4114 seems to communicate, apparently exists */
720 /* writing back original value */
721 prodigy192_ak4114_write(ice
, addr
, orig_value
);
728 * initialize the chip
730 static int __devinit
prodigy192_init(struct snd_ice1712
*ice
)
732 static const unsigned short stac_inits_prodigy
[] = {
734 STAC946X_MASTER_CLOCKING
, 0x11,
735 /* STAC946X_MASTER_VOLUME, 0,
736 STAC946X_LF_VOLUME, 0,
737 STAC946X_RF_VOLUME, 0,
738 STAC946X_LR_VOLUME, 0,
739 STAC946X_RR_VOLUME, 0,
740 STAC946X_CENTER_VOLUME, 0,
741 STAC946X_LFE_VOLUME, 0,*/
744 const unsigned short *p
;
746 struct snd_akm4xxx
*ak
;
747 struct prodigy192_spec
*spec
;
750 ice
->num_total_dacs
= 6;
751 ice
->num_total_adcs
= 2;
752 ice
->vt1720
= 0; /* ice1724, e.g. 23 GPIOs */
754 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
758 mutex_init(&spec
->mute_mutex
);
760 /* initialize codec */
761 p
= stac_inits_prodigy
;
762 for (; *p
!= (unsigned short)-1; p
+= 2)
763 stac9460_put(ice
, p
[0], p
[1]);
764 /* reusing the akm codecs infrastructure,
765 * for setting rate on stac9460 */
766 ak
= ice
->akm
= kmalloc(sizeof(struct snd_akm4xxx
), GFP_KERNEL
);
770 err
= snd_ice1712_akm4xxx_init(ak
, &akmlike_stac9460
, NULL
, ice
);
774 /* MI/ODI/O add on card with AK4114 */
775 if (prodigy192_miodio_exists(ice
)) {
776 err
= prodigy192_ak4114_init(ice
);
777 /* from this moment if err = 0 then
778 * spec->ak4114 should not be null
780 snd_printdd("AK4114 initialized with status %d\n", err
);
782 snd_printdd("AK4114 not found\n");
791 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
792 * hence the driver needs to sets up it properly.
795 static unsigned char prodigy71_eeprom
[] __devinitdata
= {
796 [ICE_EEP2_SYSCONF
] = 0x6a, /* 49MHz crystal, mpu401,
797 * spdif-in+ 1 stereo ADC,
800 [ICE_EEP2_ACLINK
] = 0x80, /* I2S */
801 [ICE_EEP2_I2S
] = 0xf8, /* vol, 96k, 24bit, 192k */
802 [ICE_EEP2_SPDIF
] = 0xc3, /* out-en, out-int, spdif-in */
803 [ICE_EEP2_GPIO_DIR
] = 0xff,
804 [ICE_EEP2_GPIO_DIR1
] = ~(VT1724_PRODIGY192_CDIN
>> 8) ,
805 [ICE_EEP2_GPIO_DIR2
] = 0xbf,
806 [ICE_EEP2_GPIO_MASK
] = 0x00,
807 [ICE_EEP2_GPIO_MASK1
] = 0x00,
808 [ICE_EEP2_GPIO_MASK2
] = 0x00,
809 [ICE_EEP2_GPIO_STATE
] = 0x00,
810 [ICE_EEP2_GPIO_STATE1
] = 0x00,
811 [ICE_EEP2_GPIO_STATE2
] = 0x10, /* GPIO20: 0 = CD drive dig. input
813 * 1 = SPDIF-OUT from ice1724
819 struct snd_ice1712_card_info snd_vt1724_prodigy192_cards
[] __devinitdata
= {
821 .subvendor
= VT1724_SUBDEVICE_PRODIGY192VE
,
822 .name
= "Audiotrak Prodigy 192",
823 .model
= "prodigy192",
824 .chip_init
= prodigy192_init
,
825 .build_controls
= prodigy192_add_controls
,
826 .eeprom_size
= sizeof(prodigy71_eeprom
),
827 .eeprom_data
= prodigy71_eeprom
,
828 /* the current MPU401 code loops infinitely
829 * when opening midi device