|
@@ -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 " \
|