From patchwork Tue Jul 27 23:49:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre X-Patchwork-Id: 114661 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6RNnxgb020996 for ; Tue, 27 Jul 2010 23:49:59 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753541Ab0G0Xt6 (ORCPT ); Tue, 27 Jul 2010 19:49:58 -0400 Received: from moutng.kundenserver.de ([212.227.126.171]:50887 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752551Ab0G0Xt5 (ORCPT ); Tue, 27 Jul 2010 19:49:57 -0400 Received: from delllaptop.localnet (lib59-1-82-229-139-157.fbx.proxad.net [82.229.139.157]) by mrelayeu.kundenserver.de (node=mreu2) with ESMTP (Nemesis) id 0Lr6Jj-1PGnQt1DxT-00dtNL; Wed, 28 Jul 2010 01:49:56 +0200 From: Pierre To: linux-acpi@vger.kernel.org Subject: Patch for toshiba_acpi driver : add illumination support Date: Wed, 28 Jul 2010 01:49:54 +0200 User-Agent: KMail/1.13.5 (Linux/2.6.34-1-amd64; KDE/4.4.5; x86_64; ; ) MIME-Version: 1.0 Message-Id: <201007280149.54905.pinaraf@pinaraf.info> X-Provags-ID: V02:K0:vZJP39Sv+FIVi5+XentGUXuIW8cmxyplImi3kV/pNfx yuCWR8nb110eukrSohwUhB/U3uTeoQcy72tA9Wfer00L/FMXZs K+zLeMLK82rT+3Gmd4UvFT8SFarASuqnzDrWX7fsalhIkDk8JO ZCiIgNrLEpY6hzFlMPnuaQ11pXUPzBHYxSi2wm8MMkufsxVRvg YjVesB7pdqzzmTyU/Z5O7y1tdjUHKmHOBoVr29DDPw= Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 27 Jul 2010 23:49:59 +0000 (UTC) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 37aa147..f3a0d95 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -4,6 +4,7 @@ * * Copyright (C) 2002-2004 John Belmonte * Copyright (C) 2008 Philip Langdale + * Copyright (C) 2010 Pierre Ducroquet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +48,7 @@ #include #include #include +#include #include #include @@ -285,6 +287,7 @@ struct toshiba_acpi_dev { struct platform_device *p_dev; struct rfkill *bt_rfk; struct input_dev *hotkey_dev; + int illumination_installed; acpi_handle handle; const char *bt_name; @@ -292,6 +295,111 @@ struct toshiba_acpi_dev { struct mutex mutex; }; +/* Illumination support */ +static int toshiba_illumination_available (void) +{ + u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status; + + in[0] = 0xf100; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "The illumination device available is not available\n"); + return 0; + } + in[0] = 0xf400; + status = hci_raw(in, out); + return 1; +} + +static void toshiba_illumination_set (struct led_classdev *cdev, + enum led_brightness brightness) +{ + u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status; + + // First request : initialize communication. + in[0] = 0xf100; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "The illumination device available is not available\n"); + return; + } + + if (brightness) { + // Switch the illumination on + in[0] = 0xf400; + in[1] = 0x14e; + in[2] = 1; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "ACPI call for illumination failed.\n"); + return; + } + } else { + // Switch the illumination off + in[0] = 0xf400; + in[1] = 0x14e; + in[2] = 0; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "ACPI call for illumination failed.\n"); + return; + } + } + + // Last request : close communication. + in[0] = 0xf200; + in[1] = 0; + in[2] = 0; + hci_raw(in, out); +} + +static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) +{ + u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status; + enum led_brightness result; + + // First request : initialize communication. + in[0] = 0xf100; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "The illumination device available is not available\n"); + return LED_OFF; + } + + // Check the illumination + in[0] = 0xf300; + in[1] = 0x14e; + status = hci_raw(in, out); + if (ACPI_FAILURE(status)) { + printk(MY_INFO "ACPI call for illumination failed.\n"); + return LED_OFF; + } + + result = out[2] ? LED_FULL : LED_OFF; + + // Last request : close communication. + in[0] = 0xf200; + in[1] = 0; + in[2] = 0; + hci_raw(in, out); + + return result; +} + +static struct led_classdev toshiba_led = { + .name = "toshiba::illumination", + .max_brightness = 1, + .brightness_set = toshiba_illumination_set, + .brightness_get = toshiba_illumination_get, +}; + + static struct toshiba_acpi_dev toshiba_acpi = { .bt_name = "Toshiba Bluetooth", }; @@ -845,7 +953,7 @@ static int toshiba_acpi_setup_keyboard(char *device) acpi_handle handle; int result; const struct key_entry *key; - + status = acpi_get_handle(NULL, device, &handle); if (ACPI_FAILURE(status)) { printk(MY_INFO "Unable to get notification device\n"); @@ -853,7 +961,7 @@ static int toshiba_acpi_setup_keyboard(char *device) } toshiba_acpi.handle = handle; - + status = acpi_evaluate_object(handle, "ENAB", NULL, NULL); if (ACPI_FAILURE(status)) { printk(MY_INFO "Unable to enable hotkeys\n"); @@ -903,6 +1011,10 @@ static void toshiba_acpi_exit(void) rfkill_destroy(toshiba_acpi.bt_rfk); } + if (toshiba_acpi.illumination_installed) { + led_classdev_unregister(&toshiba_led); + } + if (toshiba_backlight_device) backlight_device_unregister(toshiba_backlight_device); @@ -1012,6 +1124,12 @@ static int __init toshiba_acpi_init(void) return ret; } } + + toshiba_acpi.illumination_installed = 0; + if (toshiba_illumination_available()) { + if (!led_classdev_register(&(toshiba_acpi.p_dev->dev), &toshiba_led)) + toshiba_acpi.illumination_installed = 1; + } return 0; }