aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_jack.c40
-rw-r--r--sound/pci/hda/hda_jack.h10
-rw-r--r--sound/pci/hda/patch_hdmi.c2
3 files changed, 42 insertions, 10 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 87498235787a..74b46952fc98 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -339,9 +339,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
if (jack->nid) {
if (!jack->jack || jack->block_report)
continue;
- state = get_jack_plug_state(jack->pin_sense);
- snd_jack_report(jack->jack,
- state ? jack->type : 0);
+ state = jack->button_state;
+ if (get_jack_plug_state(jack->pin_sense))
+ state |= jack->type;
+ snd_jack_report(jack->jack, state);
+ if (jack->button_state) {
+ snd_jack_report(jack->jack,
+ state & ~jack->button_state);
+ jack->button_state = 0; /* button released */
+ }
}
}
EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
@@ -379,15 +385,19 @@ static void hda_free_jack_priv(struct snd_jack *jack)
* @nid: pin NID to assign
* @name: string name for the jack
* @phantom_jack: flag to deal as a phantom jack
+ * @type: jack type bits to be reported, 0 for guessing from pincfg
+ * @keymap: optional jack / key mapping
*
* This assigns a jack-detection kctl to the given pin. The kcontrol
* will have the given name and index.
*/
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, bool phantom_jack)
+ const char *name, bool phantom_jack,
+ int type, const struct hda_jack_keymap *keymap)
{
struct hda_jack_tbl *jack;
- int err, state, type;
+ const struct hda_jack_keymap *map;
+ int err, state, buttons;
jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
@@ -395,16 +405,30 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
if (jack->jack)
return 0; /* already created */
- type = get_input_jack_type(codec, nid);
- err = snd_jack_new(codec->card, name, type,
+ if (!type)
+ type = get_input_jack_type(codec, nid);
+
+ buttons = 0;
+ if (keymap) {
+ for (map = keymap; map->type; map++)
+ buttons |= map->type;
+ }
+
+ err = snd_jack_new(codec->card, name, type | buttons,
&jack->jack, true, phantom_jack);
if (err < 0)
return err;
jack->phantom_jack = !!phantom_jack;
jack->type = type;
+ jack->button_state = 0;
jack->jack->private_data = jack;
jack->jack->private_free = hda_free_jack_priv;
+ if (keymap) {
+ for (map = keymap; map->type; map++)
+ snd_jack_set_key(jack->jack, map->type, map->key);
+ }
+
state = snd_hda_jack_detect(codec, nid);
snd_jack_report(jack->jack, state ? jack->type : 0);
@@ -437,7 +461,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
if (phantom_jack)
/* Example final name: "Internal Mic Phantom Jack" */
strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
- err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
+ err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, 0, NULL);
if (err < 0)
return err;
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 695a652cc6b3..1d713201c160 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -13,6 +13,7 @@
#define __SOUND_HDA_JACK_H
#include <linux/err.h>
+#include <sound/jack.h>
struct auto_pin_cfg;
struct hda_jack_tbl;
@@ -42,9 +43,15 @@ struct hda_jack_tbl {
hda_nid_t gating_jack; /* valid when gating jack plugged */
hda_nid_t gated_jack; /* gated is dependent on this jack */
int type;
+ int button_state;
struct snd_jack *jack;
};
+struct hda_jack_keymap {
+ enum snd_jack_types type;
+ int key;
+};
+
struct hda_jack_tbl *
snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
struct hda_jack_tbl *
@@ -84,7 +91,8 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, bool phantom_jack);
+ const char *name, bool phantom_jack,
+ int type, const struct hda_jack_keymap *keymap);
int snd_hda_jack_add_kctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 5fb3fa660b89..1e5412800d24 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2142,7 +2142,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
strncat(hdmi_str, " Phantom",
sizeof(hdmi_str) - strlen(hdmi_str) - 1);
ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,
- phantom_jack);
+ phantom_jack, 0, NULL);
if (ret < 0)
return ret;
jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);