aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c92
1 files changed, 91 insertions, 1 deletions
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
8359struct tp_led_table {
8360 acpi_string name;
8361 int on_value;
8362 int off_value;
8363 int state;
8364};
8365
8366static 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
8379static 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
8397int 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}
8409EXPORT_SYMBOL_GPL(tpacpi_led_set);
8410
8411static 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
8426static 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
8434static 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
8773static int __init set_ibm_param(const char *val, struct kernel_param *kp) 8863static int __init set_ibm_param(const char *val, struct kernel_param *kp)