From: David Henningsson <david.henningsson@canonical.com>
To: Takashi Iwai <tiwai@suse.de>,
ALSA Development Mailing List <alsa-devel@alsa-project.org>
Subject: [RFC PATCH] HDA: Generic input jack handling
Date: Fri, 07 Oct 2011 13:49:46 +0200 [thread overview]
Message-ID: <4E8EE75A.3050809@canonical.com> (raw)
So, this is what I had in mind for 3.2. Assuming positive feedback from
Takashi I'll go ahead and make a real patch out of this, and to clean up
the Realtek implementation, as well as probably add this method for more
codecs.
Thoughts:
1) The unsol event tags vary wildly between different vendors. How about
standardising that as well?
2) If alc_init_jacks would call the new method, that might regress
model-based (non auto) parsers. Is that a big deal these days?
3) Todo for realtek parser is to clean up all other calls to
snd_input_jack_report so that jacks are not reported twice.
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e9b039c..69390fd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -5284,6 +5284,142 @@ int snd_hda_input_jack_add(struct hda_codec
*codec, hda_nid_t nid, int type,
}
EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
+/**
+ * snd_hda_input_auto_jack_add - Add relevant input jacks based on
+ * auto pin configuration.
+ * @param unsol_tags lists of jack types to enable, terminate with
+ * list entry with jack_type set to 0. If unsol_tag is set to 0,
+ * unsol events will not be enabled for that jack type.
+ * @return 0 or error code
+ */
+int snd_hda_input_auto_jack_add(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg,
+ const struct hda_unsol_jack_tag* unsol_tags)
+{
+ for (; unsol_tags->jack_type; unsol_tags++) {
+ hda_nid_t nid_list_storage[AUTO_CFG_MAX_INS];
+ const hda_nid_t *nid_list;
+ int nid_count = 0;
+ int i;
+ int input_match = AUTO_PIN_MIC;
+
+ switch (unsol_tags->jack_type) {
+ case SND_JACK_LINEIN:
+ input_match = AUTO_PIN_LINE_IN;
+ /* Fall through */
+ case SND_JACK_MICROPHONE:
+ for (i = 0; i < cfg->num_inputs; i++) {
+ if (cfg->inputs[i].type == input_match)
+ nid_list_storage[nid_count++] = cfg->inputs[i].pin;
+ }
+ nid_list = nid_list_storage;
+ break;
+ case SND_JACK_HEADPHONE:
+ if (cfg->line_out_type == AUTO_PIN_HP_OUT) {
+ nid_list = cfg->line_out_pins;
+ nid_count = cfg->line_outs;
+ } else {
+ nid_list = cfg->hp_pins;
+ nid_count = cfg->hp_outs;
+ }
+ break;
+ case SND_JACK_LINEOUT:
+ if (cfg->line_out_type == AUTO_PIN_LINE_OUT) {
+ nid_list = cfg->line_out_pins;
+ nid_count = cfg->line_outs;
+ }
+ break;
+ }
+
+ for (i = 0; i < nid_count; i++) {
+ int pin = nid_list[i];
+ int err;
+ if (!is_jack_detectable(codec, pin))
+ continue;
+
+ if (unsol_tags->unsol_tag) {
+ err = snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | unsol_tags->unsol_tag);
+ if (err)
+ return err;
+ }
+
+ err = snd_hda_input_jack_add(codec, pin,
+ unsol_tags->jack_type, NULL);
+ if (err)
+ return err;
+ snd_hda_input_jack_report(codec, pin);
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_input_auto_jack_add);
+
+void snd_hda_input_jack_report_type(struct hda_codec *codec, int jack_type)
+{
+ struct hda_jack_item *jacks = codec->jacks.list;
+ int i;
+
+ if (!jacks)
+ return;
+
+ for (i = 0; i < codec->jacks.used; i++, jacks++)
+ if (jacks->type == jack_type)
+ snd_hda_input_jack_report(codec, jacks->nid);
+}
+EXPORT_SYMBOL_HDA(snd_hda_input_jack_report_type);
+
+
void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
{
struct hda_jack_item *jacks = codec->jacks.list;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 46c581c..bb59a3f 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -678,11 +678,21 @@ void snd_print_channel_allocation(int spk_alloc,
char *buf, int buflen);
/*
* Input-jack notification support
*/
+
+struct hda_unsol_jack_tag {
+ int jack_type; /* SND_JACK_xxx constant */
+ int unsol_tag; /* event tag */
+};
+
#ifdef CONFIG_SND_HDA_INPUT_JACK
int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int
type,
const char *name);
void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
+void snd_hda_input_jack_report_type(struct hda_codec *codec, int
jack_type);
void snd_hda_input_jack_free(struct hda_codec *codec);
+int snd_hda_input_auto_jack_add(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg,
+ const struct hda_unsol_jack_tag *unsol_tags);
#else /* CONFIG_SND_HDA_INPUT_JACK */
static inline int snd_hda_input_jack_add(struct hda_codec *codec,
hda_nid_t nid, int type,
@@ -694,9 +704,19 @@ static inline void snd_hda_input_jack_report(struct
hda_codec *codec,
hda_nid_t nid)
{
}
+static inline void snd_hda_input_jack_report_type(struct hda_codec *codec,
+ int jack_type)
+{
+}
static inline void snd_hda_input_jack_free(struct hda_codec *codec)
{
}
+static inline int snd_hda_input_auto_jack_add(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg,
+ const struct hda_unsol_jack_tag *unsol_tags)
+{
+ return 0;
+}
#endif /* CONFIG_SND_HDA_INPUT_JACK */
#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index bf53663..90cdd6c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -38,6 +38,7 @@
#define ALC_DCVOL_EVENT 0x02
#define ALC_HP_EVENT 0x04
#define ALC_MIC_EVENT 0x08
+#define ALC_LINEIN_EVENT 0x10
/* for GPIO Poll */
#define GPIO_MASK 0x03
@@ -441,11 +442,21 @@ static void alc_fix_pll_init(struct hda_codec
*codec, hda_nid_t nid,
* Jack-reporting via input-jack layer
*/
+static const struct hda_unsol_jack_tag unsol_tags[] = {
+ {.jack_type = SND_JACK_HEADPHONE, .unsol_tag = ALC_HP_EVENT },
+ {.jack_type = SND_JACK_LINEOUT, .unsol_tag = ALC_FRONT_EVENT },
+ {.jack_type = SND_JACK_MICROPHONE, .unsol_tag = ALC_MIC_EVENT },
+ {.jack_type = SND_JACK_LINEIN, .unsol_tag = ALC_LINEIN_EVENT },
+ {} /* Zero terminator */
+};
+
/* initialization of jacks; currently checks only a few known pins */
static int alc_init_jacks(struct hda_codec *codec)
{
#ifdef CONFIG_SND_HDA_INPUT_JACK
struct alc_spec *spec = codec->spec;
+ snd_hda_input_auto_jack_add(codec, &spec->autocfg, unsol_tags);
+/* ;
int err;
unsigned int hp_nid = spec->autocfg.hp_pins[0];
unsigned int mic_nid = spec->ext_mic_pin;
@@ -472,7 +483,7 @@ static int alc_init_jacks(struct hda_codec *codec)
if (err < 0)
return err;
snd_hda_input_jack_report(codec, dock_nid);
- }
+ }*/
#endif /* CONFIG_SND_HDA_INPUT_JACK */
return 0;
}
@@ -645,12 +656,18 @@ static void alc_sku_unsol_event(struct hda_codec
*codec, unsigned int res)
switch (res) {
case ALC_HP_EVENT:
alc_hp_automute(codec);
+ snd_hda_input_jack_report_type(codec, SND_JACK_HEADPHONE);
break;
case ALC_FRONT_EVENT:
alc_line_automute(codec);
+ snd_hda_input_jack_report_type(codec, SND_JACK_LINEOUT);
break;
case ALC_MIC_EVENT:
alc_mic_automute(codec);
+ snd_hda_input_jack_report_type(codec, SND_JACK_MICROPHONE);
+ break;
+ case ALC_LINEIN_EVENT:
+ snd_hda_input_jack_report_type(codec, SND_JACK_LINEIN);
break;
}
}
--
David Henningsson, Canonical Ltd.
http://launchpad.net/~diwic
next reply other threads:[~2011-10-07 11:49 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-07 11:49 David Henningsson [this message]
2011-10-07 11:52 ` [RFC PATCH] HDA: Generic input jack handling Mark Brown
2011-10-07 12:08 ` Takashi Iwai
2011-10-07 12:46 ` David Henningsson
2011-10-07 13:03 ` Takashi Iwai
2011-10-07 15:11 ` David Henningsson
2011-10-07 15:27 ` Takashi Iwai
2011-10-07 16:04 ` David Henningsson
2011-10-08 7:11 ` Takashi Iwai
2011-10-08 7:29 ` Raymond Yau
2011-10-09 8:38 ` David Henningsson
2011-10-09 10:32 ` Takashi Iwai
2011-10-09 11:14 ` David Henningsson
2011-10-13 6:40 ` Takashi Iwai
2011-10-18 13:13 ` David Henningsson
2011-10-18 13:23 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E8EE75A.3050809@canonical.com \
--to=david.henningsson@canonical.com \
--cc=alsa-devel@alsa-project.org \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.