asus_acpi.c

来自「linux 内核源代码」· C语言 代码 · 共 1,425 行 · 第 1/3 页

C
1,425
字号
/* *  asus_acpi.c - Asus Laptop ACPI Extras * * *  Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor * *  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. *  �ic Burghard  - LED display support for W1N * */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <linux/backlight.h>#include <acpi/acpi_drivers.h>#include <acpi/acpi_bus.h>#include <asm/uaccess.h>#define ASUS_ACPI_VERSION "0.30"#define PROC_ASUS       "asus"	//the directory#define PROC_MLED       "mled"#define PROC_WLED       "wled"#define PROC_TLED       "tled"#define PROC_BT         "bluetooth"#define PROC_LEDD       "ledd"#define PROC_INFO       "info"#define PROC_LCD        "lcd"#define PROC_BRN        "brn"#define PROC_DISP       "disp"#define ACPI_HOTK_NAME          "Asus Laptop ACPI Extras Driver"#define ACPI_HOTK_CLASS         "hotkey"#define ACPI_HOTK_DEVICE_NAME   "Hotkey"/* * Some events we use, same for all Asus */#define BR_UP       0x10#define BR_DOWN     0x20/* * Flags for hotk status */#define MLED_ON     0x01	//mail LED#define WLED_ON     0x02	//wireless LED#define TLED_ON     0x04	//touchpad LED#define BT_ON       0x08	//internal BluetoothMODULE_AUTHOR("Julien Lerouge, Karol Kozimor");MODULE_DESCRIPTION(ACPI_HOTK_NAME);MODULE_LICENSE("GPL");static uid_t asus_uid;static gid_t asus_gid;module_param(asus_uid, uint, 0);MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus.\n");module_param(asus_gid, uint, 0);MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus.\n");/* For each model, all features implemented,  * those marked with R are relative to HOTK, A for absolute */struct model_data {	char *name;		//name of the laptop________________A	char *mt_mled;		//method to handle mled_____________R	char *mled_status;	//node to handle mled reading_______A	char *mt_wled;		//method to handle wled_____________R	char *wled_status;	//node to handle wled reading_______A	char *mt_tled;		//method to handle tled_____________R	char *tled_status;	//node to handle tled reading_______A	char *mt_ledd;		//method to handle LED display______R	char *mt_bt_switch;	//method to switch Bluetooth on/off_R	char *bt_status;	//no model currently supports this__?	char *mt_lcd_switch;	//method to turn LCD on/off_________A	char *lcd_status;	//node to read LCD panel state______A	char *brightness_up;	//method to set brightness up_______A	char *brightness_down;	//guess what ?______________________A	char *brightness_set;	//method to set absolute brightness_R	char *brightness_get;	//method to get absolute brightness_R	char *brightness_status;	//node to get brightness____________A	char *display_set;	//method to set video output________R	char *display_get;	//method to get video output________R};/* * This is the main structure, we can use it to store anything interesting * about the hotk device */struct asus_hotk {	struct acpi_device *device;	//the device we are in	acpi_handle handle;	//the handle of the hotk device	char status;		//status of the hotk, for LEDs, ...	u32 ledd_status;	//status of the LED display	struct model_data *methods;	//methods available on the laptop	u8 brightness;		//brightness level	enum {		A1x = 0,	//A1340D, A1300F		A2x,		//A2500H		A4G,		//A4700G		D1x,		//D1		L2D,		//L2000D		L3C,		//L3800C		L3D,		//L3400D		L3H,		//L3H, L2000E, L5D		L4R,		//L4500R		L5x,		//L5800C 		L8L,		//L8400L		M1A,		//M1300A		M2E,		//M2400E, L4400L		M6N,		//M6800N, W3400N		M6R,		//M6700R, A3000G		P30,		//Samsung P30		S1x,		//S1300A, but also L1400B and M2400A (L84F)		S2x,		//S200 (J1 reported), Victor MP-XP7210		W1N,		//W1000N		W5A,		//W5A		W3V,            //W3030V		xxN,		//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N		A4S,            //Z81sp		//(Centrino)		END_MODEL	} model;		//Models currently supported	u16 event_count[128];	//count for each event TODO make this better};/* Here we go */#define A1x_PREFIX "\\_SB.PCI0.ISA.EC0."#define L3C_PREFIX "\\_SB.PCI0.PX40.ECD0."#define M1A_PREFIX "\\_SB.PCI0.PX40.EC0."#define P30_PREFIX "\\_SB.PCI0.LPCB.EC0."#define S1x_PREFIX "\\_SB.PCI0.PX40."#define S2x_PREFIX A1x_PREFIX#define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0."static struct model_data model_conf[END_MODEL] = {	/*	 * TODO I have seen a SWBX and AIBX method on some models, like L1400B,	 * it seems to be a kind of switch, but what for ?	 */	{	 .name = "A1x",	 .mt_mled = "MLED",	 .mled_status = "\\MAIL",	 .mt_lcd_switch = A1x_PREFIX "_Q10",	 .lcd_status = "\\BKLI",	 .brightness_up = A1x_PREFIX "_Q0E",	 .brightness_down = A1x_PREFIX "_Q0F"},	{	 .name = "A2x",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .wled_status = "\\SG66",	 .mt_lcd_switch = "\\Q10",	 .lcd_status = "\\BAOF",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "A4G",	 .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\ADVG"},	{	 .name = "D1x",	 .mt_mled = "MLED",	 .mt_lcd_switch = "\\Q0D",	 .lcd_status = "\\GP11",	 .brightness_up = "\\Q0C",	 .brightness_down = "\\Q0B",	 .brightness_status = "\\BLVL",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "L2D",	 .mt_mled = "MLED",	 .mled_status = "\\SGP6",	 .mt_wled = "WLED",	 .wled_status = "\\RCP3",	 .mt_lcd_switch = "\\Q10",	 .lcd_status = "\\SGP0",	 .brightness_up = "\\Q0E",	 .brightness_down = "\\Q0F",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "L3C",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = L3C_PREFIX "_Q10",	 .lcd_status = "\\GL32",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\_SB.PCI0.PCI1.VGAC.NMAP"},	{	 .name = "L3D",	 .mt_mled = "MLED",	 .mled_status = "\\MALD",	 .mt_wled = "WLED",	 .mt_lcd_switch = "\\Q10",	 .lcd_status = "\\BKLG",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "L3H",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = "EHK",	 .lcd_status = "\\_SB.PCI0.PM.PBC",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "L4R",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .wled_status = "\\_SB.PCI0.SBRG.SG13",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\_SB.PCI0.SBSM.SEO4",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"},	{	 .name = "L5x",	 .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */	 .mt_tled = "TLED",	 .mt_lcd_switch = "\\Q0D",	 .lcd_status = "\\BAOF",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "L8L"/* No features, but at least support the hotkeys */	 },	{	 .name = "M1A",	 .mt_mled = "MLED",	 .mt_lcd_switch = M1A_PREFIX "Q10",	 .lcd_status = "\\PNOF",	 .brightness_up = M1A_PREFIX "Q0E",	 .brightness_down = M1A_PREFIX "Q0F",	 .brightness_status = "\\BRIT",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "M2E",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = "\\Q10",	 .lcd_status = "\\GP06",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},	{	 .name = "M6N",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .wled_status = "\\_SB.PCI0.SBRG.SG13",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\_SB.BKLT",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\SSTE"},	{	 .name = "M6R",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\_SB.PCI0.SBSM.SEO4",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"},	{	 .name = "P30",	 .mt_wled = "WLED",	 .mt_lcd_switch = P30_PREFIX "_Q0E",	 .lcd_status = "\\BKLT",	 .brightness_up = P30_PREFIX "_Q68",	 .brightness_down = P30_PREFIX "_Q69",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\DNXT"},	{	 .name = "S1x",	 .mt_mled = "MLED",	 .mled_status = "\\EMLE",	 .mt_wled = "WLED",	 .mt_lcd_switch = S1x_PREFIX "Q10",	 .lcd_status = "\\PNOF",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV"},	{	 .name = "S2x",	 .mt_mled = "MLED",	 .mled_status = "\\MAIL",	 .mt_lcd_switch = S2x_PREFIX "_Q10",	 .lcd_status = "\\BKLI",	 .brightness_up = S2x_PREFIX "_Q0B",	 .brightness_down = S2x_PREFIX "_Q0A"},	{	 .name = "W1N",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_ledd = "SLCM",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\BKLT",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\ADVG"},	{	 .name = "W5A",	 .mt_bt_switch = "BLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\ADVG"},	{	 .name = "W3V",	 .mt_mled = "MLED",	 .mt_wled = "WLED",	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\BKLT",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	 .display_get = "\\INFB"},       {	 .name = "xxN",	 .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */	 .mt_lcd_switch = xxN_PREFIX "_Q10",	 .lcd_status = "\\BKLT",	 .brightness_set = "SPLV",	 .brightness_get = "GPLV",	 .display_set = "SDSP",	.display_get = "\\ADVG"},	{		.name              = "A4S",		.brightness_set    = "SPLV",		.brightness_get    = "GPLV",		.mt_bt_switch      = "BLED",		.mt_wled           = "WLED"	}};/* procdir we use */static struct proc_dir_entry *asus_proc_dir;static struct backlight_device *asus_backlight_device;/* * This header is made available to allow proper configuration given model, * revision number , ... this info cannot go in struct asus_hotk because it is * available before the hotk */static struct acpi_table_header *asus_info;/* The actual device the driver binds to */static struct asus_hotk *hotk;/* * The hotkey driver and autoloading declaration */static int asus_hotk_add(struct acpi_device *device);static int asus_hotk_remove(struct acpi_device *device, int type);static const struct acpi_device_id asus_device_ids[] = {	{"ATK0100", 0},	{"", 0},};MODULE_DEVICE_TABLE(acpi, asus_device_ids);static struct acpi_driver asus_hotk_driver = {	.name = "asus_acpi",	.class = ACPI_HOTK_CLASS,	.ids = asus_device_ids,	.ops = {		.add = asus_hotk_add,		.remove = asus_hotk_remove,		},};/*  * This function evaluates an ACPI method, given an int as parameter, the * method is searched within the scope of the handle, can be NULL. The output * of the method is written is output, which can also be NULL * * returns 1 if write is successful, 0 else.  */static int write_acpi_int(acpi_handle handle, const char *method, int val,			  struct acpi_buffer *output){	struct acpi_object_list params;	//list of input parameters (an int here)	union acpi_object in_obj;	//the only param we use	acpi_status status;	params.count = 1;	params.pointer = &in_obj;	in_obj.type = ACPI_TYPE_INTEGER;	in_obj.integer.value = val;	status = acpi_evaluate_object(handle, (char *)method, &params, output);	return (status == AE_OK);}static int read_acpi_int(acpi_handle handle, const char *method, int *val){	struct acpi_buffer output;	union acpi_object out_obj;	acpi_status status;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?