1 /* 2 * HD audio interface patch for Creative X-Fi CA0110-IBG chip 3 * 4 * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de> 5 * 6 * This driver is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This driver is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <linux/init.h> 22 #include <linux/delay.h> 23 #include <linux/slab.h> 24 #include <linux/pci.h> 25 #include <linux/module.h> 26 #include <sound/core.h> 27 #include "hda_codec.h" 28 #include "hda_local.h" 29 30 /* 31 */ 32 33 struct ca0110_spec { 34 struct auto_pin_cfg autocfg; 35 struct hda_multi_out multiout; 36 hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; 37 hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; 38 hda_nid_t hp_dac; 39 hda_nid_t input_pins[AUTO_PIN_LAST]; 40 hda_nid_t adcs[AUTO_PIN_LAST]; 41 hda_nid_t dig_out; 42 hda_nid_t dig_in; 43 unsigned int num_inputs; 44 const char *input_labels[AUTO_PIN_LAST]; 45 struct hda_pcm pcm_rec[2]; /* PCM information */ 46 }; 47 48 /* 49 * PCM callbacks 50 */ 51 static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo, 52 struct hda_codec *codec, 53 struct snd_pcm_substream *substream) 54 { 55 struct ca0110_spec *spec = codec->spec; 56 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 57 hinfo); 58 } 59 60 static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 61 struct hda_codec *codec, 62 unsigned int stream_tag, 63 unsigned int format, 64 struct snd_pcm_substream *substream) 65 { 66 struct ca0110_spec *spec = codec->spec; 67 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 68 stream_tag, format, substream); 69 } 70 71 static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 72 struct hda_codec *codec, 73 struct snd_pcm_substream *substream) 74 { 75 struct ca0110_spec *spec = codec->spec; 76 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 77 } 78 79 /* 80 * Digital out 81 */ 82 static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 83 struct hda_codec *codec, 84 struct snd_pcm_substream *substream) 85 { 86 struct ca0110_spec *spec = codec->spec; 87 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 88 } 89 90 static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 91 struct hda_codec *codec, 92 struct snd_pcm_substream *substream) 93 { 94 struct ca0110_spec *spec = codec->spec; 95 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 96 } 97 98 static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 99 struct hda_codec *codec, 100 unsigned int stream_tag, 101 unsigned int format, 102 struct snd_pcm_substream *substream) 103 { 104 struct ca0110_spec *spec = codec->spec; 105 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 106 format, substream); 107 } 108 109 /* 110 * Analog capture 111 */ 112 static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 113 struct hda_codec *codec, 114 unsigned int stream_tag, 115 unsigned int format, 116 struct snd_pcm_substream *substream) 117 { 118 struct ca0110_spec *spec = codec->spec; 119 120 snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], 121 stream_tag, 0, format); 122 return 0; 123 } 124 125 static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 126 struct hda_codec *codec, 127 struct snd_pcm_substream *substream) 128 { 129 struct ca0110_spec *spec = codec->spec; 130 131 snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]); 132 return 0; 133 } 134 135 /* 136 */ 137 138 static const char * const dirstr[2] = { "Playback", "Capture" }; 139 140 static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 141 int chan, int dir) 142 { 143 char namestr[44]; 144 int type = dir ? HDA_INPUT : HDA_OUTPUT; 145 struct snd_kcontrol_new knew = 146 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); 147 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 148 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 149 } 150 151 static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 152 int chan, int dir) 153 { 154 char namestr[44]; 155 int type = dir ? HDA_INPUT : HDA_OUTPUT; 156 struct snd_kcontrol_new knew = 157 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); 158 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); 159 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 160 } 161 162 #define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) 163 #define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0) 164 #define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1) 165 #define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1) 166 #define add_mono_switch(codec, nid, pfx, chan) \ 167 _add_switch(codec, nid, pfx, chan, 0) 168 #define add_mono_volume(codec, nid, pfx, chan) \ 169 _add_volume(codec, nid, pfx, chan, 0) 170 171 static int ca0110_build_controls(struct hda_codec *codec) 172 { 173 struct ca0110_spec *spec = codec->spec; 174 struct auto_pin_cfg *cfg = &spec->autocfg; 175 static const char * const prefix[AUTO_CFG_MAX_OUTS] = { 176 "Front", "Surround", NULL, "Side", "Multi" 177 }; 178 hda_nid_t mutenid; 179 int i, err; 180 181 for (i = 0; i < spec->multiout.num_dacs; i++) { 182 if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP) 183 mutenid = spec->out_pins[i]; 184 else 185 mutenid = spec->multiout.dac_nids[i]; 186 if (!prefix[i]) { 187 err = add_mono_switch(codec, mutenid, 188 "Center", 1); 189 if (err < 0) 190 return err; 191 err = add_mono_switch(codec, mutenid, 192 "LFE", 1); 193 if (err < 0) 194 return err; 195 err = add_mono_volume(codec, spec->multiout.dac_nids[i], 196 "Center", 1); 197 if (err < 0) 198 return err; 199 err = add_mono_volume(codec, spec->multiout.dac_nids[i], 200 "LFE", 1); 201 if (err < 0) 202 return err; 203 } else { 204 err = add_out_switch(codec, mutenid, 205 prefix[i]); 206 if (err < 0) 207 return err; 208 err = add_out_volume(codec, spec->multiout.dac_nids[i], 209 prefix[i]); 210 if (err < 0) 211 return err; 212 } 213 } 214 if (cfg->hp_outs) { 215 if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP) 216 mutenid = cfg->hp_pins[0]; 217 else 218 mutenid = spec->multiout.dac_nids[i]; 219 220 err = add_out_switch(codec, mutenid, "Headphone"); 221 if (err < 0) 222 return err; 223 if (spec->hp_dac) { 224 err = add_out_volume(codec, spec->hp_dac, "Headphone"); 225 if (err < 0) 226 return err; 227 } 228 } 229 for (i = 0; i < spec->num_inputs; i++) { 230 const char *label = spec->input_labels[i]; 231 if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP) 232 mutenid = spec->input_pins[i]; 233 else 234 mutenid = spec->adcs[i]; 235 err = add_in_switch(codec, mutenid, label); 236 if (err < 0) 237 return err; 238 err = add_in_volume(codec, spec->adcs[i], label); 239 if (err < 0) 240 return err; 241 } 242 243 if (spec->dig_out) { 244 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out, 245 spec->dig_out); 246 if (err < 0) 247 return err; 248 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 249 if (err < 0) 250 return err; 251 spec->multiout.share_spdif = 1; 252 } 253 if (spec->dig_in) { 254 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); 255 if (err < 0) 256 return err; 257 err = add_in_volume(codec, spec->dig_in, "IEC958"); 258 } 259 return 0; 260 } 261 262 /* 263 */ 264 static const struct hda_pcm_stream ca0110_pcm_analog_playback = { 265 .substreams = 1, 266 .channels_min = 2, 267 .channels_max = 8, 268 .ops = { 269 .open = ca0110_playback_pcm_open, 270 .prepare = ca0110_playback_pcm_prepare, 271 .cleanup = ca0110_playback_pcm_cleanup 272 }, 273 }; 274 275 static const struct hda_pcm_stream ca0110_pcm_analog_capture = { 276 .substreams = 1, 277 .channels_min = 2, 278 .channels_max = 2, 279 .ops = { 280 .prepare = ca0110_capture_pcm_prepare, 281 .cleanup = ca0110_capture_pcm_cleanup 282 }, 283 }; 284 285 static const struct hda_pcm_stream ca0110_pcm_digital_playback = { 286 .substreams = 1, 287 .channels_min = 2, 288 .channels_max = 2, 289 .ops = { 290 .open = ca0110_dig_playback_pcm_open, 291 .close = ca0110_dig_playback_pcm_close, 292 .prepare = ca0110_dig_playback_pcm_prepare 293 }, 294 }; 295 296 static const struct hda_pcm_stream ca0110_pcm_digital_capture = { 297 .substreams = 1, 298 .channels_min = 2, 299 .channels_max = 2, 300 }; 301 302 static int ca0110_build_pcms(struct hda_codec *codec) 303 { 304 struct ca0110_spec *spec = codec->spec; 305 struct hda_pcm *info = spec->pcm_rec; 306 307 codec->pcm_info = info; 308 codec->num_pcms = 0; 309 310 info->name = "CA0110 Analog"; 311 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; 312 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; 313 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 314 spec->multiout.max_channels; 315 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; 316 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; 317 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; 318 codec->num_pcms++; 319 320 if (!spec->dig_out && !spec->dig_in) 321 return 0; 322 323 info++; 324 info->name = "CA0110 Digital"; 325 info->pcm_type = HDA_PCM_TYPE_SPDIF; 326 if (spec->dig_out) { 327 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 328 ca0110_pcm_digital_playback; 329 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out; 330 } 331 if (spec->dig_in) { 332 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 333 ca0110_pcm_digital_capture; 334 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; 335 } 336 codec->num_pcms++; 337 338 return 0; 339 } 340 341 static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) 342 { 343 if (pin) { 344 snd_hda_codec_write(codec, pin, 0, 345 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 346 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) 347 snd_hda_codec_write(codec, pin, 0, 348 AC_VERB_SET_AMP_GAIN_MUTE, 349 AMP_OUT_UNMUTE); 350 } 351 if (dac) 352 snd_hda_codec_write(codec, dac, 0, 353 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); 354 } 355 356 static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) 357 { 358 if (pin) { 359 snd_hda_codec_write(codec, pin, 0, 360 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); 361 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) 362 snd_hda_codec_write(codec, pin, 0, 363 AC_VERB_SET_AMP_GAIN_MUTE, 364 AMP_IN_UNMUTE(0)); 365 } 366 if (adc) 367 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, 368 AMP_IN_UNMUTE(0)); 369 } 370 371 static int ca0110_init(struct hda_codec *codec) 372 { 373 struct ca0110_spec *spec = codec->spec; 374 struct auto_pin_cfg *cfg = &spec->autocfg; 375 int i; 376 377 for (i = 0; i < spec->multiout.num_dacs; i++) 378 init_output(codec, spec->out_pins[i], 379 spec->multiout.dac_nids[i]); 380 init_output(codec, cfg->hp_pins[0], spec->hp_dac); 381 init_output(codec, cfg->dig_out_pins[0], spec->dig_out); 382 383 for (i = 0; i < spec->num_inputs; i++) 384 init_input(codec, spec->input_pins[i], spec->adcs[i]); 385 init_input(codec, cfg->dig_in_pin, spec->dig_in); 386 return 0; 387 } 388 389 static void ca0110_free(struct hda_codec *codec) 390 { 391 kfree(codec->spec); 392 } 393 394 static const struct hda_codec_ops ca0110_patch_ops = { 395 .build_controls = ca0110_build_controls, 396 .build_pcms = ca0110_build_pcms, 397 .init = ca0110_init, 398 .free = ca0110_free, 399 }; 400 401 402 static void parse_line_outs(struct hda_codec *codec) 403 { 404 struct ca0110_spec *spec = codec->spec; 405 struct auto_pin_cfg *cfg = &spec->autocfg; 406 int i, n; 407 unsigned int def_conf; 408 hda_nid_t nid; 409 410 n = 0; 411 for (i = 0; i < cfg->line_outs; i++) { 412 nid = cfg->line_out_pins[i]; 413 def_conf = snd_hda_codec_get_pincfg(codec, nid); 414 if (!def_conf) 415 continue; /* invalid pin */ 416 if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) 417 continue; 418 spec->out_pins[n++] = nid; 419 } 420 spec->multiout.dac_nids = spec->dacs; 421 spec->multiout.num_dacs = n; 422 spec->multiout.max_channels = n * 2; 423 } 424 425 static void parse_hp_out(struct hda_codec *codec) 426 { 427 struct ca0110_spec *spec = codec->spec; 428 struct auto_pin_cfg *cfg = &spec->autocfg; 429 int i; 430 unsigned int def_conf; 431 hda_nid_t nid, dac; 432 433 if (!cfg->hp_outs) 434 return; 435 nid = cfg->hp_pins[0]; 436 def_conf = snd_hda_codec_get_pincfg(codec, nid); 437 if (!def_conf) { 438 cfg->hp_outs = 0; 439 return; 440 } 441 if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) 442 return; 443 444 for (i = 0; i < cfg->line_outs; i++) 445 if (dac == spec->dacs[i]) 446 break; 447 if (i >= cfg->line_outs) { 448 spec->hp_dac = dac; 449 spec->multiout.hp_nid = dac; 450 } 451 } 452 453 static void parse_input(struct hda_codec *codec) 454 { 455 struct ca0110_spec *spec = codec->spec; 456 struct auto_pin_cfg *cfg = &spec->autocfg; 457 hda_nid_t nid, pin; 458 int n, i, j; 459 460 n = 0; 461 nid = codec->start_nid; 462 for (i = 0; i < codec->num_nodes; i++, nid++) { 463 unsigned int wcaps = get_wcaps(codec, nid); 464 unsigned int type = get_wcaps_type(wcaps); 465 if (type != AC_WID_AUD_IN) 466 continue; 467 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) 468 continue; 469 if (pin == cfg->dig_in_pin) { 470 spec->dig_in = nid; 471 continue; 472 } 473 for (j = 0; j < cfg->num_inputs; j++) 474 if (cfg->inputs[j].pin == pin) 475 break; 476 if (j >= cfg->num_inputs) 477 continue; 478 spec->input_pins[n] = pin; 479 spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1); 480 spec->adcs[n] = nid; 481 n++; 482 } 483 spec->num_inputs = n; 484 } 485 486 static void parse_digital(struct hda_codec *codec) 487 { 488 struct ca0110_spec *spec = codec->spec; 489 struct auto_pin_cfg *cfg = &spec->autocfg; 490 491 if (cfg->dig_outs && 492 snd_hda_get_connections(codec, cfg->dig_out_pins[0], 493 &spec->dig_out, 1) == 1) 494 spec->multiout.dig_out_nid = spec->dig_out; 495 } 496 497 static int ca0110_parse_auto_config(struct hda_codec *codec) 498 { 499 struct ca0110_spec *spec = codec->spec; 500 int err; 501 502 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 503 if (err < 0) 504 return err; 505 506 parse_line_outs(codec); 507 parse_hp_out(codec); 508 parse_digital(codec); 509 parse_input(codec); 510 return 0; 511 } 512 513 514 static int patch_ca0110(struct hda_codec *codec) 515 { 516 struct ca0110_spec *spec; 517 int err; 518 519 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 520 if (!spec) 521 return -ENOMEM; 522 codec->spec = spec; 523 524 codec->bus->needs_damn_long_delay = 1; 525 526 err = ca0110_parse_auto_config(codec); 527 if (err < 0) 528 goto error; 529 530 codec->patch_ops = ca0110_patch_ops; 531 532 return 0; 533 534 error: 535 kfree(codec->spec); 536 codec->spec = NULL; 537 return err; 538 } 539 540 541 /* 542 * patch entries 543 */ 544 static const struct hda_codec_preset snd_hda_preset_ca0110[] = { 545 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, 546 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, 547 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, 548 {} /* terminator */ 549 }; 550 551 MODULE_ALIAS("snd-hda-codec-id:1102000a"); 552 MODULE_ALIAS("snd-hda-codec-id:1102000b"); 553 MODULE_ALIAS("snd-hda-codec-id:1102000d"); 554 555 MODULE_LICENSE("GPL"); 556 MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); 557 558 static struct hda_codec_preset_list ca0110_list = { 559 .preset = snd_hda_preset_ca0110, 560 .owner = THIS_MODULE, 561 }; 562 563 static int __init patch_ca0110_init(void) 564 { 565 return snd_hda_add_codec_preset(&ca0110_list); 566 } 567 568 static void __exit patch_ca0110_exit(void) 569 { 570 snd_hda_delete_codec_preset(&ca0110_list); 571 } 572 573 module_init(patch_ca0110_init) 574 module_exit(patch_ca0110_exit) 575