mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 01:34:00 +08:00
thinkpad-acpi: Add mute and mic-mute LED functionality
The LEDs are currently not visible to userspace, for security reasons. They are exported through thinkpad_acpi.h for use by the snd-hda-intel driver. Thanks to Alex Hung <alex.hung@canonical.com> and Takashi Iwai <tiwai@suse.de> for writing parts of this patch. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
1d198f26c9
commit
420f9739a6
@ -1,7 +1,7 @@
|
|||||||
ThinkPad ACPI Extras Driver
|
ThinkPad ACPI Extras Driver
|
||||||
|
|
||||||
Version 0.24
|
Version 0.25
|
||||||
December 11th, 2009
|
October 16th, 2013
|
||||||
|
|
||||||
Borislav Deianov <borislav@users.sf.net>
|
Borislav Deianov <borislav@users.sf.net>
|
||||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||||
@ -741,6 +741,9 @@ compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
|
|||||||
Distributions must never enable this option. Individual users that
|
Distributions must never enable this option. Individual users that
|
||||||
are aware of the consequences are welcome to enabling it.
|
are aware of the consequences are welcome to enabling it.
|
||||||
|
|
||||||
|
Audio mute and microphone mute LEDs are supported, but currently not
|
||||||
|
visible to userspace. They are used by the snd-hda-intel audio driver.
|
||||||
|
|
||||||
procfs notes:
|
procfs notes:
|
||||||
|
|
||||||
The available commands are:
|
The available commands are:
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#define TPACPI_VERSION "0.24"
|
#define TPACPI_VERSION "0.25"
|
||||||
#define TPACPI_SYSFS_VERSION 0x020700
|
#define TPACPI_SYSFS_VERSION 0x020700
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -88,6 +88,7 @@
|
|||||||
|
|
||||||
#include <linux/pci_ids.h>
|
#include <linux/pci_ids.h>
|
||||||
|
|
||||||
|
#include <linux/thinkpad_acpi.h>
|
||||||
|
|
||||||
/* ThinkPad CMOS commands */
|
/* ThinkPad CMOS commands */
|
||||||
#define TP_CMOS_VOLUME_DOWN 0
|
#define TP_CMOS_VOLUME_DOWN 0
|
||||||
@ -8350,6 +8351,91 @@ static struct ibm_struct fan_driver_data = {
|
|||||||
.resume = fan_resume,
|
.resume = fan_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Mute LED subdriver
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct tp_led_table {
|
||||||
|
acpi_string name;
|
||||||
|
int on_value;
|
||||||
|
int off_value;
|
||||||
|
int state;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tp_led_table led_tables[] = {
|
||||||
|
[TPACPI_LED_MUTE] = {
|
||||||
|
.name = "SSMS",
|
||||||
|
.on_value = 1,
|
||||||
|
.off_value = 0,
|
||||||
|
},
|
||||||
|
[TPACPI_LED_MICMUTE] = {
|
||||||
|
.name = "MMTS",
|
||||||
|
.on_value = 2,
|
||||||
|
.off_value = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mute_led_on_off(struct tp_led_table *t, bool state)
|
||||||
|
{
|
||||||
|
acpi_handle temp;
|
||||||
|
int output;
|
||||||
|
|
||||||
|
if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) {
|
||||||
|
pr_warn("Thinkpad ACPI has no %s interface.\n", t->name);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acpi_evalf(hkey_handle, &output, t->name, "dd",
|
||||||
|
state ? t->on_value : t->off_value))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
t->state = state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tpacpi_led_set(int whichled, bool on)
|
||||||
|
{
|
||||||
|
struct tp_led_table *t;
|
||||||
|
|
||||||
|
if (whichled < 0 || whichled >= TPACPI_LED_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
t = &led_tables[whichled];
|
||||||
|
if (t->state < 0 || t->state == on)
|
||||||
|
return t->state;
|
||||||
|
return mute_led_on_off(t, on);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(tpacpi_led_set);
|
||||||
|
|
||||||
|
static int mute_led_init(struct ibm_init_struct *iibm)
|
||||||
|
{
|
||||||
|
acpi_handle temp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < TPACPI_LED_MAX; i++) {
|
||||||
|
struct tp_led_table *t = &led_tables[i];
|
||||||
|
if (ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp)))
|
||||||
|
mute_led_on_off(t, false);
|
||||||
|
else
|
||||||
|
t->state = -ENODEV;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mute_led_exit(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < TPACPI_LED_MAX; i++)
|
||||||
|
tpacpi_led_set(i, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ibm_struct mute_led_driver_data = {
|
||||||
|
.name = "mute_led",
|
||||||
|
.exit = mute_led_exit,
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
*
|
*
|
||||||
@ -8768,6 +8854,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
|
|||||||
.init = fan_init,
|
.init = fan_init,
|
||||||
.data = &fan_driver_data,
|
.data = &fan_driver_data,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.init = mute_led_init,
|
||||||
|
.data = &mute_led_driver_data,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init set_ibm_param(const char *val, struct kernel_param *kp)
|
static int __init set_ibm_param(const char *val, struct kernel_param *kp)
|
||||||
|
15
include/linux/thinkpad_acpi.h
Normal file
15
include/linux/thinkpad_acpi.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __THINKPAD_ACPI_H__
|
||||||
|
#define __THINKPAD_ACPI_H__
|
||||||
|
|
||||||
|
/* These two functions return 0 if success, or negative error code
|
||||||
|
(e g -ENODEV if no led present) */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TPACPI_LED_MUTE,
|
||||||
|
TPACPI_LED_MICMUTE,
|
||||||
|
TPACPI_LED_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
int tpacpi_led_set(int whichled, bool on);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user