Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/hda/codecs/realtek/alc260.c
26530 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
//
3
// Realtek ALC260 codec
4
//
5
6
#include <linux/init.h>
7
#include <linux/module.h>
8
#include "realtek.h"
9
10
static int alc260_parse_auto_config(struct hda_codec *codec)
11
{
12
static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
13
static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
14
return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
15
}
16
17
/*
18
* Pin config fixes
19
*/
20
enum {
21
ALC260_FIXUP_HP_DC5750,
22
ALC260_FIXUP_HP_PIN_0F,
23
ALC260_FIXUP_COEF,
24
ALC260_FIXUP_GPIO1,
25
ALC260_FIXUP_GPIO1_TOGGLE,
26
ALC260_FIXUP_REPLACER,
27
ALC260_FIXUP_HP_B1900,
28
ALC260_FIXUP_KN1,
29
ALC260_FIXUP_FSC_S7020,
30
ALC260_FIXUP_FSC_S7020_JWSE,
31
ALC260_FIXUP_VAIO_PINS,
32
};
33
34
static void alc260_gpio1_automute(struct hda_codec *codec)
35
{
36
struct alc_spec *spec = codec->spec;
37
38
alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
39
}
40
41
static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
42
const struct hda_fixup *fix, int action)
43
{
44
struct alc_spec *spec = codec->spec;
45
if (action == HDA_FIXUP_ACT_PROBE) {
46
/* although the machine has only one output pin, we need to
47
* toggle GPIO1 according to the jack state
48
*/
49
spec->gen.automute_hook = alc260_gpio1_automute;
50
spec->gen.detect_hp = 1;
51
spec->gen.automute_speaker = 1;
52
spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
53
snd_hda_jack_detect_enable_callback(codec, 0x0f,
54
snd_hda_gen_hp_automute);
55
alc_setup_gpio(codec, 0x01);
56
}
57
}
58
59
static void alc260_fixup_kn1(struct hda_codec *codec,
60
const struct hda_fixup *fix, int action)
61
{
62
struct alc_spec *spec = codec->spec;
63
static const struct hda_pintbl pincfgs[] = {
64
{ 0x0f, 0x02214000 }, /* HP/speaker */
65
{ 0x12, 0x90a60160 }, /* int mic */
66
{ 0x13, 0x02a19000 }, /* ext mic */
67
{ 0x18, 0x01446000 }, /* SPDIF out */
68
/* disable bogus I/O pins */
69
{ 0x10, 0x411111f0 },
70
{ 0x11, 0x411111f0 },
71
{ 0x14, 0x411111f0 },
72
{ 0x15, 0x411111f0 },
73
{ 0x16, 0x411111f0 },
74
{ 0x17, 0x411111f0 },
75
{ 0x19, 0x411111f0 },
76
{ }
77
};
78
79
switch (action) {
80
case HDA_FIXUP_ACT_PRE_PROBE:
81
snd_hda_apply_pincfgs(codec, pincfgs);
82
spec->init_amp = ALC_INIT_NONE;
83
break;
84
}
85
}
86
87
static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
88
const struct hda_fixup *fix, int action)
89
{
90
struct alc_spec *spec = codec->spec;
91
if (action == HDA_FIXUP_ACT_PRE_PROBE)
92
spec->init_amp = ALC_INIT_NONE;
93
}
94
95
static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
96
const struct hda_fixup *fix, int action)
97
{
98
struct alc_spec *spec = codec->spec;
99
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
100
spec->gen.add_jack_modes = 1;
101
spec->gen.hp_mic = 1;
102
}
103
}
104
105
static const struct hda_fixup alc260_fixups[] = {
106
[ALC260_FIXUP_HP_DC5750] = {
107
.type = HDA_FIXUP_PINS,
108
.v.pins = (const struct hda_pintbl[]) {
109
{ 0x11, 0x90130110 }, /* speaker */
110
{ }
111
}
112
},
113
[ALC260_FIXUP_HP_PIN_0F] = {
114
.type = HDA_FIXUP_PINS,
115
.v.pins = (const struct hda_pintbl[]) {
116
{ 0x0f, 0x01214000 }, /* HP */
117
{ }
118
}
119
},
120
[ALC260_FIXUP_COEF] = {
121
.type = HDA_FIXUP_VERBS,
122
.v.verbs = (const struct hda_verb[]) {
123
{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
124
{ 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
125
{ }
126
},
127
},
128
[ALC260_FIXUP_GPIO1] = {
129
.type = HDA_FIXUP_FUNC,
130
.v.func = alc_fixup_gpio1,
131
},
132
[ALC260_FIXUP_GPIO1_TOGGLE] = {
133
.type = HDA_FIXUP_FUNC,
134
.v.func = alc260_fixup_gpio1_toggle,
135
.chained = true,
136
.chain_id = ALC260_FIXUP_HP_PIN_0F,
137
},
138
[ALC260_FIXUP_REPLACER] = {
139
.type = HDA_FIXUP_VERBS,
140
.v.verbs = (const struct hda_verb[]) {
141
{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
142
{ 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
143
{ }
144
},
145
.chained = true,
146
.chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
147
},
148
[ALC260_FIXUP_HP_B1900] = {
149
.type = HDA_FIXUP_FUNC,
150
.v.func = alc260_fixup_gpio1_toggle,
151
.chained = true,
152
.chain_id = ALC260_FIXUP_COEF,
153
},
154
[ALC260_FIXUP_KN1] = {
155
.type = HDA_FIXUP_FUNC,
156
.v.func = alc260_fixup_kn1,
157
},
158
[ALC260_FIXUP_FSC_S7020] = {
159
.type = HDA_FIXUP_FUNC,
160
.v.func = alc260_fixup_fsc_s7020,
161
},
162
[ALC260_FIXUP_FSC_S7020_JWSE] = {
163
.type = HDA_FIXUP_FUNC,
164
.v.func = alc260_fixup_fsc_s7020_jwse,
165
.chained = true,
166
.chain_id = ALC260_FIXUP_FSC_S7020,
167
},
168
[ALC260_FIXUP_VAIO_PINS] = {
169
.type = HDA_FIXUP_PINS,
170
.v.pins = (const struct hda_pintbl[]) {
171
/* Pin configs are missing completely on some VAIOs */
172
{ 0x0f, 0x01211020 },
173
{ 0x10, 0x0001003f },
174
{ 0x11, 0x411111f0 },
175
{ 0x12, 0x01a15930 },
176
{ 0x13, 0x411111f0 },
177
{ 0x14, 0x411111f0 },
178
{ 0x15, 0x411111f0 },
179
{ 0x16, 0x411111f0 },
180
{ 0x17, 0x411111f0 },
181
{ 0x18, 0x411111f0 },
182
{ 0x19, 0x411111f0 },
183
{ }
184
}
185
},
186
};
187
188
static const struct hda_quirk alc260_fixup_tbl[] = {
189
SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
190
SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
191
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
192
SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
193
SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
194
SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
195
SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
196
SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
197
SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
198
SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
199
SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
200
SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
201
{}
202
};
203
204
static const struct hda_model_fixup alc260_fixup_models[] = {
205
{.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
206
{.id = ALC260_FIXUP_COEF, .name = "coef"},
207
{.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
208
{.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
209
{}
210
};
211
212
/*
213
*/
214
static int alc260_probe(struct hda_codec *codec, const struct hda_device_id *id)
215
{
216
struct alc_spec *spec;
217
int err;
218
219
err = alc_alloc_spec(codec, 0x07);
220
if (err < 0)
221
return err;
222
223
spec = codec->spec;
224
/* as quite a few machines require HP amp for speaker outputs,
225
* it's easier to enable it unconditionally; even if it's unneeded,
226
* it's almost harmless.
227
*/
228
spec->gen.prefer_hp_amp = 1;
229
spec->gen.beep_nid = 0x01;
230
231
spec->shutup = alc_eapd_shutup;
232
233
alc_pre_init(codec);
234
235
snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
236
alc260_fixups);
237
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
238
239
/* automatic parse from the BIOS config */
240
err = alc260_parse_auto_config(codec);
241
if (err < 0)
242
goto error;
243
244
if (!spec->gen.no_analog) {
245
err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
246
if (err < 0)
247
goto error;
248
}
249
250
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
251
252
return 0;
253
254
error:
255
snd_hda_gen_remove(codec);
256
return err;
257
}
258
259
static const struct hda_codec_ops alc260_codec_ops = {
260
.probe = alc260_probe,
261
.remove = snd_hda_gen_remove,
262
.build_controls = alc_build_controls,
263
.build_pcms = snd_hda_gen_build_pcms,
264
.init = alc_init,
265
.unsol_event = snd_hda_jack_unsol_event,
266
.resume = alc_resume,
267
.suspend = alc_suspend,
268
.check_power_status = snd_hda_gen_check_power_status,
269
.stream_pm = snd_hda_gen_stream_pm,
270
};
271
272
/*
273
* driver entries
274
*/
275
static const struct hda_device_id snd_hda_id_alc260[] = {
276
HDA_CODEC_ID(0x10ec0260, "ALC260"),
277
{} /* terminator */
278
};
279
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc260);
280
281
MODULE_LICENSE("GPL");
282
MODULE_DESCRIPTION("Realtek ALC260 HD-audio codec");
283
MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
284
285
static struct hda_codec_driver alc260_driver = {
286
.id = snd_hda_id_alc260,
287
.ops = &alc260_codec_ops,
288
};
289
290
module_hda_codec_driver(alc260_driver);
291
292