/*
* asus-laptop.c - Asus Laptop Support
*
*
* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
* Copyright (C) 2006-2007 Corentin Chary
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* The development page for this driver is located at
* http://sourceforge.net/projects/acpi4asus/
*
* Credits:
* Pontus Fuchs - Helper functions, cleanup
* Johann Wiesner - Small compile fixes
* John Belmonte - ACPI code for Toshiba laptop was a good starting point.
* Eric Burghard - LED display support for W1N
* Josh Green - Light Sens support
* Thomas Tuttle - His first patch for led support was very helpfull
* Sam Lin - GPS support
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/proc_fs.h>
#include <linux/backlight.h>
#include <linux/fb.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
#define ASUS_LAPTOP_VERSION "0.42"
#define ASUS_HOTK_NAME "Asus Laptop Support"
#define ASUS_HOTK_CLASS "hotkey"
#define ASUS_HOTK_DEVICE_NAME "Hotkey"
#define ASUS_HOTK_FILE "asus-laptop"
#define ASUS_HOTK_PREFIX "\\_SB.ATKD."
/*
* Some events we use, same for all Asus
*/
#define ATKD_BR_UP 0x10
#define ATKD_BR_DOWN 0x20
#define ATKD_LCD_ON 0x33
#define ATKD_LCD_OFF 0x34
/*
* Known bits returned by \_SB.ATKD.HWRS
*/
#define WL_HWRS 0x80
#define BT_HWRS 0x100
/*
* Flags for hotk status
* WL_ON and BT_ON are also used for wireless_status()
*/
#define WL_ON 0x01 //internal Wifi
#define BT_ON 0x02 //internal Bluetooth
#define MLED_ON 0x04 //mail LED
#define TLED_ON 0x08 //touchpad LED
#define RLED_ON 0x10 //Record LED
#define PLED_ON 0x20 //Phone LED
#define GLED_ON 0x40 //Gaming LED
#define LCD_ON 0x80 //LCD backlight
#define GPS_ON 0x100 //GPS
#define ASUS_LOG ASUS_HOTK_FILE ": "
#define ASUS_ERR KERN_ERR ASUS_LOG
#define ASUS_WARNING KERN_WARNING ASUS_LOG
#define ASUS_NOTICE KERN_NOTICE ASUS_LOG
#define ASUS_INFO KERN_INFO ASUS_LOG
#define ASUS_DEBUG KERN_DEBUG ASUS_LOG
MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
MODULE_DESCRIPTION(ASUS_HOTK_NAME);
MODULE_LICENSE("GPL");
/* WAPF defines the behavior of the Fn+Fx wlan key
* The significance of values is yet to be found, but
* most of the time:
* 0x0 will do nothing
* 0x1 will allow to control the device with Fn+Fx key.
* 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key
* 0x5 like 0x1 or 0x4
* So, if something doesn't work as you want, just try other values =)
*/
static uint wapf = 1;
module_param(wapf, uint, 0644);
MODULE_PARM_DESC(wapf, "WAPF value");
#define ASUS_HANDLE(object, paths...) \
static acpi_handle object##_handle = NULL; \
static char *object##_paths[] = { paths }
/* LED */
ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */
ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */
ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */
/* LEDD */
ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
/* Bluetooth and WLAN
* WLED and BLED are not handled like other XLED, because in some dsdt
* they also control the WLAN/Bluetooth device.
*/
ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED");
ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED");
ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS"); /* All new models */
/* Brightness */
ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV");
ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV");
/* Backlight */
ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
"\\_SB.PCI0.ISA.EC0._Q10", /* A1x */
"\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
"\\_SB.PCI0.PX40.EC0.Q10", /* M1A */
"\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
"\\_SB.PCI0.PX40.Q10", /* S1x */
"\\Q10"); /* A2x, L2D, L3D, M2E */
/* Display */
ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP");
ASUS_HANDLE(display_get,