[alsa-devel] [PATCH v3 0/2] Disable the ThinkPad HW mute/level control when possible
This series is being resurrected after several years, and it's quite different from before, so I'm restarting the version numbers :)
ThinkPad volume and mute controls are a mess. For whatever reason, ThinkPads have mute buttons that send KEY_MUTE *and* control an invisible-to-ALSA mute switch. Some of them have volume controls that interact with this switch as well.
This is a perennial source of problems. On most ThinkPads, if you press mute and then unmute using GUI controls, you have no sound, because userspace and ALSA state gets out of sync with the hardware switch. There's a separate "sound card" that exposes the hardware switch, but userspace code generally doesn't understand that.
There are already a few _OSI(Linux) overrides to turn all the hardware buttons into regular buttons. Rather than quirking ACPI everywhere, just teach thinkpad-acpi to program the buttons for full software control and to disable hardware controls. That allows us to remove the ACPI quirks and have normal mute controls. This approach should be much simpler than adding even more kludgey ALSA integration for questionable gain.
Tested on an X200s (with latching mute by default) and an X220 (with a mute light and toggle mute by default). Everything works as expected.
Changes from v2: - Don't try to change the mute mode on IBM ThinkPads. - Further minor cleanups. - Try to restore the mode on module unload.
Changes from v1: - Simplified the code a bit. - Improved suspend/hibernate behavior.
Andy Lutomirski (2): thinkpad-acpi: Try to use full software mute control acpi: Remove _OSI(Linux) for ThinkPads
drivers/acpi/blacklist.c | 54 ---------------- drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 64 deletions(-)
From: Andy Lutomirski luto@MIT.EDU
ThinkPads have hardware volume controls and three buttons to control them. (These are separate from the standard mixer.) By default, the buttons are:
- Mute: Mutes the hardware volume control and, on some models, generates KEY_MUTE.
- Up: Unmutes, generates KEY_VOLUMEUP, and increases volume if applicable. (Newer thinkpads only have hardware mute/unmute.)
- Down: Unmutes, generates KEY_VOLUMEDOWN, and decreases volume if applicable.
This behavior is unfortunate, since modern userspace will also handle the hotkeys and change the other mixer. If the software mixer is muted and the hardware mixer is unmuted and you push mute, hilarity ensues as they both switch state.
Rather than adding a lot of complex ALSA integration to fix this, just disable the special ThinkPad volume controls when possible. This turns the mute and volume buttons into regular buttons, and standard software controls will work as expected.
ALSA already knows about the mute light on models with a mute light, so everything should just work.
This should also allow us to remove _OSI(Linux) for all ThinkPads.
For future reference: It turns out that we can ask ACPI for one of three behaviors directly on very new models. They are "latch" (the default), "none" (no automatic control), and "toggle" (mute unmutes when muted). All of the modes besides "none" seem to be a bit buggy, though, and there doesn't seem to be a consistent way to get any notification when the HW mute state is changed.
Signed-off-by: Andy Lutomirski luto@mit.edu --- drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3bbc6eb60de5..cfc317f2de23 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6559,6 +6559,17 @@ static struct ibm_struct brightness_driver_data = { * bits 3-0 (volume). Other bits in NVRAM may have other functions, * such as bit 7 which is used to detect repeated presses of MUTE, * and we leave them unchanged. + * + * On newer Lenovo ThinkPads, the EC can automatically change the volume + * in response to user input. Unfortunately, this rarely works well. + * The laptop changes the state of its internal MUTE gate and, on some + * models, sends KEY_MUTE, causing any user code that responds to the + * mute button to get confused. The hardware MUTE gate is also + * unnecessary, since user code can handle the mute button without + * kernel or EC help. + * + * To avoid confusing userspace, we simply disable all EC-based mute + * and volume controls when possible. */
#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT @@ -6613,11 +6624,21 @@ enum tpacpi_volume_capabilities { TPACPI_VOL_CAP_MAX };
+enum tpacpi_mute_btn_mode { + TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */ + /* We don't know what mode 1 is. */ + TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */ + TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */ +}; + static enum tpacpi_volume_access_mode volume_mode = TPACPI_VOL_MODE_MAX;
static enum tpacpi_volume_capabilities volume_capabilities; static bool volume_control_allowed; +static bool software_mute_requested = true; +static bool software_mute_active; +static int software_mute_orig_mode;
/* * Used to syncronize writers to TP_EC_AUDIO and @@ -6635,6 +6656,8 @@ static void tpacpi_volume_checkpoint_nvram(void) return; if (!volume_control_allowed) return; + if (software_mute_active) + return;
vdbg_printk(TPACPI_DBG_MIXER, "trying to checkpoint mixer state to NVRAM...\n"); @@ -6696,6 +6719,12 @@ static int volume_set_status_ec(const u8 status)
dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
+ /* + * On X200s, and possibly on others, it can take a while for + * reads to become correct. + */ + msleep(1); + return 0; }
@@ -6778,6 +6807,57 @@ unlock: return rc; }
+static int volume_set_software_mute(bool startup) +{ + int result; + + if (!tpacpi_is_lenovo()) + return -ENODEV; + + if (startup) { + if (!acpi_evalf(ec_handle, &software_mute_orig_mode, + "HAUM", "qd")) + return -EIO; + + dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, + "Initial HAUM setting was %d\n", + software_mute_orig_mode); + } + + if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd", + (int)TP_EC_MUTE_BTN_NONE)) + return -EIO; + + if (result != TP_EC_MUTE_BTN_NONE) + pr_warn("Unexpected SAUM result %d\n", + result); + + /* + * In software mute mode, the standard codec controls take + * precendence, so we unmute the ThinkPad HW switch at + * startup. Just on case there are SAUM-capable ThinkPads + * with level controls, set max HW volume as well. + */ + if (tp_features.mixer_no_level_control) + result = volume_set_mute(false); + else + result = volume_set_status(TP_EC_VOLUME_MAX); + + if (result != 0) + pr_warn("Failed to unmute the HW mute switch\n"); + + return 0; +} + +static void volume_exit_software_mute(void) +{ + int r; + + if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode) + || r != software_mute_orig_mode) + pr_warn("Failed to restore mute mode\n"); +} + static int volume_alsa_set_volume(const u8 vol) { dbg_printk(TPACPI_DBG_MIXER, @@ -6885,7 +6965,12 @@ static void volume_suspend(void)
static void volume_resume(void) { - volume_alsa_notify_change(); + if (software_mute_active) { + if (volume_set_software_mute(false) < 0) + pr_warn("Failed to restore software mute\n"); + } else { + volume_alsa_notify_change(); + } }
static void volume_shutdown(void) @@ -6901,6 +6986,9 @@ static void volume_exit(void) }
tpacpi_volume_checkpoint_nvram(); + + if (software_mute_active) + volume_exit_software_mute(); }
static int __init volume_create_alsa_mixer(void) @@ -7085,16 +7173,20 @@ static int __init volume_init(struct ibm_init_struct *iibm) "mute is supported, volume control is %s\n", str_supported(!tp_features.mixer_no_level_control));
- rc = volume_create_alsa_mixer(); - if (rc) { - pr_err("Could not create the ALSA mixer interface\n"); - return rc; - } + if (software_mute_requested && volume_set_software_mute(true) == 0) { + software_mute_active = true; + } else { + rc = volume_create_alsa_mixer(); + if (rc) { + pr_err("Could not create the ALSA mixer interface\n"); + return rc; + }
- pr_info("Console audio control enabled, mode: %s\n", - (volume_control_allowed) ? - "override (read/write)" : - "monitor (read only)"); + pr_info("Console audio control enabled, mode: %s\n", + (volume_control_allowed) ? + "override (read/write)" : + "monitor (read only)"); + }
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, "registering volume hotkeys as change notification\n"); @@ -9091,6 +9183,10 @@ MODULE_PARM_DESC(volume_control, "Enables software override for the console audio " "control when true");
+module_param_named(software_mute, software_mute_requested, bool, 0444); +MODULE_PARM_DESC(software_mute, + "Request full software mute control"); + /* ALSA module API parameters */ module_param_named(index, alsa_index, int, 0444); MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
On Fri, 17 Oct 2014, Andy Lutomirski wrote:
ThinkPads have hardware volume controls and three buttons to control them. (These are separate from the standard mixer.) By default, the buttons are:
Mute: Mutes the hardware volume control and, on some models, generates KEY_MUTE.
Up: Unmutes, generates KEY_VOLUMEUP, and increases volume if applicable. (Newer thinkpads only have hardware mute/unmute.)
Down: Unmutes, generates KEY_VOLUMEDOWN, and decreases volume if applicable.
This behavior is unfortunate, since modern userspace will also handle the hotkeys and change the other mixer. If the software mixer is muted and the hardware mixer is unmuted and you push mute, hilarity ensues as they both switch state.
Rather than adding a lot of complex ALSA integration to fix this, just disable the special ThinkPad volume controls when possible. This turns the mute and volume buttons into regular buttons, and standard software controls will work as expected.
ALSA already knows about the mute light on models with a mute light, so everything should just work.
This should also allow us to remove _OSI(Linux) for all ThinkPads.
For future reference: It turns out that we can ask ACPI for one of three behaviors directly on very new models. They are "latch" (the default), "none" (no automatic control), and "toggle" (mute unmutes when muted). All of the modes besides "none" seem to be a bit buggy, though, and there doesn't seem to be a consistent way to get any notification when the HW mute state is changed.
Signed-off-by: Andy Lutomirski luto@mit.edu
Acked-by: Henrique de Moraes Holschuh hmh@hmh.eng.br
drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3bbc6eb60de5..cfc317f2de23 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6559,6 +6559,17 @@ static struct ibm_struct brightness_driver_data = {
- bits 3-0 (volume). Other bits in NVRAM may have other functions,
- such as bit 7 which is used to detect repeated presses of MUTE,
- and we leave them unchanged.
- On newer Lenovo ThinkPads, the EC can automatically change the volume
- in response to user input. Unfortunately, this rarely works well.
- The laptop changes the state of its internal MUTE gate and, on some
- models, sends KEY_MUTE, causing any user code that responds to the
- mute button to get confused. The hardware MUTE gate is also
- unnecessary, since user code can handle the mute button without
- kernel or EC help.
- To avoid confusing userspace, we simply disable all EC-based mute
*/
- and volume controls when possible.
#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT @@ -6613,11 +6624,21 @@ enum tpacpi_volume_capabilities { TPACPI_VOL_CAP_MAX };
+enum tpacpi_mute_btn_mode {
- TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */
- /* We don't know what mode 1 is. */
- TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */
- TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */
+};
static enum tpacpi_volume_access_mode volume_mode = TPACPI_VOL_MODE_MAX;
static enum tpacpi_volume_capabilities volume_capabilities; static bool volume_control_allowed; +static bool software_mute_requested = true; +static bool software_mute_active; +static int software_mute_orig_mode;
/*
- Used to syncronize writers to TP_EC_AUDIO and
@@ -6635,6 +6656,8 @@ static void tpacpi_volume_checkpoint_nvram(void) return; if (!volume_control_allowed) return;
if (software_mute_active)
return;
vdbg_printk(TPACPI_DBG_MIXER, "trying to checkpoint mixer state to NVRAM...\n");
@@ -6696,6 +6719,12 @@ static int volume_set_status_ec(const u8 status)
dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
- /*
* On X200s, and possibly on others, it can take a while for
* reads to become correct.
*/
- msleep(1);
- return 0;
}
@@ -6778,6 +6807,57 @@ unlock: return rc; }
+static int volume_set_software_mute(bool startup) +{
- int result;
- if (!tpacpi_is_lenovo())
return -ENODEV;
- if (startup) {
if (!acpi_evalf(ec_handle, &software_mute_orig_mode,
"HAUM", "qd"))
return -EIO;
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
"Initial HAUM setting was %d\n",
software_mute_orig_mode);
- }
- if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd",
(int)TP_EC_MUTE_BTN_NONE))
return -EIO;
- if (result != TP_EC_MUTE_BTN_NONE)
pr_warn("Unexpected SAUM result %d\n",
result);
- /*
* In software mute mode, the standard codec controls take
* precendence, so we unmute the ThinkPad HW switch at
* startup. Just on case there are SAUM-capable ThinkPads
* with level controls, set max HW volume as well.
*/
- if (tp_features.mixer_no_level_control)
result = volume_set_mute(false);
- else
result = volume_set_status(TP_EC_VOLUME_MAX);
- if (result != 0)
pr_warn("Failed to unmute the HW mute switch\n");
- return 0;
+}
+static void volume_exit_software_mute(void) +{
- int r;
- if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode)
|| r != software_mute_orig_mode)
pr_warn("Failed to restore mute mode\n");
+}
static int volume_alsa_set_volume(const u8 vol) { dbg_printk(TPACPI_DBG_MIXER, @@ -6885,7 +6965,12 @@ static void volume_suspend(void)
static void volume_resume(void) {
- volume_alsa_notify_change();
- if (software_mute_active) {
if (volume_set_software_mute(false) < 0)
pr_warn("Failed to restore software mute\n");
- } else {
volume_alsa_notify_change();
- }
}
static void volume_shutdown(void) @@ -6901,6 +6986,9 @@ static void volume_exit(void) }
tpacpi_volume_checkpoint_nvram();
- if (software_mute_active)
volume_exit_software_mute();
}
static int __init volume_create_alsa_mixer(void) @@ -7085,16 +7173,20 @@ static int __init volume_init(struct ibm_init_struct *iibm) "mute is supported, volume control is %s\n", str_supported(!tp_features.mixer_no_level_control));
- rc = volume_create_alsa_mixer();
- if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
- }
- if (software_mute_requested && volume_set_software_mute(true) == 0) {
software_mute_active = true;
- } else {
rc = volume_create_alsa_mixer();
if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
}
- pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
}
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, "registering volume hotkeys as change notification\n");
@@ -9091,6 +9183,10 @@ MODULE_PARM_DESC(volume_control, "Enables software override for the console audio " "control when true");
+module_param_named(software_mute, software_mute_requested, bool, 0444); +MODULE_PARM_DESC(software_mute,
"Request full software mute control");
/* ALSA module API parameters */ module_param_named(index, alsa_index, int, 0444); MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
On Fri, Oct 31, 2014 at 4:07 PM, Henrique de Moraes Holschuh hmh@hmh.eng.br wrote:
On Fri, 17 Oct 2014, Andy Lutomirski wrote:
ThinkPads have hardware volume controls and three buttons to control them. (These are separate from the standard mixer.) By default, the buttons are:
Mute: Mutes the hardware volume control and, on some models, generates KEY_MUTE.
Up: Unmutes, generates KEY_VOLUMEUP, and increases volume if applicable. (Newer thinkpads only have hardware mute/unmute.)
Down: Unmutes, generates KEY_VOLUMEDOWN, and decreases volume if applicable.
This behavior is unfortunate, since modern userspace will also handle the hotkeys and change the other mixer. If the software mixer is muted and the hardware mixer is unmuted and you push mute, hilarity ensues as they both switch state.
Rather than adding a lot of complex ALSA integration to fix this, just disable the special ThinkPad volume controls when possible. This turns the mute and volume buttons into regular buttons, and standard software controls will work as expected.
ALSA already knows about the mute light on models with a mute light, so everything should just work.
This should also allow us to remove _OSI(Linux) for all ThinkPads.
For future reference: It turns out that we can ask ACPI for one of three behaviors directly on very new models. They are "latch" (the default), "none" (no automatic control), and "toggle" (mute unmutes when muted). All of the modes besides "none" seem to be a bit buggy, though, and there doesn't seem to be a consistent way to get any notification when the HW mute state is changed.
Signed-off-by: Andy Lutomirski luto@mit.edu
Acked-by: Henrique de Moraes Holschuh hmh@hmh.eng.br
What tree do these go through? I haven't spotted them in linux-next.
Thanks, Andy
drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3bbc6eb60de5..cfc317f2de23 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6559,6 +6559,17 @@ static struct ibm_struct brightness_driver_data = {
- bits 3-0 (volume). Other bits in NVRAM may have other functions,
- such as bit 7 which is used to detect repeated presses of MUTE,
- and we leave them unchanged.
- On newer Lenovo ThinkPads, the EC can automatically change the volume
- in response to user input. Unfortunately, this rarely works well.
- The laptop changes the state of its internal MUTE gate and, on some
- models, sends KEY_MUTE, causing any user code that responds to the
- mute button to get confused. The hardware MUTE gate is also
- unnecessary, since user code can handle the mute button without
- kernel or EC help.
- To avoid confusing userspace, we simply disable all EC-based mute
*/
- and volume controls when possible.
#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT @@ -6613,11 +6624,21 @@ enum tpacpi_volume_capabilities { TPACPI_VOL_CAP_MAX };
+enum tpacpi_mute_btn_mode {
TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */
/* We don't know what mode 1 is. */
TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */
TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */
+};
static enum tpacpi_volume_access_mode volume_mode = TPACPI_VOL_MODE_MAX;
static enum tpacpi_volume_capabilities volume_capabilities; static bool volume_control_allowed; +static bool software_mute_requested = true; +static bool software_mute_active; +static int software_mute_orig_mode;
/*
- Used to syncronize writers to TP_EC_AUDIO and
@@ -6635,6 +6656,8 @@ static void tpacpi_volume_checkpoint_nvram(void) return; if (!volume_control_allowed) return;
if (software_mute_active)
return; vdbg_printk(TPACPI_DBG_MIXER, "trying to checkpoint mixer state to NVRAM...\n");
@@ -6696,6 +6719,12 @@ static int volume_set_status_ec(const u8 status)
dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
/*
* On X200s, and possibly on others, it can take a while for
* reads to become correct.
*/
msleep(1);
return 0;
}
@@ -6778,6 +6807,57 @@ unlock: return rc; }
+static int volume_set_software_mute(bool startup) +{
int result;
if (!tpacpi_is_lenovo())
return -ENODEV;
if (startup) {
if (!acpi_evalf(ec_handle, &software_mute_orig_mode,
"HAUM", "qd"))
return -EIO;
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
"Initial HAUM setting was %d\n",
software_mute_orig_mode);
}
if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd",
(int)TP_EC_MUTE_BTN_NONE))
return -EIO;
if (result != TP_EC_MUTE_BTN_NONE)
pr_warn("Unexpected SAUM result %d\n",
result);
/*
* In software mute mode, the standard codec controls take
* precendence, so we unmute the ThinkPad HW switch at
* startup. Just on case there are SAUM-capable ThinkPads
* with level controls, set max HW volume as well.
*/
if (tp_features.mixer_no_level_control)
result = volume_set_mute(false);
else
result = volume_set_status(TP_EC_VOLUME_MAX);
if (result != 0)
pr_warn("Failed to unmute the HW mute switch\n");
return 0;
+}
+static void volume_exit_software_mute(void) +{
int r;
if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode)
|| r != software_mute_orig_mode)
pr_warn("Failed to restore mute mode\n");
+}
static int volume_alsa_set_volume(const u8 vol) { dbg_printk(TPACPI_DBG_MIXER, @@ -6885,7 +6965,12 @@ static void volume_suspend(void)
static void volume_resume(void) {
volume_alsa_notify_change();
if (software_mute_active) {
if (volume_set_software_mute(false) < 0)
pr_warn("Failed to restore software mute\n");
} else {
volume_alsa_notify_change();
}
}
static void volume_shutdown(void) @@ -6901,6 +6986,9 @@ static void volume_exit(void) }
tpacpi_volume_checkpoint_nvram();
if (software_mute_active)
volume_exit_software_mute();
}
static int __init volume_create_alsa_mixer(void) @@ -7085,16 +7173,20 @@ static int __init volume_init(struct ibm_init_struct *iibm) "mute is supported, volume control is %s\n", str_supported(!tp_features.mixer_no_level_control));
rc = volume_create_alsa_mixer();
if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
}
if (software_mute_requested && volume_set_software_mute(true) == 0) {
software_mute_active = true;
} else {
rc = volume_create_alsa_mixer();
if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
}
pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
} vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, "registering volume hotkeys as change notification\n");
@@ -9091,6 +9183,10 @@ MODULE_PARM_DESC(volume_control, "Enables software override for the console audio " "control when true");
+module_param_named(software_mute, software_mute_requested, bool, 0444); +MODULE_PARM_DESC(software_mute,
"Request full software mute control");
/* ALSA module API parameters */ module_param_named(index, alsa_index, int, 0444); MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
-- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
On Mon, 08 Dec 2014, Andy Lutomirski wrote:
On Fri, Oct 31, 2014 at 4:07 PM, Henrique de Moraes Holschuh hmh@hmh.eng.br wrote:
...
Signed-off-by: Andy Lutomirski luto@mit.edu
Acked-by: Henrique de Moraes Holschuh hmh@hmh.eng.br
What tree do these go through? I haven't spotted them in linux-next.
X86 PLATFORM DRIVERS M: Darren Hart dvhart@infradead.org L: platform-driver-x86@vger.kernel.org T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git S: Maintained F: drivers/platform/x86/
Darren, could you pick up this patch series, please?
You were missing in the Cc list, and it seems to have fallen through the cracks :-(
Maybe we could use https://patchwork.kernel.org/ for platform-driver-x86 ?
On Tue, Dec 09, 2014 at 05:53:42PM -0200, Henrique de Moraes Holschuh wrote:
On Mon, 08 Dec 2014, Andy Lutomirski wrote:
On Fri, Oct 31, 2014 at 4:07 PM, Henrique de Moraes Holschuh hmh@hmh.eng.br wrote:
...
Signed-off-by: Andy Lutomirski luto@mit.edu
Acked-by: Henrique de Moraes Holschuh hmh@hmh.eng.br
What tree do these go through? I haven't spotted them in linux-next.
X86 PLATFORM DRIVERS M: Darren Hart dvhart@infradead.org L: platform-driver-x86@vger.kernel.org T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git S: Maintained F: drivers/platform/x86/
Darren, could you pick up this patch series, please?
You were missing in the Cc list, and it seems to have fallen through the cracks :-(
Maybe we could use https://patchwork.kernel.org/ for platform-driver-x86 ?
For the time being, please continue to Cc the maintainer on all patches. That's a minimum requirement anyway. I'm not opposed to discussing patchwork, but I don't want it to be a substitute to following standard mailing list practices.
AFAICT the only reason to set _OSI(Linux) on ThinkPads is to get sensible mute button behavior. Now that the thinkpad_acpi driver can do this on is own, there is no reason to keep the ACPI quirk.
Cc: Len Brown len.brown@intel.com Cc: Jerone Young jerone.young@canonical.com Signed-off-by: Andy Lutomirski luto@amacapital.net --- drivers/acpi/blacklist.c | 54 ------------------------------------------------ 1 file changed, 54 deletions(-)
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 36eb42e3b0bb..4a3cbb5d3c55 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -265,60 +265,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { */
/* - * Lenovo has a mix of systems OSI(Linux) situations - * and thus we can not wildcard the vendor. - * - * _OSI(Linux) helps sound - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), - * T400, T500 - * _OSI(Linux) has Linux specific hooks - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), - * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), - * DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), - */ - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad R61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad X61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T400", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), - }, - }, - /* * Without this this EEEpc exports a non working WMI interface, with * this it exports a working "good old" eeepc_laptop interface, fixing * both brightness control, and rfkill not working.
On Fri, 17 Oct 2014, Andy Lutomirski wrote:
AFAICT the only reason to set _OSI(Linux) on ThinkPads is to get sensible mute button behavior. Now that the thinkpad_acpi driver can do this on is own, there is no reason to keep the ACPI quirk.
Cc: Len Brown len.brown@intel.com Cc: Jerone Young jerone.young@canonical.com Signed-off-by: Andy Lutomirski luto@amacapital.net
Acked-by: Henrique de Moraes Holschuh hmh@hmh.eng.br
drivers/acpi/blacklist.c | 54 ------------------------------------------------ 1 file changed, 54 deletions(-)
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 36eb42e3b0bb..4a3cbb5d3c55 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -265,60 +265,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { */
/*
* Lenovo has a mix of systems OSI(Linux) situations
* and thus we can not wildcard the vendor.
*
* _OSI(Linux) helps sound
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
* T400, T500
* _OSI(Linux) has Linux specific hooks
* DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
* _OSI(Linux) is a NOP:
* DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
* DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"),
*/
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Lenovo ThinkPad R61",
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
},
- },
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Lenovo ThinkPad T61",
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
},
- },
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Lenovo ThinkPad X61",
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
},
- },
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Lenovo ThinkPad T400",
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"),
},
- },
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Lenovo ThinkPad T500",
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
},
- },
- /*
- Without this this EEEpc exports a non working WMI interface, with
- this it exports a working "good old" eeepc_laptop interface, fixing
- both brightness control, and rfkill not working.
On Fri, Oct 17, 2014 at 05:04:28PM -0700, Andy Lutomirski wrote:
This series is being resurrected after several years, and it's quite different from before, so I'm restarting the version numbers :)
ThinkPad volume and mute controls are a mess. For whatever reason, ThinkPads have mute buttons that send KEY_MUTE *and* control an invisible-to-ALSA mute switch. Some of them have volume controls that interact with this switch as well.
This is a perennial source of problems. On most ThinkPads, if you press mute and then unmute using GUI controls, you have no sound, because userspace and ALSA state gets out of sync with the hardware switch. There's a separate "sound card" that exposes the hardware switch, but userspace code generally doesn't understand that.
There are already a few _OSI(Linux) overrides to turn all the hardware buttons into regular buttons. Rather than quirking ACPI everywhere, just teach thinkpad-acpi to program the buttons for full software control and to disable hardware controls. That allows us to remove the ACPI quirks and have normal mute controls. This approach should be much simpler than adding even more kludgey ALSA integration for questionable gain.
Tested on an X200s (with latching mute by default) and an X220 (with a mute light and toggle mute by default). Everything works as expected.
Changes from v2:
- Don't try to change the mute mode on IBM ThinkPads.
- Further minor cleanups.
- Try to restore the mode on module unload.
Changes from v1:
- Simplified the code a bit.
- Improved suspend/hibernate behavior.
Andy Lutomirski (2): thinkpad-acpi: Try to use full software mute control acpi: Remove _OSI(Linux) for ThinkPads
drivers/acpi/blacklist.c | 54 ---------------- drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 64 deletions(-)
Andy, is this the latest version?
On Thu, Dec 4, 2014 at 3:55 AM, Darren Hart dvhart@infradead.org wrote:
On Fri, Oct 17, 2014 at 05:04:28PM -0700, Andy Lutomirski wrote:
This series is being resurrected after several years, and it's quite different from before, so I'm restarting the version numbers :)
ThinkPad volume and mute controls are a mess. For whatever reason, ThinkPads have mute buttons that send KEY_MUTE *and* control an invisible-to-ALSA mute switch. Some of them have volume controls that interact with this switch as well.
This is a perennial source of problems. On most ThinkPads, if you press mute and then unmute using GUI controls, you have no sound, because userspace and ALSA state gets out of sync with the hardware switch. There's a separate "sound card" that exposes the hardware switch, but userspace code generally doesn't understand that.
There are already a few _OSI(Linux) overrides to turn all the hardware buttons into regular buttons. Rather than quirking ACPI everywhere, just teach thinkpad-acpi to program the buttons for full software control and to disable hardware controls. That allows us to remove the ACPI quirks and have normal mute controls. This approach should be much simpler than adding even more kludgey ALSA integration for questionable gain.
Tested on an X200s (with latching mute by default) and an X220 (with a mute light and toggle mute by default). Everything works as expected.
Changes from v2:
- Don't try to change the mute mode on IBM ThinkPads.
- Further minor cleanups.
- Try to restore the mode on module unload.
Changes from v1:
- Simplified the code a bit.
- Improved suspend/hibernate behavior.
Andy Lutomirski (2): thinkpad-acpi: Try to use full software mute control acpi: Remove _OSI(Linux) for ThinkPads
drivers/acpi/blacklist.c | 54 ---------------- drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 64 deletions(-)
Andy, is this the latest version?
Yes.
--Andy
-- Darren Hart Intel Open Source Technology Center
On Tue, Dec 09, 2014 at 02:47:34PM -0800, Andy Lutomirski wrote:
On Thu, Dec 4, 2014 at 3:55 AM, Darren Hart dvhart@infradead.org wrote:
On Fri, Oct 17, 2014 at 05:04:28PM -0700, Andy Lutomirski wrote:
This series is being resurrected after several years, and it's quite different from before, so I'm restarting the version numbers :)
ThinkPad volume and mute controls are a mess. For whatever reason, ThinkPads have mute buttons that send KEY_MUTE *and* control an invisible-to-ALSA mute switch. Some of them have volume controls that interact with this switch as well.
This is a perennial source of problems. On most ThinkPads, if you press mute and then unmute using GUI controls, you have no sound, because userspace and ALSA state gets out of sync with the hardware switch. There's a separate "sound card" that exposes the hardware switch, but userspace code generally doesn't understand that.
There are already a few _OSI(Linux) overrides to turn all the hardware buttons into regular buttons. Rather than quirking ACPI everywhere, just teach thinkpad-acpi to program the buttons for full software control and to disable hardware controls. That allows us to remove the ACPI quirks and have normal mute controls. This approach should be much simpler than adding even more kludgey ALSA integration for questionable gain.
Tested on an X200s (with latching mute by default) and an X220 (with a mute light and toggle mute by default). Everything works as expected.
Changes from v2:
- Don't try to change the mute mode on IBM ThinkPads.
- Further minor cleanups.
- Try to restore the mode on module unload.
Changes from v1:
- Simplified the code a bit.
- Improved suspend/hibernate behavior.
Andy Lutomirski (2): thinkpad-acpi: Try to use full software mute control acpi: Remove _OSI(Linux) for ThinkPads
drivers/acpi/blacklist.c | 54 ---------------- drivers/platform/x86/thinkpad_acpi.c | 116 ++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 64 deletions(-)
Andy, is this the latest version?
Yes.
Queued to for-next. Pending anything unforseen, I'll attempt to get this into 3.19.
On Wed, 10 Dec 2014, Darren Hart wrote:
Queued to for-next. Pending anything unforseen, I'll attempt to get this into 3.19.
Thank you!
participants (3)
-
Andy Lutomirski
-
Darren Hart
-
Henrique de Moraes Holschuh