[PATCH 2/2] thinkpad-acpi: support hardware mute and led

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Newer thinkpad models have a mute hotkey with a led to indicate
current mute states. Thinkpad BIOS provides ACPI interfaces for
getting and changing the hardware mute along with the led.

Signed-off-by: Alex Hung <alex.hung@xxxxxxxxxxxxx>
---
 drivers/platform/x86/thinkpad_acpi.c | 89 ++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index adb3a4e..d39bf18 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -8364,6 +8364,91 @@ static struct ibm_struct fan_driver_data = {
 	.resume = fan_resume,
 };
 
+/*************************************************************************
+ * Mute LED subdriver
+ */
+
+enum {
+	TPACPI_AML_MUTE_READ_MASK = 0x01,
+};
+
+static int mute_led_on_off(int state)
+{
+	int output;
+	acpi_handle temp;
+
+	if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, "SSMS", &temp))) {
+		pr_warn("Thinkpad ACPI has no GSMS interface.\n");
+		return -EIO;
+	}
+
+	if (!acpi_evalf(hkey_handle, &output, "SSMS", "dd", state))
+		return -EIO;
+
+	return 0;
+}
+
+static void mute_led_set(struct led_classdev *led_cdev,
+	enum led_brightness value)
+{
+	if (value > 0)
+		mute_led_on_off(1);
+	else
+		mute_led_on_off(0);
+}
+
+static enum led_brightness mute_led_get(struct led_classdev *led_cdev)
+{
+	int state = 0;
+	acpi_handle temp;
+
+	if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, "GSMS", &temp))) {
+		pr_warn("Thinkpad ACPI has no GSMS interface.\n");
+		return -EIO;
+	}
+
+	if (!acpi_evalf(hkey_handle, &state, "GSMS", "dd"))
+		pr_warn("failed to get hardware mute state.\n");
+
+	state &= TPACPI_AML_MUTE_READ_MASK;
+
+	return state;
+}
+
+static struct tpacpi_led_classdev tpacpi_led_mute = {
+	.led_classdev = {
+		.name = "tpacpi::mute",
+		.brightness_set = mute_led_set,
+		.brightness_get = mute_led_get,
+	}
+};
+
+static int mute_led_init(struct ibm_init_struct *iibm)
+{
+	acpi_handle temp;
+
+	if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, "GSMS", &temp)))
+		return 0;
+
+	return led_classdev_register(&tpacpi_pdev->dev,
+		&tpacpi_led_mute.led_classdev);
+}
+
+static void mute_led_exit(void)
+{
+	acpi_handle temp;
+
+	if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, "GSMS", &temp)))
+		return;
+
+	led_classdev_unregister(&tpacpi_led_mute.led_classdev);
+}
+
+static struct ibm_struct mute_led_driver_data = {
+	.name = "mute_led",
+	.exit = mute_led_exit,
+};
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -8782,6 +8867,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)
-- 
1.8.1.2


------------------------------------------------------------------------------
LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
_______________________________________________
ibm-acpi-devel mailing list
ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel




[Index of Archives]     [Linux ACPI]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Photo]     [Yosemite Photos]     [Yosemite Advice]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux