14e01f54bSTakashi Iwai /* 24e01f54bSTakashi Iwai * HD audio interface patch for Creative X-Fi CA0110-IBG chip 34e01f54bSTakashi Iwai * 44e01f54bSTakashi Iwai * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de> 54e01f54bSTakashi Iwai * 64e01f54bSTakashi Iwai * This driver is free software; you can redistribute it and/or modify 74e01f54bSTakashi Iwai * it under the terms of the GNU General Public License as published by 84e01f54bSTakashi Iwai * the Free Software Foundation; either version 2 of the License, or 94e01f54bSTakashi Iwai * (at your option) any later version. 104e01f54bSTakashi Iwai * 114e01f54bSTakashi Iwai * This driver is distributed in the hope that it will be useful, 124e01f54bSTakashi Iwai * but WITHOUT ANY WARRANTY; without even the implied warranty of 134e01f54bSTakashi Iwai * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144e01f54bSTakashi Iwai * GNU General Public License for more details. 154e01f54bSTakashi Iwai * 164e01f54bSTakashi Iwai * You should have received a copy of the GNU General Public License 174e01f54bSTakashi Iwai * along with this program; if not, write to the Free Software 184e01f54bSTakashi Iwai * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 194e01f54bSTakashi Iwai */ 204e01f54bSTakashi Iwai 214e01f54bSTakashi Iwai #include <linux/init.h> 224e01f54bSTakashi Iwai #include <linux/slab.h> 23da155d5bSPaul Gortmaker #include <linux/module.h> 244e01f54bSTakashi Iwai #include <sound/core.h> 254e01f54bSTakashi Iwai #include "hda_codec.h" 264e01f54bSTakashi Iwai #include "hda_local.h" 27128bc4baSTakashi Iwai #include "hda_auto_parser.h" 288fadf1daSTakashi Iwai #include "hda_jack.h" 298fadf1daSTakashi Iwai #include "hda_generic.h" 304e01f54bSTakashi Iwai 314e01f54bSTakashi Iwai 32728850a7STakashi Iwai static const struct hda_codec_ops ca0110_patch_ops = { 338fadf1daSTakashi Iwai .build_controls = snd_hda_gen_build_controls, 348fadf1daSTakashi Iwai .build_pcms = snd_hda_gen_build_pcms, 358fadf1daSTakashi Iwai .init = snd_hda_gen_init, 368fadf1daSTakashi Iwai .free = snd_hda_gen_free, 378a6c21aeSTakashi Iwai .unsol_event = snd_hda_jack_unsol_event, 384e01f54bSTakashi Iwai }; 394e01f54bSTakashi Iwai 404e01f54bSTakashi Iwai static int ca0110_parse_auto_config(struct hda_codec *codec) 414e01f54bSTakashi Iwai { 428fadf1daSTakashi Iwai struct hda_gen_spec *spec = codec->spec; 434e01f54bSTakashi Iwai int err; 444e01f54bSTakashi Iwai 458fadf1daSTakashi Iwai err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0); 468fadf1daSTakashi Iwai if (err < 0) 478fadf1daSTakashi Iwai return err; 488fadf1daSTakashi Iwai err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg); 494e01f54bSTakashi Iwai if (err < 0) 504e01f54bSTakashi Iwai return err; 514e01f54bSTakashi Iwai 524e01f54bSTakashi Iwai return 0; 534e01f54bSTakashi Iwai } 544e01f54bSTakashi Iwai 554e01f54bSTakashi Iwai 561e168953STakashi Iwai static int patch_ca0110(struct hda_codec *codec) 574e01f54bSTakashi Iwai { 588fadf1daSTakashi Iwai struct hda_gen_spec *spec; 594e01f54bSTakashi Iwai int err; 604e01f54bSTakashi Iwai 614e01f54bSTakashi Iwai spec = kzalloc(sizeof(*spec), GFP_KERNEL); 624e01f54bSTakashi Iwai if (!spec) 634e01f54bSTakashi Iwai return -ENOMEM; 648fadf1daSTakashi Iwai snd_hda_gen_spec_init(spec); 654e01f54bSTakashi Iwai codec->spec = spec; 66*225068abSTakashi Iwai codec->patch_ops = ca0110_patch_ops; 674e01f54bSTakashi Iwai 688fadf1daSTakashi Iwai spec->multi_cap_vol = 1; 694e01f54bSTakashi Iwai codec->bus->needs_damn_long_delay = 1; 704e01f54bSTakashi Iwai 714e01f54bSTakashi Iwai err = ca0110_parse_auto_config(codec); 724e01f54bSTakashi Iwai if (err < 0) 734e01f54bSTakashi Iwai goto error; 744e01f54bSTakashi Iwai 754e01f54bSTakashi Iwai return 0; 764e01f54bSTakashi Iwai 774e01f54bSTakashi Iwai error: 788fadf1daSTakashi Iwai snd_hda_gen_free(codec); 794e01f54bSTakashi Iwai return err; 804e01f54bSTakashi Iwai } 814e01f54bSTakashi Iwai 824e01f54bSTakashi Iwai 834e01f54bSTakashi Iwai /* 844e01f54bSTakashi Iwai * patch entries 854e01f54bSTakashi Iwai */ 86728850a7STakashi Iwai static const struct hda_codec_preset snd_hda_preset_ca0110[] = { 874e01f54bSTakashi Iwai { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, 884e01f54bSTakashi Iwai { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, 894e01f54bSTakashi Iwai { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, 904e01f54bSTakashi Iwai {} /* terminator */ 914e01f54bSTakashi Iwai }; 924e01f54bSTakashi Iwai 934e01f54bSTakashi Iwai MODULE_ALIAS("snd-hda-codec-id:1102000a"); 944e01f54bSTakashi Iwai MODULE_ALIAS("snd-hda-codec-id:1102000b"); 954e01f54bSTakashi Iwai MODULE_ALIAS("snd-hda-codec-id:1102000d"); 964e01f54bSTakashi Iwai 974e01f54bSTakashi Iwai MODULE_LICENSE("GPL"); 984e01f54bSTakashi Iwai MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); 994e01f54bSTakashi Iwai 100d8a766a1STakashi Iwai static struct hda_codec_driver ca0110_driver = { 1014e01f54bSTakashi Iwai .preset = snd_hda_preset_ca0110, 1024e01f54bSTakashi Iwai }; 1034e01f54bSTakashi Iwai 104d8a766a1STakashi Iwai module_hda_codec_driver(ca0110_driver); 105