Skip to content

Commit

Permalink
ALSA: hda - Support led audio trigger
Browse files Browse the repository at this point in the history
Now all relevant platform drivers are providing the LED audio trigger,
we can switch the mute LED control with the LED trigger, finally.

For the mic-mute LED trigger, a common fixup function,
snd_hda_gen_fixup_micmute_led(), is provided to be called for the
corresponding quirk entries.  This sets up the capture sync hook with
ledtrig_audio_set() call appropriately.

For the mute LED trigger, which is done currently only for
thinkpad_acpi, the call is replaced with ledtrig_audio_set() as well.

Overall, the beauty of the new implementation is that the whole ugly
bindings with request_symbol() are dropped, and also that it provides
more flexibility to users.

One potential behavior change by this patch is that the mute LED enum
may be created on machines that actually have no LED device.  In the
former code, we did test-call and abort binding if the test failed.
But with the LED-trigger binding, this test isn't possible, and the
actual check is done in the LED class device side.  So it's the
downside of simpleness.

Also, note that the HD-audio codec driver doesn't select CONFIG_LEDS
and co by itself.  It's supposed to be selected by the platform
drivers instead.

Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Nov 28, 2018
1 parent 4e1d092 commit b380278
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 95 deletions.
48 changes: 0 additions & 48 deletions sound/pci/hda/dell_wmi_helper.c

This file was deleted.

31 changes: 31 additions & 0 deletions sound/pci/hda/hda_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/tlv.h>
Expand Down Expand Up @@ -4035,6 +4036,36 @@ int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led);

#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
static void call_ledtrig_micmute(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;

ledtrig_audio_set(LED_AUDIO_MICMUTE,
spec->micmute_led.led_value ? LED_ON : LED_OFF);
}
#endif

/**
* snd_hda_gen_fixup_micmute_led - A fixup for mic-mute LED trigger
*
* Pass this function to the quirk entry if another driver supports the
* audio mic-mute LED trigger. Then this will bind the mixer capture switch
* change with the LED.
*
* Note that this fixup has to be called after other fixup that sets
* cap_sync_hook. Otherwise the chaining wouldn't work.
*/
void snd_hda_gen_fixup_micmute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
if (action == HDA_FIXUP_ACT_PROBE)
snd_hda_gen_add_micmute_led(codec, call_ledtrig_micmute);
#endif
}
EXPORT_SYMBOL_GPL(snd_hda_gen_fixup_micmute_led);

/*
* parse digital I/Os and set up NIDs in BIOS auto-parse mode
*/
Expand Down
2 changes: 2 additions & 0 deletions sound/pci/hda/hda_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,5 +357,7 @@ int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);

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,
const struct hda_fixup *fix, int action);

#endif /* __SOUND_HDA_GENERIC_H */
17 changes: 7 additions & 10 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -5368,9 +5368,6 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
hda_fixup_thinkpad_acpi(codec, fix, action);
}

/* for dell wmi mic mute led */
#include "dell_wmi_helper.c"

/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"

Expand Down Expand Up @@ -5448,7 +5445,7 @@ enum {
ALC292_FIXUP_TPT440_DOCK,
ALC292_FIXUP_TPT440,
ALC283_FIXUP_HEADSET_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
ALC255_FIXUP_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS,
ALC280_FIXUP_HP_GPIO4,
ALC286_FIXUP_HP_GPIO_LED,
Expand Down Expand Up @@ -5740,7 +5737,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode,
.chained = true,
.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
.chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
.type = HDA_FIXUP_FUNC,
Expand Down Expand Up @@ -5966,7 +5963,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_alc255,
.chained = true,
.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
.chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
.type = HDA_FIXUP_FUNC,
Expand Down Expand Up @@ -6001,9 +5998,9 @@ static const struct hda_fixup alc269_fixups[] = {
{ },
},
},
[ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
[ALC255_FIXUP_MIC_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_dell_wmi,
.v.func = snd_hda_gen_fixup_micmute_led,
},
[ALC282_FIXUP_ASPIRE_V5_PINS] = {
.type = HDA_FIXUP_PINS,
Expand Down Expand Up @@ -6062,7 +6059,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_dell_alc288,
.chained = true,
.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
.chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_PINS,
Expand Down Expand Up @@ -6719,7 +6716,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
{.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
{.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
{.id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, .name = "alc255-dell-mute"},
{.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
{.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
{.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
{.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Expand Down
43 changes: 6 additions & 37 deletions sound/pci/hda/thinkpad_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
* to be included from codec driver
*/

#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
#if IS_ENABLED(CONFIG_THINKPAD_ACPI) && IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)

#include <linux/acpi.h>
#include <linux/thinkpad_acpi.h>
#include <linux/leds.h>

static int (*led_set_func)(int, bool);
static void (*old_vmaster_hook)(void *, int);

static bool is_thinkpad(struct hda_codec *codec)
Expand All @@ -23,50 +22,20 @@ static void update_tpacpi_mute_led(void *private_data, int enabled)
if (old_vmaster_hook)
old_vmaster_hook(private_data, enabled);

if (led_set_func)
led_set_func(TPACPI_LED_MUTE, !enabled);
}

static void update_tpacpi_micmute(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;

led_set_func(TPACPI_LED_MICMUTE, spec->micmute_led.led_value);
ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON);
}

static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct hda_gen_spec *spec = codec->spec;
bool removefunc = false;

if (action == HDA_FIXUP_ACT_PROBE) {
if (!is_thinkpad(codec))
return;
if (!led_set_func)
led_set_func = symbol_request(tpacpi_led_set);
if (!led_set_func) {
codec_warn(codec,
"Failed to find thinkpad-acpi symbol tpacpi_led_set\n");
return;
}

removefunc = true;
if (led_set_func(TPACPI_LED_MUTE, false) >= 0) {
old_vmaster_hook = spec->vmaster_mute.hook;
spec->vmaster_mute.hook = update_tpacpi_mute_led;
removefunc = false;
}
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 &&
!snd_hda_gen_add_micmute_led(codec,
update_tpacpi_micmute))
removefunc = false;
}

if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
symbol_put(tpacpi_led_set);
led_set_func = NULL;
old_vmaster_hook = NULL;
old_vmaster_hook = spec->vmaster_mute.hook;
spec->vmaster_mute.hook = update_tpacpi_mute_led;
snd_hda_gen_fixup_micmute_led(codec, fix, action);
}
}

Expand Down

0 comments on commit b380278

Please sign in to comment.