On Thu, 13 Jan 2022 19:31:41 +0100, Alexander Sergeyev wrote: > > On Thu, Jan 13, 2022 at 08:14:29AM +0100, Takashi Iwai wrote: > >> First, about unbind and bind via sysfs -- attempts to unbind the > >> HD-audio controller immediately trigger BUGs: > >> Is it normal/expected? > > > >A sort of. The sysfs unbind is little tested and may be still buggy > >if done during the stream operation. > > > >To be sure, could you check with my latest sound.git tree for-linus > >branch? There are a few fixes that harden the dynamic unbind. > > I assume that the referred repository is the one at [1]. I've tried > 081c73701ef0 "ALSA: hda: intel-dsp-config: reorder the config > table". It crashed with nearly identical logs. OK, then it's still something to do with the led cdev unregisteration. Could you try the patch below? > >> 1) Coeff 0x0b is flapping between 0x8003 and 0x7770 and does not seem > >> to have any effect in both non-working and working versions. Not sure > >> about this, maybe microphone is not operational since I haven't > >> checked it yet. > > I got some time to poke the internal microphone. It works, but > oddities are there as well. Initially I get "Mic Boost", "Capture" and > "Internal Mic Boost" controls in alsamixer. When I run arecord, > "Digital" control appears, but it cannot be changed until arecord is > stopped. Subsequent arecord calls do not lock "Digital" control. This > control affects sensitivity of the microphone and seems useful. That's presumably an alsa-lib softvol stuff. It's created dynamically. So not really a kernel problem. Takashi --- diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 3bf5e3410703..503cd979c908 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -84,13 +84,21 @@ static void free_kctls(struct hda_gen_spec *spec) snd_array_free(&spec->kctls); } -static void snd_hda_gen_spec_free(struct hda_gen_spec *spec) +static void snd_hda_gen_spec_free(struct hda_codec *codec) { + struct hda_gen_spec *spec = codec->spec; + if (!spec) return; free_kctls(spec); snd_array_free(&spec->paths); snd_array_free(&spec->loopback_list); +#ifdef CONFIG_SND_HDA_GENERIC_LEDS + if (spec->led_cdevs[LED_AUDIO_MUTE]) + led_classdev_unregister(spec->led_cdevs[LED_AUDIO_MUTE]); + if (spec->led_cdevs[LED_AUDIO_MICMUTE]) + led_classdev_unregister(spec->led_cdevs[LED_AUDIO_MICMUTE]); +#endif } /* @@ -3922,7 +3930,9 @@ static int create_mute_led_cdev(struct hda_codec *codec, enum led_brightness), bool micmute) { + struct hda_gen_spec *spec = codec->spec; struct led_classdev *cdev; + int err; cdev = devm_kzalloc(&codec->core.dev, sizeof(*cdev), GFP_KERNEL); if (!cdev) @@ -3935,7 +3945,11 @@ static int create_mute_led_cdev(struct hda_codec *codec, cdev->brightness = ledtrig_audio_get(micmute ? LED_AUDIO_MICMUTE : LED_AUDIO_MUTE); cdev->flags = LED_CORE_SUSPENDRESUME; - return devm_led_classdev_register(&codec->core.dev, cdev); + err = led_classdev_register(&codec->core.dev, cdev); + if (err < 0) + return err; + spec->led_cdevs[micmute ? LED_AUDIO_MICMUTE : LED_AUDIO_MUTE] = cdev; + return 0; } /** @@ -5998,7 +6012,7 @@ EXPORT_SYMBOL_GPL(snd_hda_gen_init); void snd_hda_gen_free(struct hda_codec *codec) { snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE); - snd_hda_gen_spec_free(codec->spec); + snd_hda_gen_spec_free(codec); kfree(codec->spec); codec->spec = NULL; } diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 8e1bc8ea74fc..34eba40cc6e6 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -294,6 +294,9 @@ struct hda_gen_spec { struct hda_jack_callback *cb); void (*mic_autoswitch_hook)(struct hda_codec *codec, struct hda_jack_callback *cb); + + /* leds */ + struct led_classdev *led_cdevs[NUM_AUDIO_LEDS]; }; /* values for add_stereo_mix_input flag */