Ack: [Saucy PATCH 1/8] thinkpad-acpi: Add mute and mic-mute LED functionality

Brad Figg brad.figg at canonical.com
Wed Dec 18 17:36:37 UTC 2013


On 12/16/2013 12:25 AM, Hui Wang wrote:
> From: David Henningsson <david.henningsson at canonical.com>
> 
> BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1261296
> 
> 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 at canonical.com> and Takashi Iwai
> <tiwai at suse.de> for writing parts of this patch.
> 
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> Acked-by: Henrique de Moraes Holschuh <hmh at hmh.eng.br>
> Signed-off-by: Takashi Iwai <tiwai at suse.de>
> (cherry-picked from the commit 420f9739a62cdb027f5580d25c813501ff93aa6f)
> ---
>  Documentation/laptops/thinkpad-acpi.txt |  7 ++-
>  drivers/platform/x86/thinkpad_acpi.c    | 92 ++++++++++++++++++++++++++++++++-
>  include/linux/thinkpad_acpi.h           | 15 ++++++
>  3 files changed, 111 insertions(+), 3 deletions(-)
>  create mode 100644 include/linux/thinkpad_acpi.h
> 
> diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
> index cf7bc6c..e411408 100644
> --- a/Documentation/laptops/thinkpad-acpi.txt
> +++ b/Documentation/laptops/thinkpad-acpi.txt
> @@ -1,7 +1,7 @@
>  		     ThinkPad ACPI Extras Driver
>  
> -                            Version 0.24
> -                        December 11th,  2009
> +                            Version 0.25
> +                        October 16th,  2013
>  
>                 Borislav Deianov <borislav at users.sf.net>
>               Henrique de Moraes Holschuh <hmh at hmh.eng.br>
> @@ -802,6 +802,9 @@ compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
>  Distributions must never enable this option.  Individual users that
>  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:
>  
>  The available commands are:
> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> index 99eeaf4..481b96b 100644
> --- a/drivers/platform/x86/thinkpad_acpi.c
> +++ b/drivers/platform/x86/thinkpad_acpi.c
> @@ -23,7 +23,7 @@
>  
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
> -#define TPACPI_VERSION "0.24"
> +#define TPACPI_VERSION "0.25"
>  #define TPACPI_SYSFS_VERSION 0x020700
>  
>  /*
> @@ -88,6 +88,7 @@
>  
>  #include <linux/pci_ids.h>
>  
> +#include <linux/thinkpad_acpi.h>
>  
>  /* ThinkPad CMOS commands */
>  #define TP_CMOS_VOLUME_DOWN	0
> @@ -8373,6 +8374,91 @@ static struct ibm_struct fan_driver_data = {
>  	.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,
> +};
> +
>  /****************************************************************************
>   ****************************************************************************
>   *
> @@ -8791,6 +8877,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
>  		.init = fan_init,
>  		.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)
> diff --git a/include/linux/thinkpad_acpi.h b/include/linux/thinkpad_acpi.h
> new file mode 100644
> index 0000000..361de59
> --- /dev/null
> +++ b/include/linux/thinkpad_acpi.h
> @@ -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
> 


-- 
Brad Figg brad.figg at canonical.com http://www.canonical.com




More information about the kernel-team mailing list