Enable mic mute hotkey and LEDs for an HP machine

Bug #1408295 reported by David Henningsson
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
HWE Next
Fix Released
Undecided
David Henningsson
linux (Ubuntu)
Fix Released
Undecided
David Henningsson

Bug Description

This bug is used for tracking only, please do not triage.

Changed in linux (Ubuntu):
status: New → In Progress
assignee: nobody → David Henningsson (diwic)
Revision history for this message
David Henningsson (diwic) wrote : [PATCH] ALSA: hda - Enable mic mute hotkey and LEDs for an HP machine
Download full text (4.6 KiB)

On this machine, the mic mute hotkey is connected to GPIO2. We therefore
create an extra input device for this key.

Also enable LEDs connected to GPIO3 and GPIO4.

(Note: if this patch is backported to older kernels, where KEY_MIC_MUTE is
not available, change the KEY_MIC_MUTE to KEY_F20, which was previously used
for mic mute keys.)

BugLink: https://bugs.launchpad.net/bugs/1408295
Tested-by: Keng-Yu Lin <email address hidden>
Signed-off-by: David Henningsson <email address hidden>
---
 sound/pci/hda/patch_realtek.c | 86 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 65f1f4e..3338c75 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/module.h>
+#include <linux/input.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -120,6 +121,8 @@ struct alc_spec {
  hda_nid_t pll_nid;
  unsigned int pll_coef_idx, pll_coef_bit;
  unsigned int coef0;
