From: David Henningsson <david.henningsson@canonical.com>
To: ALSA Development Mailing List <alsa-devel@alsa-project.org>
Cc: Takashi Iwai <tiwai@suse.de>
Subject: [RFC PATCH] Fixup automute for Realtek auto parser
Date: Fri, 16 Sep 2011 10:01:48 +0200 [thread overview]
Message-ID: <4E73026C.5090307@canonical.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 543 bytes --]
The ~6 months old functionality for configurable automuting is broken
for the case that the user has only HP and LO (no speakers) - basically
there is an "Automute mode" control, but enabling it does nothing. While
fixing that, I also took the liberty of refactoring/rewriting some of
that code, in order to make it easier to understand and maintain.
Takashi, given you approve/like these changes, I'll go ahead and fix up
the quirk files to fit the new variable names.
--
David Henningsson, Canonical Ltd.
http://launchpad.net/~diwic
[-- Attachment #2: realtek.patch --]
[-- Type: text/x-patch, Size: 8888 bytes --]
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 70ba45e..e3d3553 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -33,6 +33,10 @@
#include "hda_local.h"
#include "hda_beep.h"
+/* FIXME: Temporary since it won't compile otherwise */
+#undef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
+
+
/* unsol event tags */
#define ALC_FRONT_EVENT 0x01
#define ALC_DCVOL_EVENT 0x02
@@ -162,15 +166,17 @@ struct alc_spec {
void (*automute_hook)(struct hda_codec *codec);
/* for pin sensing */
- unsigned int jack_present: 1;
+ unsigned int hp_jack_present: 1;
unsigned int line_jack_present:1;
unsigned int master_mute:1;
unsigned int auto_mic:1;
unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
- unsigned int automute:1; /* HP automute enabled */
- unsigned int detect_line:1; /* Line-out detection enabled */
- unsigned int automute_lines:1; /* automute line-out as well */
- unsigned int automute_hp_lo:1; /* both HP and LO available */
+ unsigned int detect_hp:1; /* Headphones detection enabled */
+ unsigned int detect_line:1; /* Line-out detection enabled */
+ unsigned int automute_speaker:1; /* automute speakers */
+ unsigned int automute_lo:1; /* automute line-out as well */
+ unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
+ unsigned int automute_lo_possible:1; /* there are line outs and HP */
/* other flags */
unsigned int no_analog :1; /* digital I/O only */
@@ -530,8 +536,8 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
}
}
-/* Toggle internal speakers muting */
-static void update_speakers(struct hda_codec *codec)
+/* Toggle outputs muting */
+static void update_outputs(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int on;
@@ -543,10 +549,10 @@ static void update_speakers(struct hda_codec *codec)
do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins, spec->master_mute, true);
- if (!spec->automute)
+ if (!spec->automute_speaker)
on = 0;
else
- on = spec->jack_present | spec->line_jack_present;
+ on = spec->hp_jack_present | spec->line_jack_present;
on |= spec->master_mute;
do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
spec->autocfg.speaker_pins, on, false);
@@ -556,22 +562,22 @@ static void update_speakers(struct hda_codec *codec)
if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
return;
- if (!spec->automute_lines || !spec->automute)
+ if (!spec->automute_lo)
on = 0;
else
- on = spec->jack_present;
+ on = spec->hp_jack_present;
on |= spec->master_mute;
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
spec->autocfg.line_out_pins, on, false);
}
-static void call_update_speakers(struct hda_codec *codec)
+static void call_update_outputs(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
if (spec->automute_hook)
spec->automute_hook(codec);
else
- update_speakers(codec);
+ update_outputs(codec);
}
/* standard HP-automute helper */
@@ -579,12 +585,12 @@ static void alc_hp_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- spec->jack_present =
+ spec->hp_jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins);
- if (!spec->automute)
+ if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo))
return;
- call_update_speakers(codec);
+ call_update_outputs(codec);
}
/* standard line-out-automute helper */
@@ -595,9 +601,9 @@ static void alc_line_automute(struct hda_codec *codec)
spec->line_jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
spec->autocfg.line_out_pins);
- if (!spec->automute || !spec->detect_line)
+ if (!spec->automute_speaker || !spec->detect_line)
return;
- call_update_speakers(codec);
+ call_update_outputs(codec);
}
#define get_connection_index(codec, mux, nid) \
@@ -795,7 +801,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
- if (spec->automute_hp_lo) {
+ if (spec->automute_speaker_possible && spec->automute_lo_possible) {
uinfo->value.enumerated.items = 3;
texts = texts3;
} else {
@@ -814,13 +820,12 @@ static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct alc_spec *spec = codec->spec;
- unsigned int val;
- if (!spec->automute)
- val = 0;
- else if (!spec->automute_lines)
- val = 1;
- else
- val = 2;
+ unsigned int val = 0;
+ if (spec->automute_speaker)
+ val++;
+ if (spec->automute_lo)
+ val++;
+
ucontrol->value.enumerated.item[0] = val;
return 0;
}
@@ -833,28 +838,38 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
switch (ucontrol->value.enumerated.item[0]) {
case 0:
- if (!spec->automute)
+ if (!spec->automute_speaker && !spec->automute_lo)
return 0;
- spec->automute = 0;
+ spec->automute_speaker = 0;
+ spec->automute_lo = 0;
break;
case 1:
- if (spec->automute && !spec->automute_lines)
- return 0;
- spec->automute = 1;
- spec->automute_lines = 0;
+ if (spec->automute_speaker_possible) {
+ if (!spec->automute_lo && spec->automute_speaker)
+ return 0;
+ spec->automute_speaker = 1;
+ spec->automute_lo = 0;
+ }
+ else if (spec->automute_lo_possible) {
+ if (spec->automute_lo)
+ return 0;
+ spec->automute_lo = 1;
+ }
+ else
+ return -EINVAL;
break;
case 2:
- if (!spec->automute_hp_lo)
+ if (!spec->automute_lo_possible || !spec->automute_speaker_possible)
return -EINVAL;
- if (spec->automute && spec->automute_lines)
+ if (spec->automute_speaker && spec->automute_lo)
return 0;
- spec->automute = 1;
- spec->automute_lines = 1;
+ spec->automute_speaker = 1;
+ spec->automute_lo = 1;
break;
default:
return -EINVAL;
}
- call_update_speakers(codec);
+ call_update_outputs(codec);
return 1;
}
@@ -906,8 +921,6 @@ static void alc_init_auto_hp(struct hda_codec *codec)
present++;
if (present < 2) /* need two different output types */
return;
- if (present == 3)
- spec->automute_hp_lo = 1; /* both HP and LO automute */
if (!cfg->speaker_pins[0] &&
cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
@@ -923,6 +936,8 @@ static void alc_init_auto_hp(struct hda_codec *codec)
cfg->hp_outs = cfg->line_outs;
}
+ spec->automute_mode = ALC_AUTOMUTE_PIN;
+
for (i = 0; i < cfg->hp_outs; i++) {
hda_nid_t nid = cfg->hp_pins[i];
if (!is_jack_detectable(codec, nid))
@@ -932,28 +947,32 @@ static void alc_init_auto_hp(struct hda_codec *codec)
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | ALC_HP_EVENT);
- spec->automute = 1;
- spec->automute_mode = ALC_AUTOMUTE_PIN;
- }
- if (spec->automute && cfg->line_out_pins[0] &&
- cfg->speaker_pins[0] &&
- cfg->line_out_pins[0] != cfg->hp_pins[0] &&
- cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t nid = cfg->line_out_pins[i];
- if (!is_jack_detectable(codec, nid))
- continue;
- snd_printdd("realtek: Enable Line-Out auto-muting "
- "on NID 0x%x\n", nid);
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC_FRONT_EVENT);
- spec->detect_line = 1;
+ spec->detect_hp = 1;
+ }
+
+ if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) {
+ if (cfg->speaker_outs)
+ for (i = 0; i < cfg->line_outs; i++) {
+ hda_nid_t nid = cfg->line_out_pins[i];
+ if (!is_jack_detectable(codec, nid))
+ continue;
+ snd_printdd("realtek: Enable Line-Out "
+ "auto-muting on NID 0x%x\n", nid);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | ALC_FRONT_EVENT);
+ spec->detect_line = 1;
}
- spec->automute_lines = spec->detect_line;
+ spec->automute_lo_possible = spec->detect_hp;
}
- if (spec->automute) {
+ spec->automute_speaker_possible = cfg->speaker_outs &&
+ (spec->detect_hp || spec->detect_line);
+
+ spec->automute_lo = spec->automute_lo_possible;
+ spec->automute_speaker = spec->automute_speaker_possible;
+
+ if (spec->automute_speaker_possible || spec->automute_lo_possible) {
/* create a control for automute mode */
alc_add_automute_mode_enum(codec);
spec->unsol_event = alc_sku_unsol_event;
@@ -4640,7 +4659,7 @@ static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
static void alc269_quanta_automute(struct hda_codec *codec)
{
- update_speakers(codec);
+ update_outputs(codec);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_COEF_INDEX, 0x0c);
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next reply other threads:[~2011-09-16 8:01 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-16 8:01 David Henningsson [this message]
2011-09-16 8:31 ` [RFC PATCH] Fixup automute for Realtek auto parser Takashi Iwai
2011-09-16 9:22 ` David Henningsson
2011-09-16 9:35 ` Takashi Iwai
2011-09-16 10:03 ` Takashi Iwai
2011-09-16 10:45 ` David Henningsson
2011-09-16 11:07 ` Takashi Iwai
2011-09-16 11:22 ` David Henningsson
2011-09-16 12:44 ` Takashi Iwai
2011-09-16 14:22 ` David Henningsson
2011-09-16 14:30 ` Takashi Iwai
2011-09-19 9:28 ` David Henningsson
2011-09-19 9:37 ` 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=4E73026C.5090307@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.