Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/hda/codecs/realtek/alc880.c
26530 views
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
10
static 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
17
static 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
*/
27
enum {
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 */
56
static 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
64
static 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
353
static 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
424
static 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
*/
439
static 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
478
static 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
*/
494
static const struct hda_device_id snd_hda_id_alc880[] = {
495
HDA_CODEC_ID(0x10ec0880, "ALC880"),
496
{} /* terminator */
497
};
498
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc880);
499
500
MODULE_LICENSE("GPL");
501
MODULE_DESCRIPTION("Realtek ALC880 HD-audio codec");
502
MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
503
504
static struct hda_codec_driver alc880_driver = {
505
.id = snd_hda_id_alc880,
506
.ops = &alc880_codec_ops,
507
};
508
509
module_hda_codec_driver(alc880_driver);
510
511