xref: /linux/sound/hda/codecs/ca0110.c (revision 6014e9021b28e634935c776c0271b5cbcabdc5d6)
1*6014e902STakashi Iwai // SPDX-License-Identifier: GPL-2.0-or-later
2*6014e902STakashi Iwai /*
3*6014e902STakashi Iwai  * HD audio interface patch for Creative X-Fi CA0110-IBG chip
4*6014e902STakashi Iwai  *
5*6014e902STakashi Iwai  * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
6*6014e902STakashi Iwai  */
7*6014e902STakashi Iwai 
8*6014e902STakashi Iwai #include <linux/init.h>
9*6014e902STakashi Iwai #include <linux/slab.h>
10*6014e902STakashi Iwai #include <linux/module.h>
11*6014e902STakashi Iwai #include <sound/core.h>
12*6014e902STakashi Iwai #include <sound/hda_codec.h>
13*6014e902STakashi Iwai #include "hda_local.h"
14*6014e902STakashi Iwai #include "hda_auto_parser.h"
15*6014e902STakashi Iwai #include "hda_jack.h"
16*6014e902STakashi Iwai #include "generic.h"
17*6014e902STakashi Iwai 
18*6014e902STakashi Iwai 
19*6014e902STakashi Iwai static const struct hda_codec_ops ca0110_patch_ops = {
20*6014e902STakashi Iwai 	.build_controls = snd_hda_gen_build_controls,
21*6014e902STakashi Iwai 	.build_pcms = snd_hda_gen_build_pcms,
22*6014e902STakashi Iwai 	.init = snd_hda_gen_init,
23*6014e902STakashi Iwai 	.free = snd_hda_gen_free,
24*6014e902STakashi Iwai 	.unsol_event = snd_hda_jack_unsol_event,
25*6014e902STakashi Iwai };
26*6014e902STakashi Iwai 
27*6014e902STakashi Iwai static int ca0110_parse_auto_config(struct hda_codec *codec)
28*6014e902STakashi Iwai {
29*6014e902STakashi Iwai 	struct hda_gen_spec *spec = codec->spec;
30*6014e902STakashi Iwai 	int err;
31*6014e902STakashi Iwai 
32*6014e902STakashi Iwai 	err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0);
33*6014e902STakashi Iwai 	if (err < 0)
34*6014e902STakashi Iwai 		return err;
35*6014e902STakashi Iwai 	err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg);
36*6014e902STakashi Iwai 	if (err < 0)
37*6014e902STakashi Iwai 		return err;
38*6014e902STakashi Iwai 
39*6014e902STakashi Iwai 	return 0;
40*6014e902STakashi Iwai }
41*6014e902STakashi Iwai 
42*6014e902STakashi Iwai 
43*6014e902STakashi Iwai static int patch_ca0110(struct hda_codec *codec)
44*6014e902STakashi Iwai {
45*6014e902STakashi Iwai 	struct hda_gen_spec *spec;
46*6014e902STakashi Iwai 	int err;
47*6014e902STakashi Iwai 
48*6014e902STakashi Iwai 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
49*6014e902STakashi Iwai 	if (!spec)
50*6014e902STakashi Iwai 		return -ENOMEM;
51*6014e902STakashi Iwai 	snd_hda_gen_spec_init(spec);
52*6014e902STakashi Iwai 	codec->spec = spec;
53*6014e902STakashi Iwai 	codec->patch_ops = ca0110_patch_ops;
54*6014e902STakashi Iwai 
55*6014e902STakashi Iwai 	spec->multi_cap_vol = 1;
56*6014e902STakashi Iwai 	codec->bus->core.needs_damn_long_delay = 1;
57*6014e902STakashi Iwai 
58*6014e902STakashi Iwai 	err = ca0110_parse_auto_config(codec);
59*6014e902STakashi Iwai 	if (err < 0)
60*6014e902STakashi Iwai 		goto error;
61*6014e902STakashi Iwai 
62*6014e902STakashi Iwai 	return 0;
63*6014e902STakashi Iwai 
64*6014e902STakashi Iwai  error:
65*6014e902STakashi Iwai 	snd_hda_gen_free(codec);
66*6014e902STakashi Iwai 	return err;
67*6014e902STakashi Iwai }
68*6014e902STakashi Iwai 
69*6014e902STakashi Iwai 
70*6014e902STakashi Iwai /*
71*6014e902STakashi Iwai  * patch entries
72*6014e902STakashi Iwai  */
73*6014e902STakashi Iwai static const struct hda_device_id snd_hda_id_ca0110[] = {
74*6014e902STakashi Iwai 	HDA_CODEC_ENTRY(0x1102000a, "CA0110-IBG", patch_ca0110),
75*6014e902STakashi Iwai 	HDA_CODEC_ENTRY(0x1102000b, "CA0110-IBG", patch_ca0110),
76*6014e902STakashi Iwai 	HDA_CODEC_ENTRY(0x1102000d, "SB0880 X-Fi", patch_ca0110),
77*6014e902STakashi Iwai 	{} /* terminator */
78*6014e902STakashi Iwai };
79*6014e902STakashi Iwai MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0110);
80*6014e902STakashi Iwai 
81*6014e902STakashi Iwai MODULE_LICENSE("GPL");
82*6014e902STakashi Iwai MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
83*6014e902STakashi Iwai 
84*6014e902STakashi Iwai static struct hda_codec_driver ca0110_driver = {
85*6014e902STakashi Iwai 	.id = snd_hda_id_ca0110,
86*6014e902STakashi Iwai };
87*6014e902STakashi Iwai 
88*6014e902STakashi Iwai module_hda_codec_driver(ca0110_driver);
89