ALSA: hda - add beep_mode module parameter
The beep_mode parameter for snd-hda-intel module allows to choose among
different digital beep device registation to the input layer.
0 = do not register to the input layer
1 = register to the input layer all time
2 = use "Beep Switch" control exported to user space mixer applications
Also, introduce CONFIG_SND_HDA_INPUT_BEEP_MODE for default value.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 55545e0..25ae10e 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -38,6 +38,17 @@
Say Y here to build a digital beep interface for HD-audio
driver. This interface is used to generate digital beeps.
+config SND_HDA_INPUT_BEEP_MODE
+ int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)"
+ depends on SND_HDA_INPUT_BEEP=y
+ default "1"
+ range 0 2
+ help
+ Set 0 to disable the digital beep interface for HD-audio by default.
+ Set 1 to always enable the digital beep interface for HD-audio by
+ default. Set 2 to control the beep device registration to input
+ layer using a "Beep Switch" in mixer applications.
+
config SND_HDA_INPUT_JACK
bool "Support jack plugging notification via input layer"
depends on INPUT=y || INPUT=SND_HDA_INTEL
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index c819152..9e48798 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -190,14 +190,19 @@
return 0;
if (beep->enabled != enable) {
beep->enabled = enable;
- if (enable) {
- cancel_delayed_work(&beep->unregister_work);
- schedule_work(&beep->register_work);
- } else {
+ if (!enable) {
/* turn off beep */
snd_hda_codec_write_cache(beep->codec, beep->nid, 0,
AC_VERB_SET_BEEP_CONTROL, 0);
- schedule_delayed_work(&beep->unregister_work, HZ);
+ }
+ if (beep->mode == HDA_BEEP_MODE_SWREG) {
+ if (enable) {
+ cancel_delayed_work(&beep->unregister_work);
+ schedule_work(&beep->register_work);
+ } else {
+ schedule_delayed_work(&beep->unregister_work,
+ HZ);
+ }
}
return 1;
}
@@ -223,6 +228,7 @@
beep->nid = nid;
beep->codec = codec;
+ beep->mode = codec->beep_mode;
codec->beep = beep;
INIT_WORK(&beep->register_work, &snd_hda_do_register);
@@ -230,6 +236,11 @@
INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
mutex_init(&beep->mutex);
+ if (beep->mode == HDA_BEEP_MODE_ON) {
+ beep->enabled = 1;
+ snd_hda_do_register(&beep->register_work);
+ }
+
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 53eba8d..17dd1c3 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -24,10 +24,15 @@
#include "hda_codec.h"
+#define HDA_BEEP_MODE_ON 0
+#define HDA_BEEP_MODE_OFF 1
+#define HDA_BEEP_MODE_SWREG 2
+
/* beep information */
struct hda_beep {
struct input_dev *dev;
struct hda_codec *codec;
+ unsigned int mode;
char phys[32];
int tone;
hda_nid_t nid;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index b16678c..5192056 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -772,6 +772,7 @@
/* beep device */
struct hda_beep *beep;
+ unsigned int beep_mode;
/* widget capabilities cache */
unsigned int num_nodes;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e73e395..91bcbda 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -64,6 +64,10 @@
#ifdef CONFIG_SND_HDA_PATCH_LOADER
static char *patch[SNDRV_CARDS];
#endif
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
+ CONFIG_SND_HDA_INPUT_BEEP_MODE};
+#endif
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -91,6 +95,11 @@
module_param_array(patch, charp, NULL, 0444);
MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
#endif
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+module_param_array(beep_mode, int, NULL, 0444);
+MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
+ "(0=off, 1=on, 2=mute switch on/off) (default=1).");
+#endif
#ifdef CONFIG_SND_HDA_POWER_SAVE
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
@@ -404,6 +413,7 @@
unsigned short codec_mask;
int codec_probe_mask; /* copied from probe_mask option */
struct hda_bus *bus;
+ unsigned int beep_mode;
/* CORB/RIRB */
struct azx_rb corb;
@@ -1404,6 +1414,7 @@
err = snd_hda_codec_new(chip->bus, c, &codec);
if (err < 0)
continue;
+ codec->beep_mode = chip->beep_mode;
codecs++;
}
}
@@ -2579,6 +2590,10 @@
goto out_free;
card->private_data = chip;
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+ chip->beep_mode = beep_mode[dev];
+#endif
+
/* create codec instances */
err = azx_codec_create(chip, model[dev]);
if (err < 0)