diff options
-rw-r--r-- | Documentation/laptops/thinkpad-acpi.txt | 7 | ||||
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 92 | ||||
-rw-r--r-- | include/linux/thinkpad_acpi.h | 15 |
3 files changed, 111 insertions, 3 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 86c52360ffe7..fc04c14de4bb 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | ThinkPad ACPI Extras Driver | 1 | ThinkPad ACPI Extras Driver |
2 | 2 | ||
3 | Version 0.24 | 3 | Version 0.25 |
4 | December 11th, 2009 | 4 | October 16th, 2013 |
5 | 5 | ||
6 | Borislav Deianov <borislav@users.sf.net> | 6 | Borislav Deianov <borislav@users.sf.net> |
7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
@@ -741,6 +741,9 @@ compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled. | |||
741 | Distributions must never enable this option. Individual users that | 741 | Distributions must never enable this option. Individual users that |
742 | are aware of the consequences are welcome to enabling it. | 742 | are aware of the consequences are welcome to enabling it. |
743 | 743 | ||
744 | Audio mute and microphone mute LEDs are supported, but currently not | ||
745 | visible to userspace. They are used by the snd-hda-intel audio driver. | ||
746 | |||
744 | procfs notes: | 747 | procfs notes: |
745 | 748 | ||
746 | The available commands are: | 749 | The available commands are: |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 03ca6c139f1a..0b7efb269cf1 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
25 | 25 | ||
26 | #define TPACPI_VERSION "0.24" | 26 | #define TPACPI_VERSION "0.25" |
27 | #define TPACPI_SYSFS_VERSION 0x020700 | 27 | #define TPACPI_SYSFS_VERSION 0x020700 |
28 | 28 | ||
29 | /* | 29 | /* |
@@ -88,6 +88,7 @@ | |||
88 | 88 | ||
89 | #include <linux/pci_ids.h> | 89 | #include <linux/pci_ids.h> |
90 | 90 | ||
91 | #include <linux/thinkpad_acpi.h> | ||
91 | 92 | ||
92 | /* ThinkPad CMOS commands */ | 93 | /* ThinkPad CMOS commands */ |
93 | #define TP_CMOS_VOLUME_DOWN 0 | 94 | #define TP_CMOS_VOLUME_DOWN 0 |
@@ -8350,6 +8351,91 @@ static struct ibm_struct fan_driver_data = { | |||
8350 | .resume = fan_resume, | 8351 | .resume = fan_resume, |
8351 | }; | 8352 | }; |
8352 | 8353 | ||
8354 | /************************************************************************* | ||
8355 | * Mute LED subdriver | ||
8356 | */ | ||
8357 | |||
8358 | |||
8359 | struct tp_led_table { | ||
8360 | acpi_string name; | ||
8361 | int on_value; | ||
8362 | int off_value; | ||
8363 | int state; | ||
8364 | }; | ||
8365 | |||
8366 | static struct tp_led_table led_tables[] = { | ||
8367 | [TPACPI_LED_MUTE] = { | ||
8368 | .name = "SSMS", | ||
8369 | .on_value = 1, | ||
8370 | .off_value = 0, | ||
8371 | }, | ||
8372 | [TPACPI_LED_MICMUTE] = { | ||
8373 | .name = "MMTS", | ||
8374 | .on_value = 2, | ||
8375 | .off_value = 0, | ||
8376 | }, | ||
8377 | }; | ||
8378 | |||
8379 | static int mute_led_on_off(struct tp_led_table *t, bool state) | ||
8380 | { | ||
8381 | acpi_handle temp; | ||
8382 | int output; | ||
8383 | |||
8384 | if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) { | ||
8385 | pr_warn("Thinkpad ACPI has no %s interface.\n", t->name); | ||
8386 | return -EIO; | ||
8387 | } | ||
8388 | |||
8389 | if (!acpi_evalf(hkey_handle, &output, t->name, "dd", | ||
8390 | state ? t->on_value : t->off_value)) | ||
8391 | return -EIO; | ||
8392 | |||
8393 | t->state = state; | ||
8394 | return state; | ||
8395 | } | ||
8396 | |||
8397 | int tpacpi_led_set(int whichled, bool on) | ||
8398 | { | ||
8399 | struct tp_led_table *t; | ||
8400 | |||
8401 | if (whichled < 0 || whichled >= TPACPI_LED_MAX) | ||
8402 | return -EINVAL; | ||
8403 | |||
8404 | t = &led_tables[whichled]; | ||
8405 | if (t->state < 0 || t->state == on) | ||
8406 | return t->state; | ||
8407 | return mute_led_on_off(t, on); | ||
8408 | } | ||
8409 | EXPORT_SYMBOL_GPL(tpacpi_led_set); | ||
8410 | |||
8411 | static int mute_led_init(struct ibm_init_struct *iibm) | ||
8412 | { | ||
8413 | acpi_handle temp; | ||
8414 | int i; | ||
8415 | |||
8416 | for (i = 0; i < TPACPI_LED_MAX; i++) { | ||
8417 | struct tp_led_table *t = &led_tables[i]; | ||
8418 | if (ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) | ||
8419 | mute_led_on_off(t, false); | ||
8420 | else | ||
8421 | t->state = -ENODEV; | ||
8422 | } | ||
8423 | return 0; | ||
8424 | } | ||
8425 | |||
8426 | static void mute_led_exit(void) | ||
8427 | { | ||
8428 | int i; | ||
8429 | |||
8430 | for (i = 0; i < TPACPI_LED_MAX; i++) | ||
8431 | tpacpi_led_set(i, false); | ||
8432 | } | ||
8433 | |||
8434 | static struct ibm_struct mute_led_driver_data = { | ||
8435 | .name = "mute_led", | ||
8436 | .exit = mute_led_exit, | ||
8437 | }; | ||
8438 | |||
8353 | /**************************************************************************** | 8439 | /**************************************************************************** |
8354 | **************************************************************************** | 8440 | **************************************************************************** |
8355 | * | 8441 | * |
@@ -8768,6 +8854,10 @@ static struct ibm_init_struct ibms_init[] __initdata = { | |||
8768 | .init = fan_init, | 8854 | .init = fan_init, |
8769 | .data = &fan_driver_data, | 8855 | .data = &fan_driver_data, |
8770 | }, | 8856 | }, |
8857 | { | ||
8858 | .init = mute_led_init, | ||
8859 | .data = &mute_led_driver_data, | ||
8860 | }, | ||
8771 | }; | 8861 | }; |
8772 | 8862 | ||
8773 | static int __init set_ibm_param(const char *val, struct kernel_param *kp) | 8863 | static int __init set_ibm_param(const char *val, struct kernel_param *kp) |
diff --git a/include/linux/thinkpad_acpi.h b/include/linux/thinkpad_acpi.h new file mode 100644 index 000000000000..361de59a2285 --- /dev/null +++ b/include/linux/thinkpad_acpi.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef __THINKPAD_ACPI_H__ | ||
2 | #define __THINKPAD_ACPI_H__ | ||
3 | |||
4 | /* These two functions return 0 if success, or negative error code | ||
5 | (e g -ENODEV if no led present) */ | ||
6 | |||
7 | enum { | ||
8 | TPACPI_LED_MUTE, | ||
9 | TPACPI_LED_MICMUTE, | ||
10 | TPACPI_LED_MAX, | ||
11 | }; | ||
12 | |||
13 | int tpacpi_led_set(int whichled, bool on); | ||
14 | |||
15 | #endif | ||