Skip to content

Commit 27b9bca

Browse files
wangdichengtiwai
authored andcommitted
ALSA: hda/senary: Add hardware init verbs and fixup framework
Port the essential hardware initialization logic from the vendor driver and introduce the standard HDA fixup framework to handle different machine configurations. Key changes: 1. Add hardware init verbs: - Implement `senary_init_verb` to send the vendor-specific initialization sequence required by the SN6186 chip. - Override pin capabilities for Node 0x19 to ensure proper headset microphone support. 2. Introduce fixup framework: - Define a default pin configuration table (`senary_pincfg_default`) to provide a fallback for devices with invalid BIOS configurations. - Establish a quirk table structure for future machine-specific fixes. - Since the standard quirk matching relies on Subsystem IDs, we manually apply the default fixup if `snd_hda_pick_fixup` does not find a specific match. This ensures the chip is correctly initialized during probe and resume, and provides a scalable mechanism for supporting specific hardware quirks. Signed-off-by: wangdicheng <wangdicheng@kylinos.cn> Link: https://patch.msgid.link/20260304070219.450083-1-wangdich9700@163.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent dfd4b0d commit 27b9bca

1 file changed

Lines changed: 61 additions & 2 deletions

File tree

sound/hda/codecs/senarytech.c

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ struct senary_spec {
3636
unsigned int gpio_mic_led_mask;
3737
};
3838

39+
enum {
40+
SENARY_FIXUP_PINCFG_DEFAULT,
41+
};
42+
43+
static const struct hda_pintbl senary_pincfg_default[] = {
44+
{ 0x16, 0x02211020 }, /* Headphone */
45+
{ 0x17, 0x40f001f0 }, /* Not used */
46+
{ 0x18, 0x05a1904d }, /* Mic */
47+
{ 0x19, 0x02a1104e }, /* Headset Mic */
48+
{ 0x1a, 0x01819030 }, /* Line-in */
49+
{ 0x1d, 0x01014010 }, /* Line-out */
50+
{}
51+
};
52+
53+
static const struct hda_fixup senary_fixups[] = {
54+
[SENARY_FIXUP_PINCFG_DEFAULT] = {
55+
.type = HDA_FIXUP_PINS,
56+
.v.pins = senary_pincfg_default,
57+
},
58+
};
59+
60+
/* Quirk table for specific machines can be added here */
61+
static const struct hda_quirk sn6186_fixups[] = {
62+
{}
63+
};
64+
3965
#ifdef CONFIG_SND_HDA_INPUT_BEEP
4066
/* additional beep mixers; private_value will be overwritten */
4167
static const struct snd_kcontrol_new senary_beep_mixer[] = {
@@ -93,6 +119,19 @@ static void senary_auto_parse_eapd(struct hda_codec *codec)
93119
}
94120
}
95121

122+
/* Hardware specific initialization verbs */
123+
static void senary_init_verb(struct hda_codec *codec)
124+
{
125+
/* Vendor specific init sequence */
126+
snd_hda_codec_write(codec, 0x1b, 0x0, 0x05a, 0xaa);
127+
snd_hda_codec_write(codec, 0x1b, 0x0, 0x059, 0x48);
128+
snd_hda_codec_write(codec, 0x1b, 0x0, 0x01b, 0x00);
129+
snd_hda_codec_write(codec, 0x1b, 0x0, 0x01c, 0x00);
130+
131+
/* Override pin caps for headset mic */
132+
snd_hda_override_pin_caps(codec, 0x19, 0x2124);
133+
}
134+
96135
static void senary_auto_turn_eapd(struct hda_codec *codec, int num_pins,
97136
const hda_nid_t *pins, bool on)
98137
{
@@ -136,6 +175,7 @@ static int senary_init(struct hda_codec *codec)
136175

137176
snd_hda_gen_init(codec);
138177
senary_init_gpio_led(codec);
178+
senary_init_verb(codec);
139179
if (!spec->dynamic_eapd)
140180
senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
141181
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
@@ -181,11 +221,30 @@ static int senary_probe(struct hda_codec *codec, const struct hda_device_id *id)
181221
senary_auto_parse_eapd(codec);
182222
spec->gen.own_eapd_ctl = 1;
183223

184-
if (!spec->gen.vmaster_mute.hook)
185-
spec->gen.vmaster_mute.hook = senary_auto_vmaster_hook;
224+
/* Setup fixups based on codec vendor ID */
225+
switch (codec->core.vendor_id) {
226+
case 0x1fa86186:
227+
codec->pin_amp_workaround = 1;
228+
spec->gen.mixer_nid = 0x15;
229+
snd_hda_pick_fixup(codec, NULL, sn6186_fixups, senary_fixups);
230+
231+
/* If no specific quirk found, apply the default pin configuration */
232+
if (codec->fixup_id == HDA_FIXUP_ID_NOT_SET)
233+
codec->fixup_id = SENARY_FIXUP_PINCFG_DEFAULT;
234+
break;
235+
default:
236+
snd_hda_pick_fixup(codec, NULL, sn6186_fixups, senary_fixups);
237+
break;
238+
}
186239

187240
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
188241

242+
/* Run hardware init verbs once during probe */
243+
senary_init_verb(codec);
244+
245+
if (!spec->gen.vmaster_mute.hook)
246+
spec->gen.vmaster_mute.hook = senary_auto_vmaster_hook;
247+
189248
err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL,
190249
spec->parse_flags);
191250
if (err < 0)

0 commit comments

Comments
 (0)