File Index
Files and directories
Sign in
FILE

alc880.c

File preview with syntax highlighting.

linux-6.19.14/sound/hda/codecs/realtek/alc880.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2//
  3// Realtek ALC880 codec
  4//
  5
  6#include <linux/init.h>
  7#include <linux/module.h>
  8#include "realtek.h"
  9
 10static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
 11{
 12	/* For some reason, the res given from ALC880 is broken.
 13	   Here we adjust it properly. */
 14	snd_hda_jack_unsol_event(codec, res >> 2);
 15}
 16
 17static int alc880_parse_auto_config(struct hda_codec *codec)
 18{
 19	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
 20	static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
 21	return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
 22}
 23
 24/*
 25 * ALC880 fix-ups
 26 */
 27enum {
 28	ALC880_FIXUP_GPIO1,
 29	ALC880_FIXUP_GPIO2,
 30	ALC880_FIXUP_MEDION_RIM,
 31	ALC880_FIXUP_LG,
 32	ALC880_FIXUP_LG_LW25,
 33	ALC880_FIXUP_W810,
 34	ALC880_FIXUP_EAPD_COEF,
 35	ALC880_FIXUP_TCL_S700,
 36	ALC880_FIXUP_VOL_KNOB,
 37	ALC880_FIXUP_FUJITSU,
 38	ALC880_FIXUP_F1734,
 39	ALC880_FIXUP_UNIWILL,
 40	ALC880_FIXUP_UNIWILL_DIG,
 41	ALC880_FIXUP_Z71V,
 42	ALC880_FIXUP_ASUS_W5A,
 43	ALC880_FIXUP_3ST_BASE,
 44	ALC880_FIXUP_3ST,
 45	ALC880_FIXUP_3ST_DIG,
 46	ALC880_FIXUP_5ST_BASE,
 47	ALC880_FIXUP_5ST,
 48	ALC880_FIXUP_5ST_DIG,
 49	ALC880_FIXUP_6ST_BASE,
 50	ALC880_FIXUP_6ST,
 51	ALC880_FIXUP_6ST_DIG,
 52	ALC880_FIXUP_6ST_AUTOMUTE,
 53};
 54
 55/* enable the volume-knob widget support on NID 0x21 */
 56static void alc880_fixup_vol_knob(struct hda_codec *codec,
 57				  const struct hda_fixup *fix, int action)
 58{
 59	if (action == HDA_FIXUP_ACT_PROBE)
 60		snd_hda_jack_detect_enable_callback(codec, 0x21,
 61						    alc_update_knob_master);
 62}
 63
 64static const struct hda_fixup alc880_fixups[] = {
 65	[ALC880_FIXUP_GPIO1] = {
 66		.type = HDA_FIXUP_FUNC,
 67		.v.func = alc_fixup_gpio1,
 68	},
 69	[ALC880_FIXUP_GPIO2] = {
 70		.type = HDA_FIXUP_FUNC,
 71		.v.func = alc_fixup_gpio2,
 72	},
 73	[ALC880_FIXUP_MEDION_RIM] = {
 74		.type = HDA_FIXUP_VERBS,
 75		.v.verbs = (const struct hda_verb[]) {
 76			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
 77			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
 78			{ }
 79		},
 80		.chained = true,
 81		.chain_id = ALC880_FIXUP_GPIO2,
 82	},
 83	[ALC880_FIXUP_LG] = {
 84		.type = HDA_FIXUP_PINS,
 85		.v.pins = (const struct hda_pintbl[]) {
 86			/* disable bogus unused pins */
 87			{ 0x16, 0x411111f0 },
 88			{ 0x18, 0x411111f0 },
 89			{ 0x1a, 0x411111f0 },
 90			{ }
 91		}
 92	},
 93	[ALC880_FIXUP_LG_LW25] = {
 94		.type = HDA_FIXUP_PINS,
 95		.v.pins = (const struct hda_pintbl[]) {
 96			{ 0x1a, 0x0181344f }, /* line-in */
 97			{ 0x1b, 0x0321403f }, /* headphone */
 98			{ }
 99		}
100	},
101	[ALC880_FIXUP_W810] = {
102		.type = HDA_FIXUP_PINS,
103		.v.pins = (const struct hda_pintbl[]) {
104			/* disable bogus unused pins */
105			{ 0x17, 0x411111f0 },
106			{ }
107		},
108		.chained = true,
109		.chain_id = ALC880_FIXUP_GPIO2,
110	},
111	[ALC880_FIXUP_EAPD_COEF] = {
112		.type = HDA_FIXUP_VERBS,
113		.v.verbs = (const struct hda_verb[]) {
114			/* change to EAPD mode */
115			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
116			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
117			{}
118		},
119	},
120	[ALC880_FIXUP_TCL_S700] = {
121		.type = HDA_FIXUP_VERBS,
122		.v.verbs = (const struct hda_verb[]) {
123			/* change to EAPD mode */
124			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
125			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
126			{}
127		},
128		.chained = true,
129		.chain_id = ALC880_FIXUP_GPIO2,
130	},
131	[ALC880_FIXUP_VOL_KNOB] = {
132		.type = HDA_FIXUP_FUNC,
133		.v.func = alc880_fixup_vol_knob,
134	},
135	[ALC880_FIXUP_FUJITSU] = {
136		/* override all pins as BIOS on old Amilo is broken */
137		.type = HDA_FIXUP_PINS,
138		.v.pins = (const struct hda_pintbl[]) {
139			{ 0x14, 0x0121401f }, /* HP */
140			{ 0x15, 0x99030120 }, /* speaker */
141			{ 0x16, 0x99030130 }, /* bass speaker */
142			{ 0x17, 0x411111f0 }, /* N/A */
143			{ 0x18, 0x411111f0 }, /* N/A */
144			{ 0x19, 0x01a19950 }, /* mic-in */
145			{ 0x1a, 0x411111f0 }, /* N/A */
146			{ 0x1b, 0x411111f0 }, /* N/A */
147			{ 0x1c, 0x411111f0 }, /* N/A */
148			{ 0x1d, 0x411111f0 }, /* N/A */
149			{ 0x1e, 0x01454140 }, /* SPDIF out */
150			{ }
151		},
152		.chained = true,
153		.chain_id = ALC880_FIXUP_VOL_KNOB,
154	},
155	[ALC880_FIXUP_F1734] = {
156		/* almost compatible with FUJITSU, but no bass and SPDIF */
157		.type = HDA_FIXUP_PINS,
158		.v.pins = (const struct hda_pintbl[]) {
159			{ 0x14, 0x0121401f }, /* HP */
160			{ 0x15, 0x99030120 }, /* speaker */
161			{ 0x16, 0x411111f0 }, /* N/A */
162			{ 0x17, 0x411111f0 }, /* N/A */
163			{ 0x18, 0x411111f0 }, /* N/A */
164			{ 0x19, 0x01a19950 }, /* mic-in */
165			{ 0x1a, 0x411111f0 }, /* N/A */
166			{ 0x1b, 0x411111f0 }, /* N/A */
167			{ 0x1c, 0x411111f0 }, /* N/A */
168			{ 0x1d, 0x411111f0 }, /* N/A */
169			{ 0x1e, 0x411111f0 }, /* N/A */
170			{ }
171		},
172		.chained = true,
173		.chain_id = ALC880_FIXUP_VOL_KNOB,
174	},
175	[ALC880_FIXUP_UNIWILL] = {
176		/* need to fix HP and speaker pins to be parsed correctly */
177		.type = HDA_FIXUP_PINS,
178		.v.pins = (const struct hda_pintbl[]) {
179			{ 0x14, 0x0121411f }, /* HP */
180			{ 0x15, 0x99030120 }, /* speaker */
181			{ 0x16, 0x99030130 }, /* bass speaker */
182			{ }
183		},
184	},
185	[ALC880_FIXUP_UNIWILL_DIG] = {
186		.type = HDA_FIXUP_PINS,
187		.v.pins = (const struct hda_pintbl[]) {
188			/* disable bogus unused pins */
189			{ 0x17, 0x411111f0 },
190			{ 0x19, 0x411111f0 },
191			{ 0x1b, 0x411111f0 },
192			{ 0x1f, 0x411111f0 },
193			{ }
194		}
195	},
196	[ALC880_FIXUP_Z71V] = {
197		.type = HDA_FIXUP_PINS,
198		.v.pins = (const struct hda_pintbl[]) {
199			/* set up the whole pins as BIOS is utterly broken */
200			{ 0x14, 0x99030120 }, /* speaker */
201			{ 0x15, 0x0121411f }, /* HP */
202			{ 0x16, 0x411111f0 }, /* N/A */
203			{ 0x17, 0x411111f0 }, /* N/A */
204			{ 0x18, 0x01a19950 }, /* mic-in */
205			{ 0x19, 0x411111f0 }, /* N/A */
206			{ 0x1a, 0x01813031 }, /* line-in */
207			{ 0x1b, 0x411111f0 }, /* N/A */
208			{ 0x1c, 0x411111f0 }, /* N/A */
209			{ 0x1d, 0x411111f0 }, /* N/A */
210			{ 0x1e, 0x0144111e }, /* SPDIF */
211			{ }
212		}
213	},
214	[ALC880_FIXUP_ASUS_W5A] = {
215		.type = HDA_FIXUP_PINS,
216		.v.pins = (const struct hda_pintbl[]) {
217			/* set up the whole pins as BIOS is utterly broken */
218			{ 0x14, 0x0121411f }, /* HP */
219			{ 0x15, 0x411111f0 }, /* N/A */
220			{ 0x16, 0x411111f0 }, /* N/A */
221			{ 0x17, 0x411111f0 }, /* N/A */
222			{ 0x18, 0x90a60160 }, /* mic */
223			{ 0x19, 0x411111f0 }, /* N/A */
224			{ 0x1a, 0x411111f0 }, /* N/A */
225			{ 0x1b, 0x411111f0 }, /* N/A */
226			{ 0x1c, 0x411111f0 }, /* N/A */
227			{ 0x1d, 0x411111f0 }, /* N/A */
228			{ 0x1e, 0xb743111e }, /* SPDIF out */
229			{ }
230		},
231		.chained = true,
232		.chain_id = ALC880_FIXUP_GPIO1,
233	},
234	[ALC880_FIXUP_3ST_BASE] = {
235		.type = HDA_FIXUP_PINS,
236		.v.pins = (const struct hda_pintbl[]) {
237			{ 0x14, 0x01014010 }, /* line-out */
238			{ 0x15, 0x411111f0 }, /* N/A */
239			{ 0x16, 0x411111f0 }, /* N/A */
240			{ 0x17, 0x411111f0 }, /* N/A */
241			{ 0x18, 0x01a19c30 }, /* mic-in */
242			{ 0x19, 0x0121411f }, /* HP */
243			{ 0x1a, 0x01813031 }, /* line-in */
244			{ 0x1b, 0x02a19c40 }, /* front-mic */
245			{ 0x1c, 0x411111f0 }, /* N/A */
246			{ 0x1d, 0x411111f0 }, /* N/A */
247			/* 0x1e is filled in below */
248			{ 0x1f, 0x411111f0 }, /* N/A */
249			{ }
250		}
251	},
252	[ALC880_FIXUP_3ST] = {
253		.type = HDA_FIXUP_PINS,
254		.v.pins = (const struct hda_pintbl[]) {
255			{ 0x1e, 0x411111f0 }, /* N/A */
256			{ }
257		},
258		.chained = true,
259		.chain_id = ALC880_FIXUP_3ST_BASE,
260	},
261	[ALC880_FIXUP_3ST_DIG] = {
262		.type = HDA_FIXUP_PINS,
263		.v.pins = (const struct hda_pintbl[]) {
264			{ 0x1e, 0x0144111e }, /* SPDIF */
265			{ }
266		},
267		.chained = true,
268		.chain_id = ALC880_FIXUP_3ST_BASE,
269	},
270	[ALC880_FIXUP_5ST_BASE] = {
271		.type = HDA_FIXUP_PINS,
272		.v.pins = (const struct hda_pintbl[]) {
273			{ 0x14, 0x01014010 }, /* front */
274			{ 0x15, 0x411111f0 }, /* N/A */
275			{ 0x16, 0x01011411 }, /* CLFE */
276			{ 0x17, 0x01016412 }, /* surr */
277			{ 0x18, 0x01a19c30 }, /* mic-in */
278			{ 0x19, 0x0121411f }, /* HP */
279			{ 0x1a, 0x01813031 }, /* line-in */
280			{ 0x1b, 0x02a19c40 }, /* front-mic */
281			{ 0x1c, 0x411111f0 }, /* N/A */
282			{ 0x1d, 0x411111f0 }, /* N/A */
283			/* 0x1e is filled in below */
284			{ 0x1f, 0x411111f0 }, /* N/A */
285			{ }
286		}
287	},
288	[ALC880_FIXUP_5ST] = {
289		.type = HDA_FIXUP_PINS,
290		.v.pins = (const struct hda_pintbl[]) {
291			{ 0x1e, 0x411111f0 }, /* N/A */
292			{ }
293		},
294		.chained = true,
295		.chain_id = ALC880_FIXUP_5ST_BASE,
296	},
297	[ALC880_FIXUP_5ST_DIG] = {
298		.type = HDA_FIXUP_PINS,
299		.v.pins = (const struct hda_pintbl[]) {
300			{ 0x1e, 0x0144111e }, /* SPDIF */
301			{ }
302		},
303		.chained = true,
304		.chain_id = ALC880_FIXUP_5ST_BASE,
305	},
306	[ALC880_FIXUP_6ST_BASE] = {
307		.type = HDA_FIXUP_PINS,
308		.v.pins = (const struct hda_pintbl[]) {
309			{ 0x14, 0x01014010 }, /* front */
310			{ 0x15, 0x01016412 }, /* surr */
311			{ 0x16, 0x01011411 }, /* CLFE */
312			{ 0x17, 0x01012414 }, /* side */
313			{ 0x18, 0x01a19c30 }, /* mic-in */
314			{ 0x19, 0x02a19c40 }, /* front-mic */
315			{ 0x1a, 0x01813031 }, /* line-in */
316			{ 0x1b, 0x0121411f }, /* HP */
317			{ 0x1c, 0x411111f0 }, /* N/A */
318			{ 0x1d, 0x411111f0 }, /* N/A */
319			/* 0x1e is filled in below */
320			{ 0x1f, 0x411111f0 }, /* N/A */
321			{ }
322		}
323	},
324	[ALC880_FIXUP_6ST] = {
325		.type = HDA_FIXUP_PINS,
326		.v.pins = (const struct hda_pintbl[]) {
327			{ 0x1e, 0x411111f0 }, /* N/A */
328			{ }
329		},
330		.chained = true,
331		.chain_id = ALC880_FIXUP_6ST_BASE,
332	},
333	[ALC880_FIXUP_6ST_DIG] = {
334		.type = HDA_FIXUP_PINS,
335		.v.pins = (const struct hda_pintbl[]) {
336			{ 0x1e, 0x0144111e }, /* SPDIF */
337			{ }
338		},
339		.chained = true,
340		.chain_id = ALC880_FIXUP_6ST_BASE,
341	},
342	[ALC880_FIXUP_6ST_AUTOMUTE] = {
343		.type = HDA_FIXUP_PINS,
344		.v.pins = (const struct hda_pintbl[]) {
345			{ 0x1b, 0x0121401f }, /* HP with jack detect */
346			{ }
347		},
348		.chained_before = true,
349		.chain_id = ALC880_FIXUP_6ST_BASE,
350	},
351};
352
353static const struct hda_quirk alc880_fixup_tbl[] = {
354	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
355	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
356	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
357	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
358	SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
359	SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
360	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
361	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
362	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
363	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
364	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
365	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
366	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
367	SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
368	SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
369	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
370	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
371	SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
372	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
373	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
374	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
375	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
376	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
377
378	/* Below is the copied entries from alc880_quirks.c.
379	 * It's not quite sure whether BIOS sets the correct pin-config table
380	 * on these machines, thus they are kept to be compatible with
381	 * the old static quirks.  Once when it's confirmed to work without
382	 * these overrides, it'd be better to remove.
383	 */
384	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
385	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
386	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
387	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
388	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
389	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
390	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
391	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
392	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
393	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
394	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
395	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
396	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
397	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
398	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
399	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
400	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
401	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
402	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
403	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
404	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
405	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
406	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
407	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
408	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
409	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
410	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
411	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
412	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
413	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
414	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
415	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
416	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
417	/* default Intel */
418	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
419	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
420	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
421	{}
422};
423
424static const struct hda_model_fixup alc880_fixup_models[] = {
425	{.id = ALC880_FIXUP_3ST, .name = "3stack"},
426	{.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
427	{.id = ALC880_FIXUP_5ST, .name = "5stack"},
428	{.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
429	{.id = ALC880_FIXUP_6ST, .name = "6stack"},
430	{.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
431	{.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
432	{}
433};
434
435
436/*
437 * OK, here we have finally the probe for ALC880
438 */
439static int alc880_probe(struct hda_codec *codec, const struct hda_device_id *id)
440{
441	struct alc_spec *spec;
442	int err;
443
444	err = alc_alloc_spec(codec, 0x0b);
445	if (err < 0)
446		return err;
447
448	spec = codec->spec;
449	spec->gen.need_dac_fix = 1;
450	spec->gen.beep_nid = 0x01;
451
452	alc_pre_init(codec);
453
454	snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
455		       alc880_fixups);
456	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
457
458	/* automatic parse from the BIOS config */
459	err = alc880_parse_auto_config(codec);
460	if (err < 0)
461		goto error;
462
463	if (!spec->gen.no_analog) {
464		err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
465		if (err < 0)
466			goto error;
467	}
468
469	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
470
471	return 0;
472
473 error:
474	snd_hda_gen_remove(codec);
475	return err;
476}
477
478static const struct hda_codec_ops alc880_codec_ops = {
479	.probe = alc880_probe,
480	.remove = snd_hda_gen_remove,
481	.build_controls = alc_build_controls,
482	.build_pcms = snd_hda_gen_build_pcms,
483	.init = alc_init,
484	.unsol_event = alc880_unsol_event,
485	.resume = alc_resume,
486	.suspend = alc_suspend,
487	.check_power_status = snd_hda_gen_check_power_status,
488	.stream_pm = snd_hda_gen_stream_pm,
489};
490
491/*
492 * driver entries
493 */
494static const struct hda_device_id snd_hda_id_alc880[] = {
495	HDA_CODEC_ID(0x10ec0880, "ALC880"),
496	{} /* terminator */
497};
498MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc880);
499
500MODULE_LICENSE("GPL");
501MODULE_DESCRIPTION("Realtek ALC880 HD-audio codec");
502MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
503
504static struct hda_codec_driver alc880_driver = {
505	.id = snd_hda_id_alc880,
506	.ops = &alc880_codec_ops,
507};
508
509module_hda_codec_driver(alc880_driver);
~/ Read-only file preview.