xref: /linux/sound/pci/ice1712/prodigy192.c (revision d4b996f9ef1fe83d9ce9ad5c1ca0bd8231638ce5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
4  *
5  *   Lowlevel functions for AudioTrak Prodigy 192 cards
6  *   Supported IEC958 input from optional MI/ODI/O add-on card.
7  *
8  *   Specifics (SW, HW):
9  *   -------------------
10  *   	* 49.5MHz crystal
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
18  *
19  *   	* MI/ODI/O card: AK4114 based, used for iec958 input only
20  *   		- toslink input -> RX0
21  *   		- coax input -> RX1
22  *   		- 4wire protocol:
23  *   			AK4114		ICE1724
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
36  *		  MCK01 rate.
37  *
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>
41  */
42 
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>
48 
49 #include "ice1712.h"
50 #include "envy24ht.h"
51 #include "prodigy192.h"
52 #include "stac946x.h"
53 #include <sound/tlv.h>
54 
55 struct prodigy192_spec {
56 	struct ak4114 *ak4114;
57 	/* rate change needs atomic mute/unmute of all dacs*/
58 	struct mutex mute_mutex;
59 };
60 
61 static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
62 {
63 	snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
64 }
65 
66 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
67 {
68 	return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
69 }
70 
71 /*
72  * DAC mute control
73  */
74 
75 /*
76  * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
77  */
78 static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,
79 		unsigned char mute)
80 {
81 	unsigned char new, old;
82 	int change;
83 	old = stac9460_get(ice, idx);
84 	new = (~mute << 7 & 0x80) | (old & ~0x80);
85 	change = (new != old);
86 	if (change)
87 		/* dev_dbg(ice->card->dev, "Volume register 0x%02x: 0x%02x\n", idx, new);*/
88 		stac9460_put(ice, idx, new);
89 	return change;
90 }
91 
92 #define stac9460_dac_mute_info		snd_ctl_boolean_mono_info
93 
94 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
95 {
96 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
97 	unsigned char val;
98 	int idx;
99 
100 	if (kcontrol->private_value)
101 		idx = STAC946X_MASTER_VOLUME;
102 	else
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;
106 	return 0;
107 }
108 
109 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
110 {
111 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
112 	struct prodigy192_spec *spec = ice->spec;
113 	int idx, change;
114 
115 	if (kcontrol->private_value)
116 		idx = STAC946X_MASTER_VOLUME;
117 	else
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);
121 	/*
122 	dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
123 	       ucontrol->value.integer.value[0]);
124 	*/
125 	change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
126 	mutex_unlock(&spec->mute_mutex);
127 	return change;
128 }
129 
130 /*
131  * DAC volume attenuation mixer control
132  */
133 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
134 {
135 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
136 	uinfo->count = 1;
137 	uinfo->value.integer.min = 0;			/* mute */
138 	uinfo->value.integer.max = 0x7f;		/* 0dB */
139 	return 0;
140 }
141 
142 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
143 {
144 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
145 	int idx;
146 	unsigned char vol;
147 
148 	if (kcontrol->private_value)
149 		idx = STAC946X_MASTER_VOLUME;
150 	else
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;
154 
155 	return 0;
156 }
157 
158 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
159 {
160 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
161 	int idx;
162 	unsigned char tmp, ovol, nvol;
163 	int change;
164 
165 	if (kcontrol->private_value)
166 		idx = STAC946X_MASTER_VOLUME;
167 	else
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);
173 	if (change) {
174 		ovol =  (0x7f - nvol) | (tmp & 0x80);
175 		/*
176 		dev_dbg(ice->card->dev, "DAC Volume: reg 0x%02x: 0x%02x\n",
177 		       idx, ovol);
178 		*/
179 		stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
180 	}
181 	return change;
182 }
183 
184 /*
185  * ADC mute control
186  */
187 #define stac9460_adc_mute_info		snd_ctl_boolean_stereo_info
188 
189 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
190 {
191 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
192 	unsigned char val;
193 	int i;
194 
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;
198 	}
199 
200 	return 0;
201 }
202 
203 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
204 {
205 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
206 	unsigned char new, old;
207 	int i, reg;
208 	int change;
209 
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);
215 		if (change)
216 			stac9460_put(ice, reg, new);
217 	}
218 
219 	return change;
220 }
221 
222 /*
223  * ADC gain mixer control
224  */
225 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
226 {
227 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
228 	uinfo->count = 2;
229 	uinfo->value.integer.min = 0;		/* 0dB */
230 	uinfo->value.integer.max = 0x0f;	/* 22.5dB */
231 	return 0;
232 }
233 
234 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
235 {
236 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
237 	int i, reg;
238 	unsigned char vol;
239 
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;
244 	}
245 
246 	return 0;
247 }
248 
249 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
250 {
251 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
252 	int i, reg;
253 	unsigned char ovol, nvol;
254 	int change;
255 
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);
261 		if (change)
262 			stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
263 	}
264 
265 	return change;
266 }
267 
268 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
269 	       			struct snd_ctl_elem_info *uinfo)
270 {
271 	static const char * const texts[2] = { "Line In", "Mic" };
272 
273 	return snd_ctl_enum_info(uinfo, 1, 2, texts);
274 }
275 
276 
277 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
278 	       		struct snd_ctl_elem_value *ucontrol)
279 {
280 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
281 	unsigned char val;
282 
283 	val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
284 	ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
285 	return 0;
286 }
287 
288 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
289 	       		struct snd_ctl_elem_value *ucontrol)
290 {
291 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
292 	unsigned char new, old;
293 	int change;
294 	old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
295 	new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
296 	change = (new != old);
297 	if (change)
298 		stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
299 	return change;
300 }
301 /*
302  * Handler for setting correct codec rate - called when rate change is detected
303  */
304 static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
305 {
306 	unsigned char old, new;
307 	int idx;
308 	unsigned char changed[7];
309 	struct prodigy192_spec *spec = ice->spec;
310 
311 	if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
312 		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 */
317 	else
318 		new = 0x12;	/* 128x, high rate mode */
319 	old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
320 	if (old == new)
321 		return;
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);
331 	udelay(10);
332 	/* unmuting - only originally unmuted dacs -
333 	 * i.e. those changed when muting */
334 	for (idx = 0; idx < 7 ; ++idx) {
335 		if (changed[idx])
336 			stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
337 	}
338 	mutex_unlock(&spec->mute_mutex);
339 }
340 
341 
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);
344 
345 /*
346  * mixers
347  */
348 
349 static const struct snd_kcontrol_new stac_controls[] = {
350 	{
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,
356 		.private_value = 1,
357 		.tlv = { .p = db_scale_dac }
358 	},
359 	{
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,
367 		.private_value = 1,
368 		.tlv = { .p = db_scale_dac }
369 	},
370 	{
371 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
372 		.name = "DAC Switch",
373 		.count = 6,
374 		.info = stac9460_dac_mute_info,
375 		.get = stac9460_dac_mute_get,
376 		.put = stac9460_dac_mute_put,
377 	},
378 	{
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",
383 		.count = 6,
384 		.info = stac9460_dac_vol_info,
385 		.get = stac9460_dac_vol_get,
386 		.put = stac9460_dac_vol_put,
387 		.tlv = { .p = db_scale_dac }
388 	},
389 	{
390 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
391 		.name = "ADC Capture Switch",
392 		.count = 1,
393 		.info = stac9460_adc_mute_info,
394 		.get = stac9460_adc_mute_get,
395 		.put = stac9460_adc_mute_put,
396 
397 	},
398 	{
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",
403 		.count = 1,
404 		.info = stac9460_adc_vol_info,
405 		.get = stac9460_adc_vol_get,
406 		.put = stac9460_adc_vol_put,
407 		.tlv = { .p = db_scale_adc }
408 	},
409 	{
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,
415 
416 	},
417 };
418 
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
424  */
425 #define AK4114_ADDR	0x00 /* C1-C0: Chip Address
426 			      * (According to datasheet fixed to “00”)
427 			      */
428 
429 /*
430  * 4wire ak4114 protocol - writing data
431  */
432 static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
433 		       unsigned int data, int idx)
434 {
435 	for (; idx >= 0; idx--) {
436 		/* drop clock */
437 		gpio &= ~VT1724_PRODIGY192_CCLK;
438 		snd_ice1712_gpio_write(ice, gpio);
439 		udelay(1);
440 		/* set data */
441 		if (data & (1 << idx))
442 			gpio |= VT1724_PRODIGY192_CDOUT;
443 		else
444 			gpio &= ~VT1724_PRODIGY192_CDOUT;
445 		snd_ice1712_gpio_write(ice, gpio);
446 		udelay(1);
447 		/* raise clock */
448 		gpio |= VT1724_PRODIGY192_CCLK;
449 		snd_ice1712_gpio_write(ice, gpio);
450 		udelay(1);
451 	}
452 }
453 
454 /*
455  * 4wire ak4114 protocol - reading data
456  */
457 static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
458 			       int idx)
459 {
460 	unsigned char data = 0;
461 
462 	for (; idx >= 0; idx--) {
463 		/* drop clock */
464 		gpio &= ~VT1724_PRODIGY192_CCLK;
465 		snd_ice1712_gpio_write(ice, gpio);
466 		udelay(1);
467 		/* read data */
468 		if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN)
469 			data |= (1 << idx);
470 		udelay(1);
471 		/* raise clock */
472 		gpio |= VT1724_PRODIGY192_CCLK;
473 		snd_ice1712_gpio_write(ice, gpio);
474 		udelay(1);
475 	}
476 	return data;
477 }
478 /*
479  * 4wire ak4114 protocol - starting sequence
480  */
481 static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice)
482 {
483 	unsigned int tmp;
484 
485 	snd_ice1712_save_gpio_status(ice);
486 	tmp = snd_ice1712_gpio_read(ice);
487 
488 	tmp |= VT1724_PRODIGY192_CCLK; /* high at init */
489 	tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */
490 	snd_ice1712_gpio_write(ice, tmp);
491 	udelay(1);
492 	return tmp;
493 }
494 
495 /*
496  * 4wire ak4114 protocol - final sequence
497  */
498 static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
499 {
500 	tmp |= VT1724_PRODIGY192_CS; /* raise chip select */
501 	snd_ice1712_gpio_write(ice, tmp);
502 	udelay(1);
503 	snd_ice1712_restore_gpio_status(ice);
504 }
505 
506 /*
507  * Write data to addr register of ak4114
508  */
509 static void prodigy192_ak4114_write(void *private_data, unsigned char addr,
510 			       unsigned char data)
511 {
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);
519 }
520 
521 /*
522  * Read data from addr register of ak4114
523  */
524 static unsigned char prodigy192_ak4114_read(void *private_data,
525 					    unsigned char addr)
526 {
527 	struct snd_ice1712 *ice = private_data;
528 	unsigned int tmp;
529 	unsigned char data;
530 
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);
535 	return data;
536 }
537 
538 
539 static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
540 	       			struct snd_ctl_elem_info *uinfo)
541 {
542 	static const char * const texts[2] = { "Toslink", "Coax" };
543 
544 	return snd_ctl_enum_info(uinfo, 1, 2, texts);
545 }
546 
547 
548 static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol,
549 	       		struct snd_ctl_elem_value *ucontrol)
550 {
551 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
552 	unsigned char val;
553 
554 	val = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
555 	/* AK4114_IPS0 bit = 0 -> RX0 = Toslink
556 	 * AK4114_IPS0 bit = 1 -> RX1 = Coax
557 	 */
558 	ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0;
559 	return 0;
560 }
561 
562 static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,
563 	       		struct snd_ctl_elem_value *ucontrol)
564 {
565 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
566 	unsigned char new, old, itemvalue;
567 	int change;
568 
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;
572 
573 	new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0);
574 	change = (new != old);
575 	if (change)
576 		prodigy192_ak4114_write(ice, AK4114_REG_IO1, new);
577 	return change;
578 }
579 
580 
581 static const struct snd_kcontrol_new ak4114_controls[] = {
582 	{
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,
588 
589 	}
590 };
591 
592 
593 static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
594 {
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
599 		 */
600 		AK4114_DIF_I24I2S | AK4114_DEM0 ,
601 		AK4114_TX1E,
602 		AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */
603 		0,
604 		0
605 	};
606 	static const unsigned char ak4114_init_txcsb[] = {
607 		0x41, 0x02, 0x2c, 0x00, 0x00
608 	};
609 	struct prodigy192_spec *spec = ice->spec;
610 	int err;
611 
612 	err = snd_ak4114_create(ice->card,
613 				 prodigy192_ak4114_read,
614 				 prodigy192_ak4114_write,
615 				 ak4114_init_vals, ak4114_init_txcsb,
616 				 ice, &spec->ak4114);
617 	if (err < 0)
618 		return err;
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;
622 	return 0;
623 }
624 
625 static void stac9460_proc_regs_read(struct snd_info_entry *entry,
626 		struct snd_info_buffer *buffer)
627 {
628 	struct snd_ice1712 *ice = entry->private_data;
629 	int reg, val;
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);
634 	}
635 }
636 
637 
638 static void stac9460_proc_init(struct snd_ice1712 *ice)
639 {
640 	snd_card_ro_proc_new(ice->card, "stac9460_codec", ice,
641 			     stac9460_proc_regs_read);
642 }
643 
644 
645 static int prodigy192_add_controls(struct snd_ice1712 *ice)
646 {
647 	struct prodigy192_spec *spec = ice->spec;
648 	unsigned int i;
649 	int err;
650 
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));
654 		if (err < 0)
655 			return err;
656 	}
657 	if (spec->ak4114) {
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],
662 						       ice));
663 			if (err < 0)
664 				return err;
665 		}
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);
669 		if (err < 0)
670 			return err;
671 	}
672 	stac9460_proc_init(ice);
673 	return 0;
674 }
675 
676 /*
677  * check for presence of MI/ODI/O add-on card with digital inputs
678  */
679 static int prodigy192_miodio_exists(struct snd_ice1712 *ice)
680 {
681 
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 */
685 	int exists = 0;
686 
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);
693 		exists = 1;
694 	}
695 	return exists;
696 }
697 
698 /*
699  * initialize the chip
700  */
701 static int prodigy192_init(struct snd_ice1712 *ice)
702 {
703 	static const unsigned short stac_inits_prodigy[] = {
704 		STAC946X_RESET, 0,
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,*/
713 		(unsigned short)-1
714 	};
715 	const unsigned short *p;
716 	int err = 0;
717 	struct prodigy192_spec *spec;
718 
719 	/* prodigy 192 */
720 	ice->num_total_dacs = 6;
721 	ice->num_total_adcs = 2;
722 	ice->vt1720 = 0;  /* ice1724, e.g. 23 GPIOs */
723 
724 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
725 	if (!spec)
726 		return -ENOMEM;
727 	ice->spec = spec;
728 	mutex_init(&spec->mute_mutex);
729 
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;
735 
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
741 		 */
742 		dev_dbg(ice->card->dev,
743 			"AK4114 initialized with status %d\n", err);
744 	} else
745 		dev_dbg(ice->card->dev, "AK4114 not found\n");
746 
747 	return err;
748 }
749 
750 
751 /*
752  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
753  * hence the driver needs to sets up it properly.
754  */
755 
756 static const unsigned char prodigy71_eeprom[] = {
757 	[ICE_EEP2_SYSCONF]     = 0x6a,	/* 49MHz crystal, mpu401,
758 					 * spdif-in+ 1 stereo ADC,
759 					 * 3 stereo DACs
760 					 */
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
773 					 * passthrough,
774 					 * 1 = SPDIF-OUT from ice1724
775 					 */
776 };
777 
778 
779 /* entry point */
780 struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] = {
781 	{
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,
789 	},
790 	{ } /* terminator */
791 };
792