1 /* 2 * ALSA driver for ICEnsemble ICE1712 (Envy24) 3 * 4 * Lowlevel functions for M-Audio Revolution 7.1 5 * 6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24 #include <sound/driver.h> 25 #include <asm/io.h> 26 #include <linux/delay.h> 27 #include <linux/interrupt.h> 28 #include <linux/init.h> 29 #include <linux/slab.h> 30 #include <sound/core.h> 31 32 #include "ice1712.h" 33 #include "envy24ht.h" 34 #include "revo.h" 35 36 static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) 37 { 38 /* assert PRST# to converters; MT05 bit 7 */ 39 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD)); 40 mdelay(5); 41 /* deassert PRST# */ 42 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); 43 } 44 45 /* 46 * change the rate of envy24HT, AK4355 and AK4381 47 */ 48 static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) 49 { 50 unsigned char old, tmp, dfs; 51 int reg, shift; 52 53 if (rate == 0) /* no hint - S/PDIF input is master, simply return */ 54 return; 55 56 /* adjust DFS on codecs */ 57 if (rate > 96000) 58 dfs = 2; 59 else if (rate > 48000) 60 dfs = 1; 61 else 62 dfs = 0; 63 64 if (ak->type == SND_AK4355 || ak->type == SND_AK4358) { 65 reg = 2; 66 shift = 4; 67 } else { 68 reg = 1; 69 shift = 3; 70 } 71 tmp = snd_akm4xxx_get(ak, 0, reg); 72 old = (tmp >> shift) & 0x03; 73 if (old == dfs) 74 return; 75 76 /* reset DFS */ 77 snd_akm4xxx_reset(ak, 1); 78 tmp = snd_akm4xxx_get(ak, 0, reg); 79 tmp &= ~(0x03 << shift); 80 tmp |= dfs << shift; 81 // snd_akm4xxx_write(ak, 0, reg, tmp); 82 snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */ 83 snd_akm4xxx_reset(ak, 0); 84 } 85 86 /* 87 * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1) 88 */ 89 90 static void revo_i2c_start(struct snd_i2c_bus *bus) 91 { 92 struct snd_ice1712 *ice = bus->private_data; 93 snd_ice1712_save_gpio_status(ice); 94 } 95 96 static void revo_i2c_stop(struct snd_i2c_bus *bus) 97 { 98 struct snd_ice1712 *ice = bus->private_data; 99 snd_ice1712_restore_gpio_status(ice); 100 } 101 102 static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data) 103 { 104 struct snd_ice1712 *ice = bus->private_data; 105 unsigned int mask, val; 106 107 val = 0; 108 if (clock) 109 val |= VT1724_REVO_I2C_CLOCK; /* write SCL */ 110 if (data) 111 val |= VT1724_REVO_I2C_DATA; /* write SDA */ 112 mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA; 113 ice->gpio.direction &= ~mask; 114 ice->gpio.direction |= val; 115 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); 116 snd_ice1712_gpio_set_mask(ice, ~mask); 117 } 118 119 static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data) 120 { 121 struct snd_ice1712 *ice = bus->private_data; 122 unsigned int val = 0; 123 124 if (clk) 125 val |= VT1724_REVO_I2C_CLOCK; 126 if (data) 127 val |= VT1724_REVO_I2C_DATA; 128 snd_ice1712_gpio_write_bits(ice, 129 VT1724_REVO_I2C_DATA | 130 VT1724_REVO_I2C_CLOCK, val); 131 udelay(5); 132 } 133 134 static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack) 135 { 136 struct snd_ice1712 *ice = bus->private_data; 137 int bit; 138 139 if (ack) 140 udelay(5); 141 bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0; 142 return bit; 143 } 144 145 static struct snd_i2c_bit_ops revo51_bit_ops = { 146 .start = revo_i2c_start, 147 .stop = revo_i2c_stop, 148 .direction = revo_i2c_direction, 149 .setlines = revo_i2c_setlines, 150 .getdata = revo_i2c_getdata, 151 }; 152 153 static int revo51_i2c_init(struct snd_ice1712 *ice, 154 struct snd_pt2258 *pt) 155 { 156 int err; 157 158 /* create the I2C bus */ 159 err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c); 160 if (err < 0) 161 return err; 162 163 ice->i2c->private_data = ice; 164 ice->i2c->hw_ops.bit = &revo51_bit_ops; 165 166 /* create the I2C device */ 167 err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, 168 &ice->spec.revo51.dev); 169 if (err < 0) 170 return err; 171 172 pt->card = ice->card; 173 pt->i2c_bus = ice->i2c; 174 pt->i2c_dev = ice->spec.revo51.dev; 175 ice->spec.revo51.pt2258 = pt; 176 177 snd_pt2258_reset(pt); 178 179 return 0; 180 } 181 182 /* 183 * initialize the chips on M-Audio Revolution cards 184 */ 185 186 #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } 187 188 static const struct snd_akm4xxx_dac_channel revo71_front[] = { 189 AK_DAC("PCM Playback Volume", 2) 190 }; 191 192 static const struct snd_akm4xxx_dac_channel revo71_surround[] = { 193 AK_DAC("PCM Center Playback Volume", 1), 194 AK_DAC("PCM LFE Playback Volume", 1), 195 AK_DAC("PCM Side Playback Volume", 2), 196 AK_DAC("PCM Rear Playback Volume", 2), 197 }; 198 199 static const struct snd_akm4xxx_dac_channel revo51_dac[] = { 200 AK_DAC("PCM Playback Volume", 2), 201 AK_DAC("PCM Center Playback Volume", 1), 202 AK_DAC("PCM LFE Playback Volume", 1), 203 AK_DAC("PCM Rear Playback Volume", 2), 204 }; 205 206 static const char *revo51_adc_input_names[] = { 207 "Mic", 208 "Line", 209 "CD", 210 NULL 211 }; 212 213 static const struct snd_akm4xxx_adc_channel revo51_adc[] = { 214 { 215 .name = "PCM Capture Volume", 216 .switch_name = "PCM Capture Switch", 217 .num_channels = 2, 218 .input_names = revo51_adc_input_names 219 }, 220 }; 221 222 static const struct snd_akm4xxx akm_revo_front __devinitdata = { 223 .type = SND_AK4381, 224 .num_dacs = 2, 225 .ops = { 226 .set_rate_val = revo_set_rate_val 227 }, 228 .dac_info = revo71_front, 229 }; 230 231 static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { 232 .caddr = 1, 233 .cif = 0, 234 .data_mask = VT1724_REVO_CDOUT, 235 .clk_mask = VT1724_REVO_CCLK, 236 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 237 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2, 238 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 239 .add_flags = VT1724_REVO_CCLK, /* high at init */ 240 .mask_flags = 0, 241 }; 242 243 static const struct snd_akm4xxx akm_revo_surround __devinitdata = { 244 .type = SND_AK4355, 245 .idx_offset = 1, 246 .num_dacs = 6, 247 .ops = { 248 .set_rate_val = revo_set_rate_val 249 }, 250 .dac_info = revo71_surround, 251 }; 252 253 static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { 254 .caddr = 3, 255 .cif = 0, 256 .data_mask = VT1724_REVO_CDOUT, 257 .clk_mask = VT1724_REVO_CCLK, 258 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 259 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1, 260 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 261 .add_flags = VT1724_REVO_CCLK, /* high at init */ 262 .mask_flags = 0, 263 }; 264 265 static const struct snd_akm4xxx akm_revo51 __devinitdata = { 266 .type = SND_AK4358, 267 .num_dacs = 6, 268 .ops = { 269 .set_rate_val = revo_set_rate_val 270 }, 271 .dac_info = revo51_dac, 272 }; 273 274 static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { 275 .caddr = 2, 276 .cif = 0, 277 .data_mask = VT1724_REVO_CDOUT, 278 .clk_mask = VT1724_REVO_CCLK, 279 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, 280 .cs_addr = VT1724_REVO_CS1, 281 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, 282 .add_flags = VT1724_REVO_CCLK, /* high at init */ 283 .mask_flags = 0, 284 }; 285 286 static const struct snd_akm4xxx akm_revo51_adc __devinitdata = { 287 .type = SND_AK5365, 288 .num_adcs = 2, 289 .adc_info = revo51_adc, 290 }; 291 292 static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { 293 .caddr = 2, 294 .cif = 0, 295 .data_mask = VT1724_REVO_CDOUT, 296 .clk_mask = VT1724_REVO_CCLK, 297 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, 298 .cs_addr = VT1724_REVO_CS0, 299 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, 300 .add_flags = VT1724_REVO_CCLK, /* high at init */ 301 .mask_flags = 0, 302 }; 303 304 static struct snd_pt2258 ptc_revo51_volume; 305 306 /* AK4358 for AP192 DAC, AK5385A for ADC */ 307 static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) 308 { 309 struct snd_ice1712 *ice = ak->private_data[0]; 310 311 revo_set_rate_val(ak, rate); 312 313 #if 1 /* FIXME: do we need this procedure? */ 314 /* reset DFS pin of AK5385A for ADC, too */ 315 /* DFS0 (pin 18) -- GPIO10 pin 77 */ 316 snd_ice1712_save_gpio_status(ice); 317 snd_ice1712_gpio_write_bits(ice, 1 << 10, 318 rate > 48000 ? (1 << 10) : 0); 319 snd_ice1712_restore_gpio_status(ice); 320 #endif 321 } 322 323 static const struct snd_akm4xxx_dac_channel ap192_dac[] = { 324 AK_DAC("PCM Playback Volume", 2) 325 }; 326 327 static const struct snd_akm4xxx akm_ap192 __devinitdata = { 328 .type = SND_AK4358, 329 .num_dacs = 2, 330 .ops = { 331 .set_rate_val = ap192_set_rate_val 332 }, 333 .dac_info = ap192_dac, 334 }; 335 336 static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { 337 .caddr = 2, 338 .cif = 0, 339 .data_mask = VT1724_REVO_CDOUT, 340 .clk_mask = VT1724_REVO_CCLK, 341 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, 342 .cs_addr = VT1724_REVO_CS3, 343 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, 344 .add_flags = VT1724_REVO_CCLK, /* high at init */ 345 .mask_flags = 0, 346 }; 347 348 #if 0 349 /* FIXME: ak4114 makes the sound much lower due to some confliction, 350 * so let's disable it right now... 351 */ 352 #define BUILD_AK4114_AP192 353 #endif 354 355 #ifdef BUILD_AK4114_AP192 356 /* AK4114 support on Audiophile 192 */ 357 /* CDTO (pin 32) -- GPIO2 pin 52 358 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) 359 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) 360 * CSN (pin 35) -- GPIO7 pin 59 361 */ 362 #define AK4114_ADDR 0x00 363 364 static void write_data(struct snd_ice1712 *ice, unsigned int gpio, 365 unsigned int data, int idx) 366 { 367 for (; idx >= 0; idx--) { 368 /* drop clock */ 369 gpio &= ~VT1724_REVO_CCLK; 370 snd_ice1712_gpio_write(ice, gpio); 371 udelay(1); 372 /* set data */ 373 if (data & (1 << idx)) 374 gpio |= VT1724_REVO_CDOUT; 375 else 376 gpio &= ~VT1724_REVO_CDOUT; 377 snd_ice1712_gpio_write(ice, gpio); 378 udelay(1); 379 /* raise clock */ 380 gpio |= VT1724_REVO_CCLK; 381 snd_ice1712_gpio_write(ice, gpio); 382 udelay(1); 383 } 384 } 385 386 static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, 387 int idx) 388 { 389 unsigned char data = 0; 390 391 for (; idx >= 0; idx--) { 392 /* drop clock */ 393 gpio &= ~VT1724_REVO_CCLK; 394 snd_ice1712_gpio_write(ice, gpio); 395 udelay(1); 396 /* read data */ 397 if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) 398 data |= (1 << idx); 399 udelay(1); 400 /* raise clock */ 401 gpio |= VT1724_REVO_CCLK; 402 snd_ice1712_gpio_write(ice, gpio); 403 udelay(1); 404 } 405 return data; 406 } 407 408 static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) 409 { 410 unsigned int tmp; 411 412 snd_ice1712_save_gpio_status(ice); 413 tmp = snd_ice1712_gpio_read(ice); 414 tmp |= VT1724_REVO_CCLK; /* high at init */ 415 tmp |= VT1724_REVO_CS0; 416 tmp &= ~VT1724_REVO_CS3; 417 snd_ice1712_gpio_write(ice, tmp); 418 udelay(1); 419 return tmp; 420 } 421 422 static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) 423 { 424 tmp |= VT1724_REVO_CS3; 425 tmp |= VT1724_REVO_CS0; 426 snd_ice1712_gpio_write(ice, tmp); 427 udelay(1); 428 snd_ice1712_restore_gpio_status(ice); 429 } 430 431 static void ap192_ak4114_write(void *private_data, unsigned char addr, 432 unsigned char data) 433 { 434 struct snd_ice1712 *ice = private_data; 435 unsigned int tmp, addrdata; 436 437 tmp = ap192_4wire_start(ice); 438 addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); 439 addrdata = (addrdata << 8) | data; 440 write_data(ice, tmp, addrdata, 15); 441 ap192_4wire_finish(ice, tmp); 442 } 443 444 static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) 445 { 446 struct snd_ice1712 *ice = private_data; 447 unsigned int tmp; 448 unsigned char data; 449 450 tmp = ap192_4wire_start(ice); 451 write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); 452 data = read_data(ice, tmp, 7); 453 ap192_4wire_finish(ice, tmp); 454 return data; 455 } 456 457 static int ap192_ak4114_init(struct snd_ice1712 *ice) 458 { 459 static const unsigned char ak4114_init_vals[] = { 460 AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, 461 AK4114_DIF_I24I2S, 462 AK4114_TX1E, 463 AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), 464 0, 465 0 466 }; 467 static const unsigned char ak4114_init_txcsb[] = { 468 0x41, 0x02, 0x2c, 0x00, 0x00 469 }; 470 struct ak4114 *ak; 471 int err; 472 473 return snd_ak4114_create(ice->card, 474 ap192_ak4114_read, 475 ap192_ak4114_write, 476 ak4114_init_vals, ak4114_init_txcsb, 477 ice, &ak); 478 } 479 #endif /* BUILD_AK4114_AP192 */ 480 481 static int __devinit revo_init(struct snd_ice1712 *ice) 482 { 483 struct snd_akm4xxx *ak; 484 int err; 485 486 /* determine I2C, DACs and ADCs */ 487 switch (ice->eeprom.subvendor) { 488 case VT1724_SUBDEVICE_REVOLUTION71: 489 ice->num_total_dacs = 8; 490 ice->num_total_adcs = 2; 491 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; 492 break; 493 case VT1724_SUBDEVICE_REVOLUTION51: 494 ice->num_total_dacs = 6; 495 ice->num_total_adcs = 2; 496 break; 497 case VT1724_SUBDEVICE_AUDIOPHILE192: 498 ice->num_total_dacs = 2; 499 ice->num_total_adcs = 2; 500 break; 501 default: 502 snd_BUG(); 503 return -EINVAL; 504 } 505 506 /* second stage of initialization, analog parts and others */ 507 ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); 508 if (! ak) 509 return -ENOMEM; 510 ice->akm_codecs = 2; 511 switch (ice->eeprom.subvendor) { 512 case VT1724_SUBDEVICE_REVOLUTION71: 513 ice->akm_codecs = 2; 514 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0) 515 return err; 516 if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0) 517 return err; 518 /* unmute all codecs */ 519 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); 520 break; 521 case VT1724_SUBDEVICE_REVOLUTION51: 522 ice->akm_codecs = 2; 523 err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, 524 &akm_revo51_priv, ice); 525 if (err < 0) 526 return err; 527 err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc, 528 &akm_revo51_adc_priv, ice); 529 if (err < 0) 530 return err; 531 err = revo51_i2c_init(ice, &ptc_revo51_volume); 532 if (err < 0) 533 return err; 534 /* unmute all codecs */ 535 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, 536 VT1724_REVO_MUTE); 537 break; 538 case VT1724_SUBDEVICE_AUDIOPHILE192: 539 ice->akm_codecs = 1; 540 err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, 541 ice); 542 if (err < 0) 543 return err; 544 545 break; 546 } 547 548 return 0; 549 } 550 551 552 static int __devinit revo_add_controls(struct snd_ice1712 *ice) 553 { 554 int err; 555 556 switch (ice->eeprom.subvendor) { 557 case VT1724_SUBDEVICE_REVOLUTION71: 558 err = snd_ice1712_akm4xxx_build_controls(ice); 559 if (err < 0) 560 return err; 561 break; 562 case VT1724_SUBDEVICE_REVOLUTION51: 563 err = snd_ice1712_akm4xxx_build_controls(ice); 564 if (err < 0) 565 return err; 566 err = snd_pt2258_build_controls(ice->spec.revo51.pt2258); 567 if (err < 0) 568 return err; 569 break; 570 case VT1724_SUBDEVICE_AUDIOPHILE192: 571 err = snd_ice1712_akm4xxx_build_controls(ice); 572 if (err < 0) 573 return err; 574 #ifdef BUILD_AK4114_AP192 575 err = ap192_ak4114_init(ice); 576 if (err < 0) 577 return err; 578 #endif 579 break; 580 } 581 return 0; 582 } 583 584 /* entry point */ 585 const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { 586 { 587 .subvendor = VT1724_SUBDEVICE_REVOLUTION71, 588 .name = "M Audio Revolution-7.1", 589 .model = "revo71", 590 .chip_init = revo_init, 591 .build_controls = revo_add_controls, 592 }, 593 { 594 .subvendor = VT1724_SUBDEVICE_REVOLUTION51, 595 .name = "M Audio Revolution-5.1", 596 .model = "revo51", 597 .chip_init = revo_init, 598 .build_controls = revo_add_controls, 599 }, 600 { 601 .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, 602 .name = "M Audio Audiophile192", 603 .model = "ap192", 604 .chip_init = revo_init, 605 .build_controls = revo_add_controls, 606 }, 607 { } /* terminator */ 608 }; 609