+
+ struct input_dev *kb_dev;
 };

 /*
@@ -3472,6 +3475,83 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
  }
 }

+static void gpio2_mic_hotkey_event(struct hda_codec *codec,
+ struct hda_jack_callback *event)
+{
+ struct alc_spec *spec = codec->spec;
+
+ /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
+ send both key on and key off event for every interrupt. */
+ input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
+ input_sync(spec->kb_dev);
+ input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
+ input_sync(spec->kb_dev);
+}
+
+static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ /* GPIO1 = set according to SKU external amp
+ GPIO2 = mic mute hotkey
+ GPIO3 = mute LED
+ GPIO4 = mic mute LED */
+ static const struct hda_verb gpio_init[] = {
+ { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
+ { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
+ { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
+ {}
+ };
+
+ struct alc_spec *spec = codec->spec;
+
+ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+
+ spec->kb_dev = input_allocate_device();
+ if (!spec->kb_dev) {
+ snd_printk("Out of memory (input_allocate_device)\n");
+ return;
+ }
+ spec->kb_dev->name = "Microphone Mute Button";
+ spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
+ spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
+ if (input_register_device(spec->kb_dev)) {
+ snd_printk("input_register_device failed\n");
+ input_free_device(spec->kb_dev);
+ spec->kb_dev = NULL;
+ return;
+ }
+
+ snd_hda_add_verbs(codec, gpio_init);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
+ snd_hda_jack_detect_enable_callback(codec, codec->afg,
+ gpio2_mic_hotkey_event);
+
+ spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
+ spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
+ spec->gpio_led = 0;
+ spec->mute_led_polarity = 0;
+ spec->gpio_mute_led_mask = 0x08;
+ spec->gpio_mic_led_mask = 0x10;
+ return;
...

Read more...

Revision history for this message
Takashi Iwai (tiwai) wrote :
Download full text (3.8 KiB)

At Wed, 7 Jan 2015 13:30:14 +0100,
David Henningsson wrote:
>
> On this machine, the mic mute hotkey is connected to GPIO2. We therefore
> create an extra input device for this key.
>
> Also enable LEDs connected to GPIO3 and GPIO4.
>
> (Note: if this patch is backported to older kernels, where KEY_MIC_MUTE is
> not available, change the KEY_MIC_MUTE to KEY_F20, which was previously used
> for mic mute keys.)
>
> BugLink: https://bugs.launchpad.net/bugs/1408295
> Tested-by: Keng-Yu Lin <email address hidden>
> Signed-off-by: David Henningsson <email address hidden>
> ---
> sound/pci/hda/patch_realtek.c | 86 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 86 insertions(+)
>
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 65f1f4e..3338c75 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -29,6 +29,7 @@
> #include <linux/pci.h>
> #include <linux/dmi.h>
> #include <linux/module.h>
> +#include <linux/input.h>
> #include <sound/core.h>
> #include <sound/jack.h>
> #include "hda_codec.h"
> @@ -120,6 +121,8 @@ struct alc_spec {
> hda_nid_t pll_nid;
> unsigned int pll_coef_idx, pll_coef_bit;
> unsigned int coef0;
> +
> + struct input_dev *kb_dev;
> };
>
> /*
> @@ -3472,6 +3475,83 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
> }
> }
>
> +static void gpio2_mic_hotkey_event(struct hda_codec *codec,
> + struct hda_jack_callback *event)
> +{
> + struct alc_spec *spec = codec->spec;
> +
> + /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
> + send both key on and key off event for every interrupt. */
> + input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
> + input_sync(spec->kb_dev);
> + input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
> + input_sync(spec->kb_dev);

Does the build pass without CONFIG_INPUT?

> +}
> +
> +static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
> + const struct hda_fixup *fix, int action)
> +{
> + /* GPIO1 = set according to SKU external amp
> + GPIO2 = mic mute hotkey
> + GPIO3 = mute LED
> + GPIO4 = mic mute LED */
> + static const struct hda_verb gpio_init[] = {
> + { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
> + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
> + { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
> + {}
> + };
> +
> + struct alc_spec *spec = codec->spec;
> +
> + if (action == HDA_FIXUP_ACT_PRE_PROBE) {
> +
> + spec->kb_dev = input_allocate_device();
> + if (!spec->kb_dev) {
> + snd_printk("Out of memory (input_allocate_device)\n");

Better to use dev_err() (or codec_err()) macro.

> + return;
> + }
> + spec->kb_dev->name = "Microphone Mute Button";
> + spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
> + spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
> + if (input_register_device(spec->kb_dev)) {
> + snd_printk("input_register_device failed\n");

Ditto.

> + input_free_device(spec->kb_dev);
> + spec->kb_dev = NULL;
> + return;
> + }
> +
> + snd_hda_add_verbs(codec, gpio_init);
> + snd_hda_codec_write_cache(codec, codec->afg, 0,
> + AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
> + ...

Read more...

Revision history for this message
David Henningsson (diwic) wrote : [PATCH v2] ALSA: hda - Enable mic mute hotkey and LEDs for an HP machine
Download full text (4.8 KiB)

On this machine, the mic mute hotkey is connected to GPIO2. We therefore
create an extra input device for this key.

Also enable LEDs connected to GPIO3 and GPIO4.

(Note: if this patch is backported to older kernels, where KEY_MIC_MUTE is
not available, change the KEY_MIC_MUTE to KEY_F20, which was previously used
for mic mute keys.)

BugLink: https://bugs.launchpad.net/bugs/1408295
Tested-by: Keng-Yu Lin <email address hidden>
Signed-off-by: David Henningsson <email address hidden>
---

Changes since v1 (which was by mistake not posted to alsa-devel)
 - fixes according to Takashi's review comments

 sound/pci/hda/patch_realtek.c | 88 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 65f1f4e..09d2131 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/module.h>
+#include <linux/input.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -120,6 +121,9 @@ struct alc_spec {
  hda_nid_t pll_nid;
  unsigned int pll_coef_idx, pll_coef_bit;
  unsigned int coef0;
+#if IS_ENABLED(CONFIG_INPUT)
+ struct input_dev *kb_dev;
+#endif
 };

 /*
@@ -3472,6 +3476,84 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
  }
 }

+#if IS_ENABLED(CONFIG_INPUT)
+static void gpio2_mic_hotkey_event(struct hda_codec *codec,
+ struct hda_jack_callback *event)
+{
+ struct alc_spec *spec = codec->spec;
+
+ /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
+ send both key on and key off event for every interrupt. */
+ input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
+ input_sync(spec->kb_dev);
+ input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
+ input_sync(spec->kb_dev);
+}
+#endif
+
+static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+#if IS_ENABLED(CONFIG_INPUT)
+ /* GPIO1 = set according to SKU external amp
+ GPIO2 = mic mute hotkey
+ GPIO3 = mute LED
+ GPIO4 = mic mute LED */
+ static const struct hda_verb gpio_init[] = {
+ { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
+ { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
+ { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
+ {}
+ };
+
+ struct alc_spec *spec = codec->spec;
+
+ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+ spec->kb_dev = input_allocate_device();
+ if (!spec->kb_dev) {
+ codec_err(codec, "Out of memory (input_allocate_device)\n");
+ return;
+ }
+ spec->kb_dev->name = "Microphone Mute Button";
+ spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
+ spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
+ if (input_register_device(spec->kb_dev)) {
+ codec_err(codec, "input_register_device failed\n");
+ input_free_device(spec->kb_dev);
+ spec->kb_dev = NULL;
+ return;
+ }
+
+ snd_hda_add_verbs(codec, gpio_init);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
+ snd_hda_jack_detect_enable_callback(codec, codec->afg,
+ gpio2_mic_hotkey_event);
+
+ spec->gen.vmaster_mute....

Read more...

Revision history for this message
Takashi Iwai (tiwai) wrote :
Download full text (5.2 KiB)

At Wed, 7 Jan 2015 15:50:13 +0100,
David Henningsson wrote:
>
> On this machine, the mic mute hotkey is connected to GPIO2. We therefore
> create an extra input device for this key.
>
> Also enable LEDs connected to GPIO3 and GPIO4.
>
> (Note: if this patch is backported to older kernels, where KEY_MIC_MUTE is
> not available, change the KEY_MIC_MUTE to KEY_F20, which was previously used
> for mic mute keys.)
>
> BugLink: https://bugs.launchpad.net/bugs/1408295
> Tested-by: Keng-Yu Lin <email address hidden>
> Signed-off-by: David Henningsson <email address hidden>
> ---
>
> Changes since v1 (which was by mistake not posted to alsa-devel)
> - fixes according to Takashi's review comments

Thanks, applied now.

Takashi

>
> sound/pci/hda/patch_realtek.c | 88 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 88 insertions(+)
>
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 65f1f4e..09d2131 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -29,6 +29,7 @@
> #include <linux/pci.h>
> #include <linux/dmi.h>
> #include <linux/module.h>
> +#include <linux/input.h>
> #include <sound/core.h>
> #include <sound/jack.h>
> #include "hda_codec.h"
> @@ -120,6 +121,9 @@ struct alc_spec {
> hda_nid_t pll_nid;
> unsigned int pll_coef_idx, pll_coef_bit;
> unsigned int coef0;
> +#if IS_ENABLED(CONFIG_INPUT)
> + struct input_dev *kb_dev;
> +#endif
> };
>
> /*
> @@ -3472,6 +3476,84 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
> }
> }
>
> +#if IS_ENABLED(CONFIG_INPUT)
> +static void gpio2_mic_hotkey_event(struct hda_codec *codec,
> + struct hda_jack_callback *event)
> +{
> + struct alc_spec *spec = codec->spec;
> +
> + /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
> + send both key on and key off event for every interrupt. */
> + input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
> + input_sync(spec->kb_dev);
> + input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
> + input_sync(spec->kb_dev);
> +}
> +#endif
> +
> +static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
> + const struct hda_fixup *fix, int action)
> +{
> +#if IS_ENABLED(CONFIG_INPUT)
> + /* GPIO1 = set according to SKU external amp
> + GPIO2 = mic mute hotkey
> + GPIO3 = mute LED
> + GPIO4 = mic mute LED */
> + static const struct hda_verb gpio_init[] = {
> + { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
> + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
> + { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
> + {}
> + };
> +
> + struct alc_spec *spec = codec->spec;
> +
> + if (action == HDA_FIXUP_ACT_PRE_PROBE) {
> + spec->kb_dev = input_allocate_device();
> + if (!spec->kb_dev) {
> + codec_err(codec, "Out of memory (input_allocate_device)\n");
> + return;
> + }
> + spec->kb_dev->name = "Microphone Mute Button";
> + spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
> + spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
> + if (input_register_device(spec->kb_dev)) {
> + codec_err(codec, "input_register_device failed\n");
> + input_free_device(spec->kb_dev);
> + spec->kb_dev = NULL;
> + r...

Read more...

Changed in linux (Ubuntu):
status: In Progress → Fix Committed
Changed in hwe-next:
status: New → Fix Committed
assignee: nobody → David Henningsson (diwic)
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package linux - 4.0.0-4.6

---------------
linux (4.0.0-4.6) wily; urgency=low

  [ Andy Whitcroft ]

  * Release Tracking Bug
    - LP: #1470233
  * rebase to mainline v4.0.7

  [ Jay Vosburgh ]

  * SAUCE: fan: Proof of concept implementation (v2)
    - LP: #1439706
  * SAUCE: fan: tunnel multiple mapping mode (v3)
    - LP: #1470091

  [ Upstream Kernel Changes ]

  * rebase to v4.0.7
    - LP: #1427680
    - LP: #1462614

 -- Andy Whitcroft <email address hidden> Tue, 30 Jun 2015 16:55:32 +0100

Changed in linux (Ubuntu):
status: Fix Committed → Fix Released
Changed in hwe-next:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.