[PATCH v3 1/2] ALSA: hda/realtek: Add COEF controlled micmute LED support

Kai-Heng Feng kai.heng.feng at canonical.com
Wed Jun 17 17:24:30 CEST 2020



> On Jun 17, 2020, at 19:55, Takashi Iwai <tiwai at suse.de> wrote:
> 
> On Wed, 17 Jun 2020 12:29:01 +0200,
> Kai-Heng Feng wrote:
>> 
>> Currently, HDA codec LED class can only be used by GPIO controlled LED.
>> However, there are some new systems that control LED via COEF instead of
>> GPIO.
>> 
>> In order to support those systems, create a new helper that can be
>> facilitated by both COEF controlled and GPIO controlled LED.
>> 
>> In addition to that, add LED_CORE_SUSPENDRESUME flag since some systems
>> don't restore the LED properly after suspend.
>> 
>> Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> 
> Thanks for the quick follow up, the issues I pointed were fixed.
> 
> But, now looking at the code change again, I'm no longer sure whether
> it's the right move.
> 
> Basically, the led cdev should serve only for turning on/off the LED
> as given.  But your patch changes it to call the generic mixer
> updater, which is rather the one who would call the led cdev state
> update itself.  That is, it's other way round.
> 
> IMO, what we need is to make all places calling
> snd_hda_gen_add_micmute_led() to create led cdev, and change those
> calls with snd_hda_gen_fixup_micmute_led().

Ok, so it's the same as patch v1.
How should we handle vendors other than HP?
Only create led cdev if the ID matches to HP?

> 
> It'll be a bit more changes and likely not fitting with 5.8, but the
> whole result will be more consistent.

A bit off topic, but do you think it's reasonable to also create led cdev for mute LED, in addition to micmute LED?
I just found that the LEDs are still on during system suspend, and led cdev has the ability to turn off the LEDs on system suspend.

Kai-Heng

> 
> 
> thanks,
> 
> Takashi
> 
> 
>> ---
>> v3:
>> - Wording.
>> - Properly prefix exported symbol.
>> v2:
>> - Prevent platforms like Dell, Lenovoe and Huawei create double LED
>>   class devices.
>> sound/pci/hda/hda_generic.c   |  7 ++++---
>> sound/pci/hda/hda_generic.h   |  1 +
>> sound/pci/hda/patch_realtek.c | 29 ++++++++++++++++-------------
>> 3 files changed, 21 insertions(+), 16 deletions(-)
>> 
>> diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
>> index f4e9d9445e18..e4f534e9a88c 100644
>> --- a/sound/pci/hda/hda_generic.c
>> +++ b/sound/pci/hda/hda_generic.c
>> @@ -3897,7 +3897,7 @@ enum {
>> 	MICMUTE_LED_FOLLOW_MUTE,
>> };
>> 
>> -static void call_micmute_led_update(struct hda_codec *codec)
>> +void snd_hda_gen_call_micmute_led_update(struct hda_codec *codec)
>> {
>> 	struct hda_gen_spec *spec = codec->spec;
>> 	unsigned int val;
>> @@ -3924,6 +3924,7 @@ static void call_micmute_led_update(struct hda_codec *codec)
>> 	if (spec->micmute_led.update)
>> 		spec->micmute_led.update(codec);
>> }
>> +EXPORT_SYMBOL_GPL(snd_hda_gen_call_micmute_led_update);
>> 
>> static void update_micmute_led(struct hda_codec *codec,
>> 			       struct snd_kcontrol *kcontrol,
>> @@ -3945,7 +3946,7 @@ static void update_micmute_led(struct hda_codec *codec,
>> 			spec->micmute_led.capture |= mask;
>> 		else
>> 			spec->micmute_led.capture &= ~mask;
>> -		call_micmute_led_update(codec);
>> +		snd_hda_gen_call_micmute_led_update(codec);
>> 	}
>> }
>> 
>> @@ -3982,7 +3983,7 @@ static int micmute_led_mode_put(struct snd_kcontrol *kcontrol,
>> 	if (mode == spec->micmute_led.led_mode)
>> 		return 0;
>> 	spec->micmute_led.led_mode = mode;
>> -	call_micmute_led_update(codec);
>> +	snd_hda_gen_call_micmute_led_update(codec);
>> 	return 1;
>> }
>> 
>> diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
>> index fb9f1a90238b..062be242339a 100644
>> --- a/sound/pci/hda/hda_generic.h
>> +++ b/sound/pci/hda/hda_generic.h
>> @@ -353,6 +353,7 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
>> void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
>> int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
>> 
>> +void snd_hda_gen_call_micmute_led_update(struct hda_codec *codec);
>> int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
>> 				void (*hook)(struct hda_codec *));
>> void snd_hda_gen_fixup_micmute_led(struct hda_codec *codec,
>> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
>> index 6d73f8beadb6..0587d1e96b19 100644
>> --- a/sound/pci/hda/patch_realtek.c
>> +++ b/sound/pci/hda/patch_realtek.c
>> @@ -4114,10 +4114,10 @@ static int micmute_led_set(struct led_classdev *led_cdev,
>> 			   enum led_brightness brightness)
>> {
>> 	struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
>> -	struct alc_spec *spec = codec->spec;
>> +	struct hda_gen_spec *spec = codec->spec;
>> 
>> -	alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
>> -			    spec->micmute_led_polarity, !!brightness);
>> +	spec->micmute_led.led_mode = !brightness;
>> +	snd_hda_gen_call_micmute_led_update(codec);
>> 	return 0;
>> }
>> 
>> @@ -4126,7 +4126,17 @@ static struct led_classdev micmute_led_cdev = {
>> 	.max_brightness = 1,
>> 	.brightness_set_blocking = micmute_led_set,
>> 	.default_trigger = "audio-micmute",
>> +	.flags = LED_CORE_SUSPENDRESUME,
>> };
>> +
>> +static void alc_register_micmute_led(struct hda_codec *codec)
>> +{
>> +		micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
>> +		if (devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev))
>> +			codec_warn(codec, "failed to register micmute LED\n");
>> +}
>> +#else
>> +static inline void alc_register_micmute_led(struct hda_codec *codec) {}
>> #endif
>> 
>> /* setup mute and mic-mute GPIO bits, add hooks appropriately */
>> @@ -4136,9 +4146,6 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
>> 				  unsigned int micmute_mask)
>> {
>> 	struct alc_spec *spec = codec->spec;
>> -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
>> -	int err;
>> -#endif
>> 
>> 	alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
>> 
>> @@ -4151,13 +4158,7 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
>> 	if (micmute_mask) {
>> 		spec->gpio_mic_led_mask = micmute_mask;
>> 		snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
>> -
>> -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
>> -		micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
>> -		err = devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev);
>> -		if (err)
>> -			codec_warn(codec, "failed to register micmute LED\n");
>> -#endif
>> +		alc_register_micmute_led(codec);
>> 	}
>> }
>> 
>> @@ -4305,6 +4306,7 @@ static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
>> 		spec->mic_led_coefbit_on = 1<<13;
>> 		spec->mic_led_coefbit_off = 0;
>> 		snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
>> +		alc_register_micmute_led(codec);
>> 	}
>> }
>> 
>> @@ -4319,6 +4321,7 @@ static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
>> 		spec->mic_led_coefbit_on = 2<<2;
>> 		spec->mic_led_coefbit_off = 1<<2;
>> 		snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
>> +		alc_register_micmute_led(codec);
>> 	}
>> }
>> 
>> -- 
>> 2.17.1
>> 



More information about the Alsa-devel mailing list