[alsa-devel] [PATCH] hda: add support for jack detection on IDT/Sigmatel

Matthew Ranostay mranostay at embeddedalley.com
Wed Oct 15 16:43:28 CEST 2008


Added support for jack detection reporting to userspace for
IDT/Sigmatel codecs.

Signed-off-by: Matthew Ranostay <mranostay at embeddedalley.com>
---

diff --git a/core/jack.c b/core/jack.c
index 8133a2b..7a5b07b 100644
--- a/core/jack.c
+++ b/core/jack.c
@@ -95,7 +95,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
 		goto fail_input;
 	}

-	jack->input_dev->phys = "ALSA";
+	jack->input_dev->phys = "ALSA Jack Detection";

 	jack->type = type;

diff --git a/pci/Kconfig b/pci/Kconfig
index 7003711..7e40890 100644
--- a/pci/Kconfig
+++ b/pci/Kconfig
@@ -501,6 +501,7 @@ config SND_HDA_INTEL
 	tristate "Intel HD Audio"
 	select SND_PCM
 	select SND_VMASTER
+	select SND_JACK if INPUT=y || INPUT=SND
 	help
 	  Say Y here to include support for Intel "High Definition
 	  Audio" (Azalia) motherboard devices.
diff --git a/pci/hda/hda_codec.h b/pci/hda/hda_codec.h
index 60468f5..93dc961 100644
--- a/pci/hda/hda_codec.h
+++ b/pci/hda/hda_codec.h
@@ -729,6 +729,9 @@ struct hda_codec {

 	struct snd_hwdep *hwdep;	/* assigned hwdep device */

+	/* jack detection */
+	struct snd_jack *jack;
+
 	/* misc flags */
 	unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
 					     * status change
diff --git a/pci/hda/hda_proc.c b/pci/hda/hda_proc.c
index 743d779..e07652a 100644
--- a/pci/hda/hda_proc.c
+++ b/pci/hda/hda_proc.c
@@ -425,6 +425,22 @@ static void print_unsol_cap(struct snd_info_buffer *buffer,
 		    (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
 }

+static void print_presence_cap(struct snd_info_buffer *buffer,
+			      struct hda_codec *codec, hda_nid_t nid)
+{
+	int presence = snd_hda_codec_read(codec, nid, 0,
+			AC_VERB_GET_PIN_SENSE, 0);
+	int def_conf = snd_hda_codec_read(codec, nid, 0,
+			AC_VERB_GET_CONFIG_DEFAULT, 0x00);
+	def_conf = get_defcfg_connect(def_conf);
+	if (def_conf && def_conf != AC_JACK_PORT_FIXED)
+		return;
+	snd_iprintf(buffer,
+			"  Jack Presence: %s\n",
+			(presence & AC_PINSENSE_PRESENCE)
+				? "Plugged in" : "Unplugged");
+}
+
 static void print_proc_caps(struct snd_info_buffer *buffer,
 			    struct hda_codec *codec, hda_nid_t nid)
 {
@@ -552,6 +568,9 @@ static void print_codec_info(struct snd_info_entry *entry,
 					   AC_PAR_AUDIO_WIDGET_CAP);
 		unsigned int wid_type =
 			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		unsigned int pincap = snd_hda_param_read(codec, nid,
+					 AC_PAR_PIN_CAP);
+
 		hda_nid_t conn[HDA_MAX_CONNECTIONS];
 		int conn_len = 0;

@@ -632,6 +651,9 @@ static void print_codec_info(struct snd_info_entry *entry,
 		if (wid_caps & AC_WCAP_UNSOL_CAP)
 			print_unsol_cap(buffer, codec, nid);

+		if (pincap & AC_PINCAP_PRES_DETECT)
+			print_presence_cap(buffer, codec, nid);
+
 		if (wid_caps & AC_WCAP_POWER)
 			print_power_state(buffer, codec, nid);

diff --git a/pci/hda/patch_sigmatel.c b/pci/hda/patch_sigmatel.c
index a2ac720..a406fa7 100644
--- a/pci/hda/patch_sigmatel.c
+++ b/pci/hda/patch_sigmatel.c
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
+#include <sound/jack.h>
 #include "hda_codec.h"
 #include "hda_local.h"
 #include "hda_patch.h"
@@ -3617,7 +3618,7 @@ static int stac92xx_init(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
-	int i;
+	int i, err;

 	snd_hda_sequence_write(codec, spec->init);

@@ -3639,6 +3640,12 @@ static int stac92xx_init(struct hda_codec *codec)
 		stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
 					 AC_PINCTL_OUT_EN);
 		stac92xx_auto_init_hp_out(codec);
+		/* jack detection */
+		err = snd_jack_new(codec->bus->card,
+			"Headphone Jack Detection",
+			SND_JACK_HEADPHONE, &codec->jack);
+		if (err < 0)
+			return err;
 		/* fake event to set up pins */
 		codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
 	} else {
@@ -3797,6 +3804,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 		presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
 	}

+	if (codec->jack)
+		snd_jack_report(codec->jack,
+			presence ? SND_JACK_HEADPHONE : 0);
+
 	if (presence) {
 		/* disable lineouts, enable hp */
 		if (spec->hp_switch)


More information about the Alsa-devel mailing list