1 /* 2 * card driver for the Xonar DG/DGX 3 * 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 5 * 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License, version 2. 9 * 10 * This driver is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this driver; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* 20 * Xonar DG/DGX 21 * ------------ 22 * 23 * CMI8788: 24 * 25 * SPI 0 -> CS4245 26 * 27 * I²S 1 -> CS4245 28 * I²S 2 -> CS4361 (center/LFE) 29 * I²S 3 -> CS4361 (surround) 30 * I²S 4 -> CS4361 (front) 31 * 32 * GPIO 3 <- ? 33 * GPIO 4 <- headphone detect 34 * GPIO 5 -> route input jack to line-in (0) or mic-in (1) 35 * GPIO 6 -> route input jack to line-in (0) or mic-in (1) 36 * GPIO 7 -> enable rear headphone amp 37 * GPIO 8 -> enable output to speakers 38 * 39 * CS4245: 40 * 41 * input 1 <- aux 42 * input 2 <- front mic 43 * input 4 <- line/mic 44 * DAC out -> headphones 45 * aux out -> front panel headphones 46 */ 47 48 #include <linux/pci.h> 49 #include <linux/delay.h> 50 #include <sound/control.h> 51 #include <sound/core.h> 52 #include <sound/info.h> 53 #include <sound/pcm.h> 54 #include <sound/tlv.h> 55 #include "oxygen.h" 56 #include "xonar_dg.h" 57 #include "cs4245.h" 58 59 #define GPIO_MAGIC 0x0008 60 #define GPIO_HP_DETECT 0x0010 61 #define GPIO_INPUT_ROUTE 0x0060 62 #define GPIO_HP_REAR 0x0080 63 #define GPIO_OUTPUT_ENABLE 0x0100 64 65 struct dg { 66 unsigned int output_sel; 67 s8 input_vol[4][2]; 68 unsigned int input_sel; 69 u8 hp_vol_att; 70 u8 cs4245_regs[0x11]; 71 }; 72 73 static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value) 74 { 75 struct dg *data = chip->model_data; 76 77 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 78 OXYGEN_SPI_DATA_LENGTH_3 | 79 OXYGEN_SPI_CLOCK_1280 | 80 (0 << OXYGEN_SPI_CODEC_SHIFT) | 81 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 82 CS4245_SPI_ADDRESS | 83 CS4245_SPI_WRITE | 84 (reg << 8) | value); 85 data->cs4245_regs[reg] = value; 86 } 87 88 static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value) 89 { 90 struct dg *data = chip->model_data; 91 92 if (value != data->cs4245_regs[reg]) 93 cs4245_write(chip, reg, value); 94 } 95 96 static void cs4245_registers_init(struct oxygen *chip) 97 { 98 struct dg *data = chip->model_data; 99 100 cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN); 101 cs4245_write(chip, CS4245_DAC_CTRL_1, 102 data->cs4245_regs[CS4245_DAC_CTRL_1]); 103 cs4245_write(chip, CS4245_ADC_CTRL, 104 data->cs4245_regs[CS4245_ADC_CTRL]); 105 cs4245_write(chip, CS4245_SIGNAL_SEL, 106 data->cs4245_regs[CS4245_SIGNAL_SEL]); 107 cs4245_write(chip, CS4245_PGA_B_CTRL, 108 data->cs4245_regs[CS4245_PGA_B_CTRL]); 109 cs4245_write(chip, CS4245_PGA_A_CTRL, 110 data->cs4245_regs[CS4245_PGA_A_CTRL]); 111 cs4245_write(chip, CS4245_ANALOG_IN, 112 data->cs4245_regs[CS4245_ANALOG_IN]); 113 cs4245_write(chip, CS4245_DAC_A_CTRL, 114 data->cs4245_regs[CS4245_DAC_A_CTRL]); 115 cs4245_write(chip, CS4245_DAC_B_CTRL, 116 data->cs4245_regs[CS4245_DAC_B_CTRL]); 117 cs4245_write(chip, CS4245_DAC_CTRL_2, 118 CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC); 119 cs4245_write(chip, CS4245_INT_MASK, 0); 120 cs4245_write(chip, CS4245_POWER_CTRL, 0); 121 } 122 123 static void cs4245_init(struct oxygen *chip) 124 { 125 struct dg *data = chip->model_data; 126 127 data->cs4245_regs[CS4245_DAC_CTRL_1] = 128 CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST; 129 data->cs4245_regs[CS4245_ADC_CTRL] = 130 CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST; 131 data->cs4245_regs[CS4245_SIGNAL_SEL] = 132 CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH; 133 data->cs4245_regs[CS4245_PGA_B_CTRL] = 0; 134 data->cs4245_regs[CS4245_PGA_A_CTRL] = 0; 135 data->cs4245_regs[CS4245_ANALOG_IN] = 136 CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4; 137 data->cs4245_regs[CS4245_DAC_A_CTRL] = 0; 138 data->cs4245_regs[CS4245_DAC_B_CTRL] = 0; 139 cs4245_registers_init(chip); 140 snd_component_add(chip->card, "CS4245"); 141 } 142 143 static void dg_output_enable(struct oxygen *chip) 144 { 145 msleep(2500); 146 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); 147 } 148 149 static void dg_init(struct oxygen *chip) 150 { 151 struct dg *data = chip->model_data; 152 153 data->output_sel = 0; 154 data->input_sel = 3; 155 data->hp_vol_att = 2 * 16; 156 157 cs4245_init(chip); 158 159 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, 160 GPIO_MAGIC | GPIO_HP_DETECT); 161 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 162 GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE); 163 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 164 GPIO_INPUT_ROUTE | GPIO_HP_REAR); 165 dg_output_enable(chip); 166 } 167 168 static void dg_cleanup(struct oxygen *chip) 169 { 170 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); 171 } 172 173 static void dg_suspend(struct oxygen *chip) 174 { 175 dg_cleanup(chip); 176 } 177 178 static void dg_resume(struct oxygen *chip) 179 { 180 cs4245_registers_init(chip); 181 dg_output_enable(chip); 182 } 183 184 static void set_cs4245_dac_params(struct oxygen *chip, 185 struct snd_pcm_hw_params *params) 186 { 187 struct dg *data = chip->model_data; 188 u8 value; 189 190 value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK; 191 if (params_rate(params) <= 50000) 192 value |= CS4245_DAC_FM_SINGLE; 193 else if (params_rate(params) <= 100000) 194 value |= CS4245_DAC_FM_DOUBLE; 195 else 196 value |= CS4245_DAC_FM_QUAD; 197 cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value); 198 } 199 200 static void set_cs4245_adc_params(struct oxygen *chip, 201 struct snd_pcm_hw_params *params) 202 { 203 struct dg *data = chip->model_data; 204 u8 value; 205 206 value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK; 207 if (params_rate(params) <= 50000) 208 value |= CS4245_ADC_FM_SINGLE; 209 else if (params_rate(params) <= 100000) 210 value |= CS4245_ADC_FM_DOUBLE; 211 else 212 value |= CS4245_ADC_FM_QUAD; 213 cs4245_write_cached(chip, CS4245_ADC_CTRL, value); 214 } 215 216 static inline unsigned int shift_bits(unsigned int value, 217 unsigned int shift_from, 218 unsigned int shift_to, 219 unsigned int mask) 220 { 221 if (shift_from < shift_to) 222 return (value << (shift_to - shift_from)) & mask; 223 else 224 return (value >> (shift_from - shift_to)) & mask; 225 } 226 227 static unsigned int adjust_dg_dac_routing(struct oxygen *chip, 228 unsigned int play_routing) 229 { 230 return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) | 231 shift_bits(play_routing, 232 OXYGEN_PLAY_DAC2_SOURCE_SHIFT, 233 OXYGEN_PLAY_DAC1_SOURCE_SHIFT, 234 OXYGEN_PLAY_DAC1_SOURCE_MASK) | 235 shift_bits(play_routing, 236 OXYGEN_PLAY_DAC1_SOURCE_SHIFT, 237 OXYGEN_PLAY_DAC2_SOURCE_SHIFT, 238 OXYGEN_PLAY_DAC2_SOURCE_MASK) | 239 shift_bits(play_routing, 240 OXYGEN_PLAY_DAC0_SOURCE_SHIFT, 241 OXYGEN_PLAY_DAC3_SOURCE_SHIFT, 242 OXYGEN_PLAY_DAC3_SOURCE_MASK); 243 } 244 245 static int output_switch_info(struct snd_kcontrol *ctl, 246 struct snd_ctl_elem_info *info) 247 { 248 static const char *const names[3] = { 249 "Speakers", "Headphones", "FP Headphones" 250 }; 251 252 return snd_ctl_enum_info(info, 1, 3, names); 253 } 254 255 static int output_switch_get(struct snd_kcontrol *ctl, 256 struct snd_ctl_elem_value *value) 257 { 258 struct oxygen *chip = ctl->private_data; 259 struct dg *data = chip->model_data; 260 261 mutex_lock(&chip->mutex); 262 value->value.enumerated.item[0] = data->output_sel; 263 mutex_unlock(&chip->mutex); 264 return 0; 265 } 266 267 static int output_switch_put(struct snd_kcontrol *ctl, 268 struct snd_ctl_elem_value *value) 269 { 270 struct oxygen *chip = ctl->private_data; 271 struct dg *data = chip->model_data; 272 u8 reg; 273 int changed; 274 275 if (value->value.enumerated.item[0] > 2) 276 return -EINVAL; 277 278 mutex_lock(&chip->mutex); 279 changed = value->value.enumerated.item[0] != data->output_sel; 280 if (changed) { 281 data->output_sel = value->value.enumerated.item[0]; 282 283 reg = data->cs4245_regs[CS4245_SIGNAL_SEL] & 284 ~CS4245_A_OUT_SEL_MASK; 285 reg |= data->output_sel == 2 ? 286 CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ; 287 cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg); 288 289 cs4245_write_cached(chip, CS4245_DAC_A_CTRL, 290 data->output_sel ? data->hp_vol_att : 0); 291 cs4245_write_cached(chip, CS4245_DAC_B_CTRL, 292 data->output_sel ? data->hp_vol_att : 0); 293 294 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 295 data->output_sel == 1 ? GPIO_HP_REAR : 0, 296 GPIO_HP_REAR); 297 } 298 mutex_unlock(&chip->mutex); 299 return changed; 300 } 301 302 static int hp_volume_offset_info(struct snd_kcontrol *ctl, 303 struct snd_ctl_elem_info *info) 304 { 305 static const char *const names[3] = { 306 "< 64 ohms", "64-150 ohms", "150-300 ohms" 307 }; 308 309 return snd_ctl_enum_info(info, 1, 3, names); 310 } 311 312 static int hp_volume_offset_get(struct snd_kcontrol *ctl, 313 struct snd_ctl_elem_value *value) 314 { 315 struct oxygen *chip = ctl->private_data; 316 struct dg *data = chip->model_data; 317 318 mutex_lock(&chip->mutex); 319 if (data->hp_vol_att > 2 * 7) 320 value->value.enumerated.item[0] = 0; 321 else if (data->hp_vol_att > 0) 322 value->value.enumerated.item[0] = 1; 323 else 324 value->value.enumerated.item[0] = 2; 325 mutex_unlock(&chip->mutex); 326 return 0; 327 } 328 329 static int hp_volume_offset_put(struct snd_kcontrol *ctl, 330 struct snd_ctl_elem_value *value) 331 { 332 static const s8 atts[3] = { 2 * 16, 2 * 7, 0 }; 333 struct oxygen *chip = ctl->private_data; 334 struct dg *data = chip->model_data; 335 s8 att; 336 int changed; 337 338 if (value->value.enumerated.item[0] > 2) 339 return -EINVAL; 340 att = atts[value->value.enumerated.item[0]]; 341 mutex_lock(&chip->mutex); 342 changed = att != data->hp_vol_att; 343 if (changed) { 344 data->hp_vol_att = att; 345 if (data->output_sel) { 346 cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att); 347 cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att); 348 } 349 } 350 mutex_unlock(&chip->mutex); 351 return changed; 352 } 353 354 static int input_vol_info(struct snd_kcontrol *ctl, 355 struct snd_ctl_elem_info *info) 356 { 357 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 358 info->count = 2; 359 info->value.integer.min = 2 * -12; 360 info->value.integer.max = 2 * 12; 361 return 0; 362 } 363 364 static int input_vol_get(struct snd_kcontrol *ctl, 365 struct snd_ctl_elem_value *value) 366 { 367 struct oxygen *chip = ctl->private_data; 368 struct dg *data = chip->model_data; 369 unsigned int idx = ctl->private_value; 370 371 mutex_lock(&chip->mutex); 372 value->value.integer.value[0] = data->input_vol[idx][0]; 373 value->value.integer.value[1] = data->input_vol[idx][1]; 374 mutex_unlock(&chip->mutex); 375 return 0; 376 } 377 378 static int input_vol_put(struct snd_kcontrol *ctl, 379 struct snd_ctl_elem_value *value) 380 { 381 struct oxygen *chip = ctl->private_data; 382 struct dg *data = chip->model_data; 383 unsigned int idx = ctl->private_value; 384 int changed = 0; 385 386 if (value->value.integer.value[0] < 2 * -12 || 387 value->value.integer.value[0] > 2 * 12 || 388 value->value.integer.value[1] < 2 * -12 || 389 value->value.integer.value[1] > 2 * 12) 390 return -EINVAL; 391 mutex_lock(&chip->mutex); 392 changed = data->input_vol[idx][0] != value->value.integer.value[0] || 393 data->input_vol[idx][1] != value->value.integer.value[1]; 394 if (changed) { 395 data->input_vol[idx][0] = value->value.integer.value[0]; 396 data->input_vol[idx][1] = value->value.integer.value[1]; 397 if (idx == data->input_sel) { 398 cs4245_write_cached(chip, CS4245_PGA_A_CTRL, 399 data->input_vol[idx][0]); 400 cs4245_write_cached(chip, CS4245_PGA_B_CTRL, 401 data->input_vol[idx][1]); 402 } 403 } 404 mutex_unlock(&chip->mutex); 405 return changed; 406 } 407 408 static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0); 409 410 static int input_sel_info(struct snd_kcontrol *ctl, 411 struct snd_ctl_elem_info *info) 412 { 413 static const char *const names[4] = { 414 "Mic", "Aux", "Front Mic", "Line" 415 }; 416 417 return snd_ctl_enum_info(info, 1, 4, names); 418 } 419 420 static int input_sel_get(struct snd_kcontrol *ctl, 421 struct snd_ctl_elem_value *value) 422 { 423 struct oxygen *chip = ctl->private_data; 424 struct dg *data = chip->model_data; 425 426 mutex_lock(&chip->mutex); 427 value->value.enumerated.item[0] = data->input_sel; 428 mutex_unlock(&chip->mutex); 429 return 0; 430 } 431 432 static int input_sel_put(struct snd_kcontrol *ctl, 433 struct snd_ctl_elem_value *value) 434 { 435 static const u8 sel_values[4] = { 436 CS4245_SEL_MIC, 437 CS4245_SEL_INPUT_1, 438 CS4245_SEL_INPUT_2, 439 CS4245_SEL_INPUT_4 440 }; 441 struct oxygen *chip = ctl->private_data; 442 struct dg *data = chip->model_data; 443 int changed; 444 445 if (value->value.enumerated.item[0] > 3) 446 return -EINVAL; 447 448 mutex_lock(&chip->mutex); 449 changed = value->value.enumerated.item[0] != data->input_sel; 450 if (changed) { 451 data->input_sel = value->value.enumerated.item[0]; 452 453 cs4245_write(chip, CS4245_ANALOG_IN, 454 (data->cs4245_regs[CS4245_ANALOG_IN] & 455 ~CS4245_SEL_MASK) | 456 sel_values[data->input_sel]); 457 458 cs4245_write_cached(chip, CS4245_PGA_A_CTRL, 459 data->input_vol[data->input_sel][0]); 460 cs4245_write_cached(chip, CS4245_PGA_B_CTRL, 461 data->input_vol[data->input_sel][1]); 462 463 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 464 data->input_sel ? 0 : GPIO_INPUT_ROUTE, 465 GPIO_INPUT_ROUTE); 466 } 467 mutex_unlock(&chip->mutex); 468 return changed; 469 } 470 471 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 472 { 473 static const char *const names[2] = { "Active", "Frozen" }; 474 475 return snd_ctl_enum_info(info, 1, 2, names); 476 } 477 478 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 479 { 480 struct oxygen *chip = ctl->private_data; 481 struct dg *data = chip->model_data; 482 483 value->value.enumerated.item[0] = 484 !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE); 485 return 0; 486 } 487 488 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 489 { 490 struct oxygen *chip = ctl->private_data; 491 struct dg *data = chip->model_data; 492 u8 reg; 493 int changed; 494 495 mutex_lock(&chip->mutex); 496 reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE; 497 if (value->value.enumerated.item[0]) 498 reg |= CS4245_HPF_FREEZE; 499 changed = reg != data->cs4245_regs[CS4245_ADC_CTRL]; 500 if (changed) 501 cs4245_write(chip, CS4245_ADC_CTRL, reg); 502 mutex_unlock(&chip->mutex); 503 return changed; 504 } 505 506 #define INPUT_VOLUME(xname, index) { \ 507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 508 .name = xname, \ 509 .info = input_vol_info, \ 510 .get = input_vol_get, \ 511 .put = input_vol_put, \ 512 .tlv = { .p = cs4245_pga_db_scale }, \ 513 .private_value = index, \ 514 } 515 static const struct snd_kcontrol_new dg_controls[] = { 516 { 517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 518 .name = "Analog Output Playback Enum", 519 .info = output_switch_info, 520 .get = output_switch_get, 521 .put = output_switch_put, 522 }, 523 { 524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 525 .name = "Headphones Impedance Playback Enum", 526 .info = hp_volume_offset_info, 527 .get = hp_volume_offset_get, 528 .put = hp_volume_offset_put, 529 }, 530 INPUT_VOLUME("Mic Capture Volume", 0), 531 INPUT_VOLUME("Aux Capture Volume", 1), 532 INPUT_VOLUME("Front Mic Capture Volume", 2), 533 INPUT_VOLUME("Line Capture Volume", 3), 534 { 535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 536 .name = "Capture Source", 537 .info = input_sel_info, 538 .get = input_sel_get, 539 .put = input_sel_put, 540 }, 541 { 542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 543 .name = "ADC High-pass Filter Capture Enum", 544 .info = hpf_info, 545 .get = hpf_get, 546 .put = hpf_put, 547 }, 548 }; 549 550 static int dg_control_filter(struct snd_kcontrol_new *template) 551 { 552 if (!strncmp(template->name, "Master Playback ", 16)) 553 return 1; 554 return 0; 555 } 556 557 static int dg_mixer_init(struct oxygen *chip) 558 { 559 unsigned int i; 560 int err; 561 562 for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) { 563 err = snd_ctl_add(chip->card, 564 snd_ctl_new1(&dg_controls[i], chip)); 565 if (err < 0) 566 return err; 567 } 568 return 0; 569 } 570 571 static void dump_cs4245_registers(struct oxygen *chip, 572 struct snd_info_buffer *buffer) 573 { 574 struct dg *data = chip->model_data; 575 unsigned int i; 576 577 snd_iprintf(buffer, "\nCS4245:"); 578 for (i = 1; i <= 0x10; ++i) 579 snd_iprintf(buffer, " %02x", data->cs4245_regs[i]); 580 snd_iprintf(buffer, "\n"); 581 } 582 583 struct oxygen_model model_xonar_dg = { 584 .longname = "C-Media Oxygen HD Audio", 585 .chip = "CMI8786", 586 .init = dg_init, 587 .control_filter = dg_control_filter, 588 .mixer_init = dg_mixer_init, 589 .cleanup = dg_cleanup, 590 .suspend = dg_suspend, 591 .resume = dg_resume, 592 .set_dac_params = set_cs4245_dac_params, 593 .set_adc_params = set_cs4245_adc_params, 594 .adjust_dac_routing = adjust_dg_dac_routing, 595 .dump_registers = dump_cs4245_registers, 596 .model_data_size = sizeof(struct dg), 597 .device_config = PLAYBACK_0_TO_I2S | 598 PLAYBACK_1_TO_SPDIF | 599 CAPTURE_0_FROM_I2S_2 | 600 CAPTURE_1_FROM_SPDIF, 601 .dac_channels_pcm = 6, 602 .dac_channels_mixer = 0, 603 .function_flags = OXYGEN_FUNCTION_SPI, 604 .dac_mclks = OXYGEN_MCLKS(256, 128, 128), 605 .adc_mclks = OXYGEN_MCLKS(256, 128, 128), 606 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 607 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 608 }; 609