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