Skip to content

Commit 72cf0b0

Browse files
committed
Merge tag 'sound-fix-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Just a few HD-audio fixes, most of which are specific to Realtek codecs" * tag 'sound-fix-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/realtek - Fix for Lenovo B50-70 inverted internal microphone bug ALSA: hda: Fix race between creating and refreshing sysfs entries ALSA: hda/realtek - Corrected fixup for System76 Gazelle (gaze14) ALSA: hda/realtek - Avoid superfluous COEF EAPD setups ALSA: hda/realtek - Fixup headphone noise via runtime suspend
2 parents 0ef0fd3 + 56df90b commit 72cf0b0

File tree

4 files changed

+80
-27
lines changed

4 files changed

+80
-27
lines changed

include/sound/hdaudio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct hdac_device {
8181
atomic_t in_pm; /* suspend/resume being performed */
8282

8383
/* sysfs */
84+
struct mutex widget_lock;
8485
struct hdac_widget_tree *widgets;
8586

8687
/* regmap */

sound/hda/hdac_device.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ int snd_hdac_device_init(struct hdac_device *codec, struct hdac_bus *bus,
5555
codec->bus = bus;
5656
codec->addr = addr;
5757
codec->type = HDA_DEV_CORE;
58+
mutex_init(&codec->widget_lock);
5859
pm_runtime_set_active(&codec->dev);
5960
pm_runtime_get_noresume(&codec->dev);
6061
atomic_set(&codec->in_pm, 0);
@@ -141,7 +142,9 @@ int snd_hdac_device_register(struct hdac_device *codec)
141142
err = device_add(&codec->dev);
142143
if (err < 0)
143144
return err;
145+
mutex_lock(&codec->widget_lock);
144146
err = hda_widget_sysfs_init(codec);
147+
mutex_unlock(&codec->widget_lock);
145148
if (err < 0) {
146149
device_del(&codec->dev);
147150
return err;
@@ -158,7 +161,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_device_register);
158161
void snd_hdac_device_unregister(struct hdac_device *codec)
159162
{
160163
if (device_is_registered(&codec->dev)) {
164+
mutex_lock(&codec->widget_lock);
161165
hda_widget_sysfs_exit(codec);
166+
mutex_unlock(&codec->widget_lock);
162167
device_del(&codec->dev);
163168
snd_hdac_bus_remove_device(codec->bus, codec);
164169
}
@@ -404,7 +409,9 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs)
404409
}
405410

406411
if (sysfs) {
412+
mutex_lock(&codec->widget_lock);
407413
err = hda_widget_sysfs_reinit(codec, start_nid, nums);
414+
mutex_unlock(&codec->widget_lock);
408415
if (err < 0)
409416
return err;
410417
}

sound/hda/hdac_sysfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ static int widget_tree_create(struct hdac_device *codec)
395395
return 0;
396396
}
397397

398+
/* call with codec->widget_lock held */
398399
int hda_widget_sysfs_init(struct hdac_device *codec)
399400
{
400401
int err;
@@ -411,11 +412,13 @@ int hda_widget_sysfs_init(struct hdac_device *codec)
411412
return 0;
412413
}
413414

415+
/* call with codec->widget_lock held */
414416
void hda_widget_sysfs_exit(struct hdac_device *codec)
415417
{
416418
widget_tree_free(codec);
417419
}
418420

421+
/* call with codec->widget_lock held */
419422
int hda_widget_sysfs_reinit(struct hdac_device *codec,
420423
hda_nid_t start_nid, int num_nodes)
421424
{

sound/pci/hda/patch_realtek.c

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,45 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
478478
set_eapd(codec, *p, on);
479479
}
480480

481+
static int find_ext_mic_pin(struct hda_codec *codec);
482+
483+
static void alc_headset_mic_no_shutup(struct hda_codec *codec)
484+
{
485+
const struct hda_pincfg *pin;
486+
int mic_pin = find_ext_mic_pin(codec);
487+
int i;
488+
489+
/* don't shut up pins when unloading the driver; otherwise it breaks
490+
* the default pin setup at the next load of the driver
491+
*/
492+
if (codec->bus->shutdown)
493+
return;
494+
495+
snd_array_for_each(&codec->init_pins, i, pin) {
496+
/* use read here for syncing after issuing each verb */
497+
if (pin->nid != mic_pin)
498+
snd_hda_codec_read(codec, pin->nid, 0,
499+
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
500+
}
501+
502+
codec->pins_shutup = 1;
503+
}
504+
481505
static void alc_shutup_pins(struct hda_codec *codec)
482506
{
483507
struct alc_spec *spec = codec->spec;
484508

485-
if (!spec->no_shutup_pins)
486-
snd_hda_shutup_pins(codec);
509+
switch (codec->core.vendor_id) {
510+
case 0x10ec0286:
511+
case 0x10ec0288:
512+
case 0x10ec0298:
513+
alc_headset_mic_no_shutup(codec);
514+
break;
515+
default:
516+
if (!spec->no_shutup_pins)
517+
snd_hda_shutup_pins(codec);
518+
break;
519+
}
487520
}
488521

489522
/* generic shutup callback;
@@ -502,7 +535,6 @@ static void alc_eapd_shutup(struct hda_codec *codec)
502535
/* generic EAPD initialization */
503536
static void alc_auto_init_amp(struct hda_codec *codec, int type)
504537
{
505-
alc_fill_eapd_coef(codec);
506538
alc_auto_setup_eapd(codec, true);
507539
alc_write_gpio(codec);
508540
switch (type) {
@@ -797,10 +829,22 @@ static int alc_build_controls(struct hda_codec *codec)
797829
* Common callbacks
798830
*/
799831

832+
static void alc_pre_init(struct hda_codec *codec)
833+
{
834+
alc_fill_eapd_coef(codec);
835+
}
836+
837+
#define is_s4_resume(codec) \
838+
((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
839+
800840
static int alc_init(struct hda_codec *codec)
801841
{
802842
struct alc_spec *spec = codec->spec;
803843

844+
/* hibernation resume needs the full chip initialization */
845+
if (is_s4_resume(codec))
846+
alc_pre_init(codec);
847+
804848
if (spec->init_hook)
805849
spec->init_hook(codec);
806850

@@ -1538,6 +1582,8 @@ static int patch_alc880(struct hda_codec *codec)
15381582

15391583
codec->patch_ops.unsol_event = alc880_unsol_event;
15401584

1585+
alc_pre_init(codec);
1586+
15411587
snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
15421588
alc880_fixups);
15431589
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -1789,6 +1835,8 @@ static int patch_alc260(struct hda_codec *codec)
17891835

17901836
spec->shutup = alc_eapd_shutup;
17911837

1838+
alc_pre_init(codec);
1839+
17921840
snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
17931841
alc260_fixups);
17941842
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2492,6 +2540,8 @@ static int patch_alc882(struct hda_codec *codec)
24922540
break;
24932541
}
24942542

2543+
alc_pre_init(codec);
2544+
24952545
snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
24962546
alc882_fixups);
24972547
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2666,6 +2716,8 @@ static int patch_alc262(struct hda_codec *codec)
26662716
#endif
26672717
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
26682718

2719+
alc_pre_init(codec);
2720+
26692721
snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
26702722
alc262_fixups);
26712723
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2810,6 +2862,8 @@ static int patch_alc268(struct hda_codec *codec)
28102862

28112863
spec->shutup = alc_eapd_shutup;
28122864

2865+
alc_pre_init(codec);
2866+
28132867
snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
28142868
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
28152869

@@ -2924,27 +2978,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
29242978
return alc_parse_auto_config(codec, alc269_ignore, ssids);
29252979
}
29262980

2927-
static int find_ext_mic_pin(struct hda_codec *codec);
2928-
2929-
static void alc286_shutup(struct hda_codec *codec)
2930-
{
2931-
const struct hda_pincfg *pin;
2932-
int i;
2933-
int mic_pin = find_ext_mic_pin(codec);
2934-
/* don't shut up pins when unloading the driver; otherwise it breaks
2935-
* the default pin setup at the next load of the driver
2936-
*/
2937-
if (codec->bus->shutdown)
2938-
return;
2939-
snd_array_for_each(&codec->init_pins, i, pin) {
2940-
/* use read here for syncing after issuing each verb */
2941-
if (pin->nid != mic_pin)
2942-
snd_hda_codec_read(codec, pin->nid, 0,
2943-
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2944-
}
2945-
codec->pins_shutup = 1;
2946-
}
2947-
29482981
static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
29492982
{
29502983
alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
@@ -6964,7 +6997,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
69646997
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
69656998
SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
69666999
SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
6967-
SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7000+
SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7001+
SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7002+
SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
69687003
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
69697004
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
69707005
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
@@ -7007,7 +7042,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
70077042
SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
70087043
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
70097044
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
7010-
SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
7045+
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
70117046
SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
70127047
SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
70137048
SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
@@ -7736,7 +7771,6 @@ static int patch_alc269(struct hda_codec *codec)
77367771
case 0x10ec0286:
77377772
case 0x10ec0288:
77387773
spec->codec_variant = ALC269_TYPE_ALC286;
7739-
spec->shutup = alc286_shutup;
77407774
break;
77417775
case 0x10ec0298:
77427776
spec->codec_variant = ALC269_TYPE_ALC298;
@@ -7805,6 +7839,8 @@ static int patch_alc269(struct hda_codec *codec)
78057839
spec->init_hook = alc5505_dsp_init;
78067840
}
78077841

7842+
alc_pre_init(codec);
7843+
78087844
snd_hda_pick_fixup(codec, alc269_fixup_models,
78097845
alc269_fixup_tbl, alc269_fixups);
78107846
snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
@@ -7947,6 +7983,8 @@ static int patch_alc861(struct hda_codec *codec)
79477983
spec->power_hook = alc_power_eapd;
79487984
#endif
79497985

7986+
alc_pre_init(codec);
7987+
79507988
snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
79517989
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
79527990

@@ -8044,6 +8082,8 @@ static int patch_alc861vd(struct hda_codec *codec)
80448082

80458083
spec->shutup = alc_eapd_shutup;
80468084

8085+
alc_pre_init(codec);
8086+
80478087
snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
80488088
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
80498089

@@ -8779,6 +8819,8 @@ static int patch_alc662(struct hda_codec *codec)
87798819
break;
87808820
}
87818821

8822+
alc_pre_init(codec);
8823+
87828824
snd_hda_pick_fixup(codec, alc662_fixup_models,
87838825
alc662_fixup_tbl, alc662_fixups);
87848826
snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);

0 commit comments

Comments
 (0)