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