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 36static 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 */ 48static 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 90static 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 96static 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 102static 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 119static 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 134static 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 145static 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 153static 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 188static const struct snd_akm4xxx_dac_channel revo71_front[] = { 189 AK_DAC("PCM Playback Volume", 2) 190}; 191 192static 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 199static 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 206static const char *revo51_adc_input_names[] = { 207 "Mic", 208 "Line", 209 "CD", 210 NULL 211}; 212 213static 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 222static 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 231static 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 243static 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 253static 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 265static 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 274static 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 286static struct snd_akm4xxx akm_revo51_adc __devinitdata = { 287 .type = SND_AK5365, 288 .num_adcs = 2, 289 .adc_info = revo51_adc, 290}; 291 292static 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 304static struct snd_pt2258 ptc_revo51_volume; 305 306/* AK4358 for AP192 DAC, AK5385A for ADC */ 307static 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 /* reset DFS pin of AK5385A for ADC, too */ 314 /* DFS0 (pin 18) -- GPIO10 pin 77 */ 315 snd_ice1712_save_gpio_status(ice); 316 snd_ice1712_gpio_write_bits(ice, 1 << 10, 317 rate > 48000 ? (1 << 10) : 0); 318 snd_ice1712_restore_gpio_status(ice); 319} 320 321static const struct snd_akm4xxx_dac_channel ap192_dac[] = { 322 AK_DAC("PCM Playback Volume", 2) 323}; 324 325static struct snd_akm4xxx akm_ap192 __devinitdata = { 326 .type = SND_AK4358, 327 .num_dacs = 2, 328 .ops = { 329 .set_rate_val = ap192_set_rate_val 330 }, 331 .dac_info = ap192_dac, 332}; 333 334static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { 335 .caddr = 2, 336 .cif = 0, 337 .data_mask = VT1724_REVO_CDOUT, 338 .clk_mask = VT1724_REVO_CCLK, 339 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, 340 .cs_addr = VT1724_REVO_CS3, 341 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, 342 .add_flags = VT1724_REVO_CCLK, /* high at init */ 343 .mask_flags = 0, 344}; 345 346 347#ifdef BUILD_AK4114_AP192 348/* AK4114 support on Audiophile 192 */ 349/* CDTO (pin 32) -- GPIO2 pin 52 350 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) 351 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) 352 * CSN (pin 35) -- GPIO7 pin 59 353 */ 354#define AK4114_ADDR 0x00 355 356static void write_data(struct snd_ice1712 *ice, unsigned int gpio, 357 unsigned int data, int idx) 358{ 359 for (; idx >= 0; idx--) { 360 /* drop clock */ 361 gpio &= ~VT1724_REVO_CCLK; 362 snd_ice1712_gpio_write(ice, gpio); 363 udelay(1); 364 /* set data */ 365 if (data & (1 << idx)) 366 gpio |= VT1724_REVO_CDOUT; 367 else 368 gpio &= ~VT1724_REVO_CDOUT; 369 snd_ice1712_gpio_write(ice, gpio); 370 udelay(1); 371 /* raise clock */ 372 gpio |= VT1724_REVO_CCLK; 373 snd_ice1712_gpio_write(ice, gpio); 374 udelay(1); 375 } 376} 377 378static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, 379 int idx) 380{ 381 unsigned char data = 0; 382 383 for (; idx >= 0; idx--) { 384 /* drop clock */ 385 gpio &= ~VT1724_REVO_CCLK; 386 snd_ice1712_gpio_write(ice, gpio); 387 udelay(1); 388 /* read data */ 389 if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) 390 data |= (1 << idx); 391 udelay(1); 392 /* raise clock */ 393 gpio |= VT1724_REVO_CCLK; 394 snd_ice1712_gpio_write(ice, gpio); 395 udelay(1); 396 } 397 return data; 398} 399 400static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) 401{ 402 unsigned int tmp; 403 404 snd_ice1712_save_gpio_status(ice); 405 tmp = snd_ice1712_gpio_read(ice); 406 tmp |= VT1724_REVO_CCLK; /* high at init */ 407 tmp |= VT1724_REVO_CS0; 408 tmp &= ~VT1724_REVO_CS3; 409 snd_ice1712_gpio_write(ice, tmp); 410 udelay(1); 411 return tmp; 412} 413 414static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) 415{ 416 tmp |= VT1724_REVO_CS3; 417 tmp |= VT1724_REVO_CS0; 418 snd_ice1712_gpio_write(ice, tmp); 419 udelay(1); 420 snd_ice1712_restore_gpio_status(ice); 421} 422 423static void ap192_ak4114_write(void *private_data, unsigned char addr, 424 unsigned char data) 425{ 426 struct snd_ice1712 *ice = private_data; 427 unsigned int tmp, addrdata; 428 429 tmp = ap192_4wire_start(ice); 430 addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); 431 addrdata = (addrdata << 8) | data; 432 write_data(ice, tmp, addrdata, 15); 433 ap192_4wire_finish(ice, tmp); 434} 435 436static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) 437{ 438 struct snd_ice1712 *ice = private_data; 439 unsigned int tmp; 440 unsigned char data; 441 442 tmp = ap192_4wire_start(ice); 443 write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); 444 data = read_data(ice, tmp, 7); 445 ap192_4wire_finish(ice, tmp); 446 return data; 447} 448 449static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) 450{ 451 static const unsigned char ak4114_init_vals[] = { 452 AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, 453 AK4114_DIF_I24I2S, 454 AK4114_TX1E, 455 AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), 456 0, 457 0 458 }; 459 static const unsigned char ak4114_init_txcsb[] = { 460 0x41, 0x02, 0x2c, 0x00, 0x00 461 }; 462 struct ak4114 *ak; 463 int err; 464 465 return snd_ak4114_create(ice->card, 466 ap192_ak4114_read, 467 ap192_ak4114_write, 468 ak4114_init_vals, ak4114_init_txcsb, 469 ice, &ak); 470} 471#endif /* BUILD_AK4114_AP192 */ 472 473static int __devinit revo_init(struct snd_ice1712 *ice) 474{ 475 struct snd_akm4xxx *ak; 476 int err; 477 478 /* determine I2C, DACs and ADCs */ 479 switch (ice->eeprom.subvendor) { 480 case VT1724_SUBDEVICE_REVOLUTION71: 481 ice->num_total_dacs = 8; 482 ice->num_total_adcs = 2; 483 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; 484 break; 485 case VT1724_SUBDEVICE_REVOLUTION51: 486 ice->num_total_dacs = 6; 487 ice->num_total_adcs = 2; 488 break; 489 case VT1724_SUBDEVICE_AUDIOPHILE192: 490 ice->num_total_dacs = 2; 491 ice->num_total_adcs = 2; 492 break; 493 default: 494 snd_BUG(); 495 return -EINVAL; 496 } 497 498 /* second stage of initialization, analog parts and others */ 499 ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); 500 if (! ak) 501 return -ENOMEM; 502 ice->akm_codecs = 2; 503 switch (ice->eeprom.subvendor) { 504 case VT1724_SUBDEVICE_REVOLUTION71: 505 ice->akm_codecs = 2; 506 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0) 507 return err; 508 if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0) 509 return err; 510 /* unmute all codecs */ 511 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); 512 break; 513 case VT1724_SUBDEVICE_REVOLUTION51: 514 ice->akm_codecs = 2; 515 err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, 516 &akm_revo51_priv, ice); 517 if (err < 0) 518 return err; 519 err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc, 520 &akm_revo51_adc_priv, ice); 521 if (err < 0) 522 return err; 523 err = revo51_i2c_init(ice, &ptc_revo51_volume); 524 if (err < 0) 525 return err; 526 /* unmute all codecs */ 527 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, 528 VT1724_REVO_MUTE); 529 break; 530 case VT1724_SUBDEVICE_AUDIOPHILE192: 531 ice->akm_codecs = 1; 532 err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, 533 ice); 534 if (err < 0) 535 return err; 536 537 break; 538 } 539 540 return 0; 541} 542 543 544static int __devinit revo_add_controls(struct snd_ice1712 *ice) 545{ 546 int err; 547 548 switch (ice->eeprom.subvendor) { 549 case VT1724_SUBDEVICE_REVOLUTION71: 550 err = snd_ice1712_akm4xxx_build_controls(ice); 551 if (err < 0) 552 return err; 553 break; 554 case VT1724_SUBDEVICE_REVOLUTION51: 555 err = snd_ice1712_akm4xxx_build_controls(ice); 556 if (err < 0) 557 return err; 558 err = snd_pt2258_build_controls(ice->spec.revo51.pt2258); 559 if (err < 0) 560 return err; 561 break; 562 case VT1724_SUBDEVICE_AUDIOPHILE192: 563 err = snd_ice1712_akm4xxx_build_controls(ice); 564 if (err < 0) 565 return err; 566#ifdef BUILD_AK4114_AP192 567 err = ap192_ak4114_init(ice); 568 if (err < 0) 569 return err; 570#endif 571 break; 572 } 573 return 0; 574} 575 576/* entry point */ 577struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { 578 { 579 .subvendor = VT1724_SUBDEVICE_REVOLUTION71, 580 .name = "M Audio Revolution-7.1", 581 .model = "revo71", 582 .chip_init = revo_init, 583 .build_controls = revo_add_controls, 584 }, 585 { 586 .subvendor = VT1724_SUBDEVICE_REVOLUTION51, 587 .name = "M Audio Revolution-5.1", 588 .model = "revo51", 589 .chip_init = revo_init, 590 .build_controls = revo_add_controls, 591 }, 592 { 593 .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, 594 .name = "M Audio Audiophile192", 595 .model = "ap192", 596 .chip_init = revo_init, 597 .build_controls = revo_add_controls, 598 }, 599 { } /* terminator */ 600}; 601