diff options
-rw-r--r-- | Documentation/laptops/thinkpad-acpi.txt | 58 | ||||
-rw-r--r-- | drivers/platform/x86/Kconfig | 28 | ||||
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 59 |
3 files changed, 123 insertions, 22 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 169091f75e6d..75afa1229fd7 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -1092,8 +1092,8 @@ WARNING: | |||
1092 | its level up and down at every change. | 1092 | its level up and down at every change. |
1093 | 1093 | ||
1094 | 1094 | ||
1095 | Volume control | 1095 | Volume control (Console Audio control) |
1096 | -------------- | 1096 | -------------------------------------- |
1097 | 1097 | ||
1098 | procfs: /proc/acpi/ibm/volume | 1098 | procfs: /proc/acpi/ibm/volume |
1099 | ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC" | 1099 | ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC" |
@@ -1110,9 +1110,53 @@ the desktop environment to just provide on-screen-display feedback. | |||
1110 | Software volume control should be done only in the main AC97/HDA | 1110 | Software volume control should be done only in the main AC97/HDA |
1111 | mixer. | 1111 | mixer. |
1112 | 1112 | ||
1113 | This feature allows volume control on ThinkPad models with a digital | 1113 | |
1114 | volume knob (when available, not all models have it), as well as | 1114 | About the ThinkPad Console Audio control: |
1115 | mute/unmute control. The available commands are: | 1115 | |
1116 | ThinkPads have a built-in amplifier and muting circuit that drives the | ||
1117 | console headphone and speakers. This circuit is after the main AC97 | ||
1118 | or HDA mixer in the audio path, and under exclusive control of the | ||
1119 | firmware. | ||
1120 | |||
1121 | ThinkPads have three special hotkeys to interact with the console | ||
1122 | audio control: volume up, volume down and mute. | ||
1123 | |||
1124 | It is worth noting that the normal way the mute function works (on | ||
1125 | ThinkPads that do not have a "mute LED") is: | ||
1126 | |||
1127 | 1. Press mute to mute. It will *always* mute, you can press it as | ||
1128 | many times as you want, and the sound will remain mute. | ||
1129 | |||
1130 | 2. Press either volume key to unmute the ThinkPad (it will _not_ | ||
1131 | change the volume, it will just unmute). | ||
1132 | |||
1133 | This is a very superior design when compared to the cheap software-only | ||
1134 | mute-toggle solution found on normal consumer laptops: you can be | ||
1135 | absolutely sure the ThinkPad will not make noise if you press the mute | ||
1136 | button, no matter the previous state. | ||
1137 | |||
1138 | The IBM ThinkPads, and the earlier Lenovo ThinkPads have variable-gain | ||
1139 | amplifiers driving the speakers and headphone output, and the firmware | ||
1140 | also handles volume control for the headphone and speakers on these | ||
1141 | ThinkPads without any help from the operating system (this volume | ||
1142 | control stage exists after the main AC97 or HDA mixer in the audio | ||
1143 | path). | ||
1144 | |||
1145 | The newer Lenovo models only have firmware mute control, and depend on | ||
1146 | the main HDA mixer to do volume control (which is done by the operating | ||
1147 | system). In this case, the volume keys are filtered out for unmute | ||
1148 | key press (there are some firmware bugs in this area) and delivered as | ||
1149 | normal key presses to the operating system (thinkpad-acpi is not | ||
1150 | involved). | ||
1151 | |||
1152 | |||
1153 | The ThinkPad-ACPI volume control: | ||
1154 | |||
1155 | The preferred way to interact with the Console Audio control is the | ||
1156 | ALSA interface. | ||
1157 | |||
1158 | The legacy procfs interface allows one to read the current state, | ||
1159 | and if volume control is enabled, accepts the following commands: | ||
1116 | 1160 | ||
1117 | echo up >/proc/acpi/ibm/volume | 1161 | echo up >/proc/acpi/ibm/volume |
1118 | echo down >/proc/acpi/ibm/volume | 1162 | echo down >/proc/acpi/ibm/volume |
@@ -1121,12 +1165,10 @@ mute/unmute control. The available commands are: | |||
1121 | echo 'level <level>' >/proc/acpi/ibm/volume | 1165 | echo 'level <level>' >/proc/acpi/ibm/volume |
1122 | 1166 | ||
1123 | The <level> number range is 0 to 14 although not all of them may be | 1167 | The <level> number range is 0 to 14 although not all of them may be |
1124 | distinct. The unmute the volume after the mute command, use either the | 1168 | distinct. To unmute the volume after the mute command, use either the |
1125 | up or down command (the level command will not unmute the volume), or | 1169 | up or down command (the level command will not unmute the volume), or |
1126 | the unmute command. | 1170 | the unmute command. |
1127 | 1171 | ||
1128 | The current volume level and mute state is shown in the file. | ||
1129 | |||
1130 | You can use the volume_capabilities parameter to tell the driver | 1172 | You can use the volume_capabilities parameter to tell the driver |
1131 | whether your thinkpad has volume control or mute-only control: | 1173 | whether your thinkpad has volume control or mute-only control: |
1132 | volume_capabilities=1 for mixers with mute and volume control, | 1174 | volume_capabilities=1 for mixers with mute and volume control, |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index ec4faffe6b05..db32c25e3605 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -231,8 +231,36 @@ config THINKPAD_ACPI | |||
231 | 231 | ||
232 | This driver was formerly known as ibm-acpi. | 232 | This driver was formerly known as ibm-acpi. |
233 | 233 | ||
234 | Extra functionality will be available if the rfkill (CONFIG_RFKILL) | ||
235 | and/or ALSA (CONFIG_SND) subsystems are available in the kernel. | ||
236 | Note that if you want ThinkPad-ACPI to be built-in instead of | ||
237 | modular, ALSA and rfkill will also have to be built-in. | ||
238 | |||
234 | If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. | 239 | If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. |
235 | 240 | ||
241 | config THINKPAD_ACPI_ALSA_SUPPORT | ||
242 | bool "Console audio control ALSA interface" | ||
243 | depends on THINKPAD_ACPI | ||
244 | depends on SND | ||
245 | depends on SND = y || THINKPAD_ACPI = SND | ||
246 | default y | ||
247 | ---help--- | ||
248 | Enables monitoring of the built-in console audio output control | ||
249 | (headphone and speakers), which is operated by the mute and (in | ||
250 | some ThinkPad models) volume hotkeys. | ||
251 | |||
252 | If this option is enabled, ThinkPad-ACPI will export an ALSA card | ||
253 | with a single read-only mixer control, which should be used for | ||
254 | on-screen-display feedback purposes by the Desktop Environment. | ||
255 | |||
256 | Optionally, the driver will also allow software control (the | ||
257 | ALSA mixer will be made read-write). Please refer to the driver | ||
258 | documentation for details. | ||
259 | |||
260 | All IBM models have both volume and mute control. Newer Lenovo | ||
261 | models only have mute control (the volume hotkeys are just normal | ||
262 | keys and volume control is done through the main HDA mixer). | ||
263 | |||
236 | config THINKPAD_ACPI_DEBUGFACILITIES | 264 | config THINKPAD_ACPI_DEBUGFACILITIES |
237 | bool "Maintainer debug facilities" | 265 | bool "Maintainer debug facilities" |
238 | depends on THINKPAD_ACPI | 266 | depends on THINKPAD_ACPI |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 448c8aeb166b..e67e4feb35cb 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -6384,11 +6384,13 @@ static struct ibm_struct brightness_driver_data = { | |||
6384 | * and we leave them unchanged. | 6384 | * and we leave them unchanged. |
6385 | */ | 6385 | */ |
6386 | 6386 | ||
6387 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT | ||
6388 | |||
6387 | #define TPACPI_ALSA_DRVNAME "ThinkPad EC" | 6389 | #define TPACPI_ALSA_DRVNAME "ThinkPad EC" |
6388 | #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" | 6390 | #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" |
6389 | #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME | 6391 | #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME |
6390 | 6392 | ||
6391 | static int alsa_index = SNDRV_DEFAULT_IDX1; | 6393 | static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */ |
6392 | static char *alsa_id = "ThinkPadEC"; | 6394 | static char *alsa_id = "ThinkPadEC"; |
6393 | static int alsa_enable = SNDRV_DEFAULT_ENABLE1; | 6395 | static int alsa_enable = SNDRV_DEFAULT_ENABLE1; |
6394 | 6396 | ||
@@ -6705,10 +6707,11 @@ static int __init volume_create_alsa_mixer(void) | |||
6705 | 6707 | ||
6706 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, | 6708 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, |
6707 | sizeof(struct tpacpi_alsa_data), &card); | 6709 | sizeof(struct tpacpi_alsa_data), &card); |
6708 | if (rc < 0) | 6710 | if (rc < 0 || !card) { |
6709 | return rc; | 6711 | printk(TPACPI_ERR |
6710 | if (!card) | 6712 | "Failed to create ALSA card structures: %d\n", rc); |
6711 | return -ENOMEM; | 6713 | return 1; |
6714 | } | ||
6712 | 6715 | ||
6713 | BUG_ON(!card->private_data); | 6716 | BUG_ON(!card->private_data); |
6714 | data = card->private_data; | 6717 | data = card->private_data; |
@@ -6741,8 +6744,9 @@ static int __init volume_create_alsa_mixer(void) | |||
6741 | rc = snd_ctl_add(card, ctl_vol); | 6744 | rc = snd_ctl_add(card, ctl_vol); |
6742 | if (rc < 0) { | 6745 | if (rc < 0) { |
6743 | printk(TPACPI_ERR | 6746 | printk(TPACPI_ERR |
6744 | "Failed to create ALSA volume control\n"); | 6747 | "Failed to create ALSA volume control: %d\n", |
6745 | goto err_out; | 6748 | rc); |
6749 | goto err_exit; | ||
6746 | } | 6750 | } |
6747 | data->ctl_vol_id = &ctl_vol->id; | 6751 | data->ctl_vol_id = &ctl_vol->id; |
6748 | } | 6752 | } |
@@ -6750,22 +6754,25 @@ static int __init volume_create_alsa_mixer(void) | |||
6750 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); | 6754 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); |
6751 | rc = snd_ctl_add(card, ctl_mute); | 6755 | rc = snd_ctl_add(card, ctl_mute); |
6752 | if (rc < 0) { | 6756 | if (rc < 0) { |
6753 | printk(TPACPI_ERR "Failed to create ALSA mute control\n"); | 6757 | printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", |
6754 | goto err_out; | 6758 | rc); |
6759 | goto err_exit; | ||
6755 | } | 6760 | } |
6756 | data->ctl_mute_id = &ctl_mute->id; | 6761 | data->ctl_mute_id = &ctl_mute->id; |
6757 | 6762 | ||
6758 | snd_card_set_dev(card, &tpacpi_pdev->dev); | 6763 | snd_card_set_dev(card, &tpacpi_pdev->dev); |
6759 | rc = snd_card_register(card); | 6764 | rc = snd_card_register(card); |
6760 | |||
6761 | err_out: | ||
6762 | if (rc < 0) { | 6765 | if (rc < 0) { |
6763 | snd_card_free(card); | 6766 | printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); |
6764 | card = NULL; | 6767 | goto err_exit; |
6765 | } | 6768 | } |
6766 | 6769 | ||
6767 | alsa_card = card; | 6770 | alsa_card = card; |
6768 | return rc; | 6771 | return 0; |
6772 | |||
6773 | err_exit: | ||
6774 | snd_card_free(card); | ||
6775 | return 1; | ||
6769 | } | 6776 | } |
6770 | 6777 | ||
6771 | #define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */ | 6778 | #define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */ |
@@ -7016,6 +7023,28 @@ static struct ibm_struct volume_driver_data = { | |||
7016 | .shutdown = volume_shutdown, | 7023 | .shutdown = volume_shutdown, |
7017 | }; | 7024 | }; |
7018 | 7025 | ||
7026 | #else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
7027 | |||
7028 | #define alsa_card NULL | ||
7029 | |||
7030 | static void inline volume_alsa_notify_change(void) | ||
7031 | { | ||
7032 | } | ||
7033 | |||
7034 | static int __init volume_init(struct ibm_init_struct *iibm) | ||
7035 | { | ||
7036 | printk(TPACPI_INFO | ||
7037 | "volume: disabled as there is no ALSA support in this kernel\n"); | ||
7038 | |||
7039 | return 1; | ||
7040 | } | ||
7041 | |||
7042 | static struct ibm_struct volume_driver_data = { | ||
7043 | .name = "volume", | ||
7044 | }; | ||
7045 | |||
7046 | #endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
7047 | |||
7019 | /************************************************************************* | 7048 | /************************************************************************* |
7020 | * Fan subdriver | 7049 | * Fan subdriver |
7021 | */ | 7050 | */ |
@@ -8738,6 +8767,7 @@ MODULE_PARM_DESC(hotkey_report_mode, | |||
8738 | "used for backwards compatibility with userspace, " | 8767 | "used for backwards compatibility with userspace, " |
8739 | "see documentation"); | 8768 | "see documentation"); |
8740 | 8769 | ||
8770 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT | ||
8741 | module_param_named(volume_mode, volume_mode, uint, 0444); | 8771 | module_param_named(volume_mode, volume_mode, uint, 0444); |
8742 | MODULE_PARM_DESC(volume_mode, | 8772 | MODULE_PARM_DESC(volume_mode, |
8743 | "Selects volume control strategy: " | 8773 | "Selects volume control strategy: " |
@@ -8760,6 +8790,7 @@ module_param_named(id, alsa_id, charp, 0444); | |||
8760 | MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer"); | 8790 | MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer"); |
8761 | module_param_named(enable, alsa_enable, bool, 0444); | 8791 | module_param_named(enable, alsa_enable, bool, 0444); |
8762 | MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer"); | 8792 | MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer"); |
8793 | #endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
8763 | 8794 | ||
8764 | #define TPACPI_PARAM(feature) \ | 8795 | #define TPACPI_PARAM(feature) \ |
8765 | module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ | 8796 | module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ |