xref: /linux/sound/hda/codecs/realtek/alc262.c (revision aeeb85f26c3bbef6f702ac20167c45812251501d)
1*aeeb85f2STakashi Iwai // SPDX-License-Identifier: GPL-2.0-or-later
2*aeeb85f2STakashi Iwai //
3*aeeb85f2STakashi Iwai // Realtek ALC262 codec
4*aeeb85f2STakashi Iwai //
5*aeeb85f2STakashi Iwai 
6*aeeb85f2STakashi Iwai #include <linux/init.h>
7*aeeb85f2STakashi Iwai #include <linux/module.h>
8*aeeb85f2STakashi Iwai #include "realtek.h"
9*aeeb85f2STakashi Iwai 
10*aeeb85f2STakashi Iwai static int alc262_parse_auto_config(struct hda_codec *codec)
11*aeeb85f2STakashi Iwai {
12*aeeb85f2STakashi Iwai 	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
13*aeeb85f2STakashi Iwai 	static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
14*aeeb85f2STakashi Iwai 	return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
15*aeeb85f2STakashi Iwai }
16*aeeb85f2STakashi Iwai 
17*aeeb85f2STakashi Iwai /*
18*aeeb85f2STakashi Iwai  * Pin config fixes
19*aeeb85f2STakashi Iwai  */
20*aeeb85f2STakashi Iwai enum {
21*aeeb85f2STakashi Iwai 	ALC262_FIXUP_FSC_H270,
22*aeeb85f2STakashi Iwai 	ALC262_FIXUP_FSC_S7110,
23*aeeb85f2STakashi Iwai 	ALC262_FIXUP_HP_Z200,
24*aeeb85f2STakashi Iwai 	ALC262_FIXUP_TYAN,
25*aeeb85f2STakashi Iwai 	ALC262_FIXUP_LENOVO_3000,
26*aeeb85f2STakashi Iwai 	ALC262_FIXUP_BENQ,
27*aeeb85f2STakashi Iwai 	ALC262_FIXUP_BENQ_T31,
28*aeeb85f2STakashi Iwai 	ALC262_FIXUP_INV_DMIC,
29*aeeb85f2STakashi Iwai 	ALC262_FIXUP_INTEL_BAYLEYBAY,
30*aeeb85f2STakashi Iwai };
31*aeeb85f2STakashi Iwai 
32*aeeb85f2STakashi Iwai static const struct hda_fixup alc262_fixups[] = {
33*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_FSC_H270] = {
34*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_PINS,
35*aeeb85f2STakashi Iwai 		.v.pins = (const struct hda_pintbl[]) {
36*aeeb85f2STakashi Iwai 			{ 0x14, 0x99130110 }, /* speaker */
37*aeeb85f2STakashi Iwai 			{ 0x15, 0x0221142f }, /* front HP */
38*aeeb85f2STakashi Iwai 			{ 0x1b, 0x0121141f }, /* rear HP */
39*aeeb85f2STakashi Iwai 			{ }
40*aeeb85f2STakashi Iwai 		}
41*aeeb85f2STakashi Iwai 	},
42*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_FSC_S7110] = {
43*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_PINS,
44*aeeb85f2STakashi Iwai 		.v.pins = (const struct hda_pintbl[]) {
45*aeeb85f2STakashi Iwai 			{ 0x15, 0x90170110 }, /* speaker */
46*aeeb85f2STakashi Iwai 			{ }
47*aeeb85f2STakashi Iwai 		},
48*aeeb85f2STakashi Iwai 		.chained = true,
49*aeeb85f2STakashi Iwai 		.chain_id = ALC262_FIXUP_BENQ,
50*aeeb85f2STakashi Iwai 	},
51*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_HP_Z200] = {
52*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_PINS,
53*aeeb85f2STakashi Iwai 		.v.pins = (const struct hda_pintbl[]) {
54*aeeb85f2STakashi Iwai 			{ 0x16, 0x99130120 }, /* internal speaker */
55*aeeb85f2STakashi Iwai 			{ }
56*aeeb85f2STakashi Iwai 		}
57*aeeb85f2STakashi Iwai 	},
58*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_TYAN] = {
59*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_PINS,
60*aeeb85f2STakashi Iwai 		.v.pins = (const struct hda_pintbl[]) {
61*aeeb85f2STakashi Iwai 			{ 0x14, 0x1993e1f0 }, /* int AUX */
62*aeeb85f2STakashi Iwai 			{ }
63*aeeb85f2STakashi Iwai 		}
64*aeeb85f2STakashi Iwai 	},
65*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_LENOVO_3000] = {
66*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_PINCTLS,
67*aeeb85f2STakashi Iwai 		.v.pins = (const struct hda_pintbl[]) {
68*aeeb85f2STakashi Iwai 			{ 0x19, PIN_VREF50 },
69*aeeb85f2STakashi Iwai 			{}
70*aeeb85f2STakashi Iwai 		},
71*aeeb85f2STakashi Iwai 		.chained = true,
72*aeeb85f2STakashi Iwai 		.chain_id = ALC262_FIXUP_BENQ,
73*aeeb85f2STakashi Iwai 	},
74*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_BENQ] = {
75*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_VERBS,
76*aeeb85f2STakashi Iwai 		.v.verbs = (const struct hda_verb[]) {
77*aeeb85f2STakashi Iwai 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
78*aeeb85f2STakashi Iwai 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
79*aeeb85f2STakashi Iwai 			{}
80*aeeb85f2STakashi Iwai 		}
81*aeeb85f2STakashi Iwai 	},
82*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_BENQ_T31] = {
83*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_VERBS,
84*aeeb85f2STakashi Iwai 		.v.verbs = (const struct hda_verb[]) {
85*aeeb85f2STakashi Iwai 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
86*aeeb85f2STakashi Iwai 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
87*aeeb85f2STakashi Iwai 			{}
88*aeeb85f2STakashi Iwai 		}
89*aeeb85f2STakashi Iwai 	},
90*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_INV_DMIC] = {
91*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_FUNC,
92*aeeb85f2STakashi Iwai 		.v.func = alc_fixup_inv_dmic,
93*aeeb85f2STakashi Iwai 	},
94*aeeb85f2STakashi Iwai 	[ALC262_FIXUP_INTEL_BAYLEYBAY] = {
95*aeeb85f2STakashi Iwai 		.type = HDA_FIXUP_FUNC,
96*aeeb85f2STakashi Iwai 		.v.func = alc_fixup_no_depop_delay,
97*aeeb85f2STakashi Iwai 	},
98*aeeb85f2STakashi Iwai };
99*aeeb85f2STakashi Iwai 
100*aeeb85f2STakashi Iwai static const struct hda_quirk alc262_fixup_tbl[] = {
101*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
102*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
103*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
104*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
105*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
106*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
107*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
108*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
109*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
110*aeeb85f2STakashi Iwai 	SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
111*aeeb85f2STakashi Iwai 	{}
112*aeeb85f2STakashi Iwai };
113*aeeb85f2STakashi Iwai 
114*aeeb85f2STakashi Iwai static const struct hda_model_fixup alc262_fixup_models[] = {
115*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
116*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
117*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
118*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
119*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_TYAN, .name = "tyan"},
120*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
121*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_BENQ, .name = "benq"},
122*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
123*aeeb85f2STakashi Iwai 	{.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
124*aeeb85f2STakashi Iwai 	{}
125*aeeb85f2STakashi Iwai };
126*aeeb85f2STakashi Iwai 
127*aeeb85f2STakashi Iwai /*
128*aeeb85f2STakashi Iwai  */
129*aeeb85f2STakashi Iwai static int patch_alc262(struct hda_codec *codec)
130*aeeb85f2STakashi Iwai {
131*aeeb85f2STakashi Iwai 	struct alc_spec *spec;
132*aeeb85f2STakashi Iwai 	int err;
133*aeeb85f2STakashi Iwai 
134*aeeb85f2STakashi Iwai 	err = alc_alloc_spec(codec, 0x0b);
135*aeeb85f2STakashi Iwai 	if (err < 0)
136*aeeb85f2STakashi Iwai 		return err;
137*aeeb85f2STakashi Iwai 
138*aeeb85f2STakashi Iwai 	spec = codec->spec;
139*aeeb85f2STakashi Iwai 	spec->gen.shared_mic_vref_pin = 0x18;
140*aeeb85f2STakashi Iwai 
141*aeeb85f2STakashi Iwai 	spec->shutup = alc_eapd_shutup;
142*aeeb85f2STakashi Iwai 
143*aeeb85f2STakashi Iwai #if 0
144*aeeb85f2STakashi Iwai 	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
145*aeeb85f2STakashi Iwai 	 * under-run
146*aeeb85f2STakashi Iwai 	 */
147*aeeb85f2STakashi Iwai 	alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
148*aeeb85f2STakashi Iwai #endif
149*aeeb85f2STakashi Iwai 	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
150*aeeb85f2STakashi Iwai 
151*aeeb85f2STakashi Iwai 	alc_pre_init(codec);
152*aeeb85f2STakashi Iwai 
153*aeeb85f2STakashi Iwai 	snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
154*aeeb85f2STakashi Iwai 		       alc262_fixups);
155*aeeb85f2STakashi Iwai 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
156*aeeb85f2STakashi Iwai 
157*aeeb85f2STakashi Iwai 	alc_auto_parse_customize_define(codec);
158*aeeb85f2STakashi Iwai 
159*aeeb85f2STakashi Iwai 	if (has_cdefine_beep(codec))
160*aeeb85f2STakashi Iwai 		spec->gen.beep_nid = 0x01;
161*aeeb85f2STakashi Iwai 
162*aeeb85f2STakashi Iwai 	/* automatic parse from the BIOS config */
163*aeeb85f2STakashi Iwai 	err = alc262_parse_auto_config(codec);
164*aeeb85f2STakashi Iwai 	if (err < 0)
165*aeeb85f2STakashi Iwai 		goto error;
166*aeeb85f2STakashi Iwai 
167*aeeb85f2STakashi Iwai 	if (!spec->gen.no_analog && spec->gen.beep_nid) {
168*aeeb85f2STakashi Iwai 		err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
169*aeeb85f2STakashi Iwai 		if (err < 0)
170*aeeb85f2STakashi Iwai 			goto error;
171*aeeb85f2STakashi Iwai 	}
172*aeeb85f2STakashi Iwai 
173*aeeb85f2STakashi Iwai 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
174*aeeb85f2STakashi Iwai 
175*aeeb85f2STakashi Iwai 	return 0;
176*aeeb85f2STakashi Iwai 
177*aeeb85f2STakashi Iwai  error:
178*aeeb85f2STakashi Iwai 	alc_free(codec);
179*aeeb85f2STakashi Iwai 	return err;
180*aeeb85f2STakashi Iwai }
181*aeeb85f2STakashi Iwai 
182*aeeb85f2STakashi Iwai /*
183*aeeb85f2STakashi Iwai  * driver entries
184*aeeb85f2STakashi Iwai  */
185*aeeb85f2STakashi Iwai static const struct hda_device_id snd_hda_id_alc262[] = {
186*aeeb85f2STakashi Iwai 	HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
187*aeeb85f2STakashi Iwai 	{} /* terminator */
188*aeeb85f2STakashi Iwai };
189*aeeb85f2STakashi Iwai MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc262);
190*aeeb85f2STakashi Iwai 
191*aeeb85f2STakashi Iwai MODULE_LICENSE("GPL");
192*aeeb85f2STakashi Iwai MODULE_DESCRIPTION("Realtek ALC262 HD-audio codec");
193*aeeb85f2STakashi Iwai MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
194*aeeb85f2STakashi Iwai 
195*aeeb85f2STakashi Iwai static struct hda_codec_driver alc262_driver = {
196*aeeb85f2STakashi Iwai 	.id = snd_hda_id_alc262,
197*aeeb85f2STakashi Iwai };
198*aeeb85f2STakashi Iwai 
199*aeeb85f2STakashi Iwai module_hda_codec_driver(alc262_driver);
200