diff mbox

[5/8] thinkpad-acpi: disable volume control

Message ID 1260921073-7686-6-git-send-email-hmh@hmh.eng.br (mailing list archive)
State Accepted
Headers show

Commit Message

Henrique de Moraes Holschuh Dec. 15, 2009, 11:51 p.m. UTC
None
diff mbox

Patch

diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index bd87682..6a58143 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -1097,6 +1097,18 @@  Volume control
 
 procfs: /proc/acpi/ibm/volume
 
+NOTE: by default, the volume control interface operates in read-only
+mode, as it is supposed to be used for on-screen-display purposes.
+The read/write mode can be enabled through the use of the
+"volume_control=1" module parameter.
+
+NOTE: distros are urged to not enable volume_control by default, this
+should be done by the local admin only.  The ThinkPad UI is for the
+console audio control to be done through the volume keys only, and for
+the desktop environment to just provide on-screen-display feedback.
+Software volume control should be done only in the main AC97/HDA
+mixer.
+
 This feature allows volume control on ThinkPad models with a digital
 volume knob (when available, not all models have it), as well as
 mute/unmute control.  The available commands are:
@@ -1465,3 +1477,4 @@  Sysfs interface changelog:
 0x020600:	Marker for backlight change event support.
 
 0x020700:	Support for mute-only mixers.
+		Volume control in read-only mode by default.
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 4d909d5..2d74926 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -311,6 +311,7 @@  static struct {
 
 static struct {
 	u16 hotkey_mask_ff:1;
+	u16 volume_ctrl_forbidden:1;
 } tp_warned;
 
 struct thinkpad_id_data {
@@ -6434,6 +6435,7 @@  static enum tpacpi_volume_access_mode volume_mode =
 	TPACPI_VOL_MODE_MAX;
 
 static enum tpacpi_volume_capabilities volume_capabilities;
+static int volume_control_allowed;
 
 /*
  * Used to syncronize writers to TP_EC_AUDIO and
@@ -6449,6 +6451,8 @@  static void tpacpi_volume_checkpoint_nvram(void)
 
 	if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
 		return;
+	if (!volume_control_allowed)
+		return;
 
 	vdbg_printk(TPACPI_DBG_MIXER,
 		"trying to checkpoint mixer state to NVRAM...\n");
@@ -6691,6 +6695,12 @@  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));
 
+	printk(TPACPI_INFO
+		"Console audio control enabled, mode: %s\n",
+		(volume_control_allowed) ?
+			"override (read/write)" :
+			"monitor (read only)");
+
 	return 0;
 }
 
@@ -6711,11 +6721,16 @@  static int volume_read(char *p)
 		len += sprintf(p + len, "mute:\t\t%s\n",
 				onoff(status, TP_EC_AUDIO_MUTESW));
 
-		len += sprintf(p + len, "commands:\tunmute, mute\n");
-		if (!tp_features.mixer_no_level_control) {
-			len += sprintf(p + len, "commands:\tup, down\n");
-			len += sprintf(p + len, "commands:\tlevel <level>"
-			       " (<level> is 0-%d)\n", TP_EC_VOLUME_MAX);
+		if (volume_control_allowed) {
+			len += sprintf(p + len, "commands:\tunmute, mute\n");
+			if (!tp_features.mixer_no_level_control) {
+				len += sprintf(p + len,
+					       "commands:\tup, down\n");
+				len += sprintf(p + len,
+					       "commands:\tlevel <level>"
+					       " (<level> is 0-%d)\n",
+					       TP_EC_VOLUME_MAX);
+			}
 		}
 	}
 
@@ -6730,6 +6745,23 @@  static int volume_write(char *buf)
 	char *cmd;
 	int rc;
 
+	/*
+	 * We do allow volume control at driver startup, so that the
+	 * user can set initial state through the volume=... parameter hack.
+	 */
+	if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
+		if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
+			tp_warned.volume_ctrl_forbidden = 1;
+			printk(TPACPI_NOTICE
+				"Console audio control in monitor mode, "
+				"changes are not allowed.\n");
+			printk(TPACPI_NOTICE
+				"Use the volume_control=1 module parameter "
+				"to enable volume control\n");
+		}
+		return -EPERM;
+	}
+
 	rc = volume_get_status(&s);
 	if (rc < 0)
 		return rc;
@@ -8515,6 +8547,11 @@  MODULE_PARM_DESC(volume_capabilities,
 		 "Selects the mixer capabilites: "
 		 "0=auto, 1=volume and mute, 2=mute only");
 
+module_param_named(volume_control, volume_control_allowed, bool, 0444);
+MODULE_PARM_DESC(volume_control,
+		 "Enables software override for the console audio "
+		 "control when true");
+
 #define TPACPI_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
 	MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \