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; 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 guard(mutex)(&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 return stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]); 126 } 127 128 /* 129 * DAC volume attenuation mixer control 130 */ 131 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 132 { 133 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 134 uinfo->count = 1; 135 uinfo->value.integer.min = 0; /* mute */ 136 uinfo->value.integer.max = 0x7f; /* 0dB */ 137 return 0; 138 } 139 140 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 141 { 142 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 143 int idx; 144 unsigned char vol; 145 146 if (kcontrol->private_value) 147 idx = STAC946X_MASTER_VOLUME; 148 else 149 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 150 vol = stac9460_get(ice, idx) & 0x7f; 151 ucontrol->value.integer.value[0] = 0x7f - vol; 152 153 return 0; 154 } 155 156 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 157 { 158 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 159 int idx; 160 unsigned char tmp, ovol, nvol; 161 int change; 162 163 if (kcontrol->private_value) 164 idx = STAC946X_MASTER_VOLUME; 165 else 166 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 167 nvol = ucontrol->value.integer.value[0]; 168 tmp = stac9460_get(ice, idx); 169 ovol = 0x7f - (tmp & 0x7f); 170 change = (ovol != nvol); 171 if (change) 172 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 173 174 return change; 175 } 176 177 /* 178 * ADC mute control 179 */ 180 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info 181 182 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 183 { 184 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 185 unsigned char val; 186 int i; 187 188 for (i = 0; i < 2; ++i) { 189 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); 190 ucontrol->value.integer.value[i] = ~val>>7 & 0x1; 191 } 192 193 return 0; 194 } 195 196 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 197 { 198 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 199 unsigned char new, old; 200 int i, reg; 201 int change; 202 203 for (i = 0; i < 2; ++i) { 204 reg = STAC946X_MIC_L_VOLUME + i; 205 old = stac9460_get(ice, reg); 206 new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80); 207 change = (new != old); 208 if (change) 209 stac9460_put(ice, reg, new); 210 } 211 212 return change; 213 } 214 215 /* 216 * ADC gain mixer control 217 */ 218 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 219 { 220 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 221 uinfo->count = 2; 222 uinfo->value.integer.min = 0; /* 0dB */ 223 uinfo->value.integer.max = 0x0f; /* 22.5dB */ 224 return 0; 225 } 226 227 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 228 { 229 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 230 int i, reg; 231 unsigned char vol; 232 233 for (i = 0; i < 2; ++i) { 234 reg = STAC946X_MIC_L_VOLUME + i; 235 vol = stac9460_get(ice, reg) & 0x0f; 236 ucontrol->value.integer.value[i] = 0x0f - vol; 237 } 238 239 return 0; 240 } 241 242 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 243 { 244 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 245 int i, reg; 246 unsigned char ovol, nvol; 247 int change; 248 249 for (i = 0; i < 2; ++i) { 250 reg = STAC946X_MIC_L_VOLUME + i; 251 nvol = ucontrol->value.integer.value[i] & 0x0f; 252 ovol = 0x0f - stac9460_get(ice, reg); 253 change = ((ovol & 0x0f) != nvol); 254 if (change) 255 stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f)); 256 } 257 258 return change; 259 } 260 261 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, 262 struct snd_ctl_elem_info *uinfo) 263 { 264 static const char * const texts[2] = { "Line In", "Mic" }; 265 266 return snd_ctl_enum_info(uinfo, 1, 2, texts); 267 } 268 269 270 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, 271 struct snd_ctl_elem_value *ucontrol) 272 { 273 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 274 unsigned char val; 275 276 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 277 ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; 278 return 0; 279 } 280 281 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, 282 struct snd_ctl_elem_value *ucontrol) 283 { 284 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 285 unsigned char new, old; 286 int change; 287 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 288 new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); 289 change = (new != old); 290 if (change) 291 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); 292 return change; 293 } 294 /* 295 * Handler for setting correct codec rate - called when rate change is detected 296 */ 297 static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) 298 { 299 unsigned char old, new; 300 int idx; 301 unsigned char changed[7]; 302 struct prodigy192_spec *spec = ice->spec; 303 304 if (rate == 0) /* no hint - S/PDIF input is master, simply return */ 305 return; 306 else if (rate <= 48000) 307 new = 0x08; /* 256x, base rate mode */ 308 else if (rate <= 96000) 309 new = 0x11; /* 256x, mid rate mode */ 310 else 311 new = 0x12; /* 128x, high rate mode */ 312 old = stac9460_get(ice, STAC946X_MASTER_CLOCKING); 313 if (old == new) 314 return; 315 /* change detected, setting master clock, muting first */ 316 /* due to possible conflicts with mute controls - mutexing */ 317 guard(mutex)(&spec->mute_mutex); 318 /* we have to remember current mute status for each DAC */ 319 for (idx = 0; idx < 7 ; ++idx) 320 changed[idx] = stac9460_dac_mute(ice, 321 STAC946X_MASTER_VOLUME + idx, 0); 322 /*dev_dbg(ice->card->dev, "Rate change: %d, new MC: 0x%02x\n", rate, new);*/ 323 stac9460_put(ice, STAC946X_MASTER_CLOCKING, new); 324 udelay(10); 325 /* unmuting - only originally unmuted dacs - 326 * i.e. those changed when muting */ 327 for (idx = 0; idx < 7 ; ++idx) { 328 if (changed[idx]) 329 stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1); 330 } 331 } 332 333 334 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); 335 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); 336 337 /* 338 * mixers 339 */ 340 341 static const struct snd_kcontrol_new stac_controls[] = { 342 { 343 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 344 .name = "Master Playback Switch", 345 .info = stac9460_dac_mute_info, 346 .get = stac9460_dac_mute_get, 347 .put = stac9460_dac_mute_put, 348 .private_value = 1, 349 .tlv = { .p = db_scale_dac } 350 }, 351 { 352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 353 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 354 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 355 .name = "Master Playback Volume", 356 .info = stac9460_dac_vol_info, 357 .get = stac9460_dac_vol_get, 358 .put = stac9460_dac_vol_put, 359 .private_value = 1, 360 .tlv = { .p = db_scale_dac } 361 }, 362 { 363 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 364 .name = "DAC Switch", 365 .count = 6, 366 .info = stac9460_dac_mute_info, 367 .get = stac9460_dac_mute_get, 368 .put = stac9460_dac_mute_put, 369 }, 370 { 371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 372 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 373 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 374 .name = "DAC Volume", 375 .count = 6, 376 .info = stac9460_dac_vol_info, 377 .get = stac9460_dac_vol_get, 378 .put = stac9460_dac_vol_put, 379 .tlv = { .p = db_scale_dac } 380 }, 381 { 382 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 383 .name = "ADC Capture Switch", 384 .count = 1, 385 .info = stac9460_adc_mute_info, 386 .get = stac9460_adc_mute_get, 387 .put = stac9460_adc_mute_put, 388 389 }, 390 { 391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 392 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 393 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 394 .name = "ADC Capture Volume", 395 .count = 1, 396 .info = stac9460_adc_vol_info, 397 .get = stac9460_adc_vol_get, 398 .put = stac9460_adc_vol_put, 399 .tlv = { .p = db_scale_adc } 400 }, 401 { 402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 403 .name = "Analog Capture Input", 404 .info = stac9460_mic_sw_info, 405 .get = stac9460_mic_sw_get, 406 .put = stac9460_mic_sw_put, 407 408 }, 409 }; 410 411 /* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ 412 /* CDTO (pin 32) -- GPIO11 pin 86 413 * CDTI (pin 33) -- GPIO10 pin 77 414 * CCLK (pin 34) -- GPIO9 pin 76 415 * CSN (pin 35) -- GPIO8 pin 75 416 */ 417 #define AK4114_ADDR 0x00 /* C1-C0: Chip Address 418 * (According to datasheet fixed to “00”) 419 */ 420 421 /* 422 * 4wire ak4114 protocol - writing data 423 */ 424 static void write_data(struct snd_ice1712 *ice, unsigned int gpio, 425 unsigned int data, int idx) 426 { 427 for (; idx >= 0; idx--) { 428 /* drop clock */ 429 gpio &= ~VT1724_PRODIGY192_CCLK; 430 snd_ice1712_gpio_write(ice, gpio); 431 udelay(1); 432 /* set data */ 433 if (data & (1 << idx)) 434 gpio |= VT1724_PRODIGY192_CDOUT; 435 else 436 gpio &= ~VT1724_PRODIGY192_CDOUT; 437 snd_ice1712_gpio_write(ice, gpio); 438 udelay(1); 439 /* raise clock */ 440 gpio |= VT1724_PRODIGY192_CCLK; 441 snd_ice1712_gpio_write(ice, gpio); 442 udelay(1); 443 } 444 } 445 446 /* 447 * 4wire ak4114 protocol - reading data 448 */ 449 static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, 450 int idx) 451 { 452 unsigned char data = 0; 453 454 for (; idx >= 0; idx--) { 455 /* drop clock */ 456 gpio &= ~VT1724_PRODIGY192_CCLK; 457 snd_ice1712_gpio_write(ice, gpio); 458 udelay(1); 459 /* read data */ 460 if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) 461 data |= (1 << idx); 462 udelay(1); 463 /* raise clock */ 464 gpio |= VT1724_PRODIGY192_CCLK; 465 snd_ice1712_gpio_write(ice, gpio); 466 udelay(1); 467 } 468 return data; 469 } 470 /* 471 * 4wire ak4114 protocol - starting sequence 472 */ 473 static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) 474 { 475 unsigned int tmp; 476 477 snd_ice1712_save_gpio_status(ice); 478 tmp = snd_ice1712_gpio_read(ice); 479 480 tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ 481 tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ 482 snd_ice1712_gpio_write(ice, tmp); 483 udelay(1); 484 return tmp; 485 } 486 487 /* 488 * 4wire ak4114 protocol - final sequence 489 */ 490 static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) 491 { 492 tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ 493 snd_ice1712_gpio_write(ice, tmp); 494 udelay(1); 495 snd_ice1712_restore_gpio_status(ice); 496 } 497 498 /* 499 * Write data to addr register of ak4114 500 */ 501 static void prodigy192_ak4114_write(void *private_data, unsigned char addr, 502 unsigned char data) 503 { 504 struct snd_ice1712 *ice = private_data; 505 unsigned int tmp, addrdata; 506 tmp = prodigy192_4wire_start(ice); 507 addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); 508 addrdata = (addrdata << 8) | data; 509 write_data(ice, tmp, addrdata, 15); 510 prodigy192_4wire_finish(ice, tmp); 511 } 512 513 /* 514 * Read data from addr register of ak4114 515 */ 516 static unsigned char prodigy192_ak4114_read(void *private_data, 517 unsigned char addr) 518 { 519 struct snd_ice1712 *ice = private_data; 520 unsigned int tmp; 521 unsigned char data; 522 523 tmp = prodigy192_4wire_start(ice); 524 write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); 525 data = read_data(ice, tmp, 7); 526 prodigy192_4wire_finish(ice, tmp); 527 return data; 528 } 529 530 531 static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, 532 struct snd_ctl_elem_info *uinfo) 533 { 534 static const char * const texts[2] = { "Toslink", "Coax" }; 535 536 return snd_ctl_enum_info(uinfo, 1, 2, texts); 537 } 538 539 540 static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, 541 struct snd_ctl_elem_value *ucontrol) 542 { 543 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 544 unsigned char val; 545 546 val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); 547 /* AK4114_IPS0 bit = 0 -> RX0 = Toslink 548 * AK4114_IPS0 bit = 1 -> RX1 = Coax 549 */ 550 ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; 551 return 0; 552 } 553 554 static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, 555 struct snd_ctl_elem_value *ucontrol) 556 { 557 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 558 unsigned char new, old, itemvalue; 559 int change; 560 561 old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); 562 /* AK4114_IPS0 could be any bit */ 563 itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; 564 565 new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); 566 change = (new != old); 567 if (change) 568 prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); 569 return change; 570 } 571 572 573 static const struct snd_kcontrol_new ak4114_controls[] = { 574 { 575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 576 .name = "MIODIO IEC958 Capture Input", 577 .info = ak4114_input_sw_info, 578 .get = ak4114_input_sw_get, 579 .put = ak4114_input_sw_put, 580 581 } 582 }; 583 584 585 static int prodigy192_ak4114_init(struct snd_ice1712 *ice) 586 { 587 static const unsigned char ak4114_init_vals[] = { 588 AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, 589 /* ice1724 expects I2S and provides clock, 590 * DEM0 disables the deemphasis filter 591 */ 592 AK4114_DIF_I24I2S | AK4114_DEM0 , 593 AK4114_TX1E, 594 AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ 595 0, 596 0 597 }; 598 static const unsigned char ak4114_init_txcsb[] = { 599 0x41, 0x02, 0x2c, 0x00, 0x00 600 }; 601 struct prodigy192_spec *spec = ice->spec; 602 int err; 603 604 err = snd_ak4114_create(ice->card, 605 prodigy192_ak4114_read, 606 prodigy192_ak4114_write, 607 ak4114_init_vals, ak4114_init_txcsb, 608 ice, &spec->ak4114); 609 if (err < 0) 610 return err; 611 /* AK4114 in Prodigy192 cannot detect external rate correctly. 612 * No reason to stop capture stream due to incorrect checks */ 613 spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; 614 return 0; 615 } 616 617 static void stac9460_proc_regs_read(struct snd_info_entry *entry, 618 struct snd_info_buffer *buffer) 619 { 620 struct snd_ice1712 *ice = entry->private_data; 621 int reg, val; 622 /* registers 0x0 - 0x14 */ 623 for (reg = 0; reg <= 0x15; reg++) { 624 val = stac9460_get(ice, reg); 625 snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val); 626 } 627 } 628 629 630 static void stac9460_proc_init(struct snd_ice1712 *ice) 631 { 632 snd_card_ro_proc_new(ice->card, "stac9460_codec", ice, 633 stac9460_proc_regs_read); 634 } 635 636 637 static int prodigy192_add_controls(struct snd_ice1712 *ice) 638 { 639 struct prodigy192_spec *spec = ice->spec; 640 unsigned int i; 641 int err; 642 643 for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { 644 err = snd_ctl_add(ice->card, 645 snd_ctl_new1(&stac_controls[i], ice)); 646 if (err < 0) 647 return err; 648 } 649 if (spec->ak4114) { 650 /* ak4114 is connected */ 651 for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { 652 err = snd_ctl_add(ice->card, 653 snd_ctl_new1(&ak4114_controls[i], 654 ice)); 655 if (err < 0) 656 return err; 657 } 658 err = snd_ak4114_build(spec->ak4114, 659 NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ 660 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 661 if (err < 0) 662 return err; 663 } 664 stac9460_proc_init(ice); 665 return 0; 666 } 667 668 /* 669 * check for presence of MI/ODI/O add-on card with digital inputs 670 */ 671 static int prodigy192_miodio_exists(struct snd_ice1712 *ice) 672 { 673 674 unsigned char orig_value; 675 const unsigned char test_data = 0xd1; /* random value */ 676 unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ 677 int exists = 0; 678 679 orig_value = prodigy192_ak4114_read(ice, addr); 680 prodigy192_ak4114_write(ice, addr, test_data); 681 if (prodigy192_ak4114_read(ice, addr) == test_data) { 682 /* ak4114 seems to communicate, apparently exists */ 683 /* writing back original value */ 684 prodigy192_ak4114_write(ice, addr, orig_value); 685 exists = 1; 686 } 687 return exists; 688 } 689 690 /* 691 * initialize the chip 692 */ 693 static int prodigy192_init(struct snd_ice1712 *ice) 694 { 695 static const unsigned short stac_inits_prodigy[] = { 696 STAC946X_RESET, 0, 697 STAC946X_MASTER_CLOCKING, 0x11, 698 /* STAC946X_MASTER_VOLUME, 0, 699 STAC946X_LF_VOLUME, 0, 700 STAC946X_RF_VOLUME, 0, 701 STAC946X_LR_VOLUME, 0, 702 STAC946X_RR_VOLUME, 0, 703 STAC946X_CENTER_VOLUME, 0, 704 STAC946X_LFE_VOLUME, 0,*/ 705 (unsigned short)-1 706 }; 707 const unsigned short *p; 708 int err = 0; 709 struct prodigy192_spec *spec; 710 711 /* prodigy 192 */ 712 ice->num_total_dacs = 6; 713 ice->num_total_adcs = 2; 714 ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ 715 716 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 717 if (!spec) 718 return -ENOMEM; 719 ice->spec = spec; 720 mutex_init(&spec->mute_mutex); 721 722 /* initialize codec */ 723 p = stac_inits_prodigy; 724 for (; *p != (unsigned short)-1; p += 2) 725 stac9460_put(ice, p[0], p[1]); 726 ice->gpio.set_pro_rate = stac9460_set_rate_val; 727 728 /* MI/ODI/O add on card with AK4114 */ 729 if (prodigy192_miodio_exists(ice)) { 730 err = prodigy192_ak4114_init(ice); 731 /* from this moment if err = 0 then 732 * spec->ak4114 should not be null 733 */ 734 dev_dbg(ice->card->dev, 735 "AK4114 initialized with status %d\n", err); 736 } else 737 dev_dbg(ice->card->dev, "AK4114 not found\n"); 738 739 return err; 740 } 741 742 743 /* 744 * Aureon boards don't provide the EEPROM data except for the vendor IDs. 745 * hence the driver needs to sets up it properly. 746 */ 747 748 static const unsigned char prodigy71_eeprom[] = { 749 [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, 750 * spdif-in+ 1 stereo ADC, 751 * 3 stereo DACs 752 */ 753 [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 754 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ 755 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 756 [ICE_EEP2_GPIO_DIR] = 0xff, 757 [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , 758 [ICE_EEP2_GPIO_DIR2] = 0xbf, 759 [ICE_EEP2_GPIO_MASK] = 0x00, 760 [ICE_EEP2_GPIO_MASK1] = 0x00, 761 [ICE_EEP2_GPIO_MASK2] = 0x00, 762 [ICE_EEP2_GPIO_STATE] = 0x00, 763 [ICE_EEP2_GPIO_STATE1] = 0x00, 764 [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input 765 * passthrough, 766 * 1 = SPDIF-OUT from ice1724 767 */ 768 }; 769 770 771 /* entry point */ 772 struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] = { 773 { 774 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, 775 .name = "Audiotrak Prodigy 192", 776 .model = "prodigy192", 777 .chip_init = prodigy192_init, 778 .build_controls = prodigy192_add_controls, 779 .eeprom_size = sizeof(prodigy71_eeprom), 780 .eeprom_data = prodigy71_eeprom, 781 }, 782 { } /* terminator */ 783 }; 